Remove ciphersuite_info from ssl_transform

Prior to this commit, the security parameter struct `ssl_transform`
contained a `ciphersuite_info` field pointing to the information
structure for the negotiated ciphersuite. However, the only
information extracted from that structure that was used in the core
encryption and decryption functions `ssl_encrypt_buf`/`ssl_decrypt_buf`
was the authentication tag length in case of an AEAD cipher.

The present commit removes the `ciphersuite_info` field from the
`ssl_transform` structure and adds an explicit `taglen` field
for AEAD authentication tag length.

This is in accordance with the principle that the `ssl_transform`
structure should contain the raw parameters needed for the record
encryption and decryption functions to work, but not the higher-level
information that gave rise to them. For example, the `ssl_transform`
structure implicitly contains the encryption/decryption keys within
their cipher contexts, but it doesn't contain the SSL master or
premaster secrets. Likewise, it contains an explicit `maclen`, while
the status of the 'Truncated HMAC' extension -- which  determines the
value of `maclen` when the `ssl_transform` structure is created in
`ssl_derive_keys` -- is not contained in `ssl_transform`.

The `ciphersuite_info` pointer was used in other places outside
the encryption/decryption functions during the handshake, and for
these functions to work, this commit adds a `ciphersuite_info` pointer
field to the handshake-local `ssl_handshake_params` structure.
This commit is contained in:
Hanno Becker 2017-12-27 21:34:08 +00:00 committed by Manuel Pégourié-Gonnard
parent e7f2df03a3
commit 8759e16242
4 changed files with 55 additions and 57 deletions

View file

@ -387,6 +387,8 @@ struct mbedtls_ssl_handshake_params
const unsigned char *, size_t,
unsigned char *, size_t);
mbedtls_ssl_ciphersuite_t const *ciphersuite_info;
size_t pmslen; /*!< premaster length */
unsigned char randbytes[64]; /*!< random bytes */
@ -430,12 +432,11 @@ struct mbedtls_ssl_transform
/*
* Session specific crypto layer
*/
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
/*!< Chosen cipersuite_info */
size_t minlen; /*!< min. ciphertext length */
size_t ivlen; /*!< IV length */
size_t fixed_ivlen; /*!< Fixed part of IV (AEAD) */
size_t maclen; /*!< MAC length */
size_t maclen; /*!< MAC(CBC) len */
size_t taglen; /*!< TAG(AEAD) len */
unsigned char iv_enc[16]; /*!< IV (encryption) */
unsigned char iv_dec[16]; /*!< IV (decryption) */

View file

