diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 36b0e30ec..2439d5fe5 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -3952,30 +3952,49 @@ int wc_CheckProbablePrime(const byte* pRaw, word32 pRawSz, int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) { #ifndef WC_NO_RNG - mp_int p, q, tmp1, tmp2, tmp3; +#ifdef WOLFSSL_SMALL_STACK + mp_int *p = (mp_int *)XMALLOC(sizeof *p, key->heap, DYNAMIC_TYPE_RSA), + *q = (mp_int *)XMALLOC(sizeof *q, key->heap, DYNAMIC_TYPE_RSA), + *tmp1 = (mp_int *)XMALLOC(sizeof *tmp1, key->heap, DYNAMIC_TYPE_RSA), + *tmp2 = (mp_int *)XMALLOC(sizeof *tmp2, key->heap, DYNAMIC_TYPE_RSA), + *tmp3 = (mp_int *)XMALLOC(sizeof *tmp3, key->heap, DYNAMIC_TYPE_RSA); +#else + mp_int p_buf, *p = &p_buf, + q_buf, *q = &q_buf, + tmp1_buf, *tmp1 = &tmp1_buf, + tmp2_buf, *tmp2 = &tmp2_buf, + tmp3_buf, *tmp3 = &tmp3_buf; +#endif int err, i, failCount, primeSz, isPrime = 0; byte* buf = NULL; - if (key == NULL || rng == NULL) - return BAD_FUNC_ARG; + if (key == NULL || rng == NULL) { + err = BAD_FUNC_ARG; + goto out; + } - if (!RsaSizeCheck(size)) - return BAD_FUNC_ARG; + if (!RsaSizeCheck(size)) { + err = BAD_FUNC_ARG; + goto out; + } - if (e < 3 || (e & 1) == 0) - return BAD_FUNC_ARG; + if (e < 3 || (e & 1) == 0) { + err = BAD_FUNC_ARG; + goto out; + } #if defined(WOLFSSL_CRYPTOCELL) - return cc310_RSA_GenerateKeyPair(key, size, e); + err = cc310_RSA_GenerateKeyPair(key, size, e); + goto out; #endif /*WOLFSSL_CRYPTOCELL*/ #ifdef WOLF_CRYPTO_CB if (key->devId != INVALID_DEVID) { - int ret = wc_CryptoCb_MakeRsaKey(key, size, e, rng); - if (ret != CRYPTOCB_UNAVAILABLE) - return ret; + err = wc_CryptoCb_MakeRsaKey(key, size, e, rng); + if (err != CRYPTOCB_UNAVAILABLE) + goto out; /* fall-through when unavailable */ } #endif @@ -3986,7 +4005,8 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) #ifdef HAVE_CAVIUM /* TODO: Not implemented */ #elif defined(HAVE_INTEL_QA) - return IntelQaRsaKeyGen(&key->asyncDev, key, size, e, rng); + err = IntelQaRsaKeyGen(&key->asyncDev, key, size, e, rng); + goto out; #else if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_RSA_MAKE)) { WC_ASYNC_TEST* testDev = &key->asyncDev.test; @@ -3994,16 +4014,17 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) testDev->rsaMake.key = key; testDev->rsaMake.size = size; testDev->rsaMake.e = e; - return WC_PENDING_E; + err = WC_PENDING_E; + goto out; } #endif } #endif - err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL); + err = mp_init_multi(p, q, tmp1, tmp2, tmp3, NULL); if (err == MP_OKAY) - err = mp_set_int(&tmp3, e); + err = mp_set_int(tmp3, e); /* The failCount value comes from NIST FIPS 186-4, section B.3.3, * process steps 4.7 and 5.8. */ @@ -4035,11 +4056,11 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) /* make candidate odd */ buf[primeSz-1] |= 0x01; /* load value */ - err = mp_read_unsigned_bin(&p, buf, primeSz); + err = mp_read_unsigned_bin(p, buf, primeSz); } if (err == MP_OKAY) - err = _CheckProbablePrime(&p, NULL, &tmp3, size, &isPrime, rng); + err = _CheckProbablePrime(p, NULL, tmp3, size, &isPrime, rng); #ifdef HAVE_FIPS i++; @@ -4070,11 +4091,11 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) /* make candidate odd */ buf[primeSz-1] |= 0x01; /* load value */ - err = mp_read_unsigned_bin(&q, buf, primeSz); + err = mp_read_unsigned_bin(q, buf, primeSz); } if (err == MP_OKAY) - err = _CheckProbablePrime(&p, &q, &tmp3, size, &isPrime, rng); + err = _CheckProbablePrime(p, q, tmp3, size, &isPrime, rng); #ifdef HAVE_FIPS i++; @@ -4093,12 +4114,12 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) XFREE(buf, key->heap, DYNAMIC_TYPE_RSA); } - if (err == MP_OKAY && mp_cmp(&p, &q) < 0) { - err = mp_copy(&p, &tmp1); + if (err == MP_OKAY && mp_cmp(p, q) < 0) { + err = mp_copy(p, tmp1); if (err == MP_OKAY) - err = mp_copy(&q, &p); + err = mp_copy(q, p); if (err == MP_OKAY) - mp_copy(&tmp1, &q); + mp_copy(tmp1, q); } /* Setup RsaKey buffers */ @@ -4109,15 +4130,15 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) /* Software Key Calculation */ if (err == MP_OKAY) /* tmp1 = p-1 */ - err = mp_sub_d(&p, 1, &tmp1); + err = mp_sub_d(p, 1, tmp1); if (err == MP_OKAY) /* tmp2 = q-1 */ - err = mp_sub_d(&q, 1, &tmp2); + err = mp_sub_d(q, 1, tmp2); #ifdef WC_RSA_BLINDING if (err == MP_OKAY) /* tmp3 = order of n */ - err = mp_mul(&tmp1, &tmp2, &tmp3); + err = mp_mul(tmp1, tmp2, tmp3); #else if (err == MP_OKAY) /* tmp3 = lcm(p-1, q-1), last loop */ - err = mp_lcm(&tmp1, &tmp2, &tmp3); + err = mp_lcm(tmp1, tmp2, tmp3); #endif /* make key */ if (err == MP_OKAY) /* key->e = e */ @@ -4126,13 +4147,13 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) /* Blind the inverse operation with a value that is invertable */ if (err == MP_OKAY) { do { - err = mp_rand(&key->p, get_digit_count(&tmp3), rng); + err = mp_rand(&key->p, get_digit_count(tmp3), rng); if (err == MP_OKAY) err = mp_set_bit(&key->p, 0); if (err == MP_OKAY) err = mp_set_bit(&key->p, size - 1); if (err == MP_OKAY) - err = mp_gcd(&key->p, &tmp3, &key->q); + err = mp_gcd(&key->p, tmp3, &key->q); } while ((err == MP_OKAY) && !mp_isone(&key->q)); } @@ -4140,33 +4161,33 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) err = mp_mul_d(&key->p, (mp_digit)e, &key->e); #endif if (err == MP_OKAY) /* key->d = 1/e mod lcm(p-1, q-1) */ - err = mp_invmod(&key->e, &tmp3, &key->d); + err = mp_invmod(&key->e, tmp3, &key->d); #ifdef WC_RSA_BLINDING /* Take off blinding from d and reset e */ if (err == MP_OKAY) - err = mp_mulmod(&key->d, &key->p, &tmp3, &key->d); + err = mp_mulmod(&key->d, &key->p, tmp3, &key->d); if (err == MP_OKAY) err = mp_set_int(&key->e, (mp_digit)e); #endif if (err == MP_OKAY) /* key->n = pq */ - err = mp_mul(&p, &q, &key->n); + err = mp_mul(p, q, &key->n); if (err == MP_OKAY) /* key->dP = d mod(p-1) */ - err = mp_mod(&key->d, &tmp1, &key->dP); + err = mp_mod(&key->d, tmp1, &key->dP); if (err == MP_OKAY) /* key->dQ = d mod(q-1) */ - err = mp_mod(&key->d, &tmp2, &key->dQ); + err = mp_mod(&key->d, tmp2, &key->dQ); #ifdef WOLFSSL_MP_INVMOD_CONSTANT_TIME if (err == MP_OKAY) /* key->u = 1/q mod p */ - err = mp_invmod(&q, &p, &key->u); + err = mp_invmod(q, p, &key->u); #else if (err == MP_OKAY) - err = mp_sub_d(&p, 2, &tmp3); + err = mp_sub_d(p, 2, tmp3); if (err == MP_OKAY) /* key->u = 1/q mod p = q^p-2 mod p */ - err = mp_exptmod(&q, &tmp3 , &p, &key->u); + err = mp_exptmod(q, tmp3 , p, &key->u); #endif if (err == MP_OKAY) - err = mp_copy(&p, &key->p); + err = mp_copy(p, &key->p); if (err == MP_OKAY) - err = mp_copy(&q, &key->q); + err = mp_copy(q, &key->q); #ifdef HAVE_WOLF_BIGINT /* make sure raw unsigned bin version is available */ @@ -4191,11 +4212,11 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) if (err == MP_OKAY) key->type = RSA_PRIVATE; - mp_clear(&tmp1); - mp_clear(&tmp2); - mp_clear(&tmp3); - mp_clear(&p); - mp_clear(&q); + mp_clear(tmp1); + mp_clear(tmp2); + mp_clear(tmp3); + mp_clear(p); + mp_clear(q); #if defined(WOLFSSL_KEY_GEN) && !defined(WOLFSSL_NO_RSA_KEY_CHECK) /* Perform the pair-wise consistency test on the new key. */ @@ -4205,7 +4226,7 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) if (err != 0) { wc_FreeRsaKey(key); - return err; + goto out; } #if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL) @@ -4213,7 +4234,25 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) return BAD_STATE_E; } #endif - return 0; + + err = 0; + + out: + +#ifdef WOLFSSL_SMALL_STACK + if (p) + XFREE(p, key->heap, DYNAMIC_TYPE_RSA); + if (q) + XFREE(q, key->heap, DYNAMIC_TYPE_RSA); + if (tmp1) + XFREE(tmp1, key->heap, DYNAMIC_TYPE_RSA); + if (tmp2) + XFREE(tmp2, key->heap, DYNAMIC_TYPE_RSA); + if (tmp3) + XFREE(tmp3, key->heap, DYNAMIC_TYPE_RSA); +#endif + + return err; #else return NOT_COMPILED_IN; #endif