This commit is contained in:
Zhi Guan
2015-10-11 11:56:45 +08:00
parent b4ad0da508
commit 3f21c9d3d0
33 changed files with 739 additions and 402 deletions

View File

@@ -1223,6 +1223,14 @@ void ERR_load_EC_strings(void);
# define EC_F_PKEY_EC_PARAMGEN 219
# define EC_F_PKEY_EC_SIGN 218
#ifndef OPENSSL_NO_GMSSL
#define EC_F_PKEY_EC_ENCRYPT 300
#define EC_F_PKEY_EC_DECRYPT 301
#define EC_F_PKEY_SM2_SIGN 302
#define EC_F_PKEY_SM2_ENCRYPT 303
#define EC_F_PKEY_SM2_DECRYPT 304
#endif
/* Reason codes. */
# define EC_R_ASN1_ERROR 115
# define EC_R_ASN1_UNKNOWN_FIELD 116

View File

@@ -254,6 +254,11 @@ static ERR_STRING_DATA EC_str_functs[] = {
{ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "PKEY_EC_KEYGEN"},
{ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "PKEY_EC_PARAMGEN"},
{ERR_FUNC(EC_F_PKEY_EC_SIGN), "PKEY_EC_SIGN"},
{ERR_FUNC(EC_F_PKEY_EC_ENCRYPT), "PKEY_EC_ENCRYPT"},
{ERR_FUNC(EC_F_PKEY_EC_DECRYPT), "PKEY_EC_DECRYPT"},
{ERR_FUNC(EC_F_PKEY_SM2_SIGN), "PKEY_SM2_SIGN"},
{ERR_FUNC(EC_F_PKEY_SM2_ENCRYPT), "PKEY_SM2_ENCRYPT"},
{ERR_FUNC(EC_F_PKEY_SM2_DECRYPT), "PKEY_SM2_DECRYPT"},
{0, NULL}
};

View File

@@ -65,6 +65,7 @@
#include <openssl/ecdsa.h>
#include <openssl/evp.h>
#include "evp_locl.h"
#include <openssl/sm2.h>
/* EC pkey context structure */
@@ -278,6 +279,14 @@ static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx,
}
#endif
#ifndef OPENSSL_NO_ECIES
static int pkey_ec_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen);
static int pkey_ec_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen);
#endif
static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
{
EC_PKEY_CTX *dctx = ctx->data;
@@ -514,9 +523,19 @@ const EVP_PKEY_METHOD ec_pkey_meth = {
0, 0, 0, 0,
0, 0,
0,
#ifndef OPENSSL_NO_ECIES
pkey_ec_encrypt,
#else
0,
#endif
0, 0,
0,
#ifndef OPENSSL_NO_ECIES
pkey_ec_decrypt,
#else
0,
#endif
0,
#ifndef OPENSSL_NO_ECDH
@@ -528,3 +547,140 @@ const EVP_PKEY_METHOD ec_pkey_meth = {
pkey_ec_ctrl,
pkey_ec_ctrl_str
};
#ifndef OPENSSL_NO_ECIES
static int pkey_ec_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen)
{
return 0;
}
static int pkey_ec_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen)
{
return 0;
}
#endif
#ifndef OPENSSL_NO_SM2
static int pkey_sm2_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
const unsigned char *tbs, size_t tbslen)
{
int ret, type;
unsigned int sltmp;
EC_PKEY_CTX *dctx = ctx->data;
EC_KEY *ec = ctx->pkey->pkey.ec;
if (!sig) {
*siglen = ECDSA_size(ec);
return 1;
} else if (*siglen < (size_t)ECDSA_size(ec)) {
ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL);
return 0;
}
if (dctx->md)
type = EVP_MD_type(dctx->md);
else
type = NID_sha1;
ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec);
if (ret <= 0)
return ret;
*siglen = (size_t)sltmp;
return 1;
}
static int pkey_sm2_verify(EVP_PKEY_CTX *ctx,
const unsigned char *sig, size_t siglen,
const unsigned char *tbs, size_t tbslen)
{
int ret, type;
EC_PKEY_CTX *dctx = ctx->data;
EC_KEY *ec = ctx->pkey->pkey.ec;
if (dctx->md)
type = EVP_MD_type(dctx->md);
else
type = NID_sha1;
ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
return ret;
}
static int pkey_sm2_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen)
{
int ret = 0;
EC_PKEY_CTX *ec_ctx = ctx->data;
EC_KEY *ec_key = ctx->pkey->pkey.ec;
const EVP_MD *kdf_md = ec_ctx->kdf_md;
const EVP_MD *mac_md = ec_ctx->md;
point_conversion_form_t point_form = SM2_DEFAULT_POINT_CONVERSION_FORM;
if (!(ret = SM2_encrypt(kdf_md, mac_md, point_form, out, outlen, in, inlen, ec_key))) {
return 0;
}
return ret;
}
static int pkey_sm2_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen)
{
int ret = 0;
EC_PKEY_CTX *ec_ctx = ctx->data;
EC_KEY *ec_key = ctx->pkey->pkey.ec;
const EVP_MD *kdf_md = ec_ctx->kdf_md;
const EVP_MD *mac_md = ec_ctx->md;
point_conversion_form_t point_form = SM2_DEFAULT_POINT_CONVERSION_FORM;
if (!(ret = SM2_decrypt(kdf_md, mac_md, point_form, in, inlen, out, outlen, ec_key))) {
return 0;
}
return ret;
}
const EVP_PKEY_METHOD sm2_pkey_meth = {
EVP_PKEY_EC,
0,
pkey_ec_init,
pkey_ec_copy,
pkey_ec_cleanup,
0,
pkey_ec_paramgen,
0,
pkey_ec_keygen,
0,
pkey_sm2_sign,
0,
pkey_sm2_verify,
0, 0,
0, 0, 0, 0,
0,
pkey_sm2_encrypt,
0,
pkey_sm2_decrypt,
0,
#ifndef OPENSSL_NO_ECDH
pkey_ec_kdf_derive,
#else
0,
#endif
pkey_ec_ctrl,
pkey_ec_ctrl_str
};
#endif

View File

