[openssl-commits] [openssl] master update

Matt Caswell matt at openssl.org
Mon Jun 4 11:04:13 UTC 2018


The branch master has been updated
       via  722add716bce487f5818cc57cb594fd526454b70 (commit)
       via  2167239abaec5fa44072fa1194505af0b3fced89 (commit)
       via  206521a06efe10d1eafac5b313ce42850fd75136 (commit)
       via  245be5304d7c8e4a4345c971791cbf03cb5ca603 (commit)
       via  e14d6cf691c9d8ad49df280b580b6836a67c6a19 (commit)
       via  44d3845d8967c66a87e4d7628552e2bfd45ac344 (commit)
       via  266291aa8dc203c6791cc94b617323d4b04d7094 (commit)
       via  2398404e007a3d94a1be9db1574007b4242f4f9a (commit)
       via  e425f90fffd33786b6d45b46b67dc8bb61baecc7 (commit)
      from  c4d9ef4cc5bf1c48a74b64879622ae9fd6f26b03 (commit)


- Log -----------------------------------------------------------------
commit 722add716bce487f5818cc57cb594fd526454b70
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 31 16:30:33 2018 +0100

    Rebuild error codes
    
    There were a large number of error codes that were unused (probably a
    copy&paste from somewhere else). Since these have never been made public
    we should remove then and rebuild the error codes.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6386)

commit 2167239abaec5fa44072fa1194505af0b3fced89
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 31 15:53:30 2018 +0100

    Use lowercase for internal SM2 symbols
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6386)

commit 206521a06efe10d1eafac5b313ce42850fd75136
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 31 15:38:36 2018 +0100

    Remove non-existant functions from libcrypto.num
    
    These were never made public so can just be deleted.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6386)

commit 245be5304d7c8e4a4345c971791cbf03cb5ca603
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 31 14:43:14 2018 +0100

    More more on SM2 error codes and tidy up
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6386)

commit e14d6cf691c9d8ad49df280b580b6836a67c6a19
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 31 13:49:47 2018 +0100

    Improve use of the test framework in the SM2 internal tests
    
    Also general clean up of those tests
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6386)

commit 44d3845d8967c66a87e4d7628552e2bfd45ac344
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 31 13:10:12 2018 +0100

    Further work on SM2 error codes
    
    Also does some reformatting to tidy things up
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6386)

commit 266291aa8dc203c6791cc94b617323d4b04d7094
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 31 13:09:39 2018 +0100

    Add test recipes for internal SM2 tests
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6386)

commit 2398404e007a3d94a1be9db1574007b4242f4f9a
Author: Jack Lloyd <jack.lloyd at ribose.com>
Date:   Thu May 17 16:08:33 2018 -0400

    Set SM2 error codes
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6386)

commit e425f90fffd33786b6d45b46b67dc8bb61baecc7
Author: Jack Lloyd <jack.lloyd at ribose.com>
Date:   Fri Apr 6 09:45:41 2018 -0400

    Make SM2 functions private
    
    Address issue #5670
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/6386)

-----------------------------------------------------------------------

Summary of changes:
 crypto/ec/ec_pmeth.c                               |  26 +-
 crypto/err/openssl.ec                              |   2 +-
 crypto/err/openssl.txt                             |  81 +----
 {include/openssl => crypto/include/internal}/sm2.h |  26 +-
 crypto/include/internal/sm2err.h                   |  48 +++
 crypto/sm2/sm2_crypt.c                             | 274 +++++++++-------
 crypto/sm2/sm2_err.c                               | 101 +-----
 crypto/sm2/sm2_sign.c                              | 257 +++++++++------
 crypto/sm2/sm2_za.c                                | 111 +++----
 include/openssl/sm2err.h                           |  95 ------
 test/build.info                                    |  16 +-
 ...-test_internal_sm4.t => 03-test_internal_sm2.t} |   5 +-
 test/sm2_internal_test.c                           | 364 +++++++++++++++++++++
 test/sm2crypttest.c                                | 254 --------------
 test/sm2sigtest.c                                  | 238 --------------
 util/libcrypto.num                                 |  10 -
 16 files changed, 844 insertions(+), 1064 deletions(-)
 rename {include/openssl => crypto/include/internal}/sm2.h (75%)
 create mode 100644 crypto/include/internal/sm2err.h
 delete mode 100644 include/openssl/sm2err.h
 copy test/recipes/{03-test_internal_sm4.t => 03-test_internal_sm2.t} (77%)
 create mode 100644 test/sm2_internal_test.c
 delete mode 100644 test/sm2crypttest.c
 delete mode 100644 test/sm2sigtest.c

diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c
index b4105c2..0187adf 100644
--- a/crypto/ec/ec_pmeth.c
+++ b/crypto/ec/ec_pmeth.c
@@ -17,7 +17,7 @@
 #include "internal/evp_int.h"
 
 #if !defined(OPENSSL_NO_SM2)
-# include <openssl/sm2.h>
+# include "internal/sm2.h"
 #endif
 
 /* EC pkey context structure */
@@ -126,7 +126,7 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
 #if defined(OPENSSL_NO_SM2)
         return -1;
 #else
