diff options
author | deshevoy <deshevoy@yandex-team.ru> | 2022-02-10 16:46:57 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:46:57 +0300 |
commit | 28148f76dbfcc644d96427d41c92f36cbf2fdc6e (patch) | |
tree | b83306b6e37edeea782e9eed673d89286c4fef35 /contrib/libs/openssl/crypto/sm2 | |
parent | e988f30484abe5fdeedcc7a5d3c226c01a21800c (diff) | |
download | ydb-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.c | 746 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/sm2/sm2_err.c | 136 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/sm2/sm2_pmeth.c | 640 | ||||
-rw-r--r-- | contrib/libs/openssl/crypto/sm2/sm2_sign.c | 946 |
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; +} |