more sm. tests

This commit is contained in:
Zhi Guan
2016-05-22 20:42:38 +02:00
parent 62b396d193
commit 0cf9126a7d
40 changed files with 2847 additions and 706 deletions

View File

@@ -115,26 +115,25 @@ SM2_CIPHERTEXT_VALUE *d2i_SM2_CIPHERTEXT_VALUE(SM2_CIPHERTEXT_VALUE **c,
int SM2_CIPHERTEXT_VALUE_print(BIO *out, const EC_GROUP *ec_group,
const SM2_CIPHERTEXT_VALUE *cv, int indent, unsigned long flags);
/* FIXME: we should provide optional return value */
SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const SM2_ENC_PARAMS *params,
const unsigned char *in, size_t inlen, EC_KEY *ec_key);
//FIXME: output first, and change ECIES
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_encrypt(const SM2_ENC_PARAMS *params,
const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
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 SM2_encrypt_with_recommended(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
int SM2_decrypt_with_recommended(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
int SM2_encrypt_elgamal(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
int SM2_decrypt_elgamal(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key);
int SM2_encrypt(const SM2_ENC_PARAMS *params, unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen, EC_KEY *ec_key);
int SM2_decrypt(const SM2_ENC_PARAMS *params, unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen, EC_KEY *ec_key);
int SM2_encrypt_with_recommended(unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen, EC_KEY *ec_key);
int SM2_decrypt_with_recommended(unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen, EC_KEY *ec_key);
int SM2_encrypt_elgamal(unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen, EC_KEY *ec_key);
int SM2_decrypt_elgamal(unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen, EC_KEY *ec_key);
int SM2_compute_message_digest(const EVP_MD *id_md, const EVP_MD *msg_md,
const void *msg, size_t msglen, unsigned char *dgst,
@@ -252,6 +251,7 @@ void ERR_load_SM2_strings(void);
#define SM2_R_BUFFER_TOO_SMALL 108
#define SM2_R_SM2_KAP_NOT_INITED 109
#define SM2_R_RANDOM_NUMBER_GENERATION_FAILED 110
#define SM2_R_ERROR 111
#ifdef __cplusplus
}

View File

@@ -68,15 +68,20 @@ int SM2_CIPHERTEXT_VALUE_size(const EC_GROUP *group,
EC_KEY *ec_key = NULL;
size_t len = 0;
if (!(ec_key = EC_KEY_new())) {
SM2err(SM2_F_SM2_CIPHERTEXT_VALUE_SIZE, SM2_R_ERROR);
goto end;
}
if (!EC_KEY_set_group(ec_key, group)) {
SM2err(SM2_F_SM2_CIPHERTEXT_VALUE_SIZE, SM2_R_ERROR);
goto end;
}
if (!EC_KEY_generate_key(ec_key)) {
SM2err(SM2_F_SM2_CIPHERTEXT_VALUE_SIZE, SM2_R_ERROR);
goto end;
}
len += EC_POINT_point2oct(group, EC_KEY_get0_public_key(ec_key),
params->point_form, NULL, 0, NULL);
len += mlen;
@@ -107,11 +112,13 @@ int SM2_CIPHERTEXT_VALUE_encode(const SM2_CIPHERTEXT_VALUE *cv,
size_t ptlen, cvlen;
if (!bn_ctx) {
SM2err(SM2_F_SM2_CIPHERTEXT_VALUE_ENCODE, SM2_R_ERROR);
return 0;
}
if (!(ptlen = EC_POINT_point2oct(ec_group, cv->ephem_point,
params->point_form, NULL, 0, bn_ctx))) {
SM2err(SM2_F_SM2_CIPHERTEXT_VALUE_ENCODE, SM2_R_ERROR);
goto end;
}
cvlen = ptlen + cv->ciphertext_size + cv->mactag_size;
@@ -122,11 +129,13 @@ int SM2_CIPHERTEXT_VALUE_encode(const SM2_CIPHERTEXT_VALUE *cv,
goto end;
} else if (*buflen < cvlen) {
SM2err(SM2_F_SM2_CIPHERTEXT_VALUE_ENCODE, SM2_R_ERROR);
goto end;
}
if (!(ptlen = EC_POINT_point2oct(ec_group, cv->ephem_point,
params->point_form, buf, *buflen, bn_ctx))) {
SM2err(SM2_F_SM2_CIPHERTEXT_VALUE_ENCODE, SM2_R_ERROR);
goto end;
}
buf += ptlen;
@@ -158,17 +167,17 @@ SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_decode(
}
if (!(fixlen = SM2_CIPHERTEXT_VALUE_size(ec_group, params, 0))) {
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
SM2err(SM2_F_SM2_CIPHERTEXT_VALUE_DECODE, SM2_R_ERROR);
goto end;
}
if (buflen <= fixlen) {
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
SM2err(SM2_F_SM2_CIPHERTEXT_VALUE_DECODE, SM2_R_ERROR);
goto end;
}
if (!(ret = OPENSSL_malloc(sizeof(SM2_CIPHERTEXT_VALUE)))) {
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
SM2err(SM2_F_SM2_CIPHERTEXT_VALUE_DECODE, SM2_R_ERROR);
goto end;
}
@@ -176,14 +185,13 @@ SM2_CIPHERTEXT_VALUE *SM2_CIPHERTEXT_VALUE_decode(
ret->ciphertext_size = buflen - fixlen;
ret->ciphertext = OPENSSL_malloc(ret->ciphertext_size);
if (!ret->ephem_point || !ret->ciphertext) {
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
SM2err(SM2_F_SM2_CIPHERTEXT_VALUE_DECODE, SM2_R_ERROR);
goto end;
}
ptlen = fixlen - SM2_ENC_PARAMS_mactag_size(params);
if (!EC_POINT_oct2point(ec_group, ret->ephem_point, buf, ptlen, bn_ctx)) {
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
ERR_print_errors_fp(stdout);
SM2err(SM2_F_SM2_CIPHERTEXT_VALUE_DECODE, SM2_R_ERROR);
goto end;
}
@@ -242,8 +250,9 @@ end:
}
int SM2_encrypt(const SM2_ENC_PARAMS *params,
unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
EC_KEY *ec_key)
{
int ret = 0;
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
@@ -251,6 +260,7 @@ int SM2_encrypt(const SM2_ENC_PARAMS *params,
int len;
if (!(len = SM2_CIPHERTEXT_VALUE_size(ec_group, params, inlen))) {
SM2err(SM2_F_SM2_ENCRYPT, SM2_R_ERROR);
goto end;
}
@@ -263,9 +273,11 @@ int SM2_encrypt(const SM2_ENC_PARAMS *params,
}
if (!(cv = SM2_do_encrypt(params, in, inlen, ec_key))) {
SM2err(SM2_F_SM2_ENCRYPT, SM2_R_ERROR);
goto end;
}
if (!SM2_CIPHERTEXT_VALUE_encode(cv, ec_group, params, out, outlen)) {
SM2err(SM2_F_SM2_ENCRYPT, SM2_R_ERROR);
goto end;
}
@@ -293,6 +305,7 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const SM2_ENC_PARAMS *params,
int nbytes;
unsigned char dgst[EVP_MAX_MD_SIZE];
unsigned int dgstlen;
int mactag_size;
size_t len;
int i;
@@ -305,6 +318,7 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const SM2_ENC_PARAMS *params,
/* init ciphertext_value */
if (!(cv = OPENSSL_malloc(sizeof(SM2_CIPHERTEXT_VALUE)))) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
bzero(cv, sizeof(SM2_CIPHERTEXT_VALUE));
@@ -312,6 +326,7 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const SM2_ENC_PARAMS *params,
cv->ciphertext = OPENSSL_malloc(inlen);
cv->ciphertext_size = inlen;
if (!cv->ephem_point || !cv->ciphertext) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
@@ -322,14 +337,17 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const SM2_ENC_PARAMS *params,
bn_ctx = BN_CTX_new();
md_ctx = EVP_MD_CTX_create();
if (!point || !n || !h || !k || !bn_ctx || !md_ctx) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
/* init ec domain parameters */
if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
nbytes = (EC_GROUP_get_degree(ec_group) + 7) / 8;
@@ -344,23 +362,28 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const SM2_ENC_PARAMS *params,
/* A2: C1 = [k]G = (x1, y1) */
if (!EC_POINT_mul(ec_group, cv->ephem_point, k, NULL, NULL, bn_ctx)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
/* A3: check [h]P_B != O */
if (!EC_POINT_mul(ec_group, point, NULL, pub_key, h, bn_ctx)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
if (EC_POINT_is_at_infinity(ec_group, point)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
/* A4: compute ECDH [k]P_B = (x2, y2) */
if (!EC_POINT_mul(ec_group, point, NULL, pub_key, k, bn_ctx)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
if (!(len = EC_POINT_point2oct(ec_group, point,
POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
OPENSSL_assert(len == nbytes * 2 + 1);
@@ -387,31 +410,38 @@ SM2_CIPHERTEXT_VALUE *SM2_do_encrypt(const SM2_ENC_PARAMS *params,
cv->ciphertext[i] ^= in[i];
}
if (params->mactag_size) {
mactag_size = SM2_ENC_PARAMS_mactag_size(params);
if (mactag_size) {
/* A7: C3 = Hash(x2 || M || y2) */
if (!EVP_DigestInit_ex(md_ctx, params->mac_md, NULL)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, in, inlen)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
if (!EVP_DigestFinal_ex(md_ctx, dgst, &dgstlen)) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
/* GmSSL specific: reduce mactag size */
if (params->mactag_size > dgstlen) {
if (mactag_size > dgstlen) {
SM2err(SM2_F_SM2_DO_ENCRYPT, SM2_R_ERROR);
goto end;
}
cv->mactag_size = params->mactag_size;
cv->mactag_size = mactag_size;
memcpy(cv->mactag, dgst, cv->mactag_size);
}
@@ -434,8 +464,9 @@ end:
}
int SM2_decrypt(const SM2_ENC_PARAMS *params,
unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
EC_KEY *ec_key)
{
int ret = 0;
const EC_GROUP *ec_group = EC_KEY_get0_group(ec_key);
@@ -443,11 +474,11 @@ int SM2_decrypt(const SM2_ENC_PARAMS *params,
int len;
if (!(len = SM2_CIPHERTEXT_VALUE_size(ec_group, params, 0))) {
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
SM2err(SM2_F_SM2_DECRYPT, SM2_R_ERROR);
goto end;
}
if (inlen <= len) {
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
SM2err(SM2_F_SM2_DECRYPT, SM2_R_ERROR);
goto end;
}
@@ -455,16 +486,16 @@ int SM2_decrypt(const SM2_ENC_PARAMS *params,
*outlen = inlen - len;
return 1;
} else if (*outlen < inlen - len) {
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
SM2err(SM2_F_SM2_DECRYPT, SM2_R_ERROR);
return 0;
}
if (!(cv = SM2_CIPHERTEXT_VALUE_decode(ec_group, params, in, inlen))) {
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
SM2err(SM2_F_SM2_DECRYPT, SM2_R_ERROR);
goto end;
}
if (!SM2_do_decrypt(params, cv, out, outlen, ec_key)) {
fprintf(stderr, "%s %d\n", __FILE__, __LINE__);
SM2err(SM2_F_SM2_DECRYPT, SM2_R_ERROR);
goto end;
}
@@ -490,14 +521,17 @@ int SM2_do_decrypt(const SM2_ENC_PARAMS *params,
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;
if (!ec_group || !pri_key) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
if (!kdf) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
@@ -506,6 +540,7 @@ int SM2_do_decrypt(const SM2_ENC_PARAMS *params,
return 1;
}
if (*outlen < cv->ciphertext_size) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
@@ -516,32 +551,39 @@ int SM2_do_decrypt(const SM2_ENC_PARAMS *params,
bn_ctx = BN_CTX_new();
md_ctx = EVP_MD_CTX_create();
if (!point || !n || !h || !bn_ctx || !md_ctx) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
/* init ec domain parameters */
if (!EC_GROUP_get_order(ec_group, n, bn_ctx)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
if (!EC_GROUP_get_cofactor(ec_group, h, bn_ctx)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_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)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
if (EC_POINT_is_at_infinity(ec_group, point)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
/* B3: compute ECDH [d]C1 = (x2, y2) */
if (!EC_POINT_mul(ec_group, point, NULL, cv->ephem_point, pri_key, bn_ctx)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
if (!(size = EC_POINT_point2oct(ec_group, point,
POINT_CONVERSION_UNCOMPRESSED, buf, sizeof(buf), bn_ctx))) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
OPENSSL_assert(size == 1 + nbytes * 2);
@@ -558,31 +600,39 @@ int SM2_do_decrypt(const SM2_ENC_PARAMS *params,
}
*outlen = cv->ciphertext_size;
if (params->mactag_size) {
mactag_size = SM2_ENC_PARAMS_mactag_size(params);
if (mactag_size) {
/* B6: check Hash(x2 || M || y2) == C3 */
if (!EVP_DigestInit_ex(md_ctx, params->mac_md, NULL)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, buf + 1, nbytes)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, out, *outlen)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
if (!EVP_DigestUpdate(md_ctx, buf + 1 + nbytes, nbytes)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
if (!EVP_DigestFinal_ex(md_ctx, mac, &maclen)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
/* GmSSL specific */
if (params->mactag_size > maclen) {
if (mactag_size > maclen) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
if (cv->mactag_size != params->mactag_size ||
if (cv->mactag_size != mactag_size ||
memcmp(mac, cv->mactag, cv->mactag_size)) {
SM2err(SM2_F_SM2_DO_DECRYPT, SM2_R_ERROR);
goto end;
}
}
@@ -610,41 +660,41 @@ int SM2_ENC_PARAMS_init_with_recommended(SM2_ENC_PARAMS *params)
return 1;
}
int SM2_encrypt_with_recommended(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
int SM2_encrypt_with_recommended(unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen, 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);
return SM2_encrypt(&params, out, outlen, in, inlen, ec_key);
}
int SM2_decrypt_with_recommended(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
int SM2_decrypt_with_recommended(unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen, 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);
return SM2_decrypt(&params, out, outlen, in, inlen, ec_key);
}
int SM2_encrypt_elgamal(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
int SM2_encrypt_elgamal(unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen, EC_KEY *ec_key)
{
SM2_ENC_PARAMS params;
params.kdf_md = EVP_sm3();
params.mac_md = EVP_sm3();
params.mactag_size = 0;
params.point_form = POINT_CONVERSION_COMPRESSED;
return SM2_encrypt(&params, in, inlen, out, outlen, ec_key);
return SM2_encrypt(&params, out, outlen, in, inlen, ec_key);
}
int SM2_decrypt_elgamal(const unsigned char *in, size_t inlen,
unsigned char *out, size_t *outlen, EC_KEY *ec_key)
int SM2_decrypt_elgamal(unsigned char *out, size_t *outlen,
const unsigned char *in, size_t inlen, EC_KEY *ec_key)
{
SM2_ENC_PARAMS params;
params.kdf_md = EVP_sm3();
params.mac_md = EVP_sm3();
params.mactag_size = 0;
params.point_form = POINT_CONVERSION_COMPRESSED;
return SM2_decrypt(&params, in, inlen, out, outlen, ec_key);
return SM2_decrypt(&params, out, outlen, in, inlen, ec_key);
}

View File

@@ -101,6 +101,7 @@ static ERR_STRING_DATA SM2_str_reasons[] = {
{ERR_REASON(SM2_R_BUFFER_TOO_SMALL), "buffer too small"},
{ERR_REASON(SM2_R_SM2_KAP_NOT_INITED), "KAP not inited"},
{ERR_REASON(SM2_R_RANDOM_NUMBER_GENERATION_FAILED), "random number generation failed"},
{ERR_REASON(SM2_R_ERROR), "Error"},
{0,NULL}
};

View File

@@ -479,6 +479,7 @@ int SM2_sign_ex(int type, const unsigned char *dgst, int dgstlen,
int SM2_sign(int type, const unsigned char *dgst, int dgstlen,
unsigned char *sig, unsigned int *siglen, EC_KEY *ec_key)
{
fprintf(stderr, "%s %d %s() executed\n", __FILE__, __LINE__, __FUNCTION__);
return SM2_sign_ex(type, dgst, dgstlen, sig, siglen, NULL, NULL, ec_key);
}
@@ -491,6 +492,8 @@ int SM2_verify(int type, const unsigned char *dgst, int dgstlen,
int derlen = -1;
int ret = -1;
fprintf(stderr, "%s %d %s() executed\n", __FILE__, __LINE__, __FUNCTION__);
if (!(s = ECDSA_SIG_new())) {
return ret;
}

View File

@@ -337,8 +337,8 @@ int test_sm2_enc(const EC_GROUP *group,
}
buflen = sizeof(buf);
if (!SM2_encrypt(kdf_md, mac_md, point_form,
(const unsigned char *)M, strlen(M), buf, &buflen, ec_key)) {
if (!SM2_encrypt_with_recommended((const unsigned char *)M, strlen(M),
buf, &buflen, ec_key)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
@@ -355,8 +355,7 @@ int test_sm2_enc(const EC_GROUP *group,
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!SM2_decrypt(kdf_md, mac_md, point_form, buf, buflen,
msg, &msglen, ec_key)) {
if (!SM2_decrypt_with_recommended(buf, buflen, msg, &msglen, ec_key)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
@@ -625,7 +624,7 @@ int test_sm2_test_vector()
printf("sm2 kap p256 passed\n");
}
#if 0
#if 1
/* ZA will not pass! */
if (!test_sm2_kap(
sm2b257test,
@@ -663,6 +662,567 @@ end:
}
EVP_PKEY *genpkey(int curve_nid, BIO *out, int verbose)
{
int ok = 0;
EVP_PKEY *ret = NULL;
EVP_PKEY_CTX *pkctx = NULL;
if (!(pkctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_PKEY_keygen_init(pkctx)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pkctx, curve_nid)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_PKEY_keygen(pkctx, &ret)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose > 1) {
EVP_PKEY_print_private(out, ret, 4, NULL);
BIO_printf(out, "\n");
}
ok = 1;
end:
if (!ok && ret) {
EVP_PKEY_free(ret);
ret = NULL;
}
EVP_PKEY_CTX_free(pkctx);
return ret;
}
int test_evp_pkey_sign(EVP_PKEY *pkey, int do_sm2, int verbose)
{
int ret = 0;
EVP_PKEY_CTX *pkctx = NULL;
int type = do_sm2 ? NID_sm_scheme : NID_secg_scheme;
unsigned char dgst[EVP_MAX_MD_SIZE] = "hello world";
size_t dgstlen;
unsigned char sig[256];
size_t siglen;
if (!(pkctx = EVP_PKEY_CTX_new(pkey, NULL))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* EVP_PKEY_sign() */
if (!EVP_PKEY_sign_init(pkctx)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_PKEY_CTX_set_ec_sign_type(pkctx, type)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
dgstlen = 32;
bzero(sig, sizeof(sig));
siglen = sizeof(sig);
if (!EVP_PKEY_sign(pkctx, sig, &siglen, dgst, dgstlen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose > 1) {
size_t i;
printf("signature (%zu bytes) = ", siglen);
for (i = 0; i < siglen; i++) {
printf("%02X", sig[i]);
}
printf("\n");
}
if (!EVP_PKEY_verify_init(pkctx)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_PKEY_CTX_set_ec_sign_type(pkctx, type)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (EVP_PKEY_verify(pkctx, sig, siglen, dgst, dgstlen) != SM2_VERIFY_SUCCESS) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose) {
printf("test %s signing passed\n", OBJ_nid2sn(type));
}
ret = 1;
end:
EVP_PKEY_CTX_free(pkctx);
return ret;
}
int test_evp_pkey_encrypt(EVP_PKEY *pkey, int do_sm2, int verbose)
{
int ret = 0;
EVP_PKEY_CTX *pkctx = NULL;
int type = do_sm2 ? NID_sm_scheme : NID_secg_scheme;
unsigned char msg[] = "hello world this is the message";
size_t msglen = sizeof(msg);
unsigned char cbuf[512];
size_t cbuflen = sizeof(cbuf);
unsigned char mbuf[512];
size_t mbuflen = sizeof(mbuf);
int len;
unsigned int ulen;
if (!(pkctx = EVP_PKEY_CTX_new(pkey, NULL))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* EVP_PKEY_encrypt() */
if (!EVP_PKEY_encrypt_init(pkctx)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_PKEY_CTX_set_ec_enc_type(pkctx, type)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
cbuflen = sizeof(cbuf);
if (!EVP_PKEY_encrypt(pkctx, cbuf, &cbuflen, msg, msglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose > 1) {
size_t i;
printf("ciphertext (%zu bytes) = ", cbuflen);
for (i = 0; i < cbuflen; i++) {
printf("%02X", cbuf[i]);
}
printf("\n");
}
if (!EVP_PKEY_decrypt_init(pkctx)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_PKEY_CTX_set_ec_enc_type(pkctx, type)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
bzero(mbuf, sizeof(mbuf));
mbuflen = sizeof(mbuf);
if (!EVP_PKEY_decrypt(pkctx, mbuf, &mbuflen, cbuf, cbuflen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose > 1) {
printf("original message = %s\n", msg);
printf("decrypted message = %s\n", mbuf);
}
if (verbose) {
printf("test %s encryption passed\n", OBJ_nid2sn(type));
}
ret = 1;
end:
EVP_PKEY_CTX_free(pkctx);
return ret;
}
int test_evp_pkey_encrypt_old(EVP_PKEY *pkey, int verbose)
{
int ret = 0;
unsigned char msg[] = "hello world this is the message";
size_t msglen = sizeof(msg);
unsigned char cbuf[512];
size_t cbuflen = sizeof(cbuf);
unsigned char mbuf[512];
size_t mbuflen = sizeof(mbuf);
int len;
if ((len = EVP_PKEY_encrypt_old(cbuf, msg, (int)msglen, pkey)) <= 0) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose > 1) {
int i;
printf("ciphertext (%d bytes) = ", len);
for (i = 0; i < len; i++) {
printf("%02X", cbuf[i]);
}
printf("\n");
}
bzero(mbuf, sizeof(mbuf));
if ((len = EVP_PKEY_decrypt_old(mbuf, cbuf, len, pkey)) <= 0) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose > 1) {
printf("original message = %s\n", msg);
printf("decrypted message = %s\n", mbuf);
}
if (verbose) {
printf("EVP_PKEY_encrypt_old() passed!\n");
}
ret = 1;
end:
return ret;
}
int test_evp_sign(EVP_PKEY *pkey, const EVP_MD *md, int verbose)
{
int ret = 0;
EVP_MD_CTX *mdctx = NULL;
unsigned char msg[] = "hello world this is the message";
size_t msglen = sizeof(msg);
unsigned char sig[256];
unsigned int siglen = (unsigned int)sizeof(sig);
unsigned int i;
if (!(mdctx = EVP_MD_CTX_create())) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_SignInit_ex(mdctx, md, NULL)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_SignUpdate(mdctx, msg, msglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_SignFinal(mdctx, sig, &siglen, pkey)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose > 1) {
size_t i;
printf("signature (%u bytes) = ", siglen);
for (i = 0; i < siglen; i++) {
printf("%02X", sig[i]);
}
printf("\n");
}
if (!EVP_VerifyInit_ex(mdctx, md, NULL)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_VerifyUpdate(mdctx, msg, msglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (EVP_VerifyFinal(mdctx, sig, siglen, pkey) != SM2_VERIFY_SUCCESS) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose) {
printf("EVP_SignInit/Update/Final() passed\n");
}
ret = 1;
end:
EVP_MD_CTX_destroy(mdctx);
return ret;
}
int test_evp_digestsign(EVP_PKEY *pkey, int do_sm2, const EVP_MD *md, int verbose)
{
int ret = 0;
EVP_MD_CTX *mdctx = NULL;
EVP_PKEY_CTX *pkctx;
int type = do_sm2 ? NID_sm_scheme : NID_secg_scheme;
unsigned char msg[] = "hello world this is the message";
size_t msglen = sizeof(msg);
unsigned char sig[256];
size_t siglen = (unsigned int)sizeof(sig);
if (!(mdctx = EVP_MD_CTX_create())) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
pkctx = NULL;
if (!EVP_DigestSignInit(mdctx, &pkctx, md, NULL, pkey)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_PKEY_CTX_set_ec_sign_type(pkctx, type)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_DigestSignUpdate(mdctx, msg, msglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
siglen = sizeof(sig);
if (!EVP_DigestSignFinal(mdctx, sig, &siglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
pkctx = NULL;
if (!EVP_DigestVerifyInit(mdctx, &pkctx, md, NULL, pkey)) {
ERR_print_errors_fp(stderr);
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_PKEY_CTX_set_ec_sign_type(pkctx, type)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_DigestVerifyUpdate(mdctx, msg, msglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (!EVP_DigestVerifyFinal(mdctx, sig, siglen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose) {
printf("EVP_DigestSignInit/Update/Final() passed\n");
}
ret = 1;
end:
EVP_MD_CTX_destroy(mdctx);
return ret;
}
#define NUM_PKEYS 3
#define MAX_PKEY_SIZE 256
int test_evp_seal(int curve_id, const EVP_CIPHER *cipher, BIO *out, int verbose)
{
int ret = 0;
EVP_PKEY *pkey[NUM_PKEYS] = {0};
EVP_CIPHER_CTX *cctx = NULL;
unsigned char iv[16];
unsigned char ek[NUM_PKEYS][MAX_PKEY_SIZE];
int ekl[NUM_PKEYS];
unsigned char msg1[] = "Hello ";
unsigned char msg2[] = "World!";
unsigned char cbuf[256];
unsigned char mbuf[256];
unsigned char *p;
int len, clen, mlen, i;
for (i = 0; i < NUM_PKEYS; i++) {
pkey[i] = genpkey(curve_id, out, verbose);
ekl[i] = MAX_PKEY_SIZE;
}
RAND_bytes(iv, sizeof(iv));
if (!(cctx = EVP_CIPHER_CTX_new())) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (NUM_PKEYS != EVP_SealInit(cctx, cipher, ek, ekl, iv, pkey, NUM_PKEYS)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
if (verbose > 1) {
for (i = 0; i < NUM_PKEYS; i++) {
int j;
BIO_printf(out, "ek[i] (%d-byte) = ", ekl[i]);
for (j = 0; j < ekl[i]; j++) {
BIO_printf(out, "%02X", ek[i][j]);
}
BIO_printf(out, "\n");
}
}
p = cbuf;
len = sizeof(cbuf);
if (!EVP_SealUpdate(cctx, p, &len, msg1, sizeof(msg1)-1)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
p += len;
len = sizeof(cbuf) - (p - cbuf);
if (!EVP_SealUpdate(cctx, p, &len, msg2, sizeof(msg2)-1)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
p += len;
len = sizeof(cbuf) - (p - cbuf);
if (!EVP_SealFinal(cctx, p, &len)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
p += len;
clen = p - cbuf;
if (verbose > 1) {
BIO_printf(out, "ciphertext (%d-byte) = ", clen);
for (i = 0; i < clen; i++) {
BIO_printf(out, "%02X", cbuf[i]);
}
BIO_printf(out, "\n");
}
if (!EVP_OpenInit(cctx, cipher, ek[0], ekl[0], iv, pkey[0])) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
bzero(mbuf, sizeof(mbuf));
p = mbuf;
len = sizeof(mbuf);
if (!EVP_OpenUpdate(cctx, p, &len, cbuf, clen)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
p += len;
len = sizeof(mbuf) - len;
if (!EVP_OpenFinal(cctx, p, &len)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
p += len;
mlen = p - mbuf;
if (verbose > 1) {
BIO_printf(out, "message = %s%s\n", (char *)msg1, (char *)msg2);
BIO_printf(out, "message = %s\n", (char *)mbuf);
}
if (verbose) {
BIO_printf(out, "EVP_SealInit/Update/Final() passed!\n");
}
ret = 1;
end:
EVP_CIPHER_CTX_free(cctx);
for (i = 0; i < NUM_PKEYS; i++) {
EVP_PKEY_free(pkey[i]);
}
return ret;
}
int test_sm2_evp(int verbose)
{
int ret = 0;
EVP_PKEY *pkey = NULL;
BIO *out = NULL;
int curve_id = NID_sm2p256v1;
const EVP_MD *md = EVP_sm3();
const EVP_CIPHER *cipher = EVP_sms4_cbc();
ERR_load_crypto_strings();
out = BIO_new_fp(stderr, BIO_NOCLOSE);
if (!(pkey = genpkey(curve_id, out, verbose))) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* test sm2sign */
if (!test_evp_pkey_sign(pkey, 1, verbose)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* test ecdsa */
if (!test_evp_pkey_sign(pkey, 0, verbose)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* test sm2encrypt */
if (!test_evp_pkey_encrypt(pkey, 1, verbose)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* test ecies */
if (!test_evp_pkey_encrypt(pkey, 0, verbose)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* test ec default encrypt */
if (!test_evp_pkey_encrypt_old(pkey, verbose)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* test ec default sign */
if (!test_evp_sign(pkey, md, verbose)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
/* test seal/open */
if (!test_evp_seal(curve_id, cipher, out, verbose)) {
fprintf(stderr, "error: %s %d\n", __FILE__, __LINE__);
goto end;
}
ret = 1;
end:
if (ret != 1) {
ERR_print_errors_fp(stderr);
}
EVP_PKEY_free(pkey);
return ret;
}
int main(int argc, char **argv)
{
int ret = -1;
@@ -688,30 +1248,11 @@ int main(int argc, char **argv)
if (!test_sm2_test_vector()) {
goto err;
}
/*
if (!test_sm2_evp_pkey_sign()) {
if (!test_sm2_evp(2)) {
goto err;
}
if (!test_sm2_evp_pkey_encrypt()) {
goto err;
}
if (!test_sm2_evp_pkey_derive()) {
goto err;
}
if (!test_sm2_evp_sign()) {
goto err;
}
if (!test_sm2_evp_digestsign()) {
goto err;
}
if (!test_sm2_evp_encrypt_old()) {
goto err;
}
if (!test_sm2_evp_seal()) {
goto err;
}
*/
}
ret =0;
err:
if (ret)