diff options
author | Richard Levitte <levitte@openssl.org> | 2021-01-28 08:22:09 +0100 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2021-02-01 23:02:20 +0100 |
commit | f2db0528d8d7015ba39faca78a16e5e820db9df6 (patch) | |
tree | 4301c6eb84f21f3fc19e71876589c5fb8c462af4 | |
parent | 58f422f6f481ec7961fe762c97121b53abad3eb4 (diff) |
PROV: Add SM2 encoders and decoders, as well as support functionality
The EC KEYMGMT implementation handled SM2 as well, except what's
needed to support decoding: loading functions for both EC and SM2 that
checks for the presence or absence of the SM2 curve the same way as
the EC / SM2 import functions.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14028)
-rw-r--r-- | providers/decoders.inc | 4 | ||||
-rw-r--r-- | providers/encoders.inc | 14 | ||||
-rw-r--r-- | providers/implementations/encode_decode/decode_der2key.c | 14 | ||||
-rw-r--r-- | providers/implementations/encode_decode/encode_key2any.c | 26 | ||||
-rw-r--r-- | providers/implementations/encode_decode/encode_key2text.c | 7 | ||||
-rw-r--r-- | providers/implementations/include/prov/implementations.h | 17 | ||||
-rw-r--r-- | providers/implementations/keymgmt/ec_kmgmt.c | 46 |
7 files changed, 119 insertions, 9 deletions
diff --git a/providers/decoders.inc b/providers/decoders.inc index c9f0dea638..4dc687c76f 100644 --- a/providers/decoders.inc +++ b/providers/decoders.inc @@ -65,6 +65,10 @@ DECODER_w_structure("X25519", der, PKCS8, x25519, yes), DECODER_w_structure("X25519", der, SubjectPublicKeyInfo, x25519, yes), DECODER_w_structure("X448", der, PKCS8, x448, yes), DECODER_w_structure("X448", der, SubjectPublicKeyInfo, x448, yes), +# ifndef OPENSSL_NO_SM2 +DECODER_w_structure("SM2", der, PKCS8, sm2, yes), +DECODER_w_structure("SM2", der, SubjectPublicKeyInfo, sm2, yes), +# endif #endif DECODER_w_structure("RSA", der, PKCS8, rsa, yes), DECODER_w_structure("RSA", der, SubjectPublicKeyInfo, rsa, yes), diff --git a/providers/encoders.inc b/providers/encoders.inc index c8032799b8..f2b59e0846 100644 --- a/providers/encoders.inc +++ b/providers/encoders.inc @@ -60,6 +60,9 @@ ENCODER_TEXT("ED25519", ed25519, yes), ENCODER_TEXT("ED448", ed448, yes), ENCODER_TEXT("X25519", x25519, yes), ENCODER_TEXT("X448", x448, yes), +# ifndef OPENSSL_NO_SM2 +ENCODER_TEXT("SM2", sm2, yes), +# endif #endif /* @@ -104,6 +107,10 @@ ENCODER_w_structure("DSA", dsa, yes, pem, type_specific), /* EC only supports keypair and parameters output. */ ENCODER_w_structure("EC", ec, yes, der, type_specific_no_pub), ENCODER_w_structure("EC", ec, yes, pem, type_specific_no_pub), +# ifndef OPENSSL_NO_SM2 +ENCODER_w_structure("SM2", sm2, yes, der, type_specific_no_pub), +ENCODER_w_structure("SM2", sm2, yes, pem, type_specific_no_pub), +# endif #endif /* @@ -177,6 +184,13 @@ ENCODER_w_structure("ED448", ed448, yes, der, PKCS8), ENCODER_w_structure("ED448", ed448, yes, pem, PKCS8), ENCODER_w_structure("ED448", ed448, yes, der, SubjectPublicKeyInfo), ENCODER_w_structure("ED448", ed448, yes, pem, SubjectPublicKeyInfo), + +# ifndef OPENSSL_NO_SM2 +ENCODER_w_structure("SM2", sm2, yes, der, PKCS8), +ENCODER_w_structure("SM2", sm2, yes, pem, PKCS8), +ENCODER_w_structure("SM2", sm2, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("SM2", sm2, yes, pem, SubjectPublicKeyInfo), +# endif #endif /* diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c index a91bd3b7b8..6611e808d1 100644 --- a/providers/implementations/encode_decode/decode_der2key.c +++ b/providers/implementations/encode_decode/decode_der2key.c @@ -504,6 +504,16 @@ static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx) # define x448_d2i_key_params NULL # define x448_free (free_key_fn *)ecx_key_free # define x448_adjust ecx_key_adjust + +# ifndef OPENSSL_NO_SM2 +# define sm2_evp_type EVP_PKEY_SM2 +# define sm2_evp_extract (extract_key_fn *)EVP_PKEY_get1_EC_KEY +# define sm2_d2i_private_key (d2i_of_void *)d2i_ECPrivateKey +# define sm2_d2i_public_key NULL +# define sm2_d2i_key_params (d2i_of_void *)d2i_ECParameters +# define sm2_free (free_key_fn *)EC_KEY_free +# define sm2_adjust ec_adjust +# endif #endif /* ---------------------------------------------------------------------- */ @@ -762,6 +772,10 @@ MAKE_DECODER("ED25519", ed25519, ecx, PKCS8); MAKE_DECODER("ED25519", ed25519, ecx, SubjectPublicKeyInfo); MAKE_DECODER("ED448", ed448, ecx, PKCS8); MAKE_DECODER("ED448", ed448, ecx, SubjectPublicKeyInfo); +# ifndef OPENSSL_NO_SM2 +MAKE_DECODER("SM2", sm2, ec, PKCS8); +MAKE_DECODER("SM2", sm2, ec, SubjectPublicKeyInfo); +# endif #endif MAKE_DECODER("RSA", rsa, rsa, PKCS8); MAKE_DECODER("RSA", rsa, rsa, SubjectPublicKeyInfo); diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c index ee2930852e..7af53cca96 100644 --- a/providers/implementations/encode_decode/encode_key2any.c +++ b/providers/implementations/encode_decode/encode_key2any.c @@ -655,6 +655,12 @@ static int ec_pkcs8_priv_to_der(const void *veckey, unsigned char **pder) # define ec_evp_type EVP_PKEY_EC # define ec_input_type "EC" # define ec_pem_type "EC" + +# ifndef OPENSSL_NO_SM2 +# define sm2_evp_type EVP_PKEY_SM2 +# define sm2_input_type "SM2" +# define sm2_pem_type "SM2" +# endif #endif /* ---------------------------------------------------------------------- */ @@ -1139,6 +1145,10 @@ static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout, #define DO_EC_selection_mask DO_type_specific_selection_mask #define DO_EC(impl, type, output) DO_type_specific(impl, type, output) +#define SM2_output_structure "sm2" +#define DO_SM2_selection_mask DO_type_specific_selection_mask +#define DO_SM2(impl, type, output) DO_type_specific(impl, type, output) + /* PKCS#1 defines a structure for RSA private and public keys */ #define PKCS1_output_structure "pkcs1" #define DO_PKCS1_selection_mask DO_RSA_selection_mask @@ -1280,6 +1290,9 @@ MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, type_specific, der); #endif #ifndef OPENSSL_NO_EC MAKE_ENCODER(ec, ec, EVP_PKEY_EC, type_specific_no_pub, der); +# ifndef OPENSSL_NO_SM2 +MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, type_specific_no_pub, der); +# endif #endif /* @@ -1296,6 +1309,9 @@ MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, type_specific, pem); #endif #ifndef OPENSSL_NO_EC MAKE_ENCODER(ec, ec, EVP_PKEY_EC, type_specific_no_pub, pem); +# ifndef OPENSSL_NO_SM2 +MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, type_specific_no_pub, pem); +# endif #endif /* @@ -1335,6 +1351,12 @@ MAKE_ENCODER(ec, ec, EVP_PKEY_EC, PKCS8, der); MAKE_ENCODER(ec, ec, EVP_PKEY_EC, PKCS8, pem); MAKE_ENCODER(ec, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, der); MAKE_ENCODER(ec, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, pem); +# ifndef OPENSSL_NO_SM2 +MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PKCS8, der); +MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PKCS8, pem); +MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, der); +MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, pem); +# endif MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PKCS8, der); MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PKCS8, pem); MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, SubjectPublicKeyInfo, der); @@ -1376,6 +1398,10 @@ MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, DSA, pem); #ifndef OPENSSL_NO_EC MAKE_ENCODER(ec, ec, EVP_PKEY_EC, EC, der); MAKE_ENCODER(ec, ec, EVP_PKEY_EC, EC, pem); +# ifndef OPENSSL_NO_SM2 +MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SM2, der); +MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SM2, pem); +# endif #endif /* Convenience structure names */ diff --git a/providers/implementations/encode_decode/encode_key2text.c b/providers/implementations/encode_decode/encode_key2text.c index 49bbf8c2af..21cedbb0dd 100644 --- a/providers/implementations/encode_decode/encode_key2text.c +++ b/providers/implementations/encode_decode/encode_key2text.c @@ -547,6 +547,10 @@ err: } # define ec_input_type "EC" + +# ifndef OPENSSL_NO_SM2 +# define sm2_input_type "SM2" +# endif #endif /* ---------------------------------------------------------------------- */ @@ -906,6 +910,9 @@ MAKE_TEXT_ENCODER(dsa, dsa); #endif #ifndef OPENSSL_NO_EC MAKE_TEXT_ENCODER(ec, ec); +# ifndef OPENSSL_NO_SM2 +MAKE_TEXT_ENCODER(sm2, ec); +# endif MAKE_TEXT_ENCODER(ed25519, ecx); MAKE_TEXT_ENCODER(ed448, ecx); MAKE_TEXT_ENCODER(x25519, ecx); diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h index b83fddf578..bdd0c243d6 100644 --- a/providers/implementations/include/prov/implementations.h +++ b/providers/implementations/include/prov/implementations.h @@ -390,6 +390,18 @@ extern const OSSL_DISPATCH ossl_ec_to_type_specific_no_pub_pem_encoder_functions extern const OSSL_DISPATCH ossl_ec_to_type_specific_no_pub_der_encoder_functions[]; extern const OSSL_DISPATCH ossl_ec_to_text_encoder_functions[]; +#ifndef OPENSSL_NO_SM2 +extern const OSSL_DISPATCH ossl_sm2_to_SM2_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_sm2_to_SM2_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_sm2_to_PKCS8_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_sm2_to_PKCS8_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_sm2_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_sm2_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_sm2_to_type_specific_no_pub_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_sm2_to_type_specific_no_pub_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_sm2_to_text_encoder_functions[]; +#endif + extern const OSSL_DISPATCH ossl_ed25519_to_PKCS8_der_encoder_functions[]; extern const OSSL_DISPATCH ossl_ed25519_to_PKCS8_pem_encoder_functions[]; extern const OSSL_DISPATCH ossl_ed25519_to_SubjectPublicKeyInfo_der_encoder_functions[]; @@ -453,6 +465,11 @@ extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ed25519_decoder_func extern const OSSL_DISPATCH ossl_PKCS8_der_to_ed448_decoder_functions[]; extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ed448_decoder_functions[]; +#ifndef OPENSSL_NO_SM2 +extern const OSSL_DISPATCH ossl_PKCS8_der_to_sm2_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_sm2_decoder_functions[]; +#endif + extern const OSSL_DISPATCH ossl_PKCS8_der_to_rsa_decoder_functions[]; extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_rsa_decoder_functions[]; extern const OSSL_DISPATCH ossl_type_specific_keypair_der_to_rsa_decoder_functions[]; diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c index d7ed92bd68..3a58d9e4dc 100644 --- a/providers/implementations/keymgmt/ec_kmgmt.c +++ b/providers/implementations/keymgmt/ec_kmgmt.c @@ -337,12 +337,25 @@ static int ec_match(const void *keydata1, const void *keydata2, int selection) return ok; } +static int common_check_sm2(const EC_KEY *ec, int sm2_wanted) +{ + const EC_GROUP *ecg = NULL; + + /* + * sm2_wanted: import the keys or domparams only on SM2 Curve + * !sm2_wanted: import the keys or domparams only not on SM2 Curve + */ + if ((ecg = EC_KEY_get0_group(ec)) == NULL + || (sm2_wanted ^ (EC_GROUP_get_curve_name(ecg) == NID_sm2))) + return 0; + return 1; +} + static int common_import(void *keydata, int selection, const OSSL_PARAM params[], - int sm2_curve) + int sm2_wanted) { EC_KEY *ec = keydata; - const EC_GROUP *ecg = NULL; int ok = 1; if (!ossl_prov_is_running() || ec == NULL) @@ -366,12 +379,7 @@ int common_import(void *keydata, int selection, const OSSL_PARAM params[], ok = ok && ec_group_fromdata(ec, params); - /* - * sm2_curve: import the keys or domparams only on SM2 Curve - * !sm2_curve: import the keys or domparams only not on SM2 Curve - */ - if ((ecg = EC_KEY_get0_group(ec)) == NULL - || (sm2_curve ^ (EC_GROUP_get_curve_name(ecg) == NID_sm2))) + if (!common_check_sm2(ec, sm2_wanted)) return 0; if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { @@ -1267,13 +1275,18 @@ static void ec_gen_cleanup(void *genctx) OPENSSL_free(gctx); } -void *ec_load(const void *reference, size_t reference_sz) +static void *common_load(const void *reference, size_t reference_sz, + int sm2_wanted) { EC_KEY *ec = NULL; if (ossl_prov_is_running() && reference_sz == sizeof(ec)) { /* The contents of the reference is the address to our object */ ec = *(EC_KEY **)reference; + + if (!common_check_sm2(ec, sm2_wanted)) + return NULL; + /* We grabbed, so we detach it */ *(EC_KEY **)reference = NULL; return ec; @@ -1281,6 +1294,20 @@ void *ec_load(const void *reference, size_t reference_sz) return NULL; } +static void *ec_load(const void *reference, size_t reference_sz) +{ + return common_load(reference, reference_sz, 0); +} + +#ifndef FIPS_MODULE +# ifndef OPENSSL_NO_SM2 +static void *sm2_load(const void *reference, size_t reference_sz) +{ + return common_load(reference, reference_sz, 1); +} +# endif +#endif + const OSSL_DISPATCH ossl_ec_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ec_newdata }, { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ec_gen_init }, @@ -1321,6 +1348,7 @@ const OSSL_DISPATCH ossl_sm2_keymgmt_functions[] = { (void (*)(void))ec_gen_settable_params }, { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))sm2_gen }, { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup }, + { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))sm2_load }, { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata }, { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))sm2_get_params }, { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))sm2_gettable_params }, |