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 }