Update document for SM2 stuffs
authorPaul Yang <yang.yang@baishancloud.com>
Wed, 5 Sep 2018 07:19:17 +0000 (15:19 +0800)
committerPaul Yang <yang.yang@baishancloud.com>
Fri, 7 Sep 2018 10:12:26 +0000 (18:12 +0800)
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7113)

crypto/err/openssl.txt
crypto/evp/m_sigver.c
crypto/evp/pmeth_lib.c
crypto/include/internal/sm2err.h
crypto/sm2/sm2_err.c
crypto/sm2/sm2_pmeth.c
doc/man3/EVP_DigestInit.pod
doc/man3/EVP_DigestSignInit.pod
doc/man3/EVP_DigestVerifyInit.pod
doc/man3/EVP_PKEY_CTX_ctrl.pod
doc/man3/EVP_PKEY_meth_new.pod

index 2f86786d583f96d4b353d24cc8cbe737a039eb8a..c998e61616053a45f3ddbf6026567f769424f438 100644 (file)
@@ -1082,6 +1082,7 @@ RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1:126:RSA_verify_PKCS1_PSS_mgf1
 RSA_F_SETUP_TBUF:167:setup_tbuf
 SM2_F_PKEY_SM2_CTRL:109:pkey_sm2_ctrl
 SM2_F_PKEY_SM2_CTRL_STR:110:pkey_sm2_ctrl_str
+SM2_F_PKEY_SM2_DIGEST_CUSTOM:114:pkey_sm2_digest_custom
 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
@@ -2556,6 +2557,7 @@ 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_NOT_SET:112:id not set
 SM2_R_ID_TOO_LARGE:111:id too large
 SM2_R_INVALID_CURVE:108:invalid curve
 SM2_R_INVALID_DIGEST:102:invalid digest
index 2eceede28c1488a2cad8762d8edda97096fe1d59..94e37f02b22eb4f3bd9e40b8499ec3e8834a360d 100644 (file)
@@ -79,7 +79,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
      * This indicates the current algorithm requires
      * special treatment before hashing the tbs-message.
      */
-    if (ctx->pctx->pmeth->digest_custom)
+    if (ctx->pctx->pmeth->digest_custom != NULL)
         return ctx->pctx->pmeth->digest_custom(ctx->pctx, ctx);
 
     return 1;
index 76405154a95410576905a5c63d1cd0e30b1bec25..633cb8863d6d46126d7909bfc09d87809c193795 100644 (file)
@@ -859,6 +859,6 @@ void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth,
                                      int (**pdigest_custom) (EVP_PKEY_CTX *ctx,
                                                              EVP_MD_CTX *mctx))
 {
-    if (*pdigest_custom)
+    if (pdigest_custom != NULL)
         *pdigest_custom = pmeth->digest_custom;
 }
index 4b8536db32d9819ac97a0b15557eb57c872a94f1..62f2aa2a10fc1c11da4997833a7b63ae88a01ffc 100644 (file)
@@ -25,9 +25,11 @@ int ERR_load_SM2_strings(void);
  */
 #  define SM2_F_PKEY_SM2_CTRL                              109
 #  define SM2_F_PKEY_SM2_CTRL_STR                          110
+#  define SM2_F_PKEY_SM2_DIGEST_CUSTOM                     114
 #  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
@@ -43,6 +45,8 @@ 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_DIST_ID_TOO_LARGE                          110
+#  define SM2_R_ID_NOT_SET                                 112
 #  define SM2_R_ID_TOO_LARGE                               111
 #  define SM2_R_INVALID_CURVE                              108
 #  define SM2_R_INVALID_DIGEST                             102
@@ -50,6 +54,7 @@ int ERR_load_SM2_strings(void);
 #  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 7bc812e42ef46e7a34be2f2683dbac00bb596b2b..c2a96c15d92ceaa33b2263fa59cd9f26149bc3f9 100644 (file)
 static const ERR_STRING_DATA SM2_str_functs[] = {
     {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_CTRL, 0), "pkey_sm2_ctrl"},
     {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_CTRL_STR, 0), "pkey_sm2_ctrl_str"},
