]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add support for signed BIGNUMs in the OSSL_PARAM_BLD API
authorRichard Levitte <levitte@openssl.org>
Thu, 25 Nov 2021 17:46:32 +0000 (18:46 +0100)
committerRichard Levitte <levitte@openssl.org>
Wed, 26 Jan 2022 20:35:39 +0000 (21:35 +0100)
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17162)

crypto/param_build.c
doc/man3/OSSL_PARAM_BLD.pod
include/internal/param_build_set.h

index a86f4baf173fb8e332822572d40ed69996fcb4fb..918bebda6b8ce4df085968369f156e03895e3b7d 100644 (file)
@@ -192,23 +192,20 @@ int OSSL_PARAM_BLD_push_double(OSSL_PARAM_BLD *bld, const char *key,
     return param_push_num(bld, key, &num, sizeof(num), OSSL_PARAM_REAL);
 }
 
-int OSSL_PARAM_BLD_push_BN(OSSL_PARAM_BLD *bld, const char *key,
-                           const BIGNUM *bn)
-{
-    return OSSL_PARAM_BLD_push_BN_pad(bld, key, bn,
-                                      bn == NULL ? 0 : BN_num_bytes(bn));
-}
-
-int OSSL_PARAM_BLD_push_BN_pad(OSSL_PARAM_BLD *bld, const char *key,
-                               const BIGNUM *bn, size_t sz)
+static int push_BN(OSSL_PARAM_BLD *bld, const char *key,
+                   const BIGNUM *bn, size_t sz, int type)
 {
     int n, secure = 0;
     OSSL_PARAM_BLD_DEF *pd;
 
+    if (!ossl_assert(type == OSSL_PARAM_UNSIGNED_INTEGER
+                     || type == OSSL_PARAM_INTEGER))
+        return 0;
+
     if (bn != NULL) {
-        if (BN_is_negative(bn)) {
+        if (type == OSSL_PARAM_UNSIGNED_INTEGER && BN_is_negative(bn)) {
             ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_UNSUPPORTED,
-                           "Negative big numbers are unsupported for OSSL_PARAM");
+                           "Negative big numbers are unsupported for OSSL_PARAM_UNSIGNED_INTEGER");
             return 0;
         }
 
@@ -224,13 +221,32 @@ int OSSL_PARAM_BLD_push_BN_pad(OSSL_PARAM_BLD *bld, const char *key,
         if (BN_get_flags(bn, BN_FLG_SECURE) == BN_FLG_SECURE)
             secure = 1;
     }
-    pd = param_push(bld, key, sz, sz, OSSL_PARAM_UNSIGNED_INTEGER, secure);
+    pd = param_push(bld, key, sz, sz, type, secure);
     if (pd == NULL)
         return 0;
     pd->bn = bn;
     return 1;
 }
 
