diff options
author | Jack Lloyd <[email protected]> | 2017-08-04 15:33:20 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-08-04 15:33:20 -0400 |
commit | 968c1e492708d4c9372063a3965dabd72fd79dcc (patch) | |
tree | 5eca29b47ff73692e0da15bdd76e58412dd5a277 /src | |
parent | 87fcd69b587ccd60c5f248b40003cf9a0a558a53 (diff) |
Add SM2 encryption to FFI
Also add hooks for keygen, etc
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/ffi/ffi.h | 9 | ||||
-rw-r--r-- | src/lib/ffi/ffi_pkey_algs.cpp | 41 | ||||
-rw-r--r-- | src/lib/pubkey/pk_algs.cpp | 8 | ||||
-rw-r--r-- | src/tests/test_ffi.cpp | 73 |
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"); |