diff options
author | Nicola Tuveri <nic.tuv@gmail.com> | 2020-11-10 01:11:48 +0200 |
---|---|---|
committer | Nicola Tuveri <nic.tuv@gmail.com> | 2021-01-08 23:59:02 +0200 |
commit | 9e49aff2aaac4c42ea6c4078266947c75761276b (patch) | |
tree | 10b470a0ce3fcbc13bb26290003f10f0d5c60116 /crypto | |
parent | 4554988e582e676a51c451de031939b45e60d00c (diff) |
Add SM2 private key range validation
According to the relevant standards, the valid range for SM2 private
keys is [1, n-1), where n is the order of the curve generator.
For this reason we cannot reuse the EC validation function as it is, and
we introduce a new internal function `sm2_key_private_check()`.
Partially fixes https://github.com/openssl/openssl/issues/8435
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/13359)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/err/openssl.txt | 1 | ||||
-rw-r--r-- | crypto/sm2/build.info | 2 | ||||
-rw-r--r-- | crypto/sm2/sm2_err.c | 2 | ||||
-rw-r--r-- | crypto/sm2/sm2_key.c | 49 |
4 files changed, 53 insertions, 1 deletions
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 5440e47093..4e36fc3394 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -3103,6 +3103,7 @@ SM2_R_INVALID_DIGEST:102:invalid digest SM2_R_INVALID_DIGEST_TYPE:103:invalid digest type SM2_R_INVALID_ENCODING:104:invalid encoding SM2_R_INVALID_FIELD:105:invalid field +SM2_R_INVALID_PRIVATE_KEY:113:invalid private key SM2_R_NO_PARAMETERS_SET:109:no parameters set SM2_R_USER_ID_TOO_LARGE:106:user id too large SSL_R_ALGORITHM_FETCH_FAILED:295:algorithm fetch failed diff --git a/crypto/sm2/build.info b/crypto/sm2/build.info index 402a76cc5d..a50d08d0bc 100644 --- a/crypto/sm2/build.info +++ b/crypto/sm2/build.info @@ -1,5 +1,5 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - sm2_sign.c sm2_crypt.c sm2_err.c + sm2_sign.c sm2_crypt.c sm2_err.c sm2_key.c diff --git a/crypto/sm2/sm2_err.c b/crypto/sm2/sm2_err.c index 60509e14d1..ab9c094a9d 100644 --- a/crypto/sm2/sm2_err.c +++ b/crypto/sm2/sm2_err.c @@ -28,6 +28,8 @@ static const ERR_STRING_DATA SM2_str_reasons[] = { "invalid digest type"}, {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_ENCODING), "invalid encoding"}, {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_FIELD), "invalid field"}, + {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_PRIVATE_KEY), + "invalid private key"}, {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NO_PARAMETERS_SET), "no parameters set"}, {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_USER_ID_TOO_LARGE), "user id too large"}, {0, NULL} diff --git a/crypto/sm2/sm2_key.c b/crypto/sm2/sm2_key.c new file mode 100644 index 0000000000..5182d01058 --- /dev/null +++ b/crypto/sm2/sm2_key.c @@ -0,0 +1,49 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/err.h> +#include "crypto/sm2err.h" +#include "crypto/sm2.h" +#include <openssl/ec.h> /* EC_KEY and EC_GROUP functions */ + +/* + * SM2 key generation is implemented within ec_generate_key() in + * crypto/ec/ec_key.c + */ + +int sm2_key_private_check(const EC_KEY *eckey) +{ + int ret = 0; + BIGNUM *max = NULL; + const EC_GROUP *group = NULL; + const BIGNUM *priv_key = NULL, *order = NULL; + + if (eckey == NULL + || (group = EC_KEY_get0_group(eckey)) == NULL + || (priv_key = EC_KEY_get0_private_key(eckey)) == NULL + || (order = EC_GROUP_get0_order(group)) == NULL ) { + ERR_raise(ERR_LIB_SM2, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + /* range of SM2 private key is [1, n-1) */ + max = BN_dup(order); + if (max == NULL || !BN_sub_word(max, 1)) + goto end; + if (BN_cmp(priv_key, BN_value_one()) < 0 + || BN_cmp(priv_key, max) >= 0) { + ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_PRIVATE_KEY); + goto end; + } + ret = 1; + + end: + BN_free(max); + return ret; +} |