From 83985826580f869583ca1c61097554e1ca3f05ea Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 30 Aug 2019 10:42:49 +0100 Subject: [PATCH 1/3] Fix SSL context deserialization The SSL context maintains a set of 'out pointers' indicating the address at which to write the header fields of the next outgoing record. Some of these addresses have a static offset from the beginning of the record header, while other offsets can vary depending on the active record encryption mechanism: For example, if an explicit IV is in use, there's an offset between the end of the record header and the beginning of the encrypted data to allow the explicit IV to be placed in between; also, if the DTLS Connection ID (CID) feature is in use, the CID is part of the record header, shifting all subsequent information (length, IV, data) to the back. When setting up an SSL context, the out pointers are initialized according to the identity transform + no CID, and it is important to keep them up to date whenever the record encryption mechanism changes, which is done by the helper function ssl_update_out_pointers(). During context deserialization, updating the out pointers according to the deserialized record transform went missing, leaving the out pointers the initial state. When attemping to encrypt a record in this state, this lead to failure if either a CID or an explicit IV was in use. This wasn't caught in the tests by the bad luck that they didn't use CID, _and_ used the default ciphersuite based on ChaChaPoly, which doesn't have an explicit IV. Changing either of this would have made the existing tests fail. This commit fixes the bug by adding a call to ssl_update_out_pointers() to ssl_context_load() implementing context deserialization. Extending test coverage is left for a separate commit. --- library/ssl_tls.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 96276c2b6..3aa6f37a1 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -11669,6 +11669,10 @@ static int ssl_context_load( mbedtls_ssl_context *ssl, ssl->minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; #endif /* !MBEDTLS_SSL_CONF_FIXED_MINOR_VER */ + /* Adjust pointers for header fields of outgoing records to + * the given transform, accounting for explicit IV and CID. */ + ssl_update_out_pointers( ssl, ssl->transform ); + #if defined(MBEDTLS_SSL_PROTO_DTLS) ssl->in_epoch = 1; #endif From e80c1b07cb3ff19e84505dcf2c88a4de5ff69149 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 30 Aug 2019 11:18:59 +0100 Subject: [PATCH 2/3] ssl-opt.sh: Duplicate context serialization tests for CID This commit introduces a variant of each existing test for context serialization in ssl-opt.sh that also uses the DTLS Connection ID feature. --- tests/ssl-opt.sh | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 71dba368e..25214c889 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -1334,6 +1334,15 @@ run_test "Context serialization, client serializes" \ -c "Deserializing connection..." \ -S "Deserializing connection..." +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID +run_test "Context serialization, client serializes, with CID" \ + "$P_SRV dtls=1 serialize=0 exchanges=2 cid=1 cid_val=dead" \ + "$P_CLI dtls=1 serialize=1 exchanges=2 cid=1 cid_val=beef" \ + 0 \ + -c "Deserializing connection..." \ + -S "Deserializing connection..." + requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION run_test "Context serialization, server serializes" \ "$P_SRV dtls=1 serialize=1 exchanges=2" \ @@ -1342,6 +1351,15 @@ run_test "Context serialization, server serializes" \ -C "Deserializing connection..." \ -s "Deserializing connection..." +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID +run_test "Context serialization, server serializes, with CID" \ + "$P_SRV dtls=1 serialize=1 exchanges=2 cid=1 cid_val=dead" \ + "$P_CLI dtls=1 serialize=0 exchanges=2 cid=1 cid_val=beef" \ + 0 \ + -C "Deserializing connection..." \ + -s "Deserializing connection..." + requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION run_test "Context serialization, both serialize" \ "$P_SRV dtls=1 serialize=1 exchanges=2" \ @@ -1350,6 +1368,15 @@ run_test "Context serialization, both serialize" \ -c "Deserializing connection..." \ -s "Deserializing connection..." +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID +run_test "Context serialization, both serialize, with CID" \ + "$P_SRV dtls=1 serialize=1 exchanges=2 cid=1 cid_val=dead" \ + "$P_CLI dtls=1 serialize=1 exchanges=2 cid=1 cid_val=beef" \ + 0 \ + -c "Deserializing connection..." \ + -s "Deserializing connection..." + requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION run_test "Context serialization, re-init, client serializes" \ "$P_SRV dtls=1 serialize=0 exchanges=2" \ @@ -1358,6 +1385,15 @@ run_test "Context serialization, re-init, client serializes" \ -c "Deserializing connection..." \ -S "Deserializing connection..." +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID +run_test "Context serialization, re-init, client serializes, with CID" \ + "$P_SRV dtls=1 serialize=0 exchanges=2 cid=1 cid_val=dead" \ + "$P_CLI dtls=1 serialize=2 exchanges=2 cid=1 cid_val=beef" \ + 0 \ + -c "Deserializing connection..." \ + -S "Deserializing connection..." + requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION run_test "Context serialization, re-init, server serializes" \ "$P_SRV dtls=1 serialize=2 exchanges=2" \ @@ -1366,6 +1402,15 @@ run_test "Context serialization, re-init, server serializes" \ -C "Deserializing connection..." \ -s "Deserializing connection..." +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID +run_test "Context serialization, re-init, server serializes, with CID" \ + "$P_SRV dtls=1 serialize=2 exchanges=2 cid=1 cid_val=dead" \ + "$P_CLI dtls=1 serialize=0 exchanges=2 cid=1 cid_val=beef" \ + 0 \ + -C "Deserializing connection..." \ + -s "Deserializing connection..." + requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION run_test "Context serialization, re-init, both serialize" \ "$P_SRV dtls=1 serialize=2 exchanges=2" \ @@ -1374,6 +1419,15 @@ run_test "Context serialization, re-init, both serialize" \ -c "Deserializing connection..." \ -s "Deserializing connection..." +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +requires_config_enabled MBEDTLS_SSL_DTLS_CONNECTION_ID +run_test "Context serialization, re-init, both serialize, with CID" \ + "$P_SRV dtls=1 serialize=2 exchanges=2 cid=1 cid_val=dead" \ + "$P_CLI dtls=1 serialize=2 exchanges=2 cid=1 cid_val=beef" \ + 0 \ + -c "Deserializing connection..." \ + -s "Deserializing connection..." + # Tests for DTLS Connection ID extension # So far, the CID API isn't implemented, so we can't From 2e72dd8b9a9d45b501e466f8514e0c359db567e9 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 30 Aug 2019 11:32:12 +0100 Subject: [PATCH 3/3] ssl-opt.sh: Add var's of context s11n tests for ChaChaPoly,CCM,GCM This commit splits each test in ssl-opt.sh related to context serialization in three tests, exercising the use of CCM, GCM and ChaChaPoly separately. The reason is that the choice of primitive affects the presence and size of an explicit IV, and we should test that space for those IVs is correctly restored during context deserialization; in fact, this was not the case previously, as fixed in the last commit, and was not caught by the tests because only ChaChaPoly was tested. --- tests/ssl-opt.sh | 120 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 108 insertions(+), 12 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 25214c889..67fee3311 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -1327,9 +1327,25 @@ run_test "Truncated HMAC, DTLS: client enabled, server enabled" \ # Tests for Context serialization requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION -run_test "Context serialization, client serializes" \ +run_test "Context serialization, client serializes, CCM" \ "$P_SRV dtls=1 serialize=0 exchanges=2" \ - "$P_CLI dtls=1 serialize=1 exchanges=2" \ + "$P_CLI dtls=1 serialize=1 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \ + 0 \ + -c "Deserializing connection..." \ + -S "Deserializing connection..." + +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +run_test "Context serialization, client serializes, ChaChaPoly" \ + "$P_SRV dtls=1 serialize=0 exchanges=2" \ + "$P_CLI dtls=1 serialize=1 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \ + 0 \ + -c "Deserializing connection..." \ + -S "Deserializing connection..." + +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +run_test "Context serialization, client serializes, GCM" \ + "$P_SRV dtls=1 serialize=0 exchanges=2" \ + "$P_CLI dtls=1 serialize=1 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" \ 0 \ -c "Deserializing connection..." \ -S "Deserializing connection..." @@ -1344,9 +1360,25 @@ run_test "Context serialization, client serializes, with CID" \ -S "Deserializing connection..." requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION -run_test "Context serialization, server serializes" \ +run_test "Context serialization, server serializes, CCM" \ "$P_SRV dtls=1 serialize=1 exchanges=2" \ - "$P_CLI dtls=1 serialize=0 exchanges=2" \ + "$P_CLI dtls=1 serialize=0 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \ + 0 \ + -C "Deserializing connection..." \ + -s "Deserializing connection..." + +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +run_test "Context serialization, server serializes, ChaChaPoly" \ + "$P_SRV dtls=1 serialize=1 exchanges=2" \ + "$P_CLI dtls=1 serialize=0 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \ + 0 \ + -C "Deserializing connection..." \ + -s "Deserializing connection..." + +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +run_test "Context serialization, server serializes, GCM" \ + "$P_SRV dtls=1 serialize=1 exchanges=2" \ + "$P_CLI dtls=1 serialize=0 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" \ 0 \ -C "Deserializing connection..." \ -s "Deserializing connection..." @@ -1361,9 +1393,25 @@ run_test "Context serialization, server serializes, with CID" \ -s "Deserializing connection..." requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION -run_test "Context serialization, both serialize" \ +run_test "Context serialization, both serialize, CCM" \ "$P_SRV dtls=1 serialize=1 exchanges=2" \ - "$P_CLI dtls=1 serialize=1 exchanges=2" \ + "$P_CLI dtls=1 serialize=1 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \ + 0 \ + -c "Deserializing connection..." \ + -s "Deserializing connection..." + +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +run_test "Context serialization, both serialize, ChaChaPoly" \ + "$P_SRV dtls=1 serialize=1 exchanges=2" \ + "$P_CLI dtls=1 serialize=1 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \ + 0 \ + -c "Deserializing connection..." \ + -s "Deserializing connection..." + +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +run_test "Context serialization, both serialize, GCM" \ + "$P_SRV dtls=1 serialize=1 exchanges=2" \ + "$P_CLI dtls=1 serialize=1 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" \ 0 \ -c "Deserializing connection..." \ -s "Deserializing connection..." @@ -1378,9 +1426,25 @@ run_test "Context serialization, both serialize, with CID" \ -s "Deserializing connection..." requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION -run_test "Context serialization, re-init, client serializes" \ +run_test "Context serialization, re-init, client serializes, CCM" \ "$P_SRV dtls=1 serialize=0 exchanges=2" \ - "$P_CLI dtls=1 serialize=2 exchanges=2" \ + "$P_CLI dtls=1 serialize=2 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \ + 0 \ + -c "Deserializing connection..." \ + -S "Deserializing connection..." + +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +run_test "Context serialization, re-init, client serializes, ChaChaPoly" \ + "$P_SRV dtls=1 serialize=0 exchanges=2" \ + "$P_CLI dtls=1 serialize=2 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \ + 0 \ + -c "Deserializing connection..." \ + -S "Deserializing connection..." + +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +run_test "Context serialization, re-init, client serializes, GCM" \ + "$P_SRV dtls=1 serialize=0 exchanges=2" \ + "$P_CLI dtls=1 serialize=2 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256" \ 0 \ -c "Deserializing connection..." \ -S "Deserializing connection..." @@ -1395,9 +1459,25 @@ run_test "Context serialization, re-init, client serializes, with CID" \ -S "Deserializing connection..." requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION -run_test "Context serialization, re-init, server serializes" \ +run_test "Context serialization, re-init, server serializes, CCM" \ "$P_SRV dtls=1 serialize=2 exchanges=2" \ - "$P_CLI dtls=1 serialize=0 exchanges=2" \ + "$P_CLI dtls=1 serialize=0 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \ + 0 \ + -C "Deserializing connection..." \ + -s "Deserializing connection..." + +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +run_test "Context serialization, re-init, server serializes, ChaChaPoly" \ + "$P_SRV dtls=1 serialize=2 exchanges=2" \ + "$P_CLI dtls=1 serialize=0 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \ + 0 \ + -C "Deserializing connection..." \ + -s "Deserializing connection..." + +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +run_test "Context serialization, re-init, server serializes, GCM" \ + "$P_SRV dtls=1 serialize=2 exchanges=2" \ + "$P_CLI dtls=1 serialize=0 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \ 0 \ -C "Deserializing connection..." \ -s "Deserializing connection..." @@ -1412,9 +1492,25 @@ run_test "Context serialization, re-init, server serializes, with CID" \ -s "Deserializing connection..." requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION -run_test "Context serialization, re-init, both serialize" \ +run_test "Context serialization, re-init, both serialize, CCM" \ "$P_SRV dtls=1 serialize=2 exchanges=2" \ - "$P_CLI dtls=1 serialize=2 exchanges=2" \ + "$P_CLI dtls=1 serialize=2 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8" \ + 0 \ + -c "Deserializing connection..." \ + -s "Deserializing connection..." + +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +run_test "Context serialization, re-init, both serialize, ChaChaPoly" \ + "$P_SRV dtls=1 serialize=2 exchanges=2" \ + "$P_CLI dtls=1 serialize=2 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \ + 0 \ + -c "Deserializing connection..." \ + -s "Deserializing connection..." + +requires_config_enabled MBEDTLS_SSL_CONTEXT_SERIALIZATION +run_test "Context serialization, re-init, both serialize, GCM" \ + "$P_SRV dtls=1 serialize=2 exchanges=2" \ + "$P_CLI dtls=1 serialize=2 exchanges=2 force_ciphersuite=TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256" \ 0 \ -c "Deserializing connection..." \ -s "Deserializing connection..."