diff options
Diffstat (limited to 'src/lib/pubkey')
-rw-r--r-- | src/lib/pubkey/mce/info.txt | 1 | ||||
-rw-r--r-- | src/lib/pubkey/mce/mce_kem.cpp | 91 | ||||
-rw-r--r-- | src/lib/pubkey/mce/mce_kem.h | 55 | ||||
-rw-r--r-- | src/lib/pubkey/mceies/mceies.cpp | 13 | ||||
-rw-r--r-- | src/lib/pubkey/pk_ops.cpp | 43 | ||||
-rw-r--r-- | src/lib/pubkey/pk_ops.h | 40 | ||||
-rw-r--r-- | src/lib/pubkey/pk_ops_impl.h | 40 | ||||
-rw-r--r-- | src/lib/pubkey/pk_utils.h | 3 | ||||
-rw-r--r-- | src/lib/pubkey/pubkey.cpp | 40 | ||||
-rw-r--r-- | src/lib/pubkey/pubkey.h | 81 | ||||
-rw-r--r-- | src/lib/pubkey/rsa/rsa.cpp | 62 |
11 files changed, 367 insertions, 102 deletions
diff --git a/src/lib/pubkey/mce/info.txt b/src/lib/pubkey/mce/info.txt index 1e9b848dd..bb0f06764 100644 --- a/src/lib/pubkey/mce/info.txt +++ b/src/lib/pubkey/mce/info.txt @@ -1,7 +1,6 @@ define MCELIECE 20150922 <header:public> -mce_kem.h mceliece.h polyn_gf2m.h gf2m_small_m.h diff --git a/src/lib/pubkey/mce/mce_kem.cpp b/src/lib/pubkey/mce/mce_kem.cpp index dede67731..b2cefaab2 100644 --- a/src/lib/pubkey/mce/mce_kem.cpp +++ b/src/lib/pubkey/mce/mce_kem.cpp @@ -1,51 +1,74 @@ /** - * (C) 2014 cryptosource GmbH - * (C) 2014 Falko Strenzke [email protected] - * - * Botan is released under the Simplified BSD License (see license.txt) - * - */ - -#include <botan/mce_kem.h> +* (C) 2014 cryptosource GmbH +* (C) 2014 Falko Strenzke [email protected] +* (C) 2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +* +*/ + #include <botan/internal/mce_internal.h> -#include <botan/sha2_64.h> +#include <botan/internal/pk_ops_impl.h> +#include <botan/internal/pk_utils.h> namespace Botan { -McEliece_KEM_Encryptor::McEliece_KEM_Encryptor(const McEliece_PublicKey& public_key) : - m_key(public_key) +class MCE_KEM_Encryptor : public PK_Ops::KEM_Encryption_with_KDF { - } + public: + typedef McEliece_PublicKey Key_Type; -std::pair<secure_vector<byte>, secure_vector<byte>> -McEliece_KEM_Encryptor::encrypt(RandomNumberGenerator& rng) - { - const secure_vector<byte> plaintext = m_key.random_plaintext_element(rng); + MCE_KEM_Encryptor(const McEliece_PublicKey& key, + const std::string& kdf) : + KEM_Encryption_with_KDF(kdf), m_key(key) {} + + private: + void raw_kem_encrypt(secure_vector<byte>& out_encapsulated_key, + secure_vector<byte>& raw_shared_key, + Botan::RandomNumberGenerator& rng) override + { + secure_vector<byte> plaintext = m_key.random_plaintext_element(rng); - secure_vector<byte> ciphertext, error_mask; - mceliece_encrypt(ciphertext, error_mask, plaintext, m_key, rng); + secure_vector<byte> ciphertext, error_mask; + mceliece_encrypt(ciphertext, error_mask, plaintext, m_key, rng); - SHA_512 hash; - hash.update(plaintext); - hash.update(error_mask); - secure_vector<byte> sym_key = hash.final(); + raw_shared_key.clear(); + raw_shared_key += plaintext; + raw_shared_key += error_mask; - return std::make_pair(ciphertext, sym_key); - } + out_encapsulated_key.swap(ciphertext); + } -McEliece_KEM_Decryptor::McEliece_KEM_Decryptor(const McEliece_PrivateKey& key) : m_key(key) { } + const McEliece_PublicKey& m_key; + }; -secure_vector<Botan::byte> McEliece_KEM_Decryptor::decrypt(const byte msg[], size_t msg_len) +class MCE_KEM_Decryptor : public PK_Ops::KEM_Decryption_with_KDF { - secure_vector<byte> plaintext, error_mask; - mceliece_decrypt(plaintext, error_mask, msg, msg_len, m_key); + public: + typedef McEliece_PrivateKey Key_Type; + + MCE_KEM_Decryptor(const McEliece_PrivateKey& key, + const std::string& kdf) : + KEM_Decryption_with_KDF(kdf), m_key(key) {} + + private: + secure_vector<byte> + raw_kem_decrypt(const byte encap_key[], size_t len) override + { + secure_vector<byte> plaintext, error_mask; + mceliece_decrypt(plaintext, error_mask, encap_key, len, m_key); + + secure_vector<byte> output; + output.reserve(plaintext.size() + error_mask.size()); + output.insert(output.end(), plaintext.begin(), plaintext.end()); + output.insert(output.end(), error_mask.begin(), error_mask.end()); + return output; + } - SHA_512 hash; - hash.update(plaintext); - hash.update(error_mask); + const McEliece_PrivateKey& m_key; + }; - secure_vector<byte> sym_key = hash.final(); - return sym_key; - } +BOTAN_REGISTER_PK_KEM_ENCRYPTION_OP("McEliece", MCE_KEM_Encryptor); +BOTAN_REGISTER_PK_KEM_DECRYPTION_OP("McEliece", MCE_KEM_Decryptor); } diff --git a/src/lib/pubkey/mce/mce_kem.h b/src/lib/pubkey/mce/mce_kem.h deleted file mode 100644 index cd899d568..000000000 --- a/src/lib/pubkey/mce/mce_kem.h +++ /dev/null @@ -1,55 +0,0 @@ -/** - * (C) 2014 cryptosource GmbH - * (C) 2014 Falko Strenzke [email protected] - * - * Botan is released under the Simplified BSD License (see license.txt) - * - */ - -#ifndef BOTAN_MCE_KEM_H__ -#define BOTAN_MCE_KEM_H__ - -#include <botan/mceliece.h> -#include <utility> - -namespace Botan { - -class BOTAN_DLL McEliece_KEM_Encryptor - { - public: - McEliece_KEM_Encryptor(const McEliece_PublicKey& public_key); - - /** - * returns the pair (mceliece ciphertext, symmetric key) - */ - std::pair<secure_vector<byte>, secure_vector<byte>> encrypt(RandomNumberGenerator& rng); - - private: - const McEliece_PublicKey& m_key; - }; - -class BOTAN_DLL McEliece_KEM_Decryptor - { - public: - McEliece_KEM_Decryptor(const McEliece_PrivateKey& mce_key); - - /** - * returns the derived 512-bit symmetric key - */ - secure_vector<Botan::byte> decrypt(const byte msg[], size_t msg_len); - - /** - * returns the derived 512-bit symmetric key - */ - template<typename Alloc> - secure_vector<Botan::byte> decrypt_vec(const std::vector<byte, Alloc>& v) - { - return decrypt(v.data(), v.size()); - } - - private: - const McEliece_PrivateKey& m_key; - }; -} - -#endif diff --git a/src/lib/pubkey/mceies/mceies.cpp b/src/lib/pubkey/mceies/mceies.cpp index e83fa257e..0af71719a 100644 --- a/src/lib/pubkey/mceies/mceies.cpp +++ b/src/lib/pubkey/mceies/mceies.cpp @@ -8,7 +8,7 @@ #include <botan/mceies.h> #include <botan/aead.h> #include <botan/mceliece.h> -#include <botan/mce_kem.h> +#include <botan/pubkey.h> namespace Botan { @@ -36,11 +36,10 @@ mceies_encrypt(const McEliece_PublicKey& pubkey, RandomNumberGenerator& rng, const std::string& algo) { - McEliece_KEM_Encryptor kem_op(pubkey); + PK_KEM_Encryptor kem_op(pubkey, "KDF1(SHA-512)"); - const std::pair<secure_vector<byte>,secure_vector<byte>> mce_ciphertext__key = kem_op.encrypt(rng); - const secure_vector<byte>& mce_ciphertext = mce_ciphertext__key.first; - const secure_vector<byte>& mce_key = mce_ciphertext__key.second; + secure_vector<byte> mce_ciphertext, mce_key; + kem_op.encrypt(mce_ciphertext, mce_key, 64, rng); const size_t mce_code_bytes = (pubkey.get_code_length() + 7) / 8; @@ -75,7 +74,7 @@ mceies_decrypt(const McEliece_PrivateKey& privkey, { try { - McEliece_KEM_Decryptor kem_op(privkey); + PK_KEM_Decryptor kem_op(privkey, "KDF1(SHA-512)"); const size_t mce_code_bytes = (privkey.get_code_length() + 7) / 8; @@ -88,7 +87,7 @@ mceies_decrypt(const McEliece_PrivateKey& privkey, if(ct_len < mce_code_bytes + nonce_len + aead->tag_size()) throw Exception("Input message too small to be valid"); - const secure_vector<byte> mce_key = kem_op.decrypt(ct, mce_code_bytes); + const secure_vector<byte> mce_key = kem_op.decrypt(ct, mce_code_bytes, 64); aead->set_key(aead_key(mce_key, *aead)); aead->set_associated_data(ad, ad_len); diff --git a/src/lib/pubkey/pk_ops.cpp b/src/lib/pubkey/pk_ops.cpp index bc421eb90..81b087894 100644 --- a/src/lib/pubkey/pk_ops.cpp +++ b/src/lib/pubkey/pk_ops.cpp @@ -129,4 +129,47 @@ bool PK_Ops::Verification_with_EMSA::is_valid_signature(const byte sig[], size_t } } +void PK_Ops::KEM_Encryption_with_KDF::kem_encrypt(secure_vector<byte>& out_encapsulated_key, + secure_vector<byte>& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, + const uint8_t salt[], + size_t salt_len) + { + secure_vector<byte> raw_shared; + this->raw_kem_encrypt(out_encapsulated_key, raw_shared, rng); + + out_shared_key = m_kdf->derive_key(desired_shared_key_len, + raw_shared.data(), raw_shared.size(), + salt, salt_len); + } + +PK_Ops::KEM_Encryption_with_KDF::KEM_Encryption_with_KDF(const std::string& kdf) + { + m_kdf.reset(get_kdf(kdf)); + } + +PK_Ops::KEM_Encryption_with_KDF::~KEM_Encryption_with_KDF() {} + +secure_vector<byte> +PK_Ops::KEM_Decryption_with_KDF::kem_decrypt(const byte encap_key[], + size_t len, + size_t desired_shared_key_len, + const uint8_t salt[], + size_t salt_len) + { + secure_vector<byte> raw_shared = this->raw_kem_decrypt(encap_key, len); + + return m_kdf->derive_key(desired_shared_key_len, + raw_shared.data(), raw_shared.size(), + salt, salt_len); + } + +PK_Ops::KEM_Decryption_with_KDF::KEM_Decryption_with_KDF(const std::string& kdf) + { + m_kdf.reset(get_kdf(kdf)); + } + +PK_Ops::KEM_Decryption_with_KDF::~KEM_Decryption_with_KDF() {} + } diff --git a/src/lib/pubkey/pk_ops.h b/src/lib/pubkey/pk_ops.h index 3a2a8bdb5..6fc21ea4a 100644 --- a/src/lib/pubkey/pk_ops.h +++ b/src/lib/pubkey/pk_ops.h @@ -47,11 +47,13 @@ typedef PK_Spec<Private_Key> PK_Spec_Private_Key; class BOTAN_DLL Encryption { public: + typedef PK_Spec_Public_Key Spec; + virtual size_t max_input_bits() const = 0; - virtual secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator& rng) = 0; - - typedef PK_Spec_Public_Key Spec; + virtual secure_vector<byte> encrypt(const byte msg[], + size_t msg_len, + RandomNumberGenerator& rng) = 0; virtual ~Encryption() {} }; @@ -164,6 +166,38 @@ class BOTAN_DLL Key_Agreement virtual ~Key_Agreement() {} }; +/** +* KEM (key encapsulation) +*/ +class BOTAN_DLL KEM_Encryption + { + public: + typedef PK_Spec_Public_Key Spec; + + virtual void kem_encrypt(secure_vector<byte>& out_encapsulated_key, + secure_vector<byte>& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, + const uint8_t salt[], + size_t salt_len) = 0; + + virtual ~KEM_Encryption() {} + }; + +class BOTAN_DLL KEM_Decryption + { + public: + typedef PK_Spec_Private_Key Spec; + + virtual secure_vector<byte> kem_decrypt(const byte encap_key[], + size_t len, + size_t desired_shared_key_len, + const uint8_t salt[], + size_t salt_len) = 0; + + virtual ~KEM_Decryption() {} + }; + } } diff --git a/src/lib/pubkey/pk_ops_impl.h b/src/lib/pubkey/pk_ops_impl.h index f27de4af4..0acceb53c 100644 --- a/src/lib/pubkey/pk_ops_impl.h +++ b/src/lib/pubkey/pk_ops_impl.h @@ -139,6 +139,46 @@ class Key_Agreement_with_KDF : public Key_Agreement std::unique_ptr<KDF> m_kdf; }; +class KEM_Encryption_with_KDF : public KEM_Encryption + { + public: + void kem_encrypt(secure_vector<byte>& out_encapsulated_key, + secure_vector<byte>& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, + const uint8_t salt[], + size_t salt_len) override; + + protected: + virtual void raw_kem_encrypt(secure_vector<byte>& out_encapsulated_key, + secure_vector<byte>& raw_shared_key, + Botan::RandomNumberGenerator& rng) = 0; + + KEM_Encryption_with_KDF(const std::string& kdf); + ~KEM_Encryption_with_KDF(); + private: + std::unique_ptr<KDF> m_kdf; + }; + +class KEM_Decryption_with_KDF : public KEM_Decryption + { + public: + secure_vector<byte> kem_decrypt(const byte encap_key[], + size_t len, + size_t desired_shared_key_len, + const uint8_t salt[], + size_t salt_len); + + protected: + virtual secure_vector<byte> + raw_kem_decrypt(const byte encap_key[], size_t len) = 0; + + KEM_Decryption_with_KDF(const std::string& kdf); + ~KEM_Decryption_with_KDF(); + private: + std::unique_ptr<KDF> m_kdf; + }; + } } diff --git a/src/lib/pubkey/pk_utils.h b/src/lib/pubkey/pk_utils.h index 326a6ea68..04a0bf5ca 100644 --- a/src/lib/pubkey/pk_utils.h +++ b/src/lib/pubkey/pk_utils.h @@ -32,6 +32,9 @@ OP* make_pk_op(const typename T::Spec& spec) #define BOTAN_REGISTER_PK_VERIFY_OP(NAME, TYPE) BOTAN_REGISTER_PK_OP(PK_Ops::Verification, NAME, TYPE) #define BOTAN_REGISTER_PK_KEY_AGREE_OP(NAME, TYPE) BOTAN_REGISTER_PK_OP(PK_Ops::Key_Agreement, NAME, TYPE) +#define BOTAN_REGISTER_PK_KEM_ENCRYPTION_OP(NAME, TYPE) BOTAN_REGISTER_PK_OP(PK_Ops::KEM_Encryption, NAME, TYPE) +#define BOTAN_REGISTER_PK_KEM_DECRYPTION_OP(NAME, TYPE) BOTAN_REGISTER_PK_OP(PK_Ops::KEM_Decryption, NAME, TYPE) + } #endif diff --git a/src/lib/pubkey/pubkey.cpp b/src/lib/pubkey/pubkey.cpp index b9923f54b..e870dfdec 100644 --- a/src/lib/pubkey/pubkey.cpp +++ b/src/lib/pubkey/pubkey.cpp @@ -59,6 +59,46 @@ secure_vector<byte> PK_Decryptor_EME::dec(const byte msg[], size_t length) const return m_op->decrypt(msg, length); } +PK_KEM_Encryptor::PK_KEM_Encryptor(const Public_Key& key, + const std::string& param, + const std::string& provider) + { + m_op.reset(get_pk_op<PK_Ops::KEM_Encryption>("KEM", key, param, provider)); + } + +void PK_KEM_Encryptor::encrypt(secure_vector<byte>& out_encapsulated_key, + secure_vector<byte>& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, + const uint8_t salt[], + size_t salt_len) + { + m_op->kem_encrypt(out_encapsulated_key, + out_shared_key, + desired_shared_key_len, + rng, + salt, + salt_len); + } + +PK_KEM_Decryptor::PK_KEM_Decryptor(const Private_Key& key, + const std::string& param, + const std::string& provider) + { + m_op.reset(get_pk_op<PK_Ops::KEM_Decryption>("KEM", key, param, provider)); + } + +secure_vector<byte> PK_KEM_Decryptor::decrypt(const byte encap_key[], + size_t encap_key_len, + size_t desired_shared_key_len, + const uint8_t salt[], + size_t salt_len) + { + return m_op->kem_decrypt(encap_key, encap_key_len, + desired_shared_key_len, + salt, salt_len); + } + PK_Key_Agreement::PK_Key_Agreement(const Private_Key& key, const std::string& kdf) { m_op.reset(get_pk_op<PK_Ops::Key_Agreement>("Key agreement", key, kdf)); diff --git a/src/lib/pubkey/pubkey.h b/src/lib/pubkey/pubkey.h index 637e522e4..a8caf58ac 100644 --- a/src/lib/pubkey/pubkey.h +++ b/src/lib/pubkey/pubkey.h @@ -438,6 +438,87 @@ class BOTAN_DLL PK_Decryptor_EME : public PK_Decryptor std::unique_ptr<PK_Ops::Decryption> m_op; }; +class BOTAN_DLL PK_KEM_Encryptor + { + public: + PK_KEM_Encryptor(const Public_Key& key, + const std::string& kem_param = "", + const std::string& provider = ""); + + void encrypt(secure_vector<byte>& out_encapsulated_key, + secure_vector<byte>& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, + const uint8_t salt[], + size_t salt_len); + + template<typename Alloc> + void encrypt(secure_vector<byte>& out_encapsulated_key, + secure_vector<byte>& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng, + const std::vector<uint8_t, Alloc>& salt) + { + this->encrypt(out_encapsulated_key, + out_shared_key, + desired_shared_key_len, + rng, + salt.data(), salt.size()); + } + + void encrypt(secure_vector<byte>& out_encapsulated_key, + secure_vector<byte>& out_shared_key, + size_t desired_shared_key_len, + Botan::RandomNumberGenerator& rng) + { + this->encrypt(out_encapsulated_key, + out_shared_key, + desired_shared_key_len, + rng, + nullptr, + 0); + } + + private: + std::unique_ptr<PK_Ops::KEM_Encryption> m_op; + }; + +class BOTAN_DLL PK_KEM_Decryptor + { + public: + PK_KEM_Decryptor(const Private_Key& key, + const std::string& kem_param = "", + const std::string& provider = ""); + + secure_vector<byte> decrypt(const byte encap_key[], + size_t encap_key_len, + size_t desired_shared_key_len, + const uint8_t salt[], + size_t salt_len); + + secure_vector<byte> decrypt(const byte encap_key[], + size_t encap_key_len, + size_t desired_shared_key_len) + { + return this->decrypt(encap_key, encap_key_len, + desired_shared_key_len, + nullptr, 0); + } + + template<typename Alloc1, typename Alloc2> + secure_vector<byte> decrypt(const std::vector<byte, Alloc1>& encap_key, + size_t desired_shared_key_len, + const std::vector<byte, Alloc2>& salt) + { + return this->decrypt(encap_key.data(), encap_key.size(), + desired_shared_key_len, + salt.data(), salt.size()); + } + + private: + std::unique_ptr<PK_Ops::KEM_Decryption> m_op; + }; + } #endif diff --git a/src/lib/pubkey/rsa/rsa.cpp b/src/lib/pubkey/rsa/rsa.cpp index 5804d0034..d18843315 100644 --- a/src/lib/pubkey/rsa/rsa.cpp +++ b/src/lib/pubkey/rsa/rsa.cpp @@ -1,6 +1,6 @@ /* * RSA -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2010,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -13,6 +13,8 @@ #include <botan/reducer.h> #include <future> +#include <iostream> + namespace Botan { /* @@ -156,11 +158,34 @@ class RSA_Decryption_Operation : public PK_Ops::Decryption_with_EME, const BigInt m(msg, msg_len); const BigInt x = blinded_private_op(m); const BigInt c = m_powermod_e_n(x); - BOTAN_ASSERT(m == c, "RSA sign consistency check"); + BOTAN_ASSERT(m == c, "RSA decrypt consistency check"); return BigInt::encode_locked(x); } }; +class RSA_KEM_Decryption_Operation : public PK_Ops::KEM_Decryption_with_KDF, + private RSA_Private_Operation + { + public: + typedef RSA_PrivateKey Key_Type; + + RSA_KEM_Decryption_Operation(const RSA_PrivateKey& key, + const std::string& kdf) : + PK_Ops::KEM_Decryption_with_KDF(kdf), + RSA_Private_Operation(key) + {} + + secure_vector<byte> + raw_kem_decrypt(const byte encap_key[], size_t len) override + { + const BigInt m(encap_key, len); + const BigInt x = blinded_private_op(m); + const BigInt c = m_powermod_e_n(x); + BOTAN_ASSERT(m == c, "RSA KEM consistency check"); + return BigInt::encode_1363(x, n.bytes()); + } + }; + /** * RSA public (encrypt/verify) operation */ @@ -181,6 +206,8 @@ class RSA_Public_Operation return powermod_e_n(m); } + const BigInt& get_n() const { return n; } + const BigInt& n; Fixed_Exponent_Power_Mod powermod_e_n; }; @@ -230,11 +257,42 @@ class RSA_Verify_Operation : public PK_Ops::Verification_with_EMSA, } }; +class RSA_KEM_Encryption_Operation : public PK_Ops::KEM_Encryption_with_KDF, + private RSA_Public_Operation + { + public: + typedef RSA_PublicKey Key_Type; + + RSA_KEM_Encryption_Operation(const RSA_PublicKey& key, + const std::string& kdf) : + PK_Ops::KEM_Encryption_with_KDF(kdf), + RSA_Public_Operation(key) {} + + private: + void raw_kem_encrypt(secure_vector<byte>& out_encapsulated_key, + secure_vector<byte>& raw_shared_key, + Botan::RandomNumberGenerator& rng) override + { + const BigInt r = BigInt::random_integer(rng, 1, get_n()); + std::cout << "R = " << r << "\n"; + const BigInt c = public_op(r); + std::cout << "C0 = " << c << "\n"; + + out_encapsulated_key = BigInt::encode_locked(c); + raw_shared_key = BigInt::encode_locked(r); + } + }; + + BOTAN_REGISTER_PK_ENCRYPTION_OP("RSA", RSA_Encryption_Operation); BOTAN_REGISTER_PK_DECRYPTION_OP("RSA", RSA_Decryption_Operation); + BOTAN_REGISTER_PK_SIGNATURE_OP("RSA", RSA_Signature_Operation); BOTAN_REGISTER_PK_VERIFY_OP("RSA", RSA_Verify_Operation); +BOTAN_REGISTER_PK_KEM_ENCRYPTION_OP("RSA", RSA_KEM_Encryption_Operation); +BOTAN_REGISTER_PK_KEM_DECRYPTION_OP("RSA", RSA_KEM_Decryption_Operation); + } } |