This commit is contained in:
Zhi Guan
2017-04-14 15:31:35 +08:00
parent 7fa961cd6f
commit eb21e9d572
76 changed files with 3249 additions and 2961 deletions

View File

@@ -27,3 +27,16 @@ int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d,
{
return ASN1_STRING_set(x, d, len);
}
#ifndef OPENSSL_NO_SM2
int ASN1_OCTET_STRING_is_zero(const ASN1_OCTET_STRING *a)
{
int i;
for (i = 0; i < a->length; i++) {
if (a->data[i] != 0) {
return 0;
}
}
return 1;
}
#endif

View File

@@ -51,6 +51,7 @@ static ERR_STRING_DATA BN_str_functs[] = {
{ERR_FUNC(BN_F_BN_GFP2_CMP), "BN_GFP2_cmp"},
{ERR_FUNC(BN_F_BN_GFP2_COPY), "BN_GFP2_copy"},
{ERR_FUNC(BN_F_BN_GFP2_DIV_BN), "BN_GFP2_div_bn"},
{ERR_FUNC(BN_F_BN_GFP2_EQU), "BN_GFP2_equ"},
{ERR_FUNC(BN_F_BN_GFP2_INV), "BN_GFP2_inv"},
{ERR_FUNC(BN_F_BN_GFP2_IS_ZERO), "BN_GFP2_is_zero"},
{ERR_FUNC(BN_F_BN_GFP2_MUL), "BN_GFP2_mul"},

View File

@@ -50,6 +50,7 @@
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/cpk.h>
#include "cpk_lcl.h"
ASN1_SEQUENCE(CPK_MASTER_SECRET) = {
ASN1_SIMPLE(CPK_MASTER_SECRET, version, LONG),
@@ -91,4 +92,3 @@ int i2d_CPK_PUBLIC_PARAMS_bio(BIO *bp, CPK_PUBLIC_PARAMS *params)
{
return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CPK_PUBLIC_PARAMS), bp, params);
}

View File

