diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index d541b6862..b1bd516c1 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -1728,8 +1728,9 @@ int wc_DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv, } -int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g, - word32 gSz, const byte* q, word32 qSz) +static int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, + word32 gSz, const byte* q, word32 qSz, int trusted, + WC_RNG* rng) { int ret = 0; mp_int* keyP = NULL; @@ -1766,6 +1767,18 @@ int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g, else keyP = &key->p; } + + if (ret == 0 && !trusted) { + int isPrime = 0; + if (rng != NULL) + ret = mp_prime_is_prime_ex(keyP, 8, &isPrime, rng); + else + ret = mp_prime_is_prime(keyP, 8, &isPrime); + + if (ret == 0 && isPrime == 0) + ret = DH_CHECK_PUB_E; + } + if (ret == 0 && mp_init(&key->g) != MP_OKAY) ret = MP_INIT_E; if (ret == 0) { @@ -1799,11 +1812,26 @@ int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g, } +int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g, + word32 gSz, const byte* q, word32 qSz, int trusted, + WC_RNG* rng) +{ + return _DhSetKey(key, p, pSz, g, gSz, q, qSz, trusted, rng); +} + + +int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g, + word32 gSz, const byte* q, word32 qSz) +{ + return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL); +} + + /* not in asn anymore since no actual asn types used */ int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz) { - return wc_DhSetKey_ex(key, p, pSz, g, gSz, NULL, 0); + return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL); } diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 18970489a..b7911555a 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -426,21 +426,8 @@ int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa) #endif /* WOLFSSL_KEY_GEN */ -/* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(), - * input parameters (p,q,g) should be represented as ASCII hex values. - * - * dsa - pointer to initialized DsaKey structure - * p - DSA (p) parameter, ASCII hex string - * pSz - length of p - * q - DSA (q) parameter, ASCII hex string - * qSz - length of q - * g - DSA (g) parameter, ASCII hex string - * gSz - length of g - * - * returns 0 on success, negative upon failure - */ -int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q, - const char* g) +static int _DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q, + const char* g, int trusted, WC_RNG* rng) { int err; word32 pSz, qSz; @@ -450,6 +437,18 @@ int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q, /* read p */ err = mp_read_radix(&dsa->p, p, MP_RADIX_HEX); + if (err == MP_OKAY && !trusted) { + int isPrime = 1; + if (rng == NULL) + err = mp_prime_is_prime(&dsa->p, 8, &isPrime); + else + err = mp_prime_is_prime_ex(&dsa->p, 8, &isPrime, rng); + + if (err == MP_OKAY) { + if (!isPrime) + err = DH_CHECK_PUB_E; + } + } /* read q */ if (err == MP_OKAY) @@ -478,6 +477,49 @@ int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q, } +/* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(), + * input parameters (p,q,g) should be represented as ASCII hex values. + * + * dsa - pointer to initialized DsaKey structure + * p - DSA (p) parameter, ASCII hex string + * pSz - length of p + * q - DSA (q) parameter, ASCII hex string + * qSz - length of q + * g - DSA (g) parameter, ASCII hex string + * gSz - length of g + * + * returns 0 on success, negative upon failure + */ +int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q, + const char* g) +{ + return _DsaImportParamsRaw(dsa, p, q, g, 1, NULL); +} + + +/* Import raw DSA parameters into DsaKey structure for use with wc_MakeDsaKey(), + * input parameters (p,q,g) should be represented as ASCII hex values. Check + * that the p value is probably prime. + * + * dsa - pointer to initialized DsaKey structure + * p - DSA (p) parameter, ASCII hex string + * pSz - length of p + * q - DSA (q) parameter, ASCII hex string + * qSz - length of q + * g - DSA (g) parameter, ASCII hex string + * gSz - length of g + * trusted - trust that p is OK + * rng - random number generator for the prime test + * + * returns 0 on success, negative upon failure + */ +int wc_DsaImportParamsRawCheck(DsaKey* dsa, const char* p, const char* q, + const char* g, int trusted, WC_RNG* rng) +{ + return _DsaImportParamsRaw(dsa, p, q, g, trusted, rng); +} + + /* Export raw DSA parameters from DsaKey structure * * dsa - pointer to initialized DsaKey structure diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index de3160e51..b7d978848 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -4320,7 +4320,7 @@ int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) #endif /* WOLFSSL_KEY_GEN || HAVE_COMP_KEY || HAVE_ECC || DEBUG_WOLFSSL */ -#ifdef WOLFSSL_KEY_GEN +#if defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA) const mp_digit ltm_prime_tab[PRIME_SIZE] = { 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, @@ -4476,75 +4476,6 @@ static int mp_prime_is_divisible (mp_int * a, int *result) return MP_OKAY; } -static const int USE_BBS = 1; - -int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap) -{ - int err, res, type; - byte* buf; - - if (N == NULL || rng == NULL) - return MP_VAL; - - /* get type */ - if (len < 0) { - type = USE_BBS; - len = -len; - } else { - type = 0; - } - - /* allow sizes between 2 and 512 bytes for a prime size */ - if (len < 2 || len > 512) { - return MP_VAL; - } - - /* allocate buffer to work with */ - buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_RSA); - if (buf == NULL) { - return MP_MEM; - } - XMEMSET(buf, 0, len); - - do { -#ifdef SHOW_GEN - printf("."); - fflush(stdout); -#endif - /* generate value */ - err = wc_RNG_GenerateBlock(rng, buf, len); - if (err != 0) { - XFREE(buf, heap, DYNAMIC_TYPE_RSA); - return err; - } - - /* munge bits */ - buf[0] |= 0x80 | 0x40; - buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); - - /* load value */ - if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) { - XFREE(buf, heap, DYNAMIC_TYPE_RSA); - return err; - } - - /* test */ - /* Running Miller-Rabin up to 3 times gives us a 2^{-80} chance - * of a 1024-bit candidate being a false positive, when it is our - * prime candidate. (Note 4.49 of Handbook of Applied Cryptography.) - * Using 8 because we've always used 8. */ - if ((err = mp_prime_is_prime_ex(N, 8, &res, rng)) != MP_OKAY) { - XFREE(buf, heap, DYNAMIC_TYPE_RSA); - return err; - } - } while (res == MP_NO); - - XMEMSET(buf, 0, len); - XFREE(buf, heap, DYNAMIC_TYPE_RSA); - - return MP_OKAY; -} - /* * Sets result to 1 if probably prime, 0 otherwise */ @@ -4696,6 +4627,79 @@ LBL_B:mp_clear (&b); return err; } +#endif /* WOLFSSL_KEY_GEN NO_DH NO_DSA NO_RSA */ + +#ifdef WOLFSSL_KEY_GEN + +static const int USE_BBS = 1; + +int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap) +{ + int err, res, type; + byte* buf; + + if (N == NULL || rng == NULL) + return MP_VAL; + + /* get type */ + if (len < 0) { + type = USE_BBS; + len = -len; + } else { + type = 0; + } + + /* allow sizes between 2 and 512 bytes for a prime size */ + if (len < 2 || len > 512) { + return MP_VAL; + } + + /* allocate buffer to work with */ + buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_RSA); + if (buf == NULL) { + return MP_MEM; + } + XMEMSET(buf, 0, len); + + do { +#ifdef SHOW_GEN + printf("."); + fflush(stdout); +#endif + /* generate value */ + err = wc_RNG_GenerateBlock(rng, buf, len); + if (err != 0) { + XFREE(buf, heap, DYNAMIC_TYPE_RSA); + return err; + } + + /* munge bits */ + buf[0] |= 0x80 | 0x40; + buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); + + /* load value */ + if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) { + XFREE(buf, heap, DYNAMIC_TYPE_RSA); + return err; + } + + /* test */ + /* Running Miller-Rabin up to 3 times gives us a 2^{-80} chance + * of a 1024-bit candidate being a false positive, when it is our + * prime candidate. (Note 4.49 of Handbook of Applied Cryptography.) + * Using 8 because we've always used 8. */ + if ((err = mp_prime_is_prime_ex(N, 8, &res, rng)) != MP_OKAY) { + XFREE(buf, heap, DYNAMIC_TYPE_RSA); + return err; + } + } while (res == MP_NO); + + XMEMSET(buf, 0, len); + XFREE(buf, heap, DYNAMIC_TYPE_RSA); + + return MP_OKAY; +} + /* computes least common multiple as |a*b|/(a, b) */ int mp_lcm (mp_int * a, mp_int * b, mp_int * c) diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 6ead9d792..db102d9a7 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -2607,7 +2607,8 @@ int mp_montgomery_calc_normalization(mp_int *a, mp_int *b) #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \ defined(WOLFSSL_DEBUG_MATH) || defined(DEBUG_WOLFSSL) || \ - defined(WOLFSSL_PUBLIC_MP) + defined(WOLFSSL_PUBLIC_MP) || !defined(NO_DH) || !defined(NO_DSA) || \ + !defined(NO_RSA) #ifdef WOLFSSL_KEY_GEN /* swap the elements of two integers, for cases where you can't simply swap the @@ -2755,26 +2756,11 @@ int mp_mod_d(fp_int *a, fp_digit b, fp_digit *c) #endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) */ -#ifdef WOLFSSL_KEY_GEN -static void fp_gcd(fp_int *a, fp_int *b, fp_int *c); -static void fp_lcm(fp_int *a, fp_int *b, fp_int *c); +#if !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA) || defined(WOLFSSL_KEY_GEN) + static int fp_isprime_ex(fp_int *a, int t); /* static int fp_isprime(fp_int *a); */ -static int fp_randprime(fp_int* N, int len, WC_RNG* rng, void* heap); - -int mp_gcd(fp_int *a, fp_int *b, fp_int *c) -{ - fp_gcd(a, b, c); - return MP_OKAY; -} - - -int mp_lcm(fp_int *a, fp_int *b, fp_int *c) -{ - fp_lcm(a, b, c); - return MP_OKAY; -} int mp_prime_is_prime(mp_int* a, int t, int* result) @@ -2784,28 +2770,6 @@ int mp_prime_is_prime(mp_int* a, int t, int* result) return MP_OKAY; } -int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap) -{ - int err; - - err = fp_randprime(N, len, rng, heap); - switch(err) { - case FP_VAL: - return MP_VAL; - case FP_MEM: - return MP_MEM; - default: - break; - } - - return MP_OKAY; -} - -int mp_exch (mp_int * a, mp_int * b) -{ - fp_exch(a, b); - return MP_OKAY; -} /* Miller-Rabin test of "a" to the base of "b" as described in * HAC pp. 139 Algorithm 4.24 @@ -2920,6 +2884,12 @@ int fp_isprime_ex(fp_int *a, int t) return FP_NO; } + for (r = 0; r < FP_PRIME_SIZE; r++) { + if (fp_cmp_d(a, primes[r]) == FP_EQ) { + return FP_YES; + } + } + /* do trial division */ for (r = 0; r < FP_PRIME_SIZE; r++) { res = fp_mod_d(a, primes[r], &d); @@ -2960,6 +2930,13 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) fp_digit d; int r; + for (r = 0; r < FP_PRIME_SIZE; r++) { + if (fp_cmp_d(a, primes[r]) == FP_EQ) { + *result = FP_YES; + return FP_OKAY; + } + } + for (r = 0; r < FP_PRIME_SIZE; r++) { if (fp_mod_d(a, primes[r], &d) == MP_OKAY) { if (d == 0) @@ -3017,6 +2994,52 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng) return FP_OKAY; } +#endif /* NO_RSA NO_DSA NO_DH WOLFSSL_KEY_GEN */ + + +#ifdef WOLFSSL_KEY_GEN + +static void fp_gcd(fp_int *a, fp_int *b, fp_int *c); +static void fp_lcm(fp_int *a, fp_int *b, fp_int *c); +static int fp_randprime(fp_int* N, int len, WC_RNG* rng, void* heap); + +int mp_gcd(fp_int *a, fp_int *b, fp_int *c) +{ + fp_gcd(a, b, c); + return MP_OKAY; +} + + +int mp_lcm(fp_int *a, fp_int *b, fp_int *c) +{ + fp_lcm(a, b, c); + return MP_OKAY; +} + +int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap) +{ + int err; + + err = fp_randprime(N, len, rng, heap); + switch(err) { + case FP_VAL: + return MP_VAL; + case FP_MEM: + return MP_MEM; + default: + break; + } + + return MP_OKAY; +} + +int mp_exch (mp_int * a, mp_int * b) +{ + fp_exch(a, b); + return MP_OKAY; +} + + int fp_randprime(fp_int* N, int len, WC_RNG* rng, void* heap) { diff --git a/wolfssl/wolfcrypt/dh.h b/wolfssl/wolfcrypt/dh.h index f30a19f3c..edb59d0cc 100644 --- a/wolfssl/wolfcrypt/dh.h +++ b/wolfssl/wolfcrypt/dh.h @@ -98,6 +98,9 @@ WOLFSSL_API int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g word32 gSz); WOLFSSL_API int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz, const byte* q, word32 qSz); +WOLFSSL_API int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, + const byte* g, word32 gSz, const byte* q, word32 qSz, + int trusted, WC_RNG* rng); WOLFSSL_API int wc_DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz, byte* g, word32* gInOutSz); WOLFSSL_API int wc_DhCheckPubKey(DhKey* key, const byte* pub, word32 pubSz); diff --git a/wolfssl/wolfcrypt/dsa.h b/wolfssl/wolfcrypt/dsa.h index 752cf4186..3a0c0f3d0 100644 --- a/wolfssl/wolfcrypt/dsa.h +++ b/wolfssl/wolfcrypt/dsa.h @@ -80,6 +80,9 @@ WOLFSSL_API int wc_MakeDsaParameters(WC_RNG *rng, int modulus_size, DsaKey *dsa) /* raw export functions */ WOLFSSL_API int wc_DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q, const char* g); +WOLFSSL_API int wc_DsaImportParamsRawCheck(DsaKey* dsa, const char* p, + const char* q, const char* g, + int trusted, WC_RNG* rng); WOLFSSL_API int wc_DsaExportParamsRaw(DsaKey* dsa, byte* p, word32* pSz, byte* q, word32* qSz, byte* g, word32* gSz); diff --git a/wolfssl/wolfcrypt/integer.h b/wolfssl/wolfcrypt/integer.h index 646437adb..d7da22004 100644 --- a/wolfssl/wolfcrypt/integer.h +++ b/wolfssl/wolfcrypt/integer.h @@ -370,9 +370,11 @@ MP_API int mp_radix_size (mp_int * a, int radix, int *size); MP_API int mp_read_radix(mp_int* a, const char* str, int radix); #endif -#ifdef WOLFSSL_KEY_GEN +#if defined(WOLFSSL_KEY_GEN) || !defined(NO_RSA) || !defined(NO_DSA) || !defined(NO_DH) MP_API int mp_prime_is_prime (mp_int * a, int t, int *result); MP_API int mp_prime_is_prime_ex (mp_int * a, int t, int *result, WC_RNG*); +#endif /* WOLFSSL_KEY_GEN NO_RSA NO_DSA NO_DH */ +#ifdef WOLFSSL_KEY_GEN MP_API int mp_gcd (mp_int * a, mp_int * b, mp_int * c); MP_API int mp_lcm (mp_int * a, mp_int * b, mp_int * c); MP_API int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap); diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index 104df8b75..980fa69c4 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -728,11 +728,13 @@ MP_API int mp_radix_size (mp_int * a, int radix, int *size); MP_API int mp_montgomery_calc_normalization(mp_int *a, mp_int *b); #endif +#if !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA) || defined(WOLFSSL_KEY_GEN) +MP_API int mp_prime_is_prime(mp_int* a, int t, int* result); +MP_API int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng); +#endif /* NO_DH NO_DSA NO_RSA WOLFSSL_KEY_GEN */ #ifdef WOLFSSL_KEY_GEN MP_API int mp_gcd(fp_int *a, fp_int *b, fp_int *c); MP_API int mp_lcm(fp_int *a, fp_int *b, fp_int *c); -MP_API int mp_prime_is_prime(mp_int* a, int t, int* result); -MP_API int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng); MP_API int mp_rand_prime(mp_int* N, int len, WC_RNG* rng, void* heap); MP_API int mp_exch(mp_int *a, mp_int *b); #endif /* WOLFSSL_KEY_GEN */