forked from wolfSSL/wolfssl
rsa.c:wc_CheckProbablePrime(): WOLFSSL_SMALL_STACK refactor
This commit is contained in:
@ -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
|
||||
|
Reference in New Issue
Block a user