diff options
Diffstat (limited to 'rsa.c')
-rw-r--r-- | rsa.c | 90 |
1 files changed, 52 insertions, 38 deletions
@@ -473,20 +473,13 @@ static hal_error_t modexpng(hal_core_t *core, .dP = dP_buf, .dP_len = sizeof(dP_buf), .dQ = dQ_buf, .dQ_len = sizeof(dQ_buf), .qInv = u_buf, .qInv_len = sizeof(u_buf), - .bf = bf_buf, .bf_len = sizeof(bf_buf), - .ubf = ubf_buf, .ubf_len = sizeof(ubf_buf), }; if (bf) { - if ((err = unpack_fp(bf, bf_buf, sizeof(bf_buf))) != HAL_OK || - (err = unpack_fp(ubf, ubf_buf, sizeof(ubf_buf))) != HAL_OK) + if ((err = unpack_fp(bf, (args.bf = bf_buf), (args.bf_len = sizeof(bf_buf)))) != HAL_OK || + (err = unpack_fp(ubf, (args.ubf = ubf_buf), (args.ubf_len = sizeof(ubf_buf)))) != HAL_OK) goto fail; } - else { - /* set blinding factors to (1,1) */ - memset(bf_buf, 0, sizeof(bf_buf)); bf_buf[sizeof(bf_buf) - 1] = 1; - memset(ubf_buf, 0, sizeof(ubf_buf)); ubf_buf[sizeof(ubf_buf) - 1] = 1; - } if ((err = unpack_fp(msg, msgbuf, sizeof(msgbuf))) != HAL_OK || (err = unpack_fp(key->d, expbuf, sizeof(expbuf))) != HAL_OK || @@ -499,10 +492,11 @@ static hal_error_t modexpng(hal_core_t *core, (err = hal_modexpng(&args)) != HAL_OK) goto fail; - fp_read_unsigned_bin(res, resbuf, sizeof(resbuf)); - /* we do the blinding factor mutation in create_blinding_factors, - * so we don't need to read them back from the core - */ + fp_read_unsigned_bin(res, resbuf, sizeof(resbuf)); + if (bf) { + fp_read_unsigned_bin(bf, bf_buf, sizeof(bf_buf)); + fp_read_unsigned_bin(ubf, ubf_buf, sizeof(ubf_buf)); + } fail: memset(msgbuf, 0, sizeof(msgbuf)); @@ -620,14 +614,16 @@ int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d) /* * Create blinding factors. + * + * If there is no blinding cache, bf and ubf point to user-supplied fp_ints. + * If there is a blinding cache, this returns pointers to a cache entry. */ -static hal_error_t create_blinding_factors(hal_rsa_key_t *key, fp_int *bf, fp_int *ubf) +static hal_error_t create_blinding_factors(hal_rsa_key_t *key, fp_int **bf, fp_int **ubf) { if (key == NULL || bf == NULL || ubf == NULL) return HAL_ERROR_IMPOSSIBLE; - const int precalc = !(key->flags & RSA_FLAG_PRECALC_N_DONE); uint8_t rnd[fp_unsigned_bin_size(unconst_fp_int(key->n))]; hal_error_t err = HAL_OK; @@ -645,43 +641,53 @@ static hal_error_t create_blinding_factors(hal_rsa_key_t *key, fp_int *bf, fp_in best_index = i; } if (fp_cmp_mag(b->n, key->n) == FP_EQ) { - if (fp_sqrmod(b->bf, key->n, b->bf) != FP_OKAY || - fp_sqrmod(b->ubf, key->n, b->ubf) != FP_OKAY) + /* + * ModExpNG does blinding factor mutation in hardware. + * ModExpA7 needs it done in software here. + */ + if (!hal_modexp_using_modexpng() && + (fp_sqrmod(b->bf, key->n, b->bf) != FP_OKAY || + fp_sqrmod(b->ubf, key->n, b->ubf) != FP_OKAY)) continue; /* should never happen, but be safe */ - fp_copy(b->bf, bf); - fp_copy(b->ubf, ubf); + *bf = b->bf; + *ubf = b->ubf; err = HAL_OK; goto fail; } } + + /* Didn't find the modulus in the cache, so create a new cache entry. */ + { + bfc_slot_t *b = &bfc.slot[best_index]; + fp_copy(key->n, b->n); + b->lru = ++bfc.lru; + *bf = b->bf; + *ubf = b->ubf; + } +#else + if (*bf == NULL || *ubf == NULL) + lose(HAL_ERROR_BAD_ARGUMENTS); #endif if ((err = hal_get_random(NULL, rnd, sizeof(rnd))) != HAL_OK) goto fail; - fp_init(bf); - fp_read_unsigned_bin(bf, rnd, sizeof(rnd)); - fp_copy(bf, ubf); + fp_init(*bf); + fp_read_unsigned_bin(*bf, rnd, sizeof(rnd)); + fp_copy(*bf, *ubf); + + const int precalc = !(key->flags & RSA_FLAG_PRECALC_N_DONE); /* bf = ubf ** e mod n */ - if ((err = modexp(NULL, precalc, bf, key->e, key->n, bf, + if ((err = modexp(NULL, precalc, *bf, key->e, key->n, *bf, key->nC, sizeof(key->nC), key->nF, sizeof(key->nF))) != HAL_OK) goto fail; if (precalc) key->flags |= RSA_FLAG_PRECALC_N_DONE | RSA_FLAG_NEEDS_SAVING; - FP_CHECK(fp_invmod(ubf, unconst_fp_int(key->n), ubf)); - -#if HAL_RSA_BLINDING_CACHE_SIZE > 0 - { - bfc_slot_t *b = &bfc.slot[best_index]; - fp_copy(key->n, b->n); - fp_copy(bf, b->bf); - fp_copy(ubf, b->ubf); - b->lru = ++bfc.lru; - } -#endif + /* ubf = ubf ** -1 mod n */ + FP_CHECK(fp_invmod(*ubf, unconst_fp_int(key->n), *ubf)); fail: hal_rsa_bf_unlock(); @@ -699,12 +705,16 @@ static hal_error_t rsa_crt(hal_core_t *core1, hal_core_t *core2, hal_rsa_key_t * return HAL_ERROR_IMPOSSIBLE; hal_error_t err = HAL_OK; - fp_int bf[1] = INIT_FP_INT; - fp_int ubf[1] = INIT_FP_INT; +#if HAL_RSA_BLINDING_CACHE_SIZE > 0 + fp_int *bf, *ubf; +#else + fp_int _bf[1] = INIT_FP_INT, *bf = _bf; + fp_int _ubf[1] = INIT_FP_INT, *ubf = _ubf; +#endif if (hal_modexp_using_modexpng()) { if (blinding) { - if ((err = create_blinding_factors(key, bf, ubf)) != HAL_OK) + if ((err = create_blinding_factors(key, &bf, &ubf)) != HAL_OK) return err; return modexpng(core1, msg, key, bf, ubf, sig); } @@ -713,6 +723,10 @@ static hal_error_t rsa_crt(hal_core_t *core1, hal_core_t *core2, hal_rsa_key_t * } } + /* + * ModExpA7 from here down + */ + const int precalc = !(key->flags & RSA_FLAG_PRECALC_PQ_DONE); fp_int t[1] = INIT_FP_INT; fp_int m1[1] = INIT_FP_INT; @@ -722,7 +736,7 @@ static hal_error_t rsa_crt(hal_core_t *core1, hal_core_t *core2, hal_rsa_key_t * * Handle blinding if requested. */ if (blinding) { - if ((err = create_blinding_factors(key, bf, ubf)) != HAL_OK) + if ((err = create_blinding_factors(key, &bf, &ubf)) != HAL_OK) goto fail; /* msg = (msg * bf) % modulus */ FP_CHECK(fp_mulmod(msg, bf, unconst_fp_int(key->n), msg)); |