Support setting SM2 ID
authorPaul Yang <yang.yang@baishancloud.com>
Tue, 4 Sep 2018 09:21:10 +0000 (17:21 +0800)
committerPaul Yang <yang.yang@baishancloud.com>
Fri, 7 Sep 2018 10:12:26 +0000 (18:12 +0800)
zero-length ID is allowed, but it's not allowed to skip the ID.

Fixes: #6534
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7113)

15 files changed:
crypto/err/openssl.txt
crypto/evp/digest.c
crypto/evp/evp_lib.c
crypto/evp/m_sigver.c
crypto/evp/pmeth_lib.c
crypto/include/internal/evp_int.h
crypto/include/internal/sm2.h
crypto/include/internal/sm2err.h
crypto/sm2/sm2_err.c
crypto/sm2/sm2_pmeth.c
crypto/sm2/sm2_sign.c
include/openssl/ec.h
include/openssl/evp.h
test/evp_extra_test.c
util/private.num

index 3ecd44b5e83a8c5144612a89e2648b52097441d3..2f86786d583f96d4b353d24cc8cbe737a039eb8a 100644 (file)
@@ -1086,6 +1086,7 @@ SM2_F_PKEY_SM2_INIT:111:pkey_sm2_init
 SM2_F_PKEY_SM2_SIGN:112:pkey_sm2_sign
 SM2_F_SM2_COMPUTE_MSG_HASH:100:sm2_compute_msg_hash
 SM2_F_SM2_COMPUTE_USERID_DIGEST:101:sm2_compute_userid_digest
+SM2_F_SM2_COMPUTE_Z_DIGEST:113:sm2_compute_z_digest
 SM2_F_SM2_DECRYPT:102:sm2_decrypt
 SM2_F_SM2_ENCRYPT:103:sm2_encrypt
 SM2_F_SM2_PLAINTEXT_SIZE:104:sm2_plaintext_size
@@ -2554,6 +2555,8 @@ RSA_R_WRONG_SIGNATURE_LENGTH:119:wrong signature length
 SM2_R_ASN1_ERROR:100:asn1 error
 SM2_R_BAD_SIGNATURE:101:bad signature
 SM2_R_BUFFER_TOO_SMALL:107:buffer too small
+SM2_R_DIST_ID_TOO_LARGE:110:dist id too large
+SM2_R_ID_TOO_LARGE:111:id too large
 SM2_R_INVALID_CURVE:108:invalid curve
 SM2_R_INVALID_DIGEST:102:invalid digest
 SM2_R_INVALID_DIGEST_TYPE:103:invalid digest type
index 8a2d162df186cbcfeb4be1fbffa748e3ddabb0e1..f78dab7678654a56d4b286e6cebeb2c44f01776e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -34,9 +34,9 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
     }
     /*
      * pctx should be freed by the user of EVP_MD_CTX
-     * if EVP_MD_CTX_FLAG_NEGLECT_PCTX is set
+     * if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set
      */
-    if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_NEGLECT_PCTX))
+    if (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX))
         EVP_PKEY_CTX_free(ctx->pctx);
 #ifndef OPENSSL_NO_ENGINE
     ENGINE_finish(ctx->engine);
@@ -229,6 +229,9 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
     EVP_MD_CTX_reset(out);
     memcpy(out, in, sizeof(*out));
 
+    /* copied EVP_MD_CTX should free the copied EVP_PKEY_CTX */
+    EVP_MD_CTX_clear_flags(out, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
+
     /* Null these variables, since they are getting fixed up
      * properly below.  Anything else may cause a memleak and/or
      * double free if any of the memory allocations below fail
index 4faaf694b4e6f8b85c25501f1778076fcf9abc5b..81a5bf00129096cfbc0ca278ca04343a1fa61c63 100644 (file)
@@ -464,7 +464,7 @@ void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx)
 {
     ctx->pctx = pctx;
     /* make sure pctx is not freed when destroying EVP_MD_CTX */
-    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NEGLECT_PCTX);
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
 }
 
 void *EVP_MD_CTX_md_data(const EVP_MD_CTX *ctx)
