aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/openssl/crypto/sm2
diff options
context:
space:
mode:
authordeshevoy <deshevoy@yandex-team.ru>2022-02-10 16:46:57 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:46:57 +0300
commit28148f76dbfcc644d96427d41c92f36cbf2fdc6e (patch)
treeb83306b6e37edeea782e9eed673d89286c4fef35 /contrib/libs/openssl/crypto/sm2
parente988f30484abe5fdeedcc7a5d3c226c01a21800c (diff)
downloadydb-28148f76dbfcc644d96427d41c92f36cbf2fdc6e.tar.gz
Restoring authorship annotation for <deshevoy@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/openssl/crypto/sm2')
-rw-r--r--contrib/libs/openssl/crypto/sm2/sm2_crypt.c746
-rw-r--r--contrib/libs/openssl/crypto/sm2/sm2_err.c136
-rw-r--r--contrib/libs/openssl/crypto/sm2/sm2_pmeth.c640
-rw-r--r--contrib/libs/openssl/crypto/sm2/sm2_sign.c946
4 files changed, 1234 insertions, 1234 deletions
diff --git a/contrib/libs/openssl/crypto/sm2/sm2_crypt.c b/contrib/libs/openssl/crypto/sm2/sm2_crypt.c
index 6dc2c43704..83b97f4edc 100644
--- a/contrib/libs/openssl/crypto/sm2/sm2_crypt.c
+++ b/contrib/libs/openssl/crypto/sm2/sm2_crypt.c
@@ -1,388 +1,388 @@
-/*
+/*
* Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
- * Copyright 2017 Ribose Inc. All Rights Reserved.
- * Ported from Ribose contributions from Botan.
- *
- * 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
- */
-
+ * Copyright 2017 Ribose Inc. All Rights Reserved.
+ * Ported from Ribose contributions from Botan.
+ *
+ * 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 "crypto/sm2.h"
#include "crypto/sm2err.h"
#include "crypto/ec.h" /* ecdh_KDF_X9_63() */
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/bn.h>
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
-#include <string.h>
-
-typedef struct SM2_Ciphertext_st SM2_Ciphertext;
-DECLARE_ASN1_FUNCTIONS(SM2_Ciphertext)
-
-struct SM2_Ciphertext_st {
- BIGNUM *C1x;
- BIGNUM *C1y;
- ASN1_OCTET_STRING *C3;
- ASN1_OCTET_STRING *C2;
-};
-
-ASN1_SEQUENCE(SM2_Ciphertext) = {
- ASN1_SIMPLE(SM2_Ciphertext, C1x, BIGNUM),
- ASN1_SIMPLE(SM2_Ciphertext, C1y, BIGNUM),
- ASN1_SIMPLE(SM2_Ciphertext, C3, ASN1_OCTET_STRING),
- ASN1_SIMPLE(SM2_Ciphertext, C2, ASN1_OCTET_STRING),
-} ASN1_SEQUENCE_END(SM2_Ciphertext)
-
-IMPLEMENT_ASN1_FUNCTIONS(SM2_Ciphertext)
-
-static size_t ec_field_size(const EC_GROUP *group)
-{
- /* Is there some simpler way to do this? */
- BIGNUM *p = BN_new();
- BIGNUM *a = BN_new();
- BIGNUM *b = BN_new();
- size_t field_size = 0;
-
- if (p == NULL || a == NULL || b == NULL)
- goto done;
-
- if (!EC_GROUP_get_curve(group, p, a, b, NULL))
- goto done;
- field_size = (BN_num_bits(p) + 7) / 8;
-
- done:
- BN_free(p);
- BN_free(a);
- BN_free(b);
-
- return field_size;
-}
-
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <string.h>
+
+typedef struct SM2_Ciphertext_st SM2_Ciphertext;
+DECLARE_ASN1_FUNCTIONS(SM2_Ciphertext)
+
+struct SM2_Ciphertext_st {
+ BIGNUM *C1x;
+ BIGNUM *C1y;
+ ASN1_OCTET_STRING *C3;
+ ASN1_OCTET_STRING *C2;
+};
+
+ASN1_SEQUENCE(SM2_Ciphertext) = {
+ ASN1_SIMPLE(SM2_Ciphertext, C1x, BIGNUM),
+ ASN1_SIMPLE(SM2_Ciphertext, C1y, BIGNUM),
+ ASN1_SIMPLE(SM2_Ciphertext, C3, ASN1_OCTET_STRING),
+ ASN1_SIMPLE(SM2_Ciphertext, C2, ASN1_OCTET_STRING),
+} ASN1_SEQUENCE_END(SM2_Ciphertext)
+
+IMPLEMENT_ASN1_FUNCTIONS(SM2_Ciphertext)
+
+static size_t ec_field_size(const EC_GROUP *group)
+{
+ /* Is there some simpler way to do this? */
+ BIGNUM *p = BN_new();
+ BIGNUM *a = BN_new();
+ BIGNUM *b = BN_new();
+ size_t field_size = 0;
+
+ if (p == NULL || a == NULL || b == NULL)
+ goto done;
+
+ if (!EC_GROUP_get_curve(group, p, a, b, NULL))
+ goto done;
+ field_size = (BN_num_bits(p) + 7) / 8;
+
+ done:
+ BN_free(p);
+ BN_free(a);
+ BN_free(b);
+
+ return field_size;
+}
+
int sm2_plaintext_size(const unsigned char *ct, size_t ct_size, size_t *pt_size)
-{
+{
struct SM2_Ciphertext_st *sm2_ctext = NULL;
-
+
sm2_ctext = d2i_SM2_Ciphertext(NULL, &ct, ct_size);
-
+
if (sm2_ctext == NULL) {
- SM2err(SM2_F_SM2_PLAINTEXT_SIZE, SM2_R_INVALID_ENCODING);
- return 0;
- }
-
+ SM2err(SM2_F_SM2_PLAINTEXT_SIZE, SM2_R_INVALID_ENCODING);
+ return 0;
+ }
+
*pt_size = sm2_ctext->C2->length;
SM2_Ciphertext_free(sm2_ctext);
- return 1;
-}
-
-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 int md_size = EVP_MD_size(digest);
- size_t sz;
-
- if (field_size == 0 || md_size < 0)
- return 0;
-
- /* Integer and string are simple type; set constructed = 0, means primitive and definite length encoding. */
- sz = 2 * ASN1_object_size(0, field_size + 1, V_ASN1_INTEGER)
- + ASN1_object_size(0, md_size, V_ASN1_OCTET_STRING)
- + ASN1_object_size(0, msg_len, V_ASN1_OCTET_STRING);
- /* Sequence is structured type; set constructed = 1, means constructed and definite length encoding. */
- *ct_size = ASN1_object_size(1, sz, V_ASN1_SEQUENCE);
-
- return 1;
-}
-
-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, ciphertext_leni;
- size_t i;
- BN_CTX *ctx = NULL;
- BIGNUM *k = NULL;
- BIGNUM *x1 = NULL;
- 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);
- const EC_POINT *P = EC_KEY_get0_public_key(key);
- EC_POINT *kG = NULL;
- EC_POINT *kP = NULL;
- uint8_t *msg_mask = NULL;
- uint8_t *x2y2 = NULL;
- uint8_t *C3 = NULL;
- size_t field_size;
- const int C3_size = EVP_MD_size(digest);
-
- /* NULL these before any "goto done" */
- ctext_struct.C2 = NULL;
- ctext_struct.C3 = NULL;
-
- if (hash == NULL || C3_size <= 0) {
- SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
- goto done;
- }
-
- field_size = ec_field_size(group);
- if (field_size == 0) {
- SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
- goto done;
- }
-
- kG = EC_POINT_new(group);
- kP = EC_POINT_new(group);
- ctx = BN_CTX_new();
- 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);
- x1 = BN_CTX_get(ctx);
- x2 = BN_CTX_get(ctx);
- y1 = BN_CTX_get(ctx);
- y2 = BN_CTX_get(ctx);
-
- 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) {
- SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- memset(ciphertext_buf, 0, *ciphertext_len);
-
- if (!BN_priv_rand_range(k, order)) {
- SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
- goto done;
- }
-
- if (!EC_POINT_mul(group, kG, k, NULL, NULL, ctx)
- || !EC_POINT_get_affine_coordinates(group, kG, x1, y1, ctx)
- || !EC_POINT_mul(group, kP, NULL, P, k, ctx)
- || !EC_POINT_get_affine_coordinates(group, kP, x2, y2, ctx)) {
- SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EC_LIB);
- goto done;
- }
-
- 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;
- }
-
- msg_mask = OPENSSL_zalloc(msg_len);
- 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_63(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
- || 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();
- ctext_struct.C2 = ASN1_OCTET_STRING_new();
-
- 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;
- }
-
- 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);
- EVP_MD_CTX_free(hash);
- BN_CTX_free(ctx);
- EC_POINT_free(kG);
- EC_POINT_free(kP);
- return rc;
-}
-
-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 int hash_size = EVP_MD_size(digest);
- uint8_t *msg_mask = NULL;
- const uint8_t *C2 = NULL;
- const uint8_t *C3 = NULL;
- int msg_len = 0;
- EVP_MD_CTX *hash = NULL;
-
- if (field_size == 0 || hash_size <= 0)
- goto done;
-
- memset(ptext_buf, 0xFF, *ptext_len);
-
- sm2_ctext = d2i_SM2_Ciphertext(NULL, &ciphertext, ciphertext_len);
-
- if (sm2_ctext == NULL) {
- SM2err(SM2_F_SM2_DECRYPT, SM2_R_ASN1_ERROR);
- goto done;
- }
-
- 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;
+ return 1;
+}
+
+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 int md_size = EVP_MD_size(digest);
+ size_t sz;
+
+ if (field_size == 0 || md_size < 0)
+ return 0;
+
+ /* Integer and string are simple type; set constructed = 0, means primitive and definite length encoding. */
+ sz = 2 * ASN1_object_size(0, field_size + 1, V_ASN1_INTEGER)
+ + ASN1_object_size(0, md_size, V_ASN1_OCTET_STRING)
+ + ASN1_object_size(0, msg_len, V_ASN1_OCTET_STRING);
+ /* Sequence is structured type; set constructed = 1, means constructed and definite length encoding. */
+ *ct_size = ASN1_object_size(1, sz, V_ASN1_SEQUENCE);
+
+ return 1;
+}
+
+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, ciphertext_leni;
+ size_t i;
+ BN_CTX *ctx = NULL;
+ BIGNUM *k = NULL;
+ BIGNUM *x1 = NULL;
+ 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);
+ const EC_POINT *P = EC_KEY_get0_public_key(key);
+ EC_POINT *kG = NULL;
+ EC_POINT *kP = NULL;
+ uint8_t *msg_mask = NULL;
+ uint8_t *x2y2 = NULL;
+ uint8_t *C3 = NULL;
+ size_t field_size;
+ const int C3_size = EVP_MD_size(digest);
+
+ /* NULL these before any "goto done" */
+ ctext_struct.C2 = NULL;
+ ctext_struct.C3 = NULL;
+
+ if (hash == NULL || C3_size <= 0) {
+ SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
+ goto done;
+ }
+
+ field_size = ec_field_size(group);
+ if (field_size == 0) {
+ SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
+ goto done;
+ }
+
+ kG = EC_POINT_new(group);
+ kP = EC_POINT_new(group);
+ ctx = BN_CTX_new();
+ 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);
+ x1 = BN_CTX_get(ctx);
+ x2 = BN_CTX_get(ctx);
+ y1 = BN_CTX_get(ctx);
+ y2 = BN_CTX_get(ctx);
+
+ 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) {
+ SM2err(SM2_F_SM2_ENCRYPT, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ memset(ciphertext_buf, 0, *ciphertext_len);
+
+ if (!BN_priv_rand_range(k, order)) {
+ SM2err(SM2_F_SM2_ENCRYPT, ERR_R_INTERNAL_ERROR);
+ goto done;
+ }
+
+ if (!EC_POINT_mul(group, kG, k, NULL, NULL, ctx)
+ || !EC_POINT_get_affine_coordinates(group, kG, x1, y1, ctx)
+ || !EC_POINT_mul(group, kP, NULL, P, k, ctx)
+ || !EC_POINT_get_affine_coordinates(group, kP, x2, y2, ctx)) {
+ SM2err(SM2_F_SM2_ENCRYPT, ERR_R_EC_LIB);
+ goto done;
+ }
+
+ 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;
+ }
+
+ msg_mask = OPENSSL_zalloc(msg_len);
+ 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_63(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
+ || 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();
+ ctext_struct.C2 = ASN1_OCTET_STRING_new();
+
+ 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;
+ }
+
+ 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);
+ EVP_MD_CTX_free(hash);
+ BN_CTX_free(ctx);
+ EC_POINT_free(kG);
+ EC_POINT_free(kP);
+ return rc;
+}
+
+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 int hash_size = EVP_MD_size(digest);
+ uint8_t *msg_mask = NULL;
+ const uint8_t *C2 = NULL;
+ const uint8_t *C3 = NULL;
+ int msg_len = 0;
+ EVP_MD_CTX *hash = NULL;
+
+ if (field_size == 0 || hash_size <= 0)
+ goto done;
+
+ memset(ptext_buf, 0xFF, *ptext_len);
+
+ sm2_ctext = d2i_SM2_Ciphertext(NULL, &ciphertext, ciphertext_len);
+
+ if (sm2_ctext == NULL) {
+ SM2err(SM2_F_SM2_DECRYPT, SM2_R_ASN1_ERROR);
+ goto done;
+ }
+
+ 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;
if (*ptext_len < (size_t)msg_len) {
SM2err(SM2_F_SM2_DECRYPT, SM2_R_BUFFER_TOO_SMALL);
goto done;
}
-
- ctx = BN_CTX_new();
- 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) {
- 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) {
- SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- C1 = EC_POINT_new(group);
- if (C1 == NULL) {
- SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- if (!EC_POINT_set_affine_coordinates(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(group, C1, x2, y2, ctx)) {
- SM2err(SM2_F_SM2_DECRYPT, ERR_R_EC_LIB);
- goto done;
- }
-
- if (BN_bn2binpad(x2, x2y2, field_size) < 0
- || BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0
- || !ecdh_KDF_X9_63(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) {
- SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- 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 (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);
-
- OPENSSL_free(msg_mask);
- OPENSSL_free(x2y2);
- OPENSSL_free(computed_C3);
- EC_POINT_free(C1);
- BN_CTX_free(ctx);
- SM2_Ciphertext_free(sm2_ctext);
- EVP_MD_CTX_free(hash);
-
- return rc;
-}
+
+ ctx = BN_CTX_new();
+ 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) {
+ 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) {
+ SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ C1 = EC_POINT_new(group);
+ if (C1 == NULL) {
+ SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ if (!EC_POINT_set_affine_coordinates(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(group, C1, x2, y2, ctx)) {
+ SM2err(SM2_F_SM2_DECRYPT, ERR_R_EC_LIB);
+ goto done;
+ }
+
+ if (BN_bn2binpad(x2, x2y2, field_size) < 0
+ || BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0
+ || !ecdh_KDF_X9_63(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) {
+ SM2err(SM2_F_SM2_DECRYPT, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ 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 (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);
+
+ OPENSSL_free(msg_mask);
+ OPENSSL_free(x2y2);
+ OPENSSL_free(computed_C3);
+ EC_POINT_free(C1);
+ BN_CTX_free(ctx);
+ SM2_Ciphertext_free(sm2_ctext);
+ EVP_MD_CTX_free(hash);
+
+ return rc;
+}
diff --git a/contrib/libs/openssl/crypto/sm2/sm2_err.c b/contrib/libs/openssl/crypto/sm2/sm2_err.c
index 8d20112c74..e5973e9c71 100644
--- a/contrib/libs/openssl/crypto/sm2/sm2_err.c
+++ b/contrib/libs/openssl/crypto/sm2/sm2_err.c
@@ -1,69 +1,69 @@
-/*
- * 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
- */
-
-#include <openssl/err.h>
+/*
+ * 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
+ */
+
+#include <openssl/err.h>
#include "crypto/sm2err.h"
-
-#ifndef OPENSSL_NO_ERR
-
-static const ERR_STRING_DATA SM2_str_functs[] = {
- {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_COPY, 0), "pkey_sm2_copy"},
- {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"},
- {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_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"},
- {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_NO_PARAMETERS_SET), "no parameters set"},
- {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_USER_ID_TOO_LARGE), "user id too large"},
- {0, NULL}
-};
-
-#endif
-
-int ERR_load_SM2_strings(void)
-{
-#ifndef OPENSSL_NO_ERR
- if (ERR_func_error_string(SM2_str_functs[0].error) == NULL) {
- ERR_load_strings_const(SM2_str_functs);
- ERR_load_strings_const(SM2_str_reasons);
- }
-#endif
- return 1;
-}
+
+#ifndef OPENSSL_NO_ERR
+
+static const ERR_STRING_DATA SM2_str_functs[] = {
+ {ERR_PACK(ERR_LIB_SM2, SM2_F_PKEY_SM2_COPY, 0), "pkey_sm2_copy"},
+ {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"},
+ {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_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"},
+ {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_NO_PARAMETERS_SET), "no parameters set"},
+ {ERR_PACK(ERR_LIB_SM2, 0, SM2_R_USER_ID_TOO_LARGE), "user id too large"},
+ {0, NULL}
+};
+
+#endif
+
+int ERR_load_SM2_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+ if (ERR_func_error_string(SM2_str_functs[0].error) == NULL) {
+ ERR_load_strings_const(SM2_str_functs);
+ ERR_load_strings_const(SM2_str_reasons);
+ }
+#endif
+ return 1;
+}
diff --git a/contrib/libs/openssl/crypto/sm2/sm2_pmeth.c b/contrib/libs/openssl/crypto/sm2/sm2_pmeth.c
index 288f4d73dd..0e722b910b 100644
--- a/contrib/libs/openssl/crypto/sm2/sm2_pmeth.c
+++ b/contrib/libs/openssl/crypto/sm2/sm2_pmeth.c
@@ -1,329 +1,329 @@
-/*
+/*
* Copyright 2006-2021 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 "internal/cryptlib.h"
-#include <openssl/asn1t.h>
-#include <openssl/ec.h>
-#include <openssl/evp.h>
+ *
+ * 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 "internal/cryptlib.h"
+#include <openssl/asn1t.h>
+#include <openssl/ec.h>
+#include <openssl/evp.h>
#include "crypto/evp.h"
#include "crypto/sm2.h"
#include "crypto/sm2err.h"
-
-/* EC pkey context structure */
-
-typedef struct {
- /* Key and paramgen group */
- EC_GROUP *gen_group;
- /* message digest */
- const EVP_MD *md;
- /* Distinguishing Identifier, ISO/IEC 15946-3 */
- uint8_t *id;
- size_t id_len;
- /* id_set indicates if the 'id' field is set (1) or not (0) */
- int id_set;
-} SM2_PKEY_CTX;
-
-static int pkey_sm2_init(EVP_PKEY_CTX *ctx)
-{
- SM2_PKEY_CTX *smctx;
-
- if ((smctx = OPENSSL_zalloc(sizeof(*smctx))) == NULL) {
- SM2err(SM2_F_PKEY_SM2_INIT, ERR_R_MALLOC_FAILURE);
- return 0;
- }
-
- ctx->data = smctx;
- return 1;
-}
-
-static void pkey_sm2_cleanup(EVP_PKEY_CTX *ctx)
-{
- SM2_PKEY_CTX *smctx = ctx->data;
-
- if (smctx != NULL) {
- EC_GROUP_free(smctx->gen_group);
- OPENSSL_free(smctx->id);
- OPENSSL_free(smctx);
- ctx->data = NULL;
- }
-}
-
-static int pkey_sm2_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
-{
- SM2_PKEY_CTX *dctx, *sctx;
-
- if (!pkey_sm2_init(dst))
- return 0;
- sctx = src->data;
- dctx = dst->data;
- if (sctx->gen_group != NULL) {
- dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
- if (dctx->gen_group == NULL) {
- pkey_sm2_cleanup(dst);
- return 0;
- }
- }
- if (sctx->id != NULL) {
- dctx->id = OPENSSL_malloc(sctx->id_len);
- if (dctx->id == NULL) {
- SM2err(SM2_F_PKEY_SM2_COPY, ERR_R_MALLOC_FAILURE);
- pkey_sm2_cleanup(dst);
- return 0;
- }
- memcpy(dctx->id, sctx->id, sctx->id_len);
- }
- dctx->id_len = sctx->id_len;
- dctx->id_set = sctx->id_set;
- dctx->md = sctx->md;
-
- return 1;
-}
-
-static int pkey_sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
- const unsigned char *tbs, size_t tbslen)
-{
- int ret;
- unsigned int sltmp;
- EC_KEY *ec = ctx->pkey->pkey.ec;
- const int sig_sz = ECDSA_size(ctx->pkey->pkey.ec);
-
- if (sig_sz <= 0) {
- return 0;
- }
-
- if (sig == NULL) {
- *siglen = (size_t)sig_sz;
- return 1;
- }
-
- if (*siglen < (size_t)sig_sz) {
- SM2err(SM2_F_PKEY_SM2_SIGN, SM2_R_BUFFER_TOO_SMALL);
- return 0;
- }
-
- ret = sm2_sign(tbs, tbslen, sig, &sltmp, ec);
-
- if (ret <= 0)
- return ret;
- *siglen = (size_t)sltmp;
- return 1;
-}
-
-static int pkey_sm2_verify(EVP_PKEY_CTX *ctx,
- const unsigned char *sig, size_t siglen,
- const unsigned char *tbs, size_t tbslen)
-{
- EC_KEY *ec = ctx->pkey->pkey.ec;
-
- return sm2_verify(tbs, tbslen, sig, siglen, ec);
-}
-
-static int pkey_sm2_encrypt(EVP_PKEY_CTX *ctx,
- unsigned char *out, size_t *outlen,
- const unsigned char *in, size_t inlen)
-{
- EC_KEY *ec = ctx->pkey->pkey.ec;
- SM2_PKEY_CTX *dctx = ctx->data;
- const EVP_MD *md = (dctx->md == NULL) ? EVP_sm3() : dctx->md;
-
- if (out == NULL) {
- if (!sm2_ciphertext_size(ec, md, inlen, outlen))
- return -1;
- else
- return 1;
- }
-
- return sm2_encrypt(ec, md, in, inlen, out, outlen);
-}
-
-static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx,
- unsigned char *out, size_t *outlen,
- const unsigned char *in, size_t inlen)
-{
- EC_KEY *ec = ctx->pkey->pkey.ec;
- SM2_PKEY_CTX *dctx = ctx->data;
- const EVP_MD *md = (dctx->md == NULL) ? EVP_sm3() : dctx->md;
-
- if (out == NULL) {
+
+/* EC pkey context structure */
+
+typedef struct {
+ /* Key and paramgen group */
+ EC_GROUP *gen_group;
+ /* message digest */
+ const EVP_MD *md;
+ /* Distinguishing Identifier, ISO/IEC 15946-3 */
+ uint8_t *id;
+ size_t id_len;
+ /* id_set indicates if the 'id' field is set (1) or not (0) */
+ int id_set;
+} SM2_PKEY_CTX;
+
+static int pkey_sm2_init(EVP_PKEY_CTX *ctx)
+{
+ SM2_PKEY_CTX *smctx;
+
+ if ((smctx = OPENSSL_zalloc(sizeof(*smctx))) == NULL) {
+ SM2err(SM2_F_PKEY_SM2_INIT, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ ctx->data = smctx;
+ return 1;
+}
+
+static void pkey_sm2_cleanup(EVP_PKEY_CTX *ctx)
+{
+ SM2_PKEY_CTX *smctx = ctx->data;
+
+ if (smctx != NULL) {
+ EC_GROUP_free(smctx->gen_group);
+ OPENSSL_free(smctx->id);
+ OPENSSL_free(smctx);
+ ctx->data = NULL;
+ }
+}
+
+static int pkey_sm2_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
+{
+ SM2_PKEY_CTX *dctx, *sctx;
+
+ if (!pkey_sm2_init(dst))
+ return 0;
+ sctx = src->data;
+ dctx = dst->data;
+ if (sctx->gen_group != NULL) {
+ dctx->gen_group = EC_GROUP_dup(sctx->gen_group);
+ if (dctx->gen_group == NULL) {
+ pkey_sm2_cleanup(dst);
+ return 0;
+ }
+ }
+ if (sctx->id != NULL) {
+ dctx->id = OPENSSL_malloc(sctx->id_len);
+ if (dctx->id == NULL) {
+ SM2err(SM2_F_PKEY_SM2_COPY, ERR_R_MALLOC_FAILURE);
+ pkey_sm2_cleanup(dst);
+ return 0;
+ }
+ memcpy(dctx->id, sctx->id, sctx->id_len);
+ }
+ dctx->id_len = sctx->id_len;
+ dctx->id_set = sctx->id_set;
+ dctx->md = sctx->md;
+
+ return 1;
+}
+
+static int pkey_sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs, size_t tbslen)
+{
+ int ret;
+ unsigned int sltmp;
+ EC_KEY *ec = ctx->pkey->pkey.ec;
+ const int sig_sz = ECDSA_size(ctx->pkey->pkey.ec);
+
+ if (sig_sz <= 0) {
+ return 0;
+ }
+
+ if (sig == NULL) {
+ *siglen = (size_t)sig_sz;
+ return 1;
+ }
+
+ if (*siglen < (size_t)sig_sz) {
+ SM2err(SM2_F_PKEY_SM2_SIGN, SM2_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ ret = sm2_sign(tbs, tbslen, sig, &sltmp, ec);
+
+ if (ret <= 0)
+ return ret;
+ *siglen = (size_t)sltmp;
+ return 1;
+}
+
+static int pkey_sm2_verify(EVP_PKEY_CTX *ctx,
+ const unsigned char *sig, size_t siglen,
+ const unsigned char *tbs, size_t tbslen)
+{
+ EC_KEY *ec = ctx->pkey->pkey.ec;
+
+ return sm2_verify(tbs, tbslen, sig, siglen, ec);
+}
+
+static int pkey_sm2_encrypt(EVP_PKEY_CTX *ctx,
+ unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen)
+{
+ EC_KEY *ec = ctx->pkey->pkey.ec;
+ SM2_PKEY_CTX *dctx = ctx->data;
+ const EVP_MD *md = (dctx->md == NULL) ? EVP_sm3() : dctx->md;
+
+ if (out == NULL) {
+ if (!sm2_ciphertext_size(ec, md, inlen, outlen))
+ return -1;
+ else
+ return 1;
+ }
+
+ return sm2_encrypt(ec, md, in, inlen, out, outlen);
+}
+
+static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx,
+ unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen)
+{
+ EC_KEY *ec = ctx->pkey->pkey.ec;
+ SM2_PKEY_CTX *dctx = ctx->data;
+ const EVP_MD *md = (dctx->md == NULL) ? EVP_sm3() : dctx->md;
+
+ if (out == NULL) {
if (!sm2_plaintext_size(in, inlen, outlen))
- return -1;
- else
- return 1;
- }
-
- return sm2_decrypt(ec, md, in, inlen, out, outlen);
-}
-
-static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
-{
- SM2_PKEY_CTX *smctx = ctx->data;
- EC_GROUP *group;
- uint8_t *tmp_id;
-
- switch (type) {
- case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
- group = EC_GROUP_new_by_curve_name(p1);
- if (group == NULL) {
- SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_INVALID_CURVE);
- return 0;
- }
- EC_GROUP_free(smctx->gen_group);
- smctx->gen_group = group;
- return 1;
-
- case EVP_PKEY_CTRL_EC_PARAM_ENC:
- if (smctx->gen_group == NULL) {
- SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_NO_PARAMETERS_SET);
- return 0;
- }
- EC_GROUP_set_asn1_flag(smctx->gen_group, p1);
- return 1;
-
- case EVP_PKEY_CTRL_MD:
- smctx->md = p2;
- return 1;
-
- case EVP_PKEY_CTRL_GET_MD:
- *(const EVP_MD **)p2 = smctx->md;
- return 1;
-
- case EVP_PKEY_CTRL_SET1_ID:
- if (p1 > 0) {
- tmp_id = OPENSSL_malloc(p1);
- if (tmp_id == NULL) {
- SM2err(SM2_F_PKEY_SM2_CTRL, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- 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;
- smctx->id_set = 1;
- return 1;
-
- case EVP_PKEY_CTRL_GET1_ID:
- memcpy(p2, smctx->id, smctx->id_len);
- return 1;
-
- case EVP_PKEY_CTRL_GET1_ID_LEN:
- *(size_t *)p2 = smctx->id_len;
- return 1;
-
+ return -1;
+ else
+ return 1;
+ }
+
+ return sm2_decrypt(ec, md, in, inlen, out, outlen);
+}
+
+static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+ SM2_PKEY_CTX *smctx = ctx->data;
+ EC_GROUP *group;
+ uint8_t *tmp_id;
+
+ switch (type) {
+ case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
+ group = EC_GROUP_new_by_curve_name(p1);
+ if (group == NULL) {
+ SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_INVALID_CURVE);
+ return 0;
+ }
+ EC_GROUP_free(smctx->gen_group);
+ smctx->gen_group = group;
+ return 1;
+
+ case EVP_PKEY_CTRL_EC_PARAM_ENC:
+ if (smctx->gen_group == NULL) {
+ SM2err(SM2_F_PKEY_SM2_CTRL, SM2_R_NO_PARAMETERS_SET);
+ return 0;
+ }
+ EC_GROUP_set_asn1_flag(smctx->gen_group, p1);
+ return 1;
+
+ case EVP_PKEY_CTRL_MD:
+ smctx->md = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_MD:
+ *(const EVP_MD **)p2 = smctx->md;
+ return 1;
+
+ case EVP_PKEY_CTRL_SET1_ID:
+ if (p1 > 0) {
+ tmp_id = OPENSSL_malloc(p1);
+ if (tmp_id == NULL) {
+ SM2err(SM2_F_PKEY_SM2_CTRL, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ 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;
+ smctx->id_set = 1;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET1_ID:
+ memcpy(p2, smctx->id, smctx->id_len);
+ return 1;
+
+ case EVP_PKEY_CTRL_GET1_ID_LEN:
+ *(size_t *)p2 = smctx->id_len;
+ return 1;
+
case EVP_PKEY_CTRL_DIGESTINIT:
/* nothing to be inited, this is to suppress the error... */
return 1;
- default:
- return -2;
- }
-}
-
-static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx,
- const char *type, const char *value)
-{
- if (strcmp(type, "ec_paramgen_curve") == 0) {
- int nid = NID_undef;
-
- if (((nid = EC_curve_nist2nid(value)) == NID_undef)
- && ((nid = OBJ_sn2nid(value)) == NID_undef)
- && ((nid = OBJ_ln2nid(value)) == NID_undef)) {
- SM2err(SM2_F_PKEY_SM2_CTRL_STR, SM2_R_INVALID_CURVE);
- return 0;
- }
- return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
- } else if (strcmp(type, "ec_param_enc") == 0) {
- int param_enc;
-
- if (strcmp(value, "explicit") == 0)
- param_enc = 0;
- else if (strcmp(value, "named_curve") == 0)
- param_enc = OPENSSL_EC_NAMED_CURVE;
- else
- return -2;
- return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
- }
-
- return -2;
-}
-
-static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
-{
- uint8_t z[EVP_MAX_MD_SIZE];
- SM2_PKEY_CTX *smctx = ctx->data;
- EC_KEY *ec = ctx->pkey->pkey.ec;
- const EVP_MD *md = EVP_MD_CTX_md(mctx);
- int mdlen = EVP_MD_size(md);
-
- if (!smctx->id_set) {
- /*
- * An ID value must be set. The specifications are not clear whether a
- * NULL is allowed. We only allow it if set explicitly for maximum
- * flexibility.
- */
- SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_ID_NOT_SET);
- return 0;
- }
-
- if (mdlen < 0) {
- SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_INVALID_DIGEST);
- return 0;
- }
-
- /* get hashed prefix 'z' of tbs message */
- if (!sm2_compute_z_digest(z, md, smctx->id, smctx->id_len, ec))
- return 0;
-
- return EVP_DigestUpdate(mctx, z, (size_t)mdlen);
-}
-
-const EVP_PKEY_METHOD sm2_pkey_meth = {
- EVP_PKEY_SM2,
- 0,
- pkey_sm2_init,
- pkey_sm2_copy,
- pkey_sm2_cleanup,
-
- 0,
- 0,
-
- 0,
- 0,
-
- 0,
- pkey_sm2_sign,
-
- 0,
- pkey_sm2_verify,
-
- 0, 0,
-
- 0, 0, 0, 0,
-
- 0,
- pkey_sm2_encrypt,
-
- 0,
- pkey_sm2_decrypt,
-
- 0,
- 0,
- pkey_sm2_ctrl,
- pkey_sm2_ctrl_str,
-
- 0, 0,
-
- 0, 0, 0,
-
- pkey_sm2_digest_custom
-};
+ default:
+ return -2;
+ }
+}
+
+static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx,
+ const char *type, const char *value)
+{
+ if (strcmp(type, "ec_paramgen_curve") == 0) {
+ int nid = NID_undef;
+
+ if (((nid = EC_curve_nist2nid(value)) == NID_undef)
+ && ((nid = OBJ_sn2nid(value)) == NID_undef)
+ && ((nid = OBJ_ln2nid(value)) == NID_undef)) {
+ SM2err(SM2_F_PKEY_SM2_CTRL_STR, SM2_R_INVALID_CURVE);
+ return 0;
+ }
+ return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
+ } else if (strcmp(type, "ec_param_enc") == 0) {
+ int param_enc;
+
+ if (strcmp(value, "explicit") == 0)
+ param_enc = 0;
+ else if (strcmp(value, "named_curve") == 0)
+ param_enc = OPENSSL_EC_NAMED_CURVE;
+ else
+ return -2;
+ return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
+ }
+
+ return -2;
+}
+
+static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+{
+ uint8_t z[EVP_MAX_MD_SIZE];
+ SM2_PKEY_CTX *smctx = ctx->data;
+ EC_KEY *ec = ctx->pkey->pkey.ec;
+ const EVP_MD *md = EVP_MD_CTX_md(mctx);
+ int mdlen = EVP_MD_size(md);
+
+ if (!smctx->id_set) {
+ /*
+ * An ID value must be set. The specifications are not clear whether a
+ * NULL is allowed. We only allow it if set explicitly for maximum
+ * flexibility.
+ */
+ SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_ID_NOT_SET);
+ return 0;
+ }
+
+ if (mdlen < 0) {
+ SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_INVALID_DIGEST);
+ return 0;
+ }
+
+ /* get hashed prefix 'z' of tbs message */
+ if (!sm2_compute_z_digest(z, md, smctx->id, smctx->id_len, ec))
+ return 0;
+
+ return EVP_DigestUpdate(mctx, z, (size_t)mdlen);
+}
+
+const EVP_PKEY_METHOD sm2_pkey_meth = {
+ EVP_PKEY_SM2,
+ 0,
+ pkey_sm2_init,
+ pkey_sm2_copy,
+ pkey_sm2_cleanup,
+
+ 0,
+ 0,
+
+ 0,
+ 0,
+
+ 0,
+ pkey_sm2_sign,
+
+ 0,
+ pkey_sm2_verify,
+
+ 0, 0,
+
+ 0, 0, 0, 0,
+
+ 0,
+ pkey_sm2_encrypt,
+
+ 0,
+ pkey_sm2_decrypt,
+
+ 0,
+ 0,
+ pkey_sm2_ctrl,
+ pkey_sm2_ctrl_str,
+
+ 0, 0,
+
+ 0, 0, 0,
+
+ pkey_sm2_digest_custom
+};
diff --git a/contrib/libs/openssl/crypto/sm2/sm2_sign.c b/contrib/libs/openssl/crypto/sm2/sm2_sign.c
index 9bb723ea19..683f03f935 100644
--- a/contrib/libs/openssl/crypto/sm2/sm2_sign.c
+++ b/contrib/libs/openssl/crypto/sm2/sm2_sign.c
@@ -1,479 +1,479 @@
-/*
+/*
* Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
- * Copyright 2017 Ribose Inc. All Rights Reserved.
- * Ported from Ribose contributions from Botan.
- *
- * 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
- */
-
+ * Copyright 2017 Ribose Inc. All Rights Reserved.
+ * Ported from Ribose contributions from Botan.
+ *
+ * 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 "crypto/sm2.h"
#include "crypto/sm2err.h"
#include "crypto/ec.h" /* ec_group_do_inverse_ord() */
-#include "internal/numbers.h"
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#include <string.h>
-
-int sm2_compute_z_digest(uint8_t *out,
- const EVP_MD *digest,
- const uint8_t *id,
- const size_t id_len,
- const EC_KEY *key)
-{
- int rc = 0;
- const EC_GROUP *group = EC_KEY_get0_group(key);
- 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;
- uint16_t entl = 0;
- uint8_t e_byte = 0;
-
- hash = EVP_MD_CTX_new();
- ctx = BN_CTX_new();
- if (hash == NULL || ctx == NULL) {
- SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- p = BN_CTX_get(ctx);
- a = BN_CTX_get(ctx);
- b = BN_CTX_get(ctx);
- xG = BN_CTX_get(ctx);
- yG = BN_CTX_get(ctx);
- xA = BN_CTX_get(ctx);
- yA = BN_CTX_get(ctx);
-
- if (yA == NULL) {
- SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- if (!EVP_DigestInit(hash, digest)) {
- SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
- goto done;
- }
-
- /* Z = h(ENTL || ID || a || b || xG || yG || xA || yA) */
-
- if (id_len >= (UINT16_MAX / 8)) {
- /* too large */
- SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, SM2_R_ID_TOO_LARGE);
- goto done;
- }
-
- entl = (uint16_t)(8 * id_len);
-
- e_byte = entl >> 8;
- if (!EVP_DigestUpdate(hash, &e_byte, 1)) {
- SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
- goto done;
- }
- e_byte = entl & 0xFF;
- if (!EVP_DigestUpdate(hash, &e_byte, 1)) {
- SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
- goto done;
- }
-
- if (id_len > 0 && !EVP_DigestUpdate(hash, id, id_len)) {
- SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
- goto done;
- }
-
- if (!EC_GROUP_get_curve(group, p, a, b, ctx)) {
- SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EC_LIB);
- goto done;
- }
-
- p_bytes = BN_num_bytes(p);
- buf = OPENSSL_zalloc(p_bytes);
- if (buf == NULL) {
- SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- 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(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(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_Z_DIGEST, ERR_R_INTERNAL_ERROR);
- goto done;
- }
-
- rc = 1;
-
- done:
- OPENSSL_free(buf);
- BN_CTX_free(ctx);
- EVP_MD_CTX_free(hash);
- return rc;
-}
-
-static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,
- const EC_KEY *key,
- const uint8_t *id,
- const size_t id_len,
- 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 *z = NULL;
- BIGNUM *e = NULL;
-
- if (md_size < 0) {
- SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, SM2_R_INVALID_DIGEST);
- goto done;
- }
-
- z = OPENSSL_zalloc(md_size);
- if (hash == NULL || z == NULL) {
- SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- if (!sm2_compute_z_digest(z, digest, id, id_len, key)) {
- /* SM2err already called */
- goto done;
- }
-
- if (!EVP_DigestInit(hash, digest)
- || !EVP_DigestUpdate(hash, z, md_size)
- || !EVP_DigestUpdate(hash, msg, msg_len)
- /* reuse z buffer to hold H(Z || M) */
- || !EVP_DigestFinal(hash, z, NULL)) {
- SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_EVP_LIB);
- goto done;
- }
-
- e = BN_bin2bn(z, md_size, NULL);
- if (e == NULL)
- SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_INTERNAL_ERROR);
-
- done:
- OPENSSL_free(z);
- EVP_MD_CTX_free(hash);
- return 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;
- BIGNUM *k = NULL;
- BIGNUM *rk = NULL;
- BIGNUM *r = NULL;
- BIGNUM *s = NULL;
- BIGNUM *x1 = NULL;
- BIGNUM *tmp = NULL;
-
- kG = EC_POINT_new(group);
- ctx = BN_CTX_new();
- if (kG == NULL || ctx == NULL) {
- SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- 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) {
- 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
- */
- r = BN_new();
- s = BN_new();
-
- if (r == NULL || s == NULL) {
- SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- for (;;) {
- 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(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;
-
- 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;
-
- if (!BN_add(s, dA, BN_value_one())
- || !ec_group_do_inverse_ord(group, s, s, 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) {
- SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- /* takes ownership of r and s */
- ECDSA_SIG_set0(sig, r, s);
- break;
- }
-
- done:
- if (sig == NULL) {
- BN_free(r);
- BN_free(s);
- }
-
- 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)
-{
- 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();
- pt = EC_POINT_new(group);
- 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) {
- SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_MALLOC_FAILURE);
- goto done;
- }
-
- /*
- * B1: verify whether r' in [1,n-1], verification failed if not
+#include "internal/numbers.h"
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <string.h>
+
+int sm2_compute_z_digest(uint8_t *out,
+ const EVP_MD *digest,
+ const uint8_t *id,
+ const size_t id_len,
+ const EC_KEY *key)
+{
+ int rc = 0;
+ const EC_GROUP *group = EC_KEY_get0_group(key);
+ 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;
+ uint16_t entl = 0;
+ uint8_t e_byte = 0;
+
+ hash = EVP_MD_CTX_new();
+ ctx = BN_CTX_new();
+ if (hash == NULL || ctx == NULL) {
+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ p = BN_CTX_get(ctx);
+ a = BN_CTX_get(ctx);
+ b = BN_CTX_get(ctx);
+ xG = BN_CTX_get(ctx);
+ yG = BN_CTX_get(ctx);
+ xA = BN_CTX_get(ctx);
+ yA = BN_CTX_get(ctx);
+
+ if (yA == NULL) {
+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ if (!EVP_DigestInit(hash, digest)) {
+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
+ goto done;
+ }
+
+ /* Z = h(ENTL || ID || a || b || xG || yG || xA || yA) */
+
+ if (id_len >= (UINT16_MAX / 8)) {
+ /* too large */
+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, SM2_R_ID_TOO_LARGE);
+ goto done;
+ }
+
+ entl = (uint16_t)(8 * id_len);
+
+ e_byte = entl >> 8;
+ if (!EVP_DigestUpdate(hash, &e_byte, 1)) {
+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
+ goto done;
+ }
+ e_byte = entl & 0xFF;
+ if (!EVP_DigestUpdate(hash, &e_byte, 1)) {
+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
+ goto done;
+ }
+
+ if (id_len > 0 && !EVP_DigestUpdate(hash, id, id_len)) {
+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EVP_LIB);
+ goto done;
+ }
+
+ if (!EC_GROUP_get_curve(group, p, a, b, ctx)) {
+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_EC_LIB);
+ goto done;
+ }
+
+ p_bytes = BN_num_bytes(p);
+ buf = OPENSSL_zalloc(p_bytes);
+ if (buf == NULL) {
+ SM2err(SM2_F_SM2_COMPUTE_Z_DIGEST, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ 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(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(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_Z_DIGEST, ERR_R_INTERNAL_ERROR);
+ goto done;
+ }
+
+ rc = 1;
+
+ done:
+ OPENSSL_free(buf);
+ BN_CTX_free(ctx);
+ EVP_MD_CTX_free(hash);
+ return rc;
+}
+
+static BIGNUM *sm2_compute_msg_hash(const EVP_MD *digest,
+ const EC_KEY *key,
+ const uint8_t *id,
+ const size_t id_len,
+ 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 *z = NULL;
+ BIGNUM *e = NULL;
+
+ if (md_size < 0) {
+ SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, SM2_R_INVALID_DIGEST);
+ goto done;
+ }
+
+ z = OPENSSL_zalloc(md_size);
+ if (hash == NULL || z == NULL) {
+ SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ if (!sm2_compute_z_digest(z, digest, id, id_len, key)) {
+ /* SM2err already called */
+ goto done;
+ }
+
+ if (!EVP_DigestInit(hash, digest)
+ || !EVP_DigestUpdate(hash, z, md_size)
+ || !EVP_DigestUpdate(hash, msg, msg_len)
+ /* reuse z buffer to hold H(Z || M) */
+ || !EVP_DigestFinal(hash, z, NULL)) {
+ SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_EVP_LIB);
+ goto done;
+ }
+
+ e = BN_bin2bn(z, md_size, NULL);
+ if (e == NULL)
+ SM2err(SM2_F_SM2_COMPUTE_MSG_HASH, ERR_R_INTERNAL_ERROR);
+
+ done:
+ OPENSSL_free(z);
+ EVP_MD_CTX_free(hash);
+ return 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;
+ BIGNUM *k = NULL;
+ BIGNUM *rk = NULL;
+ BIGNUM *r = NULL;
+ BIGNUM *s = NULL;
+ BIGNUM *x1 = NULL;
+ BIGNUM *tmp = NULL;
+
+ kG = EC_POINT_new(group);
+ ctx = BN_CTX_new();
+ if (kG == NULL || ctx == NULL) {
+ SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ 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) {
+ 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
+ */
+ r = BN_new();
+ s = BN_new();
+
+ if (r == NULL || s == NULL) {
+ SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ for (;;) {
+ 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(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;
+
+ 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;
+
+ if (!BN_add(s, dA, BN_value_one())
+ || !ec_group_do_inverse_ord(group, s, s, 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) {
+ SM2err(SM2_F_SM2_SIG_GEN, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ /* takes ownership of r and s */
+ ECDSA_SIG_set0(sig, r, s);
+ break;
+ }
+
+ done:
+ if (sig == NULL) {
+ BN_free(r);
+ BN_free(s);
+ }
+
+ 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)
+{
+ 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();
+ pt = EC_POINT_new(group);
+ 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) {
+ 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: verify 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
+ * 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, verification pass if yes, otherwise failed
- */
-
- ECDSA_SIG_get0(sig, &r, &s);
-
- 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_mod_add(t, r, s, order, ctx)) {
- SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_BN_LIB);
- goto done;
- }
-
- if (BN_is_zero(t)) {
- SM2err(SM2_F_SM2_SIG_VERIFY, SM2_R_BAD_SIGNATURE);
- goto done;
- }
-
- if (!EC_POINT_mul(group, pt, s, EC_KEY_get0_public_key(key), t, ctx)
- || !EC_POINT_get_affine_coordinates(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)) {
- SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_BN_LIB);
- goto done;
- }
-
- if (BN_cmp(r, t) == 0)
- ret = 1;
-
- done:
- EC_POINT_free(pt);
- BN_CTX_free(ctx);
- return ret;
-}
-
-ECDSA_SIG *sm2_do_sign(const EC_KEY *key,
- const EVP_MD *digest,
- const uint8_t *id,
- const size_t id_len,
- const uint8_t *msg, size_t msg_len)
-{
- BIGNUM *e = NULL;
- ECDSA_SIG *sig = NULL;
-
- e = sm2_compute_msg_hash(digest, key, id, id_len, msg, msg_len);
- if (e == NULL) {
- /* SM2err already called */
- goto done;
- }
-
- sig = sm2_sig_gen(key, e);
-
- done:
- BN_free(e);
- return sig;
-}
-
-int sm2_do_verify(const EC_KEY *key,
- const EVP_MD *digest,
- const ECDSA_SIG *sig,
- const uint8_t *id,
- const size_t id_len,
- const uint8_t *msg, size_t msg_len)
-{
- BIGNUM *e = NULL;
- int ret = 0;
-
- e = sm2_compute_msg_hash(digest, key, id, id_len, msg, msg_len);
- if (e == NULL) {
- /* SM2err already called */
- goto done;
- }
-
- ret = sm2_sig_verify(key, sig, e);
-
- done:
- BN_free(e);
- return ret;
-}
-
-int sm2_sign(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;
-
- 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);
-
- 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;
-
- done:
- ECDSA_SIG_free(s);
- BN_free(e);
- return ret;
-}
-
-int sm2_verify(const unsigned char *dgst, int dgstlen,
- const unsigned char *sig, int sig_len, EC_KEY *eckey)
-{
- ECDSA_SIG *s = NULL;
- BIGNUM *e = NULL;
- const unsigned char *p = sig;
- unsigned char *der = NULL;
- int derlen = -1;
- int ret = -1;
-
- s = ECDSA_SIG_new();
- if (s == NULL) {
- SM2err(SM2_F_SM2_VERIFY, ERR_R_MALLOC_FAILURE);
- goto done;
- }
- 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) {
- 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);
-
- done:
- OPENSSL_free(der);
- BN_free(e);
- ECDSA_SIG_free(s);
- return ret;
-}
+ */
+
+ ECDSA_SIG_get0(sig, &r, &s);
+
+ 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_mod_add(t, r, s, order, ctx)) {
+ SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_BN_LIB);
+ goto done;
+ }
+
+ if (BN_is_zero(t)) {
+ SM2err(SM2_F_SM2_SIG_VERIFY, SM2_R_BAD_SIGNATURE);
+ goto done;
+ }
+
+ if (!EC_POINT_mul(group, pt, s, EC_KEY_get0_public_key(key), t, ctx)
+ || !EC_POINT_get_affine_coordinates(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)) {
+ SM2err(SM2_F_SM2_SIG_VERIFY, ERR_R_BN_LIB);
+ goto done;
+ }
+
+ if (BN_cmp(r, t) == 0)
+ ret = 1;
+
+ done:
+ EC_POINT_free(pt);
+ BN_CTX_free(ctx);
+ return ret;
+}
+
+ECDSA_SIG *sm2_do_sign(const EC_KEY *key,
+ const EVP_MD *digest,
+ const uint8_t *id,
+ const size_t id_len,
+ const uint8_t *msg, size_t msg_len)
+{
+ BIGNUM *e = NULL;
+ ECDSA_SIG *sig = NULL;
+
+ e = sm2_compute_msg_hash(digest, key, id, id_len, msg, msg_len);
+ if (e == NULL) {
+ /* SM2err already called */
+ goto done;
+ }
+
+ sig = sm2_sig_gen(key, e);
+
+ done:
+ BN_free(e);
+ return sig;
+}
+
+int sm2_do_verify(const EC_KEY *key,
+ const EVP_MD *digest,
+ const ECDSA_SIG *sig,
+ const uint8_t *id,
+ const size_t id_len,
+ const uint8_t *msg, size_t msg_len)
+{
+ BIGNUM *e = NULL;
+ int ret = 0;
+
+ e = sm2_compute_msg_hash(digest, key, id, id_len, msg, msg_len);
+ if (e == NULL) {
+ /* SM2err already called */
+ goto done;
+ }
+
+ ret = sm2_sig_verify(key, sig, e);
+
+ done:
+ BN_free(e);
+ return ret;
+}
+
+int sm2_sign(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;
+
+ 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);
+
+ 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;
+
+ done:
+ ECDSA_SIG_free(s);
+ BN_free(e);
+ return ret;
+}
+
+int sm2_verify(const unsigned char *dgst, int dgstlen,
+ const unsigned char *sig, int sig_len, EC_KEY *eckey)
+{
+ ECDSA_SIG *s = NULL;
+ BIGNUM *e = NULL;
+ const unsigned char *p = sig;
+ unsigned char *der = NULL;
+ int derlen = -1;
+ int ret = -1;
+
+ s = ECDSA_SIG_new();
+ if (s == NULL) {
+ SM2err(SM2_F_SM2_VERIFY, ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+ 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) {
+ 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);
+
+ done:
+ OPENSSL_free(der);
+ BN_free(e);
+ ECDSA_SIG_free(s);
+ return ret;
+}