Botan  2.7.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 #include <botan/exceptn.h>
10 
11 namespace Botan {
12 
14  m_hmac_md5(MessageAuthenticationCode::create_or_throw("HMAC(MD5)")),
15  m_hmac_sha1(MessageAuthenticationCode::create_or_throw("HMAC(SHA-1)"))
16  {
17  }
18 
19 namespace {
20 
21 /*
22 * TLS PRF P_hash function
23 */
24 void P_hash(uint8_t out[], size_t out_len,
26  const uint8_t secret[], size_t secret_len,
27  const uint8_t salt[], size_t salt_len)
28  {
29  try
30  {
31  mac.set_key(secret, secret_len);
32  }
33  catch(Invalid_Key_Length&)
34  {
35  throw Internal_Error("The premaster secret of " +
36  std::to_string(secret_len) +
37  " bytes is too long for the PRF");
38  }
39 
40  secure_vector<uint8_t> A(salt, salt + salt_len);
41  secure_vector<uint8_t> h;
42 
43  size_t offset = 0;
44 
45  while(offset != out_len)
46  {
47  A = mac.process(A);
48 
49  mac.update(A);
50  mac.update(salt, salt_len);
51  mac.final(h);
52 
53  const size_t writing = std::min(h.size(), out_len - offset);
54  xor_buf(&out[offset], h.data(), writing);
55  offset += writing;
56  }
57  }
58 
59 }
60 
61 size_t TLS_PRF::kdf(uint8_t key[], size_t key_len,
62  const uint8_t secret[], size_t secret_len,
63  const uint8_t salt[], size_t salt_len,
64  const uint8_t label[], size_t label_len) const
65  {
66  const size_t S1_len = (secret_len + 1) / 2,
67  S2_len = (secret_len + 1) / 2;
68  const uint8_t* S1 = secret;
69  const uint8_t* S2 = secret + (secret_len - S2_len);
71 
72  msg.reserve(label_len + salt_len);
73  msg += std::make_pair(label, label_len);
74  msg += std::make_pair(salt, salt_len);
75 
76  P_hash(key, key_len, *m_hmac_md5, S1, S1_len, msg.data(), msg.size());
77  P_hash(key, key_len, *m_hmac_sha1, S2, S2_len, msg.data(), msg.size());
78  return key_len;
79  }
80 
81 size_t TLS_12_PRF::kdf(uint8_t key[], size_t key_len,
82  const uint8_t secret[], size_t secret_len,
83  const uint8_t salt[], size_t salt_len,
84  const uint8_t label[], size_t label_len) const
85  {
87 
88  msg.reserve(label_len + salt_len);
89  msg += std::make_pair(label, label_len);
90  msg += std::make_pair(salt, salt_len);
91 
92  P_hash(key, key_len, *m_mac, secret, secret_len, msg.data(), msg.size());
93  return key_len;
94  }
95 
96 }
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:210
void final(uint8_t out[])
Definition: buf_comp.h:89
void set_key(const SymmetricKey &key)
Definition: sym_algo.h:65
void xor_buf(uint8_t out[], const uint8_t in[], size_t length)
Definition: mem_ops.h:174
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:26
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:81
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:61