Merge pull request #1903 from dgarske/dhkeycheck
Speed improvements for DH public key prime checking
This commit is contained in:
commit
5d8f4351ff
@ -21429,21 +21429,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
goto exit_sske;
|
||||
}
|
||||
|
||||
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
|
||||
!defined(WOLFSSL_OLD_PRIME_CHECK)
|
||||
ret = wc_DhSetCheckKey(ssl->buffers.serverDH_Key,
|
||||
ssl->buffers.serverDH_P.buffer,
|
||||
ssl->buffers.serverDH_P.length,
|
||||
ssl->buffers.serverDH_G.buffer,
|
||||
ssl->buffers.serverDH_G.length,
|
||||
NULL, 0, 0, ssl->rng);
|
||||
#else
|
||||
ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
|
||||
ssl->buffers.serverDH_P.buffer,
|
||||
ssl->buffers.serverDH_P.length,
|
||||
ssl->buffers.serverDH_G.buffer,
|
||||
ssl->buffers.serverDH_G.length);
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
goto exit_sske;
|
||||
}
|
||||
@ -24970,21 +24960,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
goto exit_dcke;
|
||||
}
|
||||
|
||||
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
|
||||
!defined(WOLFSSL_OLD_PRIME_CHECK)
|
||||
ret = wc_DhSetCheckKey(ssl->buffers.serverDH_Key,
|
||||
ssl->buffers.serverDH_P.buffer,
|
||||
ssl->buffers.serverDH_P.length,
|
||||
ssl->buffers.serverDH_G.buffer,
|
||||
ssl->buffers.serverDH_G.length,
|
||||
NULL, 0, 0, ssl->rng);
|
||||
#else
|
||||
ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
|
||||
ssl->buffers.serverDH_P.buffer,
|
||||
ssl->buffers.serverDH_P.length,
|
||||
ssl->buffers.serverDH_G.buffer,
|
||||
ssl->buffers.serverDH_G.length);
|
||||
#endif
|
||||
|
||||
/* set the max agree result size */
|
||||
ssl->arrays->preMasterSz = ENCRYPT_LEN;
|
||||
@ -25036,21 +25016,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
goto exit_dcke;
|
||||
}
|
||||
|
||||
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
|
||||
!defined(WOLFSSL_OLD_PRIME_CHECK)
|
||||
ret = wc_DhSetCheckKey(ssl->buffers.serverDH_Key,
|
||||
ssl->buffers.serverDH_P.buffer,
|
||||
ssl->buffers.serverDH_P.length,
|
||||
ssl->buffers.serverDH_G.buffer,
|
||||
ssl->buffers.serverDH_G.length,
|
||||
NULL, 0, 0, ssl->rng);
|
||||
#else
|
||||
ret = wc_DhSetKey(ssl->buffers.serverDH_Key,
|
||||
ssl->buffers.serverDH_P.buffer,
|
||||
ssl->buffers.serverDH_P.length,
|
||||
ssl->buffers.serverDH_G.buffer,
|
||||
ssl->buffers.serverDH_G.length);
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
|
42
src/ssl.c
42
src/ssl.c
@ -1477,6 +1477,25 @@ int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz,
|
||||
if (ssl->options.side == WOLFSSL_CLIENT_END)
|
||||
return SIDE_ERROR;
|
||||
|
||||
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
|
||||
!defined(HAVE_SELFTEST)
|
||||
{
|
||||
DhKey checkKey;
|
||||
int error, freeKey = 0;
|
||||
|
||||
error = wc_InitDhKey(&checkKey);
|
||||
if (!error) {
|
||||
freeKey = 1;
|
||||
error = wc_DhSetCheckKey(&checkKey,
|
||||
p, pSz, g, gSz, NULL, 0, 0, ssl->rng);
|
||||
}
|
||||
if (freeKey)
|
||||
wc_FreeDhKey(&checkKey);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) {
|
||||
XFREE(ssl->buffers.serverDH_P.buffer, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
ssl->buffers.serverDH_P.buffer = NULL;
|
||||
@ -1545,6 +1564,29 @@ int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz,
|
||||
if (pSz > ctx->maxDhKeySz)
|
||||
return DH_KEY_SIZE_E;
|
||||
|
||||
#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \
|
||||
!defined(HAVE_SELFTEST)
|
||||
{
|
||||
DhKey checkKey;
|
||||
WC_RNG rng;
|
||||
int error, freeKey = 0;
|
||||
|
||||
error = wc_InitRng(&rng);
|
||||
if (!error)
|
||||
error = wc_InitDhKey(&checkKey);
|
||||
if (!error) {
|
||||
freeKey = 1;
|
||||
error = wc_DhSetCheckKey(&checkKey,
|
||||
p, pSz, g, gSz, NULL, 0, 0, &rng);
|
||||
}
|
||||
if (freeKey)
|
||||
wc_FreeDhKey(&checkKey);
|
||||
wc_FreeRng(&rng);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
XFREE(ctx->serverDH_P.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
ctx->serverDH_P.buffer = NULL;
|
||||
XFREE(ctx->serverDH_G.buffer, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
|
@ -56,6 +56,17 @@
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Possible DH enable options:
|
||||
* NO_RSA: Overall control of DH default: on (not defined)
|
||||
* WOLFSSL_OLD_PRIME_CHECK: Disables the new prime number check. It does not
|
||||
directly effect this file, but it does speed up DH
|
||||
removing the testing. It is not recommended to
|
||||
disable the prime checking. default: off
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(USER_MATH_LIB) && !defined(WOLFSSL_DH_CONST)
|
||||
#include <math.h>
|
||||
#define XPOW(x,y) pow((x),(y))
|
||||
|
@ -3193,15 +3193,11 @@ int mp_prime_is_prime(mp_int* a, int t, int* result)
|
||||
* Randomly the chance of error is no more than 1/4 and often
|
||||
* very much lower.
|
||||
*/
|
||||
static int fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result)
|
||||
static int fp_prime_miller_rabin_ex(fp_int * a, fp_int * b, int *result,
|
||||
fp_int *n1, fp_int *y, fp_int *r)
|
||||
{
|
||||
#ifndef WOLFSSL_SMALL_STACK
|
||||
fp_int n1[1], y[1], r[1];
|
||||
#else
|
||||
fp_int *n1, *y, *r;
|
||||
#endif
|
||||
int s, j;
|
||||
int err;
|
||||
int s, j;
|
||||
int err;
|
||||
|
||||
/* default */
|
||||
*result = FP_NO;
|
||||
@ -3211,26 +3207,15 @@ static int fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result)
|
||||
return FP_OKAY;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
n1 = (fp_int*)XMALLOC(sizeof(fp_int) * 3, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (n1 == NULL) {
|
||||
return FP_MEM;
|
||||
}
|
||||
y = &n1[1]; r = &n1[2];
|
||||
#endif
|
||||
|
||||
/* get n1 = a - 1 */
|
||||
fp_init_copy(n1, a);
|
||||
fp_copy(a, n1);
|
||||
err = fp_sub_d(n1, 1, n1);
|
||||
if (err != FP_OKAY) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(n1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
/* set 2**s * r = n1 */
|
||||
fp_init_copy(r, n1);
|
||||
fp_copy(n1, r);
|
||||
|
||||
/* count the number of least significant bits
|
||||
* which are zero
|
||||
@ -3241,7 +3226,7 @@ static int fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result)
|
||||
fp_div_2d (r, s, r, NULL);
|
||||
|
||||
/* compute y = b**r mod a */
|
||||
fp_init(y);
|
||||
fp_zero(y);
|
||||
fp_exptmod(b, r, a, y);
|
||||
|
||||
/* if y != 1 and y != n1 do */
|
||||
@ -3253,9 +3238,6 @@ static int fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result)
|
||||
|
||||
/* if y == 1 then composite */
|
||||
if (fp_cmp_d (y, 1) == FP_EQ) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(n1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return FP_OKAY;
|
||||
}
|
||||
++j;
|
||||
@ -3263,9 +3245,6 @@ static int fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result)
|
||||
|
||||
/* if y != n1 then composite */
|
||||
if (fp_cmp (y, n1) != FP_EQ) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(n1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return FP_OKAY;
|
||||
}
|
||||
}
|
||||
@ -3273,10 +3252,41 @@ static int fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result)
|
||||
/* probably prime now */
|
||||
*result = FP_YES;
|
||||
|
||||
return FP_OKAY;
|
||||
}
|
||||
|
||||
static int fp_prime_miller_rabin(fp_int * a, fp_int * b, int *result)
|
||||
{
|
||||
int err;
|
||||
#ifndef WOLFSSL_SMALL_STACK
|
||||
fp_int n1[1], y[1], r[1];
|
||||
#else
|
||||
fp_int *n1, *y, *r;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
n1 = (fp_int*)XMALLOC(sizeof(fp_int) * 3, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (n1 == NULL) {
|
||||
return FP_MEM;
|
||||
}
|
||||
y = &n1[1]; r = &n1[2];
|
||||
#endif
|
||||
|
||||
fp_init(n1);
|
||||
fp_init(y);
|
||||
fp_init(r);
|
||||
|
||||
err = fp_prime_miller_rabin_ex(a, b, result, n1, y, r);
|
||||
|
||||
fp_clear(n1);
|
||||
fp_clear(y);
|
||||
fp_clear(r);
|
||||
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(n1, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return FP_OKAY;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@ -3333,6 +3343,7 @@ int fp_isprime_ex(fp_int *a, int t, int* result)
|
||||
return FP_NO;
|
||||
}
|
||||
|
||||
/* check against primes table */
|
||||
for (r = 0; r < FP_PRIME_SIZE; r++) {
|
||||
if (fp_cmp_d(a, primes[r]) == FP_EQ) {
|
||||
*result = FP_YES;
|
||||
@ -3382,11 +3393,11 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)
|
||||
if (a == NULL || result == NULL || rng == NULL)
|
||||
return FP_VAL;
|
||||
|
||||
/* do trial division */
|
||||
if (ret == FP_YES) {
|
||||
fp_digit d;
|
||||
int r;
|
||||
|
||||
/* check against primes table */
|
||||
for (r = 0; r < FP_PRIME_SIZE; r++) {
|
||||
if (fp_cmp_d(a, primes[r]) == FP_EQ) {
|
||||
*result = FP_YES;
|
||||
@ -3394,6 +3405,7 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)
|
||||
}
|
||||
}
|
||||
|
||||
/* do trial division */
|
||||
for (r = 0; r < FP_PRIME_SIZE; r++) {
|
||||
if (fp_mod_d(a, primes[r], &d) == MP_OKAY) {
|
||||
if (d == 0)
|
||||
@ -3409,10 +3421,10 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)
|
||||
* give a (1/4)^t chance of a false prime. */
|
||||
if (ret == FP_YES) {
|
||||
#ifndef WOLFSSL_SMALL_STACK
|
||||
fp_int b[1], c[1];
|
||||
fp_int b[1], c[1], n1[1], y[1], r[1];
|
||||
byte base[FP_MAX_PRIME_SIZE];
|
||||
#else
|
||||
fp_int *b, *c;
|
||||
fp_int *b, *c, *n1, *y, *r;
|
||||
byte* base;
|
||||
#endif
|
||||
word32 baseSz;
|
||||
@ -3431,15 +3443,19 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)
|
||||
if (base == NULL)
|
||||
return FP_MEM;
|
||||
|
||||
b = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
b = (fp_int*)XMALLOC(sizeof(fp_int) * 5, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (b == NULL) {
|
||||
return FP_MEM;
|
||||
}
|
||||
c = &b[1];
|
||||
c = &b[1]; n1 = &b[2]; y= &b[3]; r = &b[4];
|
||||
#endif
|
||||
|
||||
fp_init(b);
|
||||
fp_init(c);
|
||||
fp_init(n1);
|
||||
fp_init(y);
|
||||
fp_init(r);
|
||||
|
||||
err = fp_sub_d(a, 2, c);
|
||||
if (err != FP_OKAY) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
@ -3449,16 +3465,29 @@ int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)
|
||||
return err;
|
||||
}
|
||||
while (t > 0) {
|
||||
wc_RNG_GenerateBlock(rng, base, baseSz);
|
||||
if ((err = wc_RNG_GenerateBlock(rng, base, baseSz)) != 0) {
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(b, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
fp_read_unsigned_bin(b, base, baseSz);
|
||||
if (fp_cmp_d(b, 2) != FP_GT || fp_cmp(b, c) != FP_LT)
|
||||
if (fp_cmp_d(b, 2) != FP_GT || fp_cmp(b, c) != FP_LT) {
|
||||
continue;
|
||||
fp_prime_miller_rabin(a, b, &ret);
|
||||
}
|
||||
|
||||
fp_prime_miller_rabin_ex(a, b, &ret, n1, y, r);
|
||||
if (ret == FP_NO)
|
||||
break;
|
||||
fp_zero(b);
|
||||
t--;
|
||||
}
|
||||
|
||||
fp_clear(n1);
|
||||
fp_clear(y);
|
||||
fp_clear(r);
|
||||
fp_clear(b);
|
||||
fp_clear(c);
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
|
@ -11859,6 +11859,16 @@ int dh_test(void)
|
||||
if (ret == 0)
|
||||
ret = dh_fips_generate_test(&rng);
|
||||
|
||||
|
||||
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
|
||||
!defined(WOLFSSL_OLD_PRIME_CHECK)
|
||||
if (ret == 0) {
|
||||
/* Test Check Key */
|
||||
ret = wc_DhSetCheckKey(&key, dh_p, sizeof(dh_p), dh_g, sizeof(dh_g),
|
||||
NULL, 0, 0, &rng);
|
||||
}
|
||||
#endif
|
||||
|
||||
done:
|
||||
|
||||
wc_FreeDhKey(&key);
|
||||
|
Loading…
x
Reference in New Issue
Block a user