wolfssl/wolfcrypt/sp_int.h and wolfcrypt/src/sp_int.c: add WOLFSSL_SP_DYN_STACK macro to orthogonalize gnarly setup logic, and refactor to use it throughout; refactor several more sp_int stack-allocated data buffers as sp_int_digit[]s rather than char[]s.

This commit is contained in:
Daniel Pouzzner
2025-05-14 15:38:12 -05:00
parent f0f4084f94
commit 55bbd84445
2 changed files with 37 additions and 43 deletions

View File

@ -31,17 +31,13 @@ This library provides single precision (SP) integer math functions.
#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) #if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
#if (!defined(WOLFSSL_SMALL_STACK) && !defined(SP_ALLOC)) || \ #ifdef WOLFSSL_SP_DYN_STACK
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 are statically declaring a variable smaller than sp_int.
* We track available memory in the 'size' field. * We track available memory in the 'size' field.
* Disable warnings of sp_int being partly outside array bounds of variable. * Disable warnings of sp_int being partly outside array bounds of variable.
*/ */
PRAGMA_GCC("GCC diagnostic ignored \"-Warray-bounds\"") PRAGMA_GCC_DIAG_PUSH
#endif PRAGMA_GCC("GCC diagnostic ignored \"-Warray-bounds\"")
#endif #endif
#ifdef NO_INLINE #ifdef NO_INLINE
@ -98,7 +94,7 @@ PRAGMA_GCC("GCC diagnostic ignored \"-Warray-bounds\"")
* WOLFSSL_SP_INT_NEGATIVE Enables negative values to be used. * WOLFSSL_SP_INT_NEGATIVE Enables negative values to be used.
* WOLFSSL_SP_INT_DIGIT_ALIGN Enable when unaligned access of sp_int_digit * WOLFSSL_SP_INT_DIGIT_ALIGN Enable when unaligned access of sp_int_digit
* pointer is not allowed. * pointer is not allowed.
* WOLFSSL_SP_NO_DYN_STACK Disable use of dynamic stack items. * WOLFSSL_SP_DYN_STACK Enable use of dynamic stack items.
* Dynamic arrays used when not small stack. * Dynamic arrays used when not small stack.
* WOLFSSL_SP_FAST_MODEXP Allow fast mod_exp with small C code * WOLFSSL_SP_FAST_MODEXP Allow fast mod_exp with small C code
* WOLFSSL_SP_LOW_MEM Use algorithms that use less memory. * WOLFSSL_SP_LOW_MEM Use algorithms that use less memory.
@ -127,8 +123,7 @@ PRAGMA_GCC("GCC diagnostic ignored \"-Warray-bounds\"")
#define DECL_SP_INT(n, s) \ #define DECL_SP_INT(n, s) \
sp_int* n = NULL sp_int* n = NULL
#else #else
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ #ifdef WOLFSSL_SP_DYN_STACK
!defined(WOLFSSL_SP_NO_DYN_STACK)
/* Declare a variable on the stack with the required data size. */ /* Declare a variable on the stack with the required data size. */
#define DECL_SP_INT(n, s) \ #define DECL_SP_INT(n, s) \
sp_int_digit n##d[MP_INT_SIZEOF_DIGITS(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. */ /* Declare a variable that will be assigned a value on XMALLOC. */
#define DECL_SP_INT_ARRAY(n, s, c) \ #define DECL_SP_INT_ARRAY(n, s, c) \
DECL_DYN_SP_INT_ARRAY(n, s, c) DECL_DYN_SP_INT_ARRAY(n, s, c)
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ #elif defined(WOLFSSL_SP_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
/* Declare a variable on the stack with the required data size. */ /* Declare a variable on the stack with the required data size. */
#define DECL_SP_INT_ARRAY(n, s, c) \ #define DECL_SP_INT_ARRAY(n, s, c) \
sp_int_digit n##d[MP_INT_SIZEOF_DIGITS(s) * (c)]; \ sp_int_digit n##d[MP_INT_SIZEOF_DIGITS(s) * (c)]; \
@ -264,8 +258,7 @@ while (0)
!defined(WOLFSSL_SP_NO_MALLOC) !defined(WOLFSSL_SP_NO_MALLOC)
#define ALLOC_SP_INT_ARRAY(n, s, c, err, h) \ #define ALLOC_SP_INT_ARRAY(n, s, c, err, h) \
ALLOC_DYN_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) && \ #elif defined(WOLFSSL_SP_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
/* Data declared on stack that supports multiple sp_ints of the /* Data declared on stack that supports multiple sp_ints of the
* required size. Use pointers into data to make up array and set sizes. * 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; unsigned int k;
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
sp_int_digit* t = NULL; sp_int_digit* t = NULL;
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ #elif defined(WOLFSSL_SP_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
sp_int_digit t[a->used]; sp_int_digit t[a->used];
#else #else
sp_int_digit t[SP_INT_DIGITS / 2]; 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; sp_size_t k;
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
sp_int_digit* t = NULL; sp_int_digit* t = NULL;
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ #elif defined(WOLFSSL_SP_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
sp_int_digit t[a->used + b->used]; sp_int_digit t[a->used + b->used];
#else #else
sp_int_digit t[SP_INT_DIGITS]; 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; sp_size_t k;
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
sp_int_digit* t = NULL; sp_int_digit* t = NULL;
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ #elif defined(WOLFSSL_SP_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
sp_int_digit t[a->used + b->used]; sp_int_digit t[a->used + b->used];
#else #else
sp_int_digit t[SP_INT_DIGITS]; 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; sp_size_t k;
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
sp_int_digit* t = NULL; sp_int_digit* t = NULL;
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ #elif defined(WOLFSSL_SP_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
sp_int_digit t[((a->used + 1) / 2) * 2 + 1]; sp_int_digit t[((a->used + 1) / 2) * 2 + 1];
#else #else
sp_int_digit t[(SP_INT_DIGITS + 1) / 2]; 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; sp_size_t k;
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC)
sp_int_digit* t = NULL; sp_int_digit* t = NULL;
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ #elif defined(WOLFSSL_SP_DYN_STACK)
!defined(WOLFSSL_SP_NO_DYN_STACK)
sp_int_digit t[a->used * 2]; sp_int_digit t[a->used * 2];
#else #else
sp_int_digit t[SP_INT_DIGITS]; sp_int_digit t[SP_INT_DIGITS];
@ -19891,12 +19879,8 @@ void sp_memzero_check(sp_int* sp)
} }
#endif /* WOLFSSL_CHECK_MEM_ZERO */ #endif /* WOLFSSL_CHECK_MEM_ZERO */
#if (!defined(WOLFSSL_SMALL_STACK) && !defined(SP_ALLOC)) || \ #ifdef WOLFSSL_SP_DYN_STACK
defined(WOLFSSL_SP_NO_MALLOC) PRAGMA_GCC_DIAG_POP
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
!defined(WOLFSSL_SP_NO_DYN_STACK)
PRAGMA_GCC_DIAG_POP
#endif
#endif #endif
#endif /* WOLFSSL_SP_MATH || WOLFSSL_SP_MATH_ALL */ #endif /* WOLFSSL_SP_MATH || WOLFSSL_SP_MATH_ALL */