+    {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_DIGEST_CUSTOM, 0),
+     "pkey_sm2_digest_custom"},
     {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_INIT, 0), "pkey_sm2_init"},
     {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"},
@@ -36,6 +40,8 @@ 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_DIST_ID_TOO_LARGE), "dist id too large"},
+    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ID_NOT_SET), "id not set"},
     {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"},
@@ -44,6 +50,7 @@ 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 aed7f33044575bbdca9444daae815c1f3723d4ec..4b61e243aa463fae98eaf44d7cd65c315f8d4d77 100644 (file)
@@ -163,6 +163,7 @@ 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:
@@ -192,14 +193,16 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
         return 1;
 
     case EVP_PKEY_CTRL_SET1_ID:
-        OPENSSL_free(smctx->id);
         if (p1 > 0) {
-            smctx->id = OPENSSL_malloc(p1);
-            if (smctx->id == NULL)
+            tmp_id = OPENSSL_malloc(p1);
+            if (tmp_id == NULL)
                 return 0;
-            memcpy(smctx->id, p2, p1);
+            memcpy(tmp_id, p2, p1);
+            OPENSSL_free(smctx->id);
+            smctx->id = tmp_id;
         } else {
             /* set null-ID */
+            OPENSSL_free(smctx->id);
             smctx->id = NULL;
         }
         smctx->id_len = (size_t)p1;
@@ -260,6 +263,7 @@ static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
          * NULL is allowed. We only allow it if set explicitly for maximum
          * flexibility.
          */
+        SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_ID_NOT_SET);
         return 0;
     }
 
index 67f4f021966cac9fee5c320136b11dcfa7cfa396..02e7719274c0c3d3f5611addbce8de24e11f9c0f 100644 (file)
@@ -11,7 +11,8 @@ EVP_MD_block_size, EVP_MD_CTX_md, EVP_MD_CTX_size,
 EVP_MD_CTX_block_size, EVP_MD_CTX_type, EVP_MD_CTX_md_data,
 EVP_md_null,
 EVP_get_digestbyname, EVP_get_digestbynid,
-EVP_get_digestbyobj - EVP digest routines
+EVP_get_digestbyobj,
+EVP_MD_CTX_set_pkey_ctx - EVP digest routines
 
 =head1 SYNOPSIS
 
@@ -54,6 +55,8 @@ EVP_get_digestbyobj - EVP digest routines
  const EVP_MD *EVP_get_digestbynid(int type);
  const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *o);
 
+ void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx);
+
 =head1 DESCRIPTION
 
 The EVP digest routines are a high level interface to message digests,
@@ -179,6 +182,13 @@ EVP_get_digestbyobj()
 Returns an B<EVP_MD> structure when passed a digest name, a digest B<NID> or an
 B<ASN1_OBJECT> structure respectively.
 
+=item EVP_MD_CTX_set_pkey_ctx()
+
+Assigns an B<EVP_PKEY_CTX> to B<EVP_MD_CTX>. This is usually used to provide
+a customzied B<EVP_PKEY_CTX> to L<EVP_DigestSignInit(3)> or
+L<EVP_DigestVerifyInit(3)>. The B<EVP_PKEY_CTX> passed to this function should
+be freed by the caller.
+
 =back
 
 =head1 FLAGS
@@ -256,6 +266,10 @@ EVP_get_digestbyobj()
 
 Returns either an B<EVP_MD> structure or NULL if an error occurs.
 
+=item EVP_MD_CTX_set_pkey_ctx()
+
+This function has no return value.
+
 =back
 
 =head1 NOTES
@@ -360,6 +374,8 @@ later, so now EVP_sha1() can be used with RSA and DSA.
 
 EVP_dss1() was removed in OpenSSL 1.1.0.
 
+EVP_MD_CTX_set_pkey_ctx() is added in 1.1.1.
+
 =head1 COPYRIGHT
 
 Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
index fe2be7bbf58dcb4a23a6785249f33cec31bfa5c8..773de87efac4dd48214b80201d35771dce19567b 100644 (file)
@@ -28,8 +28,15 @@ EVP_MD_CTX_new() before calling this function. If B<pctx> is not NULL, the
 EVP_PKEY_CTX of the signing operation will be written to B<*pctx>: this can
 be used to set alternative signing options. Note that any existing value in
 B<*pctx> is overwritten. The EVP_PKEY_CTX value returned must not be freed