@@ -51,6 +51,7 @@
#include <openssl/ecdh.h>
#include <openssl/objects.h>
#include <openssl/cpk.h>
#include "cpk_lcl.h"
int CPK_PUBLIC_PARAMS_compute_share_key(CPK_PUBLIC_PARAMS *params,
void *out, size_t outlen, const char *id, EVP_PKEY *priv_key,

54
crypto/ec2/ec_expoint.c → crypto/cpk/cpk_lcl.h Normal file → Executable file
View File

@@ -1,5 +1,5 @@
/* ====================================================================
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
* Copyright (c) 2007 - 2016 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -46,45 +46,25 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
/*
* this file is to implement elliptic curve operations over extension
* fields
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/ossl_typ.h>
typedef struct {
int security_bits;
int n_bits;
int p_bits;
int q_bits;
} PAIRING_SEC;
static PAIRING_SEC sec_tbl[] = {
/* k |n| |p| |q| */
{ 80, 1024, 512, 160},
{112, 2048, 1024, 224},
{128, 3072, 1536, 256},
{192, 7680, 3840, 384},
{256, 15360, 7680, 512}
struct cpk_master_secret_st {
long version;
X509_NAME *id;
X509_ALGOR *pkey_algor;
X509_ALGOR *map_algor;
ASN1_OCTET_STRING *secret_factors;
};
const EVP_MD *PAIRING_nbits_to_md(int nbits)
{
switch (nbits) {
case 1024: return EVP_sha1();
case 2048: return EVP_sha224();
case 3072: return EVP_sha256();
case 7680: return EVP_sha384();
case 15360: return EVP_sha512();
}
return NULL;
}
struct cpk_public_params_st {
long version;
X509_NAME *id;
X509_ALGOR *pkey_algor;
X509_ALGOR *map_algor;
ASN1_OCTET_STRING *public_factors;
};

View File

@@ -61,13 +61,10 @@
#include <openssl/cpk.h>
#include "../dsa/dsa_locl.h"
#include "../x509/x509_lcl.h"
#include "cpk_lcl.h"
#define ASN1_STRING_data(a) ((a)->data)
static DSA *X509_ALGOR_get1_DSA(X509_ALGOR *algor);
static int extract_dsa_params(CPK_MASTER_SECRET *master, CPK_PUBLIC_PARAMS *param);
static DSA *extract_dsa_priv_key(CPK_MASTER_SECRET *master, const char *id);
static DSA *extract_dsa_pub_key(CPK_PUBLIC_PARAMS *param, const char *id);
static EC_KEY *X509_ALGOR_get1_EC_KEY(X509_ALGOR *algor);
static int extract_ec_params(CPK_MASTER_SECRET *master, CPK_PUBLIC_PARAMS *param);
@@ -244,14 +241,6 @@ CPK_PUBLIC_PARAMS *CPK_MASTER_SECRET_extract_public_params(CPK_MASTER_SECRET *ma
}
switch (pkey_type) {
case EVP_PKEY_DSA:
if (!extract_dsa_params(master, param)) {
CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS,
ERR_R_CPK_LIB);
goto err;
}
break;
case EVP_PKEY_EC:
if (!extract_ec_params(master, param)) {
CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PUBLIC_PARAMS,
@@ -285,21 +274,7 @@ EVP_PKEY *CPK_MASTER_SECRET_extract_private_key(
pkey_type = OBJ_obj2nid(master->pkey_algor->algorithm);
if (pkey_type == EVP_PKEY_DSA) {
DSA *dsa;
if (!(dsa = extract_dsa_priv_key(master, id))) {
CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY,
ERR_R_CPK_LIB);
goto err;
}
if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
DSA_free(dsa);
CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY,
ERR_R_EVP_LIB);
goto err;
}
} else if (pkey_type == EVP_PKEY_EC) {
if (pkey_type == EVP_PKEY_EC) {
EC_KEY *ec_key;
if (!(ec_key = extract_ec_priv_key(master, id))) {
CPKerr(CPK_F_CPK_MASTER_SECRET_EXTRACT_PRIVATE_KEY,
@@ -341,21 +316,8 @@ EVP_PKEY *CPK_PUBLIC_PARAMS_extract_public_key(CPK_PUBLIC_PARAMS *param,
pkey_type = OBJ_obj2nid(param->pkey_algor->algorithm);
if (pkey_type == EVP_PKEY_DSA) {
DSA *dsa = NULL;
if (!(dsa = extract_dsa_pub_key(param, id))) {
CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY,
ERR_R_CPK_LIB);
goto err;
}
if (!EVP_PKEY_assign_DSA(pkey, dsa)) {
DSA_free(dsa);
CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY,
ERR_R_EVP_LIB);
goto err;
}
} else if (pkey_type == EVP_PKEY_EC) {
if (pkey_type == EVP_PKEY_EC) {
EC_KEY *ec_key = NULL;
if (!(ec_key = extract_ec_pub_key(param, id))) {
CPKerr(CPK_F_CPK_PUBLIC_PARAMS_EXTRACT_PUBLIC_KEY,
@@ -477,237 +439,6 @@ err:
return ret;
}
/*
* static functions
*/
#if 0
// FIXME: check DSA and EC_KEY
static int X509_ALGOR_cmp(X509_ALGOR *a, X509_ALGOR *b)
{
int pkey_type = OBJ_obj2nid(a->algorithm);
if (pkey_type != EVP_PKEY_DSA || pkey_type != EVP_PKEY_EC)
return 1;
if (a->algorithm != b->algorithm)
return -1;
return 0;
}
#endif
static DSA *X509_ALGOR_get1_DSA(X509_ALGOR *algor)
{
DSA *dsa = NULL;
int ptype;
const void *pval;
ASN1_OCTET_STRING *pstr;
const unsigned char *p;
X509_ALGOR_get0(NULL, &ptype, &pval, algor);
if (ptype != V_ASN1_SEQUENCE) {
CPKerr(CPK_F_X509_ALGOR_GET1_DSA, CPK_R_BAD_DATA);
return NULL;
}
pstr = (ASN1_OCTET_STRING *)pval;
p = pstr->data;
if (!(dsa = d2i_DSAparams(NULL, &p, pstr->length))) {
CPKerr(CPK_F_X509_ALGOR_GET1_DSA, ERR_R_DSA_LIB);
return NULL;
}
return dsa;
}
static int extract_dsa_params(CPK_MASTER_SECRET *master, CPK_PUBLIC_PARAMS *param)
{
int ret = 0;
DSA *dsa = NULL;
BIGNUM *pri = BN_new();
BIGNUM *pub = BN_new();
BN_CTX *ctx = BN_CTX_new();
int i, pri_size, pub_size, num_factors;
const unsigned char *pri_ptr;
unsigned char *pub_ptr;
if (!pri || !pub || !ctx) {
goto err;
}
if (!(dsa = (DSA *)X509_ALGOR_get1_DSA(master->pkey_algor))) {
goto err;
}
pri_size = BN_num_bytes(dsa->q);
pub_size = BN_num_bytes(dsa->p);
if ((num_factors = CPK_MAP_num_factors(master->map_algor)) <= 0) {
goto err;
}
if (ASN1_STRING_length(master->secret_factors) != pri_size * num_factors) {
goto err;
}
ASN1_STRING_free(param->public_factors);
if (!ASN1_STRING_set(param->public_factors, NULL, pub_size * num_factors)) {
goto err;
}
pri_ptr = ASN1_STRING_data(master->secret_factors);
pub_ptr = ASN1_STRING_data(param->public_factors);
memset(pub_ptr, 0, ASN1_STRING_length(param->public_factors));
for (i = 0; i < num_factors; i++) {
if (!BN_bin2bn(pri_ptr, pri_size, pri)) {
goto err;
}
if (BN_is_zero(pri) || BN_cmp(pri, dsa->q) >= 0) {
goto err;
}
if (!BN_mod_exp(pub, dsa->g, pri, dsa->p, ctx)) {
goto err;
}
if (!BN_bn2bin(pub, pub_ptr + pub_size - BN_num_bytes(pub))) {
goto err;
}
pri_ptr += pri_size;
pub_ptr += pub_size;
}
ret = 1;
err:
if (dsa) DSA_free(dsa);
if (pri) BN_free(pri);
if (pub) BN_free(pub);
if (ctx) BN_CTX_free(ctx);
return ret;
}
static DSA *extract_dsa_priv_key(CPK_MASTER_SECRET *master, const char *id)
{
int e = 1;
DSA *dsa = NULL;
BIGNUM *bn = BN_new();
BN_CTX *ctx = BN_CTX_new();
const unsigned char *p;
int *index = NULL;
int i, num_indexes, bn_size;
if (!bn || !ctx) {
goto err;
}
if (!(dsa = X509_ALGOR_get1_DSA(master->pkey_algor))) {
goto err;
}
if ((num_indexes = CPK_MAP_num_indexes(master->map_algor)) <= 0) {
goto err;
}
if (!(index = OPENSSL_malloc(sizeof(int) * num_indexes))) {
goto err;
}
if (!CPK_MAP_str2index(master->map_algor, id, index)) {
goto err;
}
if (!dsa->priv_key) {
if (!(dsa->priv_key = BN_new())) {
goto err;
}
}
BN_zero(dsa->priv_key);
bn_size = BN_num_bytes(dsa->q);
for (i = 0; i < num_indexes; i++) {
p = ASN1_STRING_data(master->secret_factors) + bn_size * index[i];
if (!BN_bin2bn(p, bn_size, bn)) {
goto err;
}
if (BN_is_zero(bn) || BN_cmp(bn, dsa->q) >= 0) {
goto err;
}
if (!BN_mod_add(dsa->priv_key, dsa->priv_key, bn, dsa->q, ctx)) {
goto err;
}
}
if (!(dsa->pub_key))
if (!(dsa->pub_key = BN_new())) {
goto err;
}
if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
goto err;
}
e = 0;
err:
if (e && dsa) {
DSA_free(dsa);
dsa = NULL;
}
if (bn) BN_free(bn);
if (ctx) BN_CTX_free(ctx);
if (index) OPENSSL_free(index);
return dsa;
}
static DSA *extract_dsa_pub_key(CPK_PUBLIC_PARAMS *param, const char *id)
{
int e = 1;
DSA *dsa = NULL;
BIGNUM *bn = BN_new();
BN_CTX *ctx = BN_CTX_new();
const unsigned char *p;
int *index = NULL;
int i, num_indexes, bn_size;
if (!bn || !ctx) {
goto err;
}
if (!(dsa = X509_ALGOR_get1_DSA(param->pkey_algor))) {
goto err;
}
if ((num_indexes = CPK_MAP_num_indexes(param->map_algor)) <= 0) {
goto err;
}
if (!(index = OPENSSL_malloc(sizeof(int) * num_indexes))) {
goto err;
}
if (!CPK_MAP_str2index(param->map_algor, id, index)) {
goto err;
}
if (!dsa->pub_key) {
if (!(dsa->pub_key = BN_new())) {
goto err;
}
}
BN_zero(dsa->pub_key);
bn_size = BN_num_bytes(dsa->p);
for (i = 0; i < num_indexes; i++) {
p = ASN1_STRING_data(param->public_factors) + bn_size * index[i];
if (!BN_bin2bn(p, bn_size, bn)) {
goto err;
}
if (BN_is_zero(bn) || BN_cmp(bn, dsa->p) >= 0) {
goto err;
}
if (!BN_mod_add(dsa->pub_key, dsa->pub_key, bn, dsa->p, ctx)) {
goto err;
}
}
e = 0;
err:
if (e && dsa) {
DSA_free(dsa);
dsa = NULL;
}
if (bn) BN_free(bn);
if (ctx) BN_CTX_free(ctx);
if (index) OPENSSL_free(index);
return dsa;
}
static EC_KEY *X509_ALGOR_get1_EC_KEY(X509_ALGOR *algor)
{
@@ -715,9 +446,9 @@ static EC_KEY *X509_ALGOR_get1_EC_KEY(X509_ALGOR *algor)
int ptype;
const void *pval;
const unsigned char *p;
X509_ALGOR_get0(NULL, &ptype, &pval, algor);
if (ptype == V_ASN1_SEQUENCE) {
ASN1_OCTET_STRING *pstr = (ASN1_OCTET_STRING *)pval;
p = pstr->data;
@@ -725,14 +456,14 @@ static EC_KEY *X509_ALGOR_get1_EC_KEY(X509_ALGOR *algor)
CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, ERR_R_EC_LIB);
return NULL;
}
} else if (ptype == V_ASN1_OBJECT) {
ASN1_OBJECT *poid = (ASN1_OBJECT *)pval;
EC_GROUP *group;
if (!(ec_key = EC_KEY_new())) {
if (!(ec_key = EC_KEY_new())) {
CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, ERR_R_MALLOC_FAILURE);
return NULL;
}
}
if (!(group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)))) {
EC_KEY_free(ec_key);
CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, ERR_R_EC_LIB);
@@ -746,12 +477,12 @@ static EC_KEY *X509_ALGOR_get1_EC_KEY(X509_ALGOR *algor)
return NULL;
}
EC_GROUP_free(group);
} else {
CPKerr(CPK_F_X509_ALGOR_GET1_EC_KEY, CPK_R_BAD_DATA);
return NULL;
}
return ec_key;
return ec_key;
}
static int extract_ec_params(CPK_MASTER_SECRET *master, CPK_PUBLIC_PARAMS *param)
@@ -766,11 +497,11 @@ static int extract_ec_params(CPK_MASTER_SECRET *master, CPK_PUBLIC_PARAMS *param
int i, bn_size, pt_size, num_factors;
const unsigned char *bn_ptr;
unsigned char *pt_ptr;
if (!bn || !order || !ctx) {
goto err;
}
if (!(ec_key = X509_ALGOR_get1_EC_KEY(master->pkey_algor))) {
goto err;
}
@@ -780,7 +511,7 @@ static int extract_ec_params(CPK_MASTER_SECRET *master, CPK_PUBLIC_PARAMS *param
}
bn_size = BN_num_bytes(order);
pt_size = bn_size + 1;
if ((num_factors = CPK_MAP_num_factors(master->map_algor)) <= 0) {
goto err;
}
@@ -790,13 +521,13 @@ static int extract_ec_params(CPK_MASTER_SECRET *master, CPK_PUBLIC_PARAMS *param
if (!ASN1_STRING_set(param->public_factors, NULL, pt_size * num_factors)) {
goto err;
}
bn_ptr = ASN1_STRING_data(master->secret_factors);
pt_ptr = ASN1_STRING_data(param->public_factors);
memset(pt_ptr, 0, ASN1_STRING_length(param->public_factors));
if (!(pt = EC_POINT_new(ec_group))) {
goto err;
goto err;
}
for (i = 0; i < num_factors; i++) {
if (!BN_bin2bn(bn_ptr, bn_size, bn)) {
@@ -808,17 +539,17 @@ static int extract_ec_params(CPK_MASTER_SECRET *master, CPK_PUBLIC_PARAMS *param
if (!EC_POINT_mul(ec_group, pt, bn, NULL, NULL, ctx)) {
goto err;
}
if (!EC_POINT_point2oct(ec_group, pt,
if (!EC_POINT_point2oct(ec_group, pt,
POINT_CONVERSION_COMPRESSED, pt_ptr, pt_size, ctx)) {
goto err;
}
bn_ptr += bn_size;
pt_ptr += pt_size;
}
ret = 1;
err:
err:
if (ec_key) EC_KEY_free(ec_key);
if (bn) BN_free(bn);
if (order) BN_free(order);
@@ -827,8 +558,6 @@ err:
return ret;
}
static EC_KEY *extract_ec_priv_key(CPK_MASTER_SECRET *master, const char *id)
{
int e = 1;
@@ -842,11 +571,11 @@ static EC_KEY *extract_ec_priv_key(CPK_MASTER_SECRET *master, const char *id)
int *index = NULL;
int i, num_indexes, bn_size;
if (!priv_key || !bn || !order || !ctx) {
goto err;
}
if (!(ec_key = X509_ALGOR_get1_EC_KEY(master->pkey_algor))) {
goto err;
}
@@ -860,17 +589,17 @@ static EC_KEY *extract_ec_priv_key(CPK_MASTER_SECRET *master, const char *id)
}
if (!(index = OPENSSL_malloc(sizeof(int) * num_indexes))) {
goto err;
}
}
if (!CPK_MAP_str2index(master->map_algor, id, index)) {
goto err;
}
BN_zero(priv_key);
if (!(EC_GROUP_get_order(EC_KEY_get0_group(ec_key), order, ctx))) {
goto err;
}
bn_size = BN_num_bytes(order);
for (i = 0; i < num_indexes; i++) {
const unsigned char *p =
ASN1_STRING_data(master->secret_factors) +
@@ -897,7 +626,7 @@ static EC_KEY *extract_ec_priv_key(CPK_MASTER_SECRET *master, const char *id)
goto err;
}
e = 0;
err:
if (e && ec_key) {
EC_KEY_free(ec_key);
@@ -924,12 +653,12 @@ static EC_KEY *extract_ec_pub_key(CPK_PUBLIC_PARAMS *param, const char *id)
BN_CTX *ctx = BN_CTX_new();
int *index = NULL;
int i, bn_size, pt_size, num_indexes, num_factors;
if (!(ec_key = X509_ALGOR_get1_EC_KEY(param->pkey_algor))) {
goto err;
goto err;
}
ec_group = EC_KEY_get0_group(ec_key);
if (!(pub_key = EC_POINT_new(ec_group))) {
goto err;
}
@@ -953,7 +682,7 @@ static EC_KEY *extract_ec_pub_key(CPK_PUBLIC_PARAMS *param, const char *id)
}
if (!(index = OPENSSL_malloc(sizeof(int) * num_indexes))) {
goto err;
}
}
if (!CPK_MAP_str2index(param->map_algor, id, index)) {
goto err;
}
@@ -962,9 +691,9 @@ static EC_KEY *extract_ec_pub_key(CPK_PUBLIC_PARAMS *param, const char *id)
goto err;
}
for (i = 0; i < num_indexes; i++) {
const unsigned char *p =
ASN1_STRING_data(param->public_factors) +
pt_size * index[i];
const unsigned char *p =
ASN1_STRING_data(param->public_factors) +
pt_size * index[i];
if (!EC_POINT_oct2point(ec_group, pt, p, pt_size, ctx)) {
goto err;
@@ -990,5 +719,3 @@ err:
if (index) OPENSSL_free(index);
return ec_key;
}

View File

@@ -52,6 +52,7 @@
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/cpk.h>
#include "cpk_lcl.h"
X509_ALGOR *CPK_MAP_new_default()
{
@@ -175,4 +176,3 @@ err:
if (bn) BN_free(bn);
return ret;
}

View File

@@ -50,6 +50,7 @@
#include <string.h>
#include <openssl/bio.h>
#include <openssl/cpk.h>
#include "cpk_lcl.h"
int CPK_MASTER_SECRET_print(BIO *out, CPK_MASTER_SECRET *master,
int indent, unsigned long flags)

View File

@@ -45,6 +45,8 @@ static ERR_STRING_DATA EC_str_functs[] = {
{ERR_FUNC(EC_F_ECIES_PARAMS_GET_MAC), "ECIES_PARAMS_get_mac"},
{ERR_FUNC(EC_F_ECIES_PARAMS_INIT_WITH_RECOMMENDED),
"ECIES_PARAMS_init_with_recommended"},
{ERR_FUNC(EC_F_ECIES_PARAMS_INIT_WITH_TYPE),
"ECIES_PARAMS_init_with_type"},
{ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "eckey_param2type"},
{ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "eckey_param_decode"},
{ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "eckey_priv_decode"},
@@ -244,8 +246,8 @@ static ERR_STRING_DATA EC_str_functs[] = {
{ERR_FUNC(EC_F_SM2_DECRYPT), "SM2_decrypt"},
{ERR_FUNC(EC_F_SM2_DO_DECRYPT), "SM2_do_decrypt"},
{ERR_FUNC(EC_F_SM2_DO_ENCRYPT), "SM2_do_encrypt"},
{ERR_FUNC(EC_F_SM2_DO_SIGN), "sm2_do_sign"},
{ERR_FUNC(EC_F_SM2_DO_VERIFY), "sm2_do_verify"},
{ERR_FUNC(EC_F_SM2_DO_SIGN), "SM2_do_sign"},
{ERR_FUNC(EC_F_SM2_DO_VERIFY), "SM2_do_verify"},
{ERR_FUNC(EC_F_SM2_ENCRYPT), "SM2_encrypt"},
{ERR_FUNC(EC_F_SM2_ENC_PARAMS_DUP), "SM2_ENC_PARAMS_dup"},
{ERR_FUNC(EC_F_SM2_ENC_PARAMS_INIT_WITH_RECOMMENDED),
@@ -257,7 +259,7 @@ static ERR_STRING_DATA EC_str_functs[] = {
{ERR_FUNC(EC_F_SM2_KAP_CTX_INIT), "SM2_KAP_CTX_init"},
{ERR_FUNC(EC_F_SM2_KAP_FINAL_CHECK), "SM2_KAP_final_check"},
{ERR_FUNC(EC_F_SM2_KAP_PREPARE), "SM2_KAP_prepare"},
{ERR_FUNC(EC_F_SM2_SIGN_SETUP), "sm2_sign_setup"},
{ERR_FUNC(EC_F_SM2_SIGN_SETUP), "SM2_sign_setup"},
{ERR_FUNC(EC_F_TYPE1CURVE_EVAL_LINE_TEXTBOOK),
"type1curve_eval_line_textbook"},
{ERR_FUNC(EC_F_TYPE1CURVE_EVAL_MILLER_TEXTBOOK),
@@ -299,6 +301,7 @@ static ERR_STRING_DATA EC_str_reasons[] = {
{ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),
"ec group new by name failure"},
{ERR_REASON(EC_R_ENCRYPT_FAILED), "encrypt failed"},
{ERR_REASON(EC_R_ENCRYPT_FAILURE), "encrypt failure"},
{ERR_REASON(EC_R_ERROR), "error"},
{ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"},
{ERR_REASON(EC_R_GEN_MAC_FAILED), "gen mac failed"},
@@ -326,13 +329,16 @@ static ERR_STRING_DATA EC_str_reasons[] = {
{ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"},
{ERR_REASON(EC_R_INVALID_ECIES_CIPHERTEXT), "invalid ecies ciphertext"},
{ERR_REASON(EC_R_INVALID_ECIES_PARAMETERS), "invalid ecies parameters"},
{ERR_REASON(EC_R_INVALID_ECIES_PARAMS), "invalid ecies params"},
{ERR_REASON(EC_R_INVALID_EC_KEY), "invalid ec key"},
{ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"},
{ERR_REASON(EC_R_INVALID_ENC_PARAM), "invalid enc param"},
{ERR_REASON(EC_R_INVALID_ENC_TYPE), "invalid enc type"},
{ERR_REASON(EC_R_INVALID_FIELD), "invalid field"},
{ERR_REASON(EC_R_INVALID_FORM), "invalid form"},
{ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"},
{ERR_REASON(EC_R_INVALID_ID_LENGTH), "invalid id length"},
{ERR_REASON(EC_R_INVALID_INPUT_LENGTH), "invalid input length"},
{ERR_REASON(EC_R_INVALID_KDF_MD), "invalid kdf md"},
{ERR_REASON(EC_R_INVALID_KEY), "invalid key"},
{ERR_REASON(EC_R_INVALID_MD), "invalid md"},

View File

@@ -28,10 +28,10 @@ static const EC_KEY_METHOD openssl_ec_key_method = {
ossl_ecdsa_verify,
ossl_ecdsa_verify_sig,
#ifndef OPENSSL_NO_SM2
gmssl_ecies_encrypt,
gmssl_ecies_do_encrypt,
gmssl_ecies_decrypt,
gmssl_ecies_do_decrypt,
ECIES_encrypt,
NULL,
ECIES_decrypt,
NULL,
#endif
};

View File

@@ -41,13 +41,9 @@ typedef struct {
size_t kdf_outlen;
#ifndef OPENSSL_NO_SM2
int sign_type;
int exch_type;
int enc_type;
int dh_type;
union {
void *ptr;
ECIES_PARAMS *ecies;
SM2_ENC_PARAMS *sm2;
} enc_param;
int enc_param;
#endif
} EC_PKEY_CTX;
@@ -63,9 +59,9 @@ static int pkey_ec_init(EVP_PKEY_CTX *ctx)
dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE;
#ifndef OPENSSL_NO_SM2
dctx->sign_type = NID_secg_scheme;
dctx->exch_type = NID_secg_scheme;
dctx->enc_type = NID_secg_scheme;
dctx->dh_type = NID_secg_scheme;
dctx->enc_param.ptr = NULL;
dctx->enc_param = NID_undef;
#endif
ctx->data = dctx;
return 1;
@@ -102,23 +98,9 @@ static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
dctx->kdf_ukmlen = sctx->kdf_ukmlen;
#ifndef OPENSSL_NO_SM2
dctx->sign_type = sctx->sign_type;
dctx->exch_type = sctx->exch_type;
dctx->enc_type = sctx->enc_type;
dctx->dh_type = sctx->dh_type;
if (sctx->enc_param.ptr) {
if (sctx->enc_type == NID_secg_scheme) {
dctx->enc_param.ecies = ECIES_PARAMS_dup(sctx->enc_param.ecies);
if (!dctx->enc_param.ecies) {
return 0;
}
} else if (sctx->enc_type == NID_sm_scheme) {
dctx->enc_param.sm2 = SM2_ENC_PARAMS_dup(sctx->enc_param.sm2);
if (!dctx->enc_param.sm2) {
return 0;
}
} else {
return 0;
}
}
dctx->enc_param = sctx->enc_param;
#endif
return 1;
}
@@ -130,18 +112,6 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx)
EC_GROUP_free(dctx->gen_group);
EC_KEY_free(dctx->co_key);
OPENSSL_free(dctx->kdf_ukm);
#ifndef OPENSSL_NO_SM2
if (dctx->enc_param.ptr) {
if (dctx->enc_type == NID_secg_scheme) {
ECIES_PARAMS_free(dctx->enc_param.ecies);
} else if (dctx->enc_type == NID_sm_scheme) {
SM2_ENC_PARAMS_free(dctx->enc_param.sm2);
} else {
/* this should not happen */
OPENSSL_free(dctx->enc_param.ptr);
}
}
#endif
OPENSSL_free(dctx);
}
}
@@ -214,33 +184,17 @@ static int pkey_ec_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen
switch (dctx->enc_type) {
case NID_sm_scheme:
if (dctx->enc_param.sm2) {
if (!SM2_encrypt(dctx->enc_param.sm2, in, inlen, out, outlen, ec_key)) {
ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_SM2_ENCRYPT_FAILED);
return 0;
}
} else {
if (!SM2_encrypt_with_recommended(in, inlen, out, outlen, ec_key)) {
ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_SM2_ENCRYPT_WITH_RECOMMENDED_FAILED);
return 0;
}
if (!SM2_encrypt(dctx->enc_param, in, inlen, out, outlen, ec_key)) {
ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_SM2_ENCRYPT_FAILED);
return 0;
}
break;
case NID_secg_scheme:
if (dctx->enc_param.ecies) {
if (!ECIES_encrypt(dctx->enc_param.ecies, in, inlen, out, outlen, ec_key)) {
ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_ECIES_ENCRYPT_FAILED);
return 0;
}
} else {
if (!ECIES_encrypt_with_recommended(in, inlen, out, outlen, ec_key)) {
ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_ECIES_ENCRYPT_WITH_RECOMMENDED_FAILED);
return 0;
}
if (!ECIES_encrypt(dctx->enc_param, in, inlen, out, outlen, ec_key)) {
ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_ECIES_ENCRYPT_FAILED);
return 0;
}
break;
default:
ECerr(EC_F_PKEY_EC_ENCRYPT, EC_R_INVALID_ENC_TYPE);
return 0;
@@ -257,30 +211,15 @@ static int pkey_ec_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen
switch (dctx->enc_type) {
case NID_sm_scheme:
if (dctx->enc_param.sm2) {
if (!SM2_decrypt(dctx->enc_param.sm2, in, inlen, out, outlen, ec_key)) {
ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_SM2_DECRYPT_FAILED);
return 0;
}
} else {
if (!SM2_decrypt_with_recommended(in, inlen, out, outlen, ec_key)) {
ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_SM2_DECRYPT_WITH_RECOMMENDED_FAILED);
return 0;
}
if (!SM2_decrypt(dctx->enc_param, in, inlen, out, outlen, ec_key)) {
ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_SM2_DECRYPT_FAILED);
return 0;
}
break;
case NID_secg_scheme:
if (dctx->enc_param.ecies) {
if (!ECIES_decrypt(dctx->enc_param.ecies, in, inlen, out, outlen, ec_key)) {
ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_ECIES_DECRYPT_FAILED);
return 0;
}
} else {
if (!ECIES_decrypt_with_recommended(in, inlen, out, outlen, ec_key)) {
ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_ECIES_DECRYPT_WITH_RECOMMENDED_FAILED);
return 0;
}
if (!ECIES_decrypt(dctx->enc_param, in, inlen, out, outlen, ec_key)) {
ECerr(EC_F_PKEY_EC_DECRYPT, EC_R_ECIES_DECRYPT_FAILED);
return 0;
}
break;
@@ -325,7 +264,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
outlen = *keylen;
#ifndef OPENSSL_NO_SM2
if (dctx->dh_type == NID_sm_scheme)
if (dctx->exch_type == NID_sm_scheme)
ret = SM2_compute_key(key, outlen, pubkey, eckey, 0);
else
#endif
@@ -465,14 +404,14 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case EVP_PKEY_CTRL_EC_DH_TYPE:
if (p1 == -2)
return dctx->dh_type;
return dctx->exch_type;
if (p1 != NID_secg_scheme && p1 != NID_sm_scheme)
return -2;
dctx->dh_type = p1;
dctx->exch_type = p1;
return 1;
case EVP_PKEY_CTRL_GET_EC_DH_TYPE:
*(int *)p2 = dctx->dh_type;
*(int *)p2 = dctx->exch_type;
return 1;
#endif
@@ -556,6 +495,7 @@ static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx,
}
return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid);
#ifndef OPENSSL_NO_SM2
} else if (!strcmp(type, "signer")) {
} else if (!strcmp(type, "ec_sign_algor")) {
int sign_type;
if (!strcmp(value, "ecdsa"))

View File

@@ -121,18 +121,6 @@ int BN_GFP2_copy(BN_GFP2 *r, const BN_GFP2 *a)
return 1;
}
int BN_GFP2_zero(BN_GFP2 *a)
{
if (!a || !a->a0 || !a->a1) {
BNerr(BN_F_BN_GFP2_ZERO, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
BN_zero(a->a0);
BN_zero(a->a1);
return 1;
}
int BN_GFP2_one(BN_GFP2 *a)
{
if (!a || !a->a0 || !a->a1) {
@@ -145,6 +133,18 @@ int BN_GFP2_one(BN_GFP2 *a)
return 1;
}
int BN_GFP2_zero(BN_GFP2 *a)
{
if (!a || !a->a0 || !a->a1) {
BNerr(BN_F_BN_GFP2_ZERO, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
BN_zero(a->a0);
BN_zero(a->a1);
return 1;
}
/* return 1 on success, so dont use !BN_GFP2_is_zero() to check return value */
int BN_GFP2_is_zero(const BN_GFP2 *a)
{
@@ -156,26 +156,16 @@ int BN_GFP2_is_zero(const BN_GFP2 *a)
return (BN_is_zero(a->a0) && BN_is_zero(a->a1));
}
/*
* can we compare values on F_p^2 ?
*/
int BN_GFP2_cmp(const BN_GFP2 *a, const BN_GFP2 *b)
int BN_GFP2_equ(const BN_GFP2 *a, const BN_GFP2 *b)
{
if (!a || !b || !a->a0 || !a->a1 || !b->a0 || !b->a1) {
BNerr(BN_F_BN_GFP2_CMP, ERR_R_PASSED_NULL_PARAMETER);
return -1;
BNerr(BN_F_BN_GFP2_EQU, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
return ((BN_cmp(a->a0, b->a0) == 0) && (BN_cmp(a->a1, b->a1) == 0));
}
int BN_GFP2_equ(const BN_GFP2 *a, const BN_GFP2 *b)
{
//FIXME
return 0;
}
int BN_GFP2_add(BN_GFP2 *r, const BN_GFP2 *a, const BN_GFP2 *b,
const BIGNUM *p, BN_CTX *ctx)
{
@@ -416,6 +406,45 @@ end:
return ret;
}
int BN_bn2gfp2(const BIGNUM *bn, BN_GFP2 *gfp2, const BIGNUM *p, BN_CTX *ctx)
{
int ret = 0;
BIGNUM *a;
if (!(a = BN_CTX_get(ctx))) {
goto end;
}
BN_one(a);
if (!BN_lshift(a, a, BN_num_bytes(p)*8)) {
goto end;
}
if (!BN_rshift(gfp2->a1, bn, BN_num_bytes(p)*8)) {
goto end;
}
if (!BN_mod(gfp2->a0, bn, a, ctx)) {
goto end;
}
ret = 1;
end:
BN_CTX_end(ctx);
return ret;
}
/* return (a0 + a1 << 2^n), n = log_2(p), n % 8 == 0 */
int BN_gfp22bn(const BN_GFP2 *gfp2, BIGNUM *bn, const BIGNUM *p, BN_CTX *ctx)
{
if (!BN_lshift(bn, gfp2->a1, BN_num_bytes(p) * 8)) {
return 0;
}
if (!BN_add(bn, bn, gfp2->a0)) {
return 0;
}
return 1;
}
int BN_GFP2_canonical(const BN_GFP2 *a, unsigned char *out, size_t *outlen,
int order, const BIGNUM *p, BN_CTX *ctx)
{
@@ -462,42 +491,3 @@ int BN_GFP2_canonical(const BN_GFP2 *a, unsigned char *out, size_t *outlen,
*outlen = len;
return 1;
}
int BN_bn2gfp2(const BIGNUM *bn, BN_GFP2 *gfp2, const BIGNUM *p, BN_CTX *ctx)
{
int ret = 0;
BIGNUM *a;
if (!(a = BN_CTX_get(ctx))) {
goto end;
}
BN_one(a);
if (!BN_lshift(a, a, BN_num_bytes(p)*8)) {
goto end;
}
if (!BN_rshift(gfp2->a1, bn, BN_num_bytes(p)*8)) {
goto end;
}
if (!BN_mod(gfp2->a0, bn, a, ctx)) {
goto end;
}
ret = 1;
end:
BN_CTX_end(ctx);
return ret;
}
/* return (a0 + a1 << 2^n), n = log_2(p), n % 8 == 0 */
int BN_gfp22bn(const BN_GFP2 *gfp2, BIGNUM *bn, const BIGNUM *p, BN_CTX *ctx)
{
if (!BN_lshift(bn, gfp2->a1, BN_num_bytes(p) * 8)) {
return 0;
}
if (!BN_add(bn, bn, gfp2->a0)) {
return 0;
}
return 1;
}

View File

@@ -135,33 +135,3 @@ end:
OPENSSL_free(buf);
return ret;
}
#if 0
int main(void)
{
char *s = "This ASCII string without null-terminator";
BIGNUM *bn = NULL;
BIGNUM *ret = NULL;
BIGNUM *range = NULL;
BN_hex2bn(&range, "ffffffffffffffffffffefffffffffffffffffff");
BN_hex2bn(&bn, "79317c1610c1fc018e9c53d89d59c108cd518608");
if (!BN_hash2bn(&ret, s, strlen(s), EVP_sha1(), range)) {
printf("BN_hash2bn() function failed\n");
return 0;
}
if (!ret) {
printf("shit\n");
}
printf("%s\n", BN_bn2hex(ret));
if (BN_cmp(ret, bn) != 0) {
printf("BN_hash2bn() test failed\n");
return 0;
}
printf("BN_hash2bn() test passed\n");
return 1;
}
#endif

View File

@@ -60,6 +60,16 @@
* use it for fast check of solinas
*/
#define BN_SOLINAS_192V1 0
#define BN_SOLINAS_192V2 1
#define BN_SOLINAS_224V1 2
#define BN_SOLINAS_256V1 3
#define BN_SOLINAS_384V1 4
#define BN_SOLINAS_512V1 5
#define BN_SOLINAS_512V2 6
#define BN_SOLINAS_1024V1 7
#define BN_SOLINAS_1024V2 8
static BN_SOLINAS BN_solinas_table[] = {
{ 192, 16, -1, -1 },
{ 192, 64, -1, -1 },
@@ -92,7 +102,6 @@ static BN_SOLINAS BN_solinas_table[] = {
* 0xfffffffffbfffffffffffffffffffffffff
*/
int BN_bn2solinas(const BIGNUM *bn, BN_SOLINAS *solinas)
{
int ret = 0;
@@ -115,6 +124,7 @@ int BN_bn2solinas(const BIGNUM *bn, BN_SOLINAS *solinas)
}
solinas->c = BN_is_bit_set(bn, 1) ? 1 : -1;
if (BN_is_bit_set(bn, nbits - 1)) {
solinas->s = -1;
solinas->a = nbits;
@@ -133,10 +143,16 @@ end:
int BN_solinas2bn(const BN_SOLINAS *solinas, BIGNUM *bn)
{
int ret = 0;
#if 0
BIGNUM *tmp = NULL;
if (b <= 0 || a <= b || (s != 1 && s != -1) ||
(c != 1 && c != -1)) {
if (!solinas || !bn) {
BNerr(BN_F_BN_SOLINAS2BN, ERR_R_MALLOC_FAILURE);
return 0;
}
if (solinas->b <= 0 || solinas->a <= solinas->b
|| (solinas->s != 1 && solinas->s != -1)
|| (solinas->c != 1 && solinas->c != -1)) {
BNerr(BN_F_BN_SOLINAS2BN, BN_R_INVALID_SOLINAS_PARAMETERS);
return 0;
}
@@ -148,36 +164,38 @@ int BN_solinas2bn(const BN_SOLINAS *solinas, BIGNUM *bn)
BN_one(tmp);
if (!BN_lshift(solinas, tmp, a)) {
if (!BN_lshift(bn, tmp, solinas->a)) {
BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB);
goto end;
}
if (!BN_lshift(tmp, tmp, b)) {
if (!BN_lshift(tmp, tmp, solinas->b)) {
BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB);
goto end;
}
if (!BN_add_word(tmp, c)) {
if (!BN_add_word(tmp, solinas->c)) {
BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB);
goto end;
}
if (s > 0) {
if (!BN_add(solinas, solinas, tmp)) {
if (solinas->s > 0) {
if (!BN_add(bn, bn, tmp)) {
BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB);
goto end;
}
} else {
if (!BN_sub(solinas, solinas, tmp)) {
if (!BN_sub(bn, bn, tmp)) {
BNerr(BN_F_BN_SOLINAS2BN, ERR_R_BN_LIB);
goto end;
}
}
/* check if solinas is a prime */
/* check if it is a prime */
ret = 1;
end:
BN_free(tmp);
#endif
return ret;
}
@@ -191,3 +209,7 @@ int BN_is_solinas(const BIGNUM *a)
return 0;
}
BN_SOLINAS *BN_get_solinas(int index)
{
return NULL;
}

View File

@@ -1,3 +1,3 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=bn_gfp2.c bn_solinas.c bn_hash.c \
fppoint.c ec_expoint.c ec_hash.c ec_type1.c
fppoint.c ec_hash.c ec_type1.c

View File

@@ -51,8 +51,10 @@
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/bn_gfp2.h>
EC_GROUP *EC_GROUP_generate_type1curve(const BIGNUM *order, BN_CTX *bn_ctx)
{
ECerr(EC_F_EC_GROUP_GENERATE_TYPE1CURVE, 0);
@@ -781,3 +783,31 @@ int EC_type1curve_tate_ratio(const EC_GROUP *group, BN_GFP2 *r,
return 0;
}
typedef struct {
int security_bits;
int n_bits;
int p_bits;
int q_bits;
} TYPE1CURVE_SEC;
static TYPE1CURVE_SEC sec_tbl[] = {
/* k |n| |p| |q| */
{ 80, 1024, 512, 160},
{112, 2048, 1024, 224},
{128, 3072, 1536, 256},
{192, 7680, 3840, 384},
{256, 15360, 7680, 512}
};
const EVP_MD *TYPE1CURVE_nbits_to_md(int nbits)
{
switch (nbits) {
case 1024: return EVP_sha1();
case 2048: return EVP_sha224();
case 3072: return EVP_sha256();
case 7680: return EVP_sha384();
case 15360: return EVP_sha512();
}
return NULL;
}

View File

@@ -1,2 +1,2 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=ecies_asn1.c ecies_lib.c ecies_gmssl.c
SOURCE[../../libcrypto]=ecies_asn1.c ecies_lib.c

View File

@@ -57,6 +57,7 @@
#include <openssl/obj_mac.h>
#include <openssl/kdf2.h>
#include <openssl/ecies.h>
#include "ecies_lcl.h"
/*
* From SEC 1, Version 1.9 Draft, 2008

View File

@@ -1,128 +0,0 @@
/* ====================================================================
* Copyright (c) 2007 - 2017 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/rand.h>
#include <openssl/ecies.h>
static int ECIES_PARAMS_init_with_type(ECIES_PARAMS *params, int type)
{
return 0;
}
int gmssl_ecies_encrypt(int type, const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
ECIES_CIPHERTEXT_VALUE *cv = NULL;
ECIES_PARAMS params;
if (!ECIES_PARAMS_init_with_type(&params, type)) {
return 0;
}
RAND_seed(in, inlen);
if (!(cv = ECIES_do_encrypt(&params, in, inlen, ec_key))) {
*outlen = 0;
return 0;
}
*outlen = i2d_ECIES_CIPHERTEXT_VALUE(cv, &out);
ECIES_CIPHERTEXT_VALUE_free(cv);
return 1;
}
int gmssl_ecies_decrypt(int type, const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
ECIES_CIPHERTEXT_VALUE *cv = NULL;
ECIES_PARAMS params;
const unsigned char *cp = in;
unsigned char *der = NULL;
int derlen = -1;
int ret = -1;
if (!ECIES_PARAMS_init_with_type(&params, type)) {
return -1;
}
if (!(cv = d2i_ECIES_CIPHERTEXT_VALUE(NULL, &cp, inlen))) {
return -1;
}
derlen = i2d_ECIES_CIPHERTEXT_VALUE(cv, &der);
if (derlen != inlen || memcmp(in, der, derlen) != 0) {
goto end;
}
ret = ECIES_do_decrypt(&params, cv, out, outlen, ec_key);
end:
OPENSSL_clear_free(der, derlen);
ECIES_CIPHERTEXT_VALUE_free(cv);
return ret;
}
ECIES_CIPHERTEXT_VALUE *gmssl_ecies_do_encrypt(int type, const unsigned char *in,
size_t inlen, EC_KEY *ec_key)
{
ECIES_PARAMS param;
ECIES_PARAMS_init_with_recommended(&param);
return ECIES_do_encrypt(&param, in, inlen, ec_key);
}
int gmssl_ecies_do_decrypt(int type, const ECIES_CIPHERTEXT_VALUE *in,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
ECIES_PARAMS param;
ECIES_PARAMS_init_with_recommended(&param);
return ECIES_do_decrypt(&param, in, out, outlen, ec_key);
}

View File

@@ -50,6 +50,12 @@
#include <string.h>
#include <openssl/ecies.h>
struct ecies_ciphertext_value_st {
ASN1_OCTET_STRING *ephem_point;
ASN1_OCTET_STRING *ciphertext;
ASN1_OCTET_STRING *mactag;
};
int gmssl_ecies_encrypt(int type, const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
int gmssl_ecies_decrypt(int type, const unsigned char *in, size_t inlen,

View File

@@ -60,9 +60,40 @@
#include <openssl/kdf2.h>
#include <openssl/ecies.h>
#include "internal/o_str.h"
#include "ecies_lcl.h"
#define ECIES_ENC_RANDOM_IV 1
int ECIES_PARAMS_init_with_type(ECIES_PARAMS *params, int type)
{
if (!params) {
ECerr(EC_F_ECIES_PARAMS_INIT_WITH_TYPE, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
switch (type) {
case NID_ecies_with_x9_63_sha1_xor_hmac:
params->kdf_nid = NID_x9_63_kdf;
params->kdf_md = EVP_sha1();
params->enc_nid = NID_xor_in_ecies;
params->mac_nid = NID_hmac_full_ecies;
params->hmac_md = EVP_sha1();
break;
case NID_ecies_with_x9_63_sha256_xor_hmac:
params->kdf_nid = NID_x9_63_kdf;
params->kdf_md = EVP_sha256();
params->enc_nid = NID_xor_in_ecies;
params->mac_nid = NID_hmac_full_ecies;
params->hmac_md = EVP_sha256();
break;
default:
ECerr(EC_F_ECIES_PARAMS_INIT_WITH_TYPE, EC_R_INVALID_ECIES_PARAMS);
return 0;
}
return 1;
}
int ECIES_PARAMS_init_with_recommended(ECIES_PARAMS *param)
{
if (!param) {
@@ -80,37 +111,6 @@ int ECIES_PARAMS_init_with_recommended(ECIES_PARAMS *param)
return 1;
}
ECIES_PARAMS *ECIES_PARAMS_new(void)
{
ECIES_PARAMS *ret = NULL;
if (!(ret = OPENSSL_malloc(sizeof(*ret)))) {
return NULL;
}
ECIES_PARAMS_init_with_recommended(ret);
return ret;
}
ECIES_PARAMS *ECIES_PARAMS_dup(const ECIES_PARAMS *param)
{
ECIES_PARAMS *ret = NULL;
if (!(ret = OPENSSL_zalloc(sizeof(*ret)))) {
return NULL;
}
/* check param */
memcpy(ret, param, sizeof(*param));
return ret;
}
void ECIES_PARAMS_free(ECIES_PARAMS *param)
{
OPENSSL_free(param);
}
KDF_FUNC ECIES_PARAMS_get_kdf(const ECIES_PARAMS *param)
{
if (!param || !param->kdf_md) {
@@ -650,16 +650,22 @@ end:
return ret;
}
int ECIES_encrypt(const ECIES_PARAMS *param,
const unsigned char *in, size_t inlen,
int ECIES_encrypt(int type, const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
int ret = 0;
ECIES_PARAMS param;
ECIES_CIPHERTEXT_VALUE *cv = NULL;
unsigned char *p = out;
int len;
if (!(cv = ECIES_do_encrypt(param, in, inlen, ec_key))) {
if (!ECIES_PARAMS_init_with_type(&param, type)) {
ECerr(EC_F_ECIES_ENCRYPT, EC_R_INVALID_ENC_PARAM);
return 0;
}
RAND_seed(in, inlen);
if (!(cv = ECIES_do_encrypt(&param, in, inlen, ec_key))) {
ECerr(EC_F_ECIES_ENCRYPT, EC_R_ENCRYPT_FAILED);
return 0;
}
@@ -694,22 +700,40 @@ end:
return ret;
}
int ECIES_decrypt(const ECIES_PARAMS *param,
const unsigned char *in, size_t inlen,
int ECIES_decrypt(int type, const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
int ret = 0;
ECIES_PARAMS param;
ECIES_CIPHERTEXT_VALUE *cv = NULL;
const unsigned char *p = in;
if (!(cv = d2i_ECIES_CIPHERTEXT_VALUE(NULL, &p, (long)inlen))) {
ECerr(EC_F_ECIES_DECRYPT, EC_R_ENCRYPT_FAILED);
if (!in) {
ECerr(EC_F_ECIES_DECRYPT, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (!ECIES_do_decrypt(param, cv, out, outlen, ec_key)) {
ECerr(EC_F_ECIES_DECRYPT, EC_R_ENCRYPT_FAILED);
if (inlen <= 0 || inlen > INT_MAX) {
ECerr(EC_F_ECIES_DECRYPT, EC_R_INVALID_INPUT_LENGTH);
return 0;
}
if (!ECIES_PARAMS_init_with_type(&param, type)) {
ECerr(EC_F_ECIES_DECRYPT, EC_R_INVALID_ENC_PARAM);
return 0;
}
if (!(cv = d2i_ECIES_CIPHERTEXT_VALUE(NULL, &in, (long)inlen))) {
ECerr(EC_F_ECIES_DECRYPT, EC_R_INVALID_ECIES_CIPHERTEXT);
return 0;
}
if (inlen != i2d_ECIES_CIPHERTEXT_VALUE(cv, NULL)) {
ECerr(EC_F_ECIES_DECRYPT, EC_R_INVALID_ECIES_CIPHERTEXT);
goto end;
}
if (!ECIES_do_decrypt(&param, cv, out, outlen, ec_key)) {
ECerr(EC_F_ECIES_DECRYPT, EC_R_ENCRYPT_FAILURE);
goto end;
}
@@ -718,21 +742,3 @@ end:
ECIES_CIPHERTEXT_VALUE_free(cv);
return ret;
}
int ECIES_encrypt_with_recommended(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
ECIES_PARAMS param;
ECIES_PARAMS_init_with_recommended(&param);
return ECIES_encrypt(&param, in, inlen, out, outlen, ec_key);
}
int ECIES_decrypt_with_recommended(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
ECIES_PARAMS param;
ECIES_PARAMS_init_with_recommended(&param);
return ECIES_decrypt(&param, in, inlen, out, outlen, ec_key);
}

View File

@@ -67,6 +67,7 @@ static ERR_STRING_DATA ERR_str_libraries[] = {
{ERR_PACK(ERR_LIB_GMAPI, 0, 0), "GMAPI routines"},
{ERR_PACK(ERR_LIB_BFIBE, 0, 0), "BFIBE routines"},
{ERR_PACK(ERR_LIB_BB1IBE, 0, 0), "BB1IBE routines"},
{ERR_PACK(ERR_LIB_SM2, 0, 0), "SM2 routines"},
{ERR_PACK(ERR_LIB_SM9, 0, 0), "SM9 routines"},
{ERR_PACK(ERR_LIB_SAF, 0, 0), "SAF routines"},
{ERR_PACK(ERR_LIB_SDF, 0, 0), "SDF routines"},
@@ -124,6 +125,7 @@ static ERR_STRING_DATA ERR_str_reasons[] = {
{ERR_R_GMAPI_LIB, "GMAPI lib"},
{ERR_R_BFIBE_LIB, "BFIBE lib"},
{ERR_R_BB1IBE_LIB, "BB1IBE lib"},
{ERR_R_SM2_LIB, "SM2 lib"},
{ERR_R_SM9_LIB, "SM9 lib"},
{ERR_R_SAF_LIB, "SAF lib"},
{ERR_R_SDF_LIB, "SDF lib"},

View File

@@ -47,6 +47,7 @@
#include <openssl/gmapi.h>
#include <openssl/bfibe.h>
#include <openssl/bb1ibe.h>
#include <openssl/sm2.h>
#include <openssl/sm9.h>
#include <openssl/gmsaf.h>
#include <openssl/gmsdf.h>
@@ -138,6 +139,9 @@ int err_load_crypto_strings_int(void)
# ifndef OPENSSL_NO_BB1IBE
ERR_load_BB1IBE_strings() == 0 ||
# endif
# ifndef OPENSSL_NO_SM2
ERR_load_SM2_strings() == 0 ||
# endif
# ifndef OPENSSL_NO_SM9
ERR_load_SM9_strings() == 0 ||
# endif

View File

@@ -43,6 +43,7 @@ L OTP include/openssl/otp.h crypto/otp/otp_err.c
L GMAPI include/openssl/gmapi.h crypto/gmapi/gmapi_err.c
L BFIBE include/openssl/bfibe.h crypto/bfibe/bfibe_err.c
L BB1IBE include/openssl/bb1ibe.h crypto/bb1ibe/bb1ibe_err.c
L SM2 include/openssl/sm2.h crypto/sm2/sm2_err.c
L SM9 include/openssl/sm9.h crypto/sm9/sm9_err.c
L SAF include/openssl/gmsaf.h crypto/saf/saf_err.c
L SDF include/openssl/gmsdf.h crypto/sdf/sdf_err.c

View File

@@ -145,7 +145,16 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return ctx->update(ctx, data, count);
#ifndef OPENSSL_NO_SM2
if (!ctx->is_updated && ctx->pctx && ctx->pctx->pre_update) {
if (!ctx->update(ctx, ctx->pctx->pre_update,
ctx->pctx->pre_update_len)) {
return 0;
}
}
ctx->is_updated = 1;
#endif
return ctx->update(ctx, data, count);
}
/* The caller can assume that this removes any secret data from the context */

View File

@@ -19,6 +19,7 @@ struct evp_md_ctx_st {
EVP_PKEY_CTX *pctx;
/* Update function: usually copied from EVP_MD */
int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
int is_updated;
} /* EVP_MD_CTX */ ;
struct evp_cipher_ctx_st {

View File

@@ -10,13 +10,15 @@
#include <stdio.h>
#include "internal/cryptlib.h"
#ifndef OPENSSL_NO_SHA1
#ifndef OPENSSL_NO_SHA
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/sha.h>
#include <openssl/rsa.h>
#include "internal/evp_int.h"
# include <openssl/evp.h>
# include <openssl/objects.h>
# include <openssl/sha.h>
# ifndef OPENSSL_NO_RSA
# include <openssl/rsa.h>
# endif
# include "internal/evp_int.h"
static int init(EVP_MD_CTX *ctx)
{
@@ -112,6 +114,7 @@ const EVP_MD *EVP_sha1(void)
return (&sha1_md);
}
# ifndef OPENSSL_NO_SHA256
static int init224(EVP_MD_CTX *ctx)
{
return SHA224_Init(EVP_MD_CTX_md_data(ctx));
@@ -174,7 +177,9 @@ const EVP_MD *EVP_sha256(void)
{
return (&sha256_md);
}
# endif
# ifndef OPENSSL_NO_SHA512
static int init384(EVP_MD_CTX *ctx)
{
return SHA384_Init(EVP_MD_CTX_md_data(ctx));
@@ -233,4 +238,5 @@ const EVP_MD *EVP_sha512(void)
{
return (&sha512_md);
}
# endif
#endif

View File

@@ -48,14 +48,14 @@
*/
#include <stdio.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/objects.h>
#include "internal/cryptlib.h"
#include "internal/evp_int.h"
#ifndef OPENSSL_NO_SM3
# include <openssl/evp.h>
# include <openssl/x509.h>
# include <openssl/objects.h>
# include <openssl/sm3.h>
# include "internal/evp_int.h"
static int init(EVP_MD_CTX *ctx)
{

View File

@@ -1,3 +1,51 @@
/* ====================================================================
* Copyright (c) 2014 - 2017 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
/*
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
*
@@ -13,24 +61,37 @@
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/sm2.h>
int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl,
EVP_PKEY *priv)
{
int ret = -1;
int ret = 0;
EVP_PKEY_CTX *ctx = NULL;
size_t siz;
#ifndef OPENSSL_NO_RSA
if (EVP_PKEY_id(priv) != EVP_PKEY_RSA) {
if (EVP_PKEY_id(priv) == EVP_PKEY_RSA) {
if ((ret = RSA_private_decrypt(ekl, ek, key, EVP_PKEY_get0_RSA(priv), RSA_PKCS1_PADDING)) < 0) {
EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, ERR_R_RSA_LIB);
return 0;
}
}
#endif
EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA);
#ifndef OPENSSL_NO_RSA
goto err;
}
ret =
RSA_private_decrypt(ekl, ek, key, EVP_PKEY_get0_RSA(priv),
RSA_PKCS1_PADDING);
err:
#ifndef OPENSSL_NO_SM2
if (!(ctx = EVP_PKEY_CTX_new(priv, NULL))
|| !EVP_PKEY_decrypt_init(ctx)
|| !EVP_PKEY_CTX_set_ec_enc_type(ctx, NID_sm_scheme)
|| !EVP_PKEY_decrypt(ctx, key, &siz, ek, ekl)) {
EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, ERR_R_EVP_LIB);
goto end;
}
ret = (int)siz;
#endif
return (ret);
end:
EVP_PKEY_CTX_free(ctx);
return (ret);
}

View File

@@ -61,6 +61,7 @@
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/sm2.h>
int EVP_PKEY_encrypt_old(unsigned char *out, const unsigned char *in,
int inlen, EVP_PKEY *pkey)

View File

@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2017 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
@@ -139,6 +139,18 @@ static ERR_STRING_DATA GMAPI_str_functs[] = {
{ERR_FUNC(GMAPI_F_SKF_MACINIT), "SKF_MacInit"},
{ERR_FUNC(GMAPI_F_SKF_MACUPDATE), "SKF_MacUpdate"},
{ERR_FUNC(GMAPI_F_SKF_SETSYMMKEY), "SKF_SetSymmKey"},
{ERR_FUNC(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER),
"SM2CiphertextValue_get_ECCCipher"},
{ERR_FUNC(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHERBLOB),
"SM2CiphertextValue_get_ECCCIPHERBLOB"},
{ERR_FUNC(GMAPI_F_SM2CIPHERTEXTVALUE_NEW_FROM_ECCCIPHER),
"SM2CiphertextValue_new_from_ECCCipher"},
{ERR_FUNC(GMAPI_F_SM2CIPHERTEXTVALUE_NEW_FROM_ECCCIPHERBLOB),
"SM2CiphertextValue_new_from_ECCCIPHERBLOB"},
{ERR_FUNC(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER),
"SM2CiphertextValue_set_ECCCipher"},
{ERR_FUNC(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHERBLOB),
"SM2CiphertextValue_set_ECCCIPHERBLOB"},
{ERR_FUNC(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER),
"SM2_CIPHERTEXT_VALUE_get_ECCCipher"},
{ERR_FUNC(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHERBLOB),

View File

@@ -288,40 +288,39 @@ int EC_KEY_get_ECCrefPrivateKey(EC_KEY *ec_key, ECCrefPrivateKey *ref)
return 1;
}
SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_new_from_ECCCipher(
const ECCCipher *ref)
SM2CiphertextValue *SM2CiphertextValue_new_from_ECCCipher(const ECCCipher *ref)
{
SM2_CIPHERTEXT_VALUE *ret = NULL;
SM2_CIPHERTEXT_VALUE *cv = NULL;
SM2CiphertextValue *ret = NULL;
SM2CiphertextValue *cv = NULL;
EC_GROUP *group = NULL;
/* check arguments */
if (!ref) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_NEW_FROM_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_NEW_FROM_ECCCIPHER,
ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (ref->L > INT_MAX) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_NEW_FROM_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_NEW_FROM_ECCCIPHER,
GMAPI_R_INVALID_CIPHETEXT_LENGTH);
return NULL;
}
/* ECCCipher => SM2_CIPHERTEXT_VALUE */
/* ECCCipher => SM2CiphertextValue */
if (!(group = EC_GROUP_new_by_curve_name(NID_sm2p256v1))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_NEW_FROM_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_NEW_FROM_ECCCIPHER,
ERR_R_EC_LIB);
goto end;
}
if (!(cv = SM2_CIPHERTEXT_VALUE_new(group))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_NEW_FROM_ECCCIPHER,
if (!(cv = SM2CiphertextValue_new(group))) {
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_NEW_FROM_ECCCIPHER,
GMAPI_R_MALLOC_FAILED);
goto end;
}
if (!SM2_CIPHERTEXT_VALUE_set_ECCCipher(cv, ref)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_NEW_FROM_ECCCIPHER,
if (!SM2CiphertextValue_set_ECCCipher(cv, ref)) {
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_NEW_FROM_ECCCIPHER,
GMAPI_R_INVALID_SM2_CIPHERTEXT);
goto end;
}
@@ -331,7 +330,7 @@ SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_new_from_ECCCipher(
end:
EC_GROUP_free(group);
SM2_CIPHERTEXT_VALUE_free(cv);
SM2CiphertextValue_free(cv);
return ret;
}
@@ -344,7 +343,7 @@ end:
* implementations, developers have to check the encoding of the vendor's
* library to make sure the encoding/decoding is correct
*/
int SM2_CIPHERTEXT_VALUE_set_ECCCipher(SM2_CIPHERTEXT_VALUE *cv,
int SM2CiphertextValue_set_ECCCipher(SM2CiphertextValue *cv,
const ECCCipher *ref)
{
int ret = 0;
@@ -356,20 +355,20 @@ int SM2_CIPHERTEXT_VALUE_set_ECCCipher(SM2_CIPHERTEXT_VALUE *cv,
/* check arguments */
if (!cv || !ref) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
/* variables */
if (!(group = EC_GROUP_new_by_curve_name(NID_sm2p256v1))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER,
ERR_R_EC_LIB);
goto end;
}
/* this will never happen with GmSSL's sdf.h */
if (EC_GROUP_get_degree(group) > ECCref_MAX_BITS) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER,
GMAPI_R_INVALID_KEY_LENGTH);
goto end;
}
@@ -377,7 +376,7 @@ int SM2_CIPHERTEXT_VALUE_set_ECCCipher(SM2_CIPHERTEXT_VALUE *cv,
/* malloc */
if (!(bn_ctx = BN_CTX_new())) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER,
ERR_R_MALLOC_FAILURE);
goto end;
}
@@ -385,36 +384,37 @@ int SM2_CIPHERTEXT_VALUE_set_ECCCipher(SM2_CIPHERTEXT_VALUE *cv,
x = BN_CTX_get(bn_ctx);
y = BN_CTX_get(bn_ctx);
if (!x || !y) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER,
ERR_R_MALLOC_FAILURE);
goto end;
}
/* ECCCipher ==> SM2_CIPHERTEXT_VALUE */
if (!BN_bin2bn(ref->x, ECCref_MAX_LEN, x)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHER,
/* ECCCipher ==> SM2CiphertextValue */
if (!BN_bin2bn(ref->x, ECCref_MAX_LEN, cv->xCoordinate)) {
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER,
ERR_R_BN_LIB);
goto end;
}
if (!BN_bin2bn(ref->y, ECCref_MAX_LEN, y)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHER,
if (!BN_bin2bn(ref->y, ECCref_MAX_LEN, cv->yCoordinate)) {
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER,
ERR_R_BN_LIB);
goto end;
}
if (!cv->ephem_point) {
if (!(cv->ephem_point = EC_POINT_new(group))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHER, ERR_R_EC_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER, ERR_R_EC_LIB);
goto end;
}
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
if (!EC_POINT_set_affine_coordinates_GFp(group, cv->ephem_point, x, y, bn_ctx)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHER, ERR_R_EC_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER, ERR_R_EC_LIB);
goto end;
}
} else {
if (!EC_POINT_get_affine_coordinates_GF2m(group, cv->ephem_point, x, y, bn_ctx)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHER, ERR_R_EC_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER, ERR_R_EC_LIB);
goto end;
}
}
@@ -423,14 +423,14 @@ int SM2_CIPHERTEXT_VALUE_set_ECCCipher(SM2_CIPHERTEXT_VALUE *cv,
memcpy(cv->mactag, ref->M, 32);
if (ref->L <= 0 || ref->L > INT_MAX) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER,
GMAPI_R_INVALID_CIPHERTEXT_LENGTH);
goto end;
}
cv->ciphertext_size = (size_t)ref->L;
if (!(cv->ciphertext = OPENSSL_realloc(cv->ciphertext, (size_t)ref->L))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHER,
GMAPI_R_MALLOC_FAILED);
goto end;
}
@@ -459,7 +459,7 @@ end:
* use the vendor's header file. Then the errors can be found by the
* compiler.
*/
int SM2_CIPHERTEXT_VALUE_get_ECCCipher(const SM2_CIPHERTEXT_VALUE *cv,
int SM2CiphertextValue_get_ECCCipher(const SM2CiphertextValue *cv,
ECCCipher *ref)
{
int ret = 0;
@@ -470,7 +470,7 @@ int SM2_CIPHERTEXT_VALUE_get_ECCCipher(const SM2_CIPHERTEXT_VALUE *cv,
/* check arguments */
if (!cv || !ref) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -480,19 +480,19 @@ int SM2_CIPHERTEXT_VALUE_get_ECCCipher(const SM2_CIPHERTEXT_VALUE *cv,
* ciphertext
*/
if (ref->L < cv->ciphertext_size) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER,
GMAPI_R_BUFFER_TOO_SMALL);
return 0;
}
/* malloc */
if (!(group = EC_GROUP_new_by_curve_name(NID_sm2p256v1))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER, ERR_R_EC_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER, ERR_R_EC_LIB);
return 0;
}
if (!(bn_ctx = BN_CTX_new())) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER, ERR_R_BN_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER, ERR_R_BN_LIB);
goto end;
}
@@ -500,53 +500,53 @@ int SM2_CIPHERTEXT_VALUE_get_ECCCipher(const SM2_CIPHERTEXT_VALUE *cv,
x = BN_CTX_get(bn_ctx);
y = BN_CTX_get(bn_ctx);
if (!x || !y) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER,
ERR_R_MALLOC_FAILURE);
goto end;
}
/* SM2_CIPHERTEXT_VALUE ==> ECCCipher */
/* SM2CiphertextValue ==> ECCCipher */
memset(ref, 0, sizeof(*ref));
/* encode ephem point `ECCCipher->x`, `ECCCipher->y` */
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(group, cv->ephem_point, x, y, bn_ctx)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER, ERR_R_EC_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER, ERR_R_EC_LIB);
goto end;
}
} else {
if (!EC_POINT_get_affine_coordinates_GF2m(group, cv->ephem_point, x, y, bn_ctx)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER,
ERR_R_EC_LIB);
goto end;
}
}
/*
* check compatible of SM2_CIPHERTEXT_VALUE with EC_GROUP
* check compatible of SM2CiphertextValue with EC_GROUP
* In gmapi we only do simple checks, i.e. length of coordinates.
* We assume that more checks, such as x, y in the range of [1, p]
* and other semantic checks should be done by the `sm2` module.
*/
if (BN_num_bits(x) > EC_GROUP_get_degree(group) ||
BN_num_bits(y) > EC_GROUP_get_degree(group)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER,
GMAPI_R_INVALID_CIPHERTEXT_POINT);
goto end;
}
if (!BN_bn2bin(x, ref->x + ECCref_MAX_LEN - BN_num_bytes(x))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER,
ERR_R_BN_LIB);
goto end;
}
if (!BN_bn2bin(y, ref->y + ECCref_MAX_LEN - BN_num_bytes(y))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER,
ERR_R_BN_LIB);
goto end;
}
/* encode mac `ECCCipher->M[32]` */
if (cv->mactag_size != 32) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER,
GMAPI_R_INVALID_CIPHERTEXT_MAC);
goto end;
}
@@ -554,7 +554,7 @@ int SM2_CIPHERTEXT_VALUE_get_ECCCipher(const SM2_CIPHERTEXT_VALUE *cv,
/* encode ciphertext `ECCCipher->L`, `ECCCipher->C[]` */
if (cv->ciphertext_size <= 0 || cv->ciphertext_size > INT_MAX) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHER,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHER,
GMAPI_R_INVALID_CIPHERTEXT_LENGTH);
goto end;
}
@@ -693,4 +693,3 @@ int ECDSA_SIG_get_ECCSignature(const ECDSA_SIG *sig, ECCSignature *ref)
return 1;
}

View File

@@ -0,0 +1,15 @@
crypto/gmapi/gmapi_sdf_ec.o: crypto/gmapi/gmapi_sdf_ec.c \
include/openssl/ec.h include/openssl/opensslconf.h \
include/openssl/asn1.h include/openssl/e_os2.h include/openssl/bio.h \
include/openssl/crypto.h include/openssl/stack.h \
include/openssl/safestack.h include/openssl/opensslv.h \
include/openssl/ossl_typ.h include/openssl/symhacks.h \
include/openssl/bn.h include/openssl/err.h include/openssl/lhash.h \
include/openssl/sdf.h include/openssl/sgd.h include/openssl/gmapi.h \
include/openssl/sm2.h include/openssl/evp.h include/openssl/objects.h \
include/openssl/obj_mac.h include/openssl/kdf2.h include/openssl/kdf.h \
include/openssl/x509.h include/openssl/buffer.h \
include/openssl/paillier.h include/openssl/rsa.h include/openssl/dsa.h \
include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \
include/openssl/pkcs7.h include/openssl/ecies.h include/openssl/sm3.h \
include/openssl/saf.h include/openssl/skf.h include/openssl/sof.h

View File

@@ -250,27 +250,27 @@ end:
return ret;
}
SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_new_from_ECCCIPHERBLOB(
SM2CiphertextValue *SM2CiphertextValue_new_from_ECCCIPHERBLOB(
const ECCCIPHERBLOB *blob)
{
int ok = 0;
SM2_CIPHERTEXT_VALUE *ret = NULL;
SM2CiphertextValue *ret = NULL;
EC_GROUP *group = NULL;
if (!(group = EC_GROUP_new_by_curve_name(NID_sm2p256v1))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_NEW_FROM_ECCCIPHERBLOB,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_NEW_FROM_ECCCIPHERBLOB,
ERR_R_EC_LIB);
goto end;
}
if (!(ret = SM2_CIPHERTEXT_VALUE_new(group))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_NEW_FROM_ECCCIPHERBLOB,
if (!(ret = SM2CiphertextValue_new(group))) {
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_NEW_FROM_ECCCIPHERBLOB,
GMAPI_R_MALLOC_FAILED);
goto end;
}
if (!SM2_CIPHERTEXT_VALUE_set_ECCCIPHERBLOB(ret, blob)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_NEW_FROM_ECCCIPHERBLOB,
if (!SM2CiphertextValue_set_ECCCIPHERBLOB(ret, blob)) {
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_NEW_FROM_ECCCIPHERBLOB,
GMAPI_R_INVALID_EC_PUBLIC_KEY);
goto end;
}
@@ -279,14 +279,14 @@ SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_new_from_ECCCIPHERBLOB(
end:
if (!ok) {
SM2_CIPHERTEXT_VALUE_free(ret);
SM2CiphertextValue_free(ret);
ret = NULL;
}
EC_GROUP_free(group);
return ret;
}
int SM2_CIPHERTEXT_VALUE_set_ECCCIPHERBLOB(SM2_CIPHERTEXT_VALUE *cv,
int SM2CiphertextValue_set_ECCCIPHERBLOB(SM2CiphertextValue *cv,
const ECCCIPHERBLOB *blob)
{
int ret = 0;
@@ -297,45 +297,45 @@ int SM2_CIPHERTEXT_VALUE_set_ECCCIPHERBLOB(SM2_CIPHERTEXT_VALUE *cv,
int nbytes;
if (!(group = EC_GROUP_new_by_curve_name(NID_sm2p256v1))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHERBLOB,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHERBLOB,
ERR_R_EC_LIB);
return 0;
}
nbytes = (EC_GROUP_get_degree(group) + 7)/8;
if (nbytes > ECC_MAX_XCOORDINATE_BITS_LEN/8) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHERBLOB,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHERBLOB,
GMAPI_R_INVALID_KEY_LENGTH);
goto end;
}
if (!(x = BN_bin2bn(blob->XCoordinate, nbytes, NULL))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHERBLOB, ERR_R_BN_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHERBLOB, ERR_R_BN_LIB);
goto end;
}
if (!(y = BN_bin2bn(blob->YCoordinate, nbytes, NULL))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHERBLOB, ERR_R_BN_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHERBLOB, ERR_R_BN_LIB);
goto end;
}
if (!(bn_ctx = BN_CTX_new())) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHERBLOB, ERR_R_BN_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHERBLOB, ERR_R_BN_LIB);
goto end;
}
if (!cv->ephem_point) {
if (!(cv->ephem_point = EC_POINT_new(group))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHERBLOB, ERR_R_EC_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHERBLOB, ERR_R_EC_LIB);
goto end;
}
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
if (!EC_POINT_set_affine_coordinates_GFp(group, cv->ephem_point, x, y, bn_ctx)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHERBLOB, ERR_R_EC_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHERBLOB, ERR_R_EC_LIB);
goto end;
}
} else {
if (!EC_POINT_get_affine_coordinates_GF2m(group, cv->ephem_point, x, y, bn_ctx)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHERBLOB, ERR_R_EC_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHERBLOB, ERR_R_EC_LIB);
goto end;
}
}
@@ -344,12 +344,12 @@ int SM2_CIPHERTEXT_VALUE_set_ECCCIPHERBLOB(SM2_CIPHERTEXT_VALUE *cv,
cv->mactag_size = 32;
if ((cv->ciphertext_size = blob->CipherLen) <= 0) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHERBLOB,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHERBLOB,
GMAPI_R_INVALID_CIPHERTEXT_LENGTH);
goto end;
}
if (!(cv->ciphertext = OPENSSL_realloc(cv->ciphertext, blob->CipherLen))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_SET_ECCCIPHERBLOB,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_SET_ECCCIPHERBLOB,
GMAPI_R_MALLOC_FAILED);
goto end;
}
@@ -365,7 +365,7 @@ end:
return ret;
}
int SM2_CIPHERTEXT_VALUE_get_ECCCIPHERBLOB(const SM2_CIPHERTEXT_VALUE *cv,
int SM2CiphertextValue_get_ECCCIPHERBLOB(const SM2CiphertextValue *cv,
ECCCIPHERBLOB *blob)
{
int ret = 0;
@@ -375,7 +375,7 @@ int SM2_CIPHERTEXT_VALUE_get_ECCCIPHERBLOB(const SM2_CIPHERTEXT_VALUE *cv,
BN_CTX *bn_ctx = NULL;
if (!(group = EC_GROUP_new_by_curve_name(NID_sm2p256v1))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHERBLOB, ERR_R_EC_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHERBLOB, ERR_R_EC_LIB);
return 0;
}
@@ -383,45 +383,45 @@ int SM2_CIPHERTEXT_VALUE_get_ECCCIPHERBLOB(const SM2_CIPHERTEXT_VALUE *cv,
y = BN_new();
bn_ctx = BN_CTX_new();
if (!x || !y || !bn_ctx) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHERBLOB, ERR_R_BN_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHERBLOB, ERR_R_BN_LIB);
goto end;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(group, cv->ephem_point, x, y, bn_ctx)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHERBLOB, ERR_R_EC_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHERBLOB, ERR_R_EC_LIB);
goto end;
}
} else {
if (!EC_POINT_get_affine_coordinates_GF2m(group, cv->ephem_point, x, y, bn_ctx)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHERBLOB, ERR_R_EC_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHERBLOB, ERR_R_EC_LIB);
goto end;
}
}
if ((BN_num_bytes(x) > 256/8) || (BN_num_bytes(y) > 256/8)) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHERBLOB,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHERBLOB,
GMAPI_R_INVALID_CIPHERTEXT_POINT);
goto end;
}
if (!BN_bn2bin(x, blob->XCoordinate + 256/8 - BN_num_bytes(x))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHERBLOB, ERR_R_BN_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHERBLOB, ERR_R_BN_LIB);
goto end;
}
if (!BN_bn2bin(y, blob->YCoordinate + 256/8 - BN_num_bytes(y))) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHERBLOB, ERR_R_BN_LIB);
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHERBLOB, ERR_R_BN_LIB);
goto end;
}
if (cv->mactag_size != 32) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHERBLOB,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHERBLOB,
GMAPI_R_INVALID_CIPHERTEXT_MAC);
goto end;
}
memcpy(blob->HASH, cv->mactag, cv->mactag_size);
if (cv->ciphertext_size <= 0) {
GMAPIerr(GMAPI_F_SM2_CIPHERTEXT_VALUE_GET_ECCCIPHERBLOB,
GMAPIerr(GMAPI_F_SM2CIPHERTEXTVALUE_GET_ECCCIPHERBLOB,
GMAPI_R_INVALID_CIPHERTEXT_LENGTH);
goto end;
}

View File

@@ -27,6 +27,10 @@ struct evp_pkey_ctx_st {
/* implementation specific keygen data */
int *keygen_info;
int keygen_info_count;
#ifndef OPENSSL_NO_SM2
unsigned char *pre_update;
size_t pre_update_len;
#endif
} /* EVP_PKEY_CTX */ ;
#define EVP_PKEY_FLAG_DYNAMIC 1

View File

@@ -10,7 +10,7 @@
*/
/* Serialized OID's */
static const unsigned char so[7486] = {
static const unsigned char so[7733] = {
0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */
@@ -1053,9 +1053,40 @@ static const unsigned char so[7486] = {
0x2B,0x06,0x01,0x04,0x01,0x83,0x83,0x0D,0x01,0x01,0x01, /* [ 7452] OBJ_cpk_sha1_map */
0x2B,0x06,0x01,0x04,0x01,0x83,0x83,0x0D,0x01,0x01,0x02, /* [ 7463] OBJ_cpk_sha256_map */
0x2B,0x06,0x01,0x04,0x01,0x83,0x83,0x0D,0x01,0x01,0x03, /* [ 7474] OBJ_cpk_sm3_map */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,0x02,0x01, /* [ 7485] OBJ_sm2encrypt_with_sm3 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,0x02,0x02, /* [ 7496] OBJ_sm2encrypt_with_sha1 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,0x02,0x03, /* [ 7507] OBJ_sm2encrypt_with_sha224 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,0x02,0x04, /* [ 7518] OBJ_sm2encrypt_with_sha256 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,0x02,0x05, /* [ 7529] OBJ_sm2encrypt_with_sha384 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,0x02,0x06, /* [ 7540] OBJ_sm2encrypt_with_sha512 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,0x02,0x07, /* [ 7551] OBJ_sm2encrypt_with_rmd160 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,0x02,0x08, /* [ 7562] OBJ_sm2encrypt_with_whirlpool */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,0x02,0x09, /* [ 7573] OBJ_sm2encrypt_with_blake2b512 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,0x02,0x0A, /* [ 7584] OBJ_sm2encrypt_with_blake2s256 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,0x02,0x0B, /* [ 7595] OBJ_sm2encrypt_with_md5 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x84,0x08, /* [ 7606] OBJ_sm2sign_with_whirlpool */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x84,0x09, /* [ 7614] OBJ_sm2sign_with_blake2b512 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x84,0x0A, /* [ 7622] OBJ_sm2sign_with_blake2s256 */
0x2B,0x81,0x04,0x01,0x08,0x01, /* [ 7630] OBJ_ecies_with_x9_63_sha1_xor_hmac */
0x2B,0x81,0x04,0x01,0x08,0x02, /* [ 7636] OBJ_ecies_with_x9_63_sha256_xor_hmac */
0x2B,0x81,0x04,0x01,0x08,0x03, /* [ 7642] OBJ_ecies_with_x9_63_sha512_xor_hmac */
0x2B,0x81,0x04,0x01,0x08,0x04, /* [ 7648] OBJ_ecies_with_x9_63_sha1_aes128_cbc_hmac */
0x2B,0x81,0x04,0x01,0x08,0x05, /* [ 7654] OBJ_ecies_with_x9_63_sha256_aes128_cbc_hmac */
0x2B,0x81,0x04,0x01,0x08,0x06, /* [ 7660] OBJ_ecies_with_x9_63_sha512_aes256_cbc_hmac */
0x2B,0x81,0x04,0x01,0x08,0x07, /* [ 7666] OBJ_ecies_with_x9_63_sha256_aes128_ctr_hmac */
0x2B,0x81,0x04,0x01,0x08,0x08, /* [ 7672] OBJ_ecies_with_x9_63_sha512_aes256_ctr_hmac */
0x2B,0x81,0x04,0x01,0x08,0x09, /* [ 7678] OBJ_ecies_with_x9_63_sha256_aes128_cbc_hmac_half */
0x2B,0x81,0x04,0x01,0x08,0x0A, /* [ 7684] OBJ_ecies_with_x9_63_sha512_aes256_cbc_hmac_half */
0x2B,0x81,0x04,0x01,0x08,0x0B, /* [ 7690] OBJ_ecies_with_x9_63_sha256_aes128_ctr_hmac_half */
0x2B,0x81,0x04,0x01,0x08,0x0C, /* [ 7696] OBJ_ecies_with_x9_63_sha512_aes256_ctr_hmac_half */
0x2B,0x81,0x04,0x01,0x08,0x0D, /* [ 7702] OBJ_ecies_with_x9_63_sha1_aes128_cbc_cmac */
0x2B,0x81,0x04,0x01,0x08,0x0E, /* [ 7708] OBJ_ecies_with_x9_63_sha256_aes128_cbc_cmac */
0x2B,0x81,0x04,0x01,0x08,0x0F, /* [ 7714] OBJ_ecies_with_x9_63_sha512_aes256_cbc_cmac */
0x2B,0x81,0x04,0x01,0x08,0x10, /* [ 7720] OBJ_ecies_with_x9_63_sha256_aes128_ctr_cmac */
0x2B,0x81,0x04,0x01,0x08,0x11, /* [ 7726] OBJ_ecies_with_x9_63_sha512_aes256_ctr_cmac */
};
#define NUM_NID 1155
#define NUM_NID 1188
static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"UNDEF", "undefined", NID_undef},
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@@ -2212,9 +2243,42 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"cpk-sha1-map", "cpk-sha1-map", NID_cpk_sha1_map, 11, &so[7452]},
{"cpk-sha256-map", "cpk-sha256-map", NID_cpk_sha256_map, 11, &so[7463]},
{"cpk-sm3-map", "cpk-sm3-map", NID_cpk_sm3_map, 11, &so[7474]},
{"sm2encrypt-with-sm3", "sm2encrypt-with-sm3", NID_sm2encrypt_with_sm3, 11, &so[7485]},
{"sm2encrypt-with-sha1", "sm2encrypt-with-sha1", NID_sm2encrypt_with_sha1, 11, &so[7496]},
{"sm2encrypt-with-sha224", "sm2encrypt-with-sha224", NID_sm2encrypt_with_sha224, 11, &so[7507]},
{"sm2encrypt-with-sha256", "sm2encrypt-with-sha256", NID_sm2encrypt_with_sha256, 11, &so[7518]},
{"sm2encrypt-with-sha384", "sm2encrypt-with-sha384", NID_sm2encrypt_with_sha384, 11, &so[7529]},
{"sm2encrypt-with-sha512", "sm2encrypt-with-sha512", NID_sm2encrypt_with_sha512, 11, &so[7540]},
{"sm2encrypt-with-rmd160", "sm2encrypt-with-rmd160", NID_sm2encrypt_with_rmd160, 11, &so[7551]},
{"sm2encrypt-with-whirlpool", "sm2encrypt-with-whirlpool", NID_sm2encrypt_with_whirlpool, 11, &so[7562]},
{"sm2encrypt-with-blake2b512", "sm2encrypt-with-blake2b512", NID_sm2encrypt_with_blake2b512, 11, &so[7573]},
{"sm2encrypt-with-blake2s256", "sm2encrypt-with-blake2s256", NID_sm2encrypt_with_blake2s256, 11, &so[7584]},
{"sm2encrypt-with-md5", "sm2encrypt-with-md5", NID_sm2encrypt_with_md5, 11, &so[7595]},
{"SM2Sign-with-Whirlpool", "sm2sign-with-whirlpool", NID_sm2sign_with_whirlpool, 8, &so[7606]},
{"SM2Sign-with-Blake2b512", "sm2sign-with-blake2b512", NID_sm2sign_with_blake2b512, 8, &so[7614]},
{"SM2Sign-with-Blake2s256", "sm2sign-with-blake2s256", NID_sm2sign_with_blake2s256, 8, &so[7622]},
{"ecies-with-x9-63-sha1-xor-hmac", "ecies-with-x9-63-sha1-xor-hmac", NID_ecies_with_x9_63_sha1_xor_hmac, 6, &so[7630]},
{"ecies-with-x9-63-sha256-xor-hmac", "ecies-with-x9-63-sha256-xor-hmac", NID_ecies_with_x9_63_sha256_xor_hmac, 6, &so[7636]},
{"ecies-with-x9-63-sha512-xor-hmac", "ecies-with-x9-63-sha512-xor-hmac", NID_ecies_with_x9_63_sha512_xor_hmac, 6, &so[7642]},
{"ecies-with-x9-63-sha1-aes128-cbc-hmac", "ecies-with-x9-63-sha1-aes128-cbc-hmac", NID_ecies_with_x9_63_sha1_aes128_cbc_hmac, 6, &so[7648]},
{"ecies-with-x9-63-sha256-aes128-cbc-hmac", "ecies-with-x9-63-sha256-aes128-cbc-hmac", NID_ecies_with_x9_63_sha256_aes128_cbc_hmac, 6, &so[7654]},
{"ecies-with-x9-63-sha512-aes256-cbc-hmac", "ecies-with-x9-63-sha512-aes256-cbc-hmac", NID_ecies_with_x9_63_sha512_aes256_cbc_hmac, 6, &so[7660]},
{"ecies-with-x9-63-sha256-aes128-ctr-hmac", "ecies-with-x9-63-sha256-aes128-ctr-hmac", NID_ecies_with_x9_63_sha256_aes128_ctr_hmac, 6, &so[7666]},
{"ecies-with-x9-63-sha512-aes256-ctr-hmac", "ecies-with-x9-63-sha512-aes256-ctr-hmac", NID_ecies_with_x9_63_sha512_aes256_ctr_hmac, 6, &so[7672]},
{"ecies-with-x9-63-sha256-aes128-cbc-hmac-half", "ecies-with-x9-63-sha256-aes128-cbc-hmac-half", NID_ecies_with_x9_63_sha256_aes128_cbc_hmac_half, 6, &so[7678]},
{"ecies-with-x9-63-sha512-aes256-cbc-hmac-half", "ecies-with-x9-63-sha512-aes256-cbc-hmac-half", NID_ecies_with_x9_63_sha512_aes256_cbc_hmac_half, 6, &so[7684]},
{"ecies-with-x9-63-sha256-aes128-ctr-hmac-half", "ecies-with-x9-63-sha256-aes128-ctr-hmac-half", NID_ecies_with_x9_63_sha256_aes128_ctr_hmac_half, 6, &so[7690]},
{"ecies-with-x9-63-sha512-aes256-ctr-hmac-half", "ecies-with-x9-63-sha512-aes256-ctr-hmac-half", NID_ecies_with_x9_63_sha512_aes256_ctr_hmac_half, 6, &so[7696]},
{"ecies-with-x9-63-sha1-aes128-cbc-cmac", "ecies-with-x9-63-sha1-aes128-cbc-cmac", NID_ecies_with_x9_63_sha1_aes128_cbc_cmac, 6, &so[7702]},
{"ecies-with-x9-63-sha256-aes128-cbc-cmac", "ecies-with-x9-63-sha256-aes128-cbc-cmac", NID_ecies_with_x9_63_sha256_aes128_cbc_cmac, 6, &so[7708]},
{"ecies-with-x9-63-sha512-aes256-cbc-cmac", "ecies-with-x9-63-sha512-aes256-cbc-cmac", NID_ecies_with_x9_63_sha512_aes256_cbc_cmac, 6, &so[7714]},
{"ecies-with-x9-63-sha256-aes128-ctr-cmac", "ecies-with-x9-63-sha256-aes128-ctr-cmac", NID_ecies_with_x9_63_sha256_aes128_ctr_cmac, 6, &so[7720]},
{"ecies-with-x9-63-sha512-aes256-ctr-cmac", "ecies-with-x9-63-sha512-aes256-ctr-cmac", NID_ecies_with_x9_63_sha512_aes256_ctr_cmac, 6, &so[7726]},
{"KxSM2", "kx-sm2", NID_kx_sm2},
{"AuthSM2", "auth-sm2", NID_auth_sm2},
};
#define NUM_SN 1144
#define NUM_SN 1177
static const unsigned int sn_objs[NUM_SN] = {
364, /* "AD_DVCS" */
419, /* "AES-128-CBC" */
@@ -2256,6 +2320,7 @@ static const unsigned int sn_objs[NUM_SN] = {
1053, /* "AuthNULL" */
1048, /* "AuthPSK" */
1046, /* "AuthRSA" */
1187, /* "AuthSM2" */
1052, /* "AuthSRP" */
91, /* "BF-CBC" */
93, /* "BF-CFB" */
@@ -2358,6 +2423,7 @@ static const unsigned int sn_objs[NUM_SN] = {
1043, /* "KxPSK" */
1037, /* "KxRSA" */
1042, /* "KxRSA_PSK" */
1186, /* "KxSM2" */
1044, /* "KxSRP" */
15, /* "L" */
856, /* "LocalKeySet" */
@@ -2443,6 +2509,8 @@ static const unsigned int sn_objs[NUM_SN] = {
1095, /* "SM1-CFB8" */
1090, /* "SM1-ECB" */
1092, /* "SM1-OFB" */
1167, /* "SM2Sign-with-Blake2b512" */
1168, /* "SM2Sign-with-Blake2s256" */
1134, /* "SM2Sign-with-RMD160" */
1129, /* "SM2Sign-with-SHA1" */
1132, /* "SM2Sign-with-SHA224" */
@@ -2450,6 +2518,7 @@ static const unsigned int sn_objs[NUM_SN] = {
1133, /* "SM2Sign-with-SHA384" */
1131, /* "SM2Sign-with-SHA511" */
1128, /* "SM2Sign-with-SM3" */
1166, /* "SM2Sign-with-Whirlpool" */
1126, /* "SM3" */
1115, /* "SM5" */
1087, /* "SM6-CBC" */
@@ -2644,6 +2713,23 @@ static const unsigned int sn_objs[NUM_SN] = {
792, /* "ecdsa-with-Specified" */
1063, /* "ecies-recommendedParameters" */
1064, /* "ecies-specifiedParameters" */
1181, /* "ecies-with-x9-63-sha1-aes128-cbc-cmac" */
1172, /* "ecies-with-x9-63-sha1-aes128-cbc-hmac" */
1169, /* "ecies-with-x9-63-sha1-xor-hmac" */
1182, /* "ecies-with-x9-63-sha256-aes128-cbc-cmac" */
1173, /* "ecies-with-x9-63-sha256-aes128-cbc-hmac" */
1177, /* "ecies-with-x9-63-sha256-aes128-cbc-hmac-half" */
1184, /* "ecies-with-x9-63-sha256-aes128-ctr-cmac" */
1175, /* "ecies-with-x9-63-sha256-aes128-ctr-hmac" */
1179, /* "ecies-with-x9-63-sha256-aes128-ctr-hmac-half" */
1170, /* "ecies-with-x9-63-sha256-xor-hmac" */
1183, /* "ecies-with-x9-63-sha512-aes256-cbc-cmac" */
1174, /* "ecies-with-x9-63-sha512-aes256-cbc-hmac" */
1178, /* "ecies-with-x9-63-sha512-aes256-cbc-hmac-half" */
1185, /* "ecies-with-x9-63-sha512-aes256-ctr-cmac" */
1176, /* "ecies-with-x9-63-sha512-aes256-ctr-hmac" */
1180, /* "ecies-with-x9-63-sha512-aes256-ctr-hmac-half" */
1171, /* "ecies-with-x9-63-sha512-xor-hmac" */
48, /* "emailAddress" */
132, /* "emailProtection" */
885, /* "enhancedSearchGuide" */
@@ -3294,6 +3380,17 @@ static const unsigned int sn_objs[NUM_SN] = {
1119, /* "sm2encrypt" */
1120, /* "sm2encrypt-recommendedParameters" */
1121, /* "sm2encrypt-specifiedParameters" */
1163, /* "sm2encrypt-with-blake2b512" */
1164, /* "sm2encrypt-with-blake2s256" */
1165, /* "sm2encrypt-with-md5" */
1161, /* "sm2encrypt-with-rmd160" */
1156, /* "sm2encrypt-with-sha1" */
1157, /* "sm2encrypt-with-sha224" */
1158, /* "sm2encrypt-with-sha256" */
1159, /* "sm2encrypt-with-sha384" */
1160, /* "sm2encrypt-with-sha512" */
1155, /* "sm2encrypt-with-sm3" */
1162, /* "sm2encrypt-with-whirlpool" */
1149, /* "sm2exchange" */
1116, /* "sm2p256v1" */
1117, /* "sm2sign" */
@@ -3362,7 +3459,7 @@ static const unsigned int sn_objs[NUM_SN] = {
1069, /* "xor-in-ecies" */
};
#define NUM_LN 1144
#define NUM_LN 1177
static const unsigned int ln_objs[NUM_LN] = {
363, /* "AD Time Stamping" */
405, /* "ANSI X9.62" */
@@ -3600,6 +3697,7 @@ static const unsigned int ln_objs[NUM_LN] = {
1053, /* "auth-null" */
1048, /* "auth-psk" */
1046, /* "auth-rsa" */
1187, /* "auth-sm2" */
1052, /* "auth-srp" */
882, /* "authorityRevocationList" */
1138, /* "bb1" */
@@ -3783,6 +3881,23 @@ static const unsigned int ln_objs[NUM_LN] = {
792, /* "ecdsa-with-Specified" */
1063, /* "ecies-recommendedParameters" */
1064, /* "ecies-specifiedParameters" */
1181, /* "ecies-with-x9-63-sha1-aes128-cbc-cmac" */
1172, /* "ecies-with-x9-63-sha1-aes128-cbc-hmac" */
1169, /* "ecies-with-x9-63-sha1-xor-hmac" */
1182, /* "ecies-with-x9-63-sha256-aes128-cbc-cmac" */
1173, /* "ecies-with-x9-63-sha256-aes128-cbc-hmac" */
1177, /* "ecies-with-x9-63-sha256-aes128-cbc-hmac-half" */
1184, /* "ecies-with-x9-63-sha256-aes128-ctr-cmac" */
1175, /* "ecies-with-x9-63-sha256-aes128-ctr-hmac" */
1179, /* "ecies-with-x9-63-sha256-aes128-ctr-hmac-half" */
1170, /* "ecies-with-x9-63-sha256-xor-hmac" */
1183, /* "ecies-with-x9-63-sha512-aes256-cbc-cmac" */
1174, /* "ecies-with-x9-63-sha512-aes256-cbc-hmac" */
1178, /* "ecies-with-x9-63-sha512-aes256-cbc-hmac-half" */
1185, /* "ecies-with-x9-63-sha512-aes256-ctr-cmac" */
1176, /* "ecies-with-x9-63-sha512-aes256-ctr-hmac" */
1180, /* "ecies-with-x9-63-sha512-aes256-ctr-hmac-half" */
1171, /* "ecies-with-x9-63-sha512-xor-hmac" */
48, /* "emailAddress" */
632, /* "encrypted track 2" */
885, /* "enhancedSearchGuide" */
@@ -4092,6 +4207,7 @@ static const unsigned int ln_objs[NUM_LN] = {
1043, /* "kx-psk" */
1037, /* "kx-rsa" */
1042, /* "kx-rsa-psk" */
1186, /* "kx-sm2" */
1044, /* "kx-srp" */
477, /* "lastModifiedBy" */
476, /* "lastModifiedTime" */
@@ -4413,9 +4529,22 @@ static const unsigned int ln_objs[NUM_LN] = {
1119, /* "sm2encrypt" */
1120, /* "sm2encrypt-recommendedParameters" */
1121, /* "sm2encrypt-specifiedParameters" */
1163, /* "sm2encrypt-with-blake2b512" */
1164, /* "sm2encrypt-with-blake2s256" */
1165, /* "sm2encrypt-with-md5" */
1161, /* "sm2encrypt-with-rmd160" */
1156, /* "sm2encrypt-with-sha1" */
1157, /* "sm2encrypt-with-sha224" */
1158, /* "sm2encrypt-with-sha256" */
1159, /* "sm2encrypt-with-sha384" */
1160, /* "sm2encrypt-with-sha512" */
1155, /* "sm2encrypt-with-sm3" */
1162, /* "sm2encrypt-with-whirlpool" */
1149, /* "sm2exchange" */
1116, /* "sm2p256v1" */
1117, /* "sm2sign" */
1167, /* "sm2sign-with-blake2b512" */
1168, /* "sm2sign-with-blake2s256" */
1134, /* "sm2sign-with-rmd160" */
1129, /* "sm2sign-with-sha1" */
1132, /* "sm2sign-with-sha224" */
@@ -4423,6 +4552,7 @@ static const unsigned int ln_objs[NUM_LN] = {
1133, /* "sm2sign-with-sha384" */
1131, /* "sm2sign-with-sha512" */
1128, /* "sm2sign-with-sm3" */
1166, /* "sm2sign-with-whirlpool" */
1126, /* "sm3" */
1115, /* "sm5" */
1087, /* "sm6-cbc" */
@@ -4510,7 +4640,7 @@ static const unsigned int ln_objs[NUM_LN] = {
1136, /* "zuc" */
};
#define NUM_OBJ 1048
#define NUM_OBJ 1079
static const unsigned int obj_objs[NUM_OBJ] = {
0, /* OBJ_undef 0 */
181, /* OBJ_iso 1 */
@@ -4858,6 +4988,23 @@ static const unsigned int obj_objs[NUM_OBJ] = {
505, /* OBJ_mime_mhs_headings 1 3 6 1 7 1 1 */
506, /* OBJ_mime_mhs_bodies 1 3 6 1 7 1 2 */
119, /* OBJ_ripemd160WithRSA 1 3 36 3 3 1 2 */
1169, /* OBJ_ecies_with_x9_63_sha1_xor_hmac 1 3 132 1 8 1 */
1170, /* OBJ_ecies_with_x9_63_sha256_xor_hmac 1 3 132 1 8 2 */
1171, /* OBJ_ecies_with_x9_63_sha512_xor_hmac 1 3 132 1 8 3 */
1172, /* OBJ_ecies_with_x9_63_sha1_aes128_cbc_hmac 1 3 132 1 8 4 */
1173, /* OBJ_ecies_with_x9_63_sha256_aes128_cbc_hmac 1 3 132 1 8 5 */
1174, /* OBJ_ecies_with_x9_63_sha512_aes256_cbc_hmac 1 3 132 1 8 6 */
1175, /* OBJ_ecies_with_x9_63_sha256_aes128_ctr_hmac 1 3 132 1 8 7 */
1176, /* OBJ_ecies_with_x9_63_sha512_aes256_ctr_hmac 1 3 132 1 8 8 */
1177, /* OBJ_ecies_with_x9_63_sha256_aes128_cbc_hmac_half 1 3 132 1 8 9 */
1178, /* OBJ_ecies_with_x9_63_sha512_aes256_cbc_hmac_half 1 3 132 1 8 10 */
1179, /* OBJ_ecies_with_x9_63_sha256_aes128_ctr_hmac_half 1 3 132 1 8 11 */
1180, /* OBJ_ecies_with_x9_63_sha512_aes256_ctr_hmac_half 1 3 132 1 8 12 */
1181, /* OBJ_ecies_with_x9_63_sha1_aes128_cbc_cmac 1 3 132 1 8 13 */
1182, /* OBJ_ecies_with_x9_63_sha256_aes128_cbc_cmac 1 3 132 1 8 14 */
1183, /* OBJ_ecies_with_x9_63_sha512_aes256_cbc_cmac 1 3 132 1 8 15 */
1184, /* OBJ_ecies_with_x9_63_sha256_aes128_ctr_cmac 1 3 132 1 8 16 */
1185, /* OBJ_ecies_with_x9_63_sha512_aes256_ctr_cmac 1 3 132 1 8 17 */
937, /* OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1 3 132 1 11 0 */
938, /* OBJ_dhSinglePass_stdDH_sha256kdf_scheme 1 3 132 1 11 1 */
939, /* OBJ_dhSinglePass_stdDH_sha384kdf_scheme 1 3 132 1 11 2 */
@@ -5019,6 +5166,9 @@ static const unsigned int obj_objs[NUM_OBJ] = {
1132, /* OBJ_sm2sign_with_sha224 1 2 156 10197 1 505 */
1133, /* OBJ_sm2sign_with_sha384 1 2 156 10197 1 506 */
1134, /* OBJ_sm2sign_with_rmd160 1 2 156 10197 1 507 */
1166, /* OBJ_sm2sign_with_whirlpool 1 2 156 10197 1 520 */
1167, /* OBJ_sm2sign_with_blake2b512 1 2 156 10197 1 521 */
1168, /* OBJ_sm2sign_with_blake2s256 1 2 156 10197 1 522 */
1136, /* OBJ_zuc 1 2 156 10197 1 800 */
776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */
777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */
@@ -5471,6 +5621,17 @@ static const unsigned int obj_objs[NUM_OBJ] = {
952, /* OBJ_ct_precert_poison 1 3 6 1 4 1 11129 2 4 3 */
953, /* OBJ_ct_precert_signer 1 3 6 1 4 1 11129 2 4 4 */
954, /* OBJ_ct_cert_scts 1 3 6 1 4 1 11129 2 4 5 */
1155, /* OBJ_sm2encrypt_with_sm3 1 2 156 10197 1 301 3 2 1 */
1156, /* OBJ_sm2encrypt_with_sha1 1 2 156 10197 1 301 3 2 2 */
1157, /* OBJ_sm2encrypt_with_sha224 1 2 156 10197 1 301 3 2 3 */
1158, /* OBJ_sm2encrypt_with_sha256 1 2 156 10197 1 301 3 2 4 */
1159, /* OBJ_sm2encrypt_with_sha384 1 2 156 10197 1 301 3 2 5 */
1160, /* OBJ_sm2encrypt_with_sha512 1 2 156 10197 1 301 3 2 6 */
1161, /* OBJ_sm2encrypt_with_rmd160 1 2 156 10197 1 301 3 2 7 */
1162, /* OBJ_sm2encrypt_with_whirlpool 1 2 156 10197 1 301 3 2 8 */
1163, /* OBJ_sm2encrypt_with_blake2b512 1 2 156 10197 1 301 3 2 9 */
1164, /* OBJ_sm2encrypt_with_blake2s256 1 2 156 10197 1 301 3 2 10 */
1165, /* OBJ_sm2encrypt_with_md5 1 2 156 10197 1 301 3 2 11 */
751, /* OBJ_camellia_128_cbc 1 2 392 200011 61 1 1 1 2 */
752, /* OBJ_camellia_192_cbc 1 2 392 200011 61 1 1 1 3 */
753, /* OBJ_camellia_256_cbc 1 2 392 200011 61 1 1 1 4 */

View File

@@ -1152,3 +1152,36 @@ cpk_map 1151
cpk_sha1_map 1152
cpk_sha256_map 1153
cpk_sm3_map 1154
sm2encrypt_with_sm3 1155
sm2encrypt_with_sha1 1156
sm2encrypt_with_sha224 1157
sm2encrypt_with_sha256 1158
sm2encrypt_with_sha384 1159
sm2encrypt_with_sha512 1160
sm2encrypt_with_rmd160 1161
sm2encrypt_with_whirlpool 1162
sm2encrypt_with_blake2b512 1163
sm2encrypt_with_blake2s256 1164
sm2encrypt_with_md5 1165
sm2sign_with_whirlpool 1166
sm2sign_with_blake2b512 1167
sm2sign_with_blake2s256 1168
ecies_with_x9_63_sha1_xor_hmac 1169
ecies_with_x9_63_sha256_xor_hmac 1170
ecies_with_x9_63_sha512_xor_hmac 1171
ecies_with_x9_63_sha1_aes128_cbc_hmac 1172
ecies_with_x9_63_sha256_aes128_cbc_hmac 1173
ecies_with_x9_63_sha512_aes256_cbc_hmac 1174
ecies_with_x9_63_sha256_aes128_ctr_hmac 1175
ecies_with_x9_63_sha512_aes256_ctr_hmac 1176
ecies_with_x9_63_sha256_aes128_cbc_hmac_half 1177
ecies_with_x9_63_sha512_aes256_cbc_hmac_half 1178
ecies_with_x9_63_sha256_aes128_ctr_hmac_half 1179
ecies_with_x9_63_sha512_aes256_ctr_hmac_half 1180
ecies_with_x9_63_sha1_aes128_cbc_cmac 1181
ecies_with_x9_63_sha256_aes128_cbc_cmac 1182
ecies_with_x9_63_sha512_aes256_cbc_cmac 1183
ecies_with_x9_63_sha256_aes128_ctr_cmac 1184
ecies_with_x9_63_sha512_aes256_ctr_cmac 1185
kx_sm2 1186
auth_sm2 1187

View File

@@ -1476,6 +1476,7 @@ id-pkinit 5 : pkInitKDC : Signing KDC Response
: KxPSK : kx-psk
: KxSRP : kx-srp
: KxGOST : kx-gost
: KxSM2 : kx-sm2
# NIDs for cipher authentication
: AuthRSA : auth-rsa
@@ -1486,6 +1487,7 @@ id-pkinit 5 : pkInitKDC : Signing KDC Response
: AuthGOST12 : auth-gost12
: AuthSRP : auth-srp
: AuthNULL : auth-null
: AuthSM2 : auth-sm2
# GmSSL SECG ECIES OID
secg-scheme 7 : ecies-recommendedParameters
@@ -1508,6 +1510,26 @@ secg-scheme 24 0 : cmac-aes128-ecies
secg-scheme 24 1 : cmac-aes192-ecies
secg-scheme 24 2 : cmac-aes256-ecies
ecies-specifiedParameters 1 : ecies-with-x9-63-sha1-xor-hmac
ecies-specifiedParameters 2 : ecies-with-x9-63-sha256-xor-hmac
ecies-specifiedParameters 3 : ecies-with-x9-63-sha512-xor-hmac
ecies-specifiedParameters 4 : ecies-with-x9-63-sha1-aes128-cbc-hmac
ecies-specifiedParameters 5 : ecies-with-x9-63-sha256-aes128-cbc-hmac
ecies-specifiedParameters 6 : ecies-with-x9-63-sha512-aes256-cbc-hmac
ecies-specifiedParameters 7 : ecies-with-x9-63-sha256-aes128-ctr-hmac
ecies-specifiedParameters 8 : ecies-with-x9-63-sha512-aes256-ctr-hmac
ecies-specifiedParameters 9 : ecies-with-x9-63-sha256-aes128-cbc-hmac-half
ecies-specifiedParameters 10 : ecies-with-x9-63-sha512-aes256-cbc-hmac-half
ecies-specifiedParameters 11 : ecies-with-x9-63-sha256-aes128-ctr-hmac-half
ecies-specifiedParameters 12 : ecies-with-x9-63-sha512-aes256-ctr-hmac-half
ecies-specifiedParameters 13 : ecies-with-x9-63-sha1-aes128-cbc-cmac
ecies-specifiedParameters 14 : ecies-with-x9-63-sha256-aes128-cbc-cmac
ecies-specifiedParameters 15 : ecies-with-x9-63-sha512-aes256-cbc-cmac
ecies-specifiedParameters 16 : ecies-with-x9-63-sha256-aes128-ctr-cmac
ecies-specifiedParameters 17 : ecies-with-x9-63-sha512-aes256-ctr-cmac
# GmSSL SM OID
member-body 156 : ISO-CN : ISO CN Member Body
ISO-CN 10197 : oscca
@@ -1564,8 +1586,21 @@ sm-scheme 301 : sm2p256v1
sm-scheme 301 1 : sm2sign
sm-scheme 301 2 : sm2exchange
sm-scheme 301 3 : sm2encrypt
sm-scheme 301 101 : wapip192v1
sm2encrypt 1 : sm2encrypt-recommendedParameters
sm2encrypt 2 : sm2encrypt-specifiedParameters
sm2encrypt 2 1 : sm2encrypt-with-sm3
sm2encrypt 2 2 : sm2encrypt-with-sha1
sm2encrypt 2 3 : sm2encrypt-with-sha224
sm2encrypt 2 4 : sm2encrypt-with-sha256
sm2encrypt 2 5 : sm2encrypt-with-sha384
sm2encrypt 2 6 : sm2encrypt-with-sha512
sm2encrypt 2 7 : sm2encrypt-with-rmd160
sm2encrypt 2 8 : sm2encrypt-with-whirlpool
sm2encrypt 2 9 : sm2encrypt-with-blake2b512
sm2encrypt 2 10 : sm2encrypt-with-blake2s256
sm2encrypt 2 11 : sm2encrypt-with-md5
sm-scheme 302 : id-sm9PublicKey
sm-scheme 302 1 : sm9sign
@@ -1574,6 +1609,7 @@ sm-scheme 302 3 : sm9encrypt
sm-scheme 401 : SM3 : sm3
sm-scheme 401 2 : HMAC-SM3 : hmac-sm3
sm-scheme 501 : SM2Sign-with-SM3 : sm2sign-with-sm3
sm-scheme 502 : SM2Sign-with-SHA1 : sm2sign-with-sha1
sm-scheme 503 : SM2Sign-with-SHA256 : sm2sign-with-sha256
@@ -1581,8 +1617,10 @@ sm-scheme 504 : SM2Sign-with-SHA511 : sm2sign-with-sha512
sm-scheme 505 : SM2Sign-with-SHA224 : sm2sign-with-sha224
sm-scheme 506 : SM2Sign-with-SHA384 : sm2sign-with-sha384
sm-scheme 507 : SM2Sign-with-RMD160 : sm2sign-with-rmd160
sm-scheme 520 : SM2Sign-with-Whirlpool : sm2sign-with-whirlpool
sm-scheme 521 : SM2Sign-with-Blake2b512 : sm2sign-with-blake2b512
sm-scheme 522 : SM2Sign-with-Blake2s256 : sm2sign-with-blake2s256
sm-scheme 301 101 : wapip192v1
# GmSSL ZUC OID
sm-scheme 800 : ZUC : zuc

View File

@@ -1,3 +1,3 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=sm2_asn1.c sm2_id.c sm2_sign.c sm2_enc.c sm2_kap.c \
sm2_kmeth.c
SOURCE[../../libcrypto]=sm2_err.c sm2_asn1.c sm2_id.c sm2_sign.c sm2_enc.c \
sm2_exch.c sm2_kmeth.c

View File

@@ -55,147 +55,14 @@
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include <openssl/obj_mac.h>
#include "sm2_lcl.h"
typedef struct SM2CiphertextValue_st {
ASN1_INTEGER *xCoordinate;
ASN1_INTEGER *yCoordinate;
ASN1_OCTET_STRING *hash;
ASN1_OCTET_STRING *ciphertext;
} SM2CiphertextValue;
ASN1_SEQUENCE(SM2CiphertextValue) = {
ASN1_SIMPLE(SM2CiphertextValue, xCoordinate, ASN1_INTEGER),
ASN1_SIMPLE(SM2CiphertextValue, yCoordinate, ASN1_INTEGER),
ASN1_SIMPLE(SM2CiphertextValue, xCoordinate, BIGNUM),
ASN1_SIMPLE(SM2CiphertextValue, yCoordinate, BIGNUM),
ASN1_SIMPLE(SM2CiphertextValue, hash, ASN1_OCTET_STRING),
ASN1_SIMPLE(SM2CiphertextValue, ciphertext, ASN1_OCTET_STRING),
} ASN1_SEQUENCE_END(SM2CiphertextValue)
IMPLEMENT_ASN1_FUNCTIONS(SM2CiphertextValue)
IMPLEMENT_ASN1_DUP_FUNCTION(SM2CiphertextValue)
int i2d_SM2_CIPHERTEXT_VALUE(const EC_GROUP *group, const SM2_CIPHERTEXT_VALUE *c,
unsigned char **out)
{
int ret = 0;
SM2CiphertextValue *asn1 = NULL;
BIGNUM *x = NULL;
BIGNUM *y = NULL;
BN_CTX *bn_ctx = NULL;
asn1 = SM2CiphertextValue_new();
x = BN_new();
y = BN_new();
bn_ctx = BN_CTX_new();
if (!asn1 || !x || !y || !bn_ctx) {
ECerr(EC_F_I2D_SM2_CIPHERTEXT_VALUE, ERR_R_MALLOC_FAILURE);
goto end;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(group, c->ephem_point, x, y, bn_ctx)) {
ECerr(EC_F_I2D_SM2_CIPHERTEXT_VALUE, ERR_R_EC_LIB);
goto end;
}
} else {
if (!EC_POINT_get_affine_coordinates_GF2m(group, c->ephem_point, x, y, bn_ctx)) {
ECerr(EC_F_I2D_SM2_CIPHERTEXT_VALUE, ERR_R_EC_LIB);
goto end;
}
}
if (!BN_to_ASN1_INTEGER(x, asn1->xCoordinate)) {
ECerr(EC_F_I2D_SM2_CIPHERTEXT_VALUE, ERR_R_BN_LIB);
goto end;
}
if (!BN_to_ASN1_INTEGER(y, asn1->yCoordinate)) {
ECerr(EC_F_I2D_SM2_CIPHERTEXT_VALUE, ERR_R_BN_LIB);
goto end;
}
if (!ASN1_OCTET_STRING_set(asn1->hash, c->mactag, c->mactag_size)) {
ECerr(EC_F_I2D_SM2_CIPHERTEXT_VALUE, ERR_R_ASN1_LIB);
goto end;
}
if (!ASN1_OCTET_STRING_set(asn1->ciphertext, c->ciphertext, c->ciphertext_size)) {
ECerr(EC_F_I2D_SM2_CIPHERTEXT_VALUE, ERR_R_ASN1_LIB);
goto end;
}
ret = 1;
end:
SM2CiphertextValue_free(asn1);
BN_free(x);
BN_free(y);
BN_CTX_free(bn_ctx);
return ret;
}
SM2_CIPHERTEXT_VALUE *d2i_SM2_CIPHERTEXT_VALUE(const EC_GROUP *group,
SM2_CIPHERTEXT_VALUE **c, const unsigned char **in, long len)
{
int e = 1;
SM2_CIPHERTEXT_VALUE *ret = NULL;
SM2CiphertextValue *asn1 = NULL;
BIGNUM *x = NULL;
BIGNUM *y = NULL;
BN_CTX *bn_ctx = NULL;
if (!(asn1 = d2i_SM2CiphertextValue(NULL, in, len))) {
ECerr(EC_F_D2I_SM2_CIPHERTEXT_VALUE, ERR_R_MALLOC_FAILURE);
goto end;
}
if (!(x = ASN1_INTEGER_to_BN(asn1->xCoordinate, NULL))) {
ECerr(EC_F_D2I_SM2_CIPHERTEXT_VALUE, ERR_R_BN_LIB);
goto end;
}
if (!(y = ASN1_INTEGER_to_BN(asn1->yCoordinate, NULL))) {
ECerr(EC_F_D2I_SM2_CIPHERTEXT_VALUE, ERR_R_BN_LIB);
goto end;
}
ret = SM2_CIPHERTEXT_VALUE_new(group);
bn_ctx = BN_CTX_new();
if (!ret || !bn_ctx) {
ECerr(EC_F_D2I_SM2_CIPHERTEXT_VALUE, ERR_R_MALLOC_FAILURE);
goto end;
}
/* (x, y) */
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
if (!EC_POINT_set_affine_coordinates_GFp(group, ret->ephem_point, x, y, bn_ctx)) {
ECerr(EC_F_D2I_SM2_CIPHERTEXT_VALUE, ERR_R_EC_LIB);
goto end;
}
} else {
if (!EC_POINT_set_affine_coordinates_GF2m(group, ret->ephem_point, x, y, bn_ctx)) {
ECerr(EC_F_D2I_SM2_CIPHERTEXT_VALUE, ERR_R_EC_LIB);
goto end;
}
}
/* hash */
ret->mactag_size = asn1->hash->length;
memcpy(ret->mactag, asn1->hash->data, asn1->hash->length);
/* ciphertext */
ret->ciphertext_size = asn1->ciphertext->length;
if (!(ret->ciphertext = OPENSSL_malloc(ret->ciphertext_size))) {
ECerr(EC_F_D2I_SM2_CIPHERTEXT_VALUE, ERR_R_MALLOC_FAILURE);
goto end;
}
memcpy(ret->ciphertext, asn1->ciphertext->data, asn1->ciphertext->length);
e = 0;
end:
SM2CiphertextValue_free(asn1);
BN_free(x);
BN_free(y);
BN_CTX_free(bn_ctx);
if (e && ret) {
SM2_CIPHERTEXT_VALUE_free(ret);
ret = NULL;
}
return ret;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 - 2016 The GmSSL Project. All rights reserved.
* Copyright (c) 2015 - 2017 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -46,551 +46,280 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/sm2.h>
#include <openssl/rand.h>
#include <openssl/kdf.h>
#include "internal/o_str.h"
#include "sm2_lcl.h"
SM2_ENC_PARAMS *SM2_ENC_PARAMS_new(void)
SM2CiphertextValue *SM2_do_encrypt(const EVP_MD *md,
const unsigned char *in, size_t inlen, EC_KEY *ec_key)
{
SM2_ENC_PARAMS *ret = NULL;
if (!(ret = OPENSSL_zalloc(sizeof(*ret)))) {
ECerr(EC_F_SM2_ENC_PARAMS_NEW, ERR_R_MALLOC_FAILURE);
return NULL;
}
SM2_ENC_PARAMS_init_with_recommended(ret);
return ret;
}
SM2_ENC_PARAMS *SM2_ENC_PARAMS_dup(const SM2_ENC_PARAMS *param)
{
SM2_ENC_PARAMS *ret = NULL;
if (!param) {
ECerr(EC_F_SM2_ENC_PARAMS_DUP, EC_R_NULL_ARGUMENT);
return NULL;
}
if (!(ret = OPENSSL_memdup(param, sizeof(*param)))) {
ECerr(EC_F_SM2_ENC_PARAMS_DUP, ERR_R_MALLOC_FAILURE);
return NULL;
}
return ret;
}
int SM2_ENC_PARAMS_init_with_recommended(SM2_ENC_PARAMS *params)
{
if (!params) {
ECerr(EC_F_SM2_ENC_PARAMS_INIT_WITH_RECOMMENDED,
EC_R_NULL_ARGUMENT);
return 0;
}
params->kdf_md = EVP_sm3();
params->mac_md = EVP_sm3();
params->point_form = POINT_CONVERSION_UNCOMPRESSED;
return 1;
}
void SM2_ENC_PARAMS_free(SM2_ENC_PARAMS *param)
{
OPENSSL_free(param);
}
int SM2_CIPHERTEXT_VALUE_size(const EC_GROUP *group,
const SM2_ENC_PARAMS *params, size_t mlen)
{
int ret = 0;
EC_KEY *ec_key = NULL;
size_t len = 0;
if (!(ec_key = EC_KEY_new())) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_SIZE, ERR_R_EC_LIB);
goto end;
}
if (!EC_KEY_set_group(ec_key, group)) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_SIZE, ERR_R_EC_LIB);
goto end;
}
if (!EC_KEY_generate_key(ec_key)) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_SIZE, ERR_R_EC_LIB);
goto end;
}
len += EC_POINT_point2oct(group, EC_KEY_get0_public_key(ec_key),
params->point_form, NULL, 0, NULL);
len += mlen;
len += EVP_MD_size(params->mac_md);
ret = (int)len;
end:
EC_KEY_free(ec_key);
return ret;
}
SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_new(const EC_GROUP *group)
{
SM2_CIPHERTEXT_VALUE *cv;
if (!(cv = OPENSSL_malloc(sizeof(*cv)))) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_NEW, EC_R_MALLOC_FAILED);
return NULL;
}
memset(cv, 0, sizeof(*cv));
if (!(cv->ephem_point = EC_POINT_new(group))) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_NEW, EC_R_POINT_NEW_FAILED);
OPENSSL_free(cv);
return NULL;
}
return cv;
}
void SM2_CIPHERTEXT_VALUE_free(SM2_CIPHERTEXT_VALUE *cv)
{
if (cv->ephem_point) EC_POINT_free(cv->ephem_point);
if (cv->ciphertext) OPENSSL_free(cv->ciphertext);
memset(cv, 0, sizeof(*cv));
OPENSSL_free(cv);
}
int SM2_CIPHERTEXT_VALUE_encode(const SM2_CIPHERTEXT_VALUE *cv,
const EC_GROUP *ec_group, const SM2_ENC_PARAMS *params,
unsigned char *buf, size_t *buflen)
{
int ret = 0;
BN_CTX *bn_ctx = BN_CTX_new();
size_t ptlen, cvlen;
OPENSSL_assert(cv);
OPENSSL_assert(ec_group);
OPENSSL_assert(buf);
OPENSSL_assert(cv->ephem_point);
if (!bn_ctx) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_ENCODE, ERR_R_BN_LIB);
return 0;
}
if (!(ptlen = EC_POINT_point2oct(ec_group, cv->ephem_point,
params->point_form, NULL, 0, bn_ctx))) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_ENCODE, EC_R_POINT2OCT_FAILED);
goto end;
}
cvlen = ptlen + cv->ciphertext_size + cv->mactag_size;
if (!buf) {
*buflen = cvlen;
ret = 1;
goto end;
} else if (*buflen < cvlen) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_ENCODE, EC_R_BUFFER_TOO_SMALL);
goto end;
}
if (!(ptlen = EC_POINT_point2oct(ec_group, cv->ephem_point,
params->point_form, buf, *buflen, bn_ctx))) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_ENCODE, EC_R_POINT2OCT_FAILED);
goto end;
}
buf += ptlen;
memcpy(buf, cv->ciphertext, cv->ciphertext_size);
buf += cv->ciphertext_size;
if (cv->mactag_size > 0) {
memcpy(buf, cv->mactag, cv->mactag_size);
}
*buflen = cvlen;
ret = 1;
end:
if (bn_ctx) BN_CTX_free(bn_ctx);
return ret;
}
SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_decode(
const EC_GROUP *ec_group, const SM2_ENC_PARAMS *params,
const unsigned char *buf, size_t buflen)
{
int ok = 0;
SM2_CIPHERTEXT_VALUE *ret = NULL;
BN_CTX *bn_ctx = BN_CTX_new();
int ptlen;
int fixlen;
if (!bn_ctx) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_DECODE, ERR_R_BN_LIB);
return NULL;
}
if (!(fixlen = SM2_CIPHERTEXT_VALUE_size(ec_group, params, 0))) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_DECODE, EC_R_GET_CIPHERTEXT_SIZE_FAILED);
goto end;
}
if (buflen <= (size_t)fixlen) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_DECODE, EC_R_BUFFER_TOO_SMALL);
goto end;
}
if (!(ret = OPENSSL_malloc(sizeof(SM2_CIPHERTEXT_VALUE)))) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_DECODE, EC_R_MALLOC_FAILED);
goto end;
}
ret->ephem_point = EC_POINT_new(ec_group);
ret->ciphertext_size = buflen - fixlen;
ret->ciphertext = OPENSSL_malloc(ret->ciphertext_size);
if (!ret->ephem_point || !ret->ciphertext) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_DECODE, EC_R_INNOR_ERROR);
goto end;
}
#if 0
//FIXME
ptlen = fixlen - SM2_ENC_PARAMS_mactag_size(params);
#endif
ptlen = (int)fixlen; //FIXME
if (!EC_POINT_oct2point(ec_group, ret->ephem_point, buf, ptlen, bn_ctx)) {
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_DECODE, EC_R_OCT2POINT_FAILED);
goto end;
}
memcpy(ret->ciphertext, buf + ptlen, ret->ciphertext_size);
//FIXME
//ret->mactag_size = SM2_ENC_PARAMS_mactag_size(params);
if (ret->mactag_size > 0) {
memcpy(ret->mactag, buf + buflen - ret->mactag_size, ret->mactag_size);
}
ok = 1;
end:
if (!ok && ret) {
SM2_CIPHERTEXT_VALUE_free(ret);
ret = NULL;
}
if (bn_ctx) BN_CTX_free(bn_ctx);
return ret;
}
int SM2_CIPHERTEXT_VALUE_print(BIO *out, const EC_GROUP *ec_group,
const SM2_CIPHERTEXT_VALUE *cv, int indent, unsigned long flags)
{
int ret = 0;
char *hex = NULL;
BN_CTX *ctx = BN_CTX_new();
size_t i;
if (!ctx) {
goto end;
}
if (!(hex = EC_POINT_point2hex(ec_group, cv->ephem_point,
POINT_CONVERSION_UNCOMPRESSED, ctx))) {
goto end;
}
BIO_printf(out, "SM2_CIPHERTEXT_VALUE.ephem_point: %s\n", hex);
BIO_printf(out, "SM2_CIPHERTEXT_VALUE.ciphertext : ");
for (i = 0; i < cv->ciphertext_size; i++) {
BIO_printf(out, "%02X", cv->ciphertext[i]);
}
BIO_printf(out, "\n");
BIO_printf(out, "SM2_CIPHERTEXT_VALUE.mactag :");
for (i = 0; i < cv->mactag_size; i++) {
BIO_printf(out, "%02X", cv->mactag[i]);
}
BIO_printf(out, "\n");
ret = 1;
end:
OPENSSL_free(hex);
BN_CTX_free(ctx);
return 0;
}
int SM2_encrypt(const SM2_ENC_PARAMS *params,
const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen,
EC_KEY *ec_key)
{
int ret = 0;
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
SM2_CIPHERTEXT_VALUE *cv = NULL;
int len;
if (!(len = SM2_CIPHERTEXT_VALUE_size(ec_group, params, inlen))) {
ECerr(EC_F_SM2_ENCRYPT, EC_R_ERROR);
goto end;
}
if (!out) {
*outlen = (size_t)len;
return 1;
} else if (*outlen < (size_t)len) {
ECerr(EC_F_SM2_ENCRYPT, EC_R_BUFFER_TOO_SMALL);
return 0;
}
if (!(cv = SM2_do_encrypt(params, in, inlen, ec_key))) {
ECerr(EC_F_SM2_ENCRYPT, EC_R_ENCRYPT_FAILED);
goto end;
}
if (!SM2_CIPHERTEXT_VALUE_encode(cv, ec_group, params, out, outlen)) {
ECerr(EC_F_SM2_ENCRYPT, EC_R_CIPHERTEXT_ENCODE_FAILED);
goto end;
}
ret = 1;
end:
if (cv) SM2_CIPHERTEXT_VALUE_free(cv);
return ret;
}
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const SM2_ENC_PARAMS *params,
const unsigned char *in, size_t inlen,
EC_KEY *ec_key)
{
int ok = 0;
SM2_CIPHERTEXT_VALUE *cv = NULL;
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
const EC_POINT *pub_key = EC_KEY_get0_public_key(ec_key);
KDF_FUNC kdf = KDF_get_x9_63(params->kdf_md);
EC_POINT *point = NULL;
SM2CiphertextValue *ret = NULL;
SM2CiphertextValue *cv = NULL;
const EC_GROUP *group;
const EC_POINT *pub_key;
KDF_FUNC kdf;
EC_POINT *ephem_point = NULL;
EC_POINT *share_point = NULL;
BIGNUM *n = NULL;
BIGNUM *h = NULL;
BIGNUM *k = NULL;
BN_CTX *bn_ctx = NULL;
EVP_MD_CTX *md_ctx = NULL;
unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
int nbytes;
unsigned char dgst[EVP_MAX_MD_SIZE];
unsigned int dgstlen;
int mactag_size;
size_t len;
size_t i;
unsigned int hashlen;
if (!ec_group || !pub_key) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_INVALID_EC_KEY);
goto end;
/* check arguments */
if (!md || !in || !ec_key) {
SM2err(SM2_F_SM2_DO_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (!kdf) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_GET_KDF_FAILED);
if (inlen < SM2_MIN_PLAINTEXT_LENGTH || inlen > SM2_MAX_PLAINTEXT_LENGTH) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_INVALID_PLAINTEXT_LENGTH);
return 0;
}
if (!(kdf = KDF_get_x9_63(md))) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_INVALID_DIGEST_ALGOR);
return 0;
}
if (!(group = EC_KEY_get0_group(ec_key))
|| !(pub_key = EC_KEY_get0_public_key(ec_key))) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_INVALID_EC_KEY);
return 0;
}
/* malloc */
if (!(cv = SM2CiphertextValue_new())
|| !(ephem_point = EC_POINT_new(group))
|| !(share_point = EC_POINT_new(group))
|| !(n = BN_new())
|| !(h = BN_new())
|| !(k = BN_new())
|| !(bn_ctx = BN_CTX_new())
|| !(md_ctx = EVP_MD_CTX_new())) {
SM2err(SM2_F_SM2_DO_ENCRYPT, ERR_R_MALLOC_FAILURE);
goto end;
}
/* init ciphertext_value */
if (!(cv = OPENSSL_malloc(sizeof(SM2_CIPHERTEXT_VALUE)))) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_MALLOC_FAILED);
goto end;
}
memset(cv, 0, sizeof(*cv));
cv->ephem_point = EC_POINT_new(ec_group);
cv->ciphertext = OPENSSL_malloc(inlen);
cv->ciphertext_size = inlen;
if (!cv->ephem_point || !cv->ciphertext) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
goto end;
}
point = EC_POINT_new(ec_group);
n = BN_new();
h = BN_new();
k = BN_new();
bn_ctx = BN_CTX_new();
md_ctx = EVP_MD_CTX_create();
if (!point || !n || !h || !k || !bn_ctx || !md_ctx) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
if (!ASN1_OCTET_STRING_set(cv->ciphertext, NULL, (int)inlen)
|| !ASN1_OCTET_STRING_set(cv->hash, NULL, EVP_MD_size(md))) {
SM2err(SM2_F_SM2_DO_ENCRYPT, ERR_R_ASN1_LIB);
goto end;
}
/* init ec domain parameters */
if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
if (!EC_GROUP_get_order(group, n, bn_ctx)) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
goto end;
}
if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
if (!EC_GROUP_get_cofactor(group, h, bn_ctx)) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
goto end;
}
nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
nbytes = (EC_GROUP_get_degree(group) + 7) / 8;
/* check [h]P_B != O */
if (!EC_POINT_mul(group, share_point, NULL, pub_key, h, bn_ctx)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, ERR_R_EC_LIB);
goto end;
}
if (EC_POINT_is_at_infinity(group, share_point)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_INVALID_PUBLIC_KEY);
goto end;
}
do
{
/* A1: rand k in [1, n-1] */
size_t size;
/* rand k in [1, n-1] */
do {
BN_rand_range(k, n);
} while (BN_is_zero(k));
/* A2: C1 = [k]G = (x1, y1) */
if (!EC_POINT_mul(ec_group, cv->ephem_point, k, NULL, NULL, bn_ctx)) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
/* compute ephem_point [k]G = (x1, y1) */
if (!EC_POINT_mul(group, ephem_point, k, NULL, NULL, bn_ctx)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, ERR_R_EC_LIB);
goto end;
}
/* A3: check [h]P_B != O */
if (!EC_POINT_mul(ec_group, point, NULL, pub_key, h, bn_ctx)) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
goto end;
}
if (EC_POINT_is_at_infinity(ec_group, point)) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
/* compute ECDH share_point [k]P_B = (x2, y2) */
if (!EC_POINT_mul(group, share_point, NULL, pub_key, k, bn_ctx)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, ERR_R_EC_LIB);
goto end;
}
/* A4: compute ECDH [k]P_B = (x2, y2) */
if (!EC_POINT_mul(ec_group, point, NULL, pub_key, k, bn_ctx)) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
goto end;
}
if (!(len = EC_POINT_point2oct(ec_group, point,
/* compute t = KDF(x2 || y2, klen) */
if (!(len = EC_POINT_point2oct(group, share_point,
POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
SM2err(SM2_F_SM2_DO_ENCRYPT, ERR_R_EC_LIB);
goto end;
}
OPENSSL_assert(len == nbytes * 2 + 1);
/* A5: t = KDF(x2 || y2, klen) */
kdf(buf + 1, len - 1, cv->ciphertext, &cv->ciphertext_size);
for (i = 0; i < cv->ciphertext_size; i++) {
if (cv->ciphertext[i]) {
break;
}
}
if (i == cv->ciphertext_size) {
continue;
size = cv->ciphertext->length;
kdf(buf + 1, len - 1, cv->ciphertext->data, &size);
if (size != inlen) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_KDF_FAILURE);
goto end;
}
break;
/* ASN1_OCTET_STRING_is_zero in asn1.h and a_octet.c */
} while (ASN1_OCTET_STRING_is_zero(cv->ciphertext));
} while (1);
/* set x/yCoordinates as (x1, y1) */
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(group, ephem_point,
cv->xCoordinate, cv->yCoordinate, bn_ctx)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, ERR_R_EC_LIB);
goto end;
}
} else {
if (!EC_POINT_get_affine_coordinates_GF2m(group, ephem_point,
cv->xCoordinate, cv->yCoordinate, bn_ctx)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, ERR_R_EC_LIB);
goto end;
}
}
/* A6: C2 = M xor t */
/* ciphertext = t xor in */
for (i = 0; i < inlen; i++) {
cv->ciphertext[i] ^= in[i];
cv->ciphertext->data[i] ^= in[i];
}
mactag_size = EVP_MD_size(params->mac_md);
if (mactag_size) {
/* A7: C3 = Hash(x2 || M || y2) */
if (!EVP_DigestInit_ex(md_ctx, params->mac_md, NULL)) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, in, inlen)) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
goto end;
}
if (!EVP_DigestFinal_ex(md_ctx, dgst, &dgstlen)) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
goto end;
}
/* GmSSL specific: reduce mactag size */
if (mactag_size > dgstlen) {
ECerr(EC_F_SM2_DO_ENCRYPT, EC_R_ERROR);
goto end;
}
cv->mactag_size = mactag_size;
memcpy(cv->mactag, dgst, cv->mactag_size);
}
ok = 1;
end:
if (!ok && cv) {
SM2_CIPHERTEXT_VALUE_free(cv);
cv = NULL;
}
if (point) EC_POINT_free(point);
if (n) BN_free(n);
if (h) BN_free(h);
if (k) BN_free(k);
if (bn_ctx) BN_CTX_free(bn_ctx);
if (md_ctx) EVP_MD_CTX_destroy(md_ctx);
return cv;
}
int SM2_decrypt(const SM2_ENC_PARAMS *params,
const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen,
EC_KEY *ec_key)
{
int ret = 0;
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
SM2_CIPHERTEXT_VALUE *cv = NULL;
int len;
if (!(len = SM2_CIPHERTEXT_VALUE_size(ec_group, params, 0))) {
ECerr(EC_F_SM2_DECRYPT, EC_R_ERROR);
/* generate hash = Hash(x2 || M || y2) */
hashlen = cv->hash->length;
if (!EVP_DigestInit_ex(md_ctx, md, NULL)
|| !EVP_DigestUpdate(md_ctx, buf + 1, nbytes)
|| !EVP_DigestUpdate(md_ctx, in, inlen)
|| !EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)
|| !EVP_DigestFinal_ex(md_ctx, cv->hash->data, &hashlen)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, ERR_R_EVP_LIB);
goto end;
}
if (inlen <= len) {
ECerr(EC_F_SM2_DECRYPT, EC_R_ERROR);
ret = cv;
cv = NULL;
end:
SM2CiphertextValue_free(cv);
EC_POINT_free(share_point);
EC_POINT_free(ephem_point);
BN_free(n);
BN_free(h);
BN_clear_free(k);
BN_CTX_free(bn_ctx);
EVP_MD_CTX_free(md_ctx);
return ret;
}
int SM2_encrypt(int type, const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
int ret = 0;
SM2CiphertextValue *cv = NULL;
const EVP_MD *md;
int len;
if (!(md = EVP_get_digestbynid(type))) {
SM2err(SM2_F_SM2_ENCRYPT, SM2_R_INVALID_DIGEST_ALGOR);
return 0;
}
if (!(cv = SM2_do_encrypt(md, in, inlen, ec_key))) {
SM2err(SM2_F_SM2_ENCRYPT, SM2_R_ENCRYPT_FAILURE);
goto end;
}
if (!out) {
*outlen = inlen - len;
return 1;
} else if (*outlen < inlen - len) {
ECerr(EC_F_SM2_DECRYPT, EC_R_ERROR);
*outlen = i2d_SM2CiphertextValue(cv, NULL);
ret = 1;
} else if (*outlen < i2d_SM2CiphertextValue(cv, NULL)) {
SM2err(SM2_F_SM2_ENCRYPT, SM2_R_BUFFER_TOO_SMALL);
ret = 0;
} else {
len = i2d_SM2CiphertextValue(cv, &out);
*outlen = len;
ret = 1;
}
end:
SM2CiphertextValue_free(cv);
return ret;
}
int SM2_decrypt(int type, const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
int ret = 0;
SM2CiphertextValue *cv = NULL;
const EVP_MD *md;
if (!in) {
SM2err(SM2_F_SM2_DECRYPT, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (!(cv = SM2_CIPHERTEXT_VALUE_decode(ec_group, params, in, inlen))) {
ECerr(EC_F_SM2_DECRYPT, EC_R_ERROR);
if (inlen <= 0 || inlen > INT_MAX) {
SM2err(SM2_F_SM2_DECRYPT, SM2_R_INVALID_INPUT_LENGTH);
return 0;
}
if (!out) {
*outlen = inlen;
return 1;
} else if (*outlen < inlen) {
SM2err(SM2_F_SM2_DECRYPT, SM2_R_BUFFER_TOO_SMALL);
return 0;
}
if (!(md = EVP_get_digestbynid(type))) {
SM2err(SM2_F_SM2_DECRYPT, SM2_R_INVALID_DIGEST_ALGOR);
return 0;
}
if (!(cv = d2i_SM2CiphertextValue(NULL, &in, (long)inlen))) {
SM2err(SM2_F_SM2_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
return 0;
}
if (inlen != i2d_SM2CiphertextValue(cv, NULL)) {
SM2err(SM2_F_SM2_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
goto end;
}
if (!SM2_do_decrypt(params, cv, out, outlen, ec_key)) {
ECerr(EC_F_SM2_DECRYPT, EC_R_ERROR);
if (!SM2_do_decrypt(md, cv, out, outlen, ec_key)) {
SM2err(SM2_F_SM2_DECRYPT, SM2_R_DECRYPT_FAILURE);
goto end;
}
ret = 1;
end:
if (cv) SM2_CIPHERTEXT_VALUE_free(cv);
SM2CiphertextValue_free(cv);
return ret;
}
int SM2_do_decrypt(const SM2_ENC_PARAMS *params,
const SM2_CIPHERTEXT_VALUE *cv,
unsigned char *out, size_t *outlen,
EC_KEY *ec_key)
int SM2_do_decrypt(const EVP_MD *md, const SM2CiphertextValue *cv,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
int ret = 0;
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
const BIGNUM *pri_key = EC_KEY_get0_private_key(ec_key);
KDF_FUNC kdf = KDF_get_x9_63(params->kdf_md);
const EC_GROUP *group;
const BIGNUM *pri_key;
KDF_FUNC kdf;
EC_POINT *point = NULL;
BIGNUM *n = NULL;
BIGNUM *h = NULL;
@@ -598,121 +327,136 @@ int SM2_do_decrypt(const SM2_ENC_PARAMS *params,
EVP_MD_CTX *md_ctx = NULL;
unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
unsigned char mac[EVP_MAX_MD_SIZE];
unsigned int maclen;
int mactag_size;
int nbytes;
size_t size;
int i;
unsigned int maclen = sizeof(mac);
int nbytes, len, i;
if (!ec_group || !pri_key) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
/* check arguments */
if (!md || !cv || !outlen || !ec_key) {
SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (!kdf) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
if (!(kdf = KDF_get_x9_63(md))) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_DIGEST_ALGOR);
return 0;
}
if (!cv->xCoordinate || !cv->yCoordinate || !cv->hash || !cv->ciphertext) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
return 0;
}
if (cv->hash->length != EVP_MD_size(md)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
return 0;
}
if (cv->ciphertext->length < SM2_MIN_PLAINTEXT_LENGTH
|| cv->ciphertext->length > SM2_MAX_PLAINTEXT_LENGTH) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
return 0;
}
if (!(group = EC_KEY_get0_group(ec_key))
|| !(pri_key = EC_KEY_get0_private_key(ec_key))) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_EC_KEY);
return 0;
}
if (!out) {
*outlen = cv->ciphertext_size;
*outlen = cv->ciphertext->length;
return 1;
}
if (*outlen < cv->ciphertext_size) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
if (*outlen < cv->ciphertext->length) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_BUFFER_TOO_SMALL);
return 0;
}
/* init vars */
point = EC_POINT_new(ec_group);
/* malloc */
point = EC_POINT_new(group);
n = BN_new();
h = BN_new();
bn_ctx = BN_CTX_new();
md_ctx = EVP_MD_CTX_create();
md_ctx = EVP_MD_CTX_new();
if (!point || !n || !h || !bn_ctx || !md_ctx) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_MALLOC_FAILURE);
goto end;
}
/* init ec domain parameters */
if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
}
if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
}
nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
/* B2: check [h]C1 != O */
if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, h, bn_ctx)) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
}
if (EC_POINT_is_at_infinity(ec_group, point)) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
if (!EC_GROUP_get_order(group, n, bn_ctx)) {
SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_EC_LIB);
goto end;
}
/* B3: compute ECDH [d]C1 = (x2, y2) */
if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, pri_key, bn_ctx)) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
if (!EC_GROUP_get_cofactor(group, h, bn_ctx)) {
SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_EC_LIB);
goto end;
}
if (!(size = EC_POINT_point2oct(ec_group, point,
nbytes = (EC_GROUP_get_degree(group) + 7) / 8;
/* get x/yCoordinates as C1 = (x1, y1) */
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
if (!EC_POINT_set_affine_coordinates_GFp(group, point,
cv->xCoordinate, cv->yCoordinate, bn_ctx)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
goto end;
}
} else {
if (!EC_POINT_set_affine_coordinates_GF2m(group, point,
cv->xCoordinate, cv->yCoordinate, bn_ctx)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
goto end;
}
}
/* check [h]C1 != O */
if (!EC_POINT_mul(group, point, NULL, point, h, bn_ctx)) {
SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_EC_LIB);
goto end;
}
if (EC_POINT_is_at_infinity(group, point)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
goto end;
}
/* compute ECDH [d]C1 = (x2, y2) */
if (!EC_POINT_mul(group, point, NULL, point, pri_key, bn_ctx)) {
SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_EC_LIB);
goto end;
}
if (!(len = EC_POINT_point2oct(group, point,
POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_EC_LIB);
goto end;
}
OPENSSL_assert(size == 1 + nbytes * 2);
/* B4: compute t = KDF(x2 || y2, clen) */
*outlen = cv->ciphertext_size; //FIXME: duplicated code
kdf(buf + 1, size - 1, out, outlen);
/* compute t = KDF(x2 || y2, clen) */
*outlen = cv->ciphertext->length;
kdf(buf + 1, len - 1, out, outlen);
/* B5: compute M = C2 xor t */
for (i = 0; i < cv->ciphertext_size; i++) {
out[i] ^= cv->ciphertext[i];
/* compute M = C2 xor t */
for (i = 0; i < cv->ciphertext->length; i++) {
out[i] ^= cv->ciphertext->data[i];
}
*outlen = cv->ciphertext_size;
mactag_size = EVP_MD_size(params->mac_md);
if (mactag_size) {
/* check hash == Hash(x2 || M || y2) */
if (!EVP_DigestInit_ex(md_ctx, md, NULL)
|| !EVP_DigestUpdate(md_ctx, buf + 1, nbytes)
|| !EVP_DigestUpdate(md_ctx, out, *outlen)
|| !EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)
|| !EVP_DigestFinal_ex(md_ctx, mac, &maclen)) {
SM2err(SM2_F_SM2_DO_DECRYPT, ERR_R_EVP_LIB);
goto end;
}
/* B6: check Hash(x2 || M || y2) == C3 */
if (!EVP_DigestInit_ex(md_ctx, params->mac_md, NULL)) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, out, *outlen)) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
}
if (!EVP_DigestFinal_ex(md_ctx, mac, &maclen)) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
}
/* GmSSL specific */
if (mactag_size > (int)maclen) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
}
if (cv->mactag_size != mactag_size ||
OPENSSL_memcmp(mac, cv->mactag, cv->mactag_size)) {
ECerr(EC_F_SM2_DO_DECRYPT, EC_R_ERROR);
goto end;
}
if (OPENSSL_memcmp(cv->hash->data, mac, maclen) != 0) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_INVALID_CIPHERTEXT);
goto end;
}
ret = 1;
@@ -721,24 +465,6 @@ end:
BN_free(n);
BN_free(h);
BN_CTX_free(bn_ctx);
EVP_MD_CTX_destroy(md_ctx);
EVP_MD_CTX_free(md_ctx);
return ret;
}
int SM2_encrypt_with_recommended(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
SM2_ENC_PARAMS params;
SM2_ENC_PARAMS_init_with_recommended(&params);
return SM2_encrypt(&params, in, inlen, out, outlen, ec_key);
}
int SM2_decrypt_with_recommended(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen,
EC_KEY *ec_key)
{
SM2_ENC_PARAMS params;
SM2_ENC_PARAMS_init_with_recommended(&params);
return SM2_decrypt(&params, in, inlen, out, outlen, ec_key);
}

