From 0abc80f498c6bc2e8f630e34b90d5c6d24c29f58 Mon Sep 17 00:00:00 2001 From: lloyd Date: Sat, 17 Apr 2010 17:57:14 +0000 Subject: Add support for TLS 1.2 PRF --- src/kdf/tls_prf/prf_tls.cpp | 59 +++++++++++++++++++++++++++++++-------------- src/kdf/tls_prf/prf_tls.h | 26 +++++++++++++++++--- 2 files changed, 63 insertions(+), 22 deletions(-) (limited to 'src/kdf') diff --git a/src/kdf/tls_prf/prf_tls.cpp b/src/kdf/tls_prf/prf_tls.cpp index 5e77f831e..7345f11c5 100644 --- a/src/kdf/tls_prf/prf_tls.cpp +++ b/src/kdf/tls_prf/prf_tls.cpp @@ -1,6 +1,6 @@ /* -* TLS PRF -* (C) 2004-2006 Jack Lloyd +* TLS v1.0 and v1.2 PRFs +* (C) 2004-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -18,19 +18,19 @@ namespace { /* * TLS PRF P_hash function */ -SecureVector P_hash(MessageAuthenticationCode* mac, - u32bit len, - const byte secret[], u32bit secret_len, - const byte seed[], u32bit seed_len) +void P_hash(byte output[], u32bit output_len, + MessageAuthenticationCode* mac, + const byte secret[], u32bit secret_len, + const byte seed[], u32bit seed_len) { - SecureVector out; - mac->set_key(secret, secret_len); SecureVector A(seed, seed_len); - while(len) + + while(output_len) { - const u32bit this_block_len = std::min(mac->OUTPUT_LENGTH, len); + const u32bit this_block_len = + std::min(mac->OUTPUT_LENGTH, output_len); A = mac->process(A); @@ -38,10 +38,10 @@ SecureVector P_hash(MessageAuthenticationCode* mac, mac->update(seed, seed_len); SecureVector block = mac->final(); - out.append(block, this_block_len); - len -= this_block_len; + xor_buf(output, &block[0], this_block_len); + output_len -= this_block_len; + output += this_block_len; } - return out; } } @@ -68,18 +68,41 @@ SecureVector TLS_PRF::derive(u32bit key_len, const byte secret[], u32bit secret_len, const byte seed[], u32bit seed_len) const { + SecureVector output(key_len); + 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 key1, key2; - key1 = P_hash(hmac_md5, key_len, S1, S1_len, seed, seed_len); - key2 = P_hash(hmac_sha1, key_len, S2, S2_len, seed, seed_len); + P_hash(output, key_len, hmac_md5, S1, S1_len, seed, seed_len); + P_hash(output, key_len, hmac_sha1, S2, S2_len, seed, seed_len); + + return output; + } + +/* +* TLS v1.2 PRF Constructor and Destructor +*/ +TLS_12_PRF::TLS_12_PRF(HashFunction* hash) + { + hmac = new HMAC(hash); + } + +TLS_12_PRF::~TLS_12_PRF() + { + delete hmac; + } + +SecureVector TLS_12_PRF::derive(u32bit key_len, + const byte secret[], u32bit secret_len, + const byte seed[], u32bit seed_len) const + { + SecureVector output(key_len); - xor_buf(key1.begin(), key2.begin(), key2.size()); + P_hash(output, key_len, hmac, secret, secret_len, seed, seed_len); - return key1; + return output; } } diff --git a/src/kdf/tls_prf/prf_tls.h b/src/kdf/tls_prf/prf_tls.h index d21279588..6d1787609 100644 --- a/src/kdf/tls_prf/prf_tls.h +++ b/src/kdf/tls_prf/prf_tls.h @@ -1,6 +1,6 @@ /* -* TLS v1.0 PRF -* (C) 1999-2007 Jack Lloyd +* TLS v1.0 and v1.2 PRFs +* (C) 2004-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -10,6 +10,7 @@ #include #include +#include namespace Botan { @@ -19,8 +20,9 @@ namespace Botan { class BOTAN_DLL TLS_PRF : public KDF { public: - SecureVector derive(u32bit, const byte[], u32bit, - const byte[], u32bit) const; + SecureVector derive(u32bit key_len, + const byte secret[], u32bit secret_len, + const byte seed[], u32bit seed_len) const; TLS_PRF(); ~TLS_PRF(); @@ -29,6 +31,22 @@ class BOTAN_DLL TLS_PRF : public KDF MessageAuthenticationCode* hmac_sha1; }; +/* +* TLS 1.2 PRF +*/ +class BOTAN_DLL TLS_12_PRF : public KDF + { + public: + SecureVector derive(u32bit key_len, + const byte secret[], u32bit secret_len, + const byte seed[], u32bit seed_len) const; + + TLS_12_PRF(HashFunction* hash); + ~TLS_12_PRF(); + private: + MessageAuthenticationCode* hmac; + }; + } #endif -- cgit v1.2.3