index 4a0e5d5c554e1130ab11b94915b4c47c0ca4658c..2eceede28c1488a2cad8762d8edda97096fe1d59 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -75,14 +75,13 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
         return 1;
     if (!EVP_DigestInit_ex(ctx, type, e))
         return 0;
-    if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_DIGEST_CUSTOM) {
-        /*
-         * This indicates the current algorithm requires
-         * special treatment before hashing the tbs-message.
-         */
-        if (ctx->pctx->pmeth->digest_custom)
-            return ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx);
-    }
+    /*
+     * This indicates the current algorithm requires
+     * special treatment before hashing the tbs-message.
+     */
+    if (ctx->pctx->pmeth->digest_custom)
+        return ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx);
+
     return 1;
 }
 
@@ -184,9 +183,9 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
     else
         vctx = 0;
     if (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) {
-        if (vctx) {
+        if (vctx)
             r = ctx->pctx->pmeth->verifyctx(ctx->pctx, sig, siglen, ctx);
-        else
+        else
             r = EVP_DigestFinal_ex(ctx, md, &mdlen);
     } else {
         EVP_MD_CTX *tmp_ctx = EVP_MD_CTX_new();
@@ -196,10 +195,10 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
             EVP_MD_CTX_free(tmp_ctx);
             return -1;
         }
-        if (vctx) {
+        if (vctx)
             r = tmp_ctx->pctx->pmeth->verifyctx(tmp_ctx->pctx,
                                                 sig, siglen, tmp_ctx);
-        else
+        else
             r = EVP_DigestFinal_ex(tmp_ctx, md, &mdlen);
         EVP_MD_CTX_free(tmp_ctx);
     }
index 7e6388e8f55382f55d321426a280d82f16d5867c..76405154a95410576905a5c63d1cd0e30b1bec25 100644 (file)
@@ -367,6 +367,7 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
                       int cmd, int p1, void *p2)
 {
     int ret;
+
     if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
         EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
         return -2;
@@ -374,6 +375,10 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
     if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype))
         return -1;
 
+    /* Skip the operation checks since this is called in a very early stage */
+    if (ctx->pmeth->digest_custom != NULL)
+        goto doit;
+
     if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
         EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET);
         return -1;
@@ -384,13 +389,13 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
         return -1;
     }
 
+ doit:
     ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2);
 
     if (ret == -2)
         EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED);
 
     return ret;
-
 }
 
 int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype,
index 3264b3df71e8c6938fa77019fb96aad8b500da1c..d86aed36f075a61df3ef45dabcd12a57a8ca68fc 100644 (file)
 #include <openssl/evp.h>
 #include "internal/refcount.h"
 
