diff options
-rw-r--r-- | checks/ecdh.cpp | 167 | ||||
-rw-r--r-- | checks/pk_bench.cpp | 14 | ||||
-rw-r--r-- | doc/log.txt | 1 | ||||
-rw-r--r-- | src/engine/def_engine/def_pk_ops.cpp | 33 | ||||
-rw-r--r-- | src/engine/def_engine/default_engine.h | 6 | ||||
-rw-r--r-- | src/engine/engine.h | 17 | ||||
-rw-r--r-- | src/engine/info.txt | 1 | ||||
-rw-r--r-- | src/libstate/pk_engine.cpp | 19 | ||||
-rw-r--r-- | src/libstate/pk_engine.h | 8 | ||||
-rw-r--r-- | src/pubkey/dh/dh.cpp | 40 | ||||
-rw-r--r-- | src/pubkey/dh/dh.h | 33 | ||||
-rw-r--r-- | src/pubkey/dh/dh_core.cpp | 65 | ||||
-rw-r--r-- | src/pubkey/dh/dh_core.h | 38 | ||||
-rw-r--r-- | src/pubkey/dh/dh_op.h | 45 | ||||
-rw-r--r-- | src/pubkey/dh/info.txt | 3 | ||||
-rw-r--r-- | src/pubkey/dlies/dlies.cpp | 45 | ||||
-rw-r--r-- | src/pubkey/dlies/dlies.h | 7 | ||||
-rw-r--r-- | src/pubkey/ecdh/ecdh.cpp | 21 | ||||
-rw-r--r-- | src/pubkey/ecdh/ecdh.h | 17 | ||||
-rw-r--r-- | src/pubkey/info.txt | 1 | ||||
-rw-r--r-- | src/pubkey/pk_keys.h | 2 | ||||
-rw-r--r-- | src/pubkey/pk_ops.h | 38 | ||||
-rw-r--r-- | src/pubkey/pubkey.cpp | 25 | ||||
-rw-r--r-- | src/pubkey/pubkey.h | 39 |
24 files changed, 265 insertions, 420 deletions
diff --git a/checks/ecdh.cpp b/checks/ecdh.cpp index d8f8e2fad..92b2f58e8 100644 --- a/checks/ecdh.cpp +++ b/checks/ecdh.cpp @@ -17,7 +17,7 @@ #include <iostream> #include <fstream> -#include <botan/symkey.h> +#include <botan/look_pk.h> #include <botan/ecdh.h> #include <botan/x509self.h> #include <botan/der_enc.h> @@ -33,50 +33,17 @@ void test_ecdh_normal_derivation(RandomNumberGenerator& rng) { std::cout << "." << std::flush; - /* - std::string p_secp = "ffffffffffffffffffffffffffffffff7fffffff"; - std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc"; - std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45"; - std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82"; - ::Botan::SecureVector<byte> sv_p_secp = decode_hex(p_secp); - ::Botan::SecureVector<byte> sv_a_secp = decode_hex(a_secp); - ::Botan::SecureVector<byte> sv_b_secp = decode_hex(b_secp); - ::Botan::SecureVector<byte> sv_G_secp_comp = decode_hex(G_secp_comp); - BigInt bi_p_secp = BigInt::decode(sv_p_secp.begin(), sv_p_secp.size()); - BigInt bi_a_secp = BigInt::decode(sv_a_secp.begin(), sv_a_secp.size()); - BigInt bi_b_secp = BigInt::decode(sv_b_secp.begin(), sv_b_secp.size()); - CurveGFp secp160r1(GFpElement(bi_p_secp,bi_a_secp), GFpElement(bi_p_secp, bi_b_secp), bi_p_secp); - */ - - std::string g_secp("024a96b5688ef573284664698968c38bb913cbfc82"); - Botan::SecureVector<Botan::byte> sv_g_secp = decode_hex(g_secp); - BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff"); - BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc"); - BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45"); - BigInt order = BigInt("0x0100000000000000000001f4c8f927aed3ca752257"); - CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp); - - BigInt cofactor = BigInt(1); - PointGFp p_G = OS2ECP ( sv_g_secp, curve ); - Botan::EC_Domain_Params dom_pars = Botan::EC_Domain_Params(curve, p_G, order, cofactor); - - /** - * begin ECDH - */ - // alices key (a key constructed by domain parameters IS an ephimeral key!) - Botan::ECDH_PrivateKey private_a(rng, dom_pars); - Botan::ECDH_PublicKey public_a = private_a; // Bob gets this - - // Bob creates a key with a matching group - Botan::ECDH_PrivateKey private_b(rng, dom_pars); //public_a.getCurve() - - // Bob sends the key back to Alice - Botan::ECDH_PublicKey public_b = private_b; // Alice gets this - - // Both of them create a key using their private key and the other's - // public key - Botan::SymmetricKey alice_key = private_a.derive_key(public_b); - Botan::SymmetricKey bob_key = private_b.derive_key(public_a); + EC_Domain_Params dom_pars(OID("1.3.132.0.8")); + + ECDH_PrivateKey private_a(rng, dom_pars); + + ECDH_PrivateKey private_b(rng, dom_pars); //public_a.getCurve() + + std::auto_ptr<PK_Key_Agreement> ka(get_pk_kas(private_a, "KDF2(SHA-1)")); + std::auto_ptr<PK_Key_Agreement> kb(get_pk_kas(private_b, "KDF2(SHA-1)")); + + SymmetricKey alice_key = ka->derive_key(32, private_b.public_value()); + SymmetricKey bob_key = kb->derive_key(32, private_a.public_value()); if(alice_key != bob_key) { @@ -93,34 +60,23 @@ void test_ecdh_some_dp(RandomNumberGenerator& rng) oids.push_back("1.3.132.0.8"); oids.push_back("1.2.840.10045.3.1.1"); - for(Botan::u32bit i = 0; i< oids.size(); i++) + for(u32bit i = 0; i< oids.size(); i++) { std::cout << "." << std::flush; - Botan::OID oid(oids[i]); - Botan::EC_Domain_Params dom_pars(oid); - Botan::ECDH_PrivateKey private_a(rng, dom_pars); - Botan::ECDH_PublicKey public_a = private_a; - /*auto_ptr<Botan::X509_Encoder> x509_key_enc = public_a.x509_encoder(); - Botan::MemoryVector<Botan::byte> enc_key_a = Botan::DER_Encoder() - .start_cons(Botan::SEQUENCE) - .encode(x509_key_enc->alg_id()) - .encode(x509_key_enc->key_bits(), Botan::BIT_STRING) - .end_cons() - .get_contents();*/ + OID oid(oids[i]); + EC_Domain_Params dom_pars(oid); - Botan::ECDH_PrivateKey private_b(rng, dom_pars); - Botan::ECDH_PublicKey public_b = private_b; - // to test the equivalence, we - // use the direct derivation method here + ECDH_PrivateKey private_a(rng, dom_pars); + ECDH_PrivateKey private_b(rng, dom_pars); - Botan::SymmetricKey alice_key = private_a.derive_key(public_b); + std::auto_ptr<PK_Key_Agreement> ka(get_pk_kas(private_a, "KDF2(SHA-1)")); + std::auto_ptr<PK_Key_Agreement> kb(get_pk_kas(private_b, "KDF2(SHA-1)")); - //cout << "encoded key = " << hex_encode(enc_key_a.begin(), enc_key_a.size()) << endl; + SymmetricKey alice_key = ka->derive_key(32, private_b.public_value()); + SymmetricKey bob_key = kb->derive_key(32, private_a.public_value()); - Botan::SymmetricKey bob_key = private_b.derive_key(public_a); CHECK_MESSAGE(alice_key == bob_key, "different keys - " << "Alice's key was: " << alice_key.as_string() << ", Bob's key was: " << bob_key.as_string()); - //cout << "key: " << alice_key.as_string() << endl; } } @@ -132,88 +88,37 @@ void test_ecdh_der_derivation(RandomNumberGenerator& rng) oids.push_back("1.3.132.0.8"); oids.push_back("1.2.840.10045.3.1.1"); - for(Botan::u32bit i = 0; i< oids.size(); i++) + for(u32bit i = 0; i< oids.size(); i++) { - Botan::OID oid(oids[i]); - Botan::EC_Domain_Params dom_pars(oid); + OID oid(oids[i]); + EC_Domain_Params dom_pars(oid); + + ECDH_PrivateKey private_a(rng, dom_pars); + ECDH_PrivateKey private_b(rng, dom_pars); + + MemoryVector<byte> key_a = private_a.public_value(); + MemoryVector<byte> key_b = private_b.public_value(); - Botan::ECDH_PrivateKey private_a(rng, dom_pars); - Botan::ECDH_PublicKey public_a = private_a; + std::auto_ptr<PK_Key_Agreement> ka(get_pk_kas(private_a, "KDF2(SHA-1)")); + std::auto_ptr<PK_Key_Agreement> kb(get_pk_kas(private_b, "KDF2(SHA-1)")); - Botan::ECDH_PrivateKey private_b(rng, dom_pars); - Botan::ECDH_PublicKey public_b = private_b; + SymmetricKey alice_key = ka->derive_key(32, key_b); + SymmetricKey bob_key = kb->derive_key(32, key_a); - Botan::MemoryVector<Botan::byte> key_der_a = private_a.public_value(); - Botan::MemoryVector<Botan::byte> key_der_b = private_b.public_value(); - Botan::SymmetricKey alice_key = private_a.derive_key(key_der_b.begin(), key_der_b.size()); - Botan::SymmetricKey bob_key = private_b.derive_key(key_der_a.begin(), key_der_a.size()); CHECK_MESSAGE(alice_key == bob_key, "different keys - " << "Alice's key was: " << alice_key.as_string() << ", Bob's key was: " << bob_key.as_string()); //cout << "key: " << alice_key.as_string() << endl; } } -/** -* The following test tests the copy ctors and and copy-assignment operators -*/ -void test_ecdh_cp_ctor_as_op(RandomNumberGenerator& rng) - { - std::cout << "." << std::flush; - - std::string g_secp("024a96b5688ef573284664698968c38bb913cbfc82"); - Botan::SecureVector<Botan::byte> sv_g_secp = decode_hex(g_secp); - BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff"); - BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc"); - BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45"); - BigInt order = BigInt("0x0100000000000000000001f4c8f927aed3ca752257"); - CurveGFp curve(bi_p_secp, bi_a_secp, bi_b_secp); - BigInt cofactor = BigInt(1); - PointGFp p_G = OS2ECP ( sv_g_secp, curve ); - Botan::EC_Domain_Params dom_pars = Botan::EC_Domain_Params(curve, p_G, order, cofactor); - - /** - * begin ECDH - */ - // alices key (a key constructed by domain parameters IS an ephimeral key!) - Botan::ECDH_PrivateKey private_a(rng, dom_pars); - Botan::ECDH_PrivateKey private_a2(private_a); - Botan::ECDH_PrivateKey private_a3 = private_a2; - - Botan::ECDH_PublicKey public_a = private_a; // Bob gets this - Botan::ECDH_PublicKey public_a2(public_a); - Botan::ECDH_PublicKey public_a3 = public_a; - // Bob creates a key with a matching group - Botan::ECDH_PrivateKey private_b(rng, dom_pars); //public_a.getCurve() - - // Bob sends the key back to Alice - Botan::ECDH_PublicKey public_b = private_b; // Alice gets this - - // Both of them create a key using their private key and the other's - // public key - Botan::SymmetricKey alice_key = private_a.derive_key(public_b); - Botan::SymmetricKey alice_key_2 = private_a2.derive_key(public_b); - Botan::SymmetricKey alice_key_3 = private_a3.derive_key(public_b); - - Botan::SymmetricKey bob_key = private_b.derive_key(public_a); - Botan::SymmetricKey bob_key_2 = private_b.derive_key(public_a2); - Botan::SymmetricKey bob_key_3 = private_b.derive_key(public_a3); - - CHECK_MESSAGE(alice_key == bob_key, "different keys - " << "Alice's key was: " << alice_key.as_string() << ", Bob's key was: " << bob_key.as_string()); - CHECK_MESSAGE(alice_key_2 == bob_key_2, "different keys - " << "Alice's key was: " << alice_key.as_string() << ", Bob's key was: " << bob_key.as_string()); - CHECK_MESSAGE(alice_key_3 == bob_key_3, "different keys - " << "Alice's key was: " << alice_key.as_string() << ", Bob's key was: " << bob_key.as_string()); - CHECK_MESSAGE(alice_key == bob_key_2, "different keys - " << "Alice's key was: " << alice_key.as_string() << ", Bob's key was: " << bob_key.as_string()); - CHECK_MESSAGE(alice_key_2 == bob_key_3, "different keys - " << "Alice's key was: " << alice_key.as_string() << ", Bob's key was: " << bob_key.as_string()); - } - } -u32bit do_ecdh_tests(Botan::RandomNumberGenerator& rng) +u32bit do_ecdh_tests(RandomNumberGenerator& rng) { std::cout << "Testing ECDH (InSiTo unit tests): "; test_ecdh_normal_derivation(rng); test_ecdh_some_dp(rng); test_ecdh_der_derivation(rng); - test_ecdh_cp_ctor_as_op(rng); std::cout << std::endl; @@ -221,5 +126,5 @@ u32bit do_ecdh_tests(Botan::RandomNumberGenerator& rng) } #else -u32bit do_ecdh_tests(Botan::RandomNumberGenerator&) { return 0; } +u32bit do_ecdh_tests(RandomNumberGenerator&) { return 0; } #endif diff --git a/checks/pk_bench.cpp b/checks/pk_bench.cpp index 395ddc3ce..56df89eb3 100644 --- a/checks/pk_bench.cpp +++ b/checks/pk_bench.cpp @@ -435,10 +435,10 @@ void benchmark_ecdh(RandomNumberGenerator& rng, ECDH_PrivateKey ecdh2(rng, params); keygen_timer.stop(); - ECDH_PublicKey pub1(ecdh1); - ECDH_PublicKey pub2(ecdh2); + std::auto_ptr<PK_Key_Agreement> ka1(get_pk_kas(ecdh1, "KDF2(SHA-1)")); + std::auto_ptr<PK_Key_Agreement> ka2(get_pk_kas(ecdh2, "KDF2(SHA-1)")); - SecureVector<byte> secret1, secret2; + SymmetricKey secret1, secret2; for(u32bit i = 0; i != 1000; ++i) { @@ -446,15 +446,15 @@ void benchmark_ecdh(RandomNumberGenerator& rng, break; kex_timer.start(); - secret1 = ecdh1.derive_key(pub2); + secret1 = ka1->derive_key(32, ecdh2.public_value()); kex_timer.stop(); kex_timer.start(); - secret2 = ecdh2.derive_key(pub1); + secret2 = ka2->derive_key(32, ecdh1.public_value()); kex_timer.stop(); if(secret1 != secret2) - std::cerr << "ECDH secrets did not match, bug in the library!?!\n"; + std::cerr << "ECDH secrets did not match\n"; } } @@ -567,7 +567,7 @@ void benchmark_dh(RandomNumberGenerator& rng, kex_timer.stop(); if(secret1 != secret2) - std::cerr << "DH secrets did not match, bug in the library!?!\n"; + std::cerr << "DH secrets did not match\n"; } } diff --git a/doc/log.txt b/doc/log.txt index e515980da..b2ce2d6a2 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -11,6 +11,7 @@ - Add a block cipher cascade construction - Add support for password hashing for authentication (passhash9.h) - Add support for Win32 high resolution system timers + - Major refactoring and API changes in the public key code - Changed S2K interface: derive_key now takes salt, iteration count - Remove dependency on TR1 for ECC and CVC code - Renamed ECKAEG to its more usual name, ECDH diff --git a/src/engine/def_engine/def_pk_ops.cpp b/src/engine/def_engine/def_pk_ops.cpp index e1040142e..b2f53376d 100644 --- a/src/engine/def_engine/def_pk_ops.cpp +++ b/src/engine/def_engine/def_pk_ops.cpp @@ -24,11 +24,31 @@ #endif #if defined(BOTAN_HAS_DIFFIE_HELLMAN) - #include <botan/dh_op.h> + #include <botan/dh.h> +#endif + +#if defined(BOTAN_HAS_ECDH) + #include <botan/ecdh.h> #endif namespace Botan { +PK_Ops::KA_Operation* +Default_Engine::get_key_agreement_op(const Private_Key& key) const + { +#if defined(BOTAN_HAS_DIFFIE_HELLMAN) + if(const DH_PrivateKey* dh = dynamic_cast<const DH_PrivateKey*>(&key)) + return new DH_KA_Operation(*dh); +#endif + +#if defined(BOTAN_HAS_ECDH) + if(const ECDH_PrivateKey* ecdh = dynamic_cast<const ECDH_PrivateKey*>(&key)) + return new ECDH_KA_Operation(*ecdh); +#endif + + return 0; + } + #if defined(BOTAN_HAS_IF_PUBLIC_KEY_FAMILY) /* * Acquire an IF op @@ -75,15 +95,4 @@ ELG_Operation* Default_Engine::elg_op(const DL_Group& group, const BigInt& y, } #endif -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) -/* -* Acquire a DH op -*/ -DH_Operation* Default_Engine::dh_op(const DL_Group& group, - const BigInt& x) const - { - return new Default_DH_Op(group, x); - } -#endif - } diff --git a/src/engine/def_engine/default_engine.h b/src/engine/def_engine/default_engine.h index aa753fadb..918a42114 100644 --- a/src/engine/def_engine/default_engine.h +++ b/src/engine/def_engine/default_engine.h @@ -20,6 +20,8 @@ class Default_Engine : public Engine public: std::string provider_name() const { return "core"; } + PK_Ops::KA_Operation* get_key_agreement_op(const Private_Key&) const; + #if defined(BOTAN_HAS_IF_PUBLIC_KEY_FAMILY) IF_Operation* if_op(const BigInt&, const BigInt&, const BigInt&, const BigInt&, const BigInt&, const BigInt&, @@ -40,10 +42,6 @@ class Default_Engine : public Engine const BigInt&) const; #endif -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) - DH_Operation* dh_op(const DL_Group&, const BigInt&) const; -#endif - Modular_Exponentiator* mod_exp(const BigInt&, Power_Mod::Usage_Hints) const; diff --git a/src/engine/engine.h b/src/engine/engine.h index ba5f95c27..ea9c05997 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -15,6 +15,8 @@ #include <botan/hash.h> #include <botan/mac.h> #include <botan/pow_mod.h> +#include <botan/pk_keys.h> +#include <botan/pk_ops.h> #include <utility> #include <map> @@ -27,10 +29,6 @@ #include <botan/dsa_op.h> #endif -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) - #include <botan/dh_op.h> -#endif - #if defined(BOTAN_HAS_NYBERG_RUEPPEL) #include <botan/nr_op.h> #endif @@ -80,6 +78,12 @@ class BOTAN_DLL Engine Algorithm_Factory&) { return 0; } + virtual PK_Ops::KA_Operation* + get_key_agreement_op(const Private_Key&) const + { + return 0; + } + #if defined(BOTAN_HAS_IF_PUBLIC_KEY_FAMILY) virtual IF_Operation* if_op(const BigInt&, const BigInt&, const BigInt&, const BigInt&, const BigInt&, const BigInt&, @@ -104,11 +108,6 @@ class BOTAN_DLL Engine const BigInt&) const { return 0; } #endif - -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) - virtual DH_Operation* dh_op(const DL_Group&, const BigInt&) const - { return 0; } -#endif }; } diff --git a/src/engine/info.txt b/src/engine/info.txt index b270edaa5..32fcf21c2 100644 --- a/src/engine/info.txt +++ b/src/engine/info.txt @@ -10,5 +10,6 @@ hash libstate mac numbertheory +pubkey stream </requires> diff --git a/src/libstate/pk_engine.cpp b/src/libstate/pk_engine.cpp index ac2fa68b0..51aaa073e 100644 --- a/src/libstate/pk_engine.cpp +++ b/src/libstate/pk_engine.cpp @@ -91,25 +91,6 @@ ELG_Operation* elg_op(const DL_Group& group, const BigInt& y, const BigInt& x) } #endif -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) -/* -* Acquire a DH op -*/ -DH_Operation* dh_op(const DL_Group& group, const BigInt& x) - { - Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); - - while(const Engine* engine = i.next()) - { - DH_Operation* op = engine->dh_op(group, x); - if(op) - return op; - } - - throw Lookup_Error("Engine_Core::dh_op: Unable to find a working engine"); - } -#endif - /* * Acquire a modular exponentiator */ diff --git a/src/libstate/pk_engine.h b/src/libstate/pk_engine.h index 25f326ef0..e6399058e 100644 --- a/src/libstate/pk_engine.h +++ b/src/libstate/pk_engine.h @@ -19,10 +19,6 @@ #include <botan/dsa_op.h> #endif -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) - #include <botan/dh_op.h> -#endif - #if defined(BOTAN_HAS_NYBERG_RUEPPEL) #include <botan/nr_op.h> #endif @@ -62,10 +58,6 @@ NR_Operation* nr_op(const DL_Group&, const BigInt&, const BigInt&); ELG_Operation* elg_op(const DL_Group&, const BigInt&, const BigInt&); #endif -#if defined(BOTAN_HAS_DIFFIE_HELLMAN) -DH_Operation* dh_op(const DL_Group&, const BigInt&); -#endif - } } diff --git a/src/pubkey/dh/dh.cpp b/src/pubkey/dh/dh.cpp index 4ebe1fa1c..70791fee4 100644 --- a/src/pubkey/dh/dh.cpp +++ b/src/pubkey/dh/dh.cpp @@ -21,14 +21,6 @@ DH_PublicKey::DH_PublicKey(const DL_Group& grp, const BigInt& y1) } /* -* Return the maximum input size in bits -*/ -u32bit DH_PublicKey::max_input_bits() const - { - return group_p().bits(); - } - -/* * Return the public value for key agreement */ MemoryVector<byte> DH_PublicKey::public_value() const @@ -55,8 +47,6 @@ DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng, if(y == 0) y = power_mod(group_g(), x, group_p()); - core = DH_Core(rng, group, x); - if(x == 0) gen_check(rng); else @@ -74,8 +64,6 @@ DH_PrivateKey::DH_PrivateKey(const AlgorithmIdentifier& alg_id, if(y == 0) y = power_mod(group_g(), x, group_p()); - core = DH_Core(rng, group, x); - load_check(rng); } @@ -87,32 +75,4 @@ MemoryVector<byte> DH_PrivateKey::public_value() const return DH_PublicKey::public_value(); } -/* -* Derive a key -*/ -SecureVector<byte> DH_PrivateKey::derive_key(const byte w[], - u32bit w_len) const - { - return derive_key(BigInt::decode(w, w_len)); - } - -/* -* Derive a key -*/ -SecureVector<byte> DH_PrivateKey::derive_key(const DH_PublicKey& key) const - { - return derive_key(key.get_y()); - } - -/* -* Derive a key -*/ -SecureVector<byte> DH_PrivateKey::derive_key(const BigInt& w) const - { - const BigInt& p = group_p(); - if(w <= 1 || w >= p-1) - throw Invalid_Argument(algo_name() + "::derive_key: Invalid key input"); - return BigInt::encode_1363(core.agree(w), p.bytes()); - } - } diff --git a/src/pubkey/dh/dh.h b/src/pubkey/dh/dh.h index 14bc916a7..318a6215c 100644 --- a/src/pubkey/dh/dh.h +++ b/src/pubkey/dh/dh.h @@ -9,7 +9,8 @@ #define BOTAN_DIFFIE_HELLMAN_H__ #include <botan/dl_algo.h> -#include <botan/dh_core.h> +#include <botan/pow_mod.h> +#include <botan/pk_ops.h> namespace Botan { @@ -22,7 +23,7 @@ class BOTAN_DLL DH_PublicKey : public virtual DL_Scheme_PublicKey std::string algo_name() const { return "DH"; } MemoryVector<byte> public_value() const; - u32bit max_input_bits() const; + u32bit max_input_bits() const { return group_p().bits(); } DL_Group::Format group_format() const { return DL_Group::ANSI_X9_42; } @@ -48,10 +49,6 @@ class BOTAN_DLL DH_PrivateKey : public DH_PublicKey, public virtual DL_Scheme_PrivateKey { public: - SecureVector<byte> derive_key(const byte other[], u32bit length) const; - SecureVector<byte> derive_key(const DH_PublicKey& other) const; - SecureVector<byte> derive_key(const BigInt& other) const; - MemoryVector<byte> public_value() const; /** @@ -72,8 +69,30 @@ class BOTAN_DLL DH_PrivateKey : public DH_PublicKey, */ DH_PrivateKey(RandomNumberGenerator& rng, const DL_Group& grp, const BigInt& x = 0); + }; + +/** +* DH operation +*/ +class BOTAN_DLL DH_KA_Operation : public PK_Ops::KA_Operation + { + public: + + DH_KA_Operation(const DH_PrivateKey& key) : + powermod_x_p(key.get_x(), key.get_domain().get_p()), + p_bytes(key.get_domain().get_p().bytes()) + {} + + SecureVector<byte> agree(const byte w[], u32bit w_len) const + { + return BigInt::encode_1363( + powermod_x_p(BigInt::decode(w, w_len)), + p_bytes); + } + private: - DH_Core core; + Fixed_Exponent_Power_Mod powermod_x_p; + u32bit p_bytes; }; } diff --git a/src/pubkey/dh/dh_core.cpp b/src/pubkey/dh/dh_core.cpp deleted file mode 100644 index cbe2dc9f1..000000000 --- a/src/pubkey/dh/dh_core.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* -* PK Algorithm Core -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/dh_core.h> -#include <botan/numthry.h> -#include <botan/internal/pk_engine.h> -#include <botan/parsing.h> -#include <algorithm> - -namespace Botan { - -/* -* DH_Core Constructor -*/ -DH_Core::DH_Core(RandomNumberGenerator& rng, - const DL_Group& group, const BigInt& x) - { - const u32bit BLINDING_BITS = BOTAN_PRIVATE_KEY_OP_BLINDING_BITS; - - op = Engine_Core::dh_op(group, x); - - const BigInt& p = group.get_p(); - - BigInt k(rng, std::min(p.bits()-1, BLINDING_BITS)); - - if(k != 0) - blinder = Blinder(k, power_mod(inverse_mod(k, p), x, p), p); - } - -/* -* DH_Core Copy Constructor -*/ -DH_Core::DH_Core(const DH_Core& core) - { - op = 0; - if(core.op) - op = core.op->clone(); - blinder = core.blinder; - } - -/* -* DH_Core Assignment Operator -*/ -DH_Core& DH_Core::operator=(const DH_Core& core) - { - delete op; - if(core.op) - op = core.op->clone(); - blinder = core.blinder; - return (*this); - } - -/* -* DH Operation -*/ -BigInt DH_Core::agree(const BigInt& i) const - { - return blinder.unblind(op->agree(blinder.blind(i))); - } - -} diff --git a/src/pubkey/dh/dh_core.h b/src/pubkey/dh/dh_core.h deleted file mode 100644 index 91b50a27a..000000000 --- a/src/pubkey/dh/dh_core.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -* DH Core -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_DH_CORE_H__ -#define BOTAN_DH_CORE_H__ - -#include <botan/dh_op.h> -#include <botan/blinding.h> - -namespace Botan { - -/* -* DH Core -*/ -class BOTAN_DLL DH_Core - { - public: - BigInt agree(const BigInt&) const; - - DH_Core& operator=(const DH_Core&); - - DH_Core() { op = 0; } - DH_Core(const DH_Core&); - DH_Core(RandomNumberGenerator& rng, - const DL_Group&, const BigInt&); - ~DH_Core() { delete op; } - private: - DH_Operation* op; - Blinder blinder; - }; - -} - -#endif diff --git a/src/pubkey/dh/dh_op.h b/src/pubkey/dh/dh_op.h deleted file mode 100644 index 50f3d7825..000000000 --- a/src/pubkey/dh/dh_op.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -* DH Operations -* (C) 1999-2008 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_DH_OPS_H__ -#define BOTAN_DH_OPS_H__ - -#include <botan/dl_group.h> -#include <botan/reducer.h> -#include <botan/pow_mod.h> - -namespace Botan { - -/* -* DH Operation Interface -*/ -class BOTAN_DLL DH_Operation - { - public: - virtual BigInt agree(const BigInt&) const = 0; - virtual DH_Operation* clone() const = 0; - virtual ~DH_Operation() {} - }; - -/* -* Botan's Default DH Operation -*/ -class BOTAN_DLL Default_DH_Op : public DH_Operation - { - public: - BigInt agree(const BigInt& i) const { return powermod_x_p(i); } - DH_Operation* clone() const { return new Default_DH_Op(*this); } - - Default_DH_Op(const DL_Group& group, const BigInt& x) : - powermod_x_p(x, group.get_p()) {} - private: - Fixed_Exponent_Power_Mod powermod_x_p; - }; - -} - -#endif diff --git a/src/pubkey/dh/info.txt b/src/pubkey/dh/info.txt index ca8f74fa1..e1e460cd0 100644 --- a/src/pubkey/dh/info.txt +++ b/src/pubkey/dh/info.txt @@ -1,14 +1,11 @@ define DIFFIE_HELLMAN <header:public> -dh_core.h -dh_op.h dh.h </header:public> <source> dh.cpp -dh_core.cpp </source> <requires> diff --git a/src/pubkey/dlies/dlies.cpp b/src/pubkey/dlies/dlies.cpp index 6ef3292e1..2253f84d5 100644 --- a/src/pubkey/dlies/dlies.cpp +++ b/src/pubkey/dlies/dlies.cpp @@ -14,16 +14,21 @@ namespace Botan { /* * DLIES_Encryptor Constructor */ -DLIES_Encryptor::DLIES_Encryptor(const PK_Key_Agreement_Key& k, +DLIES_Encryptor::DLIES_Encryptor(const PK_Key_Agreement_Key& key, KDF* kdf_obj, MessageAuthenticationCode* mac_obj, u32bit mac_kl) : - key(k), kdf(kdf_obj), mac(mac_obj), mac_keylen(mac_kl) + ka(get_pk_kas(key, "Raw")), + kdf(kdf_obj), + mac(mac_obj), + mac_keylen(mac_kl) { + my_key = key.public_value(); } DLIES_Encryptor::~DLIES_Encryptor() { + delete ka; delete kdf; delete mac; } @@ -39,19 +44,18 @@ SecureVector<byte> DLIES_Encryptor::enc(const byte in[], u32bit length, if(other_key.empty()) throw Invalid_State("DLIES: The other key was never set"); - MemoryVector<byte> v = key.public_value(); + SecureVector<byte> out(my_key.size() + length + mac->OUTPUT_LENGTH); + out.copy(my_key, my_key.size()); + out.copy(my_key.size(), in, length); - SecureVector<byte> out(v.size() + length + mac->OUTPUT_LENGTH); - out.copy(v, v.size()); - out.copy(v.size(), in, length); - - SecureVector<byte> vz(v, key.derive_key(other_key, other_key.size())); + SecureVector<byte> vz(my_key, ka->derive_key(0, other_key).bits_of()); const u32bit K_LENGTH = length + mac_keylen; OctetString K = kdf->derive_key(K_LENGTH, vz, vz.size()); + if(K.length() != K_LENGTH) throw Encoding_Error("DLIES: KDF did not provide sufficient output"); - byte* C = out + v.size(); + byte* C = out + my_key.size(); xor_buf(C, K.begin() + mac_keylen, length); mac->set_key(K.begin(), mac_keylen); @@ -84,16 +88,21 @@ u32bit DLIES_Encryptor::maximum_input_size() const /* * DLIES_Decryptor Constructor */ -DLIES_Decryptor::DLIES_Decryptor(const PK_Key_Agreement_Key& k, +DLIES_Decryptor::DLIES_Decryptor(const PK_Key_Agreement_Key& key, KDF* kdf_obj, MessageAuthenticationCode* mac_obj, u32bit mac_kl) : - key(k), kdf(kdf_obj), mac(mac_obj), mac_keylen(mac_kl) + ka(get_pk_kas(key, "Raw")), + kdf(kdf_obj), + mac(mac_obj), + mac_keylen(mac_kl) { + my_key = key.public_value(); } DLIES_Decryptor::~DLIES_Decryptor() { + delete ka; delete kdf; delete mac; } @@ -103,18 +112,16 @@ DLIES_Decryptor::~DLIES_Decryptor() */ SecureVector<byte> DLIES_Decryptor::dec(const byte msg[], u32bit length) const { - const u32bit public_len = key.public_value().size(); - - if(length < public_len + mac->OUTPUT_LENGTH) + if(length < my_key.size() + mac->OUTPUT_LENGTH) throw Decoding_Error("DLIES decryption: ciphertext is too short"); - const u32bit CIPHER_LEN = length - public_len - mac->OUTPUT_LENGTH; + const u32bit CIPHER_LEN = length - my_key.size() - mac->OUTPUT_LENGTH; - SecureVector<byte> v(msg, public_len); - SecureVector<byte> C(msg + public_len, CIPHER_LEN); - SecureVector<byte> T(msg + public_len + CIPHER_LEN, mac->OUTPUT_LENGTH); + SecureVector<byte> v(msg, my_key.size()); + SecureVector<byte> C(msg + my_key.size(), CIPHER_LEN); + SecureVector<byte> T(msg + my_key.size() + CIPHER_LEN, mac->OUTPUT_LENGTH); - SecureVector<byte> vz(v, key.derive_key(v, v.size())); + SecureVector<byte> vz(v, ka->derive_key(0, v).bits_of()); const u32bit K_LENGTH = C.size() + mac_keylen; OctetString K = kdf->derive_key(K_LENGTH, vz, vz.size()); diff --git a/src/pubkey/dlies/dlies.h b/src/pubkey/dlies/dlies.h index 88a22b9de..e8b87a091 100644 --- a/src/pubkey/dlies/dlies.h +++ b/src/pubkey/dlies/dlies.h @@ -33,9 +33,9 @@ class BOTAN_DLL DLIES_Encryptor : public PK_Encryptor RandomNumberGenerator&) const; u32bit maximum_input_size() const; - const PK_Key_Agreement_Key& key; - SecureVector<byte> other_key; + SecureVector<byte> other_key, my_key; + PK_Key_Agreement* ka; KDF* kdf; MessageAuthenticationCode* mac; u32bit mac_keylen; @@ -57,8 +57,9 @@ class BOTAN_DLL DLIES_Decryptor : public PK_Decryptor private: SecureVector<byte> dec(const byte[], u32bit) const; - const PK_Key_Agreement_Key& key; + SecureVector<byte> my_key; + PK_Key_Agreement* ka; KDF* kdf; MessageAuthenticationCode* mac; u32bit mac_keylen; diff --git a/src/pubkey/ecdh/ecdh.cpp b/src/pubkey/ecdh/ecdh.cpp index 7ecc40ae4..37dc7c392 100644 --- a/src/pubkey/ecdh/ecdh.cpp +++ b/src/pubkey/ecdh/ecdh.cpp @@ -11,6 +11,27 @@ namespace Botan { +ECDH_KA_Operation::ECDH_KA_Operation(const ECDH_PrivateKey& key) + { + cofactor = key.domain().get_cofactor(); + + curve = key.domain().get_curve(); + + l_times_priv = inverse_mod(cofactor, key.domain().get_order()) * + key.private_value(); + } + +SecureVector<byte> ECDH_KA_Operation::agree(const byte w[], u32bit w_len) const + { + PointGFp point = OS2ECP(w, w_len, curve); + + PointGFp S = (cofactor * point) * l_times_priv; + S.check_invariants(); + + return BigInt::encode_1363(S.get_affine_x(), + curve.get_p().bytes()); + } + /** * Derive a key */ diff --git a/src/pubkey/ecdh/ecdh.h b/src/pubkey/ecdh/ecdh.h index 8185e25f2..ad7efdc13 100644 --- a/src/pubkey/ecdh/ecdh.h +++ b/src/pubkey/ecdh/ecdh.h @@ -11,6 +11,7 @@ #define BOTAN_ECDH_KEY_H__ #include <botan/ecc_key.h> +#include <botan/pk_ops.h> namespace Botan { @@ -75,7 +76,7 @@ class BOTAN_DLL ECDH_PrivateKey : public ECDH_PublicKey, MemoryVector<byte> public_value() const { return EC2OSP(public_point(), PointGFp::UNCOMPRESSED); } - + private: /** * Derive a shared key with the other parties public key. * @param key the other partys public key @@ -96,6 +97,20 @@ class BOTAN_DLL ECDH_PrivateKey : public ECDH_PublicKey, SecureVector<byte> derive_key(const PointGFp& point) const; }; +/** +* ECDH operation +*/ +class BOTAN_DLL ECDH_KA_Operation : public PK_Ops::KA_Operation + { + public: + ECDH_KA_Operation(const ECDH_PrivateKey& key); + + SecureVector<byte> agree(const byte w[], u32bit w_len) const; + private: + CurveGFp curve; + BigInt l_times_priv, cofactor; + }; + } #endif diff --git a/src/pubkey/info.txt b/src/pubkey/info.txt index 4d7105e9d..01378b856 100644 --- a/src/pubkey/info.txt +++ b/src/pubkey/info.txt @@ -12,6 +12,7 @@ x509_key.cpp <header:public> pk_keys.h +pk_ops.h pkcs8.h pubkey.h pubkey_enums.h diff --git a/src/pubkey/pk_keys.h b/src/pubkey/pk_keys.h index 8015c1076..c37ce46a5 100644 --- a/src/pubkey/pk_keys.h +++ b/src/pubkey/pk_keys.h @@ -158,8 +158,8 @@ class BOTAN_DLL PK_Verifying_wo_MR_Key : public virtual Public_Key class BOTAN_DLL PK_Key_Agreement_Key : public virtual Private_Key { public: - virtual SecureVector<byte> derive_key(const byte[], u32bit) const = 0; virtual MemoryVector<byte> public_value() const = 0; + virtual ~PK_Key_Agreement_Key() {} }; diff --git a/src/pubkey/pk_ops.h b/src/pubkey/pk_ops.h new file mode 100644 index 000000000..2b9ac4366 --- /dev/null +++ b/src/pubkey/pk_ops.h @@ -0,0 +1,38 @@ +/* +* PK Operation Types +* (C) 2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PK_OPERATIONS_H__ +#define BOTAN_PK_OPERATIONS_H__ + +#include <botan/secmem.h> + +namespace Botan { + +namespace PK_Ops { + +/* +* A generic Key Agreement Operation (eg DH or ECDH) +*/ +class BOTAN_DLL KA_Operation + { + public: + /* + * Perform a key agreement operation + * @param w the other key value + * @param w_len the length of w in bytes + * @returns the agreed key + */ + virtual SecureVector<byte> agree(const byte w[], u32bit w_len) const = 0; + + virtual ~KA_Operation() {} + }; + +} + +} + +#endif diff --git a/src/pubkey/pubkey.cpp b/src/pubkey/pubkey.cpp index feb33a361..6932caa34 100644 --- a/src/pubkey/pubkey.cpp +++ b/src/pubkey/pubkey.cpp @@ -1,6 +1,6 @@ /* * Public Key Base -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -10,6 +10,8 @@ #include <botan/ber_dec.h> #include <botan/bigint.h> #include <botan/parsing.h> +#include <botan/libstate.h> +#include <botan/engine.h> #include <botan/internal/bit_ops.h> #include <memory> @@ -356,21 +358,34 @@ bool PK_Verifier_wo_MR::validate_signature(const MemoryRegion<byte>& msg, /* * PK_Key_Agreement Constructor */ -PK_Key_Agreement::PK_Key_Agreement(const PK_Key_Agreement_Key& k, +PK_Key_Agreement::PK_Key_Agreement(const PK_Key_Agreement_Key& key, KDF* kdf_obj) : - key(k), kdf(kdf_obj) + kdf(kdf_obj) { + Algorithm_Factory::Engine_Iterator i(global_state().algorithm_factory()); + + while(const Engine* engine = i.next()) + { + op = engine->get_key_agreement_op(key); + if(op) + break; + } + + if(op == 0) + throw Lookup_Error("PK_Key_Agreement: No working engine for " + + key.algo_name()); } SymmetricKey PK_Key_Agreement::derive_key(u32bit key_len, const byte in[], u32bit in_len, const byte params[], u32bit params_len) const { - OctetString z = key.derive_key(in, in_len); + SecureVector<byte> z = op->agree(in, in_len); + if(!kdf) return z; - return kdf->derive_key(key_len, z.bits_of(), params, params_len); + return kdf->derive_key(key_len, z, params, params_len); } } diff --git a/src/pubkey/pubkey.h b/src/pubkey/pubkey.h index 6d48faa4f..4d6490919 100644 --- a/src/pubkey/pubkey.h +++ b/src/pubkey/pubkey.h @@ -1,6 +1,6 @@ /* * Public Key Interface -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -9,6 +9,7 @@ #define BOTAN_PUBKEY_H__ #include <botan/pk_keys.h> +#include <botan/pk_ops.h> #include <botan/symkey.h> #include <botan/rng.h> #include <botan/eme.h> @@ -284,6 +285,23 @@ class BOTAN_DLL PK_Key_Agreement * @param in the other parties key * @param in_len the length of in in bytes * @param params extra derivation params + * @param params_len the length of params in bytes + */ + SymmetricKey derive_key(u32bit key_len, + const MemoryRegion<byte>& in, + const byte params[], + u32bit params_len) const + { + return derive_key(key_len, &in[0], in.size(), + params, params_len); + } + + /* + * Perform Key Agreement Operation + * @param key_len the desired key output size + * @param in the other parties key + * @param in_len the length of in in bytes + * @param params extra derivation params */ SymmetricKey derive_key(u32bit key_len, const byte in[], u32bit in_len, @@ -294,6 +312,21 @@ class BOTAN_DLL PK_Key_Agreement params.length()); } + /* + * Perform Key Agreement Operation + * @param key_len the desired key output size + * @param in the other parties key + * @param params extra derivation params + */ + SymmetricKey derive_key(u32bit key_len, + const MemoryRegion<byte>& in, + const std::string& params = "") const + { + return derive_key(key_len, &in[0], in.size(), + reinterpret_cast<const byte*>(params.data()), + params.length()); + } + /** * Construct a PK Key Agreement. * @param key the key to use @@ -301,12 +334,12 @@ class BOTAN_DLL PK_Key_Agreement */ PK_Key_Agreement(const PK_Key_Agreement_Key& key, KDF* kdf = 0); - ~PK_Key_Agreement() { delete kdf; } + ~PK_Key_Agreement() { delete op; delete kdf; } private: PK_Key_Agreement(const PK_Key_Agreement_Key&); PK_Key_Agreement& operator=(const PK_Key_Agreement&); - const PK_Key_Agreement_Key& key; + PK_Ops::KA_Operation* op; KDF* kdf; }; |