@ -1312,7 +1312,7 @@ static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl,
{
int ret;
if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
if( ssl->handshake->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) );
@ -1675,9 +1675,8 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
/*
* Initialize update checksum functions
*/
ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i );
if( ssl->transform_negotiate->ciphersuite_info == NULL )
ssl->handshake->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i );
if( ssl->handshake->ciphersuite_info == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) );
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
@ -1685,7 +1684,7 @@ static int ssl_parse_server_hello( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
mbedtls_ssl_optimize_checksum( ssl, ssl->handshake->ciphersuite_info );
MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) );
MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n );
@ -2330,7 +2329,7 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
{
int ret;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
unsigned char *p = NULL, *end = NULL;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
@ -2670,7 +2669,7 @@ exit:
static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
@ -2692,7 +2691,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
size_t n = 0;
size_t cert_type_len = 0, dn_len = 0;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
@ -2893,7 +2892,7 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
int ret;
size_t i, n;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
@ -3183,7 +3182,7 @@ ecdh_calc_secret:
static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
int ret;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
@ -3213,7 +3212,7 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
size_t n = 0, offset = 0;
unsigned char hash[48];
unsigned char *hash_start = hash;
@ -3323,8 +3322,7 @@ sign:
* Reason: Otherwise we should have running hashes for SHA512 and SHA224
* in order to satisfy 'weird' needs from the server side.
*/
if( ssl->transform_negotiate->ciphersuite_info->mac ==
MBEDTLS_MD_SHA384 )
if( ssl->handshake->ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
{
md_alg = MBEDTLS_MD_SHA384;
ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384;

View file

@ -1155,7 +1155,7 @@ have_ciphersuite_v2:
MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) );
ssl->session_negotiate->ciphersuite = ciphersuites[i];
ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
ssl->handshake->ciphersuite_info = ciphersuite_info;
/*
* SSLv2 Client Hello relevant renegotiation security checks
@ -1999,7 +1999,7 @@ have_ciphersuite:
MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) );
ssl->session_negotiate->ciphersuite = ciphersuites[i];
ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
ssl->handshake->ciphersuite_info = ciphersuite_info;
ssl->state++;
@ -2266,7 +2266,7 @@ static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl,
*olen = 0;
/* Skip costly computation if not needed */
if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
if( ssl->handshake->ciphersuite_info->key_exchange !=
MBEDTLS_KEY_EXCHANGE_ECJPAKE )
return;
@ -2649,7 +2649,7 @@ static int ssl_write_server_hello( mbedtls_ssl_context *ssl )
static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) );
@ -2672,7 +2672,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
{
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
size_t dn_size, total_dn_size; /* excluding length bytes */
size_t ct_len, sa_len; /* including length bytes */
unsigned char *buf, *p;
@ -2899,7 +2899,8 @@ static int ssl_prepare_server_key_exchange( mbedtls_ssl_context *ssl,
size_t *signature_len )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_PFS__ENABLED)
#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED)
unsigned char *dig_signed = NULL;
@ -3265,7 +3266,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
size_t signature_len = 0;
#if defined(MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED)
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
#endif /* MBEDTLS_KEY_EXCHANGE__SOME_NON_PFS__ENABLED */
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
@ -3711,7 +3712,7 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
unsigned char *p, *end;
ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
ciphersuite_info = ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) );
@ -3994,7 +3995,7 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
@ -4025,7 +4026,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl )
#endif
mbedtls_md_type_t md_alg;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );

View file