+/*
+ * Don't free up md_ctx->pctx in EVP_MD_CTX_reset, use the reserved flag
+ * values in evp.h
+ */
+#define EVP_MD_CTX_FLAG_KEEP_PKEY_CTX   0x0400
+
 struct evp_pkey_ctx_st {
     /* Method associated with this operation */
     const EVP_PKEY_METHOD *pmeth;
index 26a90660ee5b31426ea9582b0ecf79094b158a3a..5c5cd4b4f5672578e3473257ba3b057dad2e0b55 100644 (file)
 /* The default user id as specified in GM/T 0009-2012 */
 #  define SM2_DEFAULT_USERID "1234567812345678"
 
-int sm2_compute_userid_digest(uint8_t *out,
-                              const EVP_MD *digest,
-                              const uint8_t *id,
-                              const size_t id_len,
-                              const EC_KEY *key);
+int sm2_compute_z_digest(uint8_t *out,
+                         const EVP_MD *digest,
+                         const uint8_t *id,
+                         const size_t id_len,
+                         const EC_KEY *key);
 
 /*
- * SM2 signature operation. Computes ZA (user id digest) and then signs
- * H(ZA || msg) using SM2
+ * SM2 signature operation. Computes Z and then signs H(Z || msg) using SM2
  */
 ECDSA_SIG *sm2_do_sign(const EC_KEY *key,
                        const EVP_MD *digest,
index 9a7e2b62758cddb5e7c5b1d4eda1997fe6c52994..4b8536db32d9819ac97a0b15557eb57c872a94f1 100644 (file)
@@ -28,7 +28,7 @@ int ERR_load_SM2_strings(void);
 #  define SM2_F_PKEY_SM2_INIT                              111
 #  define SM2_F_PKEY_SM2_SIGN                              112
 #  define SM2_F_SM2_COMPUTE_MSG_HASH                       100
-#  define SM2_F_SM2_COMPUTE_USERID_DIGEST                  101
+#  define SM2_F_SM2_COMPUTE_Z_DIGEST                       113
 #  define SM2_F_SM2_DECRYPT                                102
 #  define SM2_F_SM2_ENCRYPT                                103
 #  define SM2_F_SM2_PLAINTEXT_SIZE                         104
@@ -43,13 +43,13 @@ int ERR_load_SM2_strings(void);
 #  define SM2_R_ASN1_ERROR                                 100
 #  define SM2_R_BAD_SIGNATURE                              101
 #  define SM2_R_BUFFER_TOO_SMALL                           107
+#  define SM2_R_ID_TOO_LARGE                               111
 #  define SM2_R_INVALID_CURVE                              108
 #  define SM2_R_INVALID_DIGEST                             102
 #  define SM2_R_INVALID_DIGEST_TYPE                        103
 #  define SM2_R_INVALID_ENCODING                           104
 #  define SM2_R_INVALID_FIELD                              105
 #  define SM2_R_NO_PARAMETERS_SET                          109
-#  define SM2_R_USER_ID_TOO_LARGE                          106
 
 # endif
 #endif
index 035abdc49e0ec6b949e8370c52d97bc2866375cf..7bc812e42ef46e7a34be2f2683dbac00bb596b2b 100644 (file)
@@ -20,8 +20,8 @@ static const ERR_STRING_DATA SM2_str_functs[] = {
     {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_SIGN, 0), "pkey_sm2_sign"},
     {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_MSG_HASH, 0),
      "sm2_compute_msg_hash"},
-    {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_USERID_DIGEST, 0),
-     "sm2_compute_userid_digest"},
+    {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_COMPUTE_Z_DIGEST, 0),
+     "sm2_compute_z_digest"},
     {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_DECRYPT, 0), "sm2_decrypt"},
     {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_ENCRYPT, 0), "sm2_encrypt"},
     {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_PLAINTEXT_SIZE, 0), "sm2_plaintext_size"},
@@ -36,6 +36,7 @@ static const ERR_STRING_DATA SM2_str_reasons[] = {
     {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ASN1_ERROR), "asn1 error"},
     {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_BAD_SIGNATURE), "bad signature"},
     {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_BUFFER_TOO_SMALL), "buffer too small"},
+    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ID_TOO_LARGE), "id too large"},
     {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_CURVE), "invalid curve"},
     {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_DIGEST), "invalid digest"},
     {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_DIGEST_TYPE),
@@ -43,7 +44,6 @@ static const ERR_STRING_DATA SM2_str_reasons[] = {
     {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_NO_PARAMETERS_SET), "no parameters set"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_USER_ID_TOO_LARGE), "user id too large"},
     {0, NULL}
 };
 