-        ret = SM2_sign(type, tbs, tbslen, sig, &sltmp, ec);
+        ret = sm2_sign(type, tbs, tbslen, sig, &sltmp, ec);
 #endif
     } else {
         ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
@@ -156,7 +156,7 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
 #if defined(OPENSSL_NO_SM2)
         ret = -1;
 #else
-        ret = SM2_verify(type, tbs, tbslen, sig, siglen, ec);
+        ret = sm2_verify(type, tbs, tbslen, sig, siglen, ec);
 #endif
     } else {
         ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
@@ -223,12 +223,14 @@ static int pkey_ecies_encrypt(EVP_PKEY_CTX *ctx,
             md_type = NID_sm3;
 
         if (out == NULL) {
-            *outlen = SM2_ciphertext_size(ec, EVP_get_digestbynid(md_type),
-                                          inlen);
-            ret = 1;
+            if (!sm2_ciphertext_size(ec, EVP_get_digestbynid(md_type), inlen,
+                                     outlen))
+                ret = -1;
+            else
+                ret = 1;
         }
         else {
-            ret = SM2_encrypt(ec, EVP_get_digestbynid(md_type),
+            ret = sm2_encrypt(ec, EVP_get_digestbynid(md_type),
                               in, inlen, out, outlen);
         }
 # endif
@@ -261,12 +263,14 @@ static int pkey_ecies_decrypt(EVP_PKEY_CTX *ctx,
             md_type = NID_sm3;
 
         if (out == NULL) {
-            *outlen = SM2_plaintext_size(ec, EVP_get_digestbynid(md_type),
-                                         inlen);
-            ret = 1;
+            if (!sm2_plaintext_size(ec, EVP_get_digestbynid(md_type), inlen,
+                                    outlen))
+                ret = -1;
+            else
+                ret = 1;
         }
         else {
-            ret = SM2_decrypt(ec, EVP_get_digestbynid(md_type),
+            ret = sm2_decrypt(ec, EVP_get_digestbynid(md_type),
                               in, inlen, out, outlen);
         }
 # endif
diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec
index f45e230..7fc5788 100644
--- a/crypto/err/openssl.ec
+++ b/crypto/err/openssl.ec
@@ -32,7 +32,7 @@ L CMS           include/openssl/cms.h           crypto/cms/cms_err.c
 L CT            include/openssl/ct.h            crypto/ct/ct_err.c
 L ASYNC         include/openssl/async.h         crypto/async/async_err.c
 L KDF           include/openssl/kdf.h           crypto/kdf/kdf_err.c
-L SM2           include/openssl/sm2.h           crypto/sm2/sm2_err.c
+L SM2           crypto/include/internal/sm2.h   crypto/sm2/sm2_err.c
 L OSSL_STORE    include/openssl/store.h         crypto/store/store_err.c
 
 # additional header files to be scanned for function names
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 62e798a..afd7e38 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -1063,11 +1063,15 @@ RSA_F_RSA_VERIFY:119:RSA_verify
 RSA_F_RSA_VERIFY_ASN1_OCTET_STRING:120:RSA_verify_ASN1_OCTET_STRING
 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:274:pkey_sm2_ctrl
-SM2_F_PKEY_SM2_CTRL_STR:275:pkey_sm2_ctrl_str
-SM2_F_PKEY_SM2_KEYGEN:276:pkey_sm2_keygen
-SM2_F_PKEY_SM2_PARAMGEN:277:pkey_sm2_paramgen
-SM2_F_PKEY_SM2_SIGN:278: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_DECRYPT:102:sm2_decrypt
+SM2_F_SM2_ENCRYPT:103:sm2_encrypt
+SM2_F_SM2_PLAINTEXT_SIZE:104:sm2_plaintext_size
+SM2_F_SM2_SIGN:105:sm2_sign
+SM2_F_SM2_SIG_GEN:106:sm2_sig_gen
+SM2_F_SM2_SIG_VERIFY:107:sm2_sig_verify
+SM2_F_SM2_VERIFY:108:sm2_verify
 SSL_F_ADD_CLIENT_KEY_SHARE_EXT:438:*
 SSL_F_ADD_KEY_SHARE:512:add_key_share
 SSL_F_BYTES_TO_CIPHER_LIST:519:bytes_to_cipher_list
@@ -2515,66 +2519,13 @@ RSA_R_UNSUPPORTED_MASK_PARAMETER:154:unsupported mask parameter
 RSA_R_UNSUPPORTED_SIGNATURE_TYPE:155:unsupported signature type
 RSA_R_VALUE_MISSING:147:value missing
 RSA_R_WRONG_SIGNATURE_LENGTH:119:wrong signature length
-SM2_R_ASN1_ERROR:115:asn1 error
-SM2_R_ASN5_ERROR:1150:asn5 error
-SM2_R_BAD_SIGNATURE:156:bad signature
-SM2_R_BIGNUM_OUT_OF_RANGE:144:bignum out of range
-SM2_R_BUFFER_TOO_SMALL:100:buffer too small
-SM2_R_COORDINATES_OUT_OF_RANGE:146:coordinates out of range
-SM2_R_CURVE_DOES_NOT_SUPPORT_ECDH:160:curve does not support ecdh
-SM2_R_CURVE_DOES_NOT_SUPPORT_SIGNING:159:curve does not support signing
-SM2_R_D2I_ECPKPARAMETERS_FAILURE:117:d2i ecpkparameters failure
-SM2_R_DECODE_ERROR:142:decode error
-SM2_R_DISCRIMINANT_IS_ZERO:118:discriminant is zero
-SM2_R_EC_GROUP_NEW_BY_NAME_FAILURE:119:ec group new by name failure
-SM2_R_FIELD_TOO_LARGE:143:field too large
-SM2_R_GF2M_NOT_SUPPORTED:147:gf2m not supported
-SM2_R_GROUP2PKPARAMETERS_FAILURE:120:group2pkparameters failure
-SM2_R_I2D_ECPKPARAMETERS_FAILURE:121:i2d ecpkparameters failure
-SM2_R_INCOMPATIBLE_OBJECTS:101:incompatible objects
-SM2_R_INVALID_ARGUMENT:112:invalid argument
-SM2_R_INVALID_COMPRESSED_POINT:110:invalid compressed point
-SM2_R_INVALID_COMPRESSION_BIT:109:invalid compression bit
-SM2_R_INVALID_CURVE:141:invalid curve
-SM2_R_INVALID_DIGEST:151:invalid digest
-SM2_R_INVALID_DIGEST_TYPE:138:invalid digest type
-SM2_R_INVALID_ENCODING:102:invalid encoding
-SM2_R_INVALID_FIELD:103:invalid field
-SM2_R_INVALID_FORM:104:invalid form
-SM2_R_INVALID_GROUP_ORDER:122:invalid group order
-SM2_R_INVALID_KEY:116:invalid key
-SM2_R_INVALID_OUTPUT_LENGTH:161:invalid output length
-SM2_R_INVALID_PEER_KEY:133:invalid peer key
-SM2_R_INVALID_PENTANOMIAL_BASIS:132:invalid pentanomial basis
-SM2_R_INVALID_PRIVATE_KEY:123:invalid private key
-SM2_R_INVALID_TRINOMIAL_BASIS:137:invalid trinomial basis
-SM2_R_KDF_PARAMETER_ERROR:148:kdf parameter error
-SM2_R_KEYS_NOT_SET:140:keys not set
-SM2_R_MISSING_PARAMETERS:124:missing parameters
-SM2_R_MISSING_PRIVATE_KEY:125:missing private key
-SM2_R_NEED_NEW_SETUP_VALUES:157:need new setup values
-SM2_R_NOT_A_NIST_PRIME:135:not a NIST prime
-SM2_R_NOT_IMPLEMENTED:126:not implemented
-SM2_R_NOT_INITIALIZED:111:not initialized
-SM2_R_NO_PARAMETERS_SET:139:no parameters set
-SM2_R_NO_PRIVATE_VALUE:154:no private value
-SM2_R_OPERATION_NOT_SUPPORTED:152:operation not supported
-SM2_R_PASSED_NULL_PARAMETER:134:passed null parameter
-SM2_R_PEER_KEY_ERROR:149:peer key error
-SM2_R_PKPARAMETERS2GROUP_FAILURE:127:pkparameters2group failure
-SM2_R_POINT_ARITHMETIC_FAILURE:155:point arithmetic failure
-SM2_R_POINT_AT_INFINITY:106:point at infinity
-SM2_R_POINT_IS_NOT_ON_CURVE:107:point is not on curve
-SM2_R_RANDOM_NUMBER_GENERATION_FAILED:158:random number generation failed
-SM2_R_SHARED_INFO_ERROR:150:shared info error
-SM2_R_SLOT_FULL:108:slot full
-SM2_R_UNDEFINED_GENERATOR:113:undefined generator
-SM2_R_UNDEFINED_ORDER:128:undefined order
-SM2_R_UNKNOWN_GROUP:129:unknown group
-SM2_R_UNKNOWN_ORDER:114:unknown order
-SM2_R_UNSUPPORTED_FIELD:131:unsupported field
-SM2_R_WRONG_CURVE_PARAMETERS:145:wrong curve parameters
-SM2_R_WRONG_ORDER:130:wrong order
+SM2_R_ASN1_ERROR:100:asn1 error
+SM2_R_BAD_SIGNATURE:101:bad signature
+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_USER_ID_TOO_LARGE:106:user id too large
 SSL_R_APP_DATA_IN_HANDSHAKE:100:app data in handshake
 SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT:272:\
 	attempt to reuse session in different context
diff --git a/include/openssl/sm2.h b/crypto/include/internal/sm2.h
similarity index 75%
rename from include/openssl/sm2.h
rename to crypto/include/internal/sm2.h
index af24c01..e0e2d75 100644
--- a/include/openssl/sm2.h
+++ b/crypto/include/internal/sm2.h
@@ -24,7 +24,7 @@ extern "C" {
 /* The default user id as specified in GM/T 0009-2012 */
 #  define SM2_DEFAULT_USERID "1234567812345678"
 
-int SM2_compute_userid_digest(uint8_t *out,
+int sm2_compute_userid_digest(uint8_t *out,
                               const EVP_MD *digest,
                               const char *user_id, const EC_KEY *key);
 
@@ -32,11 +32,11 @@ int SM2_compute_userid_digest(uint8_t *out,
  * SM2 signature operation. Computes ZA (user id digest) and then signs
  * H(ZA || msg) using SM2
  */
-ECDSA_SIG *SM2_do_sign(const EC_KEY *key,
+ECDSA_SIG *sm2_do_sign(const EC_KEY *key,
                        const EVP_MD *digest,
                        const char *user_id, const uint8_t *msg, size_t msg_len);
 
-int SM2_do_verify(const EC_KEY *key,
+int sm2_do_verify(const EC_KEY *key,
                   const EVP_MD *digest,
                   const ECDSA_SIG *signature,
                   const char *user_id, const uint8_t *msg, size_t msg_len);
@@ -44,40 +44,36 @@ int SM2_do_verify(const EC_KEY *key,
 /*
  * SM2 signature generation. Assumes input is an SM3 digest
  */
-int SM2_sign(int type, const unsigned char *dgst, int dgstlen,
+int sm2_sign(int type, const unsigned char *dgst, int dgstlen,
              unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
 
 /*
  * SM2 signature verification. Assumes input is an SM3 digest
  */
-int SM2_verify(int type, const unsigned char *dgst, int dgstlen,
+int sm2_verify(int type, const unsigned char *dgst, int dgstlen,
                const unsigned char *sig, int siglen, EC_KEY *eckey);
 
 
 /*
  * SM2 encryption
  */
-size_t SM2_ciphertext_size(const EC_KEY *key,
-                           const EVP_MD *digest,
-                           size_t msg_len);
+int sm2_ciphertext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len,
+                        size_t *ct_size);
 
-size_t SM2_plaintext_size(const EC_KEY *key,
-                          const EVP_MD *digest,
-                          size_t msg_len);
+int sm2_plaintext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len,
+                       size_t *pt_size);
 
-int SM2_encrypt(const EC_KEY *key,
+int sm2_encrypt(const EC_KEY *key,
                 const EVP_MD *digest,
                 const uint8_t *msg,
                 size_t msg_len,
                 uint8_t *ciphertext_buf, size_t *ciphertext_len);
 
-int SM2_decrypt(const EC_KEY *key,
+int sm2_decrypt(const EC_KEY *key,
                 const EVP_MD *digest,
                 const uint8_t *ciphertext,
                 size_t ciphertext_len, uint8_t *ptext_buf, size_t *ptext_len);
 
-int ERR_load_SM2_strings(void);
-
 #  ifdef __cplusplus
 }
 #  endif
diff --git a/crypto/include/internal/sm2err.h b/crypto/include/internal/sm2err.h
new file mode 100644
index 0000000..f2d60e1
--- /dev/null
+++ b/crypto/include/internal/sm2err.h
@@ -0,0 +1,48 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_SM2ERR_H
+# define HEADER_SM2ERR_H
+
+# include <openssl/opensslconf.h>
+
+# ifndef OPENSSL_NO_SM2
+
+#  ifdef  __cplusplus
+extern "C"
+#  endif
+int ERR_load_SM2_strings(void);
+
+/*
+ * SM2 function codes.
+ */
+#  define SM2_F_SM2_COMPUTE_MSG_HASH                       100
+#  define SM2_F_SM2_COMPUTE_USERID_DIGEST                  101
+#  define SM2_F_SM2_DECRYPT                                102
+#  define SM2_F_SM2_ENCRYPT                                103
+#  define SM2_F_SM2_PLAINTEXT_SIZE                         104
+#  define SM2_F_SM2_SIGN                                   105
+#  define SM2_F_SM2_SIG_GEN                                106
+#  define SM2_F_SM2_SIG_VERIFY                             107
+#  define SM2_F_SM2_VERIFY                                 108
+
+/*
+ * SM2 reason codes.
+ */
+#  define SM2_R_ASN1_ERROR                                 100
+#  define SM2_R_BAD_SIGNATURE                              101
+#  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_USER_ID_TOO_LARGE                          106
+
+# endif
+#endif
diff --git a/crypto/sm2/sm2_crypt.c b/crypto/sm2/sm2_crypt.c
index a31c40f..0fe1dd8 100644
--- a/crypto/sm2/sm2_crypt.c
+++ b/crypto/sm2/sm2_crypt.c
@@ -9,7 +9,9 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include <openssl/sm2.h>
+#include "internal/sm2.h"
+#include "internal/sm2err.h"
+#include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/bn.h>
 #include <openssl/asn1.h>
@@ -35,7 +37,7 @@ ASN1_SEQUENCE(SM2_Ciphertext) = {
 
 IMPLEMENT_ASN1_FUNCTIONS(SM2_Ciphertext)
 
-static size_t EC_field_size(const EC_GROUP *group)
+static size_t ec_field_size(const EC_GROUP *group)
 {
     /* Is there some simpler way to do this? */
     BIGNUM *p = BN_new();
@@ -57,31 +59,51 @@ static size_t EC_field_size(const EC_GROUP *group)
     return field_size;
 }
 
-size_t SM2_plaintext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len)
+int sm2_plaintext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len,
+                       size_t *pt_size)
 {
-    const size_t field_size = EC_field_size(EC_KEY_get0_group(key));
-    const size_t md_size = EVP_MD_size(digest);
-
-    const size_t overhead = 10 + 2 * field_size + md_size;
-    if(msg_len <= overhead)
-       return 0;
-
-    return msg_len - overhead;
+    const size_t field_size = ec_field_size(EC_KEY_get0_group(key));
+    const int md_size = EVP_MD_size(digest);
+    size_t overhead;
+
+    if (md_size < 0) {
+        SM2err(SM2_F_SM2_PLAINTEXT_SIZE, SM2_R_INVALID_DIGEST);
+        return 0;
+    }
+    if (field_size == 0) {
+        SM2err(SM2_F_SM2_PLAINTEXT_SIZE, SM2_R_INVALID_FIELD);
+        return 0;
+    }
+
+    overhead = 10 + 2 * field_size + (size_t)md_size;
+    if (msg_len <= overhead) {
+        SM2err(SM2_F_SM2_PLAINTEXT_SIZE, SM2_R_INVALID_ENCODING);
+        return 0;
+    }
+
+    *pt_size = msg_len - overhead;
+    return 1;
 }
 
-size_t SM2_ciphertext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len)
+int sm2_ciphertext_size(const EC_KEY *key, const EVP_MD *digest, size_t msg_len,
+                        size_t *ct_size)
 {
-    const size_t field_size = EC_field_size(EC_KEY_get0_group(key));
-    const size_t md_size = EVP_MD_size(digest);
-    return 10 + 2 * field_size + md_size + msg_len;
+    const size_t field_size = ec_field_size(EC_KEY_get0_group(key));
+    const int md_size = EVP_MD_size(digest);
+
+    if (field_size == 0 || md_size < 0)
+        return 0;
+
+    *ct_size = 10 + 2 * field_size + (size_t)md_size + msg_len;
+    return 1;
 }
 
-int SM2_encrypt(const EC_KEY *key,
+int sm2_encrypt(const EC_KEY *key,
                 const EVP_MD *digest,
                 const uint8_t *msg,
                 size_t msg_len, uint8_t *ciphertext_buf, size_t *ciphertext_len)
 {
-    int rc = 0;
+    int rc = 0, ciphertext_leni;
     size_t i;
     BN_CTX *ctx = NULL;
     BIGNUM *k = NULL;
@@ -89,9 +111,7 @@ int SM2_encrypt(const EC_KEY *key,
     BIGNUM *y1 = NULL;
     BIGNUM *x2 = NULL;
     BIGNUM *y2 = NULL;
-
     EVP_MD_CTX *hash = EVP_MD_CTX_new();
-
     struct SM2_Ciphertext_st ctext_struct;
     const EC_GROUP *group = EC_KEY_get0_group(key);
     const BIGNUM *order = EC_GROUP_get0_order(group);
@@ -99,24 +119,32 @@ int SM2_encrypt(const EC_KEY *key,
     EC_POINT *kG = NULL;
     EC_POINT *kP = NULL;
     uint8_t *msg_mask = NULL;
-
     uint8_t *x2y2 = NULL;
     uint8_t *C3 = NULL;
-
-    const size_t field_size = EC_field_size(group);
+    const size_t field_size = ec_field_size(group);
     const size_t C3_size = EVP_MD_size(digest);
 
-    if (field_size == 0 || C3_size == 0)
-       goto done;
+    /* NULL these before any "goto done" */
+    ctext_struct.C2 = NULL;
+    ctext_struct.C3 = NULL;
+
+    if (hash == NULL
+            || group == NULL
+            || order == NULL
+            || P == NULL
+            || field_size == 0
+            || C3_size == 0) {
+        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
+        goto done;
+    }
 
     kG = EC_POINT_new(group);
     kP = EC_POINT_new(group);
-    if (kG == NULL || kP == NULL)
-       goto done;
-
     ctx = BN_CTX_new();
-    if (ctx == NULL)
-       goto done;
+    if (kG == NULL || kP == NULL || ctx == NULL) {
+        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE);
+        goto done;
+    }
 
     BN_CTX_start(ctx);
     k = BN_CTX_get(ctx);
@@ -125,76 +153,93 @@ int SM2_encrypt(const EC_KEY *key,
     y1 = BN_CTX_get(ctx);
     y2 = BN_CTX_get(ctx);
 
-    if (y2 == NULL)
-       goto done;
+    if (y2 == NULL) {
+        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_BN_LIB);
+        goto done;
+    }
 
     x2y2 = OPENSSL_zalloc(2 * field_size);
     C3 = OPENSSL_zalloc(C3_size);
 
-    if (x2y2 == NULL || C3 == NULL)
-       goto done;
+    if (x2y2 == NULL || C3 == NULL) {
+        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE);
+        goto done;
+    }
 
     memset(ciphertext_buf, 0, *ciphertext_len);
 
-    BN_priv_rand_range(k, order);
-
-    if (EC_POINT_mul(group, kG, k, NULL, NULL, ctx) == 0)
-        goto done;
-
-    if (EC_POINT_get_affine_coordinates_GFp(group, kG, x1, y1, ctx) == 0)
+    if (!BN_priv_rand_range(k, order)) {
+        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
         goto done;
+    }
 
-    if (EC_POINT_mul(group, kP, NULL, P, k, ctx) == 0)
+    if (!EC_POINT_mul(group, kG, k, NULL, NULL, ctx)
+            || !EC_POINT_get_affine_coordinates_GFp(group, kG, x1, y1, ctx)
+            || !EC_POINT_mul(group, kP, NULL, P, k, ctx)
+            || !EC_POINT_get_affine_coordinates_GFp(group, kP, x2, y2, ctx)) {
+        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EC_LIB);
         goto done;
+    }
 
-    if (EC_POINT_get_affine_coordinates_GFp(group, kP, x2, y2, ctx) == 0)
+    if (BN_bn2binpad(x2, x2y2, field_size) < 0
+            || BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0) {
+        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
         goto done;
-
-    BN_bn2binpad(x2, x2y2, field_size);
-    BN_bn2binpad(y2, x2y2 + field_size, field_size);
+    }
 
     msg_mask = OPENSSL_zalloc(msg_len);
-    if (msg_mask == NULL)
+    if (msg_mask == NULL) {
+       SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE);
        goto done;
+   }
 
     /* X9.63 with no salt happens to match the KDF used in SM2 */
-    if (ECDH_KDF_X9_62(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, digest)
-        == 0)
+    if (!ECDH_KDF_X9_62(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0,
+                        digest)) {
+        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EVP_LIB);
         goto done;
+    }
 
     for (i = 0; i != msg_len; ++i)
         msg_mask[i] ^= msg[i];
 
-    if (EVP_DigestInit(hash, digest) == 0)
-        goto done;
-
-    if (EVP_DigestUpdate(hash, x2y2, field_size) == 0)
-        goto done;
-
-    if (EVP_DigestUpdate(hash, msg, msg_len) == 0)
-        goto done;
-
-    if (EVP_DigestUpdate(hash, x2y2 + field_size, field_size) == 0)
-        goto done;
-
-    if (EVP_DigestFinal(hash, C3, NULL) == 0)
+    if (EVP_DigestInit(hash, digest) == 0
+            || EVP_DigestUpdate(hash, x2y2, field_size) == 0
+            || EVP_DigestUpdate(hash, msg, msg_len) == 0
+            || EVP_DigestUpdate(hash, x2y2 + field_size, field_size) == 0
+            || EVP_DigestFinal(hash, C3, NULL) == 0) {
+        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EVP_LIB);
         goto done;
+    }
 
     ctext_struct.C1x = x1;
     ctext_struct.C1y = y1;
     ctext_struct.C3 = ASN1_OCTET_STRING_new();
-    ASN1_OCTET_STRING_set(ctext_struct.C3, C3, C3_size);
     ctext_struct.C2 = ASN1_OCTET_STRING_new();
-    ASN1_OCTET_STRING_set(ctext_struct.C2, msg_mask, msg_len);
 
-    *ciphertext_len = i2d_SM2_Ciphertext(&ctext_struct, &ciphertext_buf);
+    if (ctext_struct.C3 == NULL || ctext_struct.C2 == NULL) {
+       SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE);
+       goto done;
+    }
+    if (!ASN1_OCTET_STRING_set(ctext_struct.C3, C3, C3_size)
+            || !ASN1_OCTET_STRING_set(ctext_struct.C2, msg_mask, msg_len)) {
+        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
+        goto done;
+    }
 
-    ASN1_OCTET_STRING_free(ctext_struct.C2);
-    ASN1_OCTET_STRING_free(ctext_struct.C3);
+    ciphertext_leni = i2d_SM2_Ciphertext(&ctext_struct, &ciphertext_buf);
+    /* Ensure cast to size_t is safe */
+    if (ciphertext_leni < 0) {
+        SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
+        goto done;
+    }
+    *ciphertext_len = (size_t)ciphertext_leni;
 
     rc = 1;
 
  done:
+    ASN1_OCTET_STRING_free(ctext_struct.C2);
+    ASN1_OCTET_STRING_free(ctext_struct.C3);
     OPENSSL_free(msg_mask);
     OPENSSL_free(x2y2);
     OPENSSL_free(C3);
@@ -205,27 +250,23 @@ int SM2_encrypt(const EC_KEY *key,
     return rc;
 }
 
-int SM2_decrypt(const EC_KEY *key,
+int sm2_decrypt(const EC_KEY *key,
                 const EVP_MD *digest,
                 const uint8_t *ciphertext,
                 size_t ciphertext_len, uint8_t *ptext_buf, size_t *ptext_len)
 {
     int rc = 0;
     int i;
-
     BN_CTX *ctx = NULL;
     const EC_GROUP *group = EC_KEY_get0_group(key);
     EC_POINT *C1 = NULL;
     struct SM2_Ciphertext_st *sm2_ctext = NULL;
     BIGNUM *x2 = NULL;
     BIGNUM *y2 = NULL;
-
     uint8_t *x2y2 = NULL;
     uint8_t *computed_C3 = NULL;
-
-    const size_t field_size = EC_field_size(group);
+    const size_t field_size = ec_field_size(group);
     const int hash_size = EVP_MD_size(digest);
-
     uint8_t *msg_mask = NULL;
     const uint8_t *C2 = NULL;
     const uint8_t *C3 = NULL;
@@ -239,87 +280,94 @@ int SM2_decrypt(const EC_KEY *key,
 
     sm2_ctext = d2i_SM2_Ciphertext(NULL, &ciphertext, ciphertext_len);
 
-    if (sm2_ctext == NULL)
+    if (sm2_ctext == NULL) {
+        SM2err(SM2_F_SM2_DECRYPT, SM2_R_ASN1_ERROR);
         goto done;
+    }
 
-    if (sm2_ctext->C3->length != hash_size)
+    if (sm2_ctext->C3->length != hash_size) {
+        SM2err(SM2_F_SM2_DECRYPT, SM2_R_INVALID_ENCODING);
         goto done;
+    }
 
     C2 = sm2_ctext->C2->data;
     C3 = sm2_ctext->C3->data;
     msg_len = sm2_ctext->C2->length;
 
     ctx = BN_CTX_new();
-    if (ctx == NULL)
-       goto done;
+    if (ctx == NULL) {
+        SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
+        goto done;
+    }
 
     BN_CTX_start(ctx);
     x2 = BN_CTX_get(ctx);
     y2 = BN_CTX_get(ctx);
 
-    if(y2 == NULL)
-       goto done;
+    if (y2 == NULL) {
+        SM2err(SM2_F_SM2_DECRYPT, ERR_R_BN_LIB);
+        goto done;
+    }
 
     msg_mask = OPENSSL_zalloc(msg_len);
     x2y2 = OPENSSL_zalloc(2 * field_size);
     computed_C3 = OPENSSL_zalloc(hash_size);
 
-    if(msg_mask == NULL || x2y2 == NULL || computed_C3 == NULL)
-       goto done;
-
-    C1 = EC_POINT_new(group);
-    if (C1 == NULL)
-        goto done;
-
-    if (EC_POINT_set_affine_coordinates_GFp
-        (group, C1, sm2_ctext->C1x, sm2_ctext->C1y, ctx) == 0)
+    if (msg_mask == NULL || x2y2 == NULL || computed_C3 == NULL) {
+        SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
         goto done;
+    }
 
-    if (EC_POINT_mul(group, C1, NULL, C1, EC_KEY_get0_private_key(key), ctx) ==
-        0)
+    C1 = EC_POINT_new(group);
+    if (C1 == NULL) {
+        SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
         goto done;
-
-    if (EC_POINT_get_affine_coordinates_GFp(group, C1, x2, y2, ctx) == 0)
+    }
+
+    if (!EC_POINT_set_affine_coordinates_GFp(group, C1, sm2_ctext->C1x,
+                                            sm2_ctext->C1y, ctx)
+            || !EC_POINT_mul(group, C1, NULL, C1, EC_KEY_get0_private_key(key),
+                             ctx)
+            || !EC_POINT_get_affine_coordinates_GFp(group, C1, x2, y2, ctx)) {
+        SM2err(SM2_F_SM2_DECRYPT, ERR_R_EC_LIB);
         goto done;
+    }
 
-    BN_bn2binpad(x2, x2y2, field_size);
-    BN_bn2binpad(y2, x2y2 + field_size, field_size);
-
-    if (ECDH_KDF_X9_62(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0, digest)
-        == 0)
+    if (BN_bn2binpad(x2, x2y2, field_size) < 0
+            || BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0
+            || !ECDH_KDF_X9_62(msg_mask, msg_len, x2y2, 2 * field_size, NULL, 0,
+                               digest)) {
+        SM2err(SM2_F_SM2_DECRYPT, ERR_R_INTERNAL_ERROR);
         goto done;
+    }
 
     for (i = 0; i != msg_len; ++i)
         ptext_buf[i] = C2[i] ^ msg_mask[i];
 
     hash = EVP_MD_CTX_new();
-
-    if (hash == NULL)
-       goto done;
-
-    if (EVP_DigestInit(hash, digest) == 0)
+    if (hash == NULL) {
+        SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
         goto done;
-
-    if (EVP_DigestUpdate(hash, x2y2, field_size) == 0)
-        goto done;
-
-    if (EVP_DigestUpdate(hash, ptext_buf, msg_len) == 0)
-        goto done;
-
-    if (EVP_DigestUpdate(hash, x2y2 + field_size, field_size) == 0)
-        goto done;
-
-    if (EVP_DigestFinal(hash, computed_C3, NULL) == 0)
+    }
+
+    if (!EVP_DigestInit(hash, digest)
+            || !EVP_DigestUpdate(hash, x2y2, field_size)
+            || !EVP_DigestUpdate(hash, ptext_buf, msg_len)
+            || !EVP_DigestUpdate(hash, x2y2 + field_size, field_size)
+            || !EVP_DigestFinal(hash, computed_C3, NULL)) {
+        SM2err(SM2_F_SM2_DECRYPT, ERR_R_EVP_LIB);
         goto done;
+    }
 
-    if (memcmp(computed_C3, C3, hash_size) != 0)
+    if (CRYPTO_memcmp(computed_C3, C3, hash_size) != 0) {
+        SM2err(SM2_F_SM2_DECRYPT, SM2_R_INVALID_DIGEST);
         goto done;
+    }
 
     rc = 1;
     *ptext_len = msg_len;
 
  done:
-
     if (rc == 0)
         memset(ptext_buf, 0, *ptext_len);
 
diff --git a/crypto/sm2/sm2_err.c b/crypto/sm2/sm2_err.c
index 0c051f6..e36975f 100644
--- a/crypto/sm2/sm2_err.c
+++ b/crypto/sm2/sm2_err.c
@@ -9,109 +9,34 @@
  */
 
 #include <openssl/err.h>
-#include <openssl/sm2err.h>
+#include "internal/sm2err.h"
 
 #ifndef OPENSSL_NO_ERR
 
 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_KEYGEN, 0), "pkey_sm2_keygen"},
-    {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_PARAMGEN, 0), "pkey_sm2_paramgen"},
-    {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_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"},
+    {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_SIGN, 0), "sm2_sign"},
+    {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_SIG_GEN, 0), "sm2_sig_gen"},
+    {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_SIG_VERIFY, 0), "sm2_sig_verify"},
+    {ERR_PACK(ERR_LIB_SM2, SM2_F_SM2_VERIFY, 0), "sm2_verify"},
     {0, NULL}
 };
 
 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_ASN5_ERROR), "asn5 error"},
     {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_BAD_SIGNATURE), "bad signature"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_BIGNUM_OUT_OF_RANGE),
-    "bignum out of range"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_BUFFER_TOO_SMALL), "buffer too small"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_COORDINATES_OUT_OF_RANGE),
-    "coordinates out of range"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_CURVE_DOES_NOT_SUPPORT_ECDH),
-    "curve does not support ecdh"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_CURVE_DOES_NOT_SUPPORT_SIGNING),
-    "curve does not support signing"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_D2I_ECPKPARAMETERS_FAILURE),
-    "d2i ecpkparameters failure"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_DECODE_ERROR), "decode error"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_DISCRIMINANT_IS_ZERO),
-    "discriminant is zero"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_EC_GROUP_NEW_BY_NAME_FAILURE),
-    "ec group new by name failure"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_FIELD_TOO_LARGE), "field too large"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_GF2M_NOT_SUPPORTED), "gf2m not supported"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_GROUP2PKPARAMETERS_FAILURE),
-    "group2pkparameters failure"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_I2D_ECPKPARAMETERS_FAILURE),
-    "i2d ecpkparameters failure"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INCOMPATIBLE_OBJECTS),
-    "incompatible objects"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_ARGUMENT), "invalid argument"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_COMPRESSED_POINT),
-    "invalid compressed point"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_COMPRESSION_BIT),
-    "invalid compression bit"},
-    {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),
     "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_FORM), "invalid form"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_GROUP_ORDER),
