28 #pragma GCC diagnostic push
29 #pragma GCC diagnostic ignored "-Wcast-qual"
31 static cx_err_t modulus_valid(
size_t modulus_len)
33 switch (modulus_len) {
40 return CX_INVALID_PARAMETER;
44 cx_err_t cx_rsa_private_key_ctx_size(
const cx_rsa_private_key_t *key,
size_t *size)
48 *size =
sizeof(cx_rsa_1024_private_key_t);
51 *size =
sizeof(cx_rsa_2048_private_key_t);
54 *size =
sizeof(cx_rsa_3072_private_key_t);
57 *size =
sizeof(cx_rsa_4096_private_key_t);
60 return CX_INVALID_PARAMETER;
66 cx_err_t cx_rsa_get_public_components(
const cx_rsa_public_key_t *key,
uint8_t **e,
uint8_t **n)
70 *e = ((cx_rsa_1024_public_key_t *) key)->e;
71 *n = ((cx_rsa_1024_public_key_t *) key)->n;
74 *e = ((cx_rsa_2048_public_key_t *) key)->e;
75 *n = ((cx_rsa_2048_public_key_t *) key)->n;
78 *e = ((cx_rsa_3072_public_key_t *) key)->e;
79 *n = ((cx_rsa_3072_public_key_t *) key)->n;
82 *e = ((cx_rsa_4096_public_key_t *) key)->e;
83 *n = ((cx_rsa_4096_public_key_t *) key)->n;
86 return CX_INVALID_PARAMETER;
91 cx_err_t cx_rsa_get_private_components(
const cx_rsa_private_key_t *key,
uint8_t **d,
uint8_t **n)
95 *d = ((cx_rsa_1024_private_key_t *) key)->d;
96 *n = ((cx_rsa_1024_private_key_t *) key)->n;
99 *d = ((cx_rsa_2048_private_key_t *) key)->d;
100 *n = ((cx_rsa_2048_private_key_t *) key)->n;
103 *d = ((cx_rsa_3072_private_key_t *) key)->d;
104 *n = ((cx_rsa_3072_private_key_t *) key)->n;
107 *d = ((cx_rsa_4096_private_key_t *) key)->d;
108 *n = ((cx_rsa_4096_private_key_t *) key)->n;
111 return CX_INVALID_PARAMETER;
116 cx_err_t cx_rsa_init_public_key_no_throw(
const uint8_t *exponent,
120 cx_rsa_public_key_t *key)
126 if (!(((exponent == NULL) && (exponent_len == 0)) || ((exponent) && (exponent_len <= 4)))) {
127 return CX_INVALID_PARAMETER;
129 if (!(((modulus == NULL) && (modulus_len == 0)) || (modulus))) {
130 return CX_INVALID_PARAMETER;
133 return CX_INVALID_PARAMETER;
136 CX_CHECK(modulus_valid(modulus_len));
137 key->size = modulus_len;
139 CX_CHECK(cx_rsa_get_public_components(key, &e, &n));
141 if (modulus && exponent) {
143 memmove(e + (4 - exponent_len), exponent, exponent_len);
144 memmove(n, modulus, modulus_len);
147 memset(n, 0, modulus_len);
155 cx_err_t cx_rsa_init_private_key_no_throw(
const uint8_t *exponent,
159 cx_rsa_private_key_t *key)
165 if (!(((exponent == NULL) && (exponent_len == 0)) || (exponent))) {
166 return CX_INVALID_PARAMETER;
168 if (!(((modulus == NULL) && (modulus_len == 0)) || (modulus))) {
169 return CX_INVALID_PARAMETER;
171 if (exponent_len != modulus_len) {
172 return CX_INVALID_PARAMETER;
175 return CX_INVALID_PARAMETER;
178 CX_CHECK(modulus_valid(modulus_len));
179 key->size = modulus_len;
181 CX_CHECK(cx_rsa_get_private_components(key, &d, &n));
183 if (modulus && exponent) {
184 memmove(d, exponent, modulus_len);
185 memmove(n, modulus, modulus_len);
188 memset(d, 0, modulus_len);
189 memset(n, 0, modulus_len);
196 static const uint8_t C_default_e[] = {0x00, 0x01, 0x00, 0x01};
198 cx_err_t cx_rsa_generate_pair_no_throw(
size_t modulus_len,
199 cx_rsa_public_key_t *public_key,
200 cx_rsa_private_key_t *private_key,
205 cx_bn_t bn_p, bn_q, bn_n;
213 if (!(((exponent == NULL) && (exponent_len == 0)) || ((exponent) && (exponent_len <= 4)))) {
214 return CX_INVALID_PARAMETER;
216 if (!((public_key != NULL) && (private_key != NULL))) {
217 return CX_INVALID_PARAMETER;
220 CX_CHECK(modulus_valid(modulus_len));
222 private_key->size = modulus_len;
223 public_key->size = modulus_len;
224 CX_CHECK(cx_rsa_get_private_components(private_key, &pv_d, &pv_n));
225 CX_CHECK(cx_rsa_get_public_components(public_key, &pu_e, &pu_n));
227 size = modulus_len / 2;
229 CX_CHECK(cx_bn_lock(size, 0));
230 CX_CHECK(cx_bn_alloc(&bn_p, size));
231 CX_CHECK(cx_bn_alloc(&bn_q, size));
234 CX_CHECK(cx_bn_init(bn_p, externalPQ, size));
235 CX_CHECK(cx_bn_init(bn_q, externalPQ + size, size));
238 CX_CHECK(cx_bn_rand(bn_p));
239 CX_CHECK(cx_bn_set_bit(bn_p, size * 8 - 1));
240 CX_CHECK(cx_bn_set_bit(bn_p, size * 8 - 2));
241 CX_CHECK(cx_bn_rand(bn_q));
242 CX_CHECK(cx_bn_set_bit(bn_q, size * 8 - 1));
243 CX_CHECK(cx_bn_set_bit(bn_q, size * 8 - 2));
244 CX_CHECK(cx_bn_next_prime(bn_p));
245 CX_CHECK(cx_bn_next_prime(bn_q));
249 CX_CHECK(cx_bn_alloc(&bn_n, modulus_len));
250 CX_CHECK(cx_bn_mul(bn_n, bn_p, bn_q));
251 CX_CHECK(cx_bn_export(bn_n, pu_n, modulus_len));
252 if (exponent == NULL) {
253 exponent = C_default_e;
254 exponent_len =
sizeof(C_default_e);
256 memmove(pu_e + (4 - exponent_len), exponent, exponent_len);
257 CX_CHECK(cx_bn_destroy(&bn_n));
261 CX_CHECK(cx_bn_alloc(&bn_n, size));
262 CX_CHECK(cx_bn_set_u32(bn_n, 1));
263 CX_CHECK_IGNORE_CARRY(cx_bn_sub(bn_p, bn_p, bn_n));
264 CX_CHECK_IGNORE_CARRY(cx_bn_sub(bn_q, bn_q, bn_n));
265 CX_CHECK(cx_bn_destroy(&bn_n));
266 CX_CHECK(cx_bn_alloc(&bn_n, modulus_len));
267 CX_CHECK(cx_bn_mul(bn_n, bn_p, bn_q));
268 CX_CHECK(cx_bn_destroy(&bn_p));
269 CX_CHECK(cx_bn_destroy(&bn_q));
271 CX_CHECK(cx_bn_alloc(&bn_p, modulus_len));
272 CX_CHECK(cx_bn_mod_u32_invert(
273 bn_p, (pu_e[0] << 24) | (pu_e[1] << 16) | (pu_e[2] << 8) | (pu_e[3] << 0), bn_n));
274 CX_CHECK(cx_bn_export(bn_p, pv_d, modulus_len));
275 memmove(pv_n, pu_n, modulus_len);
282 cx_err_t cx_rsa_sign_with_salt_len(
const cx_rsa_private_key_t *key,
293 cx_bn_t bn_n, bn_msg, bn_r;
298 if (!(hash && (hash_len <= key->size))) {
299 return CX_INVALID_PARAMETER;
301 if (!(sig && (sig_len >= key->size))) {
302 return CX_INVALID_PARAMETER;
305 CX_CHECK(cx_rsa_get_private_components(key, &key_d, &key_n));
306 CX_CHECK(cx_bn_lock(key->size, 0));
307 CX_CHECK(cx_bn_alloc(&bn_r, key->size));
308 CX_CHECK(cx_bn_alloc_init(&bn_n, key->size, key_n, key->size));
314 CX_CHECK(cx_pkcs1_emsa_v1o5_encode(hashID, sig, sig_len, hash, hash_len));
317 CX_CHECK(cx_bn_cnt_bits(bn_n, &nbits));
318 CX_CHECK(cx_pkcs1_emsa_pss_encode_with_salt_len(
319 hashID, sig, nbits - 1, hash, hash_len, salt_len, &sig_len));
322 error = CX_INVALID_PARAMETER;
327 CX_CHECK(cx_bn_alloc_init(&bn_msg, key->size, sig, sig_len));
328 CX_CHECK(cx_bn_mod_pow2(bn_r, bn_msg, key_d, key->size, bn_n));
329 CX_CHECK(cx_bn_export(bn_r, sig, key->size));
336 cx_err_t cx_rsa_sign_no_throw(
const cx_rsa_private_key_t *key,
344 size_t output_hash_len = cx_pkcs1_get_hash_len(hashID);
345 return cx_rsa_sign_with_salt_len(
346 key, mode, hashID, hash, hash_len, sig, sig_len, output_hash_len);
349 bool cx_rsa_verify_with_salt_len(
const cx_rsa_public_key_t *key,
361 cx_bn_t bn_n, bn_msg, bn_r;
365 if (hash == NULL || hash_len > key->size) {
368 if (sig == NULL || sig_len != key->size) {
375 CX_CHECK(cx_rsa_get_public_components(key, &key_e, &key_n));
376 CX_CHECK(cx_bn_lock(key->size, 0));
377 CX_CHECK(cx_bn_alloc(&bn_r, key->size));
378 CX_CHECK(cx_bn_alloc_init(&bn_n, key->size, key_n, key->size));
379 CX_CHECK(cx_bn_alloc_init(&bn_msg, key->size, sig, sig_len));
380 CX_CHECK(cx_bn_mod_pow2(bn_r, bn_msg, key_e, 4, bn_n));
381 CX_CHECK(cx_bn_export(bn_r, sig, sig_len));
386 ok = cx_pkcs1_emsa_v1o5_verify(hashID, sig, sig_len, hash, hash_len);
389 CX_CHECK(cx_bn_cnt_bits(bn_n, &nbits));
390 ok = cx_pkcs1_emsa_pss_verify_with_salt_len(
391 hashID, sig, nbits - 1, hash, hash_len, salt_len);
394 error = CX_INVALID_PARAMETER;
400 return error == CX_OK && ok;
403 bool cx_rsa_verify(
const cx_rsa_public_key_t *key,
411 size_t output_hash_len = cx_pkcs1_get_hash_len(hashID);
412 return cx_rsa_verify_with_salt_len(
413 key, mode, hashID, hash, hash_len, sig, sig_len, output_hash_len);
416 cx_err_t cx_rsa_encrypt_no_throw(
const cx_rsa_public_key_t *key,
426 cx_bn_t bn_n, bn_msg, bn_r;
430 if (!(mesg && (mesg_len <= key->size))) {
431 return CX_INVALID_PARAMETER;
433 if (!(enc && (enc_len >= key->size))) {
434 return CX_INVALID_PARAMETER;
441 CX_CHECK(cx_pkcs1_eme_v1o5_encode(hashID, enc, enc_len, mesg, mesg_len));
445 CX_CHECK(cx_pkcs1_eme_oaep_encode(hashID, enc, enc_len, mesg, mesg_len));
448 memmove(enc, mesg, mesg_len);
452 error = CX_INVALID_PARAMETER;
457 CX_CHECK(cx_rsa_get_public_components(key, &key_e, &key_n));
458 CX_CHECK(cx_bn_lock(key->size, 0));
459 CX_CHECK(cx_bn_alloc(&bn_r, key->size));
460 CX_CHECK(cx_bn_alloc_init(&bn_n, key->size, key_n, key->size));
461 CX_CHECK(cx_bn_alloc_init(&bn_msg, key->size, enc, enc_len));
462 CX_CHECK(cx_bn_mod_pow2(bn_r, bn_msg, key_e, 4, bn_n));
463 CX_CHECK(cx_bn_export(bn_r, enc, key->size));
469 cx_err_t cx_rsa_decrypt_no_throw(
const cx_rsa_private_key_t *key,
479 cx_bn_t bn_n, bn_msg, bn_r;
484 if (!(mesg && (mesg_len == key->size))) {
485 return CX_INVALID_PARAMETER;
487 if (!(dec && (*dec_len >= key->size))) {
488 return CX_INVALID_PARAMETER;
492 CX_CHECK(cx_rsa_get_private_components(key, &key_d, &key_n));
493 CX_CHECK(cx_bn_lock(key->size, 0));
494 CX_CHECK(cx_bn_alloc(&bn_r, key->size));
495 CX_CHECK(cx_bn_alloc_init(&bn_n, key->size, key_n, key->size));
496 CX_CHECK(cx_bn_alloc_init(&bn_msg, key->size, mesg, mesg_len));
500 CX_CHECK(cx_bn_cmp(bn_msg, bn_n, &diff));
502 error = CX_INVALID_PARAMETER;
506 CX_CHECK(cx_bn_mod_pow2(bn_r, bn_msg, key_d, key->size, bn_n));
507 CX_CHECK(cx_bn_export(bn_r, dec, key->size));
512 *dec_len = cx_pkcs1_eme_v1o5_decode(hashID, dec, key->size, dec, *dec_len);
515 CX_CHECK(cx_pkcs1_eme_oaep_decode(hashID, dec, key->size, dec, dec_len));
518 *dec_len = key->size;
521 error = CX_INVALID_PARAMETER;
530 #pragma GCC diagnostic pop
#define CX_PAD_PKCS1_OAEP