From d7b893f250811e2eeb1f6445ccf72c407e71d5af Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 29 Jul 2019 09:29:53 +1000 Subject: [PATCH] Use a fixed number of bits with DSA gen and sign --- wolfcrypt/src/dsa.c | 6 ++- wolfcrypt/src/integer.c | 5 +++ wolfcrypt/src/tfm.c | 78 ++++++++++++++++++++++++++++++++++--- wolfssl/wolfcrypt/integer.h | 2 + wolfssl/wolfcrypt/tfm.h | 3 ++ 5 files changed, 87 insertions(+), 7 deletions(-) diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 6974704de..7e52bbdbf 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -209,7 +209,7 @@ int wc_MakeDsaKey(WC_RNG *rng, DsaKey *dsa) /* public key : y = g^x mod p */ if (err == MP_OKAY) - err = mp_exptmod(&dsa->g, &dsa->x, &dsa->p, &dsa->y); + err = mp_exptmod_ex(&dsa->g, &dsa->x, dsa->q.used, &dsa->p, &dsa->y); if (err == MP_OKAY) dsa->type = DSA_PRIVATE; @@ -702,8 +702,10 @@ int wc_DsaSign(const byte* digest, byte* out, DsaKey* key, WC_RNG* rng) ret = MP_INVMOD_E; /* generate r, r = (g exp k mod p) mod q */ - if (ret == 0 && mp_exptmod(&key->g, &k, &key->p, &r) != MP_OKAY) + if (ret == 0 && mp_exptmod_ex(&key->g, &k, key->q.used, &key->p, + &r) != MP_OKAY) { ret = MP_EXPTMOD_E; + } if (ret == 0 && mp_mod(&r, &key->q, &r) != MP_OKAY) ret = MP_MOD_E; diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index ca6627048..05eef9611 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -927,6 +927,11 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) #endif } +int mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P, mp_int * Y) +{ + (void)digits; + return mp_exptmod(G, X, P, Y); +} /* b = |a| * diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 99a428128..7b09410d5 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -1455,7 +1455,7 @@ int fp_exptmod_nb(exptModNb_t* nb, fp_int* G, fp_int* X, fp_int* P, fp_int* Y) Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder", Cryptographic Hardware and Embedded Systems, CHES 2002 */ -static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) +static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y) { #ifndef WOLFSSL_SMALL_STACK #ifdef WC_NO_CACHE_RESISTANT @@ -1508,7 +1508,7 @@ static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) /* set initial mode and bit cnt */ bitcnt = 1; buf = 0; - digidx = X->used - 1; + digidx = digits - 1; for (;;) { /* grab next digit as required */ @@ -1597,7 +1597,8 @@ static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) /* y = g**x (mod b) * Some restrictions... x must be positive and < b */ -static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) +static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, + fp_int * Y) { fp_digit buf, mp; int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; @@ -1609,6 +1610,8 @@ static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) fp_int M[64]; #endif + (void)digits; + /* find window size */ x = fp_count_bits (X); if (x <= 21) { @@ -1894,7 +1897,7 @@ int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) err = fp_invmod(tmp, P, tmp); if (err == FP_OKAY) { X->sign = FP_ZPOS; - err = _fp_exptmod(tmp, X, P, Y); + err = _fp_exptmod(tmp, X, X->used, P, Y); if (X != Y) { X->sign = FP_NEG; } @@ -1909,10 +1912,70 @@ int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) } else { /* Positive exponent so just exptmod */ - return _fp_exptmod(G, X, P, Y); + return _fp_exptmod(G, X, X->used, P, Y); } } +int fp_exptmod_ex(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y) +{ + +#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \ + !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) + int x = fp_count_bits (X); +#endif + + /* prevent overflows */ + if (P->used > (FP_SIZE/2)) { + return FP_VAL; + } + +#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \ + !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) + if(x > EPS_RSA_EXPT_XBTIS) { + return esp_mp_exptmod(G, X, x, P, Y); + } +#endif + + if (X->sign == FP_NEG) { +#ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */ + int err; + #ifndef WOLFSSL_SMALL_STACK + fp_int tmp[1]; + #else + fp_int *tmp; + #endif + + #ifdef WOLFSSL_SMALL_STACK + tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (tmp == NULL) + return FP_MEM; + #endif + + /* yes, copy G and invmod it */ + fp_init_copy(tmp, G); + err = fp_invmod(tmp, P, tmp); + if (err == FP_OKAY) { + X->sign = FP_ZPOS; + err = _fp_exptmod(tmp, X, digits, P, Y); + if (X != Y) { + X->sign = FP_NEG; + } + } + #ifdef WOLFSSL_SMALL_STACK + XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return err; +#else + return FP_VAL; +#endif + } + else { + /* Positive exponent so just exptmod */ + return _fp_exptmod(G, X, digits, P, Y); + } +} + + /* computes a = 2**b */ void fp_2expt(fp_int *a, int b) { @@ -3104,6 +3167,11 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) return fp_exptmod(G, X, P, Y); } +int mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P, mp_int * Y) +{ + return fp_exptmod_ex(G, X, digits, P, Y); +} + /* compare two ints (signed)*/ int mp_cmp (mp_int * a, mp_int * b) { diff --git a/wolfssl/wolfcrypt/integer.h b/wolfssl/wolfcrypt/integer.h index 162bce45a..9b44ebdfb 100644 --- a/wolfssl/wolfcrypt/integer.h +++ b/wolfssl/wolfcrypt/integer.h @@ -284,6 +284,8 @@ MP_API int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b); MP_API int mp_to_unsigned_bin (mp_int * a, unsigned char *b); MP_API int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c); MP_API int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y); +MP_API int mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P, + mp_int * Y); /* end functions needed by Rsa */ /* functions added to support above needed, removed TOOM and KARATSUBA */ diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index 22bc627f4..170280cef 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -547,6 +547,7 @@ int fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp); /* d = a**b (mod c) */ int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); +int fp_exptmod_ex(fp_int *a, fp_int *b, int minDigits, fp_int *c, fp_int *d); #ifdef WC_RSA_NONBLOCK @@ -734,6 +735,8 @@ MP_API int mp_addmod (mp_int* a, mp_int* b, mp_int* c, mp_int* d); MP_API int mp_mod(mp_int *a, mp_int *b, mp_int *c); MP_API int mp_invmod(mp_int *a, mp_int *b, mp_int *c); MP_API int mp_exptmod (mp_int * g, mp_int * x, mp_int * p, mp_int * y); +MP_API int mp_exptmod_ex (mp_int * g, mp_int * x, int minDigits, mp_int * p, + mp_int * y); MP_API int mp_mul_2d(mp_int *a, int b, mp_int *c); MP_API int mp_2expt(mp_int* a, int b);