View File

@ -788,11 +788,19 @@ typedef struct sp_ecc_ctx {
#define MP_INT_NEXT(t, cnt) \ #define MP_INT_NEXT(t, cnt) \
(sp_int*)(((byte*)(t)) + MP_INT_SIZEOF(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. */ /* Calculate the number of words required to support a number of bits. */
#define MP_BITS_CNT(bits) \ #define MP_BITS_CNT(bits) \
((unsigned int)(((((bits) + SP_WORD_SIZE - 1) / SP_WORD_SIZE) * 2 + 1))) ((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 #ifdef WOLFSSL_SMALL_STACK
/* /*
* Dynamic memory allocation of mp_int. * Dynamic memory allocation of mp_int.
@ -823,26 +831,25 @@ while (0)
/* /*
* Static allocation of mp_int. * Static allocation of mp_int.
*/ */
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ #ifdef WOLFSSL_SP_DYN_STACK
!defined(WOLFSSL_SP_NO_DYN_STACK)
/* Declare a dynamically allocated mp_int. */ /* Declare a dynamically allocated mp_int. */
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \ #define DECL_MP_INT_SIZE_DYN(name, bits, max) \
unsigned char name##d[MP_INT_SIZEOF(MP_BITS_CNT(bits))]; \ sp_int_digit name##d[MP_INT_SIZEOF_DIGITS(MP_BITS_CNT(bits))]; \
sp_int* (name) = (sp_int*)name##d sp_int* (name) = (sp_int*)name##d
#elif defined(__cplusplus) #elif defined(__cplusplus)
/* C++ doesn't tolerate parentheses around "name" (-Wparentheses) */ /* C++ doesn't tolerate parentheses around "name" (-Wparentheses) */
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \ #define DECL_MP_INT_SIZE_DYN(name, bits, max) \
unsigned char name##d[MP_INT_SIZEOF(MP_BITS_CNT(max))]; \ sp_int_digit name##d[MP_INT_SIZEOF_DIGITS(MP_BITS_CNT(max))]; \
sp_int* name = (sp_int*)name##d sp_int* name = (sp_int*)name##d
#else #else
/* Declare a dynamically allocated mp_int. */ /* Declare a dynamically allocated mp_int. */
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \ #define DECL_MP_INT_SIZE_DYN(name, bits, max) \
unsigned char name##d[MP_INT_SIZEOF(MP_BITS_CNT(max))]; \ sp_int_digit name##d[MP_INT_SIZEOF_DIGITS(MP_BITS_CNT(max))]; \
sp_int* (name) = (sp_int*)name##d sp_int* (name) = (sp_int*)name##d
#endif #endif
/* Declare a statically allocated mp_int. */ /* Declare a statically allocated mp_int. */
#define DECL_MP_INT_SIZE(name, bits) \ #define DECL_MP_INT_SIZE(name, bits) \
unsigned char name##d[MP_INT_SIZEOF(MP_BITS_CNT(bits))]; \ sp_int_digit name##d[MP_INT_SIZEOF_DIGITS(MP_BITS_CNT(bits))]; \
sp_int* (name) = (sp_int*)name##d sp_int* (name) = (sp_int*)name##d
/* Zero out mp_int of minimal size. */ /* Zero out mp_int of minimal size. */
#define NEW_MP_INT_SIZE(name, bits, heap, type) \ #define NEW_MP_INT_SIZE(name, bits, heap, type) \
@ -910,7 +917,7 @@ typedef struct sp_int {
struct WC_BIGINT raw; struct WC_BIGINT raw;
#endif #endif
/** Data of number. */ /** Data of number. */
sp_int_digit dp[SP_INT_DIGITS]; XALIGNED(SP_WORD_SIZE / 8) sp_int_digit dp[SP_INT_DIGITS];
} sp_int; } sp_int;
typedef struct sp_int_minimal { typedef struct sp_int_minimal {
@ -927,11 +934,14 @@ typedef struct sp_int_minimal {
struct WC_BIGINT raw; struct WC_BIGINT raw;
#endif #endif
/** First digit of number. */ /** First digit of number. */
sp_int_digit dp[1]; XALIGNED(SP_WORD_SIZE / 8) sp_int_digit dp[1];
} sp_int_minimal; } 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); 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. */ /* Multi-precision integer type is SP integer type. */
typedef sp_int mp_int; typedef sp_int mp_int;