From dceb99a5fb1b065debc0b3fe19481eff80843732 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Wed, 24 Jan 2018 16:45:48 -0500 Subject: [PATCH] Support SM2 ECIES scheme via EVP Reviewed-by: Rich Salz Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/4793) --- crypto/ec/ec_pmeth.c | 97 ++++++++++++++++++----- crypto/sm2/sm2_crypt.c | 1 + test/recipes/30-test_evp_data/evppkey.txt | 5 ++ 3 files changed, 84 insertions(+), 19 deletions(-) diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c index 82a4ffabf9..5f3f56c961 100644 --- a/crypto/ec/ec_pmeth.c +++ b/crypto/ec/ec_pmeth.c @@ -17,7 +17,7 @@ #include "internal/evp_int.h" #if !defined(OPENSSL_NO_SM2) - #include +# include #endif /* EC pkey context structure */ @@ -123,13 +123,12 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, if (ec_nid == NID_sm2) { #if defined(OPENSSL_NO_SM2) - ret = -1; + ret = -1; #else - ret = SM2_sign(type, tbs, tbslen, sig, &sltmp, ec); + ret = SM2_sign(type, tbs, tbslen, sig, &sltmp, ec); #endif - } - else { - ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); + } else { + ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); } if (ret <= 0) @@ -154,22 +153,19 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx, if (ec_nid == NID_sm2) { #if defined(OPENSSL_NO_SM2) - ret = -1; + ret = -1; #else - ret = SM2_verify(type, tbs, tbslen, sig, siglen, ec); + ret = SM2_verify(type, tbs, tbslen, sig, siglen, ec); #endif + } else { + ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec); } - else { - ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec); - } - return ret; } #ifndef OPENSSL_NO_EC -static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) +static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { int ret; size_t outlen; @@ -205,6 +201,68 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, return 1; } +static int pkey_ecies_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + int ret, md_type; + EC_PKEY_CTX *dctx = ctx->data; + EC_KEY *ec = ctx->pkey->pkey.ec; + const int ec_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); + + if (dctx->md) + md_type = EVP_MD_type(dctx->md); + else if (ec_nid == NID_sm2) + md_type = NID_sm3; + else + md_type = NID_sha256; + + if (ec_nid == NID_sm2) { +# if defined(OPENSSL_NO_SM2) + ret = -1; +# else + ret = SM2_encrypt(ec, EVP_get_digestbynid(md_type), + in, inlen, out, outlen); +# endif + } else { + /* standard ECIES not implemented */ + ret = -1; + } + + return ret; +} + +static int pkey_ecies_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + int ret, md_type; + EC_PKEY_CTX *dctx = ctx->data; + EC_KEY *ec = ctx->pkey->pkey.ec; + const int ec_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); + + if (dctx->md) + md_type = EVP_MD_type(dctx->md); + else if (ec_nid == NID_sm2) + md_type = NID_sm3; + else + md_type = NID_sha256; + + if (ec_nid == NID_sm2) { +# if defined(OPENSSL_NO_SM2) + ret = -1; +# else + ret = SM2_decrypt(ec, EVP_get_digestbynid(md_type), + in, inlen, out, outlen); +# endif + } else { + /* standard ECIES not implemented */ + ret = -1; + } + + return ret; +} + static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) { @@ -269,8 +327,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return dctx->cofactor_mode; else { EC_KEY *ec_key = ctx->pkey->pkey.ec; - return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : - 0; + return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0; } } else if (p1 < -1 || p1 > 1) return -2; @@ -453,7 +510,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) const EVP_PKEY_METHOD ec_pkey_meth = { EVP_PKEY_EC, - 0, + EVP_PKEY_FLAG_AUTOARGLEN, pkey_ec_init, pkey_ec_copy, pkey_ec_cleanup, @@ -474,9 +531,11 @@ const EVP_PKEY_METHOD ec_pkey_meth = { 0, 0, 0, 0, - 0, 0, + 0, + pkey_ecies_encrypt, - 0, 0, + 0, + pkey_ecies_decrypt, 0, #ifndef OPENSSL_NO_EC diff --git a/crypto/sm2/sm2_crypt.c b/crypto/sm2/sm2_crypt.c index a450146a7b..7e7be9d04a 100644 --- a/crypto/sm2/sm2_crypt.c +++ b/crypto/sm2/sm2_crypt.c @@ -303,6 +303,7 @@ int SM2_decrypt(const EC_KEY *key, goto done; rc = 1; + *ptext_len = msg_len; done: diff --git a/test/recipes/30-test_evp_data/evppkey.txt b/test/recipes/30-test_evp_data/evppkey.txt index d29fbbe730..b2bbcbc2a7 100644 --- a/test/recipes/30-test_evp_data/evppkey.txt +++ b/test/recipes/30-test_evp_data/evppkey.txt @@ -18383,3 +18383,8 @@ Verify = SM2_key1 Ctrl = digest:SM3 Input = D7AD397F6FFA5D4F7F11E7217F241607DC30618C236D2C09C1B9EA8FDADEE2E8 Output = 3046022100AB1DB64DE7C40EDBDE6651C9B8EBDB804673DB836E5D5C7FE15DCF9ED2725037022100EBA714451FF69B0BB930B379E192E7CD5FA6E3C41C7FBD8303B799AB54A54621 + +Decrypt = SM2_key1 +Input = 30818A0220466BE2EF5C11782EC77864A0055417F407A5AFC11D653C6BCE69E417BB1D05B6022062B572E21FF0DDF5C726BD3F9FF2EAE56E6294713A607E9B9525628965F62CC804203C1B5713B5DB2728EB7BF775E44F4689FC32668BDC564F52EA45B09E8DF2A5F40422084A9D0CC2997092B7D3C404FCE95956EB604D732B2307A8E5B8900ED6608CA5B197 +Output = "The floofy bunnies hop at midnight" + -- 2.25.1