aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--checks/ecdh.cpp167
-rw-r--r--checks/pk_bench.cpp14
-rw-r--r--doc/log.txt1
-rw-r--r--src/engine/def_engine/def_pk_ops.cpp33
-rw-r--r--src/engine/def_engine/default_engine.h6
-rw-r--r--src/engine/engine.h17
-rw-r--r--src/engine/info.txt1
-rw-r--r--src/libstate/pk_engine.cpp19
-rw-r--r--src/libstate/pk_engine.h8
-rw-r--r--src/pubkey/dh/dh.cpp40
-rw-r--r--src/pubkey/dh/dh.h33
-rw-r--r--src/pubkey/dh/dh_core.cpp65
-rw-r--r--src/pubkey/dh/dh_core.h38
-rw-r--r--src/pubkey/dh/dh_op.h45
-rw-r--r--src/pubkey/dh/info.txt3
-rw-r--r--src/pubkey/dlies/dlies.cpp45
-rw-r--r--src/pubkey/dlies/dlies.h7
-rw-r--r--src/pubkey/ecdh/ecdh.cpp21
-rw-r--r--src/pubkey/ecdh/ecdh.h17
-rw-r--r--src/pubkey/info.txt1
-rw-r--r--src/pubkey/pk_keys.h2
-rw-r--r--src/pubkey/pk_ops.h38
-rw-r--r--src/pubkey/pubkey.cpp25
-rw-r--r--src/pubkey/pubkey.h39
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;
};