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;