diff options
-rw-r--r-- | doc/relnotes/1_11_1.rst | 28 | ||||
-rw-r--r-- | src/tls/tls_session.cpp | 29 |
2 files changed, 40 insertions, 17 deletions
diff --git a/doc/relnotes/1_11_1.rst b/doc/relnotes/1_11_1.rst index 002437cc9..518f4702a 100644 --- a/doc/relnotes/1_11_1.rst +++ b/doc/relnotes/1_11_1.rst @@ -4,25 +4,33 @@ Version 1.11.1, Not Yet Released TLS and DTLS """""""""""""""""""""""""""""""""""""""" -Initial support for DTLS (v1.0 and v1.2) is available in this -release. - -Added :cpp:func:`TLS::Policy::acceptable_protocol_version` -and :cpp:func:`TLS::Policy::allow_server_initiated_renegotiation` +.. + Initial support for DTLS (v1.0 and v1.2) is available in this release + though it should be considered highly experimental. Currently timeouts + and retransmissions are not handled. :cpp:class:`TLS::Session_Manager_In_Memory` now chooses a random 256-bit key at startup and encrypts all sessions (using the existing :cpp:func:`TLS::Session::encrypt` mechanism) while they are stored in -memory. This is primarily to reduce pressure on ``mlock``ed memory, as -each session normally requires 48 bytes of locked memory for the -master secret, whereas now only 32 bytes are needed total. This change -may also make it slightly harder for an attacker to extract session -data from memory dumps (eg with a cold boot attack). +memory. This is primarily to reduce pressure on locked memory, as each +session normally requires 48 bytes of locked memory for the master +secret, whereas now only 32 bytes are needed total. This change may +also make it slightly harder for an attacker to extract session data +from memory dumps (eg with a cold boot attack). TLS clients were not sending a next protocol message during a session resumption, which would cause resumption failures with servers that support NPN if NPN was being offered by the client. +New policy hooks :cpp:func:`TLS::Policy::acceptable_protocol_version` +and :cpp:func:`TLS::Policy::allow_server_initiated_renegotiation` were +added. + +The keys used for session encryption were previously uniquely +determined by the master key. Now the encrypted session blob includes +two 80 bit salts which are used in the derivation of the cipher and +MAC keys. + A heartbeat request send by the counterparty during a handshake would be passed to the application callback as a heartbeat response. diff --git a/src/tls/tls_session.cpp b/src/tls/tls_session.cpp index d2aae9a7e..ed51ea580 100644 --- a/src/tls/tls_session.cpp +++ b/src/tls/tls_session.cpp @@ -141,12 +141,13 @@ std::chrono::seconds Session::session_age() const namespace { -const u32bit SESSION_CRYPTO_MAGIC = 0x571B0E4E; +const u32bit SESSION_CRYPTO_MAGIC = 0x571B0E4F; const std::string SESSION_CRYPTO_CIPHER = "AES-256/CBC"; const std::string SESSION_CRYPTO_MAC = "HMAC(SHA-256)"; const std::string SESSION_CRYPTO_KDF = "KDF2(SHA-256)"; const size_t MAGIC_LENGTH = 4; +const size_t KEY_KDF_SALT_LENGTH = 10; const size_t MAC_KEY_LENGTH = 32; const size_t CIPHER_KEY_LENGTH = 32; const size_t CIPHER_IV_LENGTH = 16; @@ -160,15 +161,21 @@ Session::encrypt(const SymmetricKey& master_key, { std::unique_ptr<KDF> kdf(get_kdf(SESSION_CRYPTO_KDF)); + const secure_vector<byte> cipher_key_salt = + rng.random_vec(KEY_KDF_SALT_LENGTH); + + const secure_vector<byte> mac_key_salt = + rng.random_vec(KEY_KDF_SALT_LENGTH); + SymmetricKey cipher_key = kdf->derive_key(CIPHER_KEY_LENGTH, master_key.bits_of(), - "tls.session.cipher-key"); + cipher_key_salt); SymmetricKey mac_key = kdf->derive_key(MAC_KEY_LENGTH, master_key.bits_of(), - "tls.session.mac-key"); + mac_key_salt); InitializationVector cipher_iv(rng, 16); @@ -181,6 +188,8 @@ Session::encrypt(const SymmetricKey& master_key, std::vector<byte> out(MAGIC_LENGTH); store_be(SESSION_CRYPTO_MAGIC, &out[0]); + out += cipher_key_salt; + out += mac_key_salt; out += cipher_iv.bits_of(); out += ctext; @@ -198,6 +207,7 @@ Session Session::decrypt(const byte buf[], size_t buf_len, const size_t MIN_CTEXT_SIZE = 4 * 16; // due to 48 byte master secret if(buf_len < (MAGIC_LENGTH + + 2 * KEY_KDF_SALT_LENGTH + CIPHER_IV_LENGTH + MIN_CTEXT_SIZE + MAC_OUTPUT_LENGTH)) @@ -208,10 +218,14 @@ Session Session::decrypt(const byte buf[], size_t buf_len, std::unique_ptr<KDF> kdf(get_kdf(SESSION_CRYPTO_KDF)); + const byte* cipher_key_salt = &buf[MAGIC_LENGTH]; + + const byte* mac_key_salt = &buf[MAGIC_LENGTH + KEY_KDF_SALT_LENGTH]; + SymmetricKey mac_key = kdf->derive_key(MAC_KEY_LENGTH, master_key.bits_of(), - "tls.session.mac-key"); + mac_key_salt, KEY_KDF_SALT_LENGTH); std::unique_ptr<MessageAuthenticationCode> mac(get_mac(SESSION_CRYPTO_MAC)); mac->set_key(mac_key); @@ -225,11 +239,12 @@ Session Session::decrypt(const byte buf[], size_t buf_len, SymmetricKey cipher_key = kdf->derive_key(CIPHER_KEY_LENGTH, master_key.bits_of(), - "tls.session.cipher-key"); + cipher_key_salt, KEY_KDF_SALT_LENGTH); - InitializationVector cipher_iv(&buf[MAGIC_LENGTH], CIPHER_IV_LENGTH); + InitializationVector cipher_iv(&buf[MAGIC_LENGTH+2*KEY_KDF_SALT_LENGTH], + CIPHER_IV_LENGTH); - const size_t CTEXT_OFFSET = MAGIC_LENGTH + CIPHER_IV_LENGTH; + const size_t CTEXT_OFFSET = MAGIC_LENGTH + 2 * KEY_KDF_SALT_LENGTH + CIPHER_IV_LENGTH; Pipe pipe(get_cipher(SESSION_CRYPTO_CIPHER, cipher_key, cipher_iv, DECRYPTION)); pipe.process_msg(&buf[CTEXT_OFFSET], |