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 const bool extended_master_secret = state.serverHello().supportsExtendedMasterSecret(); 49 50 const size_t prf_gen = 2 * (mac_keylen + cipher_keylen + cipher_nonce_bytes); 51 52 __gshared immutable immutable(ubyte)[] MASTER_SECRET_MAGIC = [ 53 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74 ]; 54 55 __gshared immutable immutable(ubyte)[] KEY_GEN_MAGIC = [ 56 0x6B, 0x65, 0x79, 0x20, 0x65, 0x78, 0x70, 0x61, 0x6E, 0x73, 0x69, 0x6F, 0x6E ]; 57 58 __gshared immutable immutable(ubyte)[] EXT_MASTER_SECRET_MAGIC = [ 59 0x65, 0x78, 0x74, 0x65, 0x6E, 0x64, 0x65, 0x64, 0x20, 60 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74 ]; 61 62 Unique!KDF prf = state.protocolSpecificPrf(); 63 64 if (resuming) 65 { 66 m_master_sec = pre_master_secret.dup; 67 } 68 else 69 { 70 SecureVector!ubyte salt; 71 salt.reserve(64); 72 73 if (extended_master_secret) 74 { 75 salt ~= cast(ubyte[])EXT_MASTER_SECRET_MAGIC; 76 salt ~= state.hash().flushInto(state.Version(), 77 state.ciphersuite().prfAlgo()); 78 } 79 else 80 { 81 salt ~= cast(ubyte[])MASTER_SECRET_MAGIC; 82 salt ~= state.clientHello().random()[]; 83 salt ~= state.serverHello().random()[]; 84 } 85 86 m_master_sec = prf.deriveKey(48, pre_master_secret, salt); 87 } 88 89 SecureVector!ubyte salt; 90 salt.reserve(64); 91 salt ~= cast(ubyte[])KEY_GEN_MAGIC; 92 salt ~= state.serverHello().randomBytes(); 93 salt ~= state.clientHello().randomBytes(); 94 95 SymmetricKey keyblock = prf.deriveKey(prf_gen, m_master_sec, salt); 96 97 const(ubyte)* key_data = keyblock.ptr; 98 99 m_c_mac = SymmetricKey(key_data, mac_keylen); 100 key_data += mac_keylen; 101 102 m_s_mac = SymmetricKey(key_data, mac_keylen); 103 key_data += mac_keylen; 104 105 m_c_cipher = SymmetricKey(key_data, cipher_keylen); 106 key_data += cipher_keylen; 107 108 m_s_cipher = SymmetricKey(key_data, cipher_keylen); 109 key_data += cipher_keylen; 110 111 m_c_iv = InitializationVector(key_data, cipher_nonce_bytes); 112 key_data += cipher_nonce_bytes; 113 114 m_s_iv = InitializationVector(key_data, cipher_nonce_bytes); 115 } 116 117 private: 118 SecureVector!ubyte m_master_sec; 119 SymmetricKey m_c_cipher, m_s_cipher, m_c_mac, m_s_mac; 120 InitializationVector m_c_iv, m_s_iv; 121 }