Botan
1.11.15
|
00001 /* 00002 * TLS v1.0 and v1.2 PRFs 00003 * (C) 2004-2010 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/kdf_utils.h> 00009 #include <botan/prf_tls.h> 00010 #include <botan/hmac.h> 00011 00012 namespace Botan { 00013 00014 TLS_12_PRF* TLS_12_PRF::make(const Spec& spec) 00015 { 00016 if(auto mac = make_a<MessageAuthenticationCode>(spec.arg(0))) 00017 return new TLS_12_PRF(mac); 00018 if(auto hash = make_a<HashFunction>(spec.arg(0))) 00019 return new TLS_12_PRF(new HMAC(hash)); 00020 return nullptr; 00021 } 00022 00023 BOTAN_REGISTER_NAMED_T(KDF, "TLS-12-PRF", TLS_12_PRF, TLS_12_PRF::make); 00024 BOTAN_REGISTER_KDF_NOARGS(TLS_PRF, "TLS-PRF"); 00025 00026 TLS_PRF::TLS_PRF() 00027 { 00028 m_hmac_md5.reset(make_a<MessageAuthenticationCode>("HMAC(MD5)")); 00029 m_hmac_sha1.reset(make_a<MessageAuthenticationCode>("HMAC(SHA-1)")); 00030 } 00031 00032 namespace { 00033 00034 /* 00035 * TLS PRF P_hash function 00036 */ 00037 void P_hash(byte out[], size_t out_len, 00038 MessageAuthenticationCode& mac, 00039 const byte secret[], size_t secret_len, 00040 const byte salt[], size_t salt_len) 00041 { 00042 try 00043 { 00044 mac.set_key(secret, secret_len); 00045 } 00046 catch(Invalid_Key_Length) 00047 { 00048 throw Internal_Error("The premaster secret of " + 00049 std::to_string(secret_len) + 00050 " bytes is too long for the PRF"); 00051 } 00052 00053 secure_vector<byte> A(salt, salt + salt_len); 00054 secure_vector<byte> h; 00055 00056 size_t offset = 0; 00057 00058 while(offset != out_len) 00059 { 00060 A = mac.process(A); 00061 00062 mac.update(A); 00063 mac.update(salt, salt_len); 00064 mac.final(h); 00065 00066 const size_t writing = std::min(h.size(), out_len - offset); 00067 xor_buf(&out[offset], &h[0], writing); 00068 offset += writing; 00069 } 00070 } 00071 00072 } 00073 00074 size_t TLS_PRF::kdf(byte key[], size_t key_len, 00075 const byte secret[], size_t secret_len, 00076 const byte salt[], size_t salt_len) const 00077 { 00078 const size_t S1_len = (secret_len + 1) / 2, 00079 S2_len = (secret_len + 1) / 2; 00080 const byte* S1 = secret; 00081 const byte* S2 = secret + (secret_len - S2_len); 00082 00083 P_hash(key, key_len, *m_hmac_md5, S1, S1_len, salt, salt_len); 00084 P_hash(key, key_len, *m_hmac_sha1, S2, S2_len, salt, salt_len); 00085 return key_len; 00086 } 00087 00088 size_t TLS_12_PRF::kdf(byte key[], size_t key_len, 00089 const byte secret[], size_t secret_len, 00090 const byte salt[], size_t salt_len) const 00091 { 00092 P_hash(key, key_len, *m_mac, secret, secret_len, salt, salt_len); 00093 return key_len; 00094 } 00095 00096 }