From 997a3773103c22f5b626ba9ee20faefc30b6aad8 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 12 Jul 2018 14:58:19 -0700 Subject: [PATCH] Prime Number Testing 1. In wc_DhGenerateParams(), changed the call to mp_prime_is_prime() to mp_prime_is_prime_ex(). 2. In wc_MakeDsaParameters(), changed the call to mp_prime_is_prime() to mp_prime_is_prime_ex(). 3. Added wc_CheckProbablePrime_ex in RSA that also takes an RNG to call mp_prime_is_prime_ex(). If RNG is NULL, call mp_prime_is_prime(). 4. Rewrite wc_CheckProbablePrime() in terms of wc_CheckProbablePrime_ex(). --- wolfcrypt/src/dh.c | 2 +- wolfcrypt/src/dsa.c | 2 +- wolfcrypt/src/rsa.c | 40 ++++++++++++++++++++++++++++------------ wolfssl/wolfcrypt/rsa.h | 4 ++++ 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index 50680e4fc..d541b6862 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -1900,7 +1900,7 @@ int wc_DhGenerateParams(WC_RNG *rng, int modSz, DhKey *dh) /* loop until p is prime */ if (ret == 0) { do { - if (mp_prime_is_prime(&dh->p, 8, &primeCheck) != MP_OKAY) + if (mp_prime_is_prime_ex(&dh->p, 8, &primeCheck, rng) != MP_OKAY) ret = PRIME_GEN_E; if (primeCheck != MP_YES) { diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 86d601560..18970489a 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -337,7 +337,7 @@ int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa) /* loop until p is prime */ while (check_prime == MP_NO) { - err = mp_prime_is_prime(&dsa->p, 8, &check_prime); + err = mp_prime_is_prime_ex(&dsa->p, 8, &check_prime, rng); if (err != MP_OKAY) { mp_clear(&dsa->q); mp_clear(&dsa->p); diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 7ef917f5c..9eaf1fe6a 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -2641,8 +2641,8 @@ static WC_INLINE int RsaSizeCheck(int size) } -static int wc_CheckProbablePrime_ex(mp_int* p, mp_int* q, mp_int* e, int nlen, - int* isPrime) +static int _CheckProbablePrime(mp_int* p, mp_int* q, mp_int* e, int nlen, + int* isPrime, WC_RNG* rng) { int ret; mp_int tmp1, tmp2; @@ -2683,10 +2683,17 @@ static int wc_CheckProbablePrime_ex(mp_int* p, mp_int* q, mp_int* e, int nlen, ret = mp_cmp_d(&tmp2, 1); if (ret != MP_EQ) goto exit; /* e divides p-1 */ - /* 4.5.1,5.6.1 - Check primality of p with 8 iterations */ - ret = mp_prime_is_prime(prime, 8, isPrime); - /* Performs some divides by a table of primes, and then does M-R, - * it sets isPrime as a side-effect. */ + /* 4.5.1,5.6.1 - Check primality of p with 8 rounds of M-R. + * mp_prime_is_prime_ex() performs test divisons against the first 256 + * prime numbers. After that it performs 8 rounds of M-R using random + * bases between 2 and n-2. + * mp_prime_is_prime() performs the same test divisions and then does + * M-R with the first 8 primes. Both functions set isPrime as a + * side-effect. */ + if (rng != NULL) + ret = mp_prime_is_prime_ex(prime, 8, isPrime, rng); + else + ret = mp_prime_is_prime(prime, 8, isPrime); if (ret != MP_OKAY) goto notOkay; exit: @@ -2698,11 +2705,10 @@ notOkay: } - -int wc_CheckProbablePrime(const byte* pRaw, word32 pRawSz, +int wc_CheckProbablePrime_ex(const byte* pRaw, word32 pRawSz, const byte* qRaw, word32 qRawSz, const byte* eRaw, word32 eRawSz, - int nlen, int* isPrime) + int nlen, int* isPrime, WC_RNG* rng) { mp_int p, q, e; mp_int* Q = NULL; @@ -2735,7 +2741,7 @@ int wc_CheckProbablePrime(const byte* pRaw, word32 pRawSz, ret = mp_read_unsigned_bin(&e, eRaw, eRawSz); if (ret == MP_OKAY) - ret = wc_CheckProbablePrime_ex(&p, Q, &e, nlen, isPrime); + ret = _CheckProbablePrime(&p, Q, &e, nlen, isPrime, rng); ret = (ret == MP_OKAY) ? 0 : PRIME_GEN_E; @@ -2747,6 +2753,16 @@ int wc_CheckProbablePrime(const byte* pRaw, word32 pRawSz, } +int wc_CheckProbablePrime(const byte* pRaw, word32 pRawSz, + const byte* qRaw, word32 qRawSz, + const byte* eRaw, word32 eRawSz, + int nlen, int* isPrime) +{ + return wc_CheckProbablePrime_ex(pRaw, pRawSz, qRaw, qRawSz, + eRaw, eRawSz, nlen, isPrime, NULL); +} + + /* Make an RSA key for size bits, with e specified, 65537 is a good e */ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) { @@ -2822,7 +2838,7 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) } if (err == MP_OKAY) - err = wc_CheckProbablePrime_ex(&p, NULL, &tmp3, size, &isPrime); + err = _CheckProbablePrime(&p, NULL, &tmp3, size, &isPrime, rng); #ifdef WOLFSSL_FIPS i++; @@ -2858,7 +2874,7 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) } if (err == MP_OKAY) - err = wc_CheckProbablePrime_ex(&p, &q, &tmp3, size, &isPrime); + err = _CheckProbablePrime(&p, &q, &tmp3, size, &isPrime, rng); #ifdef WOLFSSL_FIPS i++; diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index 6c1f988bf..cb05919c3 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -269,6 +269,10 @@ WOLFSSL_API int wc_RsaKeyToPublicDer(RsaKey*, byte* output, word32 inLen); #ifdef WOLFSSL_KEY_GEN WOLFSSL_API int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng); + WOLFSSL_API int wc_CheckProbablePrime_ex(const byte* p, word32 pSz, + const byte* q, word32 qSz, + const byte* e, word32 eSz, + int nlen, int* isPrime, WC_RNG* rng); WOLFSSL_API int wc_CheckProbablePrime(const byte* p, word32 pSz, const byte* q, word32 qSz, const byte* e, word32 eSz,