]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
PROV: Add SM2 encoders and decoders, as well as support functionality
authorRichard Levitte <levitte@openssl.org>
Thu, 28 Jan 2021 07:22:09 +0000 (08:22 +0100)
committerRichard Levitte <levitte@openssl.org>
Mon, 1 Feb 2021 22:02:20 +0000 (23:02 +0100)
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)

providers/decoders.inc
providers/encoders.inc
providers/implementations/encode_decode/decode_der2key.c
providers/implementations/encode_decode/encode_key2any.c
providers/implementations/encode_decode/encode_key2text.c
providers/implementations/include/prov/implementations.h
providers/implementations/keymgmt/ec_kmgmt.c

index c9f0dea6380ac8890f64cb7dcb15f32610733899..4dc687c76f63c274e14904200759c9a87a7eab9e 100644 (file)
@@ -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),
index c8032799b83208538610d2ced22223521ea28a3c..f2b59e08461ada616fc8a20beb12029c23611245 100644 (file)
@@ -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
 
 /*
index a91bd3b7b804f8ee9b4993dac9380fbfda5fb56e..6611e808d1abd2e35931abb6b9b727dc9fdf5bef 100644 (file)
@@ -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);
index ee2930852e223497b7a0dce7b6e11895f2a66854..7af53cca9616293da68406478952a58e775eaf4f 100644 (file)
@@ -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 */
index 49bbf8c2af9861998c66ee9b6fe10e79ab61f567..21cedbb0dd2c2e28a3fb3238cbaaecf0f0b0a7ac 100644 (file)
@@ -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);
index b83fddf57849467bf986e021bf0596a896fdf89f..bdd0c243d6a7a996cc35b4e3e806e8ffd1435fc9 100644 (file)
@@ -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[];
index d7ed92bd68f5ffba49ac5b33e5a8b081d8c2a554..3a58d9e4dc1a7bcd6e6c5b62227caa8569e66858 100644 (file)
@@ -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 },