From 946bc0e3ec19ca019fcfa95f93c37f34e12fe0bd Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Mon, 22 Nov 2021 17:10:10 +0100 Subject: [PATCH] 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) --- crypto/params_from_text.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) 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. -- 2.47.2