Coverage Report

Created: 2020-06-30 13:58

/src/botan/src/lib/kdf/prf_tls/prf_tls.cpp
Line
Count
Source (jump to first uncovered line)
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
13
TLS_PRF::TLS_PRF() :
14
   TLS_PRF(MessageAuthenticationCode::create_or_throw("HMAC(MD5)"),
15
           MessageAuthenticationCode::create_or_throw("HMAC(SHA-1)"))
16
0
   {
17
0
   }
18
19
namespace {
20
21
/*
22
* TLS PRF P_hash function
23
*/
24
void P_hash(uint8_t out[], size_t out_len,
25
            MessageAuthenticationCode& mac,
26
            const uint8_t secret[], size_t secret_len,
27
            const uint8_t salt[], size_t salt_len)
28
31.5k
   {
29
31.5k
   try
30
31.5k
      {
31
31.5k
      mac.set_key(secret, secret_len);
32
31.5k
      }
33
31.5k
   catch(Invalid_Key_Length&)
34
31.5k
      {
35
0
      throw Internal_Error("The premaster secret of " +
36
0
                           std::to_string(secret_len) +
37
0
                           " bytes is too long for the PRF");
38
0
      }
39
31.5k
40
31.5k
   secure_vector<uint8_t> A(salt, salt + salt_len);
41
31.5k
   secure_vector<uint8_t> h;
42
31.5k
43
31.5k
   size_t offset = 0;
44
31.5k
45
100k
   while(offset != out_len)
46
68.9k
      {
47
68.9k
      A = mac.process(A);
48
68.9k
49
68.9k
      mac.update(A);
50
68.9k
      mac.update(salt, salt_len);
51
68.9k
      mac.final(h);
52
68.9k
53
68.9k
      const size_t writing = std::min(h.size(), out_len - offset);
54
68.9k
      xor_buf(&out[offset], h.data(), writing);
55
68.9k
      offset += writing;
56
68.9k
      }
57
31.5k
   }
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
0
   {
66
0
   const size_t S1_len = (secret_len + 1) / 2,
67
0
                S2_len = (secret_len + 1) / 2;
68
0
   const uint8_t* S1 = secret;
69
0
   const uint8_t* S2 = secret + (secret_len - S2_len);
70
0
   secure_vector<uint8_t> msg;
71
0
72
0
   msg.reserve(label_len + salt_len);
73
0
   msg += std::make_pair(label, label_len);
74
0
   msg += std::make_pair(salt, salt_len);
75
0
76
0
   P_hash(key, key_len, *m_hmac_md5,  S1, S1_len, msg.data(), msg.size());
77
0
   P_hash(key, key_len, *m_hmac_sha1, S2, S2_len, msg.data(), msg.size());
78
0
   return key_len;
79
0
   }
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
31.5k
   {
86
31.5k
   secure_vector<uint8_t> msg;
87
31.5k
88
31.5k
   msg.reserve(label_len + salt_len);
89
31.5k
   msg += std::make_pair(label, label_len);
90
31.5k
   msg += std::make_pair(salt, salt_len);
91
31.5k
92
31.5k
   P_hash(key, key_len, *m_mac, secret, secret_len, msg.data(), msg.size());
93
31.5k
   return key_len;
94
31.5k
   }
95
96
}