summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorNicola Tuveri <nic.tuv@gmail.com>2020-11-10 01:11:48 +0200
committerNicola Tuveri <nic.tuv@gmail.com>2021-01-08 23:59:02 +0200
commit9e49aff2aaac4c42ea6c4078266947c75761276b (patch)
tree10b470a0ce3fcbc13bb26290003f10f0d5c60116 /crypto
parent4554988e582e676a51c451de031939b45e60d00c (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.txt1
-rw-r--r--crypto/sm2/build.info2
-rw-r--r--crypto/sm2/sm2_err.c2
-rw-r--r--crypto/sm2/sm2_key.c49
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;
+}