5 #include "sw/device/lib/crypto/impl/rsa/rsa_modexp.h"
7 #include "sw/device/lib/crypto/drivers/otbn.h"
10 #define MODULE_ID MAKE_MODULE_ID('r', 'm', 'e')
22 static const otbn_addr_t kOtbnVarRsaMode =
26 static const otbn_addr_t kOtbnVarRsaInOut =
36 static const uint32_t kMode2048Modexp =
38 static const uint32_t kMode2048ModexpF4 =
40 static const uint32_t kMode3072Modexp =
42 static const uint32_t kMode3072ModexpF4 =
44 static const uint32_t kMode4096Modexp =
46 static const uint32_t kMode4096ModexpF4 =
59 status_t rsa_modexp_wait(
size_t *num_words) {
61 HARDENED_TRY(otbn_busy_wait_for_done());
65 HARDENED_TRY(otbn_dmem_read(1, kOtbnVarRsaMode, &mode));
68 if (mode == kMode2048Modexp || mode == kMode2048ModexpF4) {
69 *num_words = kRsa2048NumWords;
70 }
else if (mode == kMode3072Modexp || mode == kMode3072ModexpF4) {
71 *num_words = kRsa3072NumWords;
72 }
else if (mode == kMode4096Modexp || mode == kMode4096ModexpF4) {
73 *num_words = kRsa4096NumWords;
76 return OTCRYPTO_FATAL_ERR;
92 static status_t rsa_modexp_finalize(
const size_t num_words, uint32_t *result) {
94 size_t num_words_inferred;
95 HARDENED_TRY(rsa_modexp_wait(&num_words_inferred));
98 if (num_words != num_words_inferred) {
99 return OTCRYPTO_FATAL_ERR;
103 HARDENED_TRY(otbn_dmem_read(num_words, kOtbnVarRsaInOut, result));
106 return otbn_dmem_sec_wipe();
113 HARDENED_TRY(otbn_load_app(kOtbnAppRsaModexp));
116 uint32_t mode = kMode2048Modexp;
117 HARDENED_TRY(otbn_dmem_write(1, &mode, kOtbnVarRsaMode));
120 HARDENED_TRY(otbn_dmem_write(kRsa2048NumWords, base->data, kOtbnVarRsaInOut));
121 HARDENED_TRY(otbn_dmem_write(kRsa2048NumWords, modulus->data, kOtbnVarRsaN));
122 HARDENED_TRY(otbn_dmem_write(kRsa2048NumWords, exp->data, kOtbnVarRsaD));
125 return otbn_execute();
131 if (exp != kExponentF4) {
135 memset(exp_rsa.data, 0, kRsa2048NumWords *
sizeof(uint32_t));
136 exp_rsa.data[0] = exp;
137 return rsa_modexp_consttime_2048_start(base, &exp_rsa, modulus);
141 HARDENED_TRY(otbn_load_app(kOtbnAppRsaModexp));
144 uint32_t mode = kMode2048ModexpF4;
145 HARDENED_TRY(otbn_dmem_write(1, &mode, kOtbnVarRsaMode));
148 HARDENED_TRY(otbn_dmem_write(kRsa2048NumWords, base->data, kOtbnVarRsaInOut));
149 HARDENED_TRY(otbn_dmem_write(kRsa2048NumWords, modulus->data, kOtbnVarRsaN));
152 return otbn_execute();
156 return rsa_modexp_finalize(kRsa2048NumWords, result->data);
163 HARDENED_TRY(otbn_load_app(kOtbnAppRsaModexp));
166 uint32_t mode = kMode3072Modexp;
167 HARDENED_TRY(otbn_dmem_write(1, &mode, kOtbnVarRsaMode));
170 HARDENED_TRY(otbn_dmem_write(kRsa3072NumWords, base->data, kOtbnVarRsaInOut));
171 HARDENED_TRY(otbn_dmem_write(kRsa3072NumWords, modulus->data, kOtbnVarRsaN));
172 HARDENED_TRY(otbn_dmem_write(kRsa3072NumWords, exp->data, kOtbnVarRsaD));
175 return otbn_execute();
181 if (exp != kExponentF4) {
185 memset(exp_rsa.data, 0, kRsa3072NumWords *
sizeof(uint32_t));
186 exp_rsa.data[0] = exp;
187 return rsa_modexp_consttime_3072_start(base, &exp_rsa, modulus);
191 HARDENED_TRY(otbn_load_app(kOtbnAppRsaModexp));
194 uint32_t mode = kMode3072ModexpF4;
195 HARDENED_TRY(otbn_dmem_write(1, &mode, kOtbnVarRsaMode));
198 HARDENED_TRY(otbn_dmem_write(kRsa3072NumWords, base->data, kOtbnVarRsaInOut));
199 HARDENED_TRY(otbn_dmem_write(kRsa3072NumWords, modulus->data, kOtbnVarRsaN));
202 return otbn_execute();
206 return rsa_modexp_finalize(kRsa3072NumWords, result->data);
213 HARDENED_TRY(otbn_load_app(kOtbnAppRsaModexp));
216 uint32_t mode = kMode4096Modexp;
217 HARDENED_TRY(otbn_dmem_write(1, &mode, kOtbnVarRsaMode));
220 HARDENED_TRY(otbn_dmem_write(kRsa4096NumWords, base->data, kOtbnVarRsaInOut));
221 HARDENED_TRY(otbn_dmem_write(kRsa4096NumWords, modulus->data, kOtbnVarRsaN));
222 HARDENED_TRY(otbn_dmem_write(kRsa4096NumWords, exp->data, kOtbnVarRsaD));
225 return otbn_execute();
231 if (exp != kExponentF4) {
235 memset(exp_rsa.data, 0, kRsa4096NumWords *
sizeof(uint32_t));
236 exp_rsa.data[0] = exp;
237 return rsa_modexp_consttime_4096_start(base, &exp_rsa, modulus);
241 HARDENED_TRY(otbn_load_app(kOtbnAppRsaModexp));
244 uint32_t mode = kMode4096ModexpF4;
245 HARDENED_TRY(otbn_dmem_write(1, &mode, kOtbnVarRsaMode));
248 HARDENED_TRY(otbn_dmem_write(kRsa4096NumWords, base->data, kOtbnVarRsaInOut));
249 HARDENED_TRY(otbn_dmem_write(kRsa4096NumWords, modulus->data, kOtbnVarRsaN));
252 return otbn_execute();
256 return rsa_modexp_finalize(kRsa4096NumWords, result->data);