]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
First integration of OSSL_FN into BIGNUM feature/ossl_fn
authorRichard Levitte <levitte@openssl.org>
Wed, 15 Oct 2025 12:06:34 +0000 (14:06 +0200)
committerRichard Levitte <levitte@openssl.org>
Tue, 28 Oct 2025 15:55:23 +0000 (16:55 +0100)
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 <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28930)

13 files changed:
crypto/bn/bn_dh.c
crypto/bn/bn_exp.c
crypto/bn/bn_intern.c
crypto/bn/bn_lib.c
crypto/bn/bn_local.h
crypto/bn/bn_nist.c
crypto/bn/bn_prime.c
crypto/bn/bn_rsa_fips186_4.c
crypto/bn/bn_srp.c
crypto/fn/fn_lib.c
crypto/fn/fn_local.h
include/crypto/bn.h
include/crypto/fn.h

index c0967e534c8c2073b3e9281a38c6d6b95ce2fde3..0d72a84215f847184da6e799d917156b2d363cfa 100644 (file)
@@ -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);
index 1dda2e017f1b93a1c27e00317e43aa1f9a84569e..47b370c6668673812c24188840e9389b68722ea1 100644 (file)
@@ -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
index b01c93c6f5967bdd4532de6f076918d4b48c0af9..1f5999067b758eaff71fb7665cb61b6b11ee65ed 100644 (file)
@@ -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;
index f830fe7335ab36cba4b5f6109a823c8d5c82facd..5ded63c55bcbeeb183c9766849f0f4ede99a83e4 100644 (file)
@@ -9,11 +9,14 @@
 
 #include <assert.h>
 #include <limits.h>
+#include <stdbool.h>
+#include <openssl/bn.h>
+#include <openssl/opensslconf.h>
 #include "internal/cryptlib.h"
 #include "internal/endian.h"
-#include "bn_local.h"
-#include <openssl/opensslconf.h>
 #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;
index e44c09c5169ef54b1b28bfacb966e85382a41da8..9302ea0ba2100055718a97f6276d973bf668c3d6 100644 (file)
  */
 # include <openssl/opensslconf.h>
 
+# 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
                 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 */
index 527ecb34d85459c11364107f30a7ad87b5c05f7d..6acb68aac657cb90bc72aff989fa018c4421cb66 100644 (file)
@@ -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 */
index 6d85cbb17e657e69d10c4dc6524503ffe74de0b9..15ba714721aaf0c4467ad8d5b87b9f42cb1d324d 100644 (file)
@@ -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)
index c967ca962978a9968b61cc0684b504d6dd99b7ad..49746aae033431849992b8ad58f3bdd29b63b0cf 100644 (file)
@@ -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,
 };
 
 /*
index ffb8fc61e0fe983f1c5fa3ac1c5bc32b2edcbc10..d62d8c48e48d4792b6b5d73ed632876bb007b768 100644 (file)
@@ -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
index 87da4c2a919c33ab27af0331d7f528e1a0aa8dfd..a4eb60b98edbd77e10994cb6a1f8aa661e9c8e77 100644 (file)
@@ -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);
+}
index 3d9d33eb557429d37fc152f57655e66ab0b23fb6..1b5ed7d365a57eafcc13a56ae0fc4678ca136149 100644 (file)
 #ifndef OSSL_CRYPTO_FN_LOCAL_H
 # define OSSL_CRYPTO_FN_LOCAL_H
 
+# include <string.h>
 # include <openssl/opensslconf.h>
+# include <openssl/e_os2.h>
+# 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
index 2acdeacfe899e5d2843f4c2cb5b161dd21e8f76b..b3ddd2894e435219f104289c7cddda504041636c 100644 (file)
@@ -13,6 +13,7 @@
 
 # include <openssl/bn.h>
 # include <limits.h>
+# include "types.h"
 
 BIGNUM *bn_wexpand(BIGNUM *a, int words);
 BIGNUM *bn_expand2(BIGNUM *a, int words);
index a181a0bf3234e942949b50ed17a8341efcc3579c..9892a294e6e74d93cbd03055652d76110c126eff 100644 (file)
@@ -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