Botan  2.4.0
Crypto and TLS for C++11
prf_tls.cpp
Go to the documentation of this file.
1 /*
2 * TLS v1.0 and v1.2 PRFs
3 * (C) 2004-2010 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/prf_tls.h>
9 
10 namespace Botan {
11 
13  m_hmac_md5(MessageAuthenticationCode::create_or_throw("HMAC(MD5)")),
14  m_hmac_sha1(MessageAuthenticationCode::create_or_throw("HMAC(SHA-1)"))
15  {
16  }
17 
18 namespace {
19 
20 /*
21 * TLS PRF P_hash function
22 */
23 void P_hash(uint8_t out[], size_t out_len,
25  const uint8_t secret[], size_t secret_len,
26  const uint8_t salt[], size_t salt_len)
27  {
28  try
29  {
30  mac.set_key(secret, secret_len);
31  }
32  catch(Invalid_Key_Length)
33  {
34  throw Internal_Error("The premaster secret of " +
35  std::to_string(secret_len) +
36  " bytes is too long for the PRF");
37  }
38 
39  secure_vector<uint8_t> A(salt, salt + salt_len);
41 
42  size_t offset = 0;
43 
44  while(offset != out_len)
45  {
46  A = mac.process(A);
47 
48  mac.update(A);
49  mac.update(salt, salt_len);
50  mac.final(h);
51 
52  const size_t writing = std::min(h.size(), out_len - offset);
53  xor_buf(&out[offset], h.data(), writing);
54  offset += writing;
55  }
56  }
57 
58 }
59 
60 size_t TLS_PRF::kdf(uint8_t key[], size_t key_len,
61  const uint8_t secret[], size_t secret_len,
62  const uint8_t salt[], size_t salt_len,
63  const uint8_t label[], size_t label_len) const
64  {
65  const size_t S1_len = (secret_len + 1) / 2,
66  S2_len = (secret_len + 1) / 2;
67  const uint8_t* S1 = secret;
68  const uint8_t* S2 = secret + (secret_len - S2_len);
70 
71  msg.reserve(label_len + salt_len);
72  msg += std::make_pair(label, label_len);
73  msg += std::make_pair(salt, salt_len);
74 
75  P_hash(key, key_len, *m_hmac_md5, S1, S1_len, msg.data(), msg.size());
76  P_hash(key, key_len, *m_hmac_sha1, S2, S2_len, msg.data(), msg.size());
77  return key_len;
78  }
79 
80 size_t TLS_12_PRF::kdf(uint8_t key[], size_t key_len,
81  const uint8_t secret[], size_t secret_len,
82  const uint8_t salt[], size_t salt_len,
83  const uint8_t label[], size_t label_len) const
84  {
86 
87  msg.reserve(label_len + salt_len);
88  msg += std::make_pair(label, label_len);
89  msg += std::make_pair(salt, salt_len);
90 
91  P_hash(key, key_len, *m_mac, secret, secret_len, msg.data(), msg.size());
92  return key_len;
93  }
94 
95 }
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:108
void final(uint8_t out[])
Definition: buf_comp.h:89
void set_key(const SymmetricKey &key)
Definition: sym_algo.h:66
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
Definition: mem_ops.h:163
secure_vector< uint8_t > process(const uint8_t in[], size_t length)
Definition: buf_comp.h:124
size_t salt_len
Definition: x509_obj.cpp:25
Definition: alg_id.cpp:13
size_t kdf(uint8_t key[], size_t key_len, const uint8_t secret[], size_t secret_len, const uint8_t salt[], size_t salt_len, const uint8_t label[], size_t label_len) const override
Definition: prf_tls.cpp:80
void update(const uint8_t in[], size_t length)
Definition: buf_comp.h:34
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88
size_t kdf(uint8_t key[], size_t key_len, const uint8_t secret[], size_t secret_len, const uint8_t salt[], size_t salt_len, const uint8_t label[], size_t label_len) const override
Definition: prf_tls.cpp:60