aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-08-04 15:33:20 -0400
committerJack Lloyd <[email protected]>2017-08-04 15:33:20 -0400
commit968c1e492708d4c9372063a3965dabd72fd79dcc (patch)
tree5eca29b47ff73692e0da15bdd76e58412dd5a277 /src
parent87fcd69b587ccd60c5f248b40003cf9a0a558a53 (diff)
Add SM2 encryption to FFI
Also add hooks for keygen, etc
Diffstat (limited to 'src')
-rw-r--r--src/lib/ffi/ffi.h9
-rw-r--r--src/lib/ffi/ffi_pkey_algs.cpp41
-rw-r--r--src/lib/pubkey/pk_algs.cpp8
-rw-r--r--src/tests/test_ffi.cpp73
4 files changed, 130 insertions, 1 deletions
diff --git a/src/lib/ffi/ffi.h b/src/lib/ffi/ffi.h
index 7b14bdbd4..37f38ae1b 100644
--- a/src/lib/ffi/ffi.h
+++ b/src/lib/ffi/ffi.h
@@ -899,6 +899,15 @@ BOTAN_DLL int botan_privkey_load_sm2(botan_privkey_t* key,
const botan_mp_t scalar,
const char* curve_name);
+BOTAN_DLL int botan_pubkey_load_sm2_enc(botan_pubkey_t* key,
+ const botan_mp_t public_x,
+ const botan_mp_t public_y,
+ const char* curve_name);
+
+BOTAN_DLL int botan_privkey_load_sm2_enc(botan_privkey_t* key,
+ const botan_mp_t scalar,
+ const char* curve_name);
+
/*
* Public Key Encryption
*/
diff --git a/src/lib/ffi/ffi_pkey_algs.cpp b/src/lib/ffi/ffi_pkey_algs.cpp
index c2ebad80c..844a38846 100644
--- a/src/lib/ffi/ffi_pkey_algs.cpp
+++ b/src/lib/ffi/ffi_pkey_algs.cpp
@@ -37,6 +37,7 @@
#if defined(BOTAN_HAS_SM2)
#include <botan/sm2.h>
+ #include <botan/sm2_enc.h>
#endif
#if defined(BOTAN_HAS_ECDH)
@@ -607,6 +608,46 @@ int botan_privkey_load_sm2(botan_privkey_t* key,
#endif
}
+int botan_pubkey_load_sm2_enc(botan_pubkey_t* key,
+ const botan_mp_t public_x,
+ const botan_mp_t public_y,
+ const char* curve_name)
+ {
+#if defined(BOTAN_HAS_SM2)
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ std::unique_ptr<Botan::SM2_Encryption_PublicKey> p_key;
+ if(!pubkey_load_ec(p_key, safe_get(public_x), safe_get(public_y), curve_name))
+ {
+ *key = new botan_pubkey_struct(p_key.release());
+ return BOTAN_FFI_SUCCESS;
+ }
+ return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
+ });
+#else
+ BOTAN_UNUSED(key, public_x, public_y, curve_name);
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
+int botan_privkey_load_sm2_enc(botan_privkey_t* key,
+ const botan_mp_t scalar,
+ const char* curve_name)
+ {
+#if defined(BOTAN_HAS_SM2)
+ return ffi_guard_thunk(BOTAN_CURRENT_FUNCTION, [=]() {
+ std::unique_ptr<Botan::SM2_Encryption_PrivateKey> p_key;
+ int rc = privkey_load_ec(p_key, safe_get(scalar), curve_name);
+
+ if(rc == BOTAN_FFI_SUCCESS)
+ *key = new botan_privkey_struct(p_key.release());
+ return rc;
+ });
+#else
+ BOTAN_UNUSED(key, scalar, curve_name);
+ return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
+#endif
+ }
+
/* Ed25519 specific operations */
int botan_privkey_load_ed25519(botan_privkey_t* key,
diff --git a/src/lib/pubkey/pk_algs.cpp b/src/lib/pubkey/pk_algs.cpp
index 34d659c8f..ab10f0ab9 100644
--- a/src/lib/pubkey/pk_algs.cpp
+++ b/src/lib/pubkey/pk_algs.cpp
@@ -62,6 +62,7 @@
#if defined(BOTAN_HAS_SM2)
#include <botan/sm2.h>
+ #include <botan/sm2_enc.h>
#endif
#if defined(BOTAN_HAS_OPENSSL)
@@ -141,6 +142,8 @@ load_public_key(const AlgorithmIdentifier& alg_id,
#if defined(BOTAN_HAS_SM2)
if(alg_name == "SM2_Sig")
return std::unique_ptr<Public_Key>(new SM2_Signature_PublicKey(alg_id, key_bits));
+ if(alg_name == "SM2_Enc")
+ return std::unique_ptr<Public_Key>(new SM2_Encryption_PublicKey(alg_id, key_bits));
#endif
#if defined(BOTAN_HAS_XMSS)
@@ -217,6 +220,8 @@ load_private_key(const AlgorithmIdentifier& alg_id,
#if defined(BOTAN_HAS_SM2)
if(alg_name == "SM2_Sig")
return std::unique_ptr<Private_Key>(new SM2_Signature_PrivateKey(alg_id, key_bits));
+ if(alg_name == "SM2_Enc")
+ return std::unique_ptr<Private_Key>(new SM2_Encryption_PrivateKey(alg_id, key_bits));
#endif
#if defined(BOTAN_HAS_ELGAMAL)
@@ -305,6 +310,7 @@ create_private_key(const std::string& alg_name,
alg_name == "ECKCDSA" ||
alg_name == "ECGDSA" ||
alg_name == "SM2_Sig" ||
+ alg_name == "SM2_Enc" ||
alg_name == "GOST-34.10")
{
const EC_Group ec_group(params.empty() ? "secp256r1" : params);
@@ -332,6 +338,8 @@ create_private_key(const std::string& alg_name,
#if defined(BOTAN_HAS_SM2)
if(alg_name == "SM2_Sig")
return std::unique_ptr<Private_Key>(new SM2_Signature_PrivateKey(rng, ec_group));
+ if(alg_name == "SM2_Enc")
+ return std::unique_ptr<Private_Key>(new SM2_Encryption_PrivateKey(rng, ec_group));
#endif
#if defined(BOTAN_HAS_ECGDSA)
diff --git a/src/tests/test_ffi.cpp b/src/tests/test_ffi.cpp
index 482b190f8..44882cd66 100644
--- a/src/tests/test_ffi.cpp
+++ b/src/tests/test_ffi.cpp
@@ -389,6 +389,7 @@ class FFI_Unit_Tests : public Test
#if defined(BOTAN_HAS_SM2)
results.push_back(ffi_test_sm2(rng));
+ results.push_back(ffi_test_sm2_enc(rng));
#endif
#if defined(BOTAN_HAS_MCELIECE)
@@ -1323,7 +1324,7 @@ class FFI_Unit_Tests : public Test
Test::Result ffi_test_sm2(botan_rng_t rng)
{
- Test::Result result("FFI SM2");
+ Test::Result result("FFI SM2 Sig");
static const char* kCurve = "sm2p256v1";
const std::string sm2_ident = "SM2 Ident Field";
botan_privkey_t priv;
@@ -1409,6 +1410,76 @@ class FFI_Unit_Tests : public Test
return result;
}
+ Test::Result ffi_test_sm2_enc(botan_rng_t rng)
+ {
+ Test::Result result("FFI SM2 Enc");
+ static const char* kCurve = "sm2p256v1";
+ botan_privkey_t priv;
+ botan_pubkey_t pub;
+ botan_privkey_t loaded_privkey;
+ botan_pubkey_t loaded_pubkey;
+
+ REQUIRE_FFI_OK(botan_privkey_create, (&priv, "SM2_Enc", kCurve, rng));
+ TEST_FFI_OK(botan_privkey_export_pubkey, (&pub, priv));
+ ffi_test_pubkey_export(result, pub, priv, rng);
+
+ // Check key load functions
+ botan_mp_t private_scalar, public_x, public_y;
+ botan_mp_init(&private_scalar);
+ botan_mp_init(&public_x);
+ botan_mp_init(&public_y);
+
+ TEST_FFI_OK(botan_privkey_get_field, (private_scalar, priv, "x"));
+ TEST_FFI_OK(botan_pubkey_get_field, (public_x, pub, "public_x"));
+ TEST_FFI_OK(botan_pubkey_get_field, (public_y, pub, "public_y"));
+ TEST_FFI_OK(botan_privkey_load_sm2_enc, (&loaded_privkey, private_scalar, kCurve));
+ TEST_FFI_OK(botan_pubkey_load_sm2_enc, (&loaded_pubkey, public_x, public_y, kCurve));
+ TEST_FFI_OK(botan_privkey_check_key, (loaded_privkey, rng, 0));
+ TEST_FFI_OK(botan_pubkey_check_key, (loaded_pubkey, rng, 0));
+
+ char namebuf[32] = { 0 };
+ size_t name_len = sizeof(namebuf);
+
+ TEST_FFI_OK(botan_pubkey_algo_name, (pub, &namebuf[0], &name_len));
+ result.test_eq(namebuf, namebuf, "SM2_Enc");
+
+ std::vector<uint8_t> message(32);
+ // Assumes 256-bit params:
+ std::vector<uint8_t> ciphertext(1 + 32*2 + message.size() + 32);
+ TEST_FFI_OK(botan_rng_get, (rng, message.data(), message.size()));
+
+ botan_pk_op_encrypt_t enc;
+ if(TEST_FFI_OK(botan_pk_op_encrypt_create, (&enc, loaded_pubkey, "", 0)))
+ {
+ size_t ctext_len = ciphertext.size();
+ TEST_FFI_OK(botan_pk_op_encrypt, (enc, rng, ciphertext.data(), &ctext_len,
+ message.data(), message.size()));
+
+ botan_pk_op_decrypt_t dec;
+ TEST_FFI_OK(botan_pk_op_decrypt_create, (&dec, loaded_privkey, "", 0));
+
+ std::vector<uint8_t> recovered(ciphertext.size());
+ size_t recovered_len = recovered.size();
+
+ TEST_FFI_OK(botan_pk_op_decrypt,
+ (dec, recovered.data(), &recovered_len,
+ ciphertext.data(), ciphertext.size()));
+
+ botan_pk_op_decrypt_destroy(dec);
+ }
+ botan_pk_op_encrypt_destroy(enc);
+
+ TEST_FFI_OK(botan_mp_destroy, (private_scalar));
+ TEST_FFI_OK(botan_mp_destroy, (public_x));
+ TEST_FFI_OK(botan_mp_destroy, (public_y));
+ TEST_FFI_OK(botan_pubkey_destroy, (pub));
+ TEST_FFI_OK(botan_privkey_destroy, (priv));
+ TEST_FFI_OK(botan_privkey_destroy, (loaded_privkey));
+ TEST_FFI_OK(botan_pubkey_destroy, (loaded_pubkey));
+
+ return result;
+ }
+
Test::Result ffi_test_ecdh(botan_rng_t rng)
{
Test::Result result("FFI ECDH");