From 6d2a41b9fdfb310602814c523fefd4f7bb8a01d8 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 14 Jan 2022 14:02:55 -0800 Subject: [PATCH 1/3] Enable wolfSSL SP Math all (sp_int.c) by default. If `--enable-fastmath` or `USE_FAST_MATH` is set the older `tfm.c` fast math will be used. To use the old `integer.c` heap math use `--enable-heapmath` or `USE_INTEGER_HEAP_MATH`. --- configure.ac | 118 ++++++++++++++++++----------------- src/include.am | 2 +- wolfcrypt/src/asn.c | 5 ++ wolfcrypt/src/integer.c | 4 +- wolfcrypt/src/sp_int.c | 27 +++++--- wolfcrypt/src/wolfmath.c | 2 +- wolfssl/wolfcrypt/settings.h | 35 ++++++++++- wolfssl/wolfcrypt/sp_int.h | 27 +++++--- 8 files changed, 140 insertions(+), 80 deletions(-) diff --git a/configure.ac b/configure.ac index 5b9645b26..1d160c8ba 100644 --- a/configure.ac +++ b/configure.ac @@ -494,15 +494,6 @@ fi # Single Precision maths implementation -if test "$ENABLED_LINUXKM_DEFAULTS" = "yes" -then - ENABLED_SP_DEFAULT=yes - ENABLED_SP_MATH_ALL_DEFAULT=yes -else - ENABLED_SP_DEFAULT=no - ENABLED_SP_MATH_ALL_DEFAULT=no -fi - AC_ARG_ENABLE([sp], [AS_HELP_STRING([--enable-sp],[Enable Single Precision maths implementation (default: disabled)])], [ ENABLED_SP=$enableval ], @@ -510,12 +501,12 @@ 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: disabled)])], + [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=$ENABLED_SP_MATH_ALL_DEFAULT ], + [ ENABLED_SP_MATH_ALL=yes ], ) -# Single Precision maths exclusively (no fastmath) +# Single Precision maths (acceleration for common key sizes and curves) if test "$ENABLED_LINUXKM_DEFAULTS" = "yes" && test "$ENABLED_SP" != "no" && test "$ENABLED_SP_MATH_ALL" = "no" then ENABLED_SP_MATH_DEFAULT=yes @@ -528,13 +519,22 @@ AC_ARG_ENABLE([sp-math], [ ENABLED_SP_MATH=$ENABLED_SP_MATH_DEFAULT ], ) - +# 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" +then + if test "$host_cpu" = "x86_64" || test "$host_cpu" = "aarch64" + then + SP_ASM_DEFAULT=yes + fi +fi AC_ARG_ENABLE([sp-asm], - [AS_HELP_STRING([--enable-sp-asm],[Enable Single Precision assembly implementation (default: disabled)])], + [AS_HELP_STRING([--enable-sp-asm],[Enable Single Precision assembly implementation (default: enabled on x86_64/aarch64)])], [ ENABLED_SP_ASM=$enableval ], - [ ENABLED_SP_ASM=no ], + [ ENABLED_SP_ASM=$SP_ASM_DEFAULT ], ) + # ALL FEATURES AC_ARG_ENABLE([all], [AS_HELP_STRING([--enable-all],[Enable all wolfSSL features, except SSLv3 (default: disabled)])], @@ -677,7 +677,7 @@ then if test "$ENABLED_LINUXKM_DEFAULTS" != "yes" then -# these use DES3: + # these use DES3: test "$enable_stunnel" = "" && enable_stunnel=yes test "$enable_curl" = "" && enable_curl=yes test "$enable_tcpdump" = "" && enable_tcpdump=yes @@ -1417,7 +1417,7 @@ then DEFAULT_MAX_CLASSIC_ASYM_KEY_BITS=4096 fi -ENABLED_SLOWMATH="yes" +ENABLED_HEAPMATH="yes" # lean psk build AC_ARG_ENABLE([leanpsk], @@ -3465,11 +3465,12 @@ then AC_MSG_ERROR([please disable dsa if disabling asn.]) fi -# DH and ECC need bigint +# No Big Int (ASN, RSA, DH and ECC need bigint) if test "$ENABLED_ASN" = "no" && test "$ENABLED_DH" = "no" && test "$ENABLED_ECC" = "no" && test "$ENABLED_RSA" = "no" then + ENABLED_SP_MATH_ALL=no ENABLED_FASTMATH=no - ENABLED_SLOWMATH=no + ENABLED_HEAPMATH=no fi @@ -5732,30 +5733,16 @@ then fi fi -# set fastmath default -FASTMATH_DEFAULT=no - -if test "$host_cpu" = "x86_64" || test "$host_cpu" = "aarch64" -then - FASTMATH_DEFAULT=yes -fi -if test "$ENABLED_LINUXKM_DEFAULTS" = "yes" -then - FASTMATH_DEFAULT=no -fi -if test "$ENABLED_SP_MATH" = "yes" -then - FASTMATH_DEFAULT=no -fi # fastmath AC_ARG_ENABLE([fastmath], - [AS_HELP_STRING([--enable-fastmath],[Enable fast math ops (default: enabled on x86_64/aarch64)])], + [AS_HELP_STRING([--enable-fastmath],[Enable fast math ops (default: disabled)])], [ ENABLED_FASTMATH=$enableval ], - [ ENABLED_FASTMATH=$FASTMATH_DEFAULT] + [ ENABLED_FASTMATH=no] ) -if test "x$ENABLED_FASTMATH" = "xyes" +# if sp-math-all is not set, then enable fast math +if test "x$ENABLED_FASTMATH" = "xyes" && test "$enable_sp_math_all" = "" then # turn off fastmth if leanpsk on or asn off (w/o DH and ECC) if test "$ENABLED_LEANPSK" = "yes" || test "$ENABLED_ASN" = "no" @@ -5765,11 +5752,12 @@ then ENABLED_FASTMATH=no else AM_CFLAGS="$AM_CFLAGS -DUSE_FAST_MATH" - ENABLED_SLOWMATH="no" + ENABLED_HEAPMATH=no fi else AM_CFLAGS="$AM_CFLAGS -DUSE_FAST_MATH" - ENABLED_SLOWMATH="no" + ENABLED_HEAPMATH="no" + ENABLED_SP_MATH_ALL=no fi if test "$host_cpu" = "x86_64" then @@ -5784,6 +5772,18 @@ then fi fi +# heap based integer.c math (not timing resistant) +AC_ARG_ENABLE([heapmath], + [AS_HELP_STRING([--enable-heapmath],[Enable heap based integer.c math ops (default: disabled)])], + [ ENABLED_HEAPMATH=$enableval ], + [ ENABLED_HEAPMATH=no] + ) +if test "x$ENABLED_HEAPMATH" = "xyes" +then + AM_CFLAGS="$AM_CFLAGS -DUSE_INTEGER_HEAP_MATH" + ENABLED_HEAPMATH=yes + ENABLED_SP_MATH_ALL=no +fi # fast HUGE math AC_ARG_ENABLE([fasthugemath], @@ -5801,7 +5801,7 @@ if test "$ENABLED_FASTHUGEMATH" = "yes" then ENABLED_FASTMATH="yes" AM_CFLAGS="$AM_CFLAGS -DUSE_FAST_MATH" - ENABLED_SLOWMATH="no" + ENABLED_HEAPMATH="no" fi @@ -6369,9 +6369,6 @@ if test "$ENABLED_SP_MATH" = "yes"; then if test "$ENABLED_SP_DH" = "no" && test "$ENABLED_DH" = "yes"; then AC_MSG_ERROR([Cannot use DH single precision only math and DH]) fi - - ENABLED_FASTMATH="no" - ENABLED_SLOWMATH="no" fi for v in `echo $ENABLED_SP_MATH_ALL | tr "," " "` @@ -6695,6 +6692,10 @@ if test "x$ENABLED_STATICMEMORY" = "xyes" then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_STATIC_MEMORY" + if test "x$ENABLED_HEAPMATH" = "xyes" + then + AC_MSG_ERROR([please use --enable-fastmath if enabling staticmemory.]) + fi if test "$ENABLED_LOWRESOURCE" = "yes" && test "$ENABLED_RSA" = "no" then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_STATIC_MEMORY_SMALL" @@ -7812,7 +7813,7 @@ AM_CONDITIONAL([BUILD_PWDBASED],[test "x$ENABLED_PWDBASED" = "xyes" || test "x$E AM_CONDITIONAL([BUILD_SCRYPT],[test "x$ENABLED_SCRYPT" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_CRYPTONLY],[test "x$ENABLED_CRYPTONLY" = "xyes" && test "x$ENABLED_OPENSSLEXTRA" = "xno"]) AM_CONDITIONAL([BUILD_FASTMATH],[test "x$ENABLED_FASTMATH" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) -AM_CONDITIONAL([BUILD_SLOWMATH],[test "x$ENABLED_SLOWMATH" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_HEAPMATH],[test "x$ENABLED_HEAPMATH" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_EXAMPLE_SERVERS],[test "x$ENABLED_EXAMPLES" = "xyes" && test "x$ENABLED_LEANTLS" = "xno"]) AM_CONDITIONAL([BUILD_EXAMPLE_CLIENTS],[test "x$ENABLED_EXAMPLES" = "xyes"]) AM_CONDITIONAL([BUILD_TESTS],[test "x$ENABLED_EXAMPLES" = "xyes"]) @@ -8092,7 +8093,21 @@ echo " * Old Names: $ENABLED_OLDNAMES" echo " * Max Strength Build: $ENABLED_MAXSTRENGTH" echo " * Distro Build: $ENABLED_DISTRO" echo " * Reproducible Build: $ENABLED_REPRODUCIBLE_BUILD" -echo " * fastmath: $ENABLED_FASTMATH" +echo " * Single Precision Math: $ENABLED_SP" +if test "$ENABLED_SP_MATH_ALL" != "no" +then + ENABLED_SP_MATH_DESC="all" +else + if test "$ENABLED_SP_MATH" != "no" + then + ENABLED_SP_MATH_DESC="restricted" + else + ENABLED_SP_MATH_DESC="no" + fi +fi +echo " * SP implementation: $ENABLED_SP_MATH_DESC" +echo " * Fast Math: $ENABLED_FASTMATH" +echo " * Heap Math: $ENABLED_HEAPMATH" echo " * Assembly Allowed: $ENABLED_ASM" echo " * sniffer: $ENABLED_SNIFFER" echo " * snifftest: $ENABLED_SNIFFTEST" @@ -8243,19 +8258,6 @@ echo " * Stack sizes in tests: $ENABLED_STACKSIZE" echo " * Heap stats in tests: $ENABLED_TRACKMEMORY" echo " * User Crypto: $ENABLED_USER_CRYPTO" echo " * Fast RSA: $ENABLED_FAST_RSA" -echo " * Single Precision: $ENABLED_SP" -if test "$ENABLED_SP_MATH_ALL" != "no" -then - ENABLED_SP_MATH_DESC="all" -else - if test "$ENABLED_SP_MATH" != "no" - then - ENABLED_SP_MATH_DESC="restricted" - else - ENABLED_SP_MATH_DESC="no" - fi -fi -echo " * SP math implementation: $ENABLED_SP_MATH_DESC" echo " * Async Crypto: $ENABLED_ASYNCCRYPT" echo " * PKCS#8: $ENABLED_PKCS8" echo " * PKCS#11: $ENABLED_PKCS11" diff --git a/src/include.am b/src/include.am index 7e3e466aa..361bf6a89 100644 --- a/src/include.am +++ b/src/include.am @@ -560,7 +560,7 @@ if BUILD_FASTMATH src_libwolfssl_la_SOURCES += wolfcrypt/src/tfm.c endif -if BUILD_SLOWMATH +if BUILD_HEAPMATH src_libwolfssl_la_SOURCES += wolfcrypt/src/integer.c endif diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 824736503..581bc2f28 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -1184,6 +1184,8 @@ static int GetASN_StoreData(const ASNItem* asn, ASNGetData* data, return ASN_GETINT_E; } #endif /* HAVE_WOLF_BIGINT */ + + #ifdef WOLFSSL_SP_INT_NEGATIVE /* Don't always read as positive. */ if ((data->dataType == ASN_DATA_TYPE_MP_POS_NEG) && (!zeroPadded) && (input[idx] & 0x80)) { @@ -1203,6 +1205,9 @@ static int GetASN_StoreData(const ASNItem* asn, ASNGetData* data, return ASN_GETINT_E; #endif } + #else + (void)zeroPadded; + #endif break; case ASN_DATA_TYPE_CHOICE: diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 2f9ddc841..4efd61d1f 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -43,7 +43,7 @@ #ifndef NO_BIG_INT -#ifndef USE_FAST_MATH +#if !defined(USE_FAST_MATH) && defined(USE_INTEGER_HEAP_MATH) #ifndef WOLFSSL_SP_MATH @@ -5483,6 +5483,6 @@ void mp_dump(const char* desc, mp_int* a, byte verbose) #endif /* WOLFSSL_SP_MATH */ -#endif /* USE_FAST_MATH */ +#endif /* !USE_FAST_MATH && USE_INTEGER_HEAP_MATH */ #endif /* NO_BIG_INT */ diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index e1231d5be..0f551fc7d 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -4328,6 +4328,9 @@ 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. @@ -4347,14 +4350,19 @@ int sp_init(sp_int* a) if (err == MP_OKAY) { _sp_zero(a); a->size = SP_INT_DIGITS; - #ifdef HAVE_WOLF_BIGINT - wc_bigint_init(&a->raw); - #endif } return err; } +/* Initialize the multi-precision number to be zero and have a maximum size. + * + * @param [out] a SP integer. + * @param [in] size Number of words to say are available. + * + * @return MP_OKAY on success. + * @return MP_VAL when a is NULL. + */ int sp_init_size(sp_int* a, int size) { int err = sp_init(a); @@ -5183,7 +5191,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 #if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ @@ -14758,7 +14767,7 @@ int sp_to_unsigned_bin_len(sp_int* a, byte* out, int outSz) for (i = 0; (j >= 0) && (i < a->used); i++) { int b; for (b = 0; b < SP_WORD_SIZE; b += 8) { - out[j--] = (byte) (a->dp[i] >> b); + out[j--] = (byte)(a->dp[i] >> b); if (j < 0) { break; } @@ -15040,11 +15049,11 @@ int sp_tohex(sp_int* a, char* str) #endif /* WC_DISABLE_RADIX_ZERO_PAD */ /* Most-significant word. */ for (; j >= 0; j -= 4) { - *(str++) = ByteToHex((byte) (a->dp[i] >> j)); + *(str++) = ByteToHex((byte)(a->dp[i] >> j)); } for (--i; i >= 0; i--) { for (j = SP_WORD_SIZE - 4; j >= 0; j -= 4) { - *(str++) = (byte) ByteToHex((byte) (a->dp[i] >> j)); + *(str++) = (byte)ByteToHex((byte)(a->dp[i] >> j)); } } *str = '\0'; @@ -15104,14 +15113,14 @@ int sp_todecimal(sp_int* a, char* str) i = 0; while (!sp_iszero(t)) { sp_div_d(t, 10, t, &d); - str[i++] = (char) ('0' + d); + str[i++] = (char)('0' + d); } str[i] = '\0'; for (j = 0; j <= (i - 1) / 2; j++) { int c = (unsigned char)str[j]; str[j] = str[i - 1 - j]; - str[i - 1 - j] = (char) c; + str[i - 1 - j] = (char)c; } } diff --git a/wolfcrypt/src/wolfmath.c b/wolfcrypt/src/wolfmath.c index 149b6a810..1c0d33540 100644 --- a/wolfcrypt/src/wolfmath.c +++ b/wolfcrypt/src/wolfmath.c @@ -344,7 +344,7 @@ void wc_bigint_free(WC_BIGINT* a) /* sz: make sure the buffer is at least that size and zero padded. * A `sz == 0` will use the size of `src`. - * The calculates sz is stored into dst->len in `wc_bigint_alloc`. + * The calculated sz is stored into dst->len in `wc_bigint_alloc`. */ int wc_mp_to_bigint_sz(mp_int* src, WC_BIGINT* dst, word32 sz) { diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index cb70ad9e8..3fbdcb2f6 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1881,6 +1881,39 @@ extern void uITRON4_free(void *p) ; #pragma warning(disable:2259) /* explicit casts to smaller sizes, disable */ #endif + + +/* --------------------------------------------------------------------------- + * 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 + #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 +/*----------------------------------------------------------------------------*/ + + + + /* user can specify what curves they want with ECC_USER_CURVES otherwise * all curves are on by default for now */ #ifndef ECC_USER_CURVES @@ -1890,7 +1923,7 @@ extern void uITRON4_free(void *p) ; #endif /* The minimum allowed ECC key size */ -/* Note: 224-bits is equivelant to 2048-bit RSA */ +/* Note: 224-bits is equivalent to 2048-bit RSA */ #ifndef ECC_MIN_KEY_SZ #ifdef WOLFSSL_MIN_ECC_BITS #define ECC_MIN_KEY_SZ WOLFSSL_MIN_ECC_BITS diff --git a/wolfssl/wolfcrypt/sp_int.h b/wolfssl/wolfcrypt/sp_int.h index 4492bdee9..dcec35ac4 100644 --- a/wolfssl/wolfcrypt/sp_int.h +++ b/wolfssl/wolfcrypt/sp_int.h @@ -361,7 +361,8 @@ typedef struct sp_ecc_ctx { /* Calculate number of digits to have in an sp_int based maximum size of * numbers in bits that will be used. * Double the size to hold multiplication result. - * Add one to accommodate extra digit used by sp_mul(), sp_mulmod(), sp_sqr(), and sp_sqrmod(). + * Add one to accommodate extra digit used by sp_mul(), sp_mulmod(), + * sp_sqr(), and sp_sqrmod(). */ #define SP_INT_DIGITS \ ((((SP_INT_BITS + (SP_WORD_SIZE - 1)) * 2 + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) @@ -374,7 +375,17 @@ typedef struct sp_ecc_ctx { #if !defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_HAVE_SP_DH) && \ !defined(WOLFSSL_HAVE_SP_ECC) #if !defined(NO_RSA) || !defined(NO_DH) || !defined(NO_DSA) - #define SP_INT_DIGITS (((6144 + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) + /* large SP math requires 2048-bits + */ + #if !defined(NO_DH) && defined(HAVE_FFDHE_8192) + #define SP_INT_DIGITS (((16384 + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) + #elif !defined(NO_DH) && defined(HAVE_FFDHE_6144) + #define SP_INT_DIGITS (((12288 + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) + #elif !defined(NO_DH) && defined(HAVE_FFDHE_4096) + #define SP_INT_DIGITS (((8192 + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) + #else + /* all else */ + #define SP_INT_DIGITS (((6144 + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) + #endif #elif defined(WOLFCRYPT_HAVE_SAKKE) #define SP_INT_DIGITS \ (((2 * (1024 + SP_WORD_SIZE) + SP_WORD_SIZE) / SP_WORD_SIZE) + 1) @@ -435,7 +446,7 @@ typedef struct sp_ecc_ctx { #define SP_INT_WORD_MAX ((1 << (SP_WORD_SIZE * 2)) - 1) #if SP_MUL_SQR_MAX_PARTIAL > SP_INT_WORD_MAX - /* The sum of the partials in the multiplicaiton/square can exceed the + /* The sum of the partials in the multiplication/square can exceed the * size of a word. This will overflow the word and loose data. * Use an implementation that handles carry after every add and uses an * extra temporary word for overflowing high word. @@ -652,7 +663,7 @@ typedef struct sp_ecc_ctx { * Use the number of bits in a digit as indication of how code was compiled. * * @return 1 when the number of bits are the same. - * @return 0 when the number of bits are differnt. + * @return 0 when the number of bits are different. */ #define CheckFastMathSettings() (SP_WORD_SIZE == CheckRunTimeFastMath()) @@ -668,12 +679,12 @@ typedef struct sp_ecc_ctx { (sp_int*)(((byte*)(t)) + MP_INT_SIZEOF(cnt)) /** - * A reuslt of NO. + * A result of NO. * e.g. Is prime? NO. */ #define MP_NO 0 /** - * A reuslt of YES. + * A result of YES. * e.g. Is prime? YES. */ #define MP_YES 1 @@ -760,9 +771,9 @@ typedef struct sp_int { sp_int_digit dp[SP_INT_DIGITS]; } sp_int; -/* Mulit-precision integer type is SP integer type. */ +/* Multi-precision integer type is SP integer type. */ typedef sp_int mp_int; -/* Mulit-precision integer digit type is SP integer digit type. +/* Multi-precision integer digit type is SP integer digit type. * Type is unsigned. */ typedef sp_int_digit mp_digit; From ee12c12e98ec19b50727a2677b1674fbaec7d24b Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 19 Jan 2022 10:20:21 +1000 Subject: [PATCH 2/3] 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 From 78d3284c3c40162471de880600ef5153e41b7d26 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 23 Jun 2022 09:45:13 -0700 Subject: [PATCH 3/3] Fix for FIPS 140-2 and older ACVP math selection. Fix for building with "--disable-sp-math-all --disable-fastmath". Fix for building SAKKE with `HAVE_WOLF_BIGINT`. --- configure.ac | 2 +- wolfcrypt/src/wolfmath.c | 3 +-- wolfcrypt/test/test.c | 12 ++++++------ wolfssl/wolfcrypt/settings.h | 15 ++++++++++++--- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 0184cbc14..b0b0d0f0e 100644 --- a/configure.ac +++ b/configure.ac @@ -5839,7 +5839,7 @@ AC_ARG_ENABLE([heapmath], [ ENABLED_HEAPMATH=$enableval ], [ ENABLED_HEAPMATH=no] ) -if test "x$ENABLED_HEAPMATH" = "xyes" +if test "x$ENABLED_HEAPMATH" = "xyes" || (test "x$ENABLED_SP_MATH_ALL" = "xno" && test "x$ENABLED_FASTMATH" = "xno") then AM_CFLAGS="$AM_CFLAGS -DUSE_INTEGER_HEAP_MATH" ENABLED_HEAPMATH=yes diff --git a/wolfcrypt/src/wolfmath.c b/wolfcrypt/src/wolfmath.c index 1c0d33540..d6772ea1f 100644 --- a/wolfcrypt/src/wolfmath.c +++ b/wolfcrypt/src/wolfmath.c @@ -361,8 +361,7 @@ int wc_mp_to_bigint_sz(mp_int* src, WC_BIGINT* dst, word32 sz) /* make sure destination is allocated and large enough */ err = wc_bigint_alloc(dst, sz); - if (err == MP_OKAY) { - + if (err == MP_OKAY && sz > 0) { /* leading zero pad */ y = sz - x; XMEMSET(dst->buf, 0, y); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 883e6707a..9af7ad2a0 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -30392,7 +30392,7 @@ static int sakke_api_test(WC_RNG* rng, SakkeKey* key, ecc_point* rsk) static int sakke_kat_derive_test(SakkeKey* key, ecc_point* rsk) { - static const byte pubData[] = { + WOLFSSL_SMALL_STACK_STATIC const byte pubData[] = { 0x59, 0x58, 0xEF, 0x1B, 0x16, 0x79, 0xBF, 0x09, 0x9B, 0x3A, 0x03, 0x0D, 0xF2, 0x55, 0xAA, 0x6A, 0x23, 0xC1, 0xD8, 0xF1, 0x43, 0xD4, 0xD2, 0x3F, @@ -30426,7 +30426,7 @@ static int sakke_kat_derive_test(SakkeKey* key, ecc_point* rsk) 0xB5, 0x8B, 0x7C, 0xC7, 0x96, 0xE2, 0x4E, 0x9A, 0x39, 0x40, 0x95, 0x75, 0x4F, 0x5F, 0x8B, 0xAE }; - static const byte rskData[] = { + WOLFSSL_SMALL_STACK_STATIC const byte rskData[] = { 0x93, 0xAF, 0x67, 0xE5, 0x00, 0x7B, 0xA6, 0xE6, 0xA8, 0x0D, 0xA7, 0x93, 0xDA, 0x30, 0x0F, 0xA4, 0xB5, 0x2D, 0x0A, 0x74, 0xE2, 0x5E, 0x6E, 0x7B, @@ -30461,17 +30461,17 @@ static int sakke_kat_derive_test(SakkeKey* key, ecc_point* rsk) 0x33, 0x21, 0x51, 0x23, 0x5D, 0xEC, 0xB0, 0xF5 }; - static const byte id[] = { + WOLFSSL_SMALL_STACK_STATIC const byte id[] = { 0x32, 0x30, 0x31, 0x31, 0x2D, 0x30, 0x32, 0x00, 0x74, 0x65, 0x6C, 0x3A, 0x2B, 0x34, 0x34, 0x37, 0x37, 0x30, 0x30, 0x39, 0x30, 0x30, 0x31, 0x32, 0x33, 0x00 }; - static const byte ssv[] = { + WOLFSSL_SMALL_STACK_STATIC const byte ssv[] = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0 }; - static const byte auth[] = { + WOLFSSL_SMALL_STACK_STATIC const byte auth[] = { 0x04, 0x44, 0xE8, 0xAD, 0x44, 0xAB, 0x85, 0x92, 0xA6, 0xA5, 0xA3, 0xDD, 0xCA, 0x5C, 0xF8, 0x96, 0xC7, @@ -30506,7 +30506,7 @@ static int sakke_kat_derive_test(SakkeKey* key, ecc_point* rsk) 0xC5, 0xE2, 0x75, 0x74, 0xB0, 0x77, 0x39, 0xB3, 0x4B, 0xE7, 0x4A, 0x53, 0x2F, 0x74, 0x7B, 0x86 }; - byte encSsv[] = { + WOLFSSL_SMALL_STACK_STATIC const byte encSsv[] = { 0x89, 0xE0, 0xBC, 0x66, 0x1A, 0xA1, 0xE9, 0x16, 0x38, 0xE6, 0xAC, 0xC8, 0x4E, 0x49, 0x65, 0x07 }; diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 471f4c012..37db16439 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -1886,8 +1886,9 @@ extern void uITRON4_free(void *p) ; /* --------------------------------------------------------------------------- * Math Library Selection (in order of preference) * ---------------------------------------------------------------------------*/ -/* Only evaluate this if it is A) not fips or B) only 140-3 FIPS - * (v5 or greater) */ +/* Only evaluate this if: + * A) Not fips + * B) FIPS 140-3 (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). @@ -1911,7 +1912,15 @@ extern void uITRON4_free(void *p) ; #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 */ + /* 3) Using heap math (integer.c) - USE_INTEGER_HEAP_MATH */ + #endif +#else + /* FIPS 140-2 or older */ + /* Default to fast math (tfm.c), but allow heap math (integer.c) */ + #if !defined(USE_INTEGER_HEAP_MATH) + #undef USE_FAST_MATH + #define USE_FAST_MATH + #define FP_MAX_BITS 8192 #endif #endif /*----------------------------------------------------------------------------*/