5 #include "sw/device/lib/crypto/drivers/keymgr.h"
10 #include "sw/device/lib/crypto/drivers/entropy.h"
11 #include "sw/device/lib/crypto/impl/status.h"
15 #include "keymgr_regs.h"
18 #define MODULE_ID MAKE_MODULE_ID('d', 'k', 'r')
23 static_assert(kKeymgrSaltNumWords == KEYMGR_SALT_MULTIREG_COUNT,
24 "Number of salt registers does not match.");
25 static_assert(kKeymgrOutputShareNumWords ==
26 KEYMGR_SW_SHARE0_OUTPUT_MULTIREG_COUNT,
27 "Number of output share 0 registers does not match.");
28 static_assert(kKeymgrOutputShareNumWords ==
29 KEYMGR_SW_SHARE1_OUTPUT_MULTIREG_COUNT,
30 "Number of output share 1 registers does not match.");
38 static status_t keymgr_is_idle(
void) {
39 uint32_t reg = abs_mmio_read32(kBaseAddr + KEYMGR_OP_STATUS_REG_OFFSET);
41 if (launder32(
status) == KEYMGR_OP_STATUS_STATUS_VALUE_IDLE) {
45 return OTCRYPTO_RECOV_ERR;
57 abs_mmio_write32(kBaseAddr + KEYMGR_KEY_VERSION_REG_OFFSET,
60 for (
size_t i = 0; i < kKeymgrSaltNumWords; i++) {
62 kBaseAddr + KEYMGR_SALT_0_REG_OFFSET + (i *
sizeof(uint32_t)),
63 diversification.
salt[i]);
67 abs_mmio_write32(kBaseAddr + KEYMGR_START_REG_OFFSET,
68 1 << KEYMGR_START_EN_BIT);
82 static status_t keymgr_wait_until_done(
void) {
87 reg = abs_mmio_read32(kBaseAddr + KEYMGR_OP_STATUS_REG_OFFSET);
89 }
while (
status == KEYMGR_OP_STATUS_STATUS_VALUE_WIP);
92 abs_mmio_write32(kBaseAddr + KEYMGR_OP_STATUS_REG_OFFSET, reg);
98 case KEYMGR_OP_STATUS_STATUS_VALUE_IDLE:
100 case KEYMGR_OP_STATUS_STATUS_VALUE_DONE_SUCCESS:
102 case KEYMGR_OP_STATUS_STATUS_VALUE_DONE_ERROR: {
105 abs_mmio_read32(kBaseAddr + KEYMGR_ERR_CODE_REG_OFFSET);
106 abs_mmio_write32(kBaseAddr + KEYMGR_ERR_CODE_REG_OFFSET, err_code);
107 return OTCRYPTO_RECOV_ERR;
113 return OTCRYPTO_FATAL_ERR;
125 #define WRITE_CTRL(dest, operation) \
128 bitfield_field32_write(0, KEYMGR_CONTROL_SHADOWED_DEST_SEL_FIELD, \
129 KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_##dest); \
130 ctrl = bitfield_bit32_write(ctrl, KEYMGR_CONTROL_SHADOWED_CDI_SEL_BIT, \
132 ctrl = bitfield_field32_write( \
133 ctrl, KEYMGR_CONTROL_SHADOWED_OPERATION_FIELD, \
134 KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_##operation##_OUTPUT); \
135 abs_mmio_write32_shadowed(kBaseAddr + KEYMGR_CONTROL_SHADOWED_REG_OFFSET, \
142 HARDENED_TRY(entropy_complex_check());
143 HARDENED_TRY(keymgr_is_idle());
146 WRITE_CTRL(NONE, GENERATE_SW);
149 keymgr_start(diversification);
150 HARDENED_TRY(keymgr_wait_until_done());
154 for (
size_t i = 0; i < kKeymgrOutputShareNumWords; i++) {
156 abs_mmio_read32(kBaseAddr + KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET +
157 (i *
sizeof(uint32_t)));
159 for (
size_t i = 0; i < kKeymgrOutputShareNumWords; i++) {
161 abs_mmio_read32(kBaseAddr + KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET +
162 (i *
sizeof(uint32_t)));
170 HARDENED_TRY(entropy_complex_check());
171 HARDENED_TRY(keymgr_is_idle());
174 WRITE_CTRL(AES, GENERATE_HW);
177 keymgr_start(diversification);
178 return keymgr_wait_until_done();
183 HARDENED_TRY(entropy_complex_check());
184 HARDENED_TRY(keymgr_is_idle());
187 WRITE_CTRL(KMAC, GENERATE_HW);
190 keymgr_start(diversification);
191 return keymgr_wait_until_done();
196 HARDENED_TRY(entropy_complex_check());
197 HARDENED_TRY(keymgr_is_idle());
200 WRITE_CTRL(OTBN, GENERATE_HW);
203 keymgr_start(diversification);
204 return keymgr_wait_until_done();
217 static status_t keymgr_sideload_clear(uint32_t slot) {
219 HARDENED_TRY(entropy_complex_check());
220 HARDENED_TRY(keymgr_is_idle());
224 kBaseAddr + KEYMGR_SIDELOAD_CLEAR_REG_OFFSET,
228 uint32_t sideload_clear =
229 abs_mmio_read32(kBaseAddr + KEYMGR_SIDELOAD_CLEAR_REG_OFFSET);
232 return OTCRYPTO_FATAL_ERR;
242 kBaseAddr + KEYMGR_SIDELOAD_CLEAR_REG_OFFSET,
244 KEYMGR_SIDELOAD_CLEAR_VAL_VALUE_NONE));
249 status_t keymgr_sideload_clear_aes(
void) {
250 return keymgr_sideload_clear(KEYMGR_SIDELOAD_CLEAR_VAL_VALUE_AES);
253 status_t keymgr_sideload_clear_kmac(
void) {
254 return keymgr_sideload_clear(KEYMGR_SIDELOAD_CLEAR_VAL_VALUE_KMAC);
257 status_t keymgr_sideload_clear_otbn(
void) {
258 return keymgr_sideload_clear(KEYMGR_SIDELOAD_CLEAR_VAL_VALUE_OTBN);