diff options
author | lloyd <lloyd@randombit.net> | 2014-01-10 03:41:59 +0000 |
---|---|---|
committer | lloyd <lloyd@randombit.net> | 2014-01-10 03:41:59 +0000 |
commit | 6894dca64c04936d07048c0e8cbf7e25858548c3 (patch) | |
tree | 5d572bfde9fe667dab14e3f04b5285a85d8acd95 /src/lib/kdf | |
parent | 9efa3be92442afb3d0b69890a36c7f122df18eda (diff) |
Move lib into src
Diffstat (limited to 'src/lib/kdf')
-rw-r--r-- | src/lib/kdf/info.txt | 5 | ||||
-rw-r--r-- | src/lib/kdf/kdf.cpp | 81 | ||||
-rw-r--r-- | src/lib/kdf/kdf.h | 136 | ||||
-rw-r--r-- | src/lib/kdf/kdf1/info.txt | 5 | ||||
-rw-r--r-- | src/lib/kdf/kdf1/kdf1.cpp | 24 | ||||
-rw-r--r-- | src/lib/kdf/kdf1/kdf1.h | 39 | ||||
-rw-r--r-- | src/lib/kdf/kdf2/info.txt | 5 | ||||
-rw-r--r-- | src/lib/kdf/kdf2/kdf2.cpp | 40 | ||||
-rw-r--r-- | src/lib/kdf/kdf2/kdf2.h | 37 | ||||
-rw-r--r-- | src/lib/kdf/mgf1/info.txt | 5 | ||||
-rw-r--r-- | src/lib/kdf/mgf1/mgf1.cpp | 56 | ||||
-rw-r--r-- | src/lib/kdf/mgf1/mgf1.h | 36 | ||||
-rw-r--r-- | src/lib/kdf/prf_ssl3/info.txt | 7 | ||||
-rw-r--r-- | src/lib/kdf/prf_ssl3/prf_ssl3.cpp | 76 | ||||
-rw-r--r-- | src/lib/kdf/prf_ssl3/prf_ssl3.h | 30 | ||||
-rw-r--r-- | src/lib/kdf/prf_tls/info.txt | 8 | ||||
-rw-r--r-- | src/lib/kdf/prf_tls/prf_tls.cpp | 117 | ||||
-rw-r--r-- | src/lib/kdf/prf_tls/prf_tls.h | 58 | ||||
-rw-r--r-- | src/lib/kdf/prf_x942/info.txt | 7 | ||||
-rw-r--r-- | src/lib/kdf/prf_x942/prf_x942.cpp | 92 | ||||
-rw-r--r-- | src/lib/kdf/prf_x942/prf_x942.h | 34 |
21 files changed, 898 insertions, 0 deletions
diff --git a/src/lib/kdf/info.txt b/src/lib/kdf/info.txt new file mode 100644 index 000000000..e9cbdeb1a --- /dev/null +++ b/src/lib/kdf/info.txt @@ -0,0 +1,5 @@ +define KDF_BASE 20131128 + +<requires> +alloc +</requires> diff --git a/src/lib/kdf/kdf.cpp b/src/lib/kdf/kdf.cpp new file mode 100644 index 000000000..84a0cdd15 --- /dev/null +++ b/src/lib/kdf/kdf.cpp @@ -0,0 +1,81 @@ +/* +* KDF Retrieval +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/lookup.h> +#include <botan/libstate.h> +#include <botan/scan_name.h> + +#if defined(BOTAN_HAS_KDF1) + #include <botan/kdf1.h> +#endif + +#if defined(BOTAN_HAS_KDF2) + #include <botan/kdf2.h> +#endif + +#if defined(BOTAN_HAS_X942_PRF) + #include <botan/prf_x942.h> +#endif + +#if defined(BOTAN_HAS_SSL_V3_PRF) + #include <botan/prf_ssl3.h> +#endif + +#if defined(BOTAN_HAS_TLS_V10_PRF) + #include <botan/prf_tls.h> +#endif + +namespace Botan { + +KDF* get_kdf(const std::string& algo_spec) + { + SCAN_Name request(algo_spec); + + Algorithm_Factory& af = global_state().algorithm_factory(); + + if(request.algo_name() == "Raw") + return nullptr; // No KDF + +#if defined(BOTAN_HAS_KDF1) + if(request.algo_name() == "KDF1" && request.arg_count() == 1) + return new KDF1(af.make_hash_function(request.arg(0))); +#endif + +#if defined(BOTAN_HAS_KDF2) + if(request.algo_name() == "KDF2" && request.arg_count() == 1) + return new KDF2(af.make_hash_function(request.arg(0))); +#endif + +#if defined(BOTAN_HAS_X942_PRF) + if(request.algo_name() == "X9.42-PRF" && request.arg_count() == 1) + return new X942_PRF(request.arg(0)); // OID +#endif + +#if defined(BOTAN_HAS_SSL_V3_PRF) + if(request.algo_name() == "SSL3-PRF" && request.arg_count() == 0) + return new SSL3_PRF; +#endif + +#if defined(BOTAN_HAS_TLS_V10_PRF) + if(request.algo_name() == "TLS-PRF" && request.arg_count() == 0) + return new TLS_PRF; +#endif + +#if defined(BOTAN_HAS_TLS_V10_PRF) + if(request.algo_name() == "TLS-PRF" && request.arg_count() == 0) + return new TLS_PRF; +#endif + +#if defined(BOTAN_HAS_TLS_V12_PRF) + if(request.algo_name() == "TLS-12-PRF" && request.arg_count() == 1) + return new TLS_12_PRF(af.make_mac("HMAC(" + request.arg(0) + ")")); +#endif + + throw Algorithm_Not_Found(algo_spec); + } + +} diff --git a/src/lib/kdf/kdf.h b/src/lib/kdf/kdf.h new file mode 100644 index 000000000..b0f6e1dc3 --- /dev/null +++ b/src/lib/kdf/kdf.h @@ -0,0 +1,136 @@ +/* +* KDF/MGF +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_KDF_BASE_H__ +#define BOTAN_KDF_BASE_H__ + +#include <botan/algo_base.h> +#include <botan/secmem.h> +#include <botan/types.h> + +namespace Botan { + +/** +* Key Derivation Function +*/ +class BOTAN_DLL KDF : public Algorithm + { + public: + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param salt a diversifier + */ + secure_vector<byte> derive_key(size_t key_len, + const secure_vector<byte>& secret, + const std::string& salt = "") const + { + return derive_key(key_len, &secret[0], secret.size(), + reinterpret_cast<const byte*>(salt.data()), + salt.length()); + } + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param salt a diversifier + */ + template<typename Alloc, typename Alloc2> + secure_vector<byte> derive_key(size_t key_len, + const std::vector<byte, Alloc>& secret, + const std::vector<byte, Alloc2>& salt) const + { + return derive_key(key_len, + &secret[0], secret.size(), + &salt[0], salt.size()); + } + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param salt a diversifier + * @param salt_len size of salt in bytes + */ + secure_vector<byte> derive_key(size_t key_len, + const secure_vector<byte>& secret, + const byte salt[], + size_t salt_len) const + { + return derive_key(key_len, + &secret[0], secret.size(), + salt, salt_len); + } + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param secret_len size of secret in bytes + * @param salt a diversifier + */ + secure_vector<byte> derive_key(size_t key_len, + const byte secret[], + size_t secret_len, + const std::string& salt = "") const + { + return derive_key(key_len, secret, secret_len, + reinterpret_cast<const byte*>(salt.data()), + salt.length()); + } + + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param secret_len size of secret in bytes + * @param salt a diversifier + * @param salt_len size of salt in bytes + */ + secure_vector<byte> derive_key(size_t key_len, + const byte secret[], + size_t secret_len, + const byte salt[], + size_t salt_len) const + { + return derive(key_len, secret, secret_len, salt, salt_len); + } + + void clear() {} + + virtual KDF* clone() const = 0; + private: + virtual secure_vector<byte> + derive(size_t key_len, + const byte secret[], size_t secret_len, + const byte salt[], size_t salt_len) const = 0; + }; + +/** +* Mask Generation Function +*/ +class BOTAN_DLL MGF + { + public: + virtual void mask(const byte in[], size_t in_len, + byte out[], size_t out_len) const = 0; + + virtual ~MGF() {} + }; + +/** +* Factory method for KDF (key derivation function) +* @param algo_spec the name of the KDF to create +* @return pointer to newly allocated object of that type +*/ +BOTAN_DLL KDF* get_kdf(const std::string& algo_spec); + +} + +#endif diff --git a/src/lib/kdf/kdf1/info.txt b/src/lib/kdf/kdf1/info.txt new file mode 100644 index 000000000..08192fa95 --- /dev/null +++ b/src/lib/kdf/kdf1/info.txt @@ -0,0 +1,5 @@ +define KDF1 20131128 + +<requires> +hash +</requires> diff --git a/src/lib/kdf/kdf1/kdf1.cpp b/src/lib/kdf/kdf1/kdf1.cpp new file mode 100644 index 000000000..f00f71010 --- /dev/null +++ b/src/lib/kdf/kdf1/kdf1.cpp @@ -0,0 +1,24 @@ +/* +* KDF1 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/kdf1.h> + +namespace Botan { + +/* +* KDF1 Key Derivation Mechanism +*/ +secure_vector<byte> KDF1::derive(size_t, + const byte secret[], size_t secret_len, + const byte P[], size_t P_len) const + { + hash->update(secret, secret_len); + hash->update(P, P_len); + return hash->final(); + } + +} diff --git a/src/lib/kdf/kdf1/kdf1.h b/src/lib/kdf/kdf1/kdf1.h new file mode 100644 index 000000000..6a14d2995 --- /dev/null +++ b/src/lib/kdf/kdf1/kdf1.h @@ -0,0 +1,39 @@ +/* +* KDF1 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_KDF1_H__ +#define BOTAN_KDF1_H__ + +#include <botan/kdf.h> +#include <botan/hash.h> + +namespace Botan { + +/** +* KDF1, from IEEE 1363 +*/ +class BOTAN_DLL KDF1 : public KDF + { + public: + secure_vector<byte> derive(size_t, + const byte secret[], size_t secret_len, + const byte P[], size_t P_len) const; + + std::string name() const { return "KDF1(" + hash->name() + ")"; } + KDF* clone() const { return new KDF1(hash->clone()); } + + KDF1(HashFunction* h) : hash(h) {} + KDF1(const KDF1& other) : KDF(), hash(other.hash->clone()) {} + + ~KDF1() { delete hash; } + private: + HashFunction* hash; + }; + +} + +#endif diff --git a/src/lib/kdf/kdf2/info.txt b/src/lib/kdf/kdf2/info.txt new file mode 100644 index 000000000..3481ff04f --- /dev/null +++ b/src/lib/kdf/kdf2/info.txt @@ -0,0 +1,5 @@ +define KDF2 20131128 + +<requires> +hash +</requires> diff --git a/src/lib/kdf/kdf2/kdf2.cpp b/src/lib/kdf/kdf2/kdf2.cpp new file mode 100644 index 000000000..39a929b58 --- /dev/null +++ b/src/lib/kdf/kdf2/kdf2.cpp @@ -0,0 +1,40 @@ +/* +* KDF2 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/kdf2.h> + +namespace Botan { + +/* +* KDF2 Key Derivation Mechanism +*/ +secure_vector<byte> KDF2::derive(size_t out_len, + const byte secret[], size_t secret_len, + const byte P[], size_t P_len) const + { + secure_vector<byte> output; + u32bit counter = 1; + + while(out_len && counter) + { + hash->update(secret, secret_len); + hash->update_be(counter); + hash->update(P, P_len); + + secure_vector<byte> hash_result = hash->final(); + + size_t added = std::min(hash_result.size(), out_len); + output += std::make_pair(&hash_result[0], added); + out_len -= added; + + ++counter; + } + + return output; + } + +} diff --git a/src/lib/kdf/kdf2/kdf2.h b/src/lib/kdf/kdf2/kdf2.h new file mode 100644 index 000000000..e33939df9 --- /dev/null +++ b/src/lib/kdf/kdf2/kdf2.h @@ -0,0 +1,37 @@ +/* +* KDF2 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_KDF2_H__ +#define BOTAN_KDF2_H__ + +#include <botan/kdf.h> +#include <botan/hash.h> + +namespace Botan { + +/** +* KDF2, from IEEE 1363 +*/ +class BOTAN_DLL KDF2 : public KDF + { + public: + secure_vector<byte> derive(size_t, const byte[], size_t, + const byte[], size_t) const; + + std::string name() const { return "KDF2(" + hash->name() + ")"; } + KDF* clone() const { return new KDF2(hash->clone()); } + + KDF2(HashFunction* h) : hash(h) {} + KDF2(const KDF2& other) : KDF(), hash(other.hash->clone()) {} + ~KDF2() { delete hash; } + private: + HashFunction* hash; + }; + +} + +#endif diff --git a/src/lib/kdf/mgf1/info.txt b/src/lib/kdf/mgf1/info.txt new file mode 100644 index 000000000..c6254b8a0 --- /dev/null +++ b/src/lib/kdf/mgf1/info.txt @@ -0,0 +1,5 @@ +define MGF1 20131128 + +<requires> +hash +</requires> diff --git a/src/lib/kdf/mgf1/mgf1.cpp b/src/lib/kdf/mgf1/mgf1.cpp new file mode 100644 index 000000000..e0433a02f --- /dev/null +++ b/src/lib/kdf/mgf1/mgf1.cpp @@ -0,0 +1,56 @@ +/* +* MGF1 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/mgf1.h> +#include <botan/exceptn.h> +#include <botan/internal/xor_buf.h> +#include <algorithm> +#include <memory> + +namespace Botan { + +/* +* MGF1 Mask Generation Function +*/ +void MGF1::mask(const byte in[], size_t in_len, byte out[], + size_t out_len) const + { + u32bit counter = 0; + + while(out_len) + { + hash->update(in, in_len); + hash->update_be(counter); + secure_vector<byte> buffer = hash->final(); + + size_t xored = std::min<size_t>(buffer.size(), out_len); + xor_buf(out, &buffer[0], xored); + out += xored; + out_len -= xored; + + ++counter; + } + } + +/* +* MGF1 Constructor +*/ +MGF1::MGF1(HashFunction* h) : hash(h) + { + if(!hash) + throw Invalid_Argument("MGF1 given null hash object"); + } + +/* +* MGF1 Destructor +*/ +MGF1::~MGF1() + { + delete hash; + } + +} diff --git a/src/lib/kdf/mgf1/mgf1.h b/src/lib/kdf/mgf1/mgf1.h new file mode 100644 index 000000000..95a2a2bc5 --- /dev/null +++ b/src/lib/kdf/mgf1/mgf1.h @@ -0,0 +1,36 @@ +/* +* MGF1 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_MGF1_H__ +#define BOTAN_MGF1_H__ + +#include <botan/kdf.h> +#include <botan/hash.h> + +namespace Botan { + +/** +* MGF1 from PKCS #1 v2.0 +*/ +class BOTAN_DLL MGF1 : public MGF + { + public: + void mask(const byte[], size_t, byte[], size_t) const; + + /** + MGF1 constructor: takes ownership of hash + */ + MGF1(HashFunction* hash); + + ~MGF1(); + private: + HashFunction* hash; + }; + +} + +#endif diff --git a/src/lib/kdf/prf_ssl3/info.txt b/src/lib/kdf/prf_ssl3/info.txt new file mode 100644 index 000000000..c4e830bac --- /dev/null +++ b/src/lib/kdf/prf_ssl3/info.txt @@ -0,0 +1,7 @@ +define SSL_V3_PRF 20131128 + +<requires> +md5 +sha1 +algo_base +</requires> diff --git a/src/lib/kdf/prf_ssl3/prf_ssl3.cpp b/src/lib/kdf/prf_ssl3/prf_ssl3.cpp new file mode 100644 index 000000000..93901416f --- /dev/null +++ b/src/lib/kdf/prf_ssl3/prf_ssl3.cpp @@ -0,0 +1,76 @@ +/* +* SSLv3 PRF +* (C) 2004-2006 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/prf_ssl3.h> +#include <botan/symkey.h> +#include <botan/exceptn.h> +#include <botan/sha160.h> +#include <botan/md5.h> +#include <memory> + +namespace Botan { + +namespace { + +/* +* Return the next inner hash +*/ +OctetString next_hash(size_t where, size_t want, + HashFunction& md5, HashFunction& sha1, + const byte secret[], size_t secret_len, + const byte seed[], size_t seed_len) + { + BOTAN_ASSERT(want <= md5.output_length(), + "Output size producable by MD5"); + + const byte ASCII_A_CHAR = 0x41; + + for(size_t j = 0; j != where + 1; j++) + sha1.update(static_cast<byte>(ASCII_A_CHAR + where)); + sha1.update(secret, secret_len); + sha1.update(seed, seed_len); + secure_vector<byte> sha1_hash = sha1.final(); + + md5.update(secret, secret_len); + md5.update(sha1_hash); + secure_vector<byte> md5_hash = md5.final(); + + return OctetString(&md5_hash[0], want); + } + +} + +/* +* SSL3 PRF +*/ +secure_vector<byte> SSL3_PRF::derive(size_t key_len, + const byte secret[], size_t secret_len, + const byte seed[], size_t seed_len) const + { + if(key_len > 416) + throw Invalid_Argument("SSL3_PRF: Requested key length is too large"); + + MD5 md5; + SHA_160 sha1; + + OctetString output; + + int counter = 0; + while(key_len) + { + const size_t produce = std::min<size_t>(key_len, md5.output_length()); + + output = output + next_hash(counter++, produce, md5, sha1, + secret, secret_len, seed, seed_len); + + key_len -= produce; + } + + return output.bits_of(); + } + +} diff --git a/src/lib/kdf/prf_ssl3/prf_ssl3.h b/src/lib/kdf/prf_ssl3/prf_ssl3.h new file mode 100644 index 000000000..bae8badb8 --- /dev/null +++ b/src/lib/kdf/prf_ssl3/prf_ssl3.h @@ -0,0 +1,30 @@ +/* +* SSLv3 PRF +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SSLV3_PRF_H__ +#define BOTAN_SSLV3_PRF_H__ + +#include <botan/kdf.h> + +namespace Botan { + +/** +* PRF used in SSLv3 +*/ +class BOTAN_DLL SSL3_PRF : public KDF + { + public: + secure_vector<byte> derive(size_t, const byte[], size_t, + const byte[], size_t) const; + + std::string name() const { return "SSL3-PRF"; } + KDF* clone() const { return new SSL3_PRF; } + }; + +} + +#endif diff --git a/src/lib/kdf/prf_tls/info.txt b/src/lib/kdf/prf_tls/info.txt new file mode 100644 index 000000000..505e1ff1e --- /dev/null +++ b/src/lib/kdf/prf_tls/info.txt @@ -0,0 +1,8 @@ +define TLS_V10_PRF 20131128 +define TLS_V12_PRF 20131128 + +<requires> +hmac +md5 +sha1 +</requires> diff --git a/src/lib/kdf/prf_tls/prf_tls.cpp b/src/lib/kdf/prf_tls/prf_tls.cpp new file mode 100644 index 000000000..006b418c9 --- /dev/null +++ b/src/lib/kdf/prf_tls/prf_tls.cpp @@ -0,0 +1,117 @@ +/* +* TLS v1.0 and v1.2 PRFs +* (C) 2004-2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/prf_tls.h> +#include <botan/internal/xor_buf.h> +#include <botan/hmac.h> +#include <botan/md5.h> +#include <botan/sha160.h> + +namespace Botan { + +namespace { + +/* +* TLS PRF P_hash function +*/ +void P_hash(secure_vector<byte>& output, + MessageAuthenticationCode* mac, + const byte secret[], size_t secret_len, + const byte seed[], size_t seed_len) + { + try + { + mac->set_key(secret, secret_len); + } + catch(Invalid_Key_Length) + { + throw Internal_Error("The premaster secret of " + + std::to_string(secret_len) + + " bytes is too long for the PRF"); + } + + secure_vector<byte> A(seed, seed + seed_len); + + size_t offset = 0; + + while(offset != output.size()) + { + const size_t this_block_len = + std::min<size_t>(mac->output_length(), output.size() - offset); + + A = mac->process(A); + + mac->update(A); + mac->update(seed, seed_len); + secure_vector<byte> block = mac->final(); + + xor_buf(&output[offset], &block[0], this_block_len); + offset += this_block_len; + } + } + +} + +/* +* TLS PRF Constructor and Destructor +*/ +TLS_PRF::TLS_PRF() + { + hmac_md5 = new HMAC(new MD5); + hmac_sha1 = new HMAC(new SHA_160); + } + +TLS_PRF::~TLS_PRF() + { + delete hmac_md5; + delete hmac_sha1; + } + +/* +* TLS PRF +*/ +secure_vector<byte> TLS_PRF::derive(size_t key_len, + const byte secret[], size_t secret_len, + const byte seed[], size_t seed_len) const + { + secure_vector<byte> output(key_len); + + size_t S1_len = (secret_len + 1) / 2, + S2_len = (secret_len + 1) / 2; + const byte* S1 = secret; + const byte* S2 = secret + (secret_len - S2_len); + + P_hash(output, hmac_md5, S1, S1_len, seed, seed_len); + P_hash(output, hmac_sha1, S2, S2_len, seed, seed_len); + + return output; + } + +/* +* TLS v1.2 PRF Constructor and Destructor +*/ +TLS_12_PRF::TLS_12_PRF(MessageAuthenticationCode* mac) : hmac(mac) + { + } + +TLS_12_PRF::~TLS_12_PRF() + { + delete hmac; + } + +secure_vector<byte> TLS_12_PRF::derive(size_t key_len, + const byte secret[], size_t secret_len, + const byte seed[], size_t seed_len) const + { + secure_vector<byte> output(key_len); + + P_hash(output, hmac, secret, secret_len, seed, seed_len); + + return output; + } + +} diff --git a/src/lib/kdf/prf_tls/prf_tls.h b/src/lib/kdf/prf_tls/prf_tls.h new file mode 100644 index 000000000..fce11eae0 --- /dev/null +++ b/src/lib/kdf/prf_tls/prf_tls.h @@ -0,0 +1,58 @@ +/* +* TLS v1.0 and v1.2 PRFs +* (C) 2004-2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_TLS_PRF_H__ +#define BOTAN_TLS_PRF_H__ + +#include <botan/kdf.h> +#include <botan/mac.h> +#include <botan/hash.h> + +namespace Botan { + +/** +* PRF used in TLS 1.0/1.1 +*/ +class BOTAN_DLL TLS_PRF : public KDF + { + public: + secure_vector<byte> derive(size_t key_len, + const byte secret[], size_t secret_len, + const byte seed[], size_t seed_len) const; + + std::string name() const { return "TLS-PRF"; } + KDF* clone() const { return new TLS_PRF; } + + TLS_PRF(); + ~TLS_PRF(); + private: + MessageAuthenticationCode* hmac_md5; + MessageAuthenticationCode* hmac_sha1; + }; + +/** +* PRF used in TLS 1.2 +*/ +class BOTAN_DLL TLS_12_PRF : public KDF + { + public: + secure_vector<byte> derive(size_t key_len, + const byte secret[], size_t secret_len, + const byte seed[], size_t seed_len) const; + + std::string name() const { return "TLSv12-PRF(" + hmac->name() + ")"; } + KDF* clone() const { return new TLS_12_PRF(hmac->clone()); } + + TLS_12_PRF(MessageAuthenticationCode* hmac); + ~TLS_12_PRF(); + private: + MessageAuthenticationCode* hmac; + }; + +} + +#endif diff --git a/src/lib/kdf/prf_x942/info.txt b/src/lib/kdf/prf_x942/info.txt new file mode 100644 index 000000000..ff4a6f160 --- /dev/null +++ b/src/lib/kdf/prf_x942/info.txt @@ -0,0 +1,7 @@ +define X942_PRF 20131128 + +<requires> +asn1 +oid_lookup +sha1 +</requires> diff --git a/src/lib/kdf/prf_x942/prf_x942.cpp b/src/lib/kdf/prf_x942/prf_x942.cpp new file mode 100644 index 000000000..149be163f --- /dev/null +++ b/src/lib/kdf/prf_x942/prf_x942.cpp @@ -0,0 +1,92 @@ +/* +* X9.42 PRF +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/prf_x942.h> +#include <botan/der_enc.h> +#include <botan/oids.h> +#include <botan/sha160.h> +#include <botan/loadstor.h> +#include <algorithm> +#include <memory> + +namespace Botan { + +namespace { + +/* +* Encode an integer as an OCTET STRING +*/ +std::vector<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_unlocked(); + } + +} + +/* +* X9.42 PRF +*/ +secure_vector<byte> X942_PRF::derive(size_t key_len, + const byte secret[], size_t secret_len, + const byte salt[], size_t salt_len) const + { + SHA_160 hash; + const OID kek_algo(key_wrap_oid); + + secure_vector<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(static_cast<u32bit>(8 * key_len))) + .end_explicit() + + .end_cons().get_contents() + ); + + secure_vector<byte> digest = hash.final(); + const size_t needed = std::min(digest.size(), key_len - key.size()); + key += std::make_pair(&digest[0], needed); + + ++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/lib/kdf/prf_x942/prf_x942.h b/src/lib/kdf/prf_x942/prf_x942.h new file mode 100644 index 000000000..f86b1bdd5 --- /dev/null +++ b/src/lib/kdf/prf_x942/prf_x942.h @@ -0,0 +1,34 @@ +/* +* X9.42 PRF +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_ANSI_X942_PRF_H__ +#define BOTAN_ANSI_X942_PRF_H__ + +#include <botan/kdf.h> + +namespace Botan { + +/** +* PRF from ANSI X9.42 +*/ +class BOTAN_DLL X942_PRF : public KDF + { + public: + secure_vector<byte> derive(size_t, const byte[], size_t, + const byte[], size_t) const; + + std::string name() const { return "X942_PRF(" + key_wrap_oid + ")"; } + KDF* clone() const { return new X942_PRF(key_wrap_oid); } + + X942_PRF(const std::string& oid); + private: + std::string key_wrap_oid; + }; + +} + +#endif |