+int OSSL_PARAM_BLD_push_BN(OSSL_PARAM_BLD *bld, const char *key,
+                           const BIGNUM *bn)
+{
+    if (BN_is_negative(bn))
+        return push_BN(bld, key, bn, bn == NULL ? 0 : BN_num_bytes(bn) + 1,
+                       OSSL_PARAM_INTEGER);
+    return push_BN(bld, key, bn, bn == NULL ? 0 : BN_num_bytes(bn),
+                   OSSL_PARAM_UNSIGNED_INTEGER);
+}
+
+int OSSL_PARAM_BLD_push_BN_pad(OSSL_PARAM_BLD *bld, const char *key,
+                               const BIGNUM *bn, size_t sz)
+{
+    if (BN_is_negative(bn))
+        return push_BN(bld, key, bn, bn == NULL ? 0 : BN_num_bytes(bn),
+                       OSSL_PARAM_INTEGER);
+    return push_BN(bld, key, bn, sz, OSSL_PARAM_UNSIGNED_INTEGER);
+}
+
 int OSSL_PARAM_BLD_push_utf8_string(OSSL_PARAM_BLD *bld, const char *key,
                                     const char *buf, size_t bsize)
 {
@@ -328,7 +344,10 @@ static OSSL_PARAM *param_bld_convert(OSSL_PARAM_BLD *bld, OSSL_PARAM *param,
         param[i].data = p;
         if (pd->bn != NULL) {
             /* BIGNUM */
-            BN_bn2nativepad(pd->bn, (unsigned char *)p, pd->size);
+            if (pd->type == OSSL_PARAM_UNSIGNED_INTEGER)
+                BN_bn2nativepad(pd->bn, (unsigned char *)p, pd->size);
+            else
+                BN_signed_bn2native(pd->bn, (unsigned char *)p, pd->size);
         } else if (pd->type == OSSL_PARAM_OCTET_PTR
                    || pd->type == OSSL_PARAM_UTF8_PTR) {
             /* PTR */
index 114ce44489cdb5b9f05d8ec7f8ddab39c16be9d3..8393cf0e921914169a04bdbc546ba79b550beaa2 100644 (file)
@@ -73,8 +73,16 @@ OSSL_PARAM objects of the specified size and correct type for the I<val>
 argument.
 I<val> is stored by value and an expression or auto variable can be used.
 
+When B<I<TYPE>> denotes an integer type, signed integer types will normally
+get the OSSL_PARAM type B<OSSL_PARAM_INTEGER> params.
+When B<I<TYPE>> denotes an unsigned integer type will get the OSSL_PARAM type
+B<OSSL_PARAM_UNSIGNED_INTEGER>.
+
 OSSL_PARAM_BLD_push_BN() is a function that will create an OSSL_PARAM object
 that holds the specified BIGNUM I<bn>.
+When the I<bn> is zero or positive, its OSSL_PARAM type becomes
+B<OSSL_PARAM_UNSIGNED_INTEGER>.
+When the I<bn> is negative, its OSSL_PARAM type becomes B<OSSL_PARAM_INTEGER>.
 If I<bn> is marked as being securely allocated, its OSSL_PARAM representation
 will also be securely allocated.
 The I<bn> argument is stored by reference and the underlying BIGNUM object
@@ -84,6 +92,9 @@ OSSL_PARAM_BLD_push_BN_pad() is a function that will create an OSSL_PARAM object
 that holds the specified BIGNUM I<bn>.
 The object will be padded to occupy exactly I<sz> bytes, if insufficient space
 is specified an error results.
+When the I<bn> is zero or positive, its OSSL_PARAM type becomes
+B<OSSL_PARAM_UNSIGNED_INTEGER>.
+When the I<bn> is negative, its OSSL_PARAM type becomes B<OSSL_PARAM_INTEGER>.
 If I<bn> is marked as being securely allocated, its OSSL_PARAM representation
 will also be securely allocated.
 The I<bn> argument is stored by reference and the underlying BIGNUM object
@@ -126,8 +137,10 @@ on error.
 
 =head1 NOTES
 
-OSSL_PARAM_BLD_push_BN() and OSSL_PARAM_BLD_push_BN_pad() currently only
-support nonnegative B<BIGNUM>s.  They return an error on negative B<BIGNUM>s.
+OSSL_PARAM_BLD_push_BN() and OSSL_PARAM_BLD_push_BN_pad() only
+support nonnegative B<BIGNUM>s.  They return an error on negative
+B<BIGNUM>s.
+To pass signed B<BIGNUM>s, use OSSL_PARAM_BLD_push_signed_BN().
 
 =head1 EXAMPLES
 
index 126211b7f298af978ee5a04519086e801dd2bf22..8ca7720379e54e0cbb52c4790407aa87c4c0ceeb 100644 (file)
@@ -39,6 +39,11 @@ int ossl_param_build_set_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
                             const char *key, const BIGNUM *bn);
 int ossl_param_build_set_bn_pad(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
                                 const char *key, const BIGNUM *bn,  size_t sz);
+int ossl_param_build_set_signed_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                                   const char *key, const BIGNUM *bn);
+int ossl_param_build_set_signed_bn_pad(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+                                       const char *key, const BIGNUM *bn,
+                                       size_t sz);
 int ossl_param_build_set_multi_key_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
                                       const char *names[],
                                       STACK_OF(BIGNUM_const) *stk);