From ee12c12e98ec19b50727a2677b1674fbaec7d24b Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 19 Jan 2022 10:20:21 +1000 Subject: [PATCH] Fixes required to make SP Math default fasthugemath means turn on fastmath Use sp_int_digit and not sp_digit in sp_int.c. test.c needs to use large static buffer when SP Math used like fastmath. When building static memroy, SP math all without WOLFSSL_SP_NO_MALLOC is a valid configuration. Fix freeing of bigint in sp_int.c. Cast x to a signed value to negate and then back to unsigned. (For Windows builds.) Remove warning about empty file on Windows about integer.obj. Allow RSA verify only and RSA public only to be used with other public key algorithms. If building for FIPS, then older versions of RSA and ECC require SP Math to support negative numbers. Get old FIPS files building with SP int. Disallow --enable-sp-math and --enable-sp-math-all. When just --enable-sp-math on configuration line then disable SP Math all. --- configure.ac | 103 +++++++++++++++++++++++--------- wolfcrypt/src/integer.c | 12 ++-- wolfcrypt/src/sp_int.c | 112 +++++++++++++++++++++++------------ wolfcrypt/test/test.c | 8 ++- wolfssl/wolfcrypt/include.am | 4 ++ wolfssl/wolfcrypt/settings.h | 53 +++++++++-------- wolfssl/wolfcrypt/sp_int.h | 11 +++- 7 files changed, 204 insertions(+), 99 deletions(-) diff --git a/configure.ac b/configure.ac index 1d160c8ba..0184cbc14 100644 --- a/configure.ac +++ b/configure.ac @@ -224,6 +224,12 @@ then fi AC_SUBST([ENABLED_ASM]) + +# Default math is SP Math all and not fast math +# FIPS v1 and v2 must use fast math +DEF_SP_MATH="yes" +DEF_FAST_MATH="no" + # FIPS 140 AC_ARG_ENABLE([fips], [AS_HELP_STRING([--enable-fips],[Enable FIPS 140-2, Will NOT work w/o FIPS license (default: disabled)])], @@ -286,65 +292,87 @@ AS_CASE([$ENABLED_FIPS], [disabled],[ FIPS_VERSION="disabled" ENABLED_FIPS="no" + DEF_SP_MATH="no" + DEF_FAST_MATH="yes" ], [v1|yes|cert2425],[ FIPS_VERSION="v1" HAVE_FIPS_VERSION=1 ENABLED_FIPS="yes" + DEF_SP_MATH="no" + DEF_FAST_MATH="yes" ], [v2|cert3389],[ FIPS_VERSION="v2" HAVE_FIPS_VERSION=2 HAVE_FIPS_VERSION_MINOR=0 ENABLED_FIPS="yes" + DEF_SP_MATH="no" + DEF_FAST_MATH="yes" ], [rand],[ FIPS_VERSION="rand" HAVE_FIPS_VERSION=2 HAVE_FIPS_VERSION_MINOR=1 ENABLED_FIPS="yes" + DEF_SP_MATH="no" + DEF_FAST_MATH="yes" ], [v5-RC8],[ FIPS_VERSION="v5-RC8" HAVE_FIPS_VERSION=5 HAVE_FIPS_VERSION_MINOR=0 ENABLED_FIPS="yes" + DEF_SP_MATH="no" + DEF_FAST_MATH="yes" ], [v5-RC9],[ FIPS_VERSION="v5-RC9" HAVE_FIPS_VERSION=5 HAVE_FIPS_VERSION_MINOR=1 ENABLED_FIPS="yes" + DEF_SP_MATH="no" + DEF_FAST_MATH="yes" ], [v5-RC10],[ FIPS_VERSION="v5-RC10" HAVE_FIPS_VERSION=5 HAVE_FIPS_VERSION_MINOR=2 ENABLED_FIPS="yes" + DEF_SP_MATH="no" + DEF_FAST_MATH="yes" ], [v5-RC11],[ FIPS_VERSION="v5-RC11" HAVE_FIPS_VERSION=5 HAVE_FIPS_VERSION_MINOR=2 ENABLED_FIPS="yes" + DEF_SP_MATH="no" + DEF_FAST_MATH="yes" ], [v5|v5-RC12],[ FIPS_VERSION="v5-RC12" HAVE_FIPS_VERSION=5 HAVE_FIPS_VERSION_MINOR=2 ENABLED_FIPS="yes" + DEF_SP_MATH="no" + DEF_FAST_MATH="yes" ], [ready|v5-ready],[ FIPS_VERSION="v5-ready" HAVE_FIPS_VERSION=5 HAVE_FIPS_VERSION_MINOR=3 ENABLED_FIPS="yes" + DEF_SP_MATH="no" + DEF_FAST_MATH="yes" ], [dev|v5-dev],[ FIPS_VERSION="v5-dev" HAVE_FIPS_VERSION=5 HAVE_FIPS_VERSION_MINOR=3 ENABLED_FIPS="yes" + DEF_SP_MATH="no" + DEF_FAST_MATH="yes" ], [ AC_MSG_ERROR([Invalid value for --enable-fips "$ENABLED_FIPS" (main options: v1, v2, v5, ready, dev, rand, no, disabled)]) @@ -503,7 +531,7 @@ AC_ARG_ENABLE([sp], AC_ARG_ENABLE([sp-math-all], [AS_HELP_STRING([--enable-sp-math-all],[Enable Single Precision math implementation for full algorithm suite (default: enabled)])], [ ENABLED_SP_MATH_ALL=$enableval ], - [ ENABLED_SP_MATH_ALL=yes ], + [ ENABLED_SP_MATH_ALL=$DEF_SP_MATH ], ) # Single Precision maths (acceleration for common key sizes and curves) @@ -519,6 +547,22 @@ AC_ARG_ENABLE([sp-math], [ ENABLED_SP_MATH=$ENABLED_SP_MATH_DEFAULT ], ) +if test "$enable_sp_math" != "" +then + # When the restricted SP Math is selected and not SP Math ALL, then disable + # SP Math ALL. + if test "$enable_sp_math" != "no" && test "$enable_sp_math_all" = "" + then + ENABLED_SP_MATH_ALL="no" + else + # Can't choose restricted and unrestricted SP Math + if test "$enable_sp_math" != "no" && test "$enable_sp_math_all" != "no" + then + AC_MSG_ERROR([--enable-sp-math and --enable-sp-math-all are incompatible. Use --enable-sp-math-all only when all key sizes need to be supported.]) + fi + fi +fi + # enable SP math assembly support automatically for x86_64 and aarch64 (except Linux kernel module) SP_ASM_DEFAULT=no if test "$ENABLED_SP_MATH" = "yes" && test "$ENABLED_LINUXKM_DEFAULTS" = "no" @@ -5738,9 +5782,26 @@ fi AC_ARG_ENABLE([fastmath], [AS_HELP_STRING([--enable-fastmath],[Enable fast math ops (default: disabled)])], [ ENABLED_FASTMATH=$enableval ], - [ ENABLED_FASTMATH=no] + [ ENABLED_FASTMATH=$DEF_FAST_MATH ] ) +# fast HUGE math +AC_ARG_ENABLE([fasthugemath], + [AS_HELP_STRING([--enable-fasthugemath],[Enable fast math + huge code (default: disabled)])], + [ ENABLED_FASTHUGEMATH=$enableval ], + [ ENABLED_FASTHUGEMATH=no ] + ) + +if test "$ENABLED_BUMP" = "yes" +then + ENABLED_FASTHUGEMATH="yes" +fi + +if test "$ENABLED_FASTHUGEMATH" = "yes" +then + ENABLED_FASTMATH="yes" +fi + # if sp-math-all is not set, then enable fast math if test "x$ENABLED_FASTMATH" = "xyes" && test "$enable_sp_math_all" = "" then @@ -5749,15 +5810,15 @@ then then if test "$ENABLED_DH" = "no" && test "$ENABLED_ECC" = "no" && test "$ENABLED_RSA" = "no" then - ENABLED_FASTMATH=no + ENABLED_FASTMATH="no" else AM_CFLAGS="$AM_CFLAGS -DUSE_FAST_MATH" - ENABLED_HEAPMATH=no + ENABLED_HEAPMATH="no" fi else AM_CFLAGS="$AM_CFLAGS -DUSE_FAST_MATH" ENABLED_HEAPMATH="no" - ENABLED_SP_MATH_ALL=no + ENABLED_SP_MATH_ALL="no" fi if test "$host_cpu" = "x86_64" then @@ -5785,25 +5846,6 @@ then ENABLED_SP_MATH_ALL=no fi -# fast HUGE math -AC_ARG_ENABLE([fasthugemath], - [AS_HELP_STRING([--enable-fasthugemath],[Enable fast math + huge code (default: disabled)])], - [ ENABLED_FASTHUGEMATH=$enableval ], - [ ENABLED_FASTHUGEMATH=no ] - ) - -if test "$ENABLED_BUMP" = "yes" -then - ENABLED_FASTHUGEMATH="yes" -fi - -if test "$ENABLED_FASTHUGEMATH" = "yes" -then - ENABLED_FASTMATH="yes" - AM_CFLAGS="$AM_CFLAGS -DUSE_FAST_MATH" - ENABLED_HEAPMATH="no" -fi - # Enable Examples, used to disable examples if test "$ENABLED_LINUXKM" = "yes" @@ -6399,6 +6441,10 @@ do AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NO_MALLOC" ENABLED_SP_MATH_ALL="yes" ;; + neg) + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_INT_NEGATIVE" + ENABLED_SP_MATH_ALL="yes" + ;; *) AC_MSG_ERROR([Support SP int bit sizes: 256, 384, 521, 1024, 2048, 3072, 4096. $ENABLED_SP_MATH_ALL not supported]) ;; @@ -6414,13 +6460,13 @@ if test "$ENABLED_SP_MATH_ALL" = "yes"; then case $host_cpu in *x86_64*) - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_X86_64" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_X86_64 -DWOLFSSL_X86_64_BUILD" ;; *x86*) AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_X86" ;; *aarch64*) - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_ARM64" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_ARM64 -DWOLFSSL_AARCH64_BUILD" ;; *arm*) if test $host_alias = "thumb"; then @@ -6455,6 +6501,10 @@ if test "$ENABLED_SP_MATH_ALL" = "yes"; then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_S390X" ;; esac + + if test "$ENABLED_FIPS=" != "no" || test "$SELFTEST_VERSION=" != "no"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_INT_NEGATIVE" + fi fi @@ -7027,7 +7077,6 @@ then fi fi - # When building for wolfRand, strip out all options to disable everything. AS_IF([test "x$ENABLED_FIPS" = "xyes" && test "x$FIPS_VERSION" = "xrand"], [NEW_AM_CFLAGS="-DNO_AES -DNO_DH -DNO_ASN -DNO_RSA -DNO_SHA -DNO_MD5 -DNO_BIG_INT" diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 4efd61d1f..9fbd64bb8 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -34,6 +34,12 @@ /* in case user set USE_FAST_MATH there */ #include +#ifndef NO_BIG_INT + +#if !defined(USE_FAST_MATH) && defined(USE_INTEGER_HEAP_MATH) + +#ifndef WOLFSSL_SP_MATH + #ifdef NO_INLINE #include #else @@ -41,12 +47,6 @@ #include #endif -#ifndef NO_BIG_INT - -#if !defined(USE_FAST_MATH) && defined(USE_INTEGER_HEAP_MATH) - -#ifndef WOLFSSL_SP_MATH - #include #if defined(FREESCALE_LTC_TFM) diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 0f551fc7d..586e54caf 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -4328,9 +4328,6 @@ static void _sp_zero(sp_int* a) #ifdef WOLFSSL_SP_INT_NEGATIVE a->sign = MP_ZPOS; #endif -#ifdef HAVE_WOLF_BIGINT - wc_bigint_init(&a->raw); -#endif } /* Initialize the multi-precision number to be zero. @@ -4348,6 +4345,9 @@ int sp_init(sp_int* a) err = MP_VAL; } if (err == MP_OKAY) { + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&a->raw); + #endif _sp_zero(a); a->size = SP_INT_DIGITS; } @@ -4390,6 +4390,9 @@ int sp_init_multi(sp_int* n1, sp_int* n2, sp_int* n3, sp_int* n4, sp_int* n5, sp_int* n6) { if (n1 != NULL) { + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&n1->raw); + #endif _sp_zero(n1); n1->dp[0] = 0; n1->size = SP_INT_DIGITS; @@ -4398,6 +4401,9 @@ int sp_init_multi(sp_int* n1, sp_int* n2, sp_int* n3, sp_int* n4, sp_int* n5, #endif } if (n2 != NULL) { + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&n2->raw); + #endif _sp_zero(n2); n2->dp[0] = 0; n2->size = SP_INT_DIGITS; @@ -4406,6 +4412,9 @@ int sp_init_multi(sp_int* n1, sp_int* n2, sp_int* n3, sp_int* n4, sp_int* n5, #endif } if (n3 != NULL) { + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&n3->raw); + #endif _sp_zero(n3); n3->dp[0] = 0; n3->size = SP_INT_DIGITS; @@ -4414,6 +4423,9 @@ int sp_init_multi(sp_int* n1, sp_int* n2, sp_int* n3, sp_int* n4, sp_int* n5, #endif } if (n4 != NULL) { + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&n4->raw); + #endif _sp_zero(n4); n4->dp[0] = 0; n4->size = SP_INT_DIGITS; @@ -4422,6 +4434,9 @@ int sp_init_multi(sp_int* n1, sp_int* n2, sp_int* n3, sp_int* n4, sp_int* n5, #endif } if (n5 != NULL) { + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&n5->raw); + #endif _sp_zero(n5); n5->dp[0] = 0; n5->size = SP_INT_DIGITS; @@ -4430,6 +4445,9 @@ int sp_init_multi(sp_int* n1, sp_int* n2, sp_int* n3, sp_int* n4, sp_int* n5, #endif } if (n6 != NULL) { + #ifdef HAVE_WOLF_BIGINT + wc_bigint_init(&n6->raw); + #endif _sp_zero(n6); n6->dp[0] = 0; n6->size = SP_INT_DIGITS; @@ -4513,6 +4531,7 @@ void sp_clear(sp_int* a) a->dp[i] = 0; } _sp_zero(a); + sp_free(a); } } @@ -4525,12 +4544,15 @@ void sp_clear(sp_int* a) */ void sp_forcezero(sp_int* a) { - /* Ensure all data zeroized - data not zeroed when used decreases. */ - ForceZero(a->dp, a->size * sizeof(sp_int_digit)); - _sp_zero(a); -#ifdef HAVE_WOLF_BIGINT - wc_bigint_zero(&a->raw); -#endif + if (a != NULL) { + /* Ensure all data zeroized - data not zeroed when used decreases. */ + ForceZero(a->dp, a->used * sizeof(sp_int_digit)); + _sp_zero(a); + #ifdef HAVE_WOLF_BIGINT + wc_bigint_zero(&a->raw); + #endif + sp_free(a); + } } #endif /* !WOLFSSL_RSA_VERIFY_ONLY || !NO_DH || HAVE_ECC */ @@ -4631,7 +4653,7 @@ int sp_cond_swap_ct(sp_int * a, sp_int * b, int c, int m) { int i; int err = MP_OKAY; - sp_digit mask = (sp_digit)0 - m; + sp_int_digit mask = (sp_int_digit)0 - m; DECL_SP_INT(t, c); ALLOC_SP_INT(t, c, err, NULL); @@ -4840,7 +4862,8 @@ int sp_cmp(sp_int* a, sp_int* b) * Bit check/set functions *************************/ -#if !defined(WOLFSSL_RSA_VERIFY_ONLY) +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || (defined(WOLFSSL_SP_MATH_ALL) && \ + defined(HAVE_ECC)) /* Check if a bit is set * * When a is NULL, result is 0. @@ -4892,7 +4915,7 @@ int sp_count_bits(const sp_int* a) r *= SP_WORD_SIZE; if (d > SP_HALF_MAX) { r += SP_WORD_SIZE; - while ((d & ((sp_digit)1 << (SP_WORD_SIZE - 1))) == 0) { + while ((d & ((sp_int_digit)1 << (SP_WORD_SIZE - 1))) == 0) { r--; d <<= 1; } @@ -4910,7 +4933,7 @@ int sp_count_bits(const sp_int* a) } #if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && \ - !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH) || \ + !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || !defined(NO_DH) || \ (defined(HAVE_ECC) && defined(FP_ECC)) || \ (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) @@ -4961,7 +4984,8 @@ int sp_cnt_lsb(sp_int* a) } #endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH || (HAVE_ECC && FP_ECC) */ -#if !defined(WOLFSSL_RSA_VERIFY_ONLY) +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || \ + (defined(WOLFSSL_SP_MATH_ALL) && !defined(NO_ASN)) /* Determine if the most significant byte of the encoded multi-precision number * has the top bit set. * @@ -5137,7 +5161,8 @@ int sp_set_int(sp_int* a, unsigned long n) } #endif /* WOLFSSL_SP_MATH_ALL || !NO_RSA */ -#ifndef WOLFSSL_RSA_VERIFY_ONLY +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || \ + (defined(WOLFSSL_SP_MATH_ALL) && !defined(NO_DH)) /* Compare a one digit number with a multi-precision number. * * When a is NULL, MP_LT is returned. @@ -5191,7 +5216,8 @@ int sp_cmp_d(sp_int* a, sp_int_digit d) #endif #if !defined(NO_PWDBASED) || defined(WOLFSSL_KEY_GEN) || !defined(NO_DH) || \ - !defined(NO_DSA) || (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ + !defined(NO_DSA) || \ + (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ defined(OPENSSL_EXTRA) #define WOLFSSL_SP_ADD_D #endif @@ -5212,7 +5238,7 @@ int sp_cmp_d(sp_int* a, sp_int_digit d) #define WOLFSSL_SP_INVMOD_MONT_CT #endif #if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && \ - !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH) || \ + !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || !defined(NO_DH) || \ (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) #define WOLFSSL_SP_PRIME_GEN #endif @@ -5508,7 +5534,7 @@ int sp_mul_d(sp_int* a, sp_int_digit d, sp_int* r) #define WOLFSSL_SP_DIV_D #endif #if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ - defined(WOLFSSL_HAVE_SP_DH) || \ + !defined(NO_DH) || \ (defined(HAVE_ECC) && (defined(FP_ECC) || defined(HAVE_COMP_KEY))) || \ (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) #define WOLFSSL_SP_MOD_D @@ -6265,7 +6291,8 @@ int sp_addmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r) #endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_CUSTOM_CURVES) || * WOLFCRYPT_HAVE_ECCSI || WOLFCRYPT_HAVE_SAKKE */ -#if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) +#if defined(WOLFSSL_SP_MATH_ALL) && (!defined(WOLFSSL_RSA_VERIFY_ONLY) || \ + defined(HAVE_ECC)) /* Sub b from a and reduce: r = (a - b) % m * Result is always positive. * @@ -9897,7 +9924,7 @@ int sp_mul(sp_int* a, sp_int* b, sp_int* r) { int err = MP_OKAY; #ifdef WOLFSSL_SP_INT_NEGATIVE - int sign; + int sign = MP_ZPOS; #endif if ((a == NULL) || (b == NULL) || (r == NULL)) { @@ -10337,7 +10364,7 @@ int sp_invmod_mont_ct(sp_int* a, sp_int* m, sp_int* r, sp_int_digit mp) **************************/ #if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && \ - !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || defined(WOLFSSL_HAVE_SP_DH) + !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || !defined(NO_DH) /* Internal. Exponentiates b to the power of e modulo m into r: r = b ^ e mod m * Process the exponent one bit at a time. * Is constant time and can be cache attack resistant. @@ -10441,8 +10468,8 @@ static int _sp_exptmod_ex(sp_int* b, sp_int* e, int bits, sp_int* m, sp_int* r) #endif /* (WOLFSSL_SP_MATH_ALL && !WOLFSSL_RSA_VERIFY_ONLY) || * WOLFSSL_HAVE_SP_DH */ -#if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && \ - !defined(WOLFSSL_RSA_PUBLIC_ONLY) +#if defined(WOLFSSL_SP_MATH_ALL) && ((!defined(WOLFSSL_RSA_VERIFY_ONLY) && \ + !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || !defined(NO_DH)) #ifndef WC_NO_HARDEN #if !defined(WC_NO_CACHE_RESISTANT) /* Internal. Exponentiates b to the power of e modulo m into r: r = b ^ e mod m @@ -10890,8 +10917,7 @@ static int _sp_exptmod_base_2(sp_int* e, int digits, sp_int* m, sp_int* r) #endif /* WOLFSSL_SP_MATH_ALL && !WOLFSSL_RSA_VERIFY_ONLY */ #if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ - defined(WOLFSSL_HAVE_SP_DH) || \ - (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) + !defined(NO_DH) || (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) /* Exponentiates b to the power of e modulo m into r: r = b ^ e mod m * * @param [in] b SP integer that is the base. @@ -10995,8 +11021,9 @@ int sp_exptmod_ex(sp_int* b, sp_int* e, int digits, sp_int* m, sp_int* r) { } } -#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH) -#if defined(WOLFSSL_RSA_VERIFY_ONLY) || defined(WOLFSSL_RSA_PUBLIC_ONLY) +#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) +#if (defined(WOLFSSL_RSA_VERIFY_ONLY) || defined(WOLFSSL_RSA_PUBLIC_ONLY)) && \ + defined(NO_DH) if ((!done) && (err == MP_OKAY)) err = sp_exptmod_nct(b, e, m, r); } @@ -11042,8 +11069,7 @@ int sp_exptmod_ex(sp_int* b, sp_int* e, int digits, sp_int* m, sp_int* r) #endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH */ #if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ - defined(WOLFSSL_HAVE_SP_DH) || \ - (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) + !defined(NO_DH) || (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) /* Exponentiates b to the power of e modulo m into r: r = b ^ e mod m * * @param [in] b SP integer that is the base. @@ -11220,7 +11246,7 @@ static int _sp_exptmod_nct(sp_int* b, sp_int* e, sp_int* m, sp_int* r) * window of bits left. */ while (err == MP_OKAY && ((i >= 0) || (c >= winBits))) { - sp_digit n2 = n; + sp_int_digit n2 = n; int c2 = c; int i2 = i; @@ -11604,7 +11630,8 @@ int sp_mod_2d(sp_int* a, int e, sp_int* r) } #endif /* WOLFSSL_SP_MATH_ALL && !WOLFSSL_RSA_VERIFY_ONLY */ -#if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) +#if defined(WOLFSSL_SP_MATH_ALL) && (!defined(WOLFSSL_RSA_VERIFY_ONLY) || \ + !defined(NO_DH)) /* Multiply by 2^e: r = a << e * * @param [in] a SP integer to multiply. @@ -14076,7 +14103,8 @@ int sp_sqr(sp_int* a, sp_int* r) #endif /* WOLFSSL_SP_MATH_ALL || WOLFSSL_HAVE_SP_DH || HAVE_ECC || * (!NO_RSA && !WOLFSSL_RSA_VERIFY_ONLY) */ -#if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) +#if (!defined(WOLFSSL_RSA_VERIFY_ONLY) && \ + !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || !defined(NO_DH) /* Square a mod m and store in r: r = (a * a) mod m * * @param [in] a SP integer to square. @@ -14471,7 +14499,8 @@ static int _sp_mont_red(sp_int* a, sp_int* m, sp_int_digit mp) #endif /* !SQR_MUL_ASM */ } -#ifndef WOLFSSL_RSA_VERIFY_ONLY +#if !defined(WOLFSSL_RSA_VERIFY_ONLY) || \ + (defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)) /* Reduce a number in montgomery form. * * @param [in,out] a SP integer to Montgomery reduce. @@ -14538,7 +14567,7 @@ int sp_mont_setup(sp_int* m, sp_int_digit* rho) #endif /* SP_WORD_SIZE >= 16 */ /* rho = -1/m mod b, subtract x (unsigned) from 0, assign negative */ - *rho = (sp_int_digit) ((sp_int_digit)0 - (sp_int_digit)x); + *rho = (sp_int_digit)((sp_int_digit)0 - (sp_sint_digit)x); } return err; @@ -15358,7 +15387,7 @@ int sp_rand_prime(sp_int* r, int len, WC_RNG* rng, void* heap) #endif /* LITTLE_ENDIAN_ORDER */ #ifdef WOLFSSL_SP_MATH_ALL if (bits > 0) { - r->dp[r->used - 1] &= ((sp_digit)1 << bits) - 1; + r->dp[r->used - 1] &= ((sp_int_digit)1 << bits) - 1; } #endif /* WOLFSSL_SP_MATH_ALL */ @@ -15744,9 +15773,17 @@ int sp_prime_is_prime_ex(sp_int* a, int t, int* result, WC_RNG* rng) break; } b->used = a->used; + + #ifdef BIG_ENDIAN_ORDER + if (((baseSz * 8) & SP_WORD_MASK) != 0) { + b->dp[b->used-1] >>= + SP_WORD_SIZE - ((baseSz * 8) & SP_WORD_MASK); + } + #endif /* LITTLE_ENDIAN_ORDER */ + /* Ensure the top word has no more bits than necessary. */ if (bits > 0) { - b->dp[b->used - 1] &= ((sp_digit)1 << bits) - 1; + b->dp[b->used - 1] &= ((sp_int_digit)1 << bits) - 1; sp_clamp(b); } @@ -15904,7 +15941,8 @@ int sp_gcd(sp_int* a, sp_int* b, sp_int* r) #endif /* WOLFSSL_SP_MATH_ALL && !NO_RSA && WOLFSSL_KEY_GEN */ -#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && !defined(WC_RSA_BLINDING) +#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \ + (!defined(WC_RSA_BLINDING) || defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) /* Calculates the Lowest Common Multiple (LCM) of a and b and stores in r. * diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index a4349b86a..883e6707a 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -621,7 +621,8 @@ static void myFipsCb(int ok, int err, const char* hash) static byte gTestMemory[14000]; #elif defined(WOLFSSL_CERT_EXT) static byte gTestMemory[140000]; - #elif defined(USE_FAST_MATH) && !defined(ALT_ECC_SIZE) + #elif (defined(WOLFSSL_SP_MATH_ALL) || defined(USE_FAST_MATH)) && \ + !defined(ALT_ECC_SIZE) static byte gTestMemory[160000]; #else static byte gTestMemory[80000]; @@ -16291,7 +16292,7 @@ static int dh_ffdhe_test(WC_RNG *rng, int name) ERROR_OUT(-8059, done); } -#if defined(WOLFSSL_HAVE_SP_DH) && defined(USE_FAST_MATH) +#if defined(WOLFSSL_HAVE_SP_DH) || defined(USE_FAST_MATH) /* Make p even */ key->p.dp[0] &= (mp_digit)-2; if (ret != 0) { @@ -16315,7 +16316,8 @@ static int dh_ffdhe_test(WC_RNG *rng, int name) } ret = wc_DhCheckKeyPair(key, pub, pubSz, priv, privSz); - if (ret != MP_VAL && ret != MP_EXPTMOD_E && ret != ASYNC_OP_E) { + if (ret != MP_VAL && ret != MP_EXPTMOD_E && ret != MP_CMP_E && + ret != ASYNC_OP_E) { ERROR_OUT(-8057, done); } diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 3a7c1f6e1..4173dea3f 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -148,6 +148,10 @@ endif if BUILD_SP nobase_include_HEADERS+= wolfssl/wolfcrypt/sp.h nobase_include_HEADERS+= wolfssl/wolfcrypt/sp_int.h +else +if BUILD_SP_INT +nobase_include_HEADERS+= wolfssl/wolfcrypt/sp_int.h +endif endif if BUILD_SELFTEST diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 3fbdcb2f6..471f4c012 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1886,28 +1886,33 @@ extern void uITRON4_free(void *p) ; /* --------------------------------------------------------------------------- * Math Library Selection (in order of preference) * ---------------------------------------------------------------------------*/ -/* 1) SP Math: wolfSSL proprietary math implementation (sp_int.c). - * Constant time: Always - * Enable: WOLFSSL_SP_MATH_ALL - * - * 2) Fast Math: Stack based (tfm.c) - * Constant time: Only with TFM_TIMING_RESISTANT - * Enable: USE_FAST_MATH - * - * 3) Integer Heap Math: Heap based (integer.c) - * Constant time: Not supported - * Enable: USE_INTEGER_HEAP_MATH - */ -#if defined(WOLFSSL_SP_MATH_ALL) || \ - (!defined(USE_FAST_MATH) && !defined(USE_INTEGER_HEAP_MATH)) - /* 1) Using wolfSSL SP Math (sp_int.c) */ - #ifndef WOLFSSL_SP_MATH_ALL - #define WOLFSSL_SP_MATH_ALL +/* Only evaluate this if it is A) not fips or B) only 140-3 FIPS + * (v5 or greater) */ +#if !defined(HAVE_FIPS_VERSION) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 5)) + /* 1) SP Math: wolfSSL proprietary math implementation (sp_int.c). + * Constant time: Always + * Enable: WOLFSSL_SP_MATH_ALL + * + * 2) Fast Math: Stack based (tfm.c) + * Constant time: Only with TFM_TIMING_RESISTANT + * Enable: USE_FAST_MATH + * + * 3) Integer Heap Math: Heap based (integer.c) + * Constant time: Not supported + * Enable: USE_INTEGER_HEAP_MATH + */ + #if defined(WOLFSSL_SP_MATH_ALL) || \ + (!defined(USE_FAST_MATH) && !defined(USE_INTEGER_HEAP_MATH)) + /* 1) Using wolfSSL SP Math (sp_int.c) */ + #ifndef WOLFSSL_SP_MATH_ALL + #define WOLFSSL_SP_MATH_ALL + #endif + #elif defined(USE_FAST_MATH) + /* 2) Using fast math (tfm.c) - USE_FAST_MATH */ + #else + /* 3) Using heap based (integer.c) math - USE_INTEGER_HEAP_MATH */ #endif -#elif defined(USE_FAST_MATH) - /* 2) Using fast math (tfm.c) - USE_FAST_MATH */ -#else - /* 3) Using heap based (integer.c) math - USE_INTEGER_HEAP_MATH */ #endif /*----------------------------------------------------------------------------*/ @@ -2256,9 +2261,9 @@ extern void uITRON4_free(void *p) ; #if defined(HAVE_IO_POOL) || defined(XMALLOC_USER) || defined(NO_WOLFSSL_MEMORY) #error static memory cannot be used with HAVE_IO_POOL, XMALLOC_USER or NO_WOLFSSL_MEMORY #endif - #if !defined(WOLFSSL_SP_NO_MALLOC) && \ - !defined(USE_FAST_MATH) && !defined(NO_BIG_INT) - #error The static memory option is only supported for fast math or SP with no malloc + #if !defined(WOLFSSL_SP_MATH_ALL) && !defined(USE_FAST_MATH) && \ + !defined(NO_BIG_INT) + #error The static memory option is only supported for fast math or SP Math #endif #ifdef WOLFSSL_SMALL_STACK #error static memory does not support small stack please undefine diff --git a/wolfssl/wolfcrypt/sp_int.h b/wolfssl/wolfcrypt/sp_int.h index dcec35ac4..1b1faa9aa 100644 --- a/wolfssl/wolfcrypt/sp_int.h +++ b/wolfssl/wolfcrypt/sp_int.h @@ -724,6 +724,11 @@ typedef struct sp_ecc_ctx { /* Unused error. Defined for backward compatability. */ #define MP_RANGE MP_NOT_INF +#ifdef USE_FAST_MATH +/* For old FIPS, need FP_MEM defined for old implementation. */ +#define FP_MEM (-2) +#endif + /* Number of bits in each word/digit. */ #define DIGIT_BIT SP_WORD_SIZE /* Mask of all used bits in word/digit. */ @@ -846,7 +851,8 @@ MP_API int sp_sub(sp_int* a, sp_int* b, sp_int* r); defined(WOLFCRYPT_HAVE_ECCSI) || defined(WOLFCRYPT_HAVE_SAKKE) MP_API int sp_addmod(sp_int* a, sp_int* b, sp_int* m, sp_int* r); #endif -#if defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY) +#if defined(WOLFSSL_SP_MATH_ALL) && (!defined(WOLFSSL_RSA_VERIFY_ONLY) || \ + defined(HAVE_ECC)) MP_API int sp_submod(sp_int* a, sp_int* b, sp_int* m, sp_int* r); #endif #if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC) @@ -913,7 +919,8 @@ MP_API int sp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng); #if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) MP_API int sp_gcd(sp_int* a, sp_int* b, sp_int* r); #endif -#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && !defined(WC_RSA_BLINDING) +#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \ + (!defined(WC_RSA_BLINDING) || defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) MP_API int sp_lcm(sp_int* a, sp_int* b, sp_int* r); #endif