The branch master has been updated
via 7f293d9f3b5cee4f4b15624fff15a45e0517334f (commit)
via bac1030ae4f93f22b3a81e3a2d9d3c5db363d96f (commit)
via 3995de2c0356d8e3b34e8fb2ddf22b20210e498d (commit)
via ef077ba0d2fa28fd1b481f80335bda723d3d1f20 (commit)
via bbaddbc0682a4cd3271ee41f58550f7c26e8194e (commit)
via 0943d5dd6179e2e824ec9a38b7ea6caa17a84ebd (commit)
via f4e4382cae1fb85fec6e9aa26f65fc729a40a039 (commit)
from 658608c471a6e1f9b6d7f88c060a7adb77d7d334 (commit)
- Log -----------------------------------------------------------------
commit 7f293d9f3b5cee4f4b15624fff15a45e0517334f
Author: Richard Levitte <[email protected]>
Date: Thu Jan 30 16:02:49 2020 +0100
CHANGES: Add note about the refactoring of SM2 EVP_PKEYs
Reviewed-by: Matt Caswell <[email protected]>
Reviewed-by: Dmitry Belyavskiy <[email protected]>
(Merged from https://github.com/openssl/openssl/pull/10942)
commit bac1030ae4f93f22b3a81e3a2d9d3c5db363d96f
Author: Richard Levitte <[email protected]>
Date: Fri Jan 24 18:45:23 2020 +0100
Adapt some 'openssl' commands for SM2 changes.
There's no longer any need to make an EVP_PKEY type change for SM2
keys, so we trim away that code.
Reviewed-by: Matt Caswell <[email protected]>
Reviewed-by: Dmitry Belyavskiy <[email protected]>
(Merged from https://github.com/openssl/openssl/pull/10942)
commit 3995de2c0356d8e3b34e8fb2ddf22b20210e498d
Author: Richard Levitte <[email protected]>
Date: Fri Jan 24 18:14:53 2020 +0100
Adapt tests for SM2 changes.
With test/ecdsatest.c, we test all the curves once for each EC key
type we have, i.e. one round trip with EVP_PKEY_EC and one with
EVP_PKEY_SM2. This shows that we can use "normal" EC computations on
keys with the SM2 curve (which have the type EVP_PKEY_SM2 by default)
and SM2 computations with any other curve (which have the type
EVP_PKEY_EC by default)
test/evp_test.c, on the other hand, doesn't need to explicitly set the
EVP_PKEY_SM2 alias type, as that now happens automatically.
Reviewed-by: Matt Caswell <[email protected]>
Reviewed-by: Dmitry Belyavskiy <[email protected]>
(Merged from https://github.com/openssl/openssl/pull/10942)
commit ef077ba0d2fa28fd1b481f80335bda723d3d1f20
Author: Richard Levitte <[email protected]>
Date: Fri Jan 24 18:14:06 2020 +0100
Make SM3 a mandatory hash function for SM2.
Reviewed-by: Matt Caswell <[email protected]>
Reviewed-by: Dmitry Belyavskiy <[email protected]>
(Merged from https://github.com/openssl/openssl/pull/10942)
commit bbaddbc0682a4cd3271ee41f58550f7c26e8194e
Author: Richard Levitte <[email protected]>
Date: Fri Jan 24 18:04:19 2020 +0100
X509: Refactor X509_verify() and X509_REQ_verify() for better streamlining
The solution to incorporate the SM2 identity processing was an off
the side hack that more or less duplicated the ASN1_item_verify()
code with just a few lines being different. We replace this with
a new function ASN1_item_verify_ctx(), which takes an EVP_MD_CTX
pointer instead of an EVP_PKEY pointer, just like its sibling
ASN1_item_sign_ctx().
This allows us to refactor X509_verify() and X509_REQ_verify() to
simply create a local EVP_MD_CTX and an attached EVP_PKEY_CTX,
which gets to hold the SM2 identity, if there is one, and then let
ASN1_item_verify_ctx() to its job.
This will also make it easier to adapt ASN1_item_verify_ctx() for
provider based keys.
Reviewed-by: Matt Caswell <[email protected]>
Reviewed-by: Dmitry Belyavskiy <[email protected]>
(Merged from https://github.com/openssl/openssl/pull/10942)
commit 0943d5dd6179e2e824ec9a38b7ea6caa17a84ebd
Author: Richard Levitte <[email protected]>
Date: Fri Jan 24 17:59:03 2020 +0100
Add SM2 specific parameter and key generation
This makes it possible to generate SM2 parameters and keys like this:
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2);
EVP_PKEY *pkey = EVP_PKEY_new();
EVP_PKEY_keygen_init(pctx);
EVP_PKEY_keygen(pctx, pkey);
Reviewed-by: Matt Caswell <[email protected]>
Reviewed-by: Dmitry Belyavskiy <[email protected]>
(Merged from https://github.com/openssl/openssl/pull/10942)
commit f4e4382cae1fb85fec6e9aa26f65fc729a40a039
Author: Richard Levitte <[email protected]>
Date: Fri Jan 24 17:51:39 2020 +0100
EVP_PKEY_assign_EC_KEY(): detect SM2 curve and set EVP_PKEY type accordingly
This means that when loaded or created, EC EVP_PKEYs with the SM2
curve will be regarded as EVP_PKEY_SM2 type keys by default.
Applications are no longer forced to check and fix this.
It's still possible, for those who want this, to set the key type to
EVP_PKEY_EC and thereby run the normal EC computations with the SM2
curve. This has to be done explicitly.
Reviewed-by: Matt Caswell <[email protected]>
Reviewed-by: Dmitry Belyavskiy <[email protected]>
(Merged from https://github.com/openssl/openssl/pull/10942)
-----------------------------------------------------------------------
Summary of changes:
CHANGES | 13 +++
apps/req.c | 113 +++++++-------------------
apps/speed.c | 2 -
crypto/asn1/a_verify.c | 69 ++++++++++------
crypto/ec/ec_ameth.c | 4 +-
crypto/evp/p_lib.c | 13 ++-
crypto/sm2/sm2_pmeth.c | 67 +++++++++------
crypto/x509/x_all.c | 180 ++++++++++-------------------------------
doc/man3/EVP_PKEY_set1_RSA.pod | 15 +++-
doc/man7/SM2.pod | 22 ++---
include/openssl/x509.h | 3 +
test/ecdsatest.c | 94 +++++++++++++++++----
test/evp_test.c | 11 ---
util/libcrypto.num | 1 +
14 files changed, 285 insertions(+), 322 deletions(-)
diff --git a/CHANGES b/CHANGES
index b002df633c..9eb778a004 100644
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,19 @@
Changes between 1.1.1 and 3.0.0 [xx XXX xxxx]
+ *) Reworked the treatment of EC EVP_PKEYs with the SM2 curve to
+ automatically become EVP_PKEY_SM2 rather than EVP_PKEY_EC.
+ This means that applications don't have to look at the curve NID and
+ 'EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)' to get SM2 computations.
+ However, they still can, that EVP_PKEY_set_alias_type() call acts as
+ a no-op when the EVP_PKEY is already of the given type.
+
+ Parameter and key generation is also reworked to make it possible
+ to generate EVP_PKEY_SM2 parameters and keys without having to go
+ through EVP_PKEY_EC generation and then change the EVP_PKEY type.
+ However, code that does the latter will still work as before.
+ [Richard Levitte]
+
*) Deprecated EVP_PKEY_decrypt_old(), please use EVP_PKEY_decrypt_init()
and EVP_PKEY_decrypt() instead.
Deprecated EVP_PKEY_encrypt_old(), please use EVP_PKEY_encrypt_init()
diff --git a/apps/req.c b/apps/req.c
index 87994ceb7c..7140705f09 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -1674,41 +1674,16 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx)
return 1;
}
-#ifndef OPENSSL_NO_SM2
-static int ec_pkey_is_sm2(EVP_PKEY *pkey)
-{
- EC_KEY *eckey = NULL;
- const EC_GROUP *group = NULL;
-
- if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2)
- return 1;
- if (EVP_PKEY_id(pkey) == EVP_PKEY_EC
- && (eckey = EVP_PKEY_get0_EC_KEY(pkey)) != NULL
- && (group = EC_KEY_get0_group(eckey)) != NULL
- && EC_GROUP_get_curve_name(group) == NID_sm2)
- return 1;
- return 0;
-}
-#endif
-
static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
{
EVP_PKEY_CTX *pkctx = NULL;
-#ifndef OPENSSL_NO_SM2
EVP_PKEY_CTX *pctx = NULL;
-#endif
int i, def_nid, ret = 0;
if (ctx == NULL)
goto err;
-#ifndef OPENSSL_NO_SM2
- if (ec_pkey_is_sm2(pkey)) {
- /* initialize some SM2-specific code */
- if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) {
- BIO_printf(bio_err, "Internal error.\n");
- goto err;
- }
+ if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) {
pctx = EVP_PKEY_CTX_new(pkey, NULL);
if (pctx == NULL) {
BIO_printf(bio_err, "memory allocation failure.\n");
@@ -1725,7 +1700,6 @@ static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
}
EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
}
-#endif
/*
* EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory
* for this algorithm.
@@ -1748,90 +1722,63 @@ static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey,
ret = 1;
err:
-#ifndef OPENSSL_NO_SM2
if (!ret)
EVP_PKEY_CTX_free(pctx);
-#endif
return ret;
}
+static void do_sign_cleanup(EVP_MD_CTX *ctx, EVP_PKEY *pkey)
+{
+ /*
+ * With SM2, do_sign_init() attached an EVP_PKEY_CTX to the EVP_MD_CTX,
+ * and we have to free it explicitly.
+ */
+ if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) {
+ EVP_PKEY_CTX *pctx = EVP_MD_CTX_pkey_ctx(ctx);
+
+ EVP_MD_CTX_set_pkey_ctx(ctx, NULL);
+ EVP_PKEY_CTX_free(pctx);
+ }
+}
+
int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts)
{
- int rv;
+ int rv = 0;
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
-#ifndef OPENSSL_NO_SM2
- EVP_PKEY_CTX *pctx = NULL;
-#endif
- rv = do_sign_init(mctx, pkey, md, sigopts);
- if (rv > 0) {
- rv = X509_sign_ctx(x, mctx);
-#ifndef OPENSSL_NO_SM2
- /*
- * only in SM2 case we need to free the pctx explicitly
- * if do_sign_init() fails, pctx is already freed in it
- */
- if (ec_pkey_is_sm2(pkey)) {
- pctx = EVP_MD_CTX_pkey_ctx(mctx);
- EVP_PKEY_CTX_free(pctx);
- }
-#endif
+ if (do_sign_init(mctx, pkey, md, sigopts) > 0) {
+ rv = (X509_sign_ctx(x, mctx) > 0);
+ do_sign_cleanup(mctx, pkey);
}
EVP_MD_CTX_free(mctx);
- return rv > 0 ? 1 : 0;
+ return rv;
}
int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts)
{
- int rv;
+ int rv = 0;
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
-#ifndef OPENSSL_NO_SM2
- EVP_PKEY_CTX *pctx = NULL;
-#endif
- rv = do_sign_init(mctx, pkey, md, sigopts);
- if (rv > 0) {
- rv = X509_REQ_sign_ctx(x, mctx);
-#ifndef OPENSSL_NO_SM2
- /*
- * only in SM2 case we need to free the pctx explicitly
- * if do_sign_init() fails, pctx is already freed in it
- */
- if (ec_pkey_is_sm2(pkey)) {
- pctx = EVP_MD_CTX_pkey_ctx(mctx);
- EVP_PKEY_CTX_free(pctx);
- }
-#endif
+ if (do_sign_init(mctx, pkey, md, sigopts) > 0) {
+ rv = (X509_REQ_sign_ctx(x, mctx) > 0);
+ do_sign_cleanup(mctx, pkey);
}
EVP_MD_CTX_free(mctx);
- return rv > 0 ? 1 : 0;
+ return rv;
}
int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
STACK_OF(OPENSSL_STRING) *sigopts)
{
- int rv;
+ int rv = 0;
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
-#ifndef OPENSSL_NO_SM2
- EVP_PKEY_CTX *pctx = NULL;
-#endif
- rv = do_sign_init(mctx, pkey, md, sigopts);
- if (rv > 0) {
- rv = X509_CRL_sign_ctx(x, mctx);
-#ifndef OPENSSL_NO_SM2
- /*
- * only in SM2 case we need to free the pctx explicitly
- * if do_sign_init() fails, no need to double free pctx
- */
- if (ec_pkey_is_sm2(pkey)) {
- pctx = EVP_MD_CTX_pkey_ctx(mctx);
- EVP_PKEY_CTX_free(pctx);
- }
-#endif
+ if (do_sign_init(mctx, pkey, md, sigopts) > 0) {
+ rv = (X509_CRL_sign_ctx(x, mctx) > 0);
+ do_sign_cleanup(mctx, pkey);
}
EVP_MD_CTX_free(mctx);
- return rv > 0 ? 1 : 0;
+ return rv;
}
diff --git a/apps/speed.c b/apps/speed.c
index a978bdf17a..d2afebb2c6 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -3399,8 +3399,6 @@ int speed_main(int argc, char **argv)
/* attach it sooner to rely on main final cleanup */
loopargs[i].sm2_pkey[testnum] = sm2_pkey;
loopargs[i].sigsize = ECDSA_size(EVP_PKEY_get0_EC_KEY(sm2_pkey));
- if (!EVP_PKEY_set_alias_type(sm2_pkey, EVP_PKEY_SM2))
- break;
sm2_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
sm2_vfy_pctx = EVP_PKEY_CTX_new(sm2_pkey, NULL);
diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c
index 92f9448749..94a11c18d4 100644
--- a/crypto/asn1/a_verify.c
+++ b/crypto/asn1/a_verify.c
@@ -88,65 +88,85 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a,
ASN1_BIT_STRING *signature,
int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
{
- EVP_MD_CTX *ctx = NULL;
+ int rv = -1;
+ EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+ EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL);
+
+ if (ctx == NULL || pctx == NULL) {
+ ASN1err(0, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
+
+ rv = ASN1_item_verify_ctx(it, a, signature, asn, ctx);
+
+ err:
+ EVP_PKEY_CTX_free(pctx);
+ EVP_MD_CTX_free(ctx);
+ return rv;
+}
+
+int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *a,
+ ASN1_BIT_STRING *signature, void *asn,
+ EVP_MD_CTX *ctx)
+{
+ EVP_PKEY *pkey;
unsigned char *buf_in = NULL;
int ret = -1, inl = 0;
int mdnid, pknid;
size_t inll = 0;
+ pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_pkey_ctx(ctx));
+
if (pkey == NULL) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
+ ASN1err(0, ERR_R_PASSED_NULL_PARAMETER);
return -1;
}
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+ ASN1err(0, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
return -1;
}
- ctx = EVP_MD_CTX_new();
- if (ctx == NULL) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
/* Convert signature OID into digest and public key OIDs */
if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+ ASN1err(0, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
goto err;
}
+
if (mdnid == NID_undef) {
if (pkey->ameth == NULL || pkey->ameth->item_verify == NULL) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
- ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+ ASN1err(0, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
goto err;
}
ret = pkey->ameth->item_verify(ctx, it, asn, a, signature, pkey);
/*
- * Return value of 2 means carry on, anything else means we exit
- * straight away: either a fatal error of the underlying verification
- * routine handles all verification.
+ * Return values meaning:
+ * <=0: error.
+ * 1: method does everything.
+ * 2: carry on as normal, method has called EVP_DigestVerifyInit()
*/
- if (ret != 2)
+ if (ret <= 0)
+ ASN1err(0, ERR_R_EVP_LIB);
+ if (ret <= 1)
goto err;
- ret = -1;
} else {
const EVP_MD *type = EVP_get_digestbynid(mdnid);
if (type == NULL) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
- ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+ ASN1err(0, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
goto err;
}
/* Check public key OID matches public key type */
if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
+ ASN1err(0, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
goto err;
}
if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+ ASN1err(0, ERR_R_EVP_LIB);
ret = 0;
goto err;
}
@@ -154,11 +174,11 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
inl = ASN1_item_i2d(asn, &buf_in, it);
if (inl <= 0) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_INTERNAL_ERROR);
+ ASN1err(0, ERR_R_INTERNAL_ERROR);
goto err;
}
if (buf_in == NULL) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
+ ASN1err(0, ERR_R_MALLOC_FAILURE);
goto err;
}
inll = inl;
@@ -166,12 +186,11 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
ret = EVP_DigestVerify(ctx, signature->data, (size_t)signature->length,
buf_in, inl);
if (ret <= 0) {
- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
+ ASN1err(0, ERR_R_EVP_LIB);
goto err;
}
ret = 1;
err:
OPENSSL_clear_free(buf_in, inll);
- EVP_MD_CTX_free(ctx);
return ret;
}
diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
index 6105e6b087..f38ab103ab 100644
--- a/crypto/ec/ec_ameth.c
+++ b/crypto/ec/ec_ameth.c
@@ -507,9 +507,9 @@ static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1,
void *arg2)
if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) {
/* For SM2, the only valid digest-alg is SM3 */
*(int *)arg2 = NID_sm3;
- } else {
- *(int *)arg2 = NID_sha256;
+ return 2; /* Make it mandatory */
}
+ *(int *)arg2 = NID_sha256;
return 1;
case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 07316a4522..0a3c86d63a 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -401,8 +401,19 @@ ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey)
# endif
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
{
+ int alias = type;
+
+ if (EVP_PKEY_type(type) == EVP_PKEY_EC) {
+ const EC_GROUP *group = EC_KEY_get0_group(key);
+
+ if (group != NULL && EC_GROUP_get_curve_name(group) == NID_sm2)
+ alias = EVP_PKEY_SM2;
+ }
+
if (pkey == NULL || !EVP_PKEY_set_type(pkey, type))
return 0;
+ if (!EVP_PKEY_set_alias_type(pkey, alias))
+ return 0;
pkey->pkey.ptr = key;
return (key != NULL);
}
@@ -519,7 +530,7 @@ int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey)
{
- if (pkey->type != EVP_PKEY_EC) {
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
return NULL;
}
diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c
index 27bec2cb06..1068b7b901 100644
--- a/crypto/sm2/sm2_pmeth.c
+++ b/crypto/sm2/sm2_pmeth.c
@@ -18,8 +18,6 @@
/* EC pkey context structure */
typedef struct {
- /* Key and paramgen group */
- EC_GROUP *gen_group;
/* message digest */
const EVP_MD *md;
/* Distinguishing Identifier, ISO/IEC 15946-3 */
@@ -47,7 +45,6 @@ static void pkey_sm2_cleanup(EVP_PKEY_CTX *ctx)
SM2_PKEY_CTX *smctx = ctx->data;
if (smctx != NULL) {
- EC_GROUP_free(smctx->gen_group);
OPENSSL_free(smctx->id);
OPENSSL_free(smctx);
ctx->data = NULL;
@@ -62,13 +59,6 @@ static int pkey_sm2_copy(EVP_PKEY_CTX *dst, const
EVP_PKEY_CTX *src)
return 0;
sctx = src->data;
dctx = dst->data;
- if (sctx->gen_group != NULL) {
- dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
- if (dctx->gen_group == NULL) {
- pkey_sm2_cleanup(dst);
- return 0;
- }
- }
if (sctx->id != NULL) {
dctx->id = OPENSSL_malloc(sctx->id_len);
if (dctx->id == NULL) {
@@ -163,26 +153,21 @@ static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx,
static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
SM2_PKEY_CTX *smctx = ctx->data;
- EC_GROUP *group;
uint8_t *tmp_id;
switch (type) {
case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
- group = EC_GROUP_new_by_curve_name(p1);
- if (group == NULL) {
+ /*
+ * This control could be removed, which would signal it being
+ * unsupported. However, that means that when the caller uses
+ * the correct curve, it may interpret the unsupported signal
+ * as an error, so it's better to accept the control, check the
+ * value and return a corresponding value.
+ */
+ if (p1 != NID_sm2) {
SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_INVALID_CURVE);
return 0;
}
- EC_GROUP_free(smctx->gen_group);
- smctx->gen_group = group;
- return 1;
-
- case EVP_PKEY_CTRL_EC_PARAM_ENC:
- if (smctx->gen_group == NULL) {
- SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_NO_PARAMETERS_SET);
- return 0;
- }
- EC_GROUP_set_asn1_flag(smctx->gen_group, p1);
return 1;
case EVP_PKEY_CTRL_MD:
@@ -309,6 +294,38 @@ static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx,
EVP_MD_CTX *mctx)
return EVP_DigestUpdate(mctx, z, (size_t)mdlen);
}
+static int pkey_sm2_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+ EC_KEY *ec = NULL;
+ int ret;
+
+ ec = EC_KEY_new_by_curve_name(NID_sm2);
+ if (ec == NULL)
+ return 0;
+ if (!ossl_assert(ret = EVP_PKEY_assign_EC_KEY(pkey, ec)))
+ EC_KEY_free(ec);
+ return ret;
+}
+
+static int pkey_sm2_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+ EC_KEY *ec = NULL;
+
+ ec = EC_KEY_new_by_curve_name(NID_sm2);
+ if (ec == NULL)
+ return 0;
+ if (!ossl_assert(EVP_PKEY_assign_EC_KEY(pkey, ec))) {
+ EC_KEY_free(ec);
+ return 0;
+ }
+ /* Note: if error is returned, we count on caller to free pkey->pkey.ec */
+ if (ctx->pkey != NULL
+ && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
+ return 0;
+
+ return EC_KEY_generate_key(ec);
+}
+
static const EVP_PKEY_METHOD sm2_pkey_meth = {
EVP_PKEY_SM2,
0,
@@ -317,10 +334,10 @@ static const EVP_PKEY_METHOD sm2_pkey_meth = {
pkey_sm2_cleanup,
0,
- 0,
+ pkey_sm2_paramgen,
0,
- 0,
+ pkey_sm2_keygen,
0,
pkey_sm2_sign,
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index fbdb100c00..9af26e69f0 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -19,176 +19,78 @@
#include <openssl/dsa.h>
#include <openssl/x509v3.h>
-#ifndef OPENSSL_NO_SM2
+static void clean_id_ctx(EVP_MD_CTX *ctx)
+{
+ EVP_PKEY_CTX *pctx = EVP_MD_CTX_pkey_ctx(ctx);
-# include "crypto/asn1.h"
-# include "crypto/evp.h"
+ EVP_PKEY_CTX_free(pctx);
+ EVP_MD_CTX_free(ctx);
+}
-static int common_verify_sm2(void *data, EVP_PKEY *pkey,
- int mdnid, int pknid, int req)
+static EVP_MD_CTX *make_id_ctx(EVP_PKEY *r, ASN1_OCTET_STRING *id)
{
- X509 *x = NULL;
- X509_REQ *r = NULL;
EVP_MD_CTX *ctx = NULL;
- unsigned char *buf_in = NULL;
- int ret = -1, inl = 0;
- size_t inll = 0;
EVP_PKEY_CTX *pctx = NULL;
- const EVP_MD *type = EVP_get_digestbynid(mdnid);
- ASN1_BIT_STRING *signature = NULL;
- ASN1_OCTET_STRING *sm2_id = NULL;
- ASN1_VALUE *tbv = NULL;
-
- if (type == NULL) {
- X509err(X509_F_COMMON_VERIFY_SM2,
- ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
- goto err;
- }
-
- if (pkey == NULL) {
- X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_PASSED_NULL_PARAMETER);
- return -1;
- }
-
- if (req == 1) {
- r = (X509_REQ *)data;
- signature = r->signature;
- sm2_id = r->sm2_id;
- tbv = (ASN1_VALUE *)&r->req_info;
- } else {
- x = (X509 *)data;
- signature = &x->signature;
- sm2_id = x->sm2_id;
- tbv = (ASN1_VALUE *)&x->cert_info;
- }
-
- if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
- X509err(X509_F_COMMON_VERIFY_SM2, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
- return -1;
- }
- ctx = EVP_MD_CTX_new();
- if (ctx == NULL) {
- X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_MALLOC_FAILURE);
- goto err;
+ if ((ctx = EVP_MD_CTX_new()) == NULL
+ || (pctx = EVP_PKEY_CTX_new(r, NULL)) == NULL) {
+ X509err(0, ERR_R_MALLOC_FAILURE);
+ goto error;
}
- /* Check public key OID matches public key type */
- if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
- X509err(X509_F_COMMON_VERIFY_SM2, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
- goto err;
+ if (id != NULL) {
+ if (EVP_PKEY_CTX_set1_id(pctx, id->data, id->length) <= 0) {
+ X509err(0, ERR_R_MALLOC_FAILURE);
+ goto error;
+ }
}
- if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) {
- X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB);
- ret = 0;
- goto err;
- }
- pctx = EVP_PKEY_CTX_new(pkey, NULL);
- if (pctx == NULL) {
- X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB);
- ret = 0;
- goto err;
- }
- /* NOTE: we tolerate no actual ID, to provide maximum flexibility */
- if (sm2_id != NULL
- && EVP_PKEY_CTX_set1_id(pctx, sm2_id->data, sm2_id->length) != 1) {
- X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB);
- ret = 0;
- goto err;
- }
EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
- if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) {
- X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB);
- ret = 0;
- goto err;
- }
-
- inl = ASN1_item_i2d(tbv, &buf_in,
- req == 1 ?
- ASN1_ITEM_rptr(X509_REQ_INFO) :
- ASN1_ITEM_rptr(X509_CINF));
- if (inl <= 0) {
- X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- if (buf_in == NULL) {
- X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- inll = inl;
-
- ret = EVP_DigestVerify(ctx, signature->data,
- (size_t)signature->length, buf_in, inl);
- if (ret <= 0) {
- X509err(X509_F_COMMON_VERIFY_SM2, ERR_R_EVP_LIB);
- goto err;
- }
- ret = 1;
- err:
- OPENSSL_clear_free(buf_in, inll);
- EVP_MD_CTX_free(ctx);
+ return ctx;
+ error:
EVP_PKEY_CTX_free(pctx);
- return ret;
-}
-
-static int x509_verify_sm2(X509 *x, EVP_PKEY *pkey, int mdnid, int pknid)
-{
- return common_verify_sm2(x, pkey, mdnid, pknid, 0);
-}
-
-static int x509_req_verify_sm2(X509_REQ *x, EVP_PKEY *pkey,
- int mdnid, int pknid)
-{
- return common_verify_sm2(x, pkey, mdnid, pknid, 1);
+ EVP_MD_CTX_free(ctx);
+ return NULL;
}
-#endif
-
int X509_verify(X509 *a, EVP_PKEY *r)
{
-#ifndef OPENSSL_NO_SM2
- int mdnid, pknid;
-#endif
+ int rv = 0;
+ EVP_MD_CTX *ctx = NULL;
+ ASN1_OCTET_STRING *id = NULL;
if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature))
return 0;
#ifndef OPENSSL_NO_SM2
- /* Convert signature OID into digest and public key OIDs */
- if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->sig_alg.algorithm),
- &mdnid, &pknid)) {
- X509err(X509_F_X509_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
- return 0;
- }
-
- if (pknid == NID_sm2)
- return x509_verify_sm2(a, r, mdnid, pknid);
+ id = a->sm2_id;
#endif
- return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg,
- &a->signature, &a->cert_info, r));
+ if ((ctx = make_id_ctx(r, id)) != NULL) {
+ rv = ASN1_item_verify_ctx(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg,
+ &a->signature, &a->cert_info, ctx);
+ clean_id_ctx(ctx);
+ }
+ return rv;
}
int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r)
{
-#ifndef OPENSSL_NO_SM2
- int mdnid, pknid;
-
- /* Convert signature OID into digest and public key OIDs */
- if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->sig_alg.algorithm),
- &mdnid, &pknid)) {
- X509err(X509_F_X509_REQ_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
- return 0;
- }
+ int rv = 0;
+ EVP_MD_CTX *ctx = NULL;
+ ASN1_OCTET_STRING *id = NULL;
- if (pknid == NID_sm2)
- return x509_req_verify_sm2(a, r, mdnid, pknid);
+#ifndef OPENSSL_NO_SM2
+ id = a->sm2_id;
#endif
- return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO),
- &a->sig_alg, a->signature, &a->req_info, r));
+ if ((ctx = make_id_ctx(r, id)) != NULL) {
+ rv = ASN1_item_verify_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), &a->sig_alg,
+ a->signature, &a->req_info, ctx);
+ clean_id_ctx(ctx);
+ }
+ return rv;
}
int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r)
diff --git a/doc/man3/EVP_PKEY_set1_RSA.pod b/doc/man3/EVP_PKEY_set1_RSA.pod
index 8f4d7f547a..8423a0a3b8 100644
--- a/doc/man3/EVP_PKEY_set1_RSA.pod
+++ b/doc/man3/EVP_PKEY_set1_RSA.pod
@@ -90,8 +90,7 @@ If B<engine> does not include an B<EVP_PKEY_METHOD> for
B<pkey> an
error occurs.
EVP_PKEY_set_alias_type() allows modifying a EVP_PKEY to use a
-different set of algorithms than the default. This is currently used
-to support SM2 keys, which use an identical encoding to ECDSA.
+different set of algorithms than the default.
=head1 NOTES
@@ -103,6 +102,16 @@ EVP_PKEY_assign_RSA(), EVP_PKEY_assign_DSA(),
EVP_PKEY_assign_DH(),
EVP_PKEY_assign_EC_KEY(), EVP_PKEY_assign_POLY1305()
and EVP_PKEY_assign_SIPHASH() are implemented as macros.
+EVP_PKEY_assign_EC_KEY() looks at the curve name id to determine if
+the passed B<EC_KEY> is an L<SM2(7)> key, and will set the B<EVP_PKEY>
+type to B<EVP_PKEY_SM2> in that case, instead of B<EVP_PKEY_EC>.
+
+It's possible to switch back and forth between the types B<EVP_PKEY_EC>
+and B<EVP_PKEY_SM2> with a call to EVP_PKEY_set_alias_type() on keys
+assigned with this macro if it's desirable to do a normal EC
+computations with the SM2 curve instead of the special SM2
+computations, and vice versa.
+
Most applications wishing to know a key type will simply call
EVP_PKEY_base_id() and will not care about the actual type:
which will be identical in almost all cases.
@@ -143,7 +152,7 @@ algorithms with EVP_PKEY_set_alias_type:
=head1 SEE ALSO
-L<EVP_PKEY_new(3)>
+L<EVP_PKEY_new(3)>, L<SM2(7)>
=head1 COPYRIGHT
diff --git a/doc/man7/SM2.pod b/doc/man7/SM2.pod
index c7876a0cc6..93fd12c909 100644
--- a/doc/man7/SM2.pod
+++ b/doc/man7/SM2.pod
@@ -20,25 +20,17 @@ B<SM2> signatures can be generated by using the
'DigestSign' series of APIs, for
instance, EVP_DigestSignInit(), EVP_DigestSignUpdate() and
EVP_DigestSignFinal().
Ditto for the verification process by calling the 'DigestVerify' series of
APIs.
-There are several special steps that need to be done before computing an B<SM2>
-signature.
-
-The B<EVP_PKEY> structure will default to using ECDSA for signatures when it is
-created. It should be set to B<EVP_PKEY_SM2> by calling:
-
- EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2);
-
-Then an ID should be set by calling:
+Before computing an B<SM2> signature, an B<EVP_PKEY_CTX> needs to be created,
+and an B<SM2> ID must be set for it, like this:
EVP_PKEY_CTX_set1_id(pctx, id, id_len);
-When calling the EVP_DigestSignInit() or EVP_DigestVerifyInit() functions, a
-pre-allocated B<EVP_PKEY_CTX> should be assigned to the B<EVP_MD_CTX>. This is
-done by calling:
+Before calling the EVP_DigestSignInit() or EVP_DigestVerifyInit() functions,
+that B<EVP_PKEY_CTX> should be assigned to the B<EVP_MD_CTX>, like this:
EVP_MD_CTX_set_pkey_ctx(mctx, pctx);
-And normally there is no need to pass a B<pctx> parameter to
EVP_DigestSignInit()
+There is normally no need to pass a B<pctx> parameter to EVP_DigestSignInit()
or EVP_DigestVerifyInit() in such a scenario.
SM2 can be tested with the L<openssl-speed(1)> application since version 3.0.0.
@@ -52,11 +44,10 @@ a message with the SM2 signature algorithm and the SM3 hash
algorithm:
#include <openssl/evp.h>
/* obtain an EVP_PKEY using whatever methods... */
- EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2);
mctx = EVP_MD_CTX_new();
pctx = EVP_PKEY_CTX_new(pkey, NULL);
EVP_PKEY_CTX_set1_id(pctx, id, id_len);
- EVP_MD_CTX_set_pkey_ctx(mctx, pctx);;
+ EVP_MD_CTX_set_pkey_ctx(mctx, pctx);
EVP_DigestVerifyInit(mctx, NULL, EVP_sm3(), NULL, pkey);
EVP_DigestVerifyUpdate(mctx, msg, msg_len);
EVP_DigestVerifyFinal(mctx, sig, sig_len)
@@ -64,7 +55,6 @@ a message with the SM2 signature algorithm and the SM3 hash
algorithm:
=head1 SEE ALSO
L<EVP_PKEY_CTX_new(3)>,
-L<EVP_PKEY_set_alias_type(3)>,
L<EVP_DigestSignInit(3)>,
L<EVP_DigestVerifyInit(3)>,
L<EVP_PKEY_CTX_set1_id(3)>,
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 4cd17d24f5..5e553ef4d3 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -637,6 +637,9 @@ int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD
*type, void *data,
int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey);
+int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
+ ASN1_BIT_STRING *signature, void *data,
+ EVP_MD_CTX *ctx);
int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data,
diff --git a/test/ecdsatest.c b/test/ecdsatest.c
index a62efad1cf..f99817898f 100644
--- a/test/ecdsatest.c
+++ b/test/ecdsatest.c
@@ -201,7 +201,30 @@ static int x9_62_tests(int n)
* - reject that signature after modifying the signature
* - accept that signature after un-modifying the signature
*/
-static int test_builtin(int n)
+static int set_sm2_id(EVP_MD_CTX *mctx, EVP_PKEY *pkey)
+{
+ /* With the SM2 key type, the SM2 ID is mandatory */
+ static const char sm2_id[] = { 1, 2, 3, 4, 'l', 'e', 't', 't', 'e', 'r' };
+ EVP_PKEY_CTX *pctx;
+
+ if (!TEST_ptr(pctx = EVP_PKEY_CTX_new(pkey, NULL))
+ || !TEST_int_gt(EVP_PKEY_CTX_set1_id(pctx, sm2_id, sizeof(sm2_id)), 0))
+ return 0;
+ EVP_MD_CTX_set_pkey_ctx(mctx, pctx);
+ return 1;
+}
+
+static int clean_sm2_id(EVP_MD_CTX *mctx)
+{
+ EVP_PKEY_CTX *pctx;
+
+ if (!TEST_ptr(pctx = EVP_MD_CTX_pkey_ctx(mctx)))
+ return 0;
+ EVP_PKEY_CTX_free(pctx);
+ return 1;
+}
+
+static int test_builtin(int n, int as)
{
EC_KEY *eckey_neg = NULL, *eckey = NULL;
unsigned char dirt, offset, tbs[128];
@@ -220,7 +243,8 @@ static int test_builtin(int n)
return 1;
}
- TEST_info("testing ECDSA for curve %s", OBJ_nid2sn(nid));
+ TEST_info("testing ECDSA for curve %s as %s key type", OBJ_nid2sn(nid),
+ as == EVP_PKEY_EC ? "EC" : "SM2");
if (!TEST_ptr(mctx = EVP_MD_CTX_new())
/* get some random message data */
@@ -239,37 +263,62 @@ static int test_builtin(int n)
temp = ECDSA_size(eckey);
+ /*
+ * |as| indicates how we want to treat the key, i.e. what sort of
+ * computation we want to do with it. The two choices are the key
+ * types EVP_PKEY_EC and EVP_PKEY_SM2. It's perfectly possible to
+ * switch back and forth between those two key types, regardless of
+ * curve, even though the default is to have EVP_PKEY_SM2 for the
+ * SM2 curve and EVP_PKEY_EC for all other curves.
+ */
+ if (!TEST_true(EVP_PKEY_set_alias_type(pkey, as))
+ || !TEST_true(EVP_PKEY_set_alias_type(pkey_neg, as)))
+ goto err;
+
if (!TEST_int_ge(temp, 0)
|| !TEST_ptr(sig = OPENSSL_malloc(sig_len = (size_t)temp))
/* create a signature */
+ || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
|| !TEST_true(EVP_DigestSignInit(mctx, NULL, NULL, NULL, pkey))
|| !TEST_true(EVP_DigestSign(mctx, sig, &sig_len, tbs, sizeof(tbs)))
|| !TEST_int_le(sig_len, ECDSA_size(eckey))
- /* negative test, verify with wrong key, 0 return */
+ || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
|| !TEST_true(EVP_MD_CTX_reset(mctx))
+ /* negative test, verify with wrong key, 0 return */
+ || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey_neg))
|| !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey_neg))
|| !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs,
sizeof(tbs)), 0)
- /* negative test, verify with wrong signature length, -1 return */
+ || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
|| !TEST_true(EVP_MD_CTX_reset(mctx))
+ /* negative test, verify with wrong signature length, -1 return */
+ || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
|| !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
|| !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len - 1, tbs,
sizeof(tbs)), -1)
- /* positive test, verify with correct key, 1 return */
+ || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
|| !TEST_true(EVP_MD_CTX_reset(mctx))
+ /* positive test, verify with correct key, 1 return */
+ || (as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
|| !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
- || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs,
sizeof(tbs)), 1))
+ || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs,
sizeof(tbs)), 1)
+ || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
+ || !TEST_true(EVP_MD_CTX_reset(mctx)))
goto err;
/* muck with the message, test it fails with 0 return */
tbs[0] ^= 1;
- if (!TEST_true(EVP_MD_CTX_reset(mctx))
+ if ((as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
|| !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
- || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs,
sizeof(tbs)), 0))
+ || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs,
sizeof(tbs)), 0)
+ || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
+ || !TEST_true(EVP_MD_CTX_reset(mctx)))
goto err;
/* un-muck and test it verifies */
tbs[0] ^= 1;
- if (!TEST_true(EVP_MD_CTX_reset(mctx))
+ if ((as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
|| !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
- || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs,
sizeof(tbs)), 1))
+ || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs,
sizeof(tbs)), 1)
+ || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
+ || !TEST_true(EVP_MD_CTX_reset(mctx)))
goto err;
/*-
@@ -301,15 +350,19 @@ static int test_builtin(int n)
offset = tbs[0] % sig_len;
dirt = tbs[1] ? tbs[1] : 1;
sig[offset] ^= dirt;
- if (!TEST_true(EVP_MD_CTX_reset(mctx))
+ if ((as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
|| !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
- || !TEST_int_ne(EVP_DigestVerify(mctx, sig, sig_len, tbs,
sizeof(tbs)), 1))
+ || !TEST_int_ne(EVP_DigestVerify(mctx, sig, sig_len, tbs,
sizeof(tbs)), 1)
+ || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
+ || !TEST_true(EVP_MD_CTX_reset(mctx)))
goto err;
/* un-muck and test it verifies */
sig[offset] ^= dirt;
- if (!TEST_true(EVP_MD_CTX_reset(mctx))
+ if ((as == EVP_PKEY_SM2 && !set_sm2_id(mctx, pkey))
|| !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
- || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs,
sizeof(tbs)), 1))
+ || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs,
sizeof(tbs)), 1)
+ || (as == EVP_PKEY_SM2 && !clean_sm2_id(mctx))
+ || !TEST_true(EVP_MD_CTX_reset(mctx)))
goto err;
ret = 1;
@@ -320,6 +373,16 @@ static int test_builtin(int n)
OPENSSL_free(sig);
return ret;
}
+
+static int test_builtin_as_ec(int n)
+{
+ return test_builtin(n, EVP_PKEY_EC);
+}
+
+static int test_builtin_as_sm2(int n)
+{
+ return test_builtin(n, EVP_PKEY_SM2);
+}
#endif
int setup_tests(void)
@@ -332,7 +395,8 @@ int setup_tests(void)
if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
|| !TEST_true(EC_get_builtin_curves(curves, crv_len)))
return 0;
- ADD_ALL_TESTS(test_builtin, crv_len);
+ ADD_ALL_TESTS(test_builtin_as_ec, crv_len);
+ ADD_ALL_TESTS(test_builtin_as_sm2, crv_len);
ADD_ALL_TESTS(x9_62_tests, OSSL_NELEM(ecdsa_cavs_kats));
#endif
return 1;
diff --git a/test/evp_test.c b/test/evp_test.c
index e4d30fb20d..a6335ac93e 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -3145,17 +3145,6 @@ top:
if (!TEST_ptr(key = OPENSSL_malloc(sizeof(*key))))
return 0;
key->name = take_value(pp);
-
- /* Hack to detect SM2 keys */
- if(pkey != NULL && strstr(key->name, "SM2") != NULL) {
-#ifdef OPENSSL_NO_SM2
- EVP_PKEY_free(pkey);
- pkey = NULL;
-#else
- EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2);
-#endif
- }
-
key->key = pkey;
key->next = *klist;
*klist = key;
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 8bec3443b6..9dc3f76e15 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4917,3 +4917,4 @@ PKCS8_pkey_add1_attr ? 3_0_0
EXIST::FUNCTION:
PKCS8_pkey_add1_attr_by_OBJ ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_private_check ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_pairwise_check ? 3_0_0 EXIST::FUNCTION:
+ASN1_item_verify_ctx ? 3_0_0 EXIST::FUNCTION: