Coverage Report

Created: 2021-01-13 07:05

/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/internal/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
18.5k
   {
29
18.5k
   try
30
18.5k
      {
31
18.5k
      mac.set_key(secret, secret_len);
32
18.5k
      }
33
18.5k
   catch(Invalid_Key_Length&)
34
0
      {
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
40
18.5k
   secure_vector<uint8_t> A(salt, salt + salt_len);
41
18.5k
   secure_vector<uint8_t> h;
42
43
18.5k
   size_t offset = 0;
44
45
63.8k
   while(offset != out_len)
46
45.2k
      {
47
45.2k
      A = mac.process(A);
48
49
45.2k
      mac.update(A);
50
45.2k
      mac.update(salt, salt_len);
51
45.2k
      mac.final(h);
52
53
45.2k
      const size_t writing = std::min(h.size(), out_len - offset);
54
45.2k
      xor_buf(&out[offset], h.data(), writing);
55
45.2k
      offset += writing;
56
45.2k
      }
57
18.5k
   }
58
59
}
60
61
void 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
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
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
   }
79
80
void 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
18.5k
   {
85
18.5k
   secure_vector<uint8_t> msg;
86
87
18.5k
   msg.reserve(label_len + salt_len);
88
18.5k
   msg += std::make_pair(label, label_len);
89
18.5k
   msg += std::make_pair(salt, salt_len);
90
91
18.5k
   P_hash(key, key_len, *m_mac, secret, secret_len, msg.data(), msg.size());
92
18.5k
   }
93
94
}