index 63c93891e25a85bd202bd6f56d6ab07ac74034b0..aed7f33044575bbdca9444daae815c1f3723d4ec 100644 (file)
@@ -22,30 +22,34 @@ typedef struct {
     EC_GROUP *gen_group;
     /* message digest */
     const EVP_MD *md;
+    /* Distinguishing Identifier, ISO/IEC 15946-3 */
     uint8_t *id;
     size_t id_len;
+    /* id_set indicates if the 'id' field is set (1) or not (0) */
+    int id_set;
 } SM2_PKEY_CTX;
 
 static int pkey_sm2_init(EVP_PKEY_CTX *ctx)
 {
-    SM2_PKEY_CTX *dctx;
+    SM2_PKEY_CTX *smctx;
 
-    if ((dctx = OPENSSL_zalloc(sizeof(*dctx))) == NULL) {
+    if ((smctx = OPENSSL_zalloc(sizeof(*smctx))) == NULL) {
         SM2err(SM2_F_PKEY_SM2_INIT, ERR_R_MALLOC_FAILURE);
         return 0;
     }
 
-    ctx->data = dctx;
+    ctx->data = smctx;
     return 1;
 }
 
 static void pkey_sm2_cleanup(EVP_PKEY_CTX *ctx)
 {
-    SM2_PKEY_CTX *dctx = ctx->data;
+    SM2_PKEY_CTX *smctx = ctx->data;
 
-    if (dctx != NULL) {
-        EC_GROUP_free(dctx->gen_group);
-        OPENSSL_free(dctx);
+    if (smctx != NULL) {
+        EC_GROUP_free(smctx->gen_group);
+        OPENSSL_free(smctx->id);
+        OPENSSL_free(smctx);
         ctx->data = NULL;
     }
 }
@@ -65,6 +69,16 @@ static int pkey_sm2_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
             return 0;
         }
     }
+    if (sctx->id != NULL) {
+        dctx->id = OPENSSL_malloc(sctx->id_len);
+        if (dctx->id == NULL) {
+            pkey_sm2_cleanup(dst);
+            return 0;
+        }
+        memcpy(dctx->id, sctx->id, sctx->id_len);
+    }
+    dctx->id_len = sctx->id_len;
+    dctx->id_set = sctx->id_set;
     dctx->md = sctx->md;
 
     return 1;
@@ -147,7 +161,7 @@ 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 *dctx = ctx->data;
+    SM2_PKEY_CTX *smctx = ctx->data;
     EC_GROUP *group;
 
     switch (type) {
@@ -157,29 +171,51 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
             SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_INVALID_CURVE);
             return 0;
         }
-        EC_GROUP_free(dctx->gen_group);
-        dctx->gen_group = group;
+        EC_GROUP_free(smctx->gen_group);
+        smctx->gen_group = group;
         return 1;
 
     case EVP_PKEY_CTRL_EC_PARAM_ENC:
-        if (dctx->gen_group == NULL) {
+        if (smctx->gen_group == NULL) {
             SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_NO_PARAMETERS_SET);
             return 0;
         }
-        EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
+        EC_GROUP_set_asn1_flag(smctx->gen_group, p1);
         return 1;
 
     case EVP_PKEY_CTRL_MD:
-        dctx->md = p2;
+        smctx->md = p2;
         return 1;
 
     case EVP_PKEY_CTRL_GET_MD:
-        *(const EVP_MD **)p2 = dctx->md;
+        *(const EVP_MD **)p2 = smctx->md;
+        return 1;
+
+    case EVP_PKEY_CTRL_SET1_ID:
+        OPENSSL_free(smctx->id);
+        if (p1 > 0) {
+            smctx->id = OPENSSL_malloc(p1);
+            if (smctx->id == NULL)
+                return 0;
+            memcpy(smctx->id, p2, p1);
+        } else {
+            /* set null-ID */
+            smctx->id = NULL;
+        }
+        smctx->id_len = (size_t)p1;
+        smctx->id_set = 1;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET1_ID:
+        memcpy(p2, smctx->id, smctx->id_len);
+        return 1;
+
+    case EVP_PKEY_CTRL_GET1_ID_LEN:
+        *(size_t *)p2 = smctx->id_len;
         return 1;
 
     default:
         return -2;
-
     }
 }
 
