Add TLS 1.3 specific key to SSL transform conversion function
This commit adds the TLS 1.3 specific internal function
```
mbedtls_ssl_tls13_populate_transform()
```
which creates an instance of the SSL transform structure
`mbedtls_ssl_transform` representing a TLS 1.3 record protection
mechanism.
It is analogous to the existing internal helper function
```
ssl_tls12_populate_transform()
```
which creates transform structures representing record
protection mechanisms in TLS 1.2 and earlier.
Signed-off-by: Hanno Becker <hanno.becker@arm.com>
diff --git a/library/ssl_tls13_keys.c b/library/ssl_tls13_keys.c
index f1c8a12..2831313 100644
--- a/library/ssl_tls13_keys.c
+++ b/library/ssl_tls13_keys.c
@@ -699,4 +699,112 @@
return( ret );
}
+int mbedtls_ssl_tls13_populate_transform( mbedtls_ssl_transform *transform,
+ int endpoint,
+ int ciphersuite,
+ mbedtls_ssl_key_set const *traffic_keys,
+ mbedtls_ssl_context *ssl /* DEBUG ONLY */ )
+{
+ int ret;
+ mbedtls_cipher_info_t const *cipher_info;
+ const mbedtls_ssl_ciphersuite_t *ciphersuite_info;
+ unsigned char const *key_enc;
+ unsigned char const *iv_enc;
+ unsigned char const *key_dec;
+ unsigned char const *iv_dec;
+
+#if !defined(MBEDTLS_DEBUG_C)
+ ssl = NULL; /* make sure we don't use it except for those cases */
+ (void) ssl;
+#endif
+
+ ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuite );
+
+ cipher_info = mbedtls_cipher_info_from_type( ciphersuite_info->cipher );
+ if( cipher_info == NULL )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ /*
+ * Setup cipher contexts in target transform
+ */
+
+ if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc,
+ cipher_info ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
+ return( ret );
+ }
+
+ if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec,
+ cipher_info ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret );
+ return( ret );
+ }
+
+#if defined(MBEDTLS_SSL_SRV_C)
+ if( endpoint == MBEDTLS_SSL_IS_SERVER )
+ {
+ key_enc = traffic_keys->server_write_key;
+ key_dec = traffic_keys->client_write_key;
+ iv_enc = traffic_keys->server_write_iv;
+ iv_dec = traffic_keys->client_write_iv;
+ }
+ else
+#endif /* MBEDTLS_SSL_SRV_C */
+#if defined(MBEDTLS_SSL_CLI_C)
+ if( endpoint == MBEDTLS_SSL_IS_CLIENT )
+ {
+ key_enc = traffic_keys->client_write_key;
+ key_dec = traffic_keys->server_write_key;
+ iv_enc = traffic_keys->client_write_iv;
+ iv_dec = traffic_keys->server_write_iv;
+ }
+ else
+#endif /* MBEDTLS_SSL_CLI_C */
+ {
+ /* should not happen */
+ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
+ }
+
+ memcpy( transform->iv_enc, iv_enc, traffic_keys->iv_len );
+ memcpy( transform->iv_dec, iv_dec, traffic_keys->iv_len );
+
+ if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc,
+ key_enc, cipher_info->key_bitlen,
+ MBEDTLS_ENCRYPT ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
+ return( ret );
+ }
+
+ if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec,
+ key_dec, cipher_info->key_bitlen,
+ MBEDTLS_DECRYPT ) ) != 0 )
+ {
+ MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret );
+ return( ret );
+ }
+
+ /*
+ * Setup other fields in SSL transform
+ */
+
+ if( ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_SHORT_TAG ) != 0 )
+ transform->taglen = 8;
+ else
+ transform->taglen = 16;
+
+ transform->ivlen = traffic_keys->iv_len;
+ transform->maclen = 0;
+ transform->fixed_ivlen = transform->ivlen;
+ transform->minlen = transform->taglen + 1;
+ transform->minor_ver = MBEDTLS_SSL_MINOR_VERSION_4;
+
+ return( 0 );
+}
+
#endif /* MBEDTLS_SSL_PROTO_TLS1_3_EXPERIMENTAL */
diff --git a/library/ssl_tls13_keys.h b/library/ssl_tls13_keys.h
index 3b96998..ca892b1 100644
--- a/library/ssl_tls13_keys.h
+++ b/library/ssl_tls13_keys.h
@@ -498,4 +498,37 @@
unsigned char const *transcript,
unsigned char *result );
+/**
+ * \bref Setup an SSL transform structure representing the
+ * record protection mechanism used by TLS 1.3
+ *
+ * \param transform The SSL transform structure to be created. This must have
+ * been initialized through mbedtls_ssl_transform_init() and
+ * not used in any other way prior to calling this function.
+ * In particular, this function does not clean up the
+ * transform structure prior to installing the new keys.
+ * \param endpoint Indicates whether the transform is for the client
+ * (value #MBEDTLS_SSL_IS_CLIENT) or the server
+ * (value #MBEDTLS_SSL_IS_SERVER).
+ * \param ciphersuite The numerical identifier for the ciphersuite to use.
+ * This must be one of the identifiers listed in
+ * ssl_ciphersuites.h.
+ * \param traffic_keys The key material to use. No reference is stored in
+ * the SSL transform being generated, and the caller
+ * should destroy the key material afterwards.
+ * \param ssl (Debug-only) The SSL context to use for debug output
+ * in case of failure. This parameter is only needed if
+ * #MBEDTLS_DEBUG_C is set, and is ignored otherwise.
+ *
+ * \return \c 0 on success. In this case, \p transform is ready to
+ * be used with mbedtls_ssl_transform_decrypt() and
+ * mbedtls_ssl_transform_encrypt().
+ * \return A negative error code on failure.
+ */
+int mbedtls_ssl_tls13_populate_transform( mbedtls_ssl_transform *transform,
+ int endpoint,
+ int ciphersuite,
+ mbedtls_ssl_key_set const *traffic_keys,
+ mbedtls_ssl_context *ssl );
+
#endif /* MBEDTLS_SSL_TLS1_3_KEYS_H */