1 /**
2 * TLS Session Key
3 * 
4 * Copyright:
5 * (C) 2004-2006,2011 Jack Lloyd
6 * (C) 2014-2015 Etienne Cimon
7 *
8 * License:
9 * Botan is released under the Simplified BSD License (see LICENSE.md)
10 */
11 module botan.tls.session_key;
12 
13 import botan.constants;
14 static if (BOTAN_HAS_TLS):
15 package:
16 
17 import botan.algo_base.symkey;
18 import botan.tls.handshake_state;
19 import botan.tls.messages;
20 
21 /**
22 * TLS TLSSession Keys
23 */
24 struct TLSSessionKeys
25 {
26 public:
27     const(SymmetricKey) clientCipherKey() const { return m_c_cipher; }
28     const(SymmetricKey) serverCipherKey() const { return m_s_cipher; }
29 
30     const(SymmetricKey) clientMacKey() const { return m_c_mac; }
31     const(SymmetricKey) serverMacKey() const { return m_s_mac; }
32 
33     const(InitializationVector) clientIv() const { return m_c_iv; }
34     const(InitializationVector) serverIv() const { return m_s_iv; }
35 
36     ref const(SecureVector!ubyte) masterSecret() const { return m_master_sec; }
37 
38     @disable this();
39 
40     /**
41     * TLSSessionKeys Constructor
42     */
43     this()(in HandshakeState state, auto ref SecureVector!ubyte pre_master_secret, bool resuming)
44     {
45         const size_t cipher_keylen = state.ciphersuite().cipherKeylen();
46         const size_t mac_keylen = state.ciphersuite().macKeylen();
47         const size_t cipher_nonce_bytes = state.ciphersuite().nonceBytesFromHandshake();
48         
49         const size_t prf_gen = 2 * (mac_keylen + cipher_keylen + cipher_nonce_bytes);
50         
51         __gshared immutable immutable(ubyte)[] MASTER_SECRET_MAGIC = [
52             0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74 ];
53         
54         __gshared immutable immutable(ubyte)[] KEY_GEN_MAGIC = [
55             0x6B, 0x65, 0x79, 0x20, 0x65, 0x78, 0x70, 0x61, 0x6E, 0x73, 0x69, 0x6F, 0x6E ];
56         
57         Unique!KDF prf = state.protocolSpecificPrf();
58         
59         if (resuming)
60         {
61             m_master_sec = pre_master_secret.dup;
62         }
63         else
64         {
65             SecureVector!ubyte salt;
66             
67             if (state.Version() != TLSProtocolVersion.SSL_V3)
68                 salt ~= cast(ubyte[])MASTER_SECRET_MAGIC;
69             
70             salt ~= state.clientHello().random()[];
71             salt ~= state.serverHello().random()[];
72             
73             m_master_sec = prf.deriveKey(48, pre_master_secret, salt);
74         }
75         
76         SecureVector!ubyte salt;
77         if (state.Version() != TLSProtocolVersion.SSL_V3)
78             salt ~= cast(ubyte[])KEY_GEN_MAGIC;
79         salt ~= state.serverHello().random()[];
80         salt ~= state.clientHello().random()[];
81         
82         SymmetricKey keyblock = prf.deriveKey(prf_gen, m_master_sec, salt);
83         
84         const(ubyte)* key_data = keyblock.ptr;
85         
86         m_c_mac = SymmetricKey(key_data, mac_keylen);
87         key_data += mac_keylen;
88         
89         m_s_mac = SymmetricKey(key_data, mac_keylen);
90         key_data += mac_keylen;
91         
92         m_c_cipher = SymmetricKey(key_data, cipher_keylen);
93         key_data += cipher_keylen;
94         
95         m_s_cipher = SymmetricKey(key_data, cipher_keylen);
96         key_data += cipher_keylen;
97         
98         m_c_iv = InitializationVector(key_data, cipher_nonce_bytes);
99         key_data += cipher_nonce_bytes;
100         
101         m_s_iv = InitializationVector(key_data, cipher_nonce_bytes);
102     }
103 
104 private:
105     SecureVector!ubyte m_master_sec;
106     SymmetricKey m_c_cipher, m_s_cipher, m_c_mac, m_s_mac;
107     InitializationVector m_c_iv, m_s_iv;
108 }