@@ -214,21 +250,21 @@ static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx,
 static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
 {
     uint8_t z[EVP_MAX_MD_SIZE];
-    SM2_PKEY_CTX *sctx = ctx->data;
+    SM2_PKEY_CTX *smctx = ctx->data;
     EC_KEY *ec = ctx->pkey->pkey.ec;
     const EVP_MD *md = EVP_MD_CTX_md(mctx);
 
-    if (sctx->id == NULL) {
-        /* XXX:
-         * currently we reject all null-ID for SM2, but this needs
-         * more considerations and discussion since the specifications
-         * on SM2 are not clear on null-ID
+    if (!smctx->id_set) {
+        /*
+         * An ID value must be set. The specifications are not clear whether a
+         * NULL is allowed. We only allow it if set explicitly for maximum
+         * flexibility.
          */
         return 0;
     }
 
-    /* get hashed prefix of tbs message */
-    if (!sm2_compute_userid_digest(z, md, sctx->id, sctx->id_len, ec))
+    /* get hashed prefix 'z' of tbs message */
+    if (!sm2_compute_z_digest(z, md, smctx->id, smctx->id_len, ec))
         return 0;
 
     return EVP_DigestUpdate(mctx, z, EVP_MD_size(md));
index bf68dde7b68e853dbab715f6f1e42839aadafc21..e594ffd10a0bb29976bd42e1e492591e27d2b43e 100644 (file)
 #include <openssl/bn.h>
 #include <string.h>
 
-int sm2_compute_userid_digest(uint8_t *out,
-                              const EVP_MD *digest,
-                              const uint8_t *id,
-                              const size_t id_len,
-                              const EC_KEY *key)
+int sm2_compute_z_digest(uint8_t *out,
+                         const EVP_MD *digest,
+                         const uint8_t *id,
+                         const size_t id_len,
+                         const EC_KEY *key)
 {
     int rc = 0;
     const EC_GROUP *group = EC_KEY_get0_group(key);
@@ -37,13 +37,13 @@ int sm2_compute_userid_digest(uint8_t *out,
     BIGNUM *yA = NULL;
     int p_bytes = 0;
     uint8_t *buf = NULL;
-    uint16_t entla = 0;
+    uint16_t entl = 0;
     uint8_t e_byte = 0;
 
     hash = EVP_MD_CTX_new();
     ctx = BN_CTX_new();
     if (hash == NULL || ctx == NULL) {
-        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE);
+        SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE);
         goto done;
     }
 
@@ -56,46 +56,50 @@ int sm2_compute_userid_digest(uint8_t *out,
     yA = BN_CTX_get(ctx);
 
     if (yA == NULL) {
-        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE);
+        SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE);
         goto done;
     }
 
     if (!EVP_DigestInit(hash, digest)) {
-        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
+        SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
         goto done;
     }
 
-    /* Z = SM3(ENTLA || IDA || a || b || xG || yG || xA || yA) */
+    /* Z = h(ENTL || ID || a || b || xG || yG || xA || yA) */
 
     if (id_len >= (UINT16_MAX / 8)) {
         /* too large */
-        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, SM2_R_USER_ID_TOO_LARGE);
+        SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, SM2_R_ID_TOO_LARGE);
         goto done;
     }
 
-    entla = (uint16_t)(8 * id_len);
+    entl = (uint16_t)(8 * id_len);
 
-    e_byte = entla >> 8;
+    e_byte = entl >> 8;
     if (!EVP_DigestUpdate(hash, &e_byte, 1)) {
-        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
+        SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
         goto done;
     }
-    e_byte = entla & 0xFF;
-    if (!EVP_DigestUpdate(hash, &e_byte, 1)
-            || !EVP_DigestUpdate(hash, id, id_len)) {
-        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
+    e_byte = entl & 0xFF;
+    if (!EVP_DigestUpdate(hash, &e_byte, 1)) {
+        SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
+        goto done;
+    }
+
+    if (id_len > 0 && !EVP_DigestUpdate(hash, id, id_len)) {
+        SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
         goto done;
     }
 
     if (!EC_GROUP_get_curve(group, p, a, b, ctx)) {
-        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EC_LIB);
+        SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EC_LIB);
         goto done;
     }
 
     p_bytes = BN_num_bytes(p);
     buf = OPENSSL_zalloc(p_bytes);
     if (buf == NULL) {
-        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE);
+        SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE);
         goto done;
     }
 