-    "invalid group order"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_KEY), "invalid key"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_OUTPUT_LENGTH),
-    "invalid output length"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_PEER_KEY), "invalid peer key"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_PENTANOMIAL_BASIS),
-    "invalid pentanomial basis"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_PRIVATE_KEY),
-    "invalid private key"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_TRINOMIAL_BASIS),
-    "invalid trinomial basis"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_KDF_PARAMETER_ERROR),
-    "kdf parameter error"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_KEYS_NOT_SET), "keys not set"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_MISSING_PARAMETERS), "missing parameters"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_MISSING_PRIVATE_KEY),
-    "missing private key"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NEED_NEW_SETUP_VALUES),
-    "need new setup values"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NOT_A_NIST_PRIME), "not a NIST prime"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NOT_IMPLEMENTED), "not implemented"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NOT_INITIALIZED), "not initialized"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NO_PARAMETERS_SET), "no parameters set"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NO_PRIVATE_VALUE), "no private value"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_OPERATION_NOT_SUPPORTED),
-    "operation not supported"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_PASSED_NULL_PARAMETER),
-    "passed null parameter"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_PEER_KEY_ERROR), "peer key error"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_PKPARAMETERS2GROUP_FAILURE),
-    "pkparameters2group failure"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_POINT_ARITHMETIC_FAILURE),
-    "point arithmetic failure"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_POINT_AT_INFINITY), "point at infinity"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_POINT_IS_NOT_ON_CURVE),
-    "point is not on curve"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_RANDOM_NUMBER_GENERATION_FAILED),
-    "random number generation failed"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_SHARED_INFO_ERROR), "shared info error"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_SLOT_FULL), "slot full"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_UNDEFINED_GENERATOR),
-    "undefined generator"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_UNDEFINED_ORDER), "undefined order"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_UNKNOWN_GROUP), "unknown group"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_UNKNOWN_ORDER), "unknown order"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_UNSUPPORTED_FIELD), "unsupported field"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_WRONG_CURVE_PARAMETERS),
-    "wrong curve parameters"},
-    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_WRONG_ORDER), "wrong order"},
+    {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_USER_ID_TOO_LARGE), "user id too large"},
     {0, NULL}
 };
 
