aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/relnotes/1_11_1.rst28
-rw-r--r--src/tls/tls_session.cpp29
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],