65
crypto/sm2/sm2_err.c Normal file
View File

@@ -0,0 +1,65 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/sm2.h>
/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR
# define ERR_FUNC(func) ERR_PACK(ERR_LIB_SM2,func,0)
# define ERR_REASON(reason) ERR_PACK(ERR_LIB_SM2,0,reason)
static ERR_STRING_DATA SM2_str_functs[] = {
{ERR_FUNC(SM2_F_I2O_SM2CIPHERTEXTVALUE), "i2o_SM2CiphertextValue"},
{ERR_FUNC(SM2_F_O2I_SM2CIPHERTEXTVALUE), "o2i_SM2CiphertextValue"},
{ERR_FUNC(SM2_F_SM2_DECRYPT), "SM2_decrypt"},
{ERR_FUNC(SM2_F_SM2_DO_DECRYPT), "SM2_do_decrypt"},
{ERR_FUNC(SM2_F_SM2_DO_ENCRYPT), "SM2_do_encrypt"},
{ERR_FUNC(SM2_F_SM2_DO_SIGN), "SM2_do_sign"},
{ERR_FUNC(SM2_F_SM2_DO_VERIFY), "SM2_do_verify"},
{ERR_FUNC(SM2_F_SM2_ENCRYPT), "SM2_encrypt"},
{ERR_FUNC(SM2_F_SM2_SIGN_SETUP), "SM2_sign_setup"},
{0, NULL}
};
static ERR_STRING_DATA SM2_str_reasons[] = {
{ERR_REASON(SM2_R_BAD_SIGNATURE), "bad signature"},
{ERR_REASON(SM2_R_BUFFER_TOO_SMALL), "buffer too small"},
{ERR_REASON(SM2_R_DECRYPT_FAILURE), "decrypt failure"},
{ERR_REASON(SM2_R_ENCRYPT_FAILURE), "encrypt failure"},
{ERR_REASON(SM2_R_INVALID_CIPHERTEXT), "invalid ciphertext"},
{ERR_REASON(SM2_R_INVALID_DIGEST_ALGOR), "invalid digest algor"},
{ERR_REASON(SM2_R_INVALID_EC_KEY), "invalid ec key"},
{ERR_REASON(SM2_R_INVALID_INPUT_LENGTH), "invalid input length"},
{ERR_REASON(SM2_R_INVALID_PLAINTEXT_LENGTH), "invalid plaintext length"},
{ERR_REASON(SM2_R_INVALID_PUBLIC_KEY), "invalid public key"},
{ERR_REASON(SM2_R_KDF_FAILURE), "kdf failure"},
{ERR_REASON(SM2_R_MISSING_PARAMETERS), "missing parameters"},
{ERR_REASON(SM2_R_NEED_NEW_SETUP_VALUES), "need new setup values"},
{ERR_REASON(SM2_R_RANDOM_NUMBER_GENERATION_FAILED),
"random number generation failed"},
{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(0, SM2_str_functs);
ERR_load_strings(0, SM2_str_reasons);
}
#endif
return 1;
}

