From: Richard Levitte Date: Thu, 25 Nov 2021 17:46:32 +0000 (+0100) Subject: Add support for signed BIGNUMs in the OSSL_PARAM_BLD API X-Git-Tag: openssl-3.2.0-alpha1~3020 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=17898ec6011cc583c5af69ca8f25f5d165ff3e6a;p=thirdparty%2Fopenssl.git Add support for signed BIGNUMs in the OSSL_PARAM_BLD API Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/17162) --- diff --git a/crypto/param_build.c b/crypto/param_build.c index a86f4baf173..918bebda6b8 100644 --- a/crypto/param_build.c +++ b/crypto/param_build.c @@ -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 */ diff --git a/doc/man3/OSSL_PARAM_BLD.pod b/doc/man3/OSSL_PARAM_BLD.pod index 114ce44489c..8393cf0e921 100644 --- a/doc/man3/OSSL_PARAM_BLD.pod +++ b/doc/man3/OSSL_PARAM_BLD.pod @@ -73,8 +73,16 @@ OSSL_PARAM objects of the specified size and correct type for the I argument. I is stored by value and an expression or auto variable can be used. +When B> denotes an integer type, signed integer types will normally +get the OSSL_PARAM type B params. +When B> denotes an unsigned integer type will get the OSSL_PARAM type +B. + OSSL_PARAM_BLD_push_BN() is a function that will create an OSSL_PARAM object that holds the specified BIGNUM I. +When the I is zero or positive, its OSSL_PARAM type becomes +B. +When the I is negative, its OSSL_PARAM type becomes B. If I is marked as being securely allocated, its OSSL_PARAM representation will also be securely allocated. The I 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. The object will be padded to occupy exactly I bytes, if insufficient space is specified an error results. +When the I is zero or positive, its OSSL_PARAM type becomes +B. +When the I is negative, its OSSL_PARAM type becomes B. If I is marked as being securely allocated, its OSSL_PARAM representation will also be securely allocated. The I 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 Bs. They return an error on negative Bs. +OSSL_PARAM_BLD_push_BN() and OSSL_PARAM_BLD_push_BN_pad() only +support nonnegative Bs. They return an error on negative +Bs. +To pass signed Bs, use OSSL_PARAM_BLD_push_signed_BN(). =head1 EXAMPLES diff --git a/include/internal/param_build_set.h b/include/internal/param_build_set.h index 126211b7f29..8ca7720379e 100644 --- a/include/internal/param_build_set.h +++ b/include/internal/param_build_set.h @@ -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);