@@ -76,6 +76,7 @@ STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL;
extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth;
extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth;
extern const EVP_PKEY_METHOD dhx_pkey_meth;
extern const EVP_PKEY_METHOD sm2_pkey_meth;
static const EVP_PKEY_METHOD *standard_methods[] = {
#ifndef OPENSSL_NO_RSA
@@ -89,6 +90,7 @@ static const EVP_PKEY_METHOD *standard_methods[] = {
#endif
#ifndef OPENSSL_NO_EC
&ec_pkey_meth,
&sm2_pkey_meth,
#endif
&hmac_pkey_meth,
&cmac_pkey_meth,

View File

@@ -63,11 +63,11 @@
*/
#define NUM_NID 1001
#define NUM_SN 986
#define NUM_LN 986
#define NUM_OBJ 925
#define NUM_SN 985
#define NUM_LN 985
#define NUM_OBJ 924
static const unsigned char lvalues[6491]={
static const unsigned char lvalues[6482]={
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 */
@@ -952,41 +952,40 @@ static const unsigned char lvalues[6491]={
0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x01,/* [6221] OBJ_jurisdictionLocalityName */
0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x02,/* [6232] OBJ_jurisdictionStateOrProvinceName */
0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,/* [6243] OBJ_jurisdictionCountryName */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x04,/* [6254] OBJ_sm2p256v1 */
0x2A,0x81,0x1C, /* [6263] OBJ_ISO_CN */
0x2A,0x81,0x1C,0xCF,0x55, /* [6266] OBJ_oscca */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x11, /* [6271] OBJ_sm3 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x11,0x02,/* [6279] OBJ_hmac_sm3 */
0x2A,0x81,0x1C,0xCF,0x55,0x01, /* [6288] OBJ_sm */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D, /* [6294] OBJ_sm2 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x01,/* [6302] OBJ_sm2sign */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x02,/* [6311] OBJ_sm2keyagreement */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,/* [6320] OBJ_sm2encrypt */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [6329] OBJ_sm2sign_with_sm3 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x76, /* [6337] OBJ_sm2sign_with_sha1 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x77, /* [6345] OBJ_sm2sign_with_sha256 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x01, /* [6353] OBJ_sms4_ecb */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x02, /* [6361] OBJ_sms4_cbc */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x04, /* [6369] OBJ_sms4_ofb128 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x03, /* [6377] OBJ_sms4_cfb128 */
0x2B,0x81,0x04,0x01,0x07, /* [6385] OBJ_ecies_recommendedParameters */
0x2B,0x81,0x04,0x01,0x08, /* [6390] OBJ_ecies_specifiedParameters */
0x2B,0x81,0x04,0x01,0x11,0x00, /* [6395] OBJ_x9_63_kdf */
0x2B,0x81,0x04,0x01,0x11,0x01, /* [6401] OBJ_nist_concatenation_kdf */
0x2B,0x81,0x04,0x01,0x11,0x02, /* [6407] OBJ_tls_kdf */
0x2B,0x81,0x04,0x01,0x11,0x03, /* [6413] OBJ_ikev2_kdf */
0x2B,0x81,0x04,0x01,0x12, /* [6419] OBJ_xor_in_ecies */
0x2B,0x81,0x04,0x01,0x14,0x00, /* [6424] OBJ_aes128_cbc_in_ecies */
0x2B,0x81,0x04,0x01,0x14,0x01, /* [6430] OBJ_aes192_cbc_in_ecies */
0x2B,0x81,0x04,0x01,0x14,0x02, /* [6436] OBJ_aes256_cbc_in_ecies */
0x2B,0x81,0x04,0x01,0x15,0x00, /* [6442] OBJ_aes128_ctr_in_ecies */
0x2B,0x81,0x04,0x01,0x15,0x01, /* [6448] OBJ_aes192_ctr_in_ecies */
0x2B,0x81,0x04,0x01,0x15,0x02, /* [6454] OBJ_aes256_ctr_in_ecies */
0x2B,0x81,0x04,0x01,0x16, /* [6460] OBJ_hmac_full_ecies */
0x2B,0x81,0x04,0x01,0x17, /* [6465] OBJ_hmac_half_ecies */
0x2B,0x81,0x04,0x01,0x18,0x00, /* [6470] OBJ_cmac_aes128_ecies */
0x2B,0x81,0x04,0x01,0x18,0x01, /* [6476] OBJ_cmac_aes192_ecies */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x81,0x48, /* [6482] OBJ_zuc */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D, /* [6254] OBJ_sm2p256v1 */
0x2A,0x81,0x1C, /* [6262] OBJ_ISO_CN */
0x2A,0x81,0x1C,0xCF,0x55, /* [6265] OBJ_oscca */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x11, /* [6270] OBJ_sm3 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x11,0x02,/* [6278] OBJ_hmac_sm3 */
0x2A,0x81,0x1C,0xCF,0x55,0x01, /* [6287] OBJ_sm */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x01,/* [6293] OBJ_sm2sign */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x02,/* [6302] OBJ_sm2keyagreement */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x03,/* [6311] OBJ_sm2encrypt */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [6320] OBJ_sm2sign_with_sm3 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x76, /* [6328] OBJ_sm2sign_with_sha1 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x77, /* [6336] OBJ_sm2sign_with_sha256 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x01, /* [6344] OBJ_sms4_ecb */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x02, /* [6352] OBJ_sms4_cbc */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x04, /* [6360] OBJ_sms4_ofb128 */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x03, /* [6368] OBJ_sms4_cfb128 */
0x2B,0x81,0x04,0x01,0x07, /* [6376] OBJ_ecies_recommendedParameters */
0x2B,0x81,0x04,0x01,0x08, /* [6381] OBJ_ecies_specifiedParameters */
0x2B,0x81,0x04,0x01,0x11,0x00, /* [6386] OBJ_x9_63_kdf */
0x2B,0x81,0x04,0x01,0x11,0x01, /* [6392] OBJ_nist_concatenation_kdf */
0x2B,0x81,0x04,0x01,0x11,0x02, /* [6398] OBJ_tls_kdf */
0x2B,0x81,0x04,0x01,0x11,0x03, /* [6404] OBJ_ikev2_kdf */
0x2B,0x81,0x04,0x01,0x12, /* [6410] OBJ_xor_in_ecies */
0x2B,0x81,0x04,0x01,0x14,0x00, /* [6415] OBJ_aes128_cbc_in_ecies */
0x2B,0x81,0x04,0x01,0x14,0x01, /* [6421] OBJ_aes192_cbc_in_ecies */
0x2B,0x81,0x04,0x01,0x14,0x02, /* [6427] OBJ_aes256_cbc_in_ecies */
0x2B,0x81,0x04,0x01,0x15,0x00, /* [6433] OBJ_aes128_ctr_in_ecies */
0x2B,0x81,0x04,0x01,0x15,0x01, /* [6439] OBJ_aes192_ctr_in_ecies */
0x2B,0x81,0x04,0x01,0x15,0x02, /* [6445] OBJ_aes256_ctr_in_ecies */
0x2B,0x81,0x04,0x01,0x16, /* [6451] OBJ_hmac_full_ecies */
0x2B,0x81,0x04,0x01,0x17, /* [6456] OBJ_hmac_half_ecies */
0x2B,0x81,0x04,0x01,0x18,0x00, /* [6461] OBJ_cmac_aes128_ecies */
0x2B,0x81,0x04,0x01,0x18,0x01, /* [6467] OBJ_cmac_aes192_ecies */
0x2A,0x81,0x1C,0xCF,0x55,0x01,0x81,0x48, /* [6473] OBJ_zuc */
};
static const ASN1_OBJECT nid_objs[NUM_NID]={
@@ -2549,66 +2548,66 @@ static const ASN1_OBJECT nid_objs[NUM_NID]={
NID_jurisdictionStateOrProvinceName,11,&(lvalues[6232]),0},
{"jurisdictionC","jurisdictionCountryName",
NID_jurisdictionCountryName,11,&(lvalues[6243]),0},
{"sm2p256v1","sm2p256v1",NID_sm2p256v1,9,&(lvalues[6254]),0},
{"sm2p256v1","sm2p256v1",NID_sm2p256v1,8,&(lvalues[6254]),0},
{NULL,NULL,NID_undef,0,NULL,0},
{"ISO-CN","ISO CN Member Body",NID_ISO_CN,3,&(lvalues[6263]),0},
{"oscca","oscca",NID_oscca,5,&(lvalues[6266]),0},
{"SM3","sm3",NID_sm3,8,&(lvalues[6271]),0},
{"HMAC-SM3","hmac-sm3",NID_hmac_sm3,9,&(lvalues[6279]),0},
{"ISO-CN","ISO CN Member Body",NID_ISO_CN,3,&(lvalues[6262]),0},
{"oscca","oscca",NID_oscca,5,&(lvalues[6265]),0},
{"SM3","sm3",NID_sm3,8,&(lvalues[6270]),0},
{"HMAC-SM3","hmac-sm3",NID_hmac_sm3,9,&(lvalues[6278]),0},
{NULL,NULL,NID_undef,0,NULL,0},
{NULL,NULL,NID_undef,0,NULL,0},
{NULL,NULL,NID_undef,0,NULL,0},
{NULL,NULL,NID_undef,0,NULL,0},
{"sm","sm",NID_sm,6,&(lvalues[6288]),0},
{"sm2","sm2",NID_sm2,8,&(lvalues[6294]),0},
{"sm2sign","sm2sign",NID_sm2sign,9,&(lvalues[6302]),0},
{"sm","sm",NID_sm,6,&(lvalues[6287]),0},
{NULL,NULL,NID_undef,0,NULL,0},
{"sm2sign","sm2sign",NID_sm2sign,9,&(lvalues[6293]),0},
{"sm2keyagreement","sm2keyagreement",NID_sm2keyagreement,9,
&(lvalues[6311]),0},
{"sm2encrypt","sm2encrypt",NID_sm2encrypt,9,&(lvalues[6320]),0},
&(lvalues[6302]),0},
{"sm2encrypt","sm2encrypt",NID_sm2encrypt,9,&(lvalues[6311]),0},
{"SM2Sign-with-SM3","sm2sign-with-sm3",NID_sm2sign_with_sm3,8,
&(lvalues[6329]),0},
&(lvalues[6320]),0},
{"SM2Sign-with-SHA1","sm2sign-with-sha1",NID_sm2sign_with_sha1,8,
&(lvalues[6337]),0},
&(lvalues[6328]),0},
{"SM2Sign-with-SHA256","sm2sign-with-sha256",NID_sm2sign_with_sha256,
8,&(lvalues[6345]),0},
8,&(lvalues[6336]),0},
{NULL,NULL,NID_undef,0,NULL,0},
{"SMS4-ECB","sms4-ecb",NID_sms4_ecb,8,&(lvalues[6353]),0},
{"SMS4-CBC","sms4-cbc",NID_sms4_cbc,8,&(lvalues[6361]),0},
{"SMS4-ECB","sms4-ecb",NID_sms4_ecb,8,&(lvalues[6344]),0},
{"SMS4-CBC","sms4-cbc",NID_sms4_cbc,8,&(lvalues[6352]),0},
{NULL,NULL,NID_undef,0,NULL,0},
{NULL,NULL,NID_undef,0,NULL,0},
{"SMS4-OFB","sms4-ofb",NID_sms4_ofb128,8,&(lvalues[6369]),0},
{"SMS4-CFB","sms4-cfb",NID_sms4_cfb128,8,&(lvalues[6377]),0},
{"SMS4-OFB","sms4-ofb",NID_sms4_ofb128,8,&(lvalues[6360]),0},
{"SMS4-CFB","sms4-cfb",NID_sms4_cfb128,8,&(lvalues[6368]),0},
{"ecies-recommendedParameters","ecies-recommendedParameters",
NID_ecies_recommendedParameters,5,&(lvalues[6385]),0},
NID_ecies_recommendedParameters,5,&(lvalues[6376]),0},
{"ecies-specifiedParameters","ecies-specifiedParameters",
NID_ecies_specifiedParameters,5,&(lvalues[6390]),0},
{"x9-63-kdf","x9-63-kdf",NID_x9_63_kdf,6,&(lvalues[6395]),0},
NID_ecies_specifiedParameters,5,&(lvalues[6381]),0},
{"x9-63-kdf","x9-63-kdf",NID_x9_63_kdf,6,&(lvalues[6386]),0},
{"nist-concatenation-kdf","nist-concatenation-kdf",
NID_nist_concatenation_kdf,6,&(lvalues[6401]),0},
{"tls-kdf","tls-kdf",NID_tls_kdf,6,&(lvalues[6407]),0},
{"ikev2-kdf","ikev2-kdf",NID_ikev2_kdf,6,&(lvalues[6413]),0},
{"xor-in-ecies","xor-in-ecies",NID_xor_in_ecies,5,&(lvalues[6419]),0},
NID_nist_concatenation_kdf,6,&(lvalues[6392]),0},
{"tls-kdf","tls-kdf",NID_tls_kdf,6,&(lvalues[6398]),0},
{"ikev2-kdf","ikev2-kdf",NID_ikev2_kdf,6,&(lvalues[6404]),0},
{"xor-in-ecies","xor-in-ecies",NID_xor_in_ecies,5,&(lvalues[6410]),0},
{"aes128-cbc-in-ecies","aes128-cbc-in-ecies",NID_aes128_cbc_in_ecies,
6,&(lvalues[6424]),0},
6,&(lvalues[6415]),0},
{"aes192-cbc-in-ecies","aes192-cbc-in-ecies",NID_aes192_cbc_in_ecies,
6,&(lvalues[6430]),0},
6,&(lvalues[6421]),0},
{"aes256-cbc-in-ecies","aes256-cbc-in-ecies",NID_aes256_cbc_in_ecies,
6,&(lvalues[6436]),0},
6,&(lvalues[6427]),0},
{"aes128-ctr-in-ecies","aes128-ctr-in-ecies",NID_aes128_ctr_in_ecies,
6,&(lvalues[6442]),0},
6,&(lvalues[6433]),0},
{"aes192-ctr-in-ecies","aes192-ctr-in-ecies",NID_aes192_ctr_in_ecies,
6,&(lvalues[6448]),0},
6,&(lvalues[6439]),0},
{"aes256-ctr-in-ecies","aes256-ctr-in-ecies",NID_aes256_ctr_in_ecies,
6,&(lvalues[6454]),0},
6,&(lvalues[6445]),0},
{"hmac-full-ecies","hmac-full-ecies",NID_hmac_full_ecies,5,
&(lvalues[6460]),0},
&(lvalues[6451]),0},
{"hmac-half-ecies","hmac-half-ecies",NID_hmac_half_ecies,5,
&(lvalues[6465]),0},
&(lvalues[6456]),0},
{"cmac-aes128-ecies","cmac-aes128-ecies",NID_cmac_aes128_ecies,6,
&(lvalues[6470]),0},
&(lvalues[6461]),0},
{"cmac-aes192-ecies","cmac-aes192-ecies",NID_cmac_aes192_ecies,6,
&(lvalues[6476]),0},
{"ZUC","zuc",NID_zuc,8,&(lvalues[6482]),0},
&(lvalues[6467]),0},
{"ZUC","zuc",NID_zuc,8,&(lvalues[6473]),0},
};
static const unsigned int sn_objs[NUM_SN]={
@@ -3544,7 +3543,6 @@ static const unsigned int sn_objs[NUM_SN]={
454, /* "simpleSecurityObject" */
496, /* "singleLevelQuality" */
968, /* "sm" */
969, /* "sm2" */
972, /* "sm2encrypt" */
971, /* "sm2keyagreement" */
958, /* "sm2p256v1" */
@@ -4527,7 +4525,6 @@ static const unsigned int ln_objs[NUM_LN]={
454, /* "simpleSecurityObject" */
496, /* "singleLevelQuality" */
968, /* "sm" */
969, /* "sm2" */
972, /* "sm2encrypt" */
971, /* "sm2keyagreement" */
958, /* "sm2p256v1" */
@@ -5026,7 +5023,7 @@ static const unsigned int obj_objs[NUM_OBJ]={
982, /* OBJ_sms4_cfb128 1 2 156 10197 1 104 3 */
981, /* OBJ_sms4_ofb128 1 2 156 10197 1 104 4 */
1000, /* OBJ_zuc 1 2 156 10197 1 200 */
969, /* OBJ_sm2 1 2 156 10197 1 301 */
958, /* OBJ_sm2p256v1 1 2 156 10197 1 301 */
962, /* OBJ_sm3 1 2 156 10197 1 401 */
973, /* OBJ_sm2sign_with_sm3 1 2 156 10197 1 501 */
974, /* OBJ_sm2sign_with_sha1 1 2 156 10197 1 502 */
@@ -5211,7 +5208,6 @@ static const unsigned int obj_objs[NUM_OBJ]={
970, /* OBJ_sm2sign 1 2 156 10197 1 301 1 */
971, /* OBJ_sm2keyagreement 1 2 156 10197 1 301 2 */
972, /* OBJ_sm2encrypt 1 2 156 10197 1 301 3 */
958, /* OBJ_sm2p256v1 1 2 156 10197 1 301 4 */
963, /* OBJ_hmac_sm3 1 2 156 10197 1 401 2 */
108, /* OBJ_cast5_cbc 1 2 840 113533 7 66 10 */
112, /* OBJ_pbeWithMD5AndCast5_CBC 1 2 840 113533 7 66 12 */

View File

@@ -4276,25 +4276,21 @@
#define NID_sm 968
#define OBJ_sm OBJ_oscca,1L
#define SN_sm2 "sm2"
#define NID_sm2 969
#define OBJ_sm2 OBJ_sm,301L
#define SN_sm2p256v1 "sm2p256v1"
#define NID_sm2p256v1 958
#define OBJ_sm2p256v1 OBJ_sm,301L
#define SN_sm2sign "sm2sign"
#define NID_sm2sign 970
#define OBJ_sm2sign OBJ_sm2,1L
#define OBJ_sm2sign OBJ_sm,301L,1L
#define SN_sm2keyagreement "sm2keyagreement"
#define NID_sm2keyagreement 971
#define OBJ_sm2keyagreement OBJ_sm2,2L
#define OBJ_sm2keyagreement OBJ_sm,301L,2L
#define SN_sm2encrypt "sm2encrypt"
#define NID_sm2encrypt 972
#define OBJ_sm2encrypt OBJ_sm2,3L
#define SN_sm2p256v1 "sm2p256v1"
#define NID_sm2p256v1 958
#define OBJ_sm2p256v1 OBJ_sm2,4L
#define OBJ_sm2encrypt OBJ_sm,301L,3L
#define SN_sm3 "SM3"
#define LN_sm3 "sm3"

View File

@@ -1376,11 +1376,10 @@ secg-scheme 24 1 : cmac-aes192-ecies
member-body 156 : ISO-CN : ISO CN Member Body
ISO-CN 10197 : oscca
oscca 1 : sm
sm 301 : sm2
sm2 1 : sm2sign
sm2 2 : sm2keyagreement
sm2 3 : sm2encrypt
sm2 4 : sm2p256v1
sm 301 : sm2p256v1
sm 301 1 : sm2sign
sm 301 2 : sm2keyagreement
sm 301 3 : sm2encrypt
sm 401 : SM3 : sm3
sm 401 2 : HMAC-SM3 : hmac-sm3
sm 501 : SM2Sign-with-SM3 : sm2sign-with-sm3

View File

@@ -1,5 +1,5 @@
#
# crypto/ecies/Makefile
# crypto/sm2/Makefile
#
DIR= sm2
@@ -23,7 +23,7 @@ LIBOBJ= sm2_dgst.o sm2_enc.o
SRC= $(LIBSRC)
EXHEADER= sm2_enc.h
EXHEADER= sm2.h
HEADER= $(EXHEADER)
ALL= $(GENERAL) $(SRC) $(HEADER)

89
crypto/sm2/sm2.h Normal file
View File

@@ -0,0 +1,89 @@
#ifndef HEADER_SM2_H
#define HEADER_SM2_H
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/asn1.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SM2_DEFAULT_POINT_CONVERSION_FORM 0
typedef struct sm2_ciphertext_value_st {
EC_POINT *ephem_point;
unsigned char *ciphertext;
size_t ciphertext_size;
unsigned char mactag[EVP_MAX_MD_SIZE];
unsigned int mactag_size;
} SM2_CIPHERTEXT_VALUE;
int SM2_compute_za(unsigned char *za, const EVP_MD *md,
const void *id, size_t idlen, EC_KEY *ec_key);
int SM2_compute_digest(unsigned char *dgst, unsigned int *dgstlen,
const EVP_MD *za_md, const void *id, size_t idlen, EC_KEY *ec_key,
const EVP_MD *msg_md, const void *msg, size_t msglen);
int SM2_CIPHERTEXT_VALUE_size(const EC_GROUP *ec_group,
point_conversion_form_t point_form, size_t mlen,
const EVP_MD *mac_md);
void SM2_CIPHERTEXT_VALUE_free(SM2_CIPHERTEXT_VALUE *cv);
int SM2_CIPHERTEXT_VALUE_encode(const SM2_CIPHERTEXT_VALUE *cv,
const EC_GROUP *ec_group, point_conversion_form_t point_form,
unsigned char *buf, size_t *buflen);
SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_decode(const EC_GROUP *ec_group,
point_conversion_form_t point_form, const EVP_MD *mac_md,
const unsigned char *buf, size_t buflen);
int SM2_CIPHERTEXT_VALUE_print(BIO *out, const SM2_CIPHERTEXT_VALUE *cv,
int indent, unsigned long flags);
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
const unsigned char *in, size_t inlen, EC_KEY *ec_key);
int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
const SM2_CIPHERTEXT_VALUE *cv, unsigned char *out, size_t *outlen,
EC_KEY *ec_key);
int SM2_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
point_conversion_form_t point_form, unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen, EC_KEY *ec_key);
int SM2_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
point_conversion_form_t point_form, const unsigned char *in,
size_t inlen, unsigned char *out, size_t *outlen, EC_KEY *ec_key);
void ERR_load_SM2_strings(void);
/* Error codes for the ECIES functions. */
/* Function codes. */
#define SM2_F_SM2_DO_ENCRYPT 100
#define SM2_F_SM2_DO_DECRYPT 101
#define SM2_F_SM2_CIPHERTEXT_VALUE_FREE 102
/* Reason codes. */
#define SM2_R_BAD_DATA 100
#define SM2_R_UNKNOWN_CIPHER_TYPE 101
#define SM2_R_ENCRYPT_FAILED 102
#define SM2_R_DECRYPT_FAILED 103
#define SM2_R_UNKNOWN_MAC_TYPE 104
#define SM2_R_GEN_MAC_FAILED 105
#define SM2_R_VERIFY_MAC_FAILED 106
#define SM2_R_ECDH_FAILED 107
#define SM2_R_BUFFER_TOO_SMALL 108
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -5,25 +5,29 @@
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#define EC_MAX_NBYTES ((OPENSSL_ECC_MAX_FIELD_BITS + 7)/8)
#define SM2_MAX_ID_LENGTH 4096
/*
* pkdata = a || b || G.x || G.y || P.x || P.y
*/
static int sm2_get_public_key_data(unsigned char *buf, EC_KEY *ec_key)
{
int ret = -1;
int nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
const EC_POINT *point;
int nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
unsigned char oct[EC_MAX_NBYTES * 2 + 1];
BN_CTX *ctx = NULL;
BN_CTX *bn_ctx = NULL;
BIGNUM *p = NULL;
BIGNUM *x = NULL;
BIGNUM *y = NULL;
size_t len;
OPENSSL_assert(ec_key);
OPENSSL_assert(nbytes == 256/8);
@@ -33,16 +37,16 @@ static int sm2_get_public_key_data(unsigned char *buf, EC_KEY *ec_key)
}
bzero(buf, nbytes * 6);
ctx = BN_CTX_new();
bn_ctx = BN_CTX_new();
p = BN_new();
x = BN_new();
y = BN_new();
if (!ctx || !p || !x || !y) {
if (!bn_ctx || !p || !x || !y) {
goto err;
}
/* get curve coefficients a, b */
if (!EC_GROUP_get_curve_GFp(ec_group, p, x, y, ctx)) {
if (!EC_GROUP_get_curve_GFp(ec_group, p, x, y, bn_ctx)) {
goto err;
}
buf += nbytes;
@@ -80,7 +84,7 @@ static int sm2_get_public_key_data(unsigned char *buf, EC_KEY *ec_key)
ret = (nbytes * 6);
err:
if (ctx) BN_CTX_free(ctx);
if (bn_ctx) BN_CTX_free(bn_ctx);
if (p) BN_free(p);
if (x) BN_free(x);
if (y) BN_free(y);
@@ -88,42 +92,42 @@ err:
return ret;
}
int SM2_compute_za(unsigned char *za, const EVP_MD *md,
const void *id, size_t idlen, EC_KEY *ec_key)
int SM2_compute_za(unsigned char *za, unsigned int *zalen,
const EVP_MD *md, const void *id, size_t idlen, EC_KEY *ec_key)
{
int ret = 0;
EVP_MD_CTX *ctx = NULL;
EVP_MD_CTX *md_ctx = NULL;
unsigned char pkdata[EC_MAX_NBYTES * 6];
uint16_t idbits;
int len;
idbits = cpu_to_be16(idlen * 8);
uint16_t idbits = idlen * 8;
int pkdatalen;
if ((pkdatalen = sm2_get_public_key_data(pkdata, ec_key)) < 0) {
goto err;
}
if (!(ctx = EVP_MD_CTX_create())) {
if (!(md_ctx = EVP_MD_CTX_create())) {
goto err;
}
if (!EVP_DigestInit_ex(ctx, md, NULL)) {
goto end;
if (!EVP_DigestInit_ex(md_ctx, md, NULL)) {
goto err;
}
if (!EVP_DigestUpdate(ctx, &idbits, sizeof(idbits))) {
goto end;
if (!EVP_DigestUpdate(md_ctx, &idbits, sizeof(idbits))) {
goto err;
}
if (!EVP_DigestUpdate(ctx, id, idlen)) {
goto end;
if (!EVP_DigestUpdate(md_ctx, id, idlen)) {
goto err;
}
if (!EVP_DigestUpdate(ctx, pkdata, pkdatalen)) {
goto end;
if (!EVP_DigestUpdate(md_ctx, pkdata, pkdatalen)) {
goto err;
}
if (!EVP_DigestFinal(ctx, za, &zalen)) {
if (!EVP_DigestFinal(md_ctx, za, zalen)) {
goto err;
}
ret = SM3_DIGEST_LENGTH;
ret = 1;
err:
if (ctx) EVP_MD_CTX_destroy(ctx);
if (md_ctx) EVP_MD_CTX_destroy(md_ctx);
return ret;
}
@@ -133,14 +137,14 @@ int SM2_compute_digest(unsigned char *dgst, unsigned int *dgstlen,
{
int ret = 0;
unsigned char za[EVP_MAX_MD_SIZE];
int zalen;
unsigned int zalen;
EVP_MD_CTX *ctx = NULL;
/* compute Za */
if (idlen > SM2_MAX_ID_LENGTH) {
goto err;
}
if ((zalen = SM2_compute_za(za, za_md, id, idlen, ec_key)) < 0) {
if (!SM2_compute_za(za, &zalen, za_md, id, idlen, ec_key)) {
goto err;
}

View File

@@ -6,10 +6,36 @@
#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/rand.h>
#include <oepnssl/kdf.h>
#include "sm2_enc.h"
#include <openssl/kdf.h>
#include "sm2.h"
void SM2_CIPEHRTEXT_VALUE_free(SM2_CIPHERTEXT_VALUE *cv)
int SM2_CIPHERTEXT_VALUE_size(const EC_GROUP *ec_group,
point_conversion_form_t point_form, size_t mlen,
const EVP_MD *mac_md)
{
int ret = 0;
EC_POINT *point = EC_POINT_new(ec_group);
BN_CTX *bn_ctx = BN_CTX_new();
size_t len;
if (!point || !bn_ctx) {
goto end;
}
if (!(len = EC_POINT_point2oct(ec_group, point, point_form,
NULL, 0, bn_ctx))) {
goto end;
}
len += mlen + EVP_MD_size(mac_md);
ret = len;
end:
if (point) EC_POINT_free(point);
if (bn_ctx) BN_CTX_free(bn_ctx);
return ret;
}
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);
@@ -17,9 +43,141 @@ void SM2_CIPEHRTEXT_VALUE_free(SM2_CIPHERTEXT_VALUE *cv)
OPENSSL_free(cv);
}
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
const EVP_MD *kdf_md, const EVP_MD *mac_md,
const void *in, size_t inlen, const EC_KEY *ec_key);
int SM2_CIPHERTEXT_VALUE_encode(const SM2_CIPHERTEXT_VALUE *cv,
const EC_GROUP *ec_group, point_conversion_form_t point_form,
unsigned char *buf, size_t *buflen)
{
int ret = 0;
BN_CTX *bn_ctx = BN_CTX_new();
size_t ptlen, cvlen;
if (!bn_ctx) {
return 0;
}
if (!(ptlen = EC_POINT_point2oct(ec_group, cv->ephem_point,
point_form, NULL, 0, bn_ctx))) {
goto end;
}
cvlen = ptlen + cv->ciphertext_size + cv->mactag_size;
if (!buf) {
*buflen = cvlen;
ret = 1;
goto end;
} else if (*buflen < cvlen) {
goto end;
}
if (!(ptlen = EC_POINT_point2oct(ec_group, cv->ephem_point,
point_form, buf, *buflen, bn_ctx))) {
goto end;
}
buf += ptlen;
memcpy(buf, cv->ciphertext, cv->ciphertext_size);
buf += cv->ciphertext_size;
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,
point_conversion_form_t point_form, const EVP_MD *mac_md,
const unsigned char *buf, size_t buflen)
{
int ok = 0;
SM2_CIPHERTEXT_VALUE *ret = NULL;
BN_CTX *bn_ctx = NULL;
int len = SM2_CIPHERTEXT_VALUE_size(ec_group, point_form, 0, mac_md);
int ptlen = len - EVP_MD_size(mac_md);
if (!(len = SM2_CIPHERTEXT_VALUE_size(ec_group, point_form, 0, mac_md))) {
goto end;
}
if (buflen <= len) {
goto end;
}
if (!(ret = OPENSSL_malloc(sizeof(SM2_CIPHERTEXT_VALUE)))) {
goto end;
}
ret->ephem_point = EC_POINT_new(ec_group);
ret->ciphertext_size = buflen - len;
ret->ciphertext = OPENSSL_malloc(ret->ciphertext_size);
if (!ret->ephem_point || !ret->ciphertext) {
goto end;
}
if (!(bn_ctx = BN_CTX_new())) {
goto end;
}
if (!EC_POINT_oct2point(ec_group, ret->ephem_point, buf, len, bn_ctx)) {
goto end;
}
memcpy(ret->ciphertext, buf + ptlen, ret->ciphertext_size);
ret->mactag_size = EVP_MD_size(mac_md);
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 SM2_CIPHERTEXT_VALUE *cv,
int indent, unsigned long flags)
{
OPENSSL_assert(0);
return 0;
}
int SM2_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
point_conversion_form_t point_form, unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen, 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, point_form, inlen, mac_md))) {
goto end;
}
if (!out) {
*outlen = (size_t)len;
return 1;
} else if (*outlen < (size_t)len) {
return 0;
}
if (!(cv = SM2_do_encrypt(kdf_md, mac_md, in, inlen, ec_key))) {
goto end;
}
if (!SM2_CIPHERTEXT_VALUE_encode(cv, ec_group, point_form, out, outlen)) {
goto end;
}
ret = 1;
end:
if (cv) SM2_CIPHERTEXT_VALUE_free(cv);
return ret;
}
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
const unsigned char *in, size_t inlen, EC_KEY *ec_key)
{
int ok = 0;
SM2_CIPHERTEXT_VALUE *cv = NULL;
@@ -34,25 +192,26 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
EVP_MD_CTX *md_ctx = NULL;
unsigned char buf[(OPENSSL_ECC_MAX_FIELD_BITS + 7)/4 + 1];
int nbytes;
size_t len;
int i;
if (!ec_group || !pub_key) {
goto err;
goto end;
}
if (!kdf) {
goto err;
goto end;
}
/* init ciphertext_value */
if (!(cv = OPENSSL_malloc(sizeof(SM2_CIPHERTEXT_VALUE)))) {
goto err;
goto end;
}
bzero(cv, sizeof(SM2_CIPHERTEXT_VALUE));
cv->ephem_point = EC_POINT_new(ec_group);
cv->ciphertext = OPENSSL_malloc(inlen);
cv->ciphertext_size = inlen;
if (!cv->ephem_point || !cv->ciphertext) {
goto err;
goto end;
}
point = EC_POINT_new(ec_group);
@@ -62,17 +221,17 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
bn_ctx = BN_CTX_new();
md_ctx = EVP_MD_CTX_create();
if (!point || !n || !h || !k || !bn_ctx || !md_ctx) {
goto err;
goto end;
}
/* init ec domain parameters */
if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
goto err;
goto end;
}
if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
goto err;
goto end;
}
nbytes = (EC_GROPU_get_degree(ec_group) + 7) / 8;
nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
OPENSSL_assert(nbytes == BN_num_bytes(n));
/* check sm2 curve and md is 256 bits */
@@ -89,24 +248,24 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
/* A2: C1 = [k]G = (x1, y1) */
if (!EC_POINT_mul(ec_group, cv->ephem_point, k, NULL, NULL, bn_ctx)) {
goto err;
goto end;
}
/* A3: check [h]P_B != O */
if (!EC_POINT_mul(ec_group, point, NULL, pub_key, h, bn_ctx)) {
goto err;
goto end;
}
if (EC_POINT_is_at_infinity(ec_group, point)) {
goto err;
goto end;
}
/* A4: compute ECDH [k]P_B = (x2, y2) */
if (!EC_POINT_mul(ec_group, point, NULL, pub_key, k, bn_ctx)) {
goto err;
goto end;
}
if (!(len = EC_POINT_point2oct(ec_group, point,
POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
goto err;
goto end;
}
OPENSSL_assert(len == nbytes * 2 + 1);
@@ -134,24 +293,24 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
/* A7: C3 = Hash(x2 || M || y2) */
if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) {
goto err;
goto end;
}
if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
goto err;
goto end;
}
if (!EVP_DigestUpdate(md_ctx, in, inlen)) {
goto err;
goto end;
}
if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
goto err;
goto end;
}
if (!EVP_DigestFinal_ex(md_ctx, cv->mactag, &cv->mactag_size)) {
goto err;
goto end;
}
ok = 1;
err:
end:
if (!ok && cv) {
SM2_CIPHERTEXT_VALUE_free(cv);
cv = NULL;
@@ -166,12 +325,47 @@ err:
return cv;
}
int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
const EVP_MD *kdf_md, const EVP_MD *mac_md,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
int SM2_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
point_conversion_form_t point_form, const unsigned char *in,
size_t inlen, unsigned char *out, size_t *outlen, EC_KEY *ec_key)
{
int ret = 0
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, point_form, 0, mac_md))) {
goto end;
}
if (inlen <= len) {
goto end;
}
if (!out) {
*outlen = inlen - len;
return 1;
} else if (outlen < inlen - len) {
return 0;
}
if (!(cv = SM2_CIPHERTEXT_VALUE_decode(ec_group, point_form, mac_md, in, inlen))) {
goto end;
}
if (!SM2_do_decrypt(kdf_md, mac_md, cv, out, outlen, ec_key)) {
goto end;
}
ret = 1;
end:
if (cv) SM2_CIPHERTEXT_VALUE_free(cv);
return ret;
}
int SM2_do_decrypt(const EVP_MD *kdf_md, const EVP_MD *mac_md,
const SM2_CIPHERTEXT_VALUE *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(kdf_md);
@@ -182,14 +376,16 @@ int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
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 nbytes;
size_t size;
int i;
if (!ec_group || !pub_key) {
goto err;
if (!ec_group || !pri_key) {
goto end;
}
if (!kdf) {
goto err;
goto end;
}
if (!out) {
@@ -197,7 +393,7 @@ int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
return 1;
}
if (*outlen < cv->ciphertext_size) {
goto err;
goto end;
}
/* init vars */
@@ -207,17 +403,17 @@ int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
bn_ctx = BN_CTX_new();
md_ctx = EVP_MD_CTX_create();
if (!point || !n || !h || !bn_ctx || !md_ctx) {
goto err;
goto end;
}
/* init ec domain parameters */
if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
goto err;
goto end;
}
if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
goto err;
goto end;
}
nbytes = (EC_GROPU_get_degree(ec_group) + 7) / 8;
nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
OPENSSL_assert(nbytes == BN_num_bytes(n));
/* check sm2 curve and md is 256 bits */
@@ -227,23 +423,23 @@ int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
/* B2: check [h]C1 != O */
if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, h, bn_ctx)) {
goto err;
goto end;
}
if (EC_POINT_is_at_infinity(ec_group, point)) {
goto err;
goto end;
}
/* B3: compute ECDH [d]C1 = (x2, y2) */
if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, pri_key, bn_ctx)) {
goto err;
goto end;
}
if (!(len = EC_POINT_point2oct(ec_group, point,
if (!(size = EC_POINT_point2oct(ec_group, point,
POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
goto err;
goto end;
}
/* B4: compute t = KDF(x2 || y2, clen) */
kdf(buf - 1, len - 1, out, outlen);
kdf(buf - 1, size - 1, out, outlen);
/* B5: compute M = C2 xor t */
@@ -253,26 +449,27 @@ int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
/* B6: check Hash(x2 || M || y2) == C3 */
if (!EVP_DigestInit_ex(md_ctx, mac_md, NULL)) {
goto err;
goto end;
}
if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
goto err;
goto end;
}
if (!EVP_DigestUpdate(md_ctx, out, *outlen)) {
goto err;
goto end;
}
if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
goto err;
goto end;
}
if (!EVP_DigestFinal_ex(md_ctx, mac, &maclen)) {
goto err;
goto end;
}
if (cv->mactag_size != maclen || memcmp(cv->mactag, mac, maclen)) {
goto err;
if (cv->mactag_size != maclen ||
memcmp(cv->mactag, mac, maclen)) {
goto end;
}
ret = 1;
err:
end:
if (point) EC_POINT_free(point);
if (n) BN_free(n);
if (h) BN_free(h);

View File

@@ -1,59 +0,0 @@
#ifndef HEADER_SM2_ENC_H
#define HEADER_SM2_ENC_H
#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <openssl/asn1.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct sm2_ciphertext_value_st {
EC_POINT *ephem_point;
unsigned char *ciphertext;
size_t ciphertext_size;
unsigned char mactag[EVP_MAX_MD_SIZE];
size_t mactag_size;
} SM2_CIPHERTEXT_VALUE;
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(
const EVP_MD *kdf_md, const EVP_MD *mac_md,
const void *in, size_t inlen, const EC_KEY *pub_key);
int SM2_do_decrypt(const SM2_CIPHERTEXT_VALUE *cv,
const EVP_MD *kdf_md, const EVP_MD *mac_md,
unsigned char *out, size_t *outlen, EC_KEY *pri_key);
void SM2_CIPHERTEXT_VALUE_free(SM2_CIPHERTEXT_VALUE *cv);
void ERR_load_SM2_strings(void);
/* Error codes for the ECIES functions. */
/* Function codes. */
#define SM2_F_SM2_DO_ENCRYPT 100
#define SM2_F_SM2_DO_DECRYPT 101
#define SM2_F_SM2_CIPHERTEXT_VALUE_FREE 102
/* Reason codes. */
#define SM2_R_BAD_DATA 100
#define SM2_R_UNKNOWN_CIPHER_TYPE 101
#define SM2_R_ENCRYPT_FAILED 102
#define SM2_R_DECRYPT_FAILED 103
#define SM2_R_UNKNOWN_MAC_TYPE 104
#define SM2_R_GEN_MAC_FAILED 105
#define SM2_R_VERIFY_MAC_FAILED 106
#define SM2_R_ECDH_FAILED 107
#define SM2_R_BUFFER_TOO_SMALL 108
#ifdef __cplusplus
}
#endif
#endif

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

@@ -0,0 +1,41 @@
#include <stdio.h>
#include <openssl/err.h>
#include "sm2.h"
#ifndef OPENSSL_NO_ERR
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECIES,func,0)
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECIES,0,reason)
static ERR_STRING_DATA SM2_str_functs[] = {
{ERR_FUNC(ECIES_F_ECIES_DO_ENCRYPT), "ECIES_do_encrypt"},
{ERR_FUNC(ECIES_F_ECIES_DO_DECRYPT), "ECIES_do_decrypt"},
{0,NULL}
};
static ERR_STRING_DATA SM2_str_reasons[] = {
{ERR_REASON(ECIES_R_BAD_DATA), "bad data"},
{ERR_REASON(ECIES_R_UNKNOWN_CIPHER_TYPE),"unknown cipher type"},
{ERR_REASON(ECIES_R_ENCRYPT_FAILED), "encrypt failed"},
{ERR_REASON(ECIES_R_DECRYPT_FAILED), "decrypt failed"},
{ERR_REASON(ECIES_R_UNKNOWN_MAC_TYPE), "unknown MAC type"},
{ERR_REASON(ECIES_R_GEN_MAC_FAILED), "MAC generation failed"},
{ERR_REASON(ECIES_R_VERIFY_MAC_FAILED), "MAC verification failed"},
{ERR_REASON(ECIES_R_ECDH_FAILED), "ECDH failed"},
{ERR_REASON(ECIES_R_BUFFER_TOO_SMALL), "buffer too small"},
{0,NULL}
};
#endif
void ERR_load_ECIES_strings(void)
{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(ECIES_str_functs[0].error) == NULL) {
ERR_load_strings(0,ECIES_str_functs);
ERR_load_strings(0,ECIES_str_reasons);
}
#endif
}