584
crypto/sm2/sm2_exch.c Normal file
View File

@@ -0,0 +1,584 @@
/* ====================================================================
* Copyright (c) 2015 - 2016 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
*/
#include <string.h>
#include <openssl/ec.h>
#include <openssl/sm2.h>
#include <openssl/kdf.h>
#include "sm2_lcl.h"
int SM2_KAP_CTX_init(SM2_KAP_CTX *ctx,
EC_KEY *ec_key, const char *id, size_t idlen,
EC_KEY *remote_pubkey, const char *rid, size_t ridlen,
int is_initiator, int do_checksum)
{
int ret = 0;
int w;
size_t len;
if (!ctx || !ec_key || !remote_pubkey) {
ECerr(EC_F_SM2_KAP_CTX_INIT, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
memset(ctx, 0, sizeof(*ctx));
ctx->id_dgst_md = EVP_sm3();
ctx->kdf_md = EVP_sm3();
ctx->checksum_md = EVP_sm3();
ctx->point_form = SM2_DEFAULT_POINT_CONVERSION_FORM;
if (!(ctx->kdf = KDF_get_x9_63(ctx->kdf_md))) {
ECerr(EC_F_SM2_KAP_CTX_INIT, EC_R_INVALID_KDF_MD);
goto end;
}
ctx->is_initiator = is_initiator;
ctx->do_checksum = do_checksum;
if (EC_GROUP_cmp(EC_KEY_get0_group(ec_key),
EC_KEY_get0_group(remote_pubkey), NULL) != 0) {
ECerr(EC_F_SM2_KAP_CTX_INIT, 0);
goto end;
}
len = ctx->id_dgstlen;
if (!SM2_compute_id_digest(ctx->id_dgst_md, id, idlen,
ctx->id_dgst, &len, ec_key)) {
ECerr(EC_F_SM2_KAP_CTX_INIT, 0);
goto end;
}
ctx->id_dgstlen = len;
if (!(ctx->ec_key = EC_KEY_dup(ec_key))) {
ECerr(EC_F_SM2_KAP_CTX_INIT, ERR_R_EC_LIB);
goto end;
}
len = ctx->remote_id_dgstlen;
if (!SM2_compute_id_digest(ctx->id_dgst_md, rid, ridlen,
ctx->remote_id_dgst, &len, remote_pubkey)) {
ECerr(EC_F_SM2_KAP_CTX_INIT, 0);
goto end;
}
ctx->remote_id_dgstlen = len;
if (!(ctx->remote_pubkey = EC_KEY_dup(remote_pubkey))) {
ECerr(EC_F_SM2_KAP_CTX_INIT, 0);
goto end;
}
ctx->group = EC_KEY_get0_group(ec_key);
ctx->bn_ctx = BN_CTX_new();
ctx->order = BN_new();
ctx->two_pow_w = BN_new();
ctx->t = BN_new();
if (!ctx->bn_ctx || !ctx->order || !ctx->two_pow_w || !ctx->t) {
ECerr(EC_F_SM2_KAP_CTX_INIT, ERR_R_BN_LIB);
goto end;
}
if (!EC_GROUP_get_order(EC_KEY_get0_group(ec_key), ctx->order, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_CTX_INIT, ERR_R_EC_LIB);
goto end;
}
w = (BN_num_bits(ctx->order) + 1)/2 - 1;
if (!BN_one(ctx->two_pow_w)) {
ECerr(EC_F_SM2_KAP_CTX_INIT, ERR_R_BN_LIB);
goto end;
}
if (!BN_lshift(ctx->two_pow_w, ctx->two_pow_w, w)) {
ECerr(EC_F_SM2_KAP_CTX_INIT, ERR_R_BN_LIB);
goto end;
}
if (!(ctx->point = EC_POINT_new(ctx->group))) {
ECerr(EC_F_SM2_KAP_CTX_INIT, ERR_R_EC_LIB);
goto end;
}
ret = 1;
end:
if (!ret) SM2_KAP_CTX_cleanup(ctx);
return ret;
}
void SM2_KAP_CTX_cleanup(SM2_KAP_CTX *ctx)
{
if (ctx) {
EC_KEY_free(ctx->ec_key);
EC_KEY_free(ctx->remote_pubkey);
BN_CTX_free(ctx->bn_ctx);
BN_free(ctx->two_pow_w);
BN_free(ctx->order);
EC_POINT_free(ctx->point);
BN_free(ctx->t);
memset(ctx, 0, sizeof(*ctx));
}
}
/* FIXME: ephem_point_len should be both input and output */
int SM2_KAP_prepare(SM2_KAP_CTX *ctx, unsigned char *ephem_point,
size_t *ephem_point_len)
{
int ret = 0;
const BIGNUM *prikey;
BIGNUM *h = NULL;
BIGNUM *r = NULL;
BIGNUM *x = NULL;
if (!(prikey = EC_KEY_get0_private_key(ctx->ec_key))) {
ECerr(EC_F_SM2_KAP_PREPARE, EC_R_SM2_KAP_NOT_INITED);
return 0;
}
h = BN_new();
r = BN_new();
x = BN_new();
if (!h || !r || !x) {
ECerr(EC_F_SM2_KAP_PREPARE, 0);
goto end;
}
/*
* r = rand(1, n)
* R = rG = (x, y)
*/
do {
if (!BN_rand_range(r, ctx->order)) {
ECerr(EC_F_SM2_KAP_PREPARE, EC_R_RANDOM_NUMBER_GENERATION_FAILED);
goto end;
}
} while (BN_is_zero(r));
if (!EC_POINT_mul(ctx->group, ctx->point, r, NULL, NULL, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_PREPARE, ERR_R_EC_LIB);
goto end;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(ctx->group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(ctx->group, ctx->point, x, NULL, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_PREPARE, ERR_R_EC_LIB);
goto end;
}
} else {
if (!EC_POINT_get_affine_coordinates_GF2m(ctx->group, ctx->point, x, NULL, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_PREPARE, ERR_R_EC_LIB);
goto end;
}
}
/*
* w = ceil(keybits / 2) - 1
* x = 2^w + (x and (2^w - 1)) = 2^w + (x mod 2^w)
* t = (d + x * r) mod n
* t = (h * t) mod n
*/
if (!ctx->t) {
ECerr(EC_F_SM2_KAP_PREPARE, EC_R_SM2_KAP_NOT_INITED);
goto end;
}
if (!BN_nnmod(x, x, ctx->two_pow_w, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
if (!BN_add(x, x, ctx->two_pow_w)) {
ECerr(EC_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_mul(ctx->t, x, r, ctx->order, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_add(ctx->t, ctx->t, prikey, ctx->order, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
if (!EC_GROUP_get_cofactor(ctx->group, h, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_PREPARE, ERR_R_EC_LIB);
goto end;
}
if (!BN_mul(ctx->t, ctx->t, h, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_PREPARE, ERR_R_BN_LIB);
goto end;
}
/* encode R = (x, y) for output and local buffer */
// FIXME: ret is size_t and ret is the output length
ret = EC_POINT_point2oct(ctx->group, ctx->point, ctx->point_form,
ephem_point, *ephem_point_len, ctx->bn_ctx);
memcpy(ctx->pt_buf, ephem_point, ret);
*ephem_point_len = ret;
ret = 1;
end:
if (h) BN_free(h);
if (r) BN_free(r);
if (x) BN_free(x);
return ret;
}
int SM2_KAP_compute_key(SM2_KAP_CTX *ctx, const unsigned char *remote_point,
size_t remote_point_len, unsigned char *key, size_t keylen,
unsigned char *checksum, size_t *checksumlen)
{
int ret = 0;
EVP_MD_CTX *md_ctx = NULL;
BIGNUM *x = NULL;
unsigned char share_pt_buf[1 + (OPENSSL_ECC_MAX_FIELD_BITS+7)/4 + EVP_MAX_MD_SIZE * 2 + 100];
unsigned char remote_pt_buf[1 + (OPENSSL_ECC_MAX_FIELD_BITS+7)/4 + 111];
unsigned char dgst[EVP_MAX_MD_SIZE];
unsigned int dgstlen;
unsigned int len, bnlen;
size_t klen = keylen;
md_ctx = EVP_MD_CTX_new();
x = BN_new();
if (!md_ctx || !x) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
/*
* decode point R = (x, y), encode (x, y)
* x = 2^w + (x and (2^w - 1)) = 2^w + (x mod 2^w), w = ceil(keybits / 2) - 1
* U = ht * (P + x * R)
* check U != O
*/
if (!EC_POINT_oct2point(ctx->group, ctx->point,
remote_point, remote_point_len, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
if (!(len = EC_POINT_point2oct(ctx->group, ctx->point, POINT_CONVERSION_UNCOMPRESSED,
remote_pt_buf, sizeof(remote_pt_buf), ctx->bn_ctx))) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(ctx->group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(ctx->group, ctx->point, x, NULL, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
} else {
if (!EC_POINT_get_affine_coordinates_GF2m(ctx->group, ctx->point, x, NULL, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
}
/* x = 2^w + (x and (2^w - 1)) = 2^w + (x mod 2^w) */
if (!BN_nnmod(x, x, ctx->two_pow_w, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_BN_LIB);
goto end;
}
if (!BN_add(x, x, ctx->two_pow_w)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_BN_LIB);
goto end;
}
/*
if (!BN_mod_mul(x, x, ctx->t, ctx->order, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_BN_LIB);
goto end;
}
*/
/* U = ht * (P + x * R), check U != O */
if (!EC_POINT_mul(ctx->group, ctx->point, NULL, ctx->point, x, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
if (!EC_POINT_add(ctx->group, ctx->point, ctx->point,
EC_KEY_get0_public_key(ctx->remote_pubkey), ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
if (!EC_POINT_mul(ctx->group, ctx->point, NULL, ctx->point, ctx->t, ctx->bn_ctx)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EC_LIB);
goto end;
}
if (EC_POINT_is_at_infinity(ctx->group, ctx->point)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
/* encode U, append with ZA, ZB */
if (!(len = EC_POINT_point2oct(ctx->group, ctx->point, POINT_CONVERSION_UNCOMPRESSED,
share_pt_buf, sizeof(share_pt_buf), ctx->bn_ctx))) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
if (ctx->is_initiator) {
memcpy(share_pt_buf + len, ctx->id_dgst, ctx->id_dgstlen);
len += ctx->id_dgstlen;
memcpy(share_pt_buf + len, ctx->remote_id_dgst, ctx->remote_id_dgstlen);
len += ctx->remote_id_dgstlen;
} else {
memcpy(share_pt_buf + len, ctx->remote_id_dgst, ctx->remote_id_dgstlen);
len += ctx->remote_id_dgstlen;
memcpy(share_pt_buf + len, ctx->id_dgst, ctx->id_dgstlen);
len += ctx->id_dgstlen;
}
/* key = KDF(xu, yu, ZA, ZB) */
if (!ctx->kdf(share_pt_buf + 1, len - 1, key, &klen)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, 0);
goto end;
}
if (ctx->do_checksum) {
/* generate checksum S1 or SB start with 0x02
* S1 = SB = Hash(0x02, yu, Hash(xu, ZA, ZB, x1, y1, x2, y2))
*/
if (!EVP_DigestInit_ex(md_ctx, ctx->checksum_md, NULL)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
bnlen = BN_num_bytes(ctx->order);
if (!EVP_DigestUpdate(md_ctx, share_pt_buf + 1, bnlen)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (ctx->is_initiator) {
/* update ZA,ZB,x1,y1,x2,y2 */
if (!EVP_DigestUpdate(md_ctx, ctx->id_dgst, ctx->id_dgstlen)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, ctx->remote_id_dgst, ctx->remote_id_dgstlen)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, ctx->pt_buf + 1, bnlen * 2)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, remote_pt_buf + 1, bnlen * 2)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
} else {
if (!EVP_DigestUpdate(md_ctx, ctx->remote_id_dgst, ctx->remote_id_dgstlen)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, ctx->id_dgst, ctx->id_dgstlen)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, remote_pt_buf + 1, bnlen * 2)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, ctx->pt_buf + 1, bnlen * 2)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
}
if (!EVP_DigestFinal_ex(md_ctx, dgst, &dgstlen)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
/* now dgst == H(xu,ZA,ZB,x1,y1,x2,y2)
*/
/* S1 = SB = Hash(0x02, yu, dgst) */
if (!EVP_DigestInit_ex(md_ctx, ctx->checksum_md, NULL)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, "\x02", 1)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, share_pt_buf + 1 + bnlen, bnlen)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, dgst, dgstlen)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
/* output S1 to local buffer or SB to output */
if (ctx->is_initiator) {
if (!EVP_DigestFinal_ex(md_ctx, ctx->checksum, &len)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
} else {
if (!EVP_DigestFinal_ex(md_ctx, checksum, &len)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
*checksumlen = len;
}
/* generate checksum SA or S2 start with 0x03
* SA = S2 = Hash(0x03, yu, dgst)
*/
if (!EVP_DigestInit_ex(md_ctx, ctx->checksum_md, NULL)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, "\x03", 1)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, share_pt_buf + 1 + bnlen, bnlen)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, dgst, dgstlen)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
if (ctx->is_initiator) {
if (!EVP_DigestFinal_ex(md_ctx, checksum, &len)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
*checksumlen = len;
} else {
if (!EVP_DigestFinal_ex(md_ctx, ctx->checksum, &len)) {
ECerr(EC_F_SM2_KAP_COMPUTE_KEY, ERR_R_EVP_LIB);
goto end;
}
}
}
ret = 1;
end:
EVP_MD_CTX_free(md_ctx);
BN_free(x);
return ret;
}
int SM2_KAP_final_check(SM2_KAP_CTX *ctx, const unsigned char *checksum,
size_t checksumlen)
{
if (ctx->do_checksum) {
if (checksumlen != EVP_MD_size(ctx->checksum_md)) {
ECerr(EC_F_SM2_KAP_FINAL_CHECK, EC_R_INVALID_SM2_KAP_CHECKSUM_LENGTH);
return 0;
}
if (memcmp(ctx->checksum, checksum, checksumlen)) {
ECerr(EC_F_SM2_KAP_FINAL_CHECK, EC_R_INVALID_SM2_KAP_CHECKSUM_VALUE);
return 0;
}
}
return 1;
}
int SM2_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
const EC_KEY *ec_key, KDF_FUNC kdf_f)
{
return 0;
}

View File

@@ -59,6 +59,7 @@
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include "sm2_lcl.h"
#define EC_MAX_NBYTES ((OPENSSL_ECC_MAX_FIELD_BITS + 7)/8)
@@ -211,7 +212,7 @@ int SM2_compute_id_digest(const EVP_MD *md, const char *id, size_t idlen,
}
#ifndef OPENSSL_NO_STRICT_GM
if (EVP_MD_size(md) != SM2_ID_DIGEST_LENGTH) {
if (EVP_MD_size(md) != SM2_DEFAULT_ID_DIGEST_LENGTH) {
ECerr(EC_F_SM2_COMPUTE_ID_DIGEST, EC_R_INVALID_DIGEST_ALGOR);
return 0;
}

View File

@@ -52,6 +52,8 @@
#include <openssl/ec.h>
#include <openssl/sm2.h>
#include <openssl/kdf.h>
#include "sm2_lcl.h"
int SM2_KAP_CTX_init(SM2_KAP_CTX *ctx,
EC_KEY *ec_key, const char *id, size_t idlen,

View File

@@ -58,138 +58,22 @@
#define SM2_KMETH_FLAGS 0
int SM2_ENC_PARAMS_set_type(SM2_ENC_PARAMS *params, int type)
{
const EVP_MD *md;
if (!(md = EVP_get_digestbynid(type))) {
ECerr(EC_F_SM2_ENC_PARAMS_SET_TYPE, EC_R_INVALID_DIGEST_TYPE);
return 0;
}
params->kdf_md = md;
params->mac_md = md;
params->point_form = SM2_DEFAULT_POINT_CONVERSION_FORM;
return 1;
}
SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_new_from_ECIES_CIPHERTEXT_VALUE(
const ECIES_CIPHERTEXT_VALUE *in)
{
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_NEW_FROM_ECIES_CIPHERTEXT_VALUE,
ERR_R_EC_LIB);
return NULL;
}
int SM2_CIPHERTEXT_VALUE_set_ECIES_CIPHERTEXT_VALUE(SM2_CIPHERTEXT_VALUE *sm2,
const ECIES_CIPHERTEXT_VALUE *in)
{
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_SET_ECIES_CIPHERTEXT_VALUE,
ERR_R_EC_LIB);
return 0;
}
int SM2_CIPHERTEXT_VALUE_get_ECIES_CIPHERTEXT_VALUE(
const SM2_CIPHERTEXT_VALUE *sm2, ECIES_CIPHERTEXT_VALUE *out)
{
ECerr(EC_F_SM2_CIPHERTEXT_VALUE_GET_ECIES_CIPHERTEXT_VALUE,
ERR_R_EC_LIB);
return 0;
}
static int sm2_compute_key(unsigned char **Pout, size_t *poutlen,
const EC_POINT *pub_key, const EC_KEY *ec_key)
{
return 0;
}
static int sm2_encrypt(int type, const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
SM2_ENC_PARAMS param;
if (!SM2_ENC_PARAMS_set_type(&param, type)) {
return 0;
}
return SM2_encrypt(&param, in, inlen, out, outlen, ec_key);
}
ECIES_CIPHERTEXT_VALUE *sm2_do_encrypt(int type, const unsigned char *in,
size_t inlen, EC_KEY *ec_key)
{
ECIES_CIPHERTEXT_VALUE *ret = NULL;
ECIES_CIPHERTEXT_VALUE *ecies = NULL;
SM2_CIPHERTEXT_VALUE *sm2 = NULL;
SM2_ENC_PARAMS param;
if (!(ecies = ECIES_CIPHERTEXT_VALUE_new())) {
goto end;
}
if (!SM2_ENC_PARAMS_set_type(&param, type)) {
goto end;
}
if (!(sm2 = SM2_do_encrypt(&param, in, inlen, ec_key))) {
goto end;
}
if (!SM2_CIPHERTEXT_VALUE_get_ECIES_CIPHERTEXT_VALUE(sm2, ecies)) {
goto end;
}
ret = ecies;
ecies = NULL;
end:
ECIES_CIPHERTEXT_VALUE_free(ecies);
SM2_CIPHERTEXT_VALUE_free(sm2);
return ret;
}
int sm2_decrypt(int type, const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
SM2_ENC_PARAMS param;
if (!SM2_ENC_PARAMS_set_type(&param, type)) {
return 0;
}
return SM2_decrypt(&param, in, inlen, out, outlen, ec_key);
}
int sm2_do_decrypt(int type, const ECIES_CIPHERTEXT_VALUE *in,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
int ret = 0;
SM2_CIPHERTEXT_VALUE *sm2 = NULL;
SM2_ENC_PARAMS param;
if (!SM2_ENC_PARAMS_set_type(&param, type)) {
goto end;
}
// we might require type/param
if (!(sm2 = SM2_CIPHERTEXT_VALUE_new_from_ECIES_CIPHERTEXT_VALUE(in))) {
goto end;
}
if (!SM2_do_decrypt(&param, sm2, out, outlen, ec_key)) {
goto end;
}
ret = 1;
end:
SM2_CIPHERTEXT_VALUE_free(sm2);
return ret;
}
static const EC_KEY_METHOD gmssl_ec_key_method = {
"GmSSL EC_KEY method",
EC_KEY_METHOD_SM2,
0,0,0,0,0,0,
ossl_ec_key_gen,
sm2_compute_key,
SM2_sign,
NULL,
SM2_sign_ex,
SM2_sign_setup,
SM2_do_sign,
SM2_do_sign_ex,
SM2_verify,
SM2_do_verify,
sm2_encrypt,
sm2_do_encrypt,
sm2_decrypt,
sm2_do_decrypt,
SM2_encrypt,
NULL,
SM2_decrypt,
NULL,
};
const EC_KEY_METHOD *EC_KEY_GmSSL(void)
@@ -206,7 +90,6 @@ int EC_KEY_METHOD_type(const EC_KEY_METHOD *meth)
}
}
void EC_KEY_METHOD_set_encrypt(EC_KEY_METHOD *meth,
int (*encrypt)(int type,
const unsigned char *in,

View File

@@ -1,5 +1,107 @@
/*
* Copyright (c) 2015 - 2017 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define EC_KEY_METHOD_SM2 0x02
#define SM2_DEFAULT_POINT_CONVERSION_FORM POINT_CONVERSION_UNCOMPRESSED
#define SM2_MAX_PKEY_DATA_LENGTH ((EC_MAX_NBYTES + 1) * 6)
int SM2_get_public_key_data(EC_KEY *ec_key, unsigned char *out, size_t *outlen);
int SM2_compute_message_digest(const EVP_MD *id_md, const EVP_MD *msg_md,
const unsigned char *msg, size_t msglen, const char *id, size_t idlen,
unsigned char *out, size_t *outlen,
EC_KEY *ec_key);
struct SM2CiphertextValue_st {
BIGNUM *xCoordinate;
BIGNUM *yCoordinate;
ASN1_OCTET_STRING *hash;
ASN1_OCTET_STRING *ciphertext;
};
struct sm2_kap_ctx_st {
const EVP_MD *id_dgst_md;
const EVP_MD *kdf_md;
const EVP_MD *checksum_md;
point_conversion_form_t point_form;
KDF_FUNC kdf;
int is_initiator;
int do_checksum;
EC_KEY *ec_key;
unsigned char id_dgst[EVP_MAX_MD_SIZE];
unsigned int id_dgstlen;
EC_KEY *remote_pubkey;
unsigned char remote_id_dgst[EVP_MAX_MD_SIZE];
unsigned int remote_id_dgstlen;
const EC_GROUP *group;
BN_CTX *bn_ctx;
BIGNUM *order;
BIGNUM *two_pow_w;
BIGNUM *t;
EC_POINT *point;
unsigned char pt_buf[1 + (OPENSSL_ECC_MAX_FIELD_BITS+7)/4];
unsigned char checksum[EVP_MAX_MD_SIZE];
};
int i2o_SM2CiphertextValue(const EC_GROUP *group, const SM2CiphertextValue *cv,
unsigned char **pout);
SM2CiphertextValue *o2i_SM2CiphertextValue(const EC_GROUP *group,
SM2CiphertextValue **cv, const unsigned char **pin, long len);

311
crypto/sm2/sm2_oct.c Normal file
View File

@@ -0,0 +1,311 @@
/* ====================================================================
* Copyright (c) 2007 - 2016 The GmSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the GmSSL Project.
* (http://gmssl.org/)"
*
* 4. The name "GmSSL Project" must not be used to endorse or promote
* products derived from this software without prior written
* permission. For written permission, please contact
* guanzhi1980@gmail.com.
*
* 5. Products derived from this software may not be called "GmSSL"
* nor may "GmSSL" appear in their names without prior written
* permission of the GmSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the GmSSL Project
* (http://gmssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
#include <string.h>
#include <openssl/ec.h>
#include <openssl/sm2.h>
#include <openssl/err.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include <openssl/obj_mac.h>
#include "sm2_lcl.h"
int i2o_SM2CiphertextValue(const EC_GROUP *group, const SM2CiphertextValue *cv,
unsigned char **pout)
{
int ret = 0, outlen = 0, nbytes;
EC_POINT *point = NULL;
BN_CTX *bn_ctx = NULL;
unsigned char *buf;
unsigned char *p;
if (!group || !cv || !pout) {
SM2err(SM2_F_I2O_SM2CIPHERTEXTVALUE,
ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
nbytes = (EC_GROUP_get_degree(group) + 7)/8;
if (!cv->xCoordinate || BN_num_bytes(cv->xCoordinate) > nbytes
|| !cv->yCoordinate || BN_num_bytes(cv->BN_num_bytes) > nbytes
|| ASN1_STRING_length(cv->hash) <= 0
|| ASN1_STRING_length(cv->hash) > EVP_MAX_MD_SIZE
|| ASN1_STRING_length(cv->ciphertext) <= 0) {
SM2err(SM2_F_I2O_SM2CIPHERTEXTVALUE, SM2_R_INVALID_CIPHERTEXT);
return 0;
}
/* prepare buffer */
if (*pout) {
p = *pout;
} else {
size_t buflen = 1 + nbytes * 2
+ ASN1_STRING_length(cv->ciphertext)
+ ASN1_STRING_length(cv->hash);
if (!(buf = OPENSSL_malloc(buflen))) {
SM2err(SM2_F_I2O_SM2CIPHERTEXTVALUE,
ERR_R_MALLOC_FAILURE);
return 0;
}
p = buf;
}
/* encode x, y */
if (!(point = EC_POINT_new(group)) || !(bn_ctx = BN_CTX_new())) {
SM2err(SM2_F_I2O_SM2CIPHERTEXTVALUE, ERR_R_MALLOC_FAILURE);
goto end;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
if (!EC_POINT_set_affine_coordinates_GFp(group, point,
cv->xCoordinate, cv->yCoordinate, bn_ctx)) {
goto end;
}
} else {
if (!EC_POINT_set_affine_coordinates_GF2m(group, point,
cv->xCoordinate, cv->yCoordinate, bn_ctx)) {
goto end;
}
}
if (!(siz = EC_POINT_point2oct(group, point,
POINT_CONVERSION_UNCOMPRESSED, p, 1 + 2 * nbytes, bn_ctx))) {
SM2err(SM2_F_I2O_SM2CIPHERTEXTVALUE, ERR_R_EC_LIB);
goto end;
}
OPENSSL_assert(siz == 1 + 2 * nbytes);
p += siz;
outlen += siz;
/* encode ciphertext */
memcpy(p, ASN1_STRING_get0_data(cv->ciphertext),
ASN1_STRING_length(cv->ciphertext));
p += ASN1_STRING_length(cv->ciphertext);
outlen += siz;
/* encode hash */
memcpy(out, ASN1_STRING_get0_data(cv->hash),
ASN1_STRING_length(cv->hash));
p += ASN1_STRING_length(cv->hash);
outlen += siz;
/* output */
if (*pout) {
*pout = p;
} else {
*pout = buf;
buf = NULL;
}
ret = outlen;
end:
EC_POINT_free(point);
BN_CTX_free(bn_ctx);
return ret;
}
SM2CiphertextValue *o2i_SM2CiphertextValue(const EC_GROUP *group,
const EVP_MD *md, SM2CiphertextValue **pout,
const unsigned char **pin, long len)
{
SM2CiphertextValue *ret = NULL;
SM2CiphertextValue *cv = NULL;
BN_CTX *bn_ctx = NULL;
unsigned char *p;
if (!group || !pin) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE,
ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
nbytes = (EC_GROUP_get_degree(group) + 7)/8;
if (len <= 1 + nbytes * 2 + EVP_MD_size(md)) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE,
SM2_R_INVALID_CIPHERTEXT);
return NULL;
}
if (pout && *pout) {
cv = *pout;
} else {
if (!(cv = SM2CiphertextValue_new())) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE,
ERR_R_MALLOC_FAILURE);
goto end;
}
}
if (!(point = EC_POINT_new(group))
|| !(bn_ctx = BN_CTX_new(bn_ctx))) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE,
ERR_R_MALLOC_FAILURE);
goto end;
}
p = *pin;
/* set (x, y) */
if (!EC_POINT_oct2point(group, point, p, 1 + nbytes * 2, bn_ctx)) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE,
SM2_R_INVALID_CIPHERTEXT);
goto end;
}
p += 1 + nbytes * 2;
len -= 1 + nbytes * 2;
if (!cv->xCoordinate) {
if (!(cv->xCoordinate = BN_new())) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE,
ERR_R_MALLOC_FAILURE);
goto end;
}
}
if (!cv->yCoordinate) {
if (!(cv->yCoordinate = BN_new())) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE,
ERR_R_MALLOC_FAILURE);
goto end;
}
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(group, point,
cv->xCoordinate, cv->yCoordinate, bn_ctx)) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE, ERR_R_EC_LIB);
goto end;
}
} else {
if (!EC_POINT_get_affine_coordinates_GF2m(group, point,
cv->xCoordinate, cv->yCoordinate, bn_ctx)) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE, ERR_R_EC_LIB);
goto end;
}
}
/* set ciphertext */
if (!cv->ciphertext) {
if (!(cv->ciphertext = ASN1_OCTET_STRING_new())) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE,
ERR_R_MALLOC_FAILURE);
goto end;
}
}
if (!ASN1_OCTET_STRING_set(cv->ciphertext, p, len - EVP_MD_size(md))) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE, ERR_R_ASN1_LIB);
goto end;
}
p += len - EVP_MD_size(md);
/* set hash */
if (!cv->hash) {
if (!(cv->hash = ASN1_OCTET_STRING_new())) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE,
ERR_R_MALLOC_FAILURE);
goto end;
}
}
if (!ASN1_OCTET_STRING_set(cv->hash, p, EVP_MD_size(md))) {
SM2err(SM2_F_O2I_SM2CIPHERTEXTVALUE, ERR_R_ASN1_LIB);
goto end;
}
p += EVP_MD_size(md);
/* set result */
*pin = p;
ret = cv;
end:
SM2CiphertextValue_free(cv);
EC_POINT_free(point);
BN_CTX_free(bn_ctx);
return ret;
}
int SM2_encrypt(const EVP_MD *md, const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
int ret = 0;
SM2CiphertextValue *cv = NULL;
if (!(cv = SM2_do_encrypt(md, in, inlen, ec_key))) {
goto end;
}
if (!out) {
len = i2o_SM2CiphertextValue(cv, NULL);
*outlen = len;
return 1;
}
if (!(i2o_SM2CiphertextValue(cv, &out))) {
goto end;
}
return 0;
}
int SM2_decrypt(int type, const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
SM2CiphertextValue *cv = NULL;
}

