1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
/*
* TLS Session Key
* (C) 2004-2006,2011 Jack Lloyd
*
* Released under the terms of the Botan license
*/
#include <botan/tls_session_key.h>
#include <botan/prf_ssl3.h>
#include <botan/prf_tls.h>
#include <botan/lookup.h>
#include <memory>
namespace Botan {
/**
* Generate SSLv3 session keys
*/
SymmetricKey SessionKeys::ssl3_keygen(size_t prf_gen,
const MemoryRegion<byte>& pre_master,
const MemoryRegion<byte>& client_random,
const MemoryRegion<byte>& server_random)
{
SSL3_PRF prf;
SecureVector<byte> salt;
salt += client_random;
salt += server_random;
master_sec = prf.derive_key(48, pre_master, salt);
salt.clear();
salt += server_random;
salt += client_random;
return prf.derive_key(prf_gen, master_sec, salt);
}
/**
* Generate TLS 1.0 session keys
*/
SymmetricKey SessionKeys::tls1_keygen(size_t prf_gen,
const MemoryRegion<byte>& pre_master,
const MemoryRegion<byte>& client_random,
const MemoryRegion<byte>& server_random)
{
const byte MASTER_SECRET_MAGIC[] = {
0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x73, 0x65, 0x63, 0x72, 0x65,
0x74 };
const byte KEY_GEN_MAGIC[] = {
0x6B, 0x65, 0x79, 0x20, 0x65, 0x78, 0x70, 0x61, 0x6E, 0x73, 0x69, 0x6F,
0x6E };
TLS_PRF prf;
SecureVector<byte> salt;
salt += std::make_pair(MASTER_SECRET_MAGIC, sizeof(MASTER_SECRET_MAGIC));
salt += client_random;
salt += server_random;
master_sec = prf.derive_key(48, pre_master, salt);
salt.clear();
salt += std::make_pair(KEY_GEN_MAGIC, sizeof(KEY_GEN_MAGIC));
salt += server_random;
salt += client_random;
return prf.derive_key(prf_gen, master_sec, salt);
}
/**
* SessionKeys Constructor
*/
SessionKeys::SessionKeys(const CipherSuite& suite,
Version_Code version,
const MemoryRegion<byte>& pre_master_secret,
const MemoryRegion<byte>& c_random,
const MemoryRegion<byte>& s_random,
bool resuming)
{
if(version != SSL_V3 && version != TLS_V10 && version != TLS_V11)
throw Invalid_Argument("SessionKeys: Unknown version code");
const size_t mac_keylen = output_length_of(suite.mac_algo());
const size_t cipher_keylen = suite.cipher_keylen();
size_t cipher_ivlen = 0;
if(have_block_cipher(suite.cipher_algo()))
cipher_ivlen = block_size_of(suite.cipher_algo());
const size_t prf_gen = 2 * (mac_keylen + cipher_keylen + cipher_ivlen);
if(resuming)
{
master_sec = pre_master_secret;
const byte KEY_GEN_MAGIC[] = {
0x6B, 0x65, 0x79, 0x20, 0x65, 0x78, 0x70, 0x61, 0x6E, 0x73, 0x69, 0x6F, 0x6E };
TLS_PRF prf;
SecureVector<byte> salt;
salt += std::make_pair(KEY_GEN_MAGIC, sizeof(KEY_GEN_MAGIC));
salt += s_random;
salt += c_random;
SymmetricKey keyblock = prf.derive_key(prf_gen, master_sec, salt);
const byte* key_data = keyblock.begin();
c_mac = SymmetricKey(key_data, mac_keylen);
key_data += mac_keylen;
s_mac = SymmetricKey(key_data, mac_keylen);
key_data += mac_keylen;
c_cipher = SymmetricKey(key_data, cipher_keylen);
key_data += cipher_keylen;
s_cipher = SymmetricKey(key_data, cipher_keylen);
key_data += cipher_keylen;
c_iv = InitializationVector(key_data, cipher_ivlen);
key_data += cipher_ivlen;
s_iv = InitializationVector(key_data, cipher_ivlen);
}
else
{
SymmetricKey keyblock = (version == SSL_V3) ?
ssl3_keygen(prf_gen, pre_master_secret, c_random, s_random) :
tls1_keygen(prf_gen, pre_master_secret, c_random, s_random);
const byte* key_data = keyblock.begin();
c_mac = SymmetricKey(key_data, mac_keylen);
key_data += mac_keylen;
s_mac = SymmetricKey(key_data, mac_keylen);
key_data += mac_keylen;
c_cipher = SymmetricKey(key_data, cipher_keylen);
key_data += cipher_keylen;
s_cipher = SymmetricKey(key_data, cipher_keylen);
key_data += cipher_keylen;
c_iv = InitializationVector(key_data, cipher_ivlen);
key_data += cipher_ivlen;
s_iv = InitializationVector(key_data, cipher_ivlen);
}
}
}
|