diff options
author | lloyd <[email protected]> | 2008-09-28 18:03:20 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2008-09-28 18:03:20 +0000 |
commit | 47ffeed7f8270855596c4f1d7b2d405172d78e8c (patch) | |
tree | 371535473f023f310a9c9c0281d5f62b3faedad0 /src | |
parent | 389dd2cdf55a57960581f686a8a766475a1f5d38 (diff) |
Modularize KDFs, PBKDFs, and PRFs
Diffstat (limited to 'src')
-rw-r--r-- | src/def_alg.cpp | 26 | ||||
-rw-r--r-- | src/get_enc.cpp | 31 | ||||
-rw-r--r-- | src/kdf.cpp | 65 | ||||
-rw-r--r-- | src/pgp_s2k.cpp | 82 | ||||
-rw-r--r-- | src/pkcs5.cpp | 128 | ||||
-rw-r--r-- | src/prf_x942.cpp | 89 | ||||
-rw-r--r-- | src/ssl3_prf.cpp | 71 | ||||
-rw-r--r-- | src/tls_prf.cpp | 63 |
8 files changed, 54 insertions, 501 deletions
diff --git a/src/def_alg.cpp b/src/def_alg.cpp index 6842d36d6..ad7ddae70 100644 --- a/src/def_alg.cpp +++ b/src/def_alg.cpp @@ -11,8 +11,6 @@ #include <botan/hmac.h> #include <botan/par_hash.h> #include <botan/mode_pad.h> -#include <botan/pgp_s2k.h> -#include <botan/pkcs5.h> #ifdef BOTAN_HAS_AES #include <botan/aes.h> @@ -185,11 +183,23 @@ #endif #ifdef BOTAN_HAS_SSL3_MAC -#include <botan/ssl3_mac.h> + #include <botan/ssl3_mac.h> #endif #ifdef BOTAN_HAS_ANSI_X919_MAC -#include <botan/x919_mac.h> + #include <botan/x919_mac.h> +#endif + +#ifdef BOTAN_HAS_PBKDF1 + #include <botan/pbkdf1.h> +#endif + +#ifdef BOTAN_HAS_PBKDF2 + #include <botan/pbkdf2.h> +#endif + +#ifdef BOTAN_HAS_PGPS2K + #include <botan/pgp_s2k.h> #endif namespace Botan { @@ -508,9 +518,17 @@ S2K* Default_Engine::find_s2k(const std::string& algo_spec) const const std::string algo_name = global_state().deref_alias(name[0]); +#ifdef BOTAN_HAS_PBKDF1 HANDLE_TYPE_ONE_STRING("PBKDF1", PKCS5_PBKDF1); +#endif + +#ifdef BOTAN_HAS_PBKDF2 HANDLE_TYPE_ONE_STRING("PBKDF2", PKCS5_PBKDF2); +#endif + +#ifdef BOTAN_HAS_PGPS2K HANDLE_TYPE_ONE_STRING("OpenPGP-S2K", OpenPGP_S2K); +#endif return 0; } diff --git a/src/get_enc.cpp b/src/get_enc.cpp index 77799d318..8137f4645 100644 --- a/src/get_enc.cpp +++ b/src/get_enc.cpp @@ -6,7 +6,6 @@ #include <botan/lookup.h> #include <botan/libstate.h> #include <botan/parsing.h> -#include <botan/kdf.h> #include <botan/mgf1.h> #include <botan/util.h> @@ -38,6 +37,26 @@ #include <botan/eme_pkcs.h> #endif +#ifdef BOTAN_HAS_KDF1 + #include <botan/kdf1.h> +#endif + +#ifdef BOTAN_HAS_KDF2 + #include <botan/kdf2.h> +#endif + +#ifdef BOTAN_HAS_X942_PRF + #include <botan/prf_x942.h> +#endif + +#ifdef BOTAN_HAS_SSL_V3_PRF + #include <botan/prf_ssl3.h> +#endif + +#ifdef BOTAN_HAS_TLS_V10_PRF + #include <botan/prf_tls.h> +#endif + namespace Botan { /************************************************* @@ -132,35 +151,45 @@ KDF* get_kdf(const std::string& algo_spec) std::vector<std::string> name = parse_algorithm_name(algo_spec); const std::string kdf_name = global_state().deref_alias(name[0]); +#ifdef BOTAN_HAS_KDF1 if(kdf_name == "KDF1") { if(name.size() == 2) return new KDF1(name[1]); } +#endif +#ifdef BOTAN_HAS_KDF2 if(kdf_name == "KDF2") { if(name.size() == 2) return new KDF2(name[1]); } +#endif +#ifdef BOTAN_HAS_X942_PRF if(kdf_name == "X9.42-PRF") { if(name.size() == 2) return new X942_PRF(name[1]); } +#endif +#ifdef BOTAN_HAS_TLS_V10_PRF if(kdf_name == "TLS-PRF") { if(name.size() == 1) return new TLS_PRF; } +#endif +#ifdef BOTAN_HAS_SSL_V3_PRF if(kdf_name == "SSL3-PRF") { if(name.size() == 1) return new SSL3_PRF; } +#endif throw Algorithm_Not_Found(algo_spec); } diff --git a/src/kdf.cpp b/src/kdf.cpp index 9d60a1839..dca56e1a6 100644 --- a/src/kdf.cpp +++ b/src/kdf.cpp @@ -1,9 +1,9 @@ /************************************************* -* KDF1/KDF2 Source File * +* KDF Base Class Source File * * (C) 1999-2007 Jack Lloyd * *************************************************/ -#include <botan/kdf.h> +#include <botan/pk_util.h> #include <botan/lookup.h> #include <botan/loadstor.h> #include <algorithm> @@ -67,65 +67,4 @@ SecureVector<byte> KDF::derive_key(u32bit key_len, return derive(key_len, secret, secret_len, salt, salt_len); } -/************************************************* -* KDF1 Key Derivation Mechanism * -*************************************************/ -SecureVector<byte> KDF1::derive(u32bit, - const byte secret[], u32bit secret_len, - const byte P[], u32bit P_len) const - { - std::auto_ptr<HashFunction> hash(get_hash(hash_name)); - - hash->update(secret, secret_len); - hash->update(P, P_len); - return hash->final(); - } - -/************************************************* -* KDF1 Constructor * -*************************************************/ -KDF1::KDF1(const std::string& h_name) : hash_name(h_name) - { - if(!have_hash(hash_name)) - throw Algorithm_Not_Found(hash_name); - } - -/************************************************* -* KDF2 Key Derivation Mechanism * -*************************************************/ -SecureVector<byte> KDF2::derive(u32bit out_len, - const byte secret[], u32bit secret_len, - const byte P[], u32bit P_len) const - { - SecureVector<byte> output; - u32bit counter = 1; - - std::auto_ptr<HashFunction> hash(get_hash(hash_name)); - while(out_len && counter) - { - hash->update(secret, secret_len); - for(u32bit j = 0; j != 4; ++j) - hash->update(get_byte(j, counter)); - hash->update(P, P_len); - SecureVector<byte> hash_result = hash->final(); - - u32bit added = std::min(hash_result.size(), out_len); - output.append(hash_result, added); - out_len -= added; - - ++counter; - } - - return output; - } - -/************************************************* -* KDF2 Constructor * -*************************************************/ -KDF2::KDF2(const std::string& h_name) : hash_name(h_name) - { - if(!have_hash(hash_name)) - throw Algorithm_Not_Found(hash_name); - } - } diff --git a/src/pgp_s2k.cpp b/src/pgp_s2k.cpp deleted file mode 100644 index 66a243e45..000000000 --- a/src/pgp_s2k.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************* -* OpenPGP S2K Source File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include <botan/pgp_s2k.h> -#include <botan/lookup.h> -#include <algorithm> -#include <memory> - -namespace Botan { - -/************************************************* -* Derive a key using the OpenPGP S2K algorithm * -*************************************************/ -OctetString OpenPGP_S2K::derive(u32bit key_len, const std::string& passphrase, - const byte salt_buf[], u32bit salt_size, - u32bit iterations) const - { - SecureVector<byte> key(key_len), hash_buf; - - u32bit pass = 0, generated = 0, - total_size = passphrase.size() + salt_size; - u32bit to_hash = std::max(iterations, total_size); - - std::auto_ptr<HashFunction> hash(get_hash(hash_name)); - - hash->clear(); - while(key_len > generated) - { - for(u32bit j = 0; j != pass; ++j) - hash->update(0); - - u32bit left = to_hash; - while(left >= total_size) - { - hash->update(salt_buf, salt_size); - hash->update(passphrase); - left -= total_size; - } - if(left <= salt_size) - hash->update(salt_buf, left); - else - { - hash->update(salt_buf, salt_size); - left -= salt_size; - hash->update(reinterpret_cast<const byte*>(passphrase.data()), left); - } - - hash_buf = hash->final(); - key.copy(generated, hash_buf, hash->OUTPUT_LENGTH); - generated += hash->OUTPUT_LENGTH; - ++pass; - } - - return key; - } - -/************************************************* -* Return the name of this type * -*************************************************/ -std::string OpenPGP_S2K::name() const - { - return "OpenPGP-S2K(" + hash_name + ")"; - } - -/************************************************* -* Return a clone of this object * -*************************************************/ -S2K* OpenPGP_S2K::clone() const - { - return new OpenPGP_S2K(hash_name); - } - -/************************************************* -* OpenPGP S2K Constructor * -*************************************************/ -OpenPGP_S2K::OpenPGP_S2K(const std::string& h) : hash_name(h) - { - } - -} diff --git a/src/pkcs5.cpp b/src/pkcs5.cpp deleted file mode 100644 index 8a6e7b5a8..000000000 --- a/src/pkcs5.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/************************************************* -* PKCS #5 Source File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include <botan/pkcs5.h> -#include <botan/lookup.h> -#include <botan/loadstor.h> -#include <botan/xor_buf.h> -#include <botan/hmac.h> -#include <algorithm> -#include <memory> - -namespace Botan { - -/************************************************* -* Return a PKCS#5 PBKDF1 derived key * -*************************************************/ -OctetString PKCS5_PBKDF1::derive(u32bit key_len, - const std::string& passphrase, - const byte salt[], u32bit salt_size, - u32bit iterations) const - { - if(iterations == 0) - throw Invalid_Argument("PKCS#5 PBKDF1: Invalid iteration count"); - - std::auto_ptr<HashFunction> hash(get_hash(hash_name)); - if(key_len > hash->OUTPUT_LENGTH) - throw Exception("PKCS#5 PBKDF1: Requested output length too long"); - - hash->update(passphrase); - hash->update(salt, salt_size); - SecureVector<byte> key = hash->final(); - - for(u32bit j = 1; j != iterations; ++j) - { - hash->update(key); - hash->final(key); - } - - return OctetString(key, std::min(key_len, key.size())); - } - -/************************************************* -* Return the name of this type * -*************************************************/ -std::string PKCS5_PBKDF1::name() const - { - return "PBKDF1(" + hash_name + ")"; - } - -/************************************************* -* PKCS5_PBKDF1 Constructor * -*************************************************/ -PKCS5_PBKDF1::PKCS5_PBKDF1(const std::string& h_name) : hash_name(h_name) - { - if(!have_hash(hash_name)) - throw Algorithm_Not_Found(hash_name); - } - -/************************************************* -* Return a PKCS#5 PBKDF2 derived key * -*************************************************/ -OctetString PKCS5_PBKDF2::derive(u32bit key_len, - const std::string& passphrase, - const byte salt[], u32bit salt_size, - u32bit iterations) const - { - if(iterations == 0) - throw Invalid_Argument("PKCS#5 PBKDF2: Invalid iteration count"); - - if(passphrase.length() == 0) - throw Invalid_Argument("PKCS#5 PBKDF2: Empty passphrase is invalid"); - - HMAC hmac(hash_name); - - hmac.set_key(reinterpret_cast<const byte*>(passphrase.data()), - passphrase.length()); - - SecureVector<byte> key(key_len); - - byte* T = key.begin(); - - u32bit counter = 1; - while(key_len) - { - u32bit T_size = std::min(hmac.OUTPUT_LENGTH, key_len); - SecureVector<byte> U(hmac.OUTPUT_LENGTH); - - hmac.update(salt, salt_size); - for(u32bit j = 0; j != 4; ++j) - hmac.update(get_byte(j, counter)); - hmac.final(U); - xor_buf(T, U, T_size); - - for(u32bit j = 1; j != iterations; ++j) - { - hmac.update(U); - hmac.final(U); - xor_buf(T, U, T_size); - } - - key_len -= T_size; - T += T_size; - ++counter; - } - - return key; - } - -/************************************************* -* Return the name of this type * -*************************************************/ -std::string PKCS5_PBKDF2::name() const - { - return "PBKDF2(" + hash_name + ")"; - } - -/************************************************* -* PKCS5_PBKDF2 Constructor * -*************************************************/ -PKCS5_PBKDF2::PKCS5_PBKDF2(const std::string& h_name) : hash_name(h_name) - { - if(!have_hash(hash_name)) - throw Algorithm_Not_Found(hash_name); - } - -} diff --git a/src/prf_x942.cpp b/src/prf_x942.cpp deleted file mode 100644 index 4cd53fa27..000000000 --- a/src/prf_x942.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************* -* X9.42 PRF Source File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ - -#include <botan/kdf.h> -#include <botan/der_enc.h> -#include <botan/oids.h> -#include <botan/lookup.h> -#include <botan/loadstor.h> -#include <algorithm> -#include <memory> - -namespace Botan { - -namespace { - -/************************************************* -* Encode an integer as an OCTET STRING * -*************************************************/ -MemoryVector<byte> encode_x942_int(u32bit n) - { - byte n_buf[4] = { 0 }; - store_be(n, n_buf); - return DER_Encoder().encode(n_buf, 4, OCTET_STRING).get_contents(); - } - -} - -/************************************************* -* X9.42 PRF * -*************************************************/ -SecureVector<byte> X942_PRF::derive(u32bit key_len, - const byte secret[], u32bit secret_len, - const byte salt[], u32bit salt_len) const - { - std::auto_ptr<HashFunction> hash(get_hash("SHA-1")); - const OID kek_algo(key_wrap_oid); - - SecureVector<byte> key; - u32bit counter = 1; - - while(key.size() != key_len && counter) - { - hash->update(secret, secret_len); - - hash->update( - DER_Encoder().start_cons(SEQUENCE) - - .start_cons(SEQUENCE) - .encode(kek_algo) - .raw_bytes(encode_x942_int(counter)) - .end_cons() - - .encode_if(salt_len != 0, - DER_Encoder() - .start_explicit(0) - .encode(salt, salt_len, OCTET_STRING) - .end_explicit() - ) - - .start_explicit(2) - .raw_bytes(encode_x942_int(8 * key_len)) - .end_explicit() - - .end_cons().get_contents() - ); - - SecureVector<byte> digest = hash->final(); - key.append(digest, std::min(digest.size(), key_len - key.size())); - - ++counter; - } - - return key; - } - -/************************************************* -* X9.42 Constructor * -*************************************************/ -X942_PRF::X942_PRF(const std::string& oid) - { - if(OIDS::have_oid(oid)) - key_wrap_oid = OIDS::lookup(oid).as_string(); - else - key_wrap_oid = oid; - } - -} diff --git a/src/ssl3_prf.cpp b/src/ssl3_prf.cpp deleted file mode 100644 index a86ed8ff7..000000000 --- a/src/ssl3_prf.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/************************************************* -* SSL3 PRF Source File * -* (C) 2004-2006 Jack Lloyd * -*************************************************/ - -#include <botan/kdf.h> -#include <botan/lookup.h> -#include <memory> - -namespace Botan { - -namespace { - -/************************************************* -* Return the next inner hash * -*************************************************/ -OctetString next_hash(u32bit where, u32bit want, - HashFunction* md5, HashFunction* sha1, - const byte secret[], u32bit secret_len, - const byte seed[], u32bit seed_len) - { - if(want > md5->OUTPUT_LENGTH) - throw Internal_Error("SSL3_PRF:next_hash: want is too big"); - - const byte ASCII_A_CHAR = 0x41; - - for(u32bit j = 0; j != where + 1; j++) - sha1->update(ASCII_A_CHAR + where); - sha1->update(secret, secret_len); - sha1->update(seed, seed_len); - SecureVector<byte> sha1_hash = sha1->final(); - - md5->update(secret, secret_len); - md5->update(sha1_hash); - SecureVector<byte> md5_hash = md5->final(); - - return OctetString(md5_hash, want); - } - -} - -/************************************************* -* SSL3 PRF * -*************************************************/ -SecureVector<byte> SSL3_PRF::derive(u32bit key_len, - const byte secret[], u32bit secret_len, - const byte seed[], u32bit seed_len) const - { - if(key_len > 416) - throw Internal_Error("SSL3_PRF: Requested key length is too large"); - - std::auto_ptr<HashFunction> md5(get_hash("MD5")); - std::auto_ptr<HashFunction> sha1(get_hash("SHA-1")); - - OctetString output; - - int counter = 0; - while(key_len) - { - const u32bit produce = std::min(key_len, md5->OUTPUT_LENGTH); - - output = output + next_hash(counter++, produce, md5.get(), sha1.get(), - secret, secret_len, seed, seed_len); - - key_len -= produce; - } - - return output.bits_of(); - } - -} diff --git a/src/tls_prf.cpp b/src/tls_prf.cpp deleted file mode 100644 index 2222e3baa..000000000 --- a/src/tls_prf.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/************************************************* -* TLS PRF Source File * -* (C) 2004-2006 Jack Lloyd * -*************************************************/ - -#include <botan/kdf.h> -#include <botan/lookup.h> -#include <botan/xor_buf.h> -#include <botan/hmac.h> - -namespace Botan { - -/************************************************* -* TLS PRF * -*************************************************/ -SecureVector<byte> TLS_PRF::derive(u32bit key_len, - const byte secret[], u32bit secret_len, - const byte seed[], u32bit seed_len) const - { - u32bit S1_len = (secret_len + 1) / 2, - S2_len = (secret_len + 1) / 2; - const byte* S1 = secret; - const byte* S2 = secret + (secret_len - S2_len); - - SecureVector<byte> key1, key2; - key1 = P_hash("MD5", key_len, S1, S1_len, seed, seed_len); - key2 = P_hash("SHA-1", key_len, S2, S2_len, seed, seed_len); - - xor_buf(key1.begin(), key2.begin(), key2.size()); - - return key1; - } - -/************************************************* -* TLS PRF P_hash function * -*************************************************/ -SecureVector<byte> TLS_PRF::P_hash(const std::string& hash, u32bit len, - const byte secret[], u32bit secret_len, - const byte seed[], u32bit seed_len) const - { - SecureVector<byte> out; - - HMAC hmac(hash); - hmac.set_key(secret, secret_len); - - SecureVector<byte> A(seed, seed_len); - while(len) - { - const u32bit this_block_len = std::min(hmac.OUTPUT_LENGTH, len); - - A = hmac.process(A); - - hmac.update(A); - hmac.update(seed, seed_len); - SecureVector<byte> block = hmac.final(); - - out.append(block, this_block_len); - len -= this_block_len; - } - return out; - } - -} |