diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 5099e72cd..dc86b99ef 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -56,6 +56,7 @@ CONFIG_CRYPTO_AES CONFIG_CRYPTO_CBC CONFIG_CRYPTO_CTR CONFIG_CRYPTO_DH +CONFIG_CRYPTO_DH_RFC7919_GROUPS CONFIG_CRYPTO_ECB CONFIG_CRYPTO_ECDH CONFIG_CRYPTO_ECDSA diff --git a/linuxkm/lkcapi_dh_glue.c b/linuxkm/lkcapi_dh_glue.c index a4ff71258..70f4e9923 100644 --- a/linuxkm/lkcapi_dh_glue.c +++ b/linuxkm/lkcapi_dh_glue.c @@ -56,10 +56,24 @@ #undef LINUXKM_LKCAPI_REGISTER_DH #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) + /* Support for FFDHE was added in kernel 5.18, and generic DH support + * pre-5.18 used a different binary format for the secret (an additional + * slot for q). + * + * LTS backports of FFDHE go as far back as 4.14.236, using the pre-5.18 + * binary layout, but other backports, e.g. RHEL 9.5 on kernel + * 5.14.0-503.40.1, have the 5.18+ layout. Best to disable on all pre-5.18 + * and triage as/if necessary. + */ + #undef LINUXKM_LKCAPI_REGISTER_DH +#endif + #if defined(LINUXKM_LKCAPI_REGISTER_ALL_KCONFIG) && \ - defined(CONFIG_CRYPTO_DH) && \ + (defined(CONFIG_CRYPTO_DH) || defined(CONFIG_CRYPTO_DH_RFC7919_GROUPS)) && \ !defined(LINUXKM_LKCAPI_REGISTER_DH) - #error Config conflict: target kernel has CONFIG_CRYPTO_DH, but module is missing LINUXKM_LKCAPI_REGISTER_DH. + #error Config conflict: target kernel has CONFIG_CRYPTO_DH and/or \ + _DH_RFC7919_GROUPS, but module is missing LINUXKM_LKCAPI_REGISTER_DH. #endif #if defined(LINUXKM_LKCAPI_REGISTER_DH) diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index e3a003cf1..13eaf638c 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -31,19 +31,6 @@ This library provides single precision (SP) integer math functions. #if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) -#if (!defined(WOLFSSL_SMALL_STACK) && !defined(SP_ALLOC)) || \ - defined(WOLFSSL_SP_NO_MALLOC) -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(WOLFSSL_SP_NO_DYN_STACK) -PRAGMA_GCC_DIAG_PUSH -/* We are statically declaring a variable smaller than sp_int. - * We track available memory in the 'size' field. - * Disable warnings of sp_int being partly outside array bounds of variable. - */ -PRAGMA_GCC("GCC diagnostic ignored \"-Warray-bounds\"") -#endif -#endif - #ifdef NO_INLINE #include #else @@ -112,6 +99,15 @@ PRAGMA_GCC("GCC diagnostic ignored \"-Warray-bounds\"") #include +#ifdef WOLFSSL_SP_DYN_STACK +/* We are statically declaring a variable smaller than sp_int. + * We track available memory in the 'size' field. + * Disable warnings of sp_int being partly outside array bounds of variable. + */ + PRAGMA_GCC_DIAG_PUSH + PRAGMA_GCC("GCC diagnostic ignored \"-Warray-bounds\"") +#endif + #if defined(WOLFSSL_LINUXKM) && !defined(WOLFSSL_SP_ASM) /* force off unneeded vector register save/restore. */ #undef SAVE_VECTOR_REGISTERS @@ -127,8 +123,7 @@ PRAGMA_GCC("GCC diagnostic ignored \"-Warray-bounds\"") #define DECL_SP_INT(n, s) \ sp_int* n = NULL #else - #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(WOLFSSL_SP_NO_DYN_STACK) + #ifdef WOLFSSL_SP_DYN_STACK /* Declare a variable on the stack with the required data size. */ #define DECL_SP_INT(n, s) \ sp_int_digit n##d[MP_INT_SIZEOF_DIGITS(s)]; \ @@ -218,8 +213,7 @@ PRAGMA_GCC("GCC diagnostic ignored \"-Warray-bounds\"") /* Declare a variable that will be assigned a value on XMALLOC. */ #define DECL_SP_INT_ARRAY(n, s, c) \ DECL_DYN_SP_INT_ARRAY(n, s, c) -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(WOLFSSL_SP_NO_DYN_STACK) +#elif defined(WOLFSSL_SP_DYN_STACK) /* Declare a variable on the stack with the required data size. */ #define DECL_SP_INT_ARRAY(n, s, c) \ sp_int_digit n##d[MP_INT_SIZEOF_DIGITS(s) * (c)]; \ @@ -264,8 +258,7 @@ while (0) !defined(WOLFSSL_SP_NO_MALLOC) #define ALLOC_SP_INT_ARRAY(n, s, c, err, h) \ ALLOC_DYN_SP_INT_ARRAY(n, s, c, err, h) -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(WOLFSSL_SP_NO_DYN_STACK) +#elif defined(WOLFSSL_SP_DYN_STACK) /* Data declared on stack that supports multiple sp_ints of the * required size. Use pointers into data to make up array and set sizes. */ @@ -9175,8 +9168,7 @@ static int _sp_mul_nxn(const sp_int* a, const sp_int* b, sp_int* r) unsigned int k; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) sp_int_digit* t = NULL; -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(WOLFSSL_SP_NO_DYN_STACK) +#elif defined(WOLFSSL_SP_DYN_STACK) sp_int_digit t[a->used]; #else sp_int_digit t[SP_INT_DIGITS / 2]; @@ -9252,8 +9244,7 @@ static int _sp_mul(const sp_int* a, const sp_int* b, sp_int* r) sp_size_t k; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) sp_int_digit* t = NULL; -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(WOLFSSL_SP_NO_DYN_STACK) +#elif defined(WOLFSSL_SP_DYN_STACK) sp_int_digit t[a->used + b->used]; #else sp_int_digit t[SP_INT_DIGITS]; @@ -9329,8 +9320,7 @@ static int _sp_mul(const sp_int* a, const sp_int* b, sp_int* r) sp_size_t k; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) sp_int_digit* t = NULL; -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(WOLFSSL_SP_NO_DYN_STACK) +#elif defined(WOLFSSL_SP_DYN_STACK) sp_int_digit t[a->used + b->used]; #else sp_int_digit t[SP_INT_DIGITS]; @@ -14879,8 +14869,7 @@ static int _sp_sqr(const sp_int* a, sp_int* r) sp_size_t k; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) sp_int_digit* t = NULL; -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(WOLFSSL_SP_NO_DYN_STACK) +#elif defined(WOLFSSL_SP_DYN_STACK) sp_int_digit t[((a->used + 1) / 2) * 2 + 1]; #else sp_int_digit t[(SP_INT_DIGITS + 1) / 2]; @@ -14994,8 +14983,7 @@ static int _sp_sqr(const sp_int* a, sp_int* r) sp_size_t k; #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) sp_int_digit* t = NULL; -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(WOLFSSL_SP_NO_DYN_STACK) +#elif defined(WOLFSSL_SP_DYN_STACK) sp_int_digit t[a->used * 2]; #else sp_int_digit t[SP_INT_DIGITS]; @@ -19891,12 +19879,8 @@ void sp_memzero_check(sp_int* sp) } #endif /* WOLFSSL_CHECK_MEM_ZERO */ -#if (!defined(WOLFSSL_SMALL_STACK) && !defined(SP_ALLOC)) || \ - defined(WOLFSSL_SP_NO_MALLOC) -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(WOLFSSL_SP_NO_DYN_STACK) -PRAGMA_GCC_DIAG_POP -#endif +#ifdef WOLFSSL_SP_DYN_STACK + PRAGMA_GCC_DIAG_POP #endif #endif /* WOLFSSL_SP_MATH || WOLFSSL_SP_MATH_ALL */ diff --git a/wolfssl/wolfcrypt/sp_int.h b/wolfssl/wolfcrypt/sp_int.h index e9eacf42e..f31aa9207 100644 --- a/wolfssl/wolfcrypt/sp_int.h +++ b/wolfssl/wolfcrypt/sp_int.h @@ -260,9 +260,6 @@ extern "C" { #endif #endif -/* Number of bytes in each word. */ -#define SP_WORD_SIZEOF (SP_WORD_SIZE / 8) - /* Define the types used. */ #if defined(HAVE___UINT128_T) && !defined(NO_INT128) #ifdef __SIZEOF_INT128__ @@ -285,6 +282,8 @@ extern "C" { #endif #if SP_WORD_SIZE == 8 + #define SP_WORD_SIZEOF 1 + typedef sp_uint8 sp_int_digit; typedef sp_int8 sp_int_sdigit; typedef sp_uint16 sp_int_word; @@ -292,6 +291,8 @@ extern "C" { #define SP_MASK 0xffU #elif SP_WORD_SIZE == 16 + #define SP_WORD_SIZEOF 2 + typedef sp_uint16 sp_int_digit; typedef sp_int16 sp_int_sdigit; typedef sp_uint32 sp_int_word; @@ -299,6 +300,8 @@ extern "C" { #define SP_MASK 0xffffU #elif SP_WORD_SIZE == 32 + #define SP_WORD_SIZEOF 4 + typedef sp_uint32 sp_int_digit; typedef sp_int32 sp_int_sdigit; typedef sp_uint64 sp_int_word; @@ -306,6 +309,8 @@ extern "C" { #define SP_MASK 0xffffffffU #elif SP_WORD_SIZE == 64 + #define SP_WORD_SIZEOF 8 + typedef sp_uint64 sp_int_digit; typedef sp_int64 sp_int_sdigit; #if (defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \ @@ -788,11 +793,19 @@ typedef struct sp_ecc_ctx { #define MP_INT_NEXT(t, cnt) \ (sp_int*)(((byte*)(t)) + MP_INT_SIZEOF(cnt)) +#define MP_INT_SIZEOF_DIGITS(cnt) (MP_INT_SIZEOF(cnt) / sizeof(sp_int_digit)) /* Calculate the number of words required to support a number of bits. */ #define MP_BITS_CNT(bits) \ ((unsigned int)(((((bits) + SP_WORD_SIZE - 1) / SP_WORD_SIZE) * 2 + 1))) +#if !defined(WOLFSSL_SP_NO_DYN_STACK) && defined(__STDC_VERSION__) && \ + (__STDC_VERSION__ >= 199901L) && \ + (defined(WOLFSSL_SP_NO_MALLOC) || \ + !(defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC))) + #define WOLFSSL_SP_DYN_STACK +#endif + #ifdef WOLFSSL_SMALL_STACK /* * Dynamic memory allocation of mp_int. @@ -823,26 +836,25 @@ while (0) /* * Static allocation of mp_int. */ -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(WOLFSSL_SP_NO_DYN_STACK) +#ifdef WOLFSSL_SP_DYN_STACK /* Declare a dynamically allocated mp_int. */ -#define DECL_MP_INT_SIZE_DYN(name, bits, max) \ - unsigned char name##d[MP_INT_SIZEOF(MP_BITS_CNT(bits))]; \ +#define DECL_MP_INT_SIZE_DYN(name, bits, max) \ + sp_int_digit name##d[MP_INT_SIZEOF_DIGITS(MP_BITS_CNT(bits))]; \ sp_int* (name) = (sp_int*)name##d #elif defined(__cplusplus) /* C++ doesn't tolerate parentheses around "name" (-Wparentheses) */ -#define DECL_MP_INT_SIZE_DYN(name, bits, max) \ - unsigned char name##d[MP_INT_SIZEOF(MP_BITS_CNT(max))]; \ +#define DECL_MP_INT_SIZE_DYN(name, bits, max) \ + sp_int_digit name##d[MP_INT_SIZEOF_DIGITS(MP_BITS_CNT(max))]; \ sp_int* name = (sp_int*)name##d #else /* Declare a dynamically allocated mp_int. */ -#define DECL_MP_INT_SIZE_DYN(name, bits, max) \ - unsigned char name##d[MP_INT_SIZEOF(MP_BITS_CNT(max))]; \ +#define DECL_MP_INT_SIZE_DYN(name, bits, max) \ + sp_int_digit name##d[MP_INT_SIZEOF_DIGITS(MP_BITS_CNT(max))]; \ sp_int* (name) = (sp_int*)name##d #endif /* Declare a statically allocated mp_int. */ -#define DECL_MP_INT_SIZE(name, bits) \ - unsigned char name##d[MP_INT_SIZEOF(MP_BITS_CNT(bits))]; \ +#define DECL_MP_INT_SIZE(name, bits) \ + sp_int_digit name##d[MP_INT_SIZEOF_DIGITS(MP_BITS_CNT(bits))]; \ sp_int* (name) = (sp_int*)name##d /* Zero out mp_int of minimal size. */ #define NEW_MP_INT_SIZE(name, bits, heap, type) \ @@ -910,7 +922,7 @@ typedef struct sp_int { struct WC_BIGINT raw; #endif /** Data of number. */ - sp_int_digit dp[SP_INT_DIGITS]; + XALIGNED(SP_WORD_SIZEOF) sp_int_digit dp[SP_INT_DIGITS]; } sp_int; typedef struct sp_int_minimal { @@ -927,11 +939,14 @@ typedef struct sp_int_minimal { struct WC_BIGINT raw; #endif /** First digit of number. */ - sp_int_digit dp[1]; + XALIGNED(SP_WORD_SIZEOF) sp_int_digit dp[1]; } sp_int_minimal; +/* MP_INT_SIZEOF_DIGITS() requires that sizeof(sp_int) is a multiple of + * sizeof(sp_int_digit). + */ +wc_static_assert(sizeof(struct sp_int) % sizeof(sp_int_digit) == 0); wc_static_assert(sizeof(struct sp_int_minimal) % sizeof(sp_int_digit) == 0); -#define MP_INT_SIZEOF_DIGITS(cnt) (MP_INT_SIZEOF(cnt) / sizeof(sp_int_digit)) /* Multi-precision integer type is SP integer type. */ typedef sp_int mp_int;