@@ -118,7 +122,7 @@ int sm2_compute_userid_digest(uint8_t *out,
             || BN_bn2binpad(yA, buf, p_bytes) < 0
             || !EVP_DigestUpdate(hash, buf, p_bytes)
             || !EVP_DigestFinal(hash, out, NULL)) {
-        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_INTERNAL_ERROR);
+        SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_INTERNAL_ERROR);
         goto done;
     }
 
@@ -139,7 +143,7 @@ static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,
 {
     EVP_MD_CTX *hash = EVP_MD_CTX_new();
     const int md_size = EVP_MD_size(digest);
-    uint8_t *za = NULL;
+    uint8_t *z = NULL;
     BIGNUM *e = NULL;
 
     if (md_size < 0) {
@@ -147,32 +151,32 @@ static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,
         goto done;
     }
 
-    za = OPENSSL_zalloc(md_size);
-    if (hash == NULL || za == NULL) {
+    z = OPENSSL_zalloc(md_size);
+    if (hash == NULL || z == NULL) {
         SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_MALLOC_FAILURE);
         goto done;
     }
 
-    if (!sm2_compute_userid_digest(za, digest, id, id_len, key)) {
+    if (!sm2_compute_z_digest(z, digest, id, id_len, key)) {
         /* SM2err already called */
         goto done;
     }
 
     if (!EVP_DigestInit(hash, digest)
-            || !EVP_DigestUpdate(hash, za, md_size)
+            || !EVP_DigestUpdate(hash, z, md_size)
             || !EVP_DigestUpdate(hash, msg, msg_len)
-               /* reuse za buffer to hold H(ZA || M) */
-            || !EVP_DigestFinal(hash, za, NULL)) {
+               /* reuse z buffer to hold H(Z || M) */
+            || !EVP_DigestFinal(hash, z, NULL)) {
         SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_EVP_LIB);
         goto done;
     }
 
-    e = BN_bin2bn(za, md_size, NULL);
+    e = BN_bin2bn(z, md_size, NULL);
     if (e == NULL)
         SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_INTERNAL_ERROR);
 
  done:
-    OPENSSL_free(za);
+    OPENSSL_free(z);
     EVP_MD_CTX_free(hash);
     return e;
 }
index 9cbb8b8e9d711f00811d017b711e3b7e5d453c2a..4d70da70a614efd95cdefa069999cf9d2cbb25e4 100644 (file)
@@ -1429,6 +1429,19 @@ void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth,
                                 EVP_PKEY_OP_DERIVE, \
                                 EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)(p))
 
+/* SM2 will skip the operation check so no need to pass operation here */
+# define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \
+        EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
+                                EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id))
+
+# define EVP_PKEY_CTX_get1_id(ctx, id) \
+        EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
+                                EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id))
+
+# define EVP_PKEY_CTX_get1_id_len(ctx, id_len) \
+        EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
+                                EVP_PKEY_CTRL_GET1_ID_LEN, 0, (void*)(id_len))
+
 # define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID             (EVP_PKEY_ALG_CTRL + 1)
 # define EVP_PKEY_CTRL_EC_PARAM_ENC                      (EVP_PKEY_ALG_CTRL + 2)
 # define EVP_PKEY_CTRL_EC_ECDH_COFACTOR                  (EVP_PKEY_ALG_CTRL + 3)
@@ -1439,6 +1452,9 @@ void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth,
 # define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN                 (EVP_PKEY_ALG_CTRL + 8)
 # define EVP_PKEY_CTRL_EC_KDF_UKM                        (EVP_PKEY_ALG_CTRL + 9)
 # define EVP_PKEY_CTRL_GET_EC_KDF_UKM                    (EVP_PKEY_ALG_CTRL + 10)
+# define EVP_PKEY_CTRL_SET1_ID                           (EVP_PKEY_ALG_CTRL + 11)
+# define EVP_PKEY_CTRL_GET1_ID                           (EVP_PKEY_ALG_CTRL + 12)
+# define EVP_PKEY_CTRL_GET1_ID_LEN                       (EVP_PKEY_ALG_CTRL + 13)
 /* KDF types */
 # define EVP_PKEY_ECDH_KDF_NONE                          1
 # define EVP_PKEY_ECDH_KDF_X9_62                         2
