]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Allow sign extension in OSSL_PARAM_allocate_from_text()
authorRichard Levitte <levitte@openssl.org>
Mon, 22 Nov 2021 16:10:10 +0000 (17:10 +0100)
committerRichard Levitte <levitte@openssl.org>
Wed, 24 Nov 2021 18:21:41 +0000 (19:21 +0100)
This is done for the data type OSSL_PARAM_INTEGER by checking if the
most significant bit is set, and adding 8 to the number of buffer bits
if that is the case.  Everything else is already in place.

Fixes #17103

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17104)

(cherry picked from commit 946bc0e3ec19ca019fcfa95f93c37f34e12fe0bd)

crypto/params_from_text.c

index 024c1dc6d306e1b652987460c320320e5cb551df..360f8933e1355725ed5c17a344de567ce63ced84 100644 (file)
@@ -64,7 +64,7 @@ static int prepare_from_text(const OSSL_PARAM *paramdefs, const char *key,
         }
 
         /*
-         * 2s complement negate, part 1
+         * 2's complement negate, part 1
          *
          * BN_bn2nativepad puts the absolute value of the number in the
          * buffer, i.e. if it's negative, we need to deal with it.  We do
@@ -79,6 +79,20 @@ static int prepare_from_text(const OSSL_PARAM *paramdefs, const char *key,
         }
 
         buf_bits = (size_t)BN_num_bits(*tmpbn);
+
+        /*
+         * Compensate for cases where the most significant bit in
+         * the resulting OSSL_PARAM buffer will be set after the
+         * BN_bn2nativepad() call, as the implied sign may not be
+         * correct after the second part of the 2's complement
+         * negation has been performed.
+         * We fix these cases by extending the buffer by one byte
+         * (8 bits), which will give some padding.  The second part
+         * of the 2's complement negation will do the rest.
+         */
+        if (p->data_type == OSSL_PARAM_INTEGER && buf_bits % 8 == 0)
+            buf_bits += 8;
+
         *buf_n = (buf_bits + 7) / 8;
 
         /*
@@ -86,9 +100,7 @@ static int prepare_from_text(const OSSL_PARAM *paramdefs, const char *key,
          * range checking if a size is specified.
          */
         if (p->data_size > 0) {
-            if (buf_bits > p->data_size * 8
-                || (p->data_type == OSSL_PARAM_INTEGER
-                    && buf_bits == p->data_size * 8)) {
+            if (buf_bits > p->data_size * 8) {
                 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER);
                 /* Since this is a different error, we don't break */
                 return 0;
@@ -138,7 +150,7 @@ static int construct_from_text(OSSL_PARAM *to, const OSSL_PARAM *paramdef,
             BN_bn2nativepad(tmpbn, buf, buf_n);
 
             /*
-             * 2s complement negate, part two.
+             * 2's complement negation, part two.
              *
              * Because we did the first part on the BIGNUM itself, we can just
              * invert all the bytes here and be done with it.