View File

@@ -69,13 +69,13 @@ static int sm2_sign_setup(EC_KEY *ec_key, BN_CTX *ctx_in, BIGNUM **kp, BIGNUM **
EC_POINT *point = NULL;
if (ec_key == NULL || (ec_group = EC_KEY_get0_group(ec_key)) == NULL) {
ECerr(EC_F_SM2_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
SM2err(SM2_F_SM2_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (ctx_in == NULL) {
if ((ctx = BN_CTX_new()) == NULL) {
ECerr(EC_F_SM2_SIGN_SETUP,ERR_R_MALLOC_FAILURE);
SM2err(SM2_F_SM2_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
return 0;
}
}
@@ -87,17 +87,17 @@ static int sm2_sign_setup(EC_KEY *ec_key, BN_CTX *ctx_in, BIGNUM **kp, BIGNUM **
x = BN_new();
order = BN_new();
if (!k || !x || !order) {
ECerr(EC_F_SM2_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
SM2err(SM2_F_SM2_SIGN_SETUP, ERR_R_MALLOC_FAILURE);
goto end;
}
if (!EC_GROUP_get_order(ec_group, order, ctx)) {
ECerr(EC_F_SM2_SIGN_SETUP, ERR_R_EC_LIB);
SM2err(SM2_F_SM2_SIGN_SETUP, ERR_R_EC_LIB);
goto end;
}
if ((point = EC_POINT_new(ec_group)) == NULL) {
ECerr(EC_F_SM2_SIGN_SETUP, ERR_R_EC_LIB);
SM2err(SM2_F_SM2_SIGN_SETUP, ERR_R_EC_LIB);
goto end;
}
@@ -105,8 +105,8 @@ static int sm2_sign_setup(EC_KEY *ec_key, BN_CTX *ctx_in, BIGNUM **kp, BIGNUM **
/* get random k */
do {
if (!BN_rand_range(k, order)) {
ECerr(EC_F_SM2_SIGN_SETUP,
EC_R_RANDOM_NUMBER_GENERATION_FAILED);
SM2err(SM2_F_SM2_SIGN_SETUP,
SM2_R_RANDOM_NUMBER_GENERATION_FAILED);
goto end;
}
@@ -114,24 +114,24 @@ static int sm2_sign_setup(EC_KEY *ec_key, BN_CTX *ctx_in, BIGNUM **kp, BIGNUM **
/* compute r the x-coordinate of generator * k */
if (!EC_POINT_mul(ec_group, point, k, NULL, NULL, ctx)) {
ECerr(EC_F_SM2_SIGN_SETUP, ERR_R_EC_LIB);
SM2err(SM2_F_SM2_SIGN_SETUP, ERR_R_EC_LIB);
goto end;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(ec_group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(ec_group, point, x, NULL, ctx)) {
ECerr(EC_F_SM2_SIGN_SETUP,ERR_R_EC_LIB);
SM2err(SM2_F_SM2_SIGN_SETUP, ERR_R_EC_LIB);
goto end;
}
} else /* NID_X9_62_characteristic_two_field */ {
if (!EC_POINT_get_affine_coordinates_GF2m(ec_group, point, x, NULL, ctx)) {
ECerr(EC_F_SM2_SIGN_SETUP,ERR_R_EC_LIB);
SM2err(SM2_F_SM2_SIGN_SETUP, ERR_R_EC_LIB);
goto end;
}
}
if (!BN_nnmod(x, x, order, ctx)) {
ECerr(EC_F_SM2_SIGN_SETUP, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_SIGN_SETUP, ERR_R_BN_LIB);
goto end;
}
@@ -178,12 +178,12 @@ static ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgstlen,
ec_group = EC_KEY_get0_group(ec_key);
priv_key = EC_KEY_get0_private_key(ec_key);
if (!ec_group || !priv_key) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (!(ret = ECDSA_SIG_new())) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_MALLOC_FAILURE);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->r = BN_new();
@@ -193,11 +193,11 @@ static ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgstlen,
e = BN_new();
bn = BN_new();
if (!ret->r || !ret->s || !ctx || !order || !e || !bn) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_MALLOC_FAILURE);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto end;
}
if (!EC_GROUP_get_order(ec_group, order, ctx)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_EC_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_EC_LIB);
goto end;
}
@@ -209,13 +209,13 @@ static ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgstlen,
}
#endif
if (!BN_bin2bn(dgst, dgstlen, e)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_BN_LIB);
goto end;
}
#if 0
if ((8 * dgstlen > i) && !BN_rshift(e, e, 8 - (i & 0x7))) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_BN_LIB);
goto end;
}
#endif
@@ -224,33 +224,33 @@ static ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgstlen,
/* use or compute k and (kG).x */
if (!in_k || !in_x) {
if (!sm2_sign_setup(ec_key, ctx, &k, &ret->r)) {
ECerr(EC_F_SM2_DO_SIGN,ERR_R_ECDSA_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_ECDSA_LIB);
goto end;
}
ck = k;
} else {
ck = in_k;
if (!BN_copy(ret->r, in_x)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_MALLOC_FAILURE);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto end;
}
}
/* r = e + x (mod n) */
if (!BN_mod_add(ret->r, ret->r, e, order, ctx)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_add(bn, ret->r, ck, order, ctx)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_BN_LIB);
goto end;
}
/* check r != 0 && r + k != n */
if (BN_is_zero(ret->r) || BN_is_zero(bn)) {
if (in_k && in_x) {
ECerr(EC_F_SM2_DO_SIGN, EC_R_NEED_NEW_SETUP_VALUES);
SM2err(SM2_F_SM2_DO_SIGN, SM2_R_NEED_NEW_SETUP_VALUES);
goto end;
} else
continue;
@@ -258,36 +258,36 @@ static ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgstlen,
/* s = ((1 + d)^-1 * (k - rd)) mod n */
if (!BN_one(bn)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_add(ret->s, priv_key, bn, order, ctx)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_inverse(ret->s, ret->s, order, ctx)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_mul(bn, ret->r, priv_key, order, ctx)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_sub(bn, ck, bn, order, ctx)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_BN_LIB);
goto end;
}
if (!BN_mod_mul(ret->s, ret->s, bn, order, ctx)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_BN_LIB);
goto end;
}
/* check s != 0 */
if (BN_is_zero(ret->s)) {
if (in_k && in_x) {
ECerr(EC_F_SM2_DO_SIGN, EC_R_NEED_NEW_SETUP_VALUES);
SM2err(SM2_F_SM2_DO_SIGN, SM2_R_NEED_NEW_SETUP_VALUES);
goto end;
}
} else {
@@ -298,13 +298,13 @@ static ECDSA_SIG *sm2_do_sign(const unsigned char *dgst, int dgstlen,
#if 0
if (!BN_rshift1(bn, order)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_BN_LIB);
goto end;
}
if (BN_cmp(ret->r, bn) <= 0) {
if (!BN_sub(ret->r, order, ret->r)
|| !BN_sub(ret->s, order, ret->s)) {
ECerr(EC_F_SM2_DO_SIGN, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_SIGN, ERR_R_BN_LIB);
goto end;
}
}
@@ -344,7 +344,7 @@ int sm2_do_verify(const unsigned char *dgst, int dgstlen,
!(ec_group = EC_KEY_get0_group(ec_key)) ||
!(pub_key = EC_KEY_get0_public_key(ec_key))) {
ECerr(EC_F_SM2_DO_VERIFY, EC_R_MISSING_PARAMETERS);
SM2err(SM2_F_SM2_DO_VERIFY, SM2_R_MISSING_PARAMETERS);
return -1;
}
@@ -353,21 +353,21 @@ int sm2_do_verify(const unsigned char *dgst, int dgstlen,
e = BN_new();
t = BN_new();
if (!ctx || !order || !e || !t) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_MALLOC_FAILURE);
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_MALLOC_FAILURE);
goto end;
}
if (!EC_GROUP_get_order(ec_group, order, ctx)) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_EC_LIB);
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_EC_LIB);
goto end;
}
#if 0
if (!BN_rshift1(t, order)) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_BN_LIB);
goto end;
}
if (BN_cmp(sig->r, t) <= 0) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_BN_LIB); //FIXME: error code
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_BN_LIB); //FIXME: error code
goto end;
}
#endif
@@ -380,14 +380,14 @@ int sm2_do_verify(const unsigned char *dgst, int dgstlen,
BN_is_negative(sig->s) ||
BN_ucmp(sig->s, order) >= 0) {
ECerr(EC_F_SM2_DO_VERIFY, EC_R_BAD_SIGNATURE);
SM2err(SM2_F_SM2_DO_VERIFY, SM2_R_BAD_SIGNATURE);
ret = 0;
goto end;
}
/* check t = r + s != 0 */
if (!BN_mod_add(t, sig->r, sig->s, order, ctx)) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_BN_LIB);
goto end;
}
if (BN_is_zero(t)) {
@@ -403,44 +403,44 @@ int sm2_do_verify(const unsigned char *dgst, int dgstlen,
}
#endif
if (!BN_bin2bn(dgst, dgstlen, e)) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_BN_LIB);
goto end;
}
#if 0
if ((8 * dgstlen > i) && !BN_rshift(e, e, 8 - (i & 0x7))) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_BN_LIB);
goto end;
}
#endif
/* compute (x, y) = sG + tP, P is pub_key */
if (!(point = EC_POINT_new(ec_group))) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_MALLOC_FAILURE);
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_MALLOC_FAILURE);
goto end;
}
if (!EC_POINT_mul(ec_group, point, sig->s, pub_key, t, ctx)) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_EC_LIB);
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_EC_LIB);
goto end;
}
if (EC_METHOD_get_field_type(EC_GROUP_method_of(ec_group)) == NID_X9_62_prime_field) {
if (!EC_POINT_get_affine_coordinates_GFp(ec_group, point, t, NULL, ctx)) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_EC_LIB);
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_EC_LIB);
goto end;
}
} else /* NID_X9_62_characteristic_two_field */ {
if (!EC_POINT_get_affine_coordinates_GF2m(ec_group, point, t, NULL, ctx)) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_EC_LIB);
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_EC_LIB);
goto end;
}
}
if (!BN_nnmod(t, t, order, ctx)) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_BN_LIB);
goto end;
}
/* check (sG + tP).x + e == sig.r */
if (!BN_mod_add(t, t, e, order, ctx)) {
ECerr(EC_F_SM2_DO_VERIFY, ERR_R_BN_LIB);
SM2err(SM2_F_SM2_DO_VERIFY, ERR_R_BN_LIB);
goto end;
}
if (BN_ucmp(t, sig->r) == 0) {