index b7c02438573c783b9fae25855879fad4fb67cd21..8c8051993ffe1f59f889e90ae2686ea1684a94f6 100644 (file)
@@ -180,9 +180,7 @@ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
  * if the following flag is set.
  */
 # define EVP_MD_CTX_FLAG_FINALISE        0x0200
-
-/* Don't free up ctx->pctx in EVP_MD_CTX_reset */
-# define EVP_MD_CTX_FLAG_NEGLECT_PCTX    0x0400
+/* NOTE: 0x0400 is reserved for internal usage in evp_int.h */
 
 EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len);
 EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher);
@@ -1325,8 +1323,6 @@ void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
  * Method handles all operations: don't assume any digest related defaults.
  */
 # define EVP_PKEY_FLAG_SIGCTX_CUSTOM     4
-/* Do a customized hashing process */
-# define EVP_PKEY_FLAG_DIGEST_CUSTOM     8
 
 const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type);
 EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags);
index 33a957f791d78c11de0ff1545bcd892b11c7a602..2fb3914ee8371d2f8653b2b22495c05b747eddfa 100644 (file)
@@ -16,6 +16,7 @@
 #include <openssl/evp.h>
 #include <openssl/rsa.h>
 #include <openssl/x509.h>
+#include <openssl/pem.h>
 #include "testutil.h"
 #include "internal/nelem.h"
 #include "internal/evp_int.h"
@@ -530,6 +531,7 @@ static int test_EVP_SM2(void)
     EVP_PKEY *params = NULL;
     EVP_PKEY_CTX *pctx = NULL;
     EVP_PKEY_CTX *kctx = NULL;
+    EVP_PKEY_CTX *sctx = NULL;
     size_t sig_len = 0;
     unsigned char *sig = NULL;
     EVP_MD_CTX *md_ctx = NULL;
@@ -542,6 +544,8 @@ static int test_EVP_SM2(void)
     uint8_t plaintext[8];
     size_t ptext_len = sizeof(plaintext);
 
+    uint8_t sm2_id[] = {1, 2, 3, 4, 'l', 'e', 't', 't', 'e', 'r'};
+
     pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
     if (!TEST_ptr(pctx))
         goto done;
@@ -574,6 +578,15 @@ static int test_EVP_SM2(void)
     if (!TEST_ptr(md_ctx_verify = EVP_MD_CTX_new()))
         goto done;
 
+    if (!TEST_ptr(sctx = EVP_PKEY_CTX_new(pkey, NULL)))
+        goto done;
+
+    EVP_MD_CTX_set_pkey_ctx(md_ctx, sctx);
+    EVP_MD_CTX_set_pkey_ctx(md_ctx_verify, sctx);
+
+    if (!TEST_int_gt(EVP_PKEY_CTX_set1_id(sctx, sm2_id, sizeof(sm2_id)), 0))
+        goto done;
+
     if (!TEST_true(EVP_DigestSignInit(md_ctx, NULL, EVP_sm3(), NULL, pkey)))
         goto done;
 
@@ -631,6 +644,7 @@ static int test_EVP_SM2(void)
 done:
     EVP_PKEY_CTX_free(pctx);
     EVP_PKEY_CTX_free(kctx);
+    EVP_PKEY_CTX_free(sctx);
     EVP_PKEY_CTX_free(cctx);
     EVP_PKEY_free(pkey);
     EVP_PKEY_free(params);
index b90e33db800e0525b222f7a392dbaa7d5d1ddb3d..0391091a2ffd9694883a95a4f740bccdb0979eee 100644 (file)
@@ -413,3 +413,6 @@ SSLv23_method                           define
 SSLv23_server_method                    define
 X509_STORE_set_lookup_crls_cb           define
 X509_STORE_set_verify_func              define
+EVP_PKEY_CTX_set1_id                    define
+EVP_PKEY_CTX_get1_id                    define
+EVP_PKEY_CTX_get1_id_len                define