-directly by the application (it will be freed automatically when the EVP_MD_CTX
-is freed). The digest B<type> may be NULL if the signing algorithm supports it.
+directly by the application if B<ctx> is not assigned an EVP_PKEY_CTX value before
+being passed to EVP_DigestSignInit() (which means the EVP_PKEY_CTX is created
+inside EVP_DigestSignInit() and it will be freed automatically when the
+EVP_MD_CTX is freed).
+
+The digest B<type> may be NULL if the signing algorithm supports it.
+
+No B<EVP_PKEY_CTX> will be created by EVP_DigsetSignInit() if the passed B<ctx>
+has already been assigned one via L<EVP_MD_CTX_set_ctx(3)>. See also L<SM2(7)>.
 
 Only EVP_PKEY types that support signing can be used with these functions. This
 includes MAC algorithms where the MAC generation is considered as a form of
index 0d25debcb1c8fcbac7e975b4dbfc3456b0ef0f42..e93ac2ef08107c02a48c53ef68538283762e74e9 100644 (file)
@@ -26,10 +26,15 @@ B<type> from ENGINE B<e> and public key B<pkey>. B<ctx> must be created
 with EVP_MD_CTX_new() before calling this function. If B<pctx> is not NULL, the
 EVP_PKEY_CTX of the verification operation will be written to B<*pctx>: this
 can be used to set alternative verification options. Note that any existing
-value in B<*pctx> is overwritten. The EVP_PKEY_CTX value returned must not be
-freed directly by the application (it will be freed automatically when the
+value in B<*pctx> is overwritten. The EVP_PKEY_CTX value returned must not be freed
+directly by the application if B<ctx> is not assigned an EVP_PKEY_CTX value before
+being passed to EVP_DigestSignInit() (which means the EVP_PKEY_CTX is created
+inside EVP_DigestSignInit() and it will be freed automatically when the
 EVP_MD_CTX is freed).
 
+No B<EVP_PKEY_CTX> will be created by EVP_DigsetSignInit() if the passed B<ctx>
+has already been assigned one via L<EVP_MD_CTX_set_ctx(3)>. See also L<SM2(7)>.
+
 EVP_DigestVerifyUpdate() hashes B<cnt> bytes of data at B<d> into the
 verification context B<ctx>. This function can be called several times on the
 same B<ctx> to include additional data. This function is currently implemented
index 7eb9796bdda6067708e821083f74467e71ee14fb..d70dbb9cf2cec457367c14f28faa247324e369f5 100644 (file)
@@ -17,7 +17,9 @@ EVP_PKEY_CTX_set_dh_paramgen_generator,
 EVP_PKEY_CTX_set_dh_pad,
 EVP_PKEY_CTX_set_dh_nid,
 EVP_PKEY_CTX_set_ec_paramgen_curve_nid,
-EVP_PKEY_CTX_set_ec_param_enc - algorithm specific control operations
+EVP_PKEY_CTX_set_ec_param_enc,
+EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len
+- algorithm specific control operations
 
 =head1 SYNOPSIS
 
@@ -53,6 +55,10 @@ EVP_PKEY_CTX_set_ec_param_enc - algorithm specific control operations
  int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid);
  int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int param_enc);
 
+ int EVP_PKEY_CTX_set1_id(EVP_PKEY_CTX *ctx, void *id, size_t id_len);
+ int EVP_PKEY_CTX_get1_id(EVP_PKEY_CTX *ctx, void *id);
+ int EVP_PKEY_CTX_get1_id_len(EVP_PKEY_CTX *ctx, size_t *id_len);
+
 =head1 DESCRIPTION
 
 The function EVP_PKEY_CTX_ctrl() sends a control operation to the context
@@ -160,6 +166,17 @@ For maximum compatibility the named curve form should be used. Note: the
 B<OPENSSL_EC_NAMED_CURVE> value was only added to OpenSSL 1.1.0; previous
 versions should use 0 instead.
 
+The EVP_PKEY_CTX_set1_id(), EVP_PKEY_CTX_get1_id() and EVP_PKEY_CTX_get1_id_len()
+are used to manipulate special identifier field for specific signature algorithm
+such as SM2. The EVP_PKEY_set1_id() sets an ID pointed by B<id> with the length
+B<id_len> to the library. The library maintains the memory management stuffs so
+the caller can safely free the original memory pointed by B<id>. The
+EVP_PKEY_CTX_get1_id_len() returns the length of the ID set via a previous call
+to EVP_PKEY_set1_id(). The length is usually used to allocate adequate memory for
+further calls to EVP_PKEY_CTX_get1_id(). The EVP_PKEY_CTX_get1_id() returns the
+previously set ID value to caller into B<id>, caller should allocate adequate
+memory space to B<id> before calling EVP_PKEY_CTX_get1_id().
+
 =head1 RETURN VALUES
 
 EVP_PKEY_CTX_ctrl() and its macros return a positive value for success and 0
@@ -179,7 +196,8 @@ L<EVP_PKEY_keygen(3)>
 
 =head1 HISTORY
 
-These functions were first added to OpenSSL 1.0.0.
+EVP_PKEY_CTX_set1_id(), EVP_PKEY_CTX_get1_id() and EVP_PKEY_CTX_get1_id_len()
+were added in 1.1.1, other functions were first added to OpenSSL 1.0.0.
 
 =head1 COPYRIGHT
 
index ddc99d2800eda7babd41a840004bb51e66ca49db..171d4da744447281f01bd41bf80fd5f7187bf8a4 100644 (file)
@@ -10,12 +10,14 @@ EVP_PKEY_meth_set_verify, EVP_PKEY_meth_set_verify_recover, EVP_PKEY_meth_set_si
 EVP_PKEY_meth_set_verifyctx, EVP_PKEY_meth_set_encrypt, EVP_PKEY_meth_set_decrypt,
 EVP_PKEY_meth_set_derive, EVP_PKEY_meth_set_ctrl, EVP_PKEY_meth_set_check,
 EVP_PKEY_meth_set_public_check, EVP_PKEY_meth_set_param_check,
+EVP_PKEY_meth_set_digest_custom,
 EVP_PKEY_meth_get_init, EVP_PKEY_meth_get_copy, EVP_PKEY_meth_get_cleanup,
 EVP_PKEY_meth_get_paramgen, EVP_PKEY_meth_get_keygen, EVP_PKEY_meth_get_sign,
 EVP_PKEY_meth_get_verify, EVP_PKEY_meth_get_verify_recover, EVP_PKEY_meth_get_signctx,
 EVP_PKEY_meth_get_verifyctx, EVP_PKEY_meth_get_encrypt, EVP_PKEY_meth_get_decrypt,
 EVP_PKEY_meth_get_derive, EVP_PKEY_meth_get_ctrl, EVP_PKEY_meth_get_check,
 EVP_PKEY_meth_get_public_check, EVP_PKEY_meth_get_param_check,
+EVP_PKEY_meth_get_digest_custom,
 EVP_PKEY_meth_remove
 - manipulating EVP_PKEY_METHOD structure
 
@@ -116,6 +118,9 @@ EVP_PKEY_meth_remove
                                      int (*check) (EVP_PKEY *pkey));
  void EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth,
                                     int (*check) (EVP_PKEY *pkey));
+ void EVP_PKEY_meth_set_digest_custom(EVP_PKEY_METHOD *pmeth,
+                                     int (*digest_custom) (EVP_PKEY_CTX *ctx,
+                                                           EVP_MD_CTX *mctx));
 
  void EVP_PKEY_meth_get_init(const EVP_PKEY_METHOD *pmeth,
                              int (**pinit) (EVP_PKEY_CTX *ctx));
@@ -201,6 +206,9 @@ EVP_PKEY_meth_remove
                                      int (**pcheck) (EVP_PKEY *pkey));
  void EVP_PKEY_meth_get_param_check(const EVP_PKEY_METHOD *pmeth,
                                     int (**pcheck) (EVP_PKEY *pkey));
+ void EVP_PKEY_meth_get_digest_custom(EVP_PKEY_METHOD *pmeth,
+                                     int (**pdigest_custom) (EVP_PKEY_CTX *ctx,
+                                                             EVP_MD_CTX *mctx));
 
 =head1 DESCRIPTION
 
@@ -334,6 +342,15 @@ key-pair, the public component and parameters respectively for a given B<pkey>.
 They could be called by L<EVP_PKEY_check(3)>, L<EVP_PKEY_public_check(3)> and
 L<EVP_PKEY_param_check(3)> respectively.
 
+ int (*digest_custom) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
+
+The digest_custom() method is used to generate customized digest content before
+the real message is passed to functions like L<EVP_DigestSignUpdate(3)> or
+L<EVP_DigestVerifyInit(3)>. This is usually required by some public key
+signature algorithms like SM2 which requires a hashed prefix to the message to
+be signed. The digest_custom() will be called by L<EVP_DigestSignInit(3)> and
+L<EVP_DigestVerifyInit(3)>.
+
 =head2 Functions
 
 EVP_PKEY_meth_new() creates and returns a new B<EVP_PKEY_METHOD> object,