From: Richard Levitte Date: Mon, 22 Nov 2021 16:10:10 +0000 (+0100) Subject: Allow sign extension in OSSL_PARAM_allocate_from_text() X-Git-Tag: openssl-3.2.0-alpha1~3287 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=946bc0e3ec19ca019fcfa95f93c37f34e12fe0bd;p=thirdparty%2Fopenssl.git Allow sign extension in OSSL_PARAM_allocate_from_text() 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 Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/17104) --- diff --git a/crypto/params_from_text.c b/crypto/params_from_text.c index 43323c37075..b681d8f5640 100644 --- a/crypto/params_from_text.c +++ b/crypto/params_from_text.c @@ -61,7 +61,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 @@ -76,6 +76,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; /* @@ -83,9 +97,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; @@ -135,7 +147,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.