From: Richard Levitte Date: Wed, 15 Oct 2025 12:06:34 +0000 (+0200) Subject: First integration of OSSL_FN into BIGNUM X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Ffeature%2Fossl_fn;p=thirdparty%2Fopenssl.git First integration of OSSL_FN into BIGNUM This integration is made in such a way that OSSL_FN is an optional 'data' field in BIGNUM, i.e. it's allowed to be NULL even though the BIGNUM's 'd' field is non-NULL. The public BIGNUM API will do what it can to ensure that the 'data' field becomes non-NULL, but remains lax on input BIGNUMs, for now. This allows diverse internal bn constants and hacks to continue to function with minimal friction. These constants and hacks will incrementally be modified to use OSSL_FN where they currently use BN_ULONG. Related-to: doc/designs/fixed-size-large-numbers.md Resolves: https://github.com/openssl/openssl/issues/28931 Reviewed-by: Matt Caswell Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/28930) --- diff --git a/crypto/bn/bn_dh.c b/crypto/bn/bn_dh.c index c0967e534c8..0d72a84215f 100644 --- a/crypto/bn/bn_dh.c +++ b/crypto/bn/bn_dh.c @@ -1006,49 +1006,53 @@ static const BN_ULONG ffdhe8192_q[] = { # define make_dh_bn(x) \ extern const BIGNUM ossl_bignum_##x; \ const BIGNUM ossl_bignum_##x = { \ - (BN_ULONG *) x, \ - OSSL_NELEM(x), \ - OSSL_NELEM(x), \ - 0, BN_FLG_STATIC_DATA }; + .d = (BN_ULONG *)x, \ + .top = OSSL_NELEM(x), \ + .dmax = OSSL_NELEM(x), \ + .flags = BN_FLG_STATIC_DATA, \ + } static const BN_ULONG value_2 = 2; const BIGNUM ossl_bignum_const_2 = { - (BN_ULONG *)&value_2, 1, 1, 0, BN_FLG_STATIC_DATA + .d = (BN_ULONG *)&value_2, + .top = 1, + .dmax = 1, + .flags = BN_FLG_STATIC_DATA, }; -make_dh_bn(dh1024_160_p) -make_dh_bn(dh1024_160_q) -make_dh_bn(dh1024_160_g) -make_dh_bn(dh2048_224_p) -make_dh_bn(dh2048_224_q) -make_dh_bn(dh2048_224_g) -make_dh_bn(dh2048_256_p) -make_dh_bn(dh2048_256_q) -make_dh_bn(dh2048_256_g) +make_dh_bn(dh1024_160_p); +make_dh_bn(dh1024_160_q); +make_dh_bn(dh1024_160_g); +make_dh_bn(dh2048_224_p); +make_dh_bn(dh2048_224_q); +make_dh_bn(dh2048_224_g); +make_dh_bn(dh2048_256_p); +make_dh_bn(dh2048_256_q); +make_dh_bn(dh2048_256_g); -make_dh_bn(ffdhe2048_p) -make_dh_bn(ffdhe2048_q) -make_dh_bn(ffdhe3072_p) -make_dh_bn(ffdhe3072_q) -make_dh_bn(ffdhe4096_p) -make_dh_bn(ffdhe4096_q) -make_dh_bn(ffdhe6144_p) -make_dh_bn(ffdhe6144_q) -make_dh_bn(ffdhe8192_p) -make_dh_bn(ffdhe8192_q) +make_dh_bn(ffdhe2048_p); +make_dh_bn(ffdhe2048_q); +make_dh_bn(ffdhe3072_p); +make_dh_bn(ffdhe3072_q); +make_dh_bn(ffdhe4096_p); +make_dh_bn(ffdhe4096_q); +make_dh_bn(ffdhe6144_p); +make_dh_bn(ffdhe6144_q); +make_dh_bn(ffdhe8192_p); +make_dh_bn(ffdhe8192_q); # ifndef FIPS_MODULE -make_dh_bn(modp_1536_p) -make_dh_bn(modp_1536_q) +make_dh_bn(modp_1536_p); +make_dh_bn(modp_1536_q); # endif -make_dh_bn(modp_2048_p) -make_dh_bn(modp_2048_q) -make_dh_bn(modp_3072_p) -make_dh_bn(modp_3072_q) -make_dh_bn(modp_4096_p) -make_dh_bn(modp_4096_q) -make_dh_bn(modp_6144_p) -make_dh_bn(modp_6144_q) -make_dh_bn(modp_8192_p) -make_dh_bn(modp_8192_q) +make_dh_bn(modp_2048_p); +make_dh_bn(modp_2048_q); +make_dh_bn(modp_3072_p); +make_dh_bn(modp_3072_q); +make_dh_bn(modp_4096_p); +make_dh_bn(modp_4096_q); +make_dh_bn(modp_6144_p); +make_dh_bn(modp_6144_q); +make_dh_bn(modp_8192_p); +make_dh_bn(modp_8192_q); diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c index 1dda2e017f1..47b370c6668 100644 --- a/crypto/bn/bn_exp.c +++ b/crypto/bn/bn_exp.c @@ -618,7 +618,7 @@ int bn_mod_exp_mont_fixed_top(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, unsigned char *powerbufFree = NULL; int powerbufLen = 0; unsigned char *powerbuf = NULL; - BIGNUM tmp, am; + BIGNUM tmp = { .data = NULL }, am = { .data = NULL }; #if defined(SPARC_T4_MONT) unsigned int t4 = 0; #endif diff --git a/crypto/bn/bn_intern.c b/crypto/bn/bn_intern.c index b01c93c6f59..1f5999067b7 100644 --- a/crypto/bn/bn_intern.c +++ b/crypto/bn/bn_intern.c @@ -174,6 +174,7 @@ void bn_set_static_words(BIGNUM *a, const BN_ULONG *words, int size) * |const| qualifier omission is compensated by BN_FLG_STATIC_DATA * flag, which effectively means "read-only data". */ + a->data = NULL; a->d = (BN_ULONG *)words; a->dmax = a->top = size; a->neg = 0; diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c index f830fe7335a..5ded63c55bc 100644 --- a/crypto/bn/bn_lib.c +++ b/crypto/bn/bn_lib.c @@ -9,11 +9,14 @@ #include #include +#include +#include +#include #include "internal/cryptlib.h" #include "internal/endian.h" -#include "bn_local.h" -#include #include "internal/constant_time.h" +#include "crypto/fn.h" +#include "bn_local.h" /* This stuff appears to be completely unused, so is deprecated */ #ifndef OPENSSL_NO_DEPRECATED_0_9_8 @@ -83,7 +86,10 @@ const BIGNUM *BN_value_one(void) { static const BN_ULONG data_one = 1L; static const BIGNUM const_one = { - (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA + .d = (BN_ULONG *)&data_one, + .top = 1, + .dmax = 1, + .flags = BN_FLG_STATIC_DATA, }; return &const_one; @@ -200,7 +206,7 @@ int BN_num_bits(const BIGNUM *a) return ((i * BN_BITS2) + BN_num_bits_word(a->d[i])); } -static void bn_free_d(BIGNUM *a, int clear) +static void bn_free_d(BIGNUM *a, bool clear) { if (BN_get_flags(a, BN_FLG_SECURE)) OPENSSL_secure_clear_free(a->d, a->dmax * sizeof(a->d[0])); @@ -210,13 +216,16 @@ static void bn_free_d(BIGNUM *a, int clear) OPENSSL_free(a->d); } - void BN_clear_free(BIGNUM *a) { if (a == NULL) return; - if (a->d != NULL && !BN_get_flags(a, BN_FLG_STATIC_DATA)) - bn_free_d(a, 1); + if (!BN_get_flags(a, BN_FLG_STATIC_DATA)) { + if (a->data != NULL) + OSSL_FN_clear_free(a->data); + else + bn_free_d(a, true); + } if (BN_get_flags(a, BN_FLG_MALLOCED)) { OPENSSL_cleanse(a, sizeof(*a)); OPENSSL_free(a); @@ -227,8 +236,12 @@ void BN_free(BIGNUM *a) { if (a == NULL) return; - if (!BN_get_flags(a, BN_FLG_STATIC_DATA)) - bn_free_d(a, 0); + if (!BN_get_flags(a, BN_FLG_STATIC_DATA)) { + if (a->data != NULL) + OSSL_FN_free(a->data); + else + bn_free_d(a, false); + } if (a->flags & BN_FLG_MALLOCED) OPENSSL_free(a); } @@ -263,9 +276,9 @@ BIGNUM *BN_secure_new(void) /* This is used by bn_expand2() */ /* The caller MUST check that words > b->dmax before calling this */ -static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words) +static OSSL_FN *bn_expand_internal(const BIGNUM *b, int words) { - BN_ULONG *a = NULL; + OSSL_FN *a = NULL; if (ossl_unlikely(words > (INT_MAX / (4 * BN_BITS2)))) { ERR_raise(ERR_LIB_BN, BN_R_BIGNUM_TOO_LONG); @@ -276,15 +289,19 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words) return NULL; } if (BN_get_flags(b, BN_FLG_SECURE)) - a = OPENSSL_secure_calloc(words, sizeof(*a)); + a = OSSL_FN_secure_new_limbs(words); else - a = OPENSSL_calloc(words, sizeof(*a)); + a = OSSL_FN_new_limbs(words); if (ossl_unlikely(a == NULL)) return NULL; assert(b->top <= words); - if (b->top > 0) - memcpy(a, b->d, sizeof(*a) * b->top); + if (b->top > 0) { + if (b->data != NULL) + ossl_fn_copy_internal(a, b->data, -1); + else if (b->d != NULL) + ossl_fn_copy_internal_limbs(a, b->d, b->top); + } return a; } @@ -300,14 +317,18 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words) BIGNUM *bn_expand2(BIGNUM *b, int words) { if (ossl_likely(words > b->dmax)) { - BN_ULONG *a = bn_expand_internal(b, words); + OSSL_FN *a = bn_expand_internal(b, words); if (ossl_unlikely(!a)) return NULL; - if (b->d != NULL) - bn_free_d(b, 1); - b->d = a; - b->dmax = words; + if (b->data != NULL) + OSSL_FN_clear_free(b->data); + else if (b->d != NULL) + bn_free_d(b, true); + b->data = a; + /* TODO(FIXNUM) The following is TO BE REMOVED */ + b->d = b->data->d; + b->dmax = b->data->dsize; } return b; @@ -345,9 +366,12 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) if (ossl_unlikely(bn_wexpand(a, bn_words) == NULL)) return NULL; - if (ossl_likely(b->top > 0)) - memcpy(a->d, b->d, sizeof(b->d[0]) * bn_words); - + if (ossl_likely(bn_words > 0)) { + if (b->data != NULL) + ossl_fn_copy_internal(a->data, b->data, bn_words); + else if (b->d != NULL) + ossl_fn_copy_internal_limbs(a->data, b->d, bn_words); + } a->neg = b->neg; a->top = b->top; a->flags |= b->flags & BN_FLG_FIXED_TOP; @@ -364,6 +388,7 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) void BN_swap(BIGNUM *a, BIGNUM *b) { int flags_old_a, flags_old_b; + OSSL_FN *tmp_data; BN_ULONG *tmp_d; int tmp_top, tmp_dmax, tmp_neg; @@ -373,16 +398,19 @@ void BN_swap(BIGNUM *a, BIGNUM *b) flags_old_a = a->flags; flags_old_b = b->flags; + tmp_data = a->data; tmp_d = a->d; tmp_top = a->top; tmp_dmax = a->dmax; tmp_neg = a->neg; + a->data = b->data; a->d = b->d; a->top = b->top; a->dmax = b->dmax; a->neg = b->neg; + b->data = tmp_data; b->d = tmp_d; b->top = tmp_top; b->dmax = tmp_dmax; @@ -399,7 +427,9 @@ void BN_clear(BIGNUM *a) if (a == NULL) return; bn_check_top(a); - if (a->d != NULL) + if (a->data != NULL) + OSSL_FN_clear(a->data); + else if (a->d != NULL) OPENSSL_cleanse(a->d, sizeof(*a->d) * a->dmax); a->neg = 0; a->top = 0; @@ -419,7 +449,7 @@ BN_ULONG BN_get_word(const BIGNUM *a) int BN_set_word(BIGNUM *a, BN_ULONG w) { bn_check_top(a); - if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL) + if (bn_wexpand(a, 1) == NULL) return 0; a->neg = 0; a->d[0] = w; @@ -1084,6 +1114,7 @@ int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags) { + dest->data = b->data; dest->d = b->d; dest->top = b->top; dest->dmax = b->dmax; diff --git a/crypto/bn/bn_local.h b/crypto/bn/bn_local.h index e44c09c5169..9302ea0ba21 100644 --- a/crypto/bn/bn_local.h +++ b/crypto/bn/bn_local.h @@ -17,13 +17,15 @@ */ # include +# include "internal/cryptlib.h" +# include "internal/numbers.h" # if !defined(OPENSSL_SYS_UEFI) # include "crypto/bn_conf.h" # endif # include "crypto/bn.h" -# include "internal/cryptlib.h" -# include "internal/numbers.h" + +# include "../fn/fn_local.h" /* * These preprocessor symbols control various aspects of the bignum headers @@ -206,6 +208,11 @@ const BIGNUM *_bnum2 = (a); \ if (_bnum2 != NULL) { \ int _top = _bnum2->top; \ + /* BIGNUM <-> OSSL_FN compat checks */ \ + assert((_bnum2->data == NULL /* && _bnum2->d == NULL */) \ + || (_bnum2->d == _bnum2->data->d \ + && _bnum2->dmax == _bnum2->data->dsize)); \ + /* BIGNUM specific checks */ \ assert((_top == 0 && !_bnum2->neg) || \ (_top && ((_bnum2->flags & BN_FLG_FIXED_TOP) \ || _bnum2->d[_top - 1] != 0))); \ @@ -247,16 +254,24 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, int num); struct bignum_st { - BN_ULONG *d; /* - * Pointer to an array of 'BN_BITS2' bit - * chunks. These chunks are organised in - * a least significant chunk first order. - */ - int top; /* Index of last used d +1. */ - /* The next are internal book keeping for bn_expand. */ - int dmax; /* Size of the d array. */ - int neg; /* one if the number is negative */ + /* The number itself is a FIXNUM */ + OSSL_FN *data; + + /* Some of these flags are replicated in OSSL_FN, some are not */ int flags; + + /* + * TODO(FIXNUM) The fields that follow ARE TO BE REMOVED when all relevant + * BN_ functions have transitioned to be wrappers around OSSL_FN_ functions. + * All of this is maintained by bn_expand and BIGNUM allocators and + * deallocators. + */ + + BN_ULONG *d; /* Pointer to |data->d| */ + int top; /* Index of last used d +1. */ + /* The next are internal book keeping for bn_expand. */ + int dmax; /* Copy of |data->dsize| */ + int neg; /* One if the number is negative */ }; /* Used for montgomery multiplication */ diff --git a/crypto/bn/bn_nist.c b/crypto/bn/bn_nist.c index 527ecb34d85..6acb68aac65 100644 --- a/crypto/bn/bn_nist.c +++ b/crypto/bn/bn_nist.c @@ -185,43 +185,38 @@ static const BN_ULONG _nist_p_521_sqr[] = { #endif static const BIGNUM ossl_bignum_nist_p_192 = { - (BN_ULONG *)_nist_p_192[0], - BN_NIST_192_TOP, - BN_NIST_192_TOP, - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)_nist_p_192[0], + .top = BN_NIST_192_TOP, + .dmax = BN_NIST_192_TOP, + .flags = BN_FLG_STATIC_DATA, }; static const BIGNUM ossl_bignum_nist_p_224 = { - (BN_ULONG *)_nist_p_224[0], - BN_NIST_224_TOP, - BN_NIST_224_TOP, - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)_nist_p_224[0], + .top = BN_NIST_224_TOP, + .dmax = BN_NIST_224_TOP, + .flags = BN_FLG_STATIC_DATA, }; static const BIGNUM ossl_bignum_nist_p_256 = { - (BN_ULONG *)_nist_p_256[0], - BN_NIST_256_TOP, - BN_NIST_256_TOP, - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)_nist_p_256[0], + .top = BN_NIST_256_TOP, + .dmax = BN_NIST_256_TOP, + .flags = BN_FLG_STATIC_DATA, }; static const BIGNUM ossl_bignum_nist_p_384 = { - (BN_ULONG *)_nist_p_384[0], - BN_NIST_384_TOP, - BN_NIST_384_TOP, - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)_nist_p_384[0], + .top = BN_NIST_384_TOP, + .dmax = BN_NIST_384_TOP, + .flags = BN_FLG_STATIC_DATA, }; static const BIGNUM ossl_bignum_nist_p_521 = { - (BN_ULONG *)_nist_p_521, - BN_NIST_521_TOP, - BN_NIST_521_TOP, - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)_nist_p_521, + .top = BN_NIST_521_TOP, + .dmax = BN_NIST_521_TOP, + .flags = BN_FLG_STATIC_DATA, }; const BIGNUM *BN_get0_nist_prime_192(void) @@ -361,10 +356,10 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, } buf; BN_ULONG c_d[BN_NIST_192_TOP], *res; static const BIGNUM ossl_bignum_nist_p_192_sqr = { - (BN_ULONG *)_nist_p_192_sqr, - OSSL_NELEM(_nist_p_192_sqr), - OSSL_NELEM(_nist_p_192_sqr), - 0, BN_FLG_STATIC_DATA + .d = (BN_ULONG *)_nist_p_192_sqr, + .top = OSSL_NELEM(_nist_p_192_sqr), + .dmax = OSSL_NELEM(_nist_p_192_sqr), + .flags = BN_FLG_STATIC_DATA, }; field = &ossl_bignum_nist_p_192; /* just to make sure */ @@ -498,10 +493,10 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_ULONG c_d[BN_NIST_224_TOP], *res; bn_addsub_f adjust; static const BIGNUM ossl_bignum_nist_p_224_sqr = { - (BN_ULONG *)_nist_p_224_sqr, - OSSL_NELEM(_nist_p_224_sqr), - OSSL_NELEM(_nist_p_224_sqr), - 0, BN_FLG_STATIC_DATA + .d = (BN_ULONG *)_nist_p_224_sqr, + .top = OSSL_NELEM(_nist_p_224_sqr), + .dmax = OSSL_NELEM(_nist_p_224_sqr), + .flags = BN_FLG_STATIC_DATA, }; field = &ossl_bignum_nist_p_224; /* just to make sure */ @@ -670,10 +665,10 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_ULONG c_d[BN_NIST_256_TOP], *res; bn_addsub_f adjust; static const BIGNUM ossl_bignum_nist_p_256_sqr = { - (BN_ULONG *)_nist_p_256_sqr, - OSSL_NELEM(_nist_p_256_sqr), - OSSL_NELEM(_nist_p_256_sqr), - 0, BN_FLG_STATIC_DATA + .d = (BN_ULONG *)_nist_p_256_sqr, + .top = OSSL_NELEM(_nist_p_256_sqr), + .dmax = OSSL_NELEM(_nist_p_256_sqr), + .flags = BN_FLG_STATIC_DATA, }; field = &ossl_bignum_nist_p_256; /* just to make sure */ @@ -907,10 +902,10 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, BN_ULONG c_d[BN_NIST_384_TOP], *res; bn_addsub_f adjust; static const BIGNUM ossl_bignum_nist_p_384_sqr = { - (BN_ULONG *)_nist_p_384_sqr, - OSSL_NELEM(_nist_p_384_sqr), - OSSL_NELEM(_nist_p_384_sqr), - 0, BN_FLG_STATIC_DATA + .d = (BN_ULONG *)_nist_p_384_sqr, + .top = OSSL_NELEM(_nist_p_384_sqr), + .dmax = OSSL_NELEM(_nist_p_384_sqr), + .flags = BN_FLG_STATIC_DATA, }; field = &ossl_bignum_nist_p_384; /* just to make sure */ @@ -1159,10 +1154,10 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, int top = a->top, i; BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res; static const BIGNUM ossl_bignum_nist_p_521_sqr = { - (BN_ULONG *)_nist_p_521_sqr, - OSSL_NELEM(_nist_p_521_sqr), - OSSL_NELEM(_nist_p_521_sqr), - 0, BN_FLG_STATIC_DATA + .d = (BN_ULONG *)_nist_p_521_sqr, + .top = OSSL_NELEM(_nist_p_521_sqr), + .dmax = OSSL_NELEM(_nist_p_521_sqr), + .flags = BN_FLG_STATIC_DATA, }; field = &ossl_bignum_nist_p_521; /* just to make sure */ diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c index 6d85cbb17e6..15ba714721a 100644 --- a/crypto/bn/bn_prime.c +++ b/crypto/bn/bn_prime.c @@ -55,11 +55,10 @@ static const BN_ULONG small_prime_factors[] = { #define BN_SMALL_PRIME_FACTORS_TOP OSSL_NELEM(small_prime_factors) static const BIGNUM _bignum_small_prime_factors = { - (BN_ULONG *)small_prime_factors, - BN_SMALL_PRIME_FACTORS_TOP, - BN_SMALL_PRIME_FACTORS_TOP, - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)small_prime_factors, + .top = BN_SMALL_PRIME_FACTORS_TOP, + .dmax = BN_SMALL_PRIME_FACTORS_TOP, + .flags = BN_FLG_STATIC_DATA, }; const BIGNUM *ossl_bn_get0_small_factors(void) diff --git a/crypto/bn/bn_rsa_fips186_4.c b/crypto/bn/bn_rsa_fips186_4.c index c967ca96297..49746aae033 100644 --- a/crypto/bn/bn_rsa_fips186_4.c +++ b/crypto/bn/bn_rsa_fips186_4.c @@ -41,11 +41,10 @@ static const BN_ULONG inv_sqrt_2_val[] = { }; const BIGNUM ossl_bn_inv_sqrt_2 = { - (BN_ULONG *)inv_sqrt_2_val, - OSSL_NELEM(inv_sqrt_2_val), - OSSL_NELEM(inv_sqrt_2_val), - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)inv_sqrt_2_val, + .top = OSSL_NELEM(inv_sqrt_2_val), + .dmax = OSSL_NELEM(inv_sqrt_2_val), + .flags = BN_FLG_STATIC_DATA, }; /* diff --git a/crypto/bn/bn_srp.c b/crypto/bn/bn_srp.c index ffb8fc61e0f..d62d8c48e48 100644 --- a/crypto/bn/bn_srp.c +++ b/crypto/bn/bn_srp.c @@ -49,11 +49,10 @@ static const BN_ULONG bn_group_1024_value[] = { }; const BIGNUM ossl_bn_group_1024 = { - (BN_ULONG *)bn_group_1024_value, - OSSL_NELEM(bn_group_1024_value), - OSSL_NELEM(bn_group_1024_value), - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)bn_group_1024_value, + .top = OSSL_NELEM(bn_group_1024_value), + .dmax = OSSL_NELEM(bn_group_1024_value), + .flags = BN_FLG_STATIC_DATA, }; static const BN_ULONG bn_group_1536_value[] = { @@ -84,11 +83,10 @@ static const BN_ULONG bn_group_1536_value[] = { }; const BIGNUM ossl_bn_group_1536 = { - (BN_ULONG *)bn_group_1536_value, - OSSL_NELEM(bn_group_1536_value), - OSSL_NELEM(bn_group_1536_value), - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)bn_group_1536_value, + .top = OSSL_NELEM(bn_group_1536_value), + .dmax = OSSL_NELEM(bn_group_1536_value), + .flags = BN_FLG_STATIC_DATA, }; static const BN_ULONG bn_group_2048_value[] = { @@ -127,11 +125,10 @@ static const BN_ULONG bn_group_2048_value[] = { }; const BIGNUM ossl_bn_group_2048 = { - (BN_ULONG *)bn_group_2048_value, - OSSL_NELEM(bn_group_2048_value), - OSSL_NELEM(bn_group_2048_value), - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)bn_group_2048_value, + .top = OSSL_NELEM(bn_group_2048_value), + .dmax = OSSL_NELEM(bn_group_2048_value), + .flags = BN_FLG_STATIC_DATA, }; static const BN_ULONG bn_group_3072_value[] = { @@ -186,11 +183,10 @@ static const BN_ULONG bn_group_3072_value[] = { }; const BIGNUM ossl_bn_group_3072 = { - (BN_ULONG *)bn_group_3072_value, - OSSL_NELEM(bn_group_3072_value), - OSSL_NELEM(bn_group_3072_value), - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)bn_group_3072_value, + .top = OSSL_NELEM(bn_group_3072_value), + .dmax = OSSL_NELEM(bn_group_3072_value), + .flags = BN_FLG_STATIC_DATA, }; static const BN_ULONG bn_group_4096_value[] = { @@ -261,11 +257,10 @@ static const BN_ULONG bn_group_4096_value[] = { }; const BIGNUM ossl_bn_group_4096 = { - (BN_ULONG *)bn_group_4096_value, - OSSL_NELEM(bn_group_4096_value), - OSSL_NELEM(bn_group_4096_value), - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)bn_group_4096_value, + .top = OSSL_NELEM(bn_group_4096_value), + .dmax = OSSL_NELEM(bn_group_4096_value), + .flags = BN_FLG_STATIC_DATA, }; static const BN_ULONG bn_group_6144_value[] = { @@ -368,11 +363,10 @@ static const BN_ULONG bn_group_6144_value[] = { }; const BIGNUM ossl_bn_group_6144 = { - (BN_ULONG *)bn_group_6144_value, - OSSL_NELEM(bn_group_6144_value), - OSSL_NELEM(bn_group_6144_value), - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)bn_group_6144_value, + .top = OSSL_NELEM(bn_group_6144_value), + .dmax = OSSL_NELEM(bn_group_6144_value), + .flags = BN_FLG_STATIC_DATA, }; static const BN_ULONG bn_group_8192_value[] = { @@ -507,39 +501,35 @@ static const BN_ULONG bn_group_8192_value[] = { }; const BIGNUM ossl_bn_group_8192 = { - (BN_ULONG *)bn_group_8192_value, - OSSL_NELEM(bn_group_8192_value), - OSSL_NELEM(bn_group_8192_value), - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)bn_group_8192_value, + .top = OSSL_NELEM(bn_group_8192_value), + .dmax = OSSL_NELEM(bn_group_8192_value), + .flags = BN_FLG_STATIC_DATA, }; static const BN_ULONG bn_generator_19_value[] = { 19 }; const BIGNUM ossl_bn_generator_19 = { - (BN_ULONG *)bn_generator_19_value, - 1, - 1, - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)bn_generator_19_value, + .top = 1, + .dmax = 1, + .flags = BN_FLG_STATIC_DATA, }; static const BN_ULONG bn_generator_5_value[] = { 5 }; const BIGNUM ossl_bn_generator_5 = { - (BN_ULONG *)bn_generator_5_value, - 1, - 1, - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)bn_generator_5_value, + .top = 1, + .dmax = 1, + .flags = BN_FLG_STATIC_DATA, }; static const BN_ULONG bn_generator_2_value[] = { 2 }; const BIGNUM ossl_bn_generator_2 = { - (BN_ULONG *)bn_generator_2_value, - 1, - 1, - 0, - BN_FLG_STATIC_DATA + .d = (BN_ULONG *)bn_generator_2_value, + .top = 1, + .dmax = 1, + .flags = BN_FLG_STATIC_DATA, }; #endif diff --git a/crypto/fn/fn_lib.c b/crypto/fn/fn_lib.c index 87da4c2a919..a4eb60b98ed 100644 --- a/crypto/fn/fn_lib.c +++ b/crypto/fn/fn_lib.c @@ -119,3 +119,10 @@ void OSSL_FN_clear_free(OSSL_FN *f) { ossl_fn_free_internal(f, true); } + +void OSSL_FN_clear(OSSL_FN *f) +{ + size_t limbssize = f->dsize * sizeof(OSSL_FN_ULONG); + + OPENSSL_cleanse(f->d, limbssize); +} diff --git a/crypto/fn/fn_local.h b/crypto/fn/fn_local.h index 3d9d33eb557..1b5ed7d365a 100644 --- a/crypto/fn/fn_local.h +++ b/crypto/fn/fn_local.h @@ -10,7 +10,10 @@ #ifndef OSSL_CRYPTO_FN_LOCAL_H # define OSSL_CRYPTO_FN_LOCAL_H +# include # include +# include +# include "internal/common.h" # include "crypto/fn.h" struct ossl_fn_st { @@ -32,4 +35,33 @@ struct ossl_fn_st { OSSL_FN_ULONG d[]; }; +/* + * Internal functions to support BIGNUM's bn_expand_internal, BN_copy, and + * similar. + * The caller must ensure that src and dest are not NULL. + * With ossl_fn_copy_internal, bn_words may be given -1 to signify that the + * number of BN_ULONG should be found in src. + */ +static ossl_inline OSSL_FN *ossl_fn_copy_internal_limbs(OSSL_FN *dest, + const OSSL_FN_ULONG *src, + int limbs) +{ + if (ossl_unlikely(dest->dsize < limbs)) + return NULL; + memcpy(dest->d, src, limbs * sizeof(dest->d[0])); + memset(dest->d + limbs, 0, (dest->dsize - limbs) * sizeof(dest->d[0])); + return dest; +} + +static ossl_inline OSSL_FN *ossl_fn_copy_internal(OSSL_FN *dest, + const OSSL_FN *src, + int bn_words) +{ + int words = bn_words < 0 ? src->dsize : bn_words; + + if (ossl_fn_copy_internal_limbs(dest, src->d, words) == NULL) + return NULL; + return dest; +} + #endif diff --git a/include/crypto/bn.h b/include/crypto/bn.h index 2acdeacfe89..b3ddd2894e4 100644 --- a/include/crypto/bn.h +++ b/include/crypto/bn.h @@ -13,6 +13,7 @@ # include # include +# include "types.h" BIGNUM *bn_wexpand(BIGNUM *a, int words); BIGNUM *bn_expand2(BIGNUM *a, int words); diff --git a/include/crypto/fn.h b/include/crypto/fn.h index a181a0bf323..9892a294e6e 100644 --- a/include/crypto/fn.h +++ b/include/crypto/fn.h @@ -121,6 +121,13 @@ void OSSL_FN_free(OSSL_FN *f); */ void OSSL_FN_clear_free(OSSL_FN *f); +/** + * Cleanse the data of an OSSL_FN instance, effectively making it zero. + * + * @param[in] f The OSSL_FN instance to be cleared. + */ +void OSSL_FN_clear(OSSL_FN *f); + # ifdef __cplusplus } # endif