@ -619,6 +619,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
size_t mac_key_len;
size_t iv_copy_len;
unsigned keylen;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
const mbedtls_cipher_info_t *cipher_info;
const mbedtls_md_info_t *md_info;
@ -628,19 +629,20 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) );
cipher_info = mbedtls_cipher_info_from_type( transform->ciphersuite_info->cipher );
ciphersuite_info = handshake->ciphersuite_info;
cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher );
if( cipher_info == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found",
transform->ciphersuite_info->cipher ) );
ciphersuite_info->cipher ) );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
md_info = mbedtls_md_info_from_type( transform->ciphersuite_info->mac );
md_info = mbedtls_md_info_from_type( ciphersuite_info->mac );
if( md_info == NULL )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found",
transform->ciphersuite_info->mac ) );
ciphersuite_info->mac ) );
return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
}
@ -668,7 +670,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_PROTO_TLS1_2)
#if defined(MBEDTLS_SHA512_C)
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 &&
transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
{
handshake->tls_prf = tls_prf_sha384;
handshake->calc_verify = ssl_calc_verify_tls_sha384;
@ -720,8 +722,7 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 )
{
#if defined(MBEDTLS_SHA512_C)
if( ssl->transform_negotiate->ciphersuite_info->mac ==
MBEDTLS_MD_SHA384 )
if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 )
{
hash_len = 48;
}
@ -811,10 +812,12 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
cipher_info->mode == MBEDTLS_MODE_CCM ||
cipher_info->mode == MBEDTLS_MODE_CHACHAPOLY )
{
size_t taglen, explicit_ivlen;
size_t explicit_ivlen;
transform->maclen = 0;
mac_key_len = 0;
transform->taglen =
ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
/* All modes haves 96-bit IVs;
* GCM and CCM has 4 implicit and 8 explicit bytes
@ -826,14 +829,9 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
else
transform->fixed_ivlen = 4;
/* All modes have 128-bit tags, except CCM_8 (ciphersuite flag) */
taglen = transform->ciphersuite_info->flags &
MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
/* Minimum length of encrypted record */
explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
transform->minlen = explicit_ivlen + taglen;
transform->minlen = explicit_ivlen + transform->taglen;
}
else
{
@ -1560,8 +1558,6 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
unsigned char add_data[13];
unsigned char iv[12];
mbedtls_ssl_transform *transform = ssl->transform_out;
unsigned char taglen = transform->ciphersuite_info->flags &
MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
size_t explicit_ivlen = transform->ivlen - transform->fixed_ivlen;
/*
@ -1628,7 +1624,8 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
add_data, 13,
enc_msg, enc_msglen,
enc_msg, &olen,
enc_msg + enc_msglen, taglen ) ) != 0 )
enc_msg + enc_msglen,
transform->taglen ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret );
return( ret );
@ -1640,10 +1637,11 @@ static int ssl_encrypt_buf( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
}
ssl->out_msglen += taglen;
ssl->out_msglen += ssl->transform_out->taglen;
auth_done++;
MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen );
MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen,
ssl->transform_out->taglen );
}
else
#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */
@ -1851,21 +1849,19 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
unsigned char add_data[13];
unsigned char iv[12];
mbedtls_ssl_transform *transform = ssl->transform_in;
unsigned char taglen = transform->ciphersuite_info->flags &
MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16;
size_t explicit_iv_len = transform->ivlen - transform->fixed_ivlen;
/*
* Compute and update sizes
*/
if( ssl->in_msglen < explicit_iv_len + taglen )
if( ssl->in_msglen < explicit_iv_len + transform->taglen )
{
MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) "
"+ taglen (%d)", ssl->in_msglen,
explicit_iv_len, taglen ) );
explicit_iv_len, transform->taglen ) );
return( MBEDTLS_ERR_SSL_INVALID_MAC );
}
dec_msglen = ssl->in_msglen - explicit_iv_len - taglen;
dec_msglen = ssl->in_msglen - explicit_iv_len - transform->taglen;
dec_msg = ssl->in_msg;
dec_msg_result = ssl->in_msg;
@ -1911,7 +1907,8 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
}
MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", iv, transform->ivlen );
MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen );
MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen,
transform->taglen );
/*
* Decrypt and authenticate
@ -1921,7 +1918,8 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
add_data, 13,
dec_msg, dec_msglen,
dec_msg_result, &olen,
dec_msg + dec_msglen, taglen ) ) != 0 )
dec_msg + dec_msglen,
transform->taglen ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret );
@ -2237,7 +2235,7 @@ static int ssl_decrypt_buf( mbedtls_ssl_context *ssl )
const size_t max_len = ssl->in_msglen + padlen;
const size_t min_len = ( max_len > 256 ) ? max_len - 256 : 0;
switch( ssl->transform_in->ciphersuite_info->mac )
switch( ssl->handshake->ciphersuite_info->mac )
{
#if defined(MBEDTLS_MD5_C) || defined(MBEDTLS_SHA1_C) || \
defined(MBEDTLS_SHA256_C)
@ -5281,7 +5279,7 @@ int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl,
/* No certificate support -> dummy functions */
int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
@ -5301,7 +5299,7 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
{
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
@ -5327,7 +5325,7 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
size_t i, n;
const mbedtls_x509_crt *crt;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->handshake->ciphersuite_info;
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
@ -5645,7 +5643,7 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
{
int ret;
const mbedtls_ssl_ciphersuite_t * const ciphersuite_info =
ssl->transform_negotiate->ciphersuite_info;
ssl->handshake->ciphersuite_info;
#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
const int authmode = ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET
? ssl->handshake->sni_authmode