diff --git a/crypto/sm2/sm2_sign.c b/crypto/sm2/sm2_sign.c
index e12eca1..4ca0ca8 100644
--- a/crypto/sm2/sm2_sign.c
+++ b/crypto/sm2/sm2_sign.c
@@ -9,44 +9,51 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include <openssl/sm2.h>
+#include "internal/sm2.h"
+#include "internal/sm2err.h"
+#include <openssl/err.h>
 #include <openssl/evp.h>
+#include <openssl/err.h>
 #include <openssl/bn.h>
 #include <string.h>
 
-static BIGNUM *compute_msg_hash(const EVP_MD *digest,
-                                const EC_KEY *key,
-                                const char *user_id,
-                                const uint8_t *msg, size_t msg_len)
+static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,
+                                    const EC_KEY *key,
+                                    const char *user_id,
+                                    const uint8_t *msg, size_t msg_len)
 {
     EVP_MD_CTX *hash = EVP_MD_CTX_new();
     const int md_size = EVP_MD_size(digest);
     uint8_t *za = OPENSSL_zalloc(md_size);
     BIGNUM *e = NULL;
 
-    if (za == NULL)
-        goto done;
-
-    if (hash == NULL)
-        goto done;
-
-    if (SM2_compute_userid_digest(za, digest, user_id, key) == 0)
-        goto done;
-
-    if (EVP_DigestInit(hash, digest) == 0)
+    if (hash == NULL || za == NULL) {
+        SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_MALLOC_FAILURE);
         goto done;
+    }
 
-    if (EVP_DigestUpdate(hash, za, md_size) == 0)
+    if (md_size < 0) {
+        SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, SM2_R_INVALID_DIGEST);
         goto done;
+    }
 
-    if (EVP_DigestUpdate(hash, msg, msg_len) == 0)
+    if (!sm2_compute_userid_digest(za, digest, user_id, key)) {
+        /* SM2err already called */
         goto done;
+    }
 
-    /* reuse za buffer to hold H(ZA || M) */
-    if (EVP_DigestFinal(hash, za, NULL) == 0)
+    if (!EVP_DigestInit(hash, digest)
+            || !EVP_DigestUpdate(hash, za, md_size)
+            || !EVP_DigestUpdate(hash, msg, msg_len)
+               /* reuse za buffer to hold H(ZA || M) */
+            || !EVP_DigestFinal(hash, za, NULL)) {
+        SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_EVP_LIB);
         goto done;
+    }
 
     e = BN_bin2bn(za, md_size, NULL);
+    if (e == NULL)
+        SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_INTERNAL_ERROR);
 
  done:
     OPENSSL_free(za);
@@ -54,13 +61,11 @@ static BIGNUM *compute_msg_hash(const EVP_MD *digest,
     return e;
 }
 
-static
-ECDSA_SIG *SM2_sig_gen(const EC_KEY *key, const BIGNUM *e)
+static ECDSA_SIG *sm2_sig_gen(const EC_KEY *key, const BIGNUM *e)
 {
     const BIGNUM *dA = EC_KEY_get0_private_key(key);
     const EC_GROUP *group = EC_KEY_get0_group(key);
     const BIGNUM *order = EC_GROUP_get0_order(group);
-
     ECDSA_SIG *sig = NULL;
     EC_POINT *kG = NULL;
     BN_CTX *ctx = NULL;
@@ -72,63 +77,75 @@ ECDSA_SIG *SM2_sig_gen(const EC_KEY *key, const BIGNUM *e)
     BIGNUM *tmp = NULL;
 
     kG = EC_POINT_new(group);
-    if (kG == NULL)
-        goto done;
-
     ctx = BN_CTX_new();
-    if (ctx == NULL)
+    if (kG == NULL || ctx == NULL) {
+        SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE);
         goto done;
+    }
 
-    BN_CTX_start(ctx);
 
+    BN_CTX_start(ctx);
     k = BN_CTX_get(ctx);
     rk = BN_CTX_get(ctx);
     x1 = BN_CTX_get(ctx);
     tmp = BN_CTX_get(ctx);
-
-    if (tmp == NULL)
+    if (tmp == NULL) {
+        SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE);
         goto done;
+    }
 
-    /* These values are returned and so should not be allocated out of the context */
+    /*
+     * These values are returned and so should not be allocated out of the
+     * context
+     */
     r = BN_new();
     s = BN_new();
 
-    if (r == NULL || s == NULL)
+    if (r == NULL || s == NULL) {
+        SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE);
         goto done;
+    }
 
     for (;;) {
-        BN_priv_rand_range(k, order);
-
-        if (EC_POINT_mul(group, kG, k, NULL, NULL, ctx) == 0)
-            goto done;
-
-        if (EC_POINT_get_affine_coordinates_GFp(group, kG, x1, NULL, ctx) == 0)
-            goto done;
-
-        if (BN_mod_add(r, e, x1, order, ctx) == 0)
+        if (!BN_priv_rand_range(k, order)) {
+            SM2err(SM2_F_SM2_SIG_GEN, ERR_R_INTERNAL_ERROR);
+                goto done;
+        }
+
+        if (!EC_POINT_mul(group, kG, k, NULL, NULL, ctx)
+                || !EC_POINT_get_affine_coordinates_GFp(group, kG, x1, NULL,
+                                                        ctx)
+                || !BN_mod_add(r, e, x1, order, ctx)) {
+            SM2err(SM2_F_SM2_SIG_GEN, ERR_R_INTERNAL_ERROR);
             goto done;
+        }
 
         /* try again if r == 0 or r+k == n */
         if (BN_is_zero(r))
             continue;
 
-        BN_add(rk, r, k);
+        if (!BN_add(rk, r, k)) {
+            SM2err(SM2_F_SM2_SIG_GEN, ERR_R_INTERNAL_ERROR);
+            goto done;
+        }
 
         if (BN_cmp(rk, order) == 0)
             continue;
 
-        BN_add(s, dA, BN_value_one());
-        BN_mod_inverse(s, s, order, ctx);
-
-        BN_mod_mul(tmp, dA, r, order, ctx);
-        BN_sub(tmp, k, tmp);
-
-        BN_mod_mul(s, s, tmp, order, ctx);
+        if (!BN_add(s, dA, BN_value_one())
+                || !BN_mod_inverse(s, s, order, ctx)
+                || !BN_mod_mul(tmp, dA, r, order, ctx)
+                || !BN_sub(tmp, k, tmp)
+                || !BN_mod_mul(s, s, tmp, order, ctx)) {
+            SM2err(SM2_F_SM2_SIG_GEN, ERR_R_BN_LIB);
+            goto done;
+        }
 
         sig = ECDSA_SIG_new();
-
-        if (sig == NULL)
+        if (sig == NULL) {
+            SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE);
             goto done;
+        }
 
          /* takes ownership of r and s */
         ECDSA_SIG_set0(sig, r, s);
@@ -136,7 +153,6 @@ ECDSA_SIG *SM2_sig_gen(const EC_KEY *key, const BIGNUM *e)
     }
 
  done:
-
     if (sig == NULL) {
         BN_free(r);
         BN_free(s);
@@ -145,74 +161,76 @@ ECDSA_SIG *SM2_sig_gen(const EC_KEY *key, const BIGNUM *e)
     BN_CTX_free(ctx);
     EC_POINT_free(kG);
     return sig;
-
 }
 
-static
-int SM2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, const BIGNUM *e)
+static int sm2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig,
+                          const BIGNUM *e)
 {
     int ret = 0;
     const EC_GROUP *group = EC_KEY_get0_group(key);
     const BIGNUM *order = EC_GROUP_get0_order(group);
     BN_CTX *ctx = NULL;
     EC_POINT *pt = NULL;
-
     BIGNUM *t = NULL;
     BIGNUM *x1 = NULL;
     const BIGNUM *r = NULL;
     const BIGNUM *s = NULL;
 
     ctx = BN_CTX_new();
-    if (ctx == NULL)
-        goto done;
     pt = EC_POINT_new(group);
-    if (pt == NULL)
+    if (ctx == NULL || pt == NULL) {
+        SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_MALLOC_FAILURE);
         goto done;
+    }
 
     BN_CTX_start(ctx);
-
     t = BN_CTX_get(ctx);
     x1 = BN_CTX_get(ctx);
-
-    if (x1 == NULL)
+    if (x1 == NULL) {
+        SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_MALLOC_FAILURE);
         goto done;
+    }
 
     /*
-       B1: verify whether r' in [1,n-1], verification failed if not
-       B2: vefify whether s' in [1,n-1], verification failed if not
-       B3: set M'~=ZA || M'
-       B4: calculate e'=Hv(M'~)
-       B5: calculate t = (r' + s') modn, verification failed if t=0
-       B6: calculate the point (x1', y1')=[s']G + [t]PA
-       B7: calculate R=(e'+x1') modn, verfication pass if yes, otherwise failed
+     * B1: verify whether r' in [1,n-1], verification failed if not
+     * B2: vefify whether s' in [1,n-1], verification failed if not
+     * B3: set M'~=ZA || M'
+     * B4: calculate e'=Hv(M'~)
+     * B5: calculate t = (r' + s') modn, verification failed if t=0
+     * B6: calculate the point (x1', y1')=[s']G + [t]PA
+     * B7: calculate R=(e'+x1') modn, verfication pass if yes, otherwise failed
      */
 
     ECDSA_SIG_get0(sig, &r, &s);
 
-    if (BN_cmp(r, BN_value_one()) < 0)
-        goto done;
-    if (BN_cmp(s, BN_value_one()) < 0)
-        goto done;
-
-    if (BN_cmp(order, r) <= 0)
-        goto done;
-    if (BN_cmp(order, s) <= 0)
-        goto done;
-
-    if (BN_mod_add(t, r, s, order, ctx) == 0)
+    if (BN_cmp(r, BN_value_one()) < 0
+            || BN_cmp(s, BN_value_one()) < 0
+            || BN_cmp(order, r) <= 0
+            || BN_cmp(order, s) <= 0) {
+        SM2err(SM2_F_SM2_SIG_VERIFY, SM2_R_BAD_SIGNATURE);
         goto done;
+    }
 
-    if (BN_is_zero(t) == 1)
+    if (!BN_mod_add(t, r, s, order, ctx)) {
+        SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_BN_LIB);
         goto done;
+    }
 
-    if (EC_POINT_mul(group, pt, s, EC_KEY_get0_public_key(key), t, ctx) == 0)
+    if (BN_is_zero(t)) {
+        SM2err(SM2_F_SM2_SIG_VERIFY, SM2_R_BAD_SIGNATURE);
         goto done;
+    }
 
-    if (EC_POINT_get_affine_coordinates_GFp(group, pt, x1, NULL, ctx) == 0)
+    if (!EC_POINT_mul(group, pt, s, EC_KEY_get0_public_key(key), t, ctx)
+            || !EC_POINT_get_affine_coordinates_GFp(group, pt, x1, NULL, ctx)) {
+        SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_EC_LIB);
         goto done;
+    }
 
-    if (BN_mod_add(t, e, x1, order, ctx) == 0)
+    if (!BN_mod_add(t, e, x1, order, ctx)) {
+        SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_BN_LIB);
         goto done;
+    }
 
     if (BN_cmp(r, t) == 0)
         ret = 1;
@@ -223,61 +241,74 @@ int SM2_sig_verify(const EC_KEY *key, const ECDSA_SIG *sig, const BIGNUM *e)
     return ret;
 }
 
