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.
This commit is contained in:
Hanno Becker 2019-08-30 10:42:49 +01:00
parent 3ec504738e
commit 361b10d1c4

View File

@ -11950,6 +11950,10 @@ static int ssl_context_load( mbedtls_ssl_context *ssl,
ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3;
ssl->minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; ssl->minor_ver = MBEDTLS_SSL_MINOR_VERSION_3;
/* 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) #if defined(MBEDTLS_SSL_PROTO_DTLS)
ssl->in_epoch = 1; ssl->in_epoch = 1;
#endif #endif