-ECDSA_SIG *SM2_do_sign(const EC_KEY *key,
+ECDSA_SIG *sm2_do_sign(const EC_KEY *key,
                        const EVP_MD *digest,
                        const char *user_id, const uint8_t *msg, size_t msg_len)
 {
     BIGNUM *e = NULL;
     ECDSA_SIG *sig = NULL;
 
-    e = compute_msg_hash(digest, key, user_id, msg, msg_len);
-    if (e == NULL)
+    e = sm2_compute_msg_hash(digest, key, user_id, msg, msg_len);
+    if (e == NULL) {
+        /* SM2err already called */
         goto done;
+    }
 
-    sig = SM2_sig_gen(key, e);
+    sig = sm2_sig_gen(key, e);
 
  done:
     BN_free(e);
     return sig;
 }
 
-int SM2_do_verify(const EC_KEY *key,
+int sm2_do_verify(const EC_KEY *key,
                   const EVP_MD *digest,
                   const ECDSA_SIG *sig,
                   const char *user_id, const uint8_t *msg, size_t msg_len)
 {
     BIGNUM *e = NULL;
-    int ret = -1;
+    int ret = 0;
 
-    e = compute_msg_hash(digest, key, user_id, msg, msg_len);
-    if (e == NULL)
+    e = sm2_compute_msg_hash(digest, key, user_id, msg, msg_len);
+    if (e == NULL) {
+        /* SM2err already called */
         goto done;
+    }
 
-    ret = SM2_sig_verify(key, sig, e);
+    ret = sm2_sig_verify(key, sig, e);
 
  done:
     BN_free(e);
     return ret;
 }
 
-int SM2_sign(int type, const unsigned char *dgst, int dgstlen,
+int sm2_sign(int type, const unsigned char *dgst, int dgstlen,
              unsigned char *sig, unsigned int *siglen, EC_KEY *eckey)
 {
     BIGNUM *e = NULL;
     ECDSA_SIG *s = NULL;
+    int sigleni;
     int ret = -1;
 
-    if (type != NID_sm3)
-        goto done;
-
-    if (dgstlen != 32)          /* expected length of SM3 hash */
-        goto done;
+    if (type != NID_sm3 || dgstlen != 32) {
+       SM2err(SM2_F_SM2_SIGN, SM2_R_INVALID_DIGEST_TYPE);
+       goto done;
+   }
 
     e = BN_bin2bn(dgst, dgstlen, NULL);
+    if (e == NULL) {
+       SM2err(SM2_F_SM2_SIGN, ERR_R_BN_LIB);
+       goto done;
+    }
 
-    s = SM2_sig_gen(eckey, e);
+    s = sm2_sig_gen(eckey, e);
 
-    *siglen = i2d_ECDSA_SIG(s, &sig);
+    sigleni = i2d_ECDSA_SIG(s, &sig);
+    if (sigleni < 0) {
+       SM2err(SM2_F_SM2_SIGN, ERR_R_INTERNAL_ERROR);
+       goto done;
+    }
+    *siglen = (unsigned int)sigleni;
 
     ret = 1;
 
@@ -287,7 +318,7 @@ int SM2_sign(int type, const unsigned char *dgst, int dgstlen,
     return ret;
 }
 
-int SM2_verify(int type, const unsigned char *dgst, int dgstlen,
+int sm2_verify(int type, const unsigned char *dgst, int dgstlen,
                const unsigned char *sig, int sig_len, EC_KEY *eckey)
 {
     ECDSA_SIG *s = NULL;
@@ -297,22 +328,34 @@ int SM2_verify(int type, const unsigned char *dgst, int dgstlen,
     int derlen = -1;
     int ret = -1;
 
-    if (type != NID_sm3)
-        goto done;
+    if (type != NID_sm3) {
+       SM2err(SM2_F_SM2_VERIFY, SM2_R_INVALID_DIGEST_TYPE);
+       goto done;
+   }
 
     s = ECDSA_SIG_new();
-    if (s == NULL)
+    if (s == NULL) {
+        SM2err(SM2_F_SM2_VERIFY, ERR_R_MALLOC_FAILURE);
         goto done;
-    if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL)
+    }
+    if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) {
+        SM2err(SM2_F_SM2_VERIFY, SM2_R_INVALID_ENCODING);
         goto done;
+    }
     /* Ensure signature uses DER and doesn't have trailing garbage */
     derlen = i2d_ECDSA_SIG(s, &der);
-    if (derlen != sig_len || memcmp(sig, der, derlen) != 0)
+    if (derlen != sig_len || memcmp(sig, der, derlen) != 0) {
+        SM2err(SM2_F_SM2_VERIFY, SM2_R_INVALID_ENCODING);
         goto done;
+    }
 
     e = BN_bin2bn(dgst, dgstlen, NULL);
+    if (e == NULL) {
+        SM2err(SM2_F_SM2_VERIFY, ERR_R_BN_LIB);
+        goto done;
+    }
 
-    ret = SM2_sig_verify(eckey, s, e);
+    ret = sm2_sig_verify(eckey, s, e);
 
  done:
     OPENSSL_free(der);
diff --git a/crypto/sm2/sm2_za.c b/crypto/sm2/sm2_za.c
index f76fe0f..a9560c3 100644
--- a/crypto/sm2/sm2_za.c
+++ b/crypto/sm2/sm2_za.c
@@ -9,32 +9,29 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include <openssl/sm2.h>
+#include "internal/sm2.h"
+#include "internal/sm2err.h"
+#include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/bn.h>
 #include <string.h>
 
-int SM2_compute_userid_digest(uint8_t *out,
+int sm2_compute_userid_digest(uint8_t *out,
                               const EVP_MD *digest,
                               const char *user_id,
                               const EC_KEY *key)
 {
     int rc = 0;
-
     const EC_GROUP *group = EC_KEY_get0_group(key);
-
     BN_CTX *ctx = NULL;
     EVP_MD_CTX *hash = NULL;
-
     BIGNUM *p = NULL;
     BIGNUM *a = NULL;
     BIGNUM *b = NULL;
-
     BIGNUM *xG = NULL;
     BIGNUM *yG = NULL;
     BIGNUM *xA = NULL;
     BIGNUM *yA = NULL;
-
     int p_bytes = 0;
     uint8_t *buf = NULL;
     size_t uid_len = 0;
@@ -42,12 +39,11 @@ int SM2_compute_userid_digest(uint8_t *out,
     uint8_t e_byte = 0;
 
     hash = EVP_MD_CTX_new();
-    if (hash == NULL)
-       goto done;
-
     ctx = BN_CTX_new();
-    if (ctx == NULL)
-       goto done;
+    if (hash == NULL || ctx == NULL) {
+        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE);
+        goto done;
+    }
 
     p = BN_CTX_get(ctx);
     a = BN_CTX_get(ctx);
@@ -57,70 +53,75 @@ int SM2_compute_userid_digest(uint8_t *out,
     xA = BN_CTX_get(ctx);
     yA = BN_CTX_get(ctx);
 
-    if (p == NULL || a == NULL || b == NULL ||
-        xG == NULL || yG == NULL || xA == NULL || yA == NULL)
-       goto done;
+    if (yA == NULL) {
+        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE);
+        goto done;
+    }
 
     memset(out, 0, EVP_MD_size(digest));
 
-    if (EVP_DigestInit(hash, digest) == 0)
+    if (!EVP_DigestInit(hash, digest)) {
+        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
         goto done;
+    }
 
-    /*
-       ZA=H256(ENTLA || IDA || a || b || xG || yG || xA || yA)
-     */
+    /* ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA) */
 
     uid_len = strlen(user_id);
-
-    if (uid_len >= 8192)        /* too large */
+    if (uid_len >= (UINT16_MAX / 8)) {
+        /* too large */
+        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, SM2_R_USER_ID_TOO_LARGE);
         goto done;
+    }
 
-    entla = (unsigned short)(8 * uid_len);
+    entla = (uint16_t)(8 * uid_len);
 
     e_byte = entla >> 8;
-    if (EVP_DigestUpdate(hash, &e_byte, 1) == 0)
+    if (!EVP_DigestUpdate(hash, &e_byte, 1)) {
+        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
         goto done;
+    }
     e_byte = entla & 0xFF;
-    if (EVP_DigestUpdate(hash, &e_byte, 1) == 0)
+    if (!EVP_DigestUpdate(hash, &e_byte, 1)
+            || !EVP_DigestUpdate(hash, user_id, uid_len)) {
+        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EVP_LIB);
         goto done;
+    }
 
-    if (EVP_DigestUpdate(hash, user_id, uid_len) == 0)
-        goto done;
-
-    if (EC_GROUP_get_curve_GFp(group, p, a, b, ctx) == 0)
+    if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) {
+        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_EC_LIB);
         goto done;
+    }
 
     p_bytes = BN_num_bytes(p);
     buf = OPENSSL_zalloc(p_bytes);
-
-    BN_bn2binpad(a, buf, p_bytes);
-    if (EVP_DigestUpdate(hash, buf, p_bytes) == 0)
-        goto done;
-    BN_bn2binpad(b, buf, p_bytes);
-    if (EVP_DigestUpdate(hash, buf, p_bytes) == 0)
-        goto done;
-    EC_POINT_get_affine_coordinates_GFp(group,
-                                        EC_GROUP_get0_generator(group),
-                                        xG, yG, ctx);
-    BN_bn2binpad(xG, buf, p_bytes);
-    if (EVP_DigestUpdate(hash, buf, p_bytes) == 0)
-        goto done;
-    BN_bn2binpad(yG, buf, p_bytes);
-    if (EVP_DigestUpdate(hash, buf, p_bytes) == 0)
+    if (buf == NULL) {
+        SM2err(SM2_F_SM2_COMPUTE_USERID_DIGEST, ERR_R_MALLOC_FAILURE);
         goto done;
-
-    EC_POINT_get_affine_coordinates_GFp(group,
-                                        EC_KEY_get0_public_key(key),
-                                        xA, yA, ctx);
-    BN_bn2binpad(xA, buf, p_bytes);
-    if (EVP_DigestUpdate(hash, buf, p_bytes) == 0)
-        goto done;
-    BN_bn2binpad(yA, buf, p_bytes);
-    if (EVP_DigestUpdate(hash, buf, p_bytes) == 0)
-        goto done;
-
-    if (EVP_DigestFinal(hash, out, NULL) == 0)
+    }
+
+    if (BN_bn2binpad(a, buf, p_bytes) < 0
+            || !EVP_DigestUpdate(hash, buf, p_bytes)
+            || BN_bn2binpad(b, buf, p_bytes) < 0
+            || !EVP_DigestUpdate(hash, buf, p_bytes)
+            || !EC_POINT_get_affine_coordinates_GFp(group,
+                                                EC_GROUP_get0_generator(group),
+                                                xG, yG, ctx)
+            || BN_bn2binpad(xG, buf, p_bytes) < 0
+            || !EVP_DigestUpdate(hash, buf, p_bytes)
+            || BN_bn2binpad(yG, buf, p_bytes) < 0
+            || !EVP_DigestUpdate(hash, buf, p_bytes)
+            || !EC_POINT_get_affine_coordinates_GFp(group,
+                                                    EC_KEY_get0_public_key(key),
+                                                    xA, yA, ctx)
+            || BN_bn2binpad(xA, buf, p_bytes) < 0
+            || !EVP_DigestUpdate(hash, buf, p_bytes)
+            || 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);
         goto done;
+    }
 
     rc = 1;
 
diff --git a/include/openssl/sm2err.h b/include/openssl/sm2err.h
deleted file mode 100644
index 3416c3d..0000000
--- a/include/openssl/sm2err.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Generated by util/mkerr.pl DO NOT EDIT
- * 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#ifndef HEADER_SM2ERR_H
-# define HEADER_SM2ERR_H
-
-# ifdef  __cplusplus
-extern "C" {
-# endif
-int ERR_load_SM2_strings(void);
-# ifdef  __cplusplus
-}
-# endif
-
-/*
- * SM2 function codes.
- */
-# define SM2_F_PKEY_SM2_CTRL                              274
-# define SM2_F_PKEY_SM2_CTRL_STR                          275
-# define SM2_F_PKEY_SM2_KEYGEN                            276
-# define SM2_F_PKEY_SM2_PARAMGEN                          277
-# define SM2_F_PKEY_SM2_SIGN                              278
-
-/*
- * SM2 reason codes.
- */
-# define SM2_R_ASN1_ERROR                                 115
-# define SM2_R_ASN5_ERROR                                 1150
-# define SM2_R_BAD_SIGNATURE                              156
-# define SM2_R_BIGNUM_OUT_OF_RANGE                        144
-# define SM2_R_BUFFER_TOO_SMALL                           100
-# define SM2_R_COORDINATES_OUT_OF_RANGE                   146
-# define SM2_R_CURVE_DOES_NOT_SUPPORT_ECDH                160
-# define SM2_R_CURVE_DOES_NOT_SUPPORT_SIGNING             159
-# define SM2_R_D2I_ECPKPARAMETERS_FAILURE                 117
-# define SM2_R_DECODE_ERROR                               142
-# define SM2_R_DISCRIMINANT_IS_ZERO                       118
-# define SM2_R_EC_GROUP_NEW_BY_NAME_FAILURE               119
-# define SM2_R_FIELD_TOO_LARGE                            143
-# define SM2_R_GF2M_NOT_SUPPORTED                         147
-# define SM2_R_GROUP2PKPARAMETERS_FAILURE                 120
-# define SM2_R_I2D_ECPKPARAMETERS_FAILURE                 121
-# define SM2_R_INCOMPATIBLE_OBJECTS                       101
-# define SM2_R_INVALID_ARGUMENT                           112
-# define SM2_R_INVALID_COMPRESSED_POINT                   110
-# define SM2_R_INVALID_COMPRESSION_BIT                    109
-# define SM2_R_INVALID_CURVE                              141
-# define SM2_R_INVALID_DIGEST                             151
-# define SM2_R_INVALID_DIGEST_TYPE                        138
-# define SM2_R_INVALID_ENCODING                           102
-# define SM2_R_INVALID_FIELD                              103
-# define SM2_R_INVALID_FORM                               104
-# define SM2_R_INVALID_GROUP_ORDER                        122
-# define SM2_R_INVALID_KEY                                116
-# define SM2_R_INVALID_OUTPUT_LENGTH                      161
-# define SM2_R_INVALID_PEER_KEY                           133
-# define SM2_R_INVALID_PENTANOMIAL_BASIS                  132
-# define SM2_R_INVALID_PRIVATE_KEY                        123
-# define SM2_R_INVALID_TRINOMIAL_BASIS                    137
-# define SM2_R_KDF_PARAMETER_ERROR                        148
-# define SM2_R_KEYS_NOT_SET                               140
-# define SM2_R_MISSING_PARAMETERS                         124
-# define SM2_R_MISSING_PRIVATE_KEY                        125
-# define SM2_R_NEED_NEW_SETUP_VALUES                      157
-# define SM2_R_NOT_A_NIST_PRIME                           135
-# define SM2_R_NOT_IMPLEMENTED                            126
-# define SM2_R_NOT_INITIALIZED                            111
-# define SM2_R_NO_PARAMETERS_SET                          139
-# define SM2_R_NO_PRIVATE_VALUE                           154
-# define SM2_R_OPERATION_NOT_SUPPORTED                    152
-# define SM2_R_PASSED_NULL_PARAMETER                      134
-# define SM2_R_PEER_KEY_ERROR                             149
-# define SM2_R_PKPARAMETERS2GROUP_FAILURE                 127
-# define SM2_R_POINT_ARITHMETIC_FAILURE                   155
-# define SM2_R_POINT_AT_INFINITY                          106
-# define SM2_R_POINT_IS_NOT_ON_CURVE                      107
-# define SM2_R_RANDOM_NUMBER_GENERATION_FAILED            158
-# define SM2_R_SHARED_INFO_ERROR                          150
-# define SM2_R_SLOT_FULL                                  108
-# define SM2_R_UNDEFINED_GENERATOR                        113
-# define SM2_R_UNDEFINED_ORDER                            128
-# define SM2_R_UNKNOWN_GROUP                              129
-# define SM2_R_UNKNOWN_ORDER                              114
-# define SM2_R_UNSUPPORTED_FIELD                          131
-# define SM2_R_WRONG_CURVE_PARAMETERS                     145
-# define SM2_R_WRONG_ORDER                                130
-
-#endif
diff --git a/test/build.info b/test/build.info
index 000153d..9fe511a 100644
--- a/test/build.info
+++ b/test/build.info
@@ -28,7 +28,6 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
           aborttest test_test \
           sanitytest exdatatest bntest \
           ectest ecstresstest ecdsatest gmdifftest pbelutest ideatest \
-          sm2sigtest sm2crypttest \
           md2test \
           hmactest \
           rc2test rc4test rc5test \
@@ -89,14 +88,6 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
   INCLUDE[ecdsatest]=../include
   DEPEND[ecdsatest]=../libcrypto libtestutil.a
 
-  SOURCE[sm2sigtest]=sm2sigtest.c
-  INCLUDE[sm2sigtest]=../include
-  DEPEND[sm2sigtest]=../libcrypto libtestutil.a
-
-  SOURCE[sm2crypttest]=sm2crypttest.c
-  INCLUDE[sm2crypttest]=../include
-  DEPEND[sm2crypttest]=../libcrypto libtestutil.a
-
   SOURCE[gmdifftest]=gmdifftest.c
   INCLUDE[gmdifftest]=../include
   DEPEND[gmdifftest]=../libcrypto libtestutil.a
@@ -448,6 +439,9 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
     IF[{- !$disabled{siphash} -}]
       PROGRAMS_NO_INST=siphash_internal_test
     ENDIF
+    IF[{- !$disabled{sm2} -}]
+      PROGRAMS_NO_INST=sm2_internal_test
+    ENDIF
     IF[{- !$disabled{sm4} -}]
       PROGRAMS_NO_INST=sm4_internal_test
     ENDIF
@@ -491,6 +485,10 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
     INCLUDE[siphash_internal_test]=.. ../include ../crypto/include
     DEPEND[siphash_internal_test]=../libcrypto.a libtestutil.a
 
+    SOURCE[sm2_internal_test]=sm2_internal_test.c
+    INCLUDE[sm2_internal_test]=../include ../crypto/include
+    DEPEND[sm2_internal_test]=../libcrypto.a libtestutil.a
+
     SOURCE[sm4_internal_test]=sm4_internal_test.c
     INCLUDE[sm4_internal_test]=.. ../include ../crypto/include
     DEPEND[sm4_internal_test]=../libcrypto.a libtestutil.a
diff --git a/test/recipes/03-test_internal_sm4.t b/test/recipes/03-test_internal_sm2.t
similarity index 77%
copy from test/recipes/03-test_internal_sm4.t
copy to test/recipes/03-test_internal_sm2.t
index 459d83c..b93716e 100644
--- a/test/recipes/03-test_internal_sm4.t
+++ b/test/recipes/03-test_internal_sm2.t
@@ -1,6 +1,5 @@
 #! /usr/bin/env perl
 # Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
-# Copyright 2017 [Ribose Inc.](https://www.ribose.com). 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
@@ -12,9 +11,9 @@ use OpenSSL::Test;              # get 'plan'
 use OpenSSL::Test::Simple;
 use OpenSSL::Test::Utils;
 
-setup("test_internal_sm4");
+setup("test_internal_sm2");
 
 plan skip_all => "This test is unsupported in a shared library build on Windows"
     if $^O eq 'MSWin32' && !disabled("shared");
 
-simple_test("test_internal_sm4", "sm4_internal_test", "sm4");
+simple_test("test_internal_sm2", "sm2_internal_test", "sm2");
diff --git a/test/sm2_internal_test.c b/test/sm2_internal_test.c
new file mode 100644
index 0000000..4ae7303
--- /dev/null
+++ b/test/sm2_internal_test.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright 2017-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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include "testutil.h"
+
+#ifndef OPENSSL_NO_SM2
+
+# include "internal/sm2.h"
+
+static RAND_METHOD fake_rand;
+static const RAND_METHOD *saved_rand;
+
+static uint8_t *fake_rand_bytes = NULL;
+static size_t fake_rand_bytes_offset = 0;
+
+static int get_faked_bytes(unsigned char *buf, int num)
+{
+    int i;
+
+    if (fake_rand_bytes == NULL)
+        return saved_rand->bytes(buf, num);
+
+    for (i = 0; i != num; ++i)
+        buf[i] = fake_rand_bytes[fake_rand_bytes_offset + i];
+    fake_rand_bytes_offset += num;
+    return 1;
+}
+
+static int start_fake_rand(const char *hex_bytes)
+{
+    /* save old rand method */
+    if (!TEST_ptr(saved_rand = RAND_get_rand_method()))
+        return 0;
+
+    fake_rand = *saved_rand;
+    /* use own random function */
+    fake_rand.bytes = get_faked_bytes;
+
+    fake_rand_bytes = OPENSSL_hexstr2buf(hex_bytes, NULL);
+    fake_rand_bytes_offset = 0;
+
+    /* set new RAND_METHOD */
+    if (!TEST_true(RAND_set_rand_method(&fake_rand)))
+        return 0;
+    return 1;
+}
+
+static int restore_rand(void)
+{
+    OPENSSL_free(fake_rand_bytes);
+    fake_rand_bytes = NULL;
+    fake_rand_bytes_offset = 0;
+    if (!TEST_true(RAND_set_rand_method(saved_rand)))
+        return 0;
+    return 1;
+}
+
+static EC_GROUP *create_EC_group(const char *p_hex, const char *a_hex,
+                                 const char *b_hex, const char *x_hex,
+                                 const char *y_hex, const char *order_hex,
+                                 const char *cof_hex)
+{
+    BIGNUM *p = NULL;
+    BIGNUM *a = NULL;
+    BIGNUM *b = NULL;
+    BIGNUM *g_x = NULL;
+    BIGNUM *g_y = NULL;
+    BIGNUM *order = NULL;
+    BIGNUM *cof = NULL;
+    EC_POINT *generator = NULL;
+    EC_GROUP *group = NULL;
+    int ok = 0;
+
+    if (!TEST_true(BN_hex2bn(&p, p_hex))
+            || !TEST_true(BN_hex2bn(&a, a_hex))
+            || !TEST_true(BN_hex2bn(&b, b_hex)))
+        goto done;
+
+    group = EC_GROUP_new_curve_GFp(p, a, b, NULL);
+    if (!TEST_ptr(group))
+        goto done;
+
+    generator = EC_POINT_new(group);
+    if (!TEST_ptr(generator))
+        goto done;
+
+    if (!TEST_true(BN_hex2bn(&g_x, x_hex))
+            || !TEST_true(BN_hex2bn(&g_y, y_hex))
+            || !TEST_true(EC_POINT_set_affine_coordinates_GFp(group, generator,
+                                                              g_x, g_y, NULL)))
+        goto done;
+
+    if (!TEST_true(BN_hex2bn(&order, order_hex))
+            || !TEST_true(BN_hex2bn(&cof, cof_hex))
+            || !TEST_true(EC_GROUP_set_generator(group, generator, order, cof)))
+        goto done;
+
+    ok = 1;
+done:
+    BN_free(p);
+    BN_free(a);
+    BN_free(b);
+    BN_free(g_x);
+    BN_free(g_y);
+    EC_POINT_free(generator);
+    BN_free(order);
+    BN_free(cof);
+    if (!ok) {
+        EC_GROUP_free(group);
+        group = NULL;
+    }
+
+    return group;
+}
+
+static int test_sm2_crypt(const EC_GROUP *group,
+                          const EVP_MD *digest,
+                          const char *privkey_hex,
+                          const char *message,
+                          const char *k_hex, const char *ctext_hex)
+{
+    const size_t msg_len = strlen(message);
+    BIGNUM *priv = NULL;
+    EC_KEY *key = NULL;
+    EC_POINT *pt = NULL;
+    unsigned char *expected = OPENSSL_hexstr2buf(ctext_hex, NULL);
+    size_t ctext_len = 0;
+    size_t ptext_len = 0;
+    uint8_t *ctext = NULL;
+    uint8_t *recovered = NULL;
+    size_t recovered_len = msg_len;
+    int rc = 0;
+
+    if (!TEST_ptr(expected)
+            || !TEST_true(BN_hex2bn(&priv, privkey_hex)))
+        goto done;
+
+    key = EC_KEY_new();
+    if (!TEST_ptr(key)
+            || !TEST_true(EC_KEY_set_group(key, group))
+            || !TEST_true(EC_KEY_set_private_key(key, priv)))
+        goto done;
+
+    pt = EC_POINT_new(group);
+    if (!TEST_ptr(pt)
+            || !TEST_true(EC_POINT_mul(group, pt, priv, NULL, NULL, NULL))
+            || !TEST_true(EC_KEY_set_public_key(key, pt))
+            || !TEST_true(sm2_ciphertext_size(key, digest, msg_len, &ctext_len)))
+        goto done;
+
+    ctext = OPENSSL_zalloc(ctext_len);
+    if (!TEST_ptr(ctext))
+        goto done;
+
+    start_fake_rand(k_hex);
+    if (!TEST_true(sm2_encrypt(key, digest, (const uint8_t *)message, msg_len,
+                               ctext, &ctext_len))) {
+        restore_rand();
+        goto done;
+    }
+    restore_rand();
+
+    if (!TEST_mem_eq(ctext, ctext_len, expected, ctext_len))
+        goto done;
+
+    if (!TEST_true(sm2_plaintext_size(key, digest, ctext_len, &ptext_len))
+            || !TEST_int_eq(ptext_len, msg_len))
+        goto done;
+
+    recovered = OPENSSL_zalloc(ptext_len);
+    if (!TEST_ptr(recovered)
+            || !TEST_true(sm2_decrypt(key, digest, ctext, ctext_len, recovered, &recovered_len))
+            || !TEST_int_eq(recovered_len, msg_len)
+            || !TEST_mem_eq(recovered, recovered_len, message, msg_len))
+        goto done;
+
+    rc = 1;
+ done:
+    BN_free(priv);
+    EC_POINT_free(pt);
+    OPENSSL_free(ctext);
+    OPENSSL_free(recovered);
+    OPENSSL_free(expected);
+    EC_KEY_free(key);
+    return rc;
+}
+
+static int sm2_crypt_test(void)
+{
+    int testresult = 1;
+    EC_GROUP *test_group =
+        create_EC_group
+        ("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3",
+         "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498",
+         "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A",
+         "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D",
+         "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2",
+         "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7",
+         "1");
+
+    if (!TEST_ptr(test_group))
+        goto done;
+
+    if (!test_sm2_crypt(
+            test_group,
+            EVP_sm3(),
+            "1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0",
+            "encryption standard",
+            "004C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F",
+            "307B0220245C26FB68B1DDDDB12C4B6BF9F2B6D5FE60A383B0D18D1C4144ABF1"
+            "7F6252E7022076CB9264C2A7E88E52B19903FDC47378F605E36811F5C07423A2"
+            "4B84400F01B804209C3D7360C30156FAB7C80A0276712DA9D8094A634B766D3A"
+            "285E07480653426D0413650053A89B41C418B0C3AAD00D886C00286467"))
+        goto done;
+
+    /* Same test as above except using SHA-256 instead of SM3 */
+    if (!test_sm2_crypt(
+            test_group,
+            EVP_sha256(),
+            "1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0",
+            "encryption standard",
+            "004C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F",
+            "307B0220245C26FB68B1DDDDB12C4B6BF9F2B6D5FE60A383B0D18D1C4144ABF17F"
+            "6252E7022076CB9264C2A7E88E52B19903FDC47378F605E36811F5C07423A24B84"
+            "400F01B80420BE89139D07853100EFA763F60CBE30099EA3DF7F8F364F9D10A5E9"
+            "88E3C5AAFC0413229E6C9AEE2BB92CAD649FE2C035689785DA33"))
+        goto done;
+
+    testresult = 1;
+ done:
+    EC_GROUP_free(test_group);
+
+    return testresult;
+}
+
+static int test_sm2_sign(const EC_GROUP *group,
+                         const char *userid,
+                         const char *privkey_hex,
+                         const char *message,
+                         const char *k_hex,
+                         const char *r_hex,
+                         const char *s_hex)
+{
+    const size_t msg_len = strlen(message);
+    int ok = 0;
+    BIGNUM *priv = NULL;
+    EC_POINT *pt = NULL;
+    EC_KEY *key = NULL;
+    ECDSA_SIG *sig = NULL;
+    const BIGNUM *sig_r = NULL;
+    const BIGNUM *sig_s = NULL;
+    BIGNUM *r = NULL;
+    BIGNUM *s = NULL;
+
+    if (!TEST_true(BN_hex2bn(&priv, privkey_hex)))
+        goto done;
+
+    key = EC_KEY_new();
+    if (!TEST_ptr(key)
+            || !TEST_true(EC_KEY_set_group(key, group))
+            || !TEST_true(EC_KEY_set_private_key(key, priv)))
+        goto done;
+
+    pt = EC_POINT_new(group);
+    if (!TEST_ptr(pt)
+            || !TEST_true(EC_POINT_mul(group, pt, priv, NULL, NULL, NULL))
+            || !TEST_true(EC_KEY_set_public_key(key, pt)))
+        goto done;
+
+    start_fake_rand(k_hex);
+    sig = sm2_do_sign(key, EVP_sm3(), userid, (const uint8_t *)message, msg_len);
+    restore_rand();
+
+    if (!TEST_ptr(sig))
+        goto done;
+
+    ECDSA_SIG_get0(sig, &sig_r, &sig_s);
+
+    if (!TEST_true(BN_hex2bn(&r, r_hex))
+            || !TEST_true(BN_hex2bn(&s, s_hex))
+            || !TEST_BN_eq(r, sig_r)
+            || !TEST_BN_eq(s, sig_s))
+        goto done;
+
+    ok = sm2_do_verify(key, EVP_sm3(), sig, userid, (const uint8_t *)message,
+                       msg_len);
+
+    /* We goto done whether this passes or fails */
+    TEST_true(ok);
+
+ done:
+    ECDSA_SIG_free(sig);
+    EC_POINT_free(pt);
+    EC_KEY_free(key);
+    BN_free(priv);
+    BN_free(r);
+    BN_free(s);
+
+    return ok;
+}
+
+static int sm2_sig_test(void)
+{
+    int testresult = 0;
+    /* From draft-shen-sm2-ecdsa-02 */
+    EC_GROUP *test_group =
+        create_EC_group
+        ("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3",
+         "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498",
+         "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A",
+         "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D",
+         "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2",
+         "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7",
+         "1");
+
+    if (!TEST_ptr(test_group))
+        goto done;
+
+    if (!TEST_true(test_sm2_sign(
+                        test_group,
+                        "ALICE123 at YAHOO.COM",
+                        "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263",
+                        "message digest",
+                        "006CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F",
+                        "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1",
+                        "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7")))
+        goto done;
+
+    testresult = 1;
+
+ done:
+    EC_GROUP_free(test_group);
+
+    return testresult;
+}
+
+#endif
+
+int setup_tests(void)
+{
+#ifdef OPENSSL_NO_SM2
+    TEST_note("SM2 is disabled.");
+#else
+    ADD_TEST(sm2_crypt_test);
+    ADD_TEST(sm2_sig_test);
+#endif
+    return 1;
+}
diff --git a/test/sm2crypttest.c b/test/sm2crypttest.c
deleted file mode 100644
index cd72cb0..0000000
--- a/test/sm2crypttest.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright 2017-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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <openssl/bio.h>
-#include <openssl/evp.h>
-#include <openssl/bn.h>
-#include <openssl/crypto.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-#include "testutil.h"
-
-#ifndef OPENSSL_NO_SM2
-
-# include <openssl/sm2.h>
-
-static RAND_METHOD fake_rand;
-static const RAND_METHOD *saved_rand;
-
-static uint8_t *fake_rand_bytes = NULL;
-static size_t fake_rand_bytes_offset = 0;
-
-static int get_faked_bytes(unsigned char *buf, int num)
-{
-    int i;
-
-    if (fake_rand_bytes == NULL)
-        return saved_rand->bytes(buf, num);
-
-    for (i = 0; i != num; ++i)
-        buf[i] = fake_rand_bytes[fake_rand_bytes_offset + i];
-    fake_rand_bytes_offset += num;
-    return 1;
-}
-
-static int start_fake_rand(const char *hex_bytes)
-{
-    /* save old rand method */
-    if (!TEST_ptr(saved_rand = RAND_get_rand_method()))
-        return 0;
-
-    fake_rand = *saved_rand;
-    /* use own random function */
-    fake_rand.bytes = get_faked_bytes;
-
-    fake_rand_bytes = OPENSSL_hexstr2buf(hex_bytes, NULL);
-    fake_rand_bytes_offset = 0;
-
-    /* set new RAND_METHOD */
-    if (!TEST_true(RAND_set_rand_method(&fake_rand)))
-        return 0;
-    return 1;
-}
-
-static int restore_rand(void)
-{
-    OPENSSL_free(fake_rand_bytes);
-    fake_rand_bytes = NULL;
-    fake_rand_bytes_offset = 0;
-    if (!TEST_true(RAND_set_rand_method(saved_rand)))
-        return 0;
-    return 1;
-}
-
-static EC_GROUP *create_EC_group(const char *p_hex, const char *a_hex,
-                                 const char *b_hex, const char *x_hex,
-                                 const char *y_hex, const char *order_hex,
-                                 const char *cof_hex)
-{
-    BIGNUM *p = NULL;
-    BIGNUM *a = NULL;
-    BIGNUM *b = NULL;
-    BIGNUM *g_x = NULL;
-    BIGNUM *g_y = NULL;
-    BIGNUM *order = NULL;
-    BIGNUM *cof = NULL;
-    EC_POINT *generator = NULL;
-    EC_GROUP *group = NULL;
-
-    BN_hex2bn(&p, p_hex);
-    BN_hex2bn(&a, a_hex);
-    BN_hex2bn(&b, b_hex);
-
-    group = EC_GROUP_new_curve_GFp(p, a, b, NULL);
-    BN_free(p);
-    BN_free(a);
-    BN_free(b);
-
-    if (group == NULL)
-        return NULL;
-
-    generator = EC_POINT_new(group);
-    if (generator == NULL)
-        return NULL;
-
-    BN_hex2bn(&g_x, x_hex);
-    BN_hex2bn(&g_y, y_hex);
-
-    if (EC_POINT_set_affine_coordinates_GFp(group, generator, g_x, g_y, NULL) ==
-        0)
-        return NULL;
-
-    BN_free(g_x);
-    BN_free(g_y);
-
-    BN_hex2bn(&order, order_hex);
-    BN_hex2bn(&cof, cof_hex);
-
-    if (EC_GROUP_set_generator(group, generator, order, cof) == 0)
-        return NULL;
-
-    EC_POINT_free(generator);
-    BN_free(order);
-    BN_free(cof);
-
-    return group;
-}
-
-static int test_sm2(const EC_GROUP *group,
-                    const EVP_MD *digest,
-                    const char *privkey_hex,
-                    const char *message,
-                    const char *k_hex, const char *ctext_hex)
-{
-    const size_t msg_len = strlen(message);
-
-    BIGNUM *priv = NULL;
-    EC_KEY *key = NULL;
-    EC_POINT *pt = NULL;
-    unsigned char *expected = OPENSSL_hexstr2buf(ctext_hex, NULL);
-
-    size_t ctext_len = 0;
-    size_t ptext_len = 0;
-    uint8_t *ctext = NULL;
-    uint8_t *recovered = NULL;
-    size_t recovered_len = msg_len;
-
-    int rc = 0;
-
-    BN_hex2bn(&priv, privkey_hex);
-
-    key = EC_KEY_new();
-    EC_KEY_set_group(key, group);
-    EC_KEY_set_private_key(key, priv);
-
-    pt = EC_POINT_new(group);
-    EC_POINT_mul(group, pt, priv, NULL, NULL, NULL);
-
-    EC_KEY_set_public_key(key, pt);
-    BN_free(priv);
-    EC_POINT_free(pt);
-
-    ctext_len = SM2_ciphertext_size(key, digest, msg_len);
-    ctext = OPENSSL_zalloc(ctext_len);
-    if (ctext == NULL)
-        goto done;
-
-    start_fake_rand(k_hex);
-    rc = SM2_encrypt(key, digest,
-                     (const uint8_t *)message, msg_len, ctext, &ctext_len);
-    restore_rand();
-
-    TEST_mem_eq(ctext, ctext_len, expected, ctext_len);
-    if (rc == 0)
-        goto done;
-
-    ptext_len = SM2_plaintext_size(key, digest, ctext_len);
-
-    TEST_int_eq(ptext_len, msg_len);
-
-    recovered = OPENSSL_zalloc(ptext_len);
-    if (recovered == NULL)
-        goto done;
-    rc = SM2_decrypt(key, digest, ctext, ctext_len, recovered, &recovered_len);
-
-    TEST_int_eq(recovered_len, msg_len);
-    TEST_mem_eq(recovered, recovered_len, message, msg_len);
-    if (rc == 0)
-        return 0;
-
-    rc = 1;
- done:
-
-    OPENSSL_free(ctext);
-    OPENSSL_free(recovered);
-    OPENSSL_free(expected);
-    EC_KEY_free(key);
-    return rc;
-}
-
-static int sm2_crypt_test(void)
-{
-    int rc;
-    EC_GROUP *test_group =
-        create_EC_group
-        ("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3",
-         "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498",
-         "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A",
-         "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D",
-         "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2",
-         "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7",
-         "1");
-
-    if (test_group == NULL)
-        return 0;
-
-    rc = test_sm2(test_group,
-                  EVP_sm3(),
-                  "1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0",
-                  "encryption standard",
-                  "004C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F",
-                  "307B0220245C26FB68B1DDDDB12C4B6BF9F2B6D5FE60A383B0D18D1C4144ABF1"
-                  "7F6252E7022076CB9264C2A7E88E52B19903FDC47378F605E36811F5C07423A2"
-                  "4B84400F01B804209C3D7360C30156FAB7C80A0276712DA9D8094A634B766D3A"
-                  "285E07480653426D0413650053A89B41C418B0C3AAD00D886C00286467");
-
-    if (rc == 0)
-        return 0;
-
-    /* Same test as above except using SHA-256 instead of SM3 */
-    rc = test_sm2(test_group,
-                  EVP_sha256(),
-                  "1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0",
-                  "encryption standard",
-                  "004C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F",
-                  "307B0220245C26FB68B1DDDDB12C4B6BF9F2B6D5FE60A383B0D18D1C4144ABF17F6252E7022076CB9264C2A7E88E52B19903FDC47378F605E36811F5C07423A24B84400F01B80420BE89139D07853100EFA763F60CBE30099EA3DF7F8F364F9D10A5E988E3C5AAFC0413229E6C9AEE2BB92CAD649FE2C035689785DA33");
-    if (rc == 0)
-        return 0;
-
-    EC_GROUP_free(test_group);
-
-    return 1;
-}
-
-#endif
-
-int setup_tests(void)
-{
-#ifdef OPENSSL_NO_SM2
-    TEST_note("SM2 is disabled.");
-#else
-    ADD_TEST(sm2_crypt_test);
-#endif
-    return 1;
-}
diff --git a/test/sm2sigtest.c b/test/sm2sigtest.c
deleted file mode 100644
index 33be783..0000000
--- a/test/sm2sigtest.c
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved.
- * Copyright 2017 Ribose Inc. 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
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <openssl/bio.h>
-#include <openssl/evp.h>
-#include <openssl/bn.h>
-#include <openssl/crypto.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-#include "testutil.h"
-
-#ifndef OPENSSL_NO_SM2
-
-# include <openssl/sm2.h>
-
-static RAND_METHOD fake_rand;
-static const RAND_METHOD *saved_rand;
-
-static uint8_t *fake_rand_bytes = NULL;
-static size_t fake_rand_bytes_offset = 0;
-
-static int get_faked_bytes(unsigned char *buf, int num)
-{
-    int i;
-
-    if (fake_rand_bytes == NULL)
-        return saved_rand->bytes(buf, num);
-
-    for (i = 0; i != num; ++i)
-        buf[i] = fake_rand_bytes[fake_rand_bytes_offset + i];
-    fake_rand_bytes_offset += num;
-    return 1;
-}
-
-static int start_fake_rand(const char *hex_bytes)
-{
-    /* save old rand method */
-    if (!TEST_ptr(saved_rand = RAND_get_rand_method()))
-        return 0;
-
-    fake_rand = *saved_rand;
-    /* use own random function */
-    fake_rand.bytes = get_faked_bytes;
-
-    fake_rand_bytes = OPENSSL_hexstr2buf(hex_bytes, NULL);
-    fake_rand_bytes_offset = 0;
-
-    /* set new RAND_METHOD */
-    if (!TEST_true(RAND_set_rand_method(&fake_rand)))
-        return 0;
-    return 1;
-}
-
-static int restore_rand(void)
-{
-    OPENSSL_free(fake_rand_bytes);
-    fake_rand_bytes = NULL;
-    fake_rand_bytes_offset = 0;
-    if (!TEST_true(RAND_set_rand_method(saved_rand)))
-        return 0;
-    return 1;
-}
-
-static EC_GROUP *create_EC_group(const char *p_hex, const char *a_hex,
-                                 const char *b_hex, const char *x_hex,
-                                 const char *y_hex, const char *order_hex,
-                                 const char *cof_hex)
-{
-    BIGNUM *p = NULL;
-    BIGNUM *a = NULL;
-    BIGNUM *b = NULL;
-    BIGNUM *g_x = NULL;
-    BIGNUM *g_y = NULL;
-    BIGNUM *order = NULL;
-    BIGNUM *cof = NULL;
-    EC_POINT *generator = NULL;
-    EC_GROUP *group = NULL;
-
-    BN_hex2bn(&p, p_hex);
-    BN_hex2bn(&a, a_hex);
-    BN_hex2bn(&b, b_hex);
-
-    group = EC_GROUP_new_curve_GFp(p, a, b, NULL);
-    BN_free(p);
-    BN_free(a);
-    BN_free(b);
-
-    if (group == NULL)
-        return NULL;
-
-    generator = EC_POINT_new(group);
-    if (generator == NULL)
-        return NULL;
-
-    BN_hex2bn(&g_x, x_hex);
-    BN_hex2bn(&g_y, y_hex);
-
-    if (EC_POINT_set_affine_coordinates_GFp(group, generator, g_x, g_y, NULL) ==
-        0)
-        return NULL;
-
-    BN_free(g_x);
-    BN_free(g_y);
-
-    BN_hex2bn(&order, order_hex);
-    BN_hex2bn(&cof, cof_hex);
-
-    if (EC_GROUP_set_generator(group, generator, order, cof) == 0)
-        return NULL;
-
-    EC_POINT_free(generator);
-    BN_free(order);
-    BN_free(cof);
-
-    return group;
-}
-
-
-static int test_sm2(const EC_GROUP *group,
-                    const char *userid,
-                    const char *privkey_hex,
-                    const char *message,
-                    const char *k_hex, const char *r_hex, const char *s_hex)
-{
-    const size_t msg_len = strlen(message);
-    int ok = -1;
-    BIGNUM *priv = NULL;
-    EC_POINT *pt = NULL;
-    EC_KEY *key = NULL;
-    ECDSA_SIG *sig = NULL;
-    const BIGNUM *sig_r = NULL;
-    const BIGNUM *sig_s = NULL;
-    BIGNUM *r = NULL;
-    BIGNUM *s = NULL;
-
-    BN_hex2bn(&priv, privkey_hex);
-
-    key = EC_KEY_new();
-    EC_KEY_set_group(key, group);
-    EC_KEY_set_private_key(key, priv);
-
-    pt = EC_POINT_new(group);
-    EC_POINT_mul(group, pt, priv, NULL, NULL, NULL);
-    EC_KEY_set_public_key(key, pt);
-
-    start_fake_rand(k_hex);
-    sig = SM2_do_sign(key, EVP_sm3(), userid, (const uint8_t *)message, msg_len);
-    restore_rand();
-
-    if (sig == NULL)
-        return 0;
-
-    ECDSA_SIG_get0(sig, &sig_r, &sig_s);
-
-    BN_hex2bn(&r, r_hex);
-    BN_hex2bn(&s, s_hex);
-
-    if (BN_cmp(r, sig_r) != 0) {
-        printf("Signature R mismatch: ");
-        BN_print_fp(stdout, r);
-        printf(" != ");
-        BN_print_fp(stdout, sig_r);
-        printf("\n");
-        ok = 0;
-    }
-    if (BN_cmp(s, sig_s) != 0) {
-        printf("Signature S mismatch: ");
-        BN_print_fp(stdout, s);
-        printf(" != ");
-        BN_print_fp(stdout, sig_s);
-        printf("\n");
-        ok = 0;
-    }
-
-    ok = SM2_do_verify(key, EVP_sm3(), sig, userid, (const uint8_t *)message, msg_len);
-
-    ECDSA_SIG_free(sig);
-    EC_POINT_free(pt);
-    EC_KEY_free(key);
-    BN_free(priv);
-    BN_free(r);
-    BN_free(s);
-
-    return ok;
-}
-
-static int sm2_sig_test(void)
-{
-    int rc = 0;
-    /* From draft-shen-sm2-ecdsa-02 */
-    EC_GROUP *test_group =
-        create_EC_group
-        ("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3",
-         "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498",
-         "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A",
-         "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D",
-         "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2",
-         "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7",
-         "1");
-
-    if (test_group == NULL)
-        return 0;
-
-    rc = test_sm2(test_group,
-                    "ALICE123 at YAHOO.COM",
-                    "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263",
-                    "message digest",
-                    "006CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F",
-                    "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1",
-                    "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7");
-
-    EC_GROUP_free(test_group);
-
-    return rc;
-}
-
-#endif
-
-int setup_tests(void)
-{
-#ifdef OPENSSL_NO_SM2
-    TEST_note("SM2 is disabled.");
-#else
-    ADD_TEST(sm2_sig_test);
-#endif
-    return 1;
-}
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 9d6653c..a810755 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4514,16 +4514,6 @@ EVP_PKEY_new_CMAC_key                   4455	1_1_1	EXIST::FUNCTION:
 EVP_PKEY_asn1_set_set_priv_key          4456	1_1_1	EXIST::FUNCTION:
 EVP_PKEY_asn1_set_set_pub_key           4457	1_1_1	EXIST::FUNCTION:
 RAND_DRBG_set_defaults                  4458	1_1_1	EXIST::FUNCTION:
-SM2_decrypt                             4459	1_1_1	EXIST::FUNCTION:SM2
-SM2_do_sign                             4460	1_1_1	EXIST::FUNCTION:SM2
-SM2_compute_userid_digest               4461	1_1_1	EXIST::FUNCTION:SM2
-SM2_encrypt                             4462	1_1_1	EXIST::FUNCTION:SM2
-SM2_ciphertext_size                     4463	1_1_1	EXIST::FUNCTION:SM2
-SM2_verify                              4464	1_1_1	EXIST::FUNCTION:SM2
-SM2_do_verify                           4465	1_1_1	EXIST::FUNCTION:SM2
-SM2_sign                                4466	1_1_1	EXIST::FUNCTION:SM2
-ERR_load_SM2_strings                    4467	1_1_1	EXIST::FUNCTION:SM2
-SM2_plaintext_size                      4468	1_1_1	EXIST::FUNCTION:SM2
 conf_ssl_name_find                      4469	1_1_0i	EXIST::FUNCTION:
 conf_ssl_get_cmd                        4470	1_1_0i	EXIST::FUNCTION:
 conf_ssl_get                            4471	1_1_0i	EXIST::FUNCTION:


More information about the openssl-commits mailing list