Base the PSA implementation of TLS 1.2 PRF on the MAC API
This means there is no longer a need to have an internal HMAC API, so it is being removed in this commit as well. Signed-off-by: Steven Cooreman <steven.cooreman@silabs.com>
This commit is contained in:
parent
d1ed1d935f
commit
a6df6040ee
4 changed files with 81 additions and 166 deletions
|
@ -212,11 +212,13 @@ typedef struct psa_tls12_prf_key_derivation_s
|
|||
|
||||
psa_tls12_prf_key_derivation_state_t state;
|
||||
|
||||
uint8_t *secret;
|
||||
size_t secret_length;
|
||||
uint8_t *seed;
|
||||
size_t seed_length;
|
||||
uint8_t *label;
|
||||
size_t label_length;
|
||||
mbedtls_psa_hmac_operation_t hmac;
|
||||
|
||||
uint8_t Ai[PSA_HASH_MAX_SIZE];
|
||||
|
||||
/* `HMAC_hash( prk, A(i) + seed )` in the notation of RFC 5246, Sect. 5. */
|
||||
|
|
|
@ -3223,6 +3223,13 @@ psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation
|
|||
/* TLS-1.2 PSK-to-MS KDF uses the same core as TLS-1.2 PRF */
|
||||
PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
|
||||
{
|
||||
if( operation->ctx.tls12_prf.secret != NULL )
|
||||
{
|
||||
mbedtls_platform_zeroize( operation->ctx.tls12_prf.secret,
|
||||
operation->ctx.tls12_prf.secret_length );
|
||||
mbedtls_free( operation->ctx.tls12_prf.secret );
|
||||
}
|
||||
|
||||
if( operation->ctx.tls12_prf.seed != NULL )
|
||||
{
|
||||
mbedtls_platform_zeroize( operation->ctx.tls12_prf.seed,
|
||||
|
@ -3237,7 +3244,7 @@ psa_status_t psa_key_derivation_abort( psa_key_derivation_operation_t *operation
|
|||
mbedtls_free( operation->ctx.tls12_prf.label );
|
||||
}
|
||||
|
||||
status = psa_hmac_abort_internal( &operation->ctx.tls12_prf.hmac );
|
||||
status = PSA_SUCCESS;
|
||||
|
||||
/* We leave the fields Ai and output_block to be erased safely by the
|
||||
* mbedtls_platform_zeroize() in the end of this function. */
|
||||
|
@ -3367,7 +3374,8 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
|
|||
{
|
||||
psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg );
|
||||
uint8_t hash_length = PSA_HASH_LENGTH( hash_alg );
|
||||
mbedtls_psa_hmac_operation_t backup = MBEDTLS_PSA_HMAC_OPERATION_INIT;
|
||||
psa_mac_operation_t hmac = PSA_MAC_OPERATION_INIT;
|
||||
size_t hmac_output_length;
|
||||
psa_status_t status, cleanup_status;
|
||||
|
||||
/* We can't be wanting more output after block 0xff, otherwise
|
||||
|
@ -3399,10 +3407,17 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
|
|||
* `block_number`.
|
||||
*/
|
||||
|
||||
/* Save the hash context before using it, to preserve the hash state with
|
||||
* only the inner padding in it. We need this, because inner padding depends
|
||||
* on the key (secret in the RFC's terminology). */
|
||||
status = psa_hmac_clone_internal( &tls12_prf->hmac, &backup );
|
||||
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
|
||||
psa_set_key_type( &attributes, PSA_KEY_TYPE_HMAC );
|
||||
psa_set_key_bits( &attributes,
|
||||
PSA_BYTES_TO_BITS( tls12_prf->secret_length ) );
|
||||
psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
|
||||
|
||||
status = psa_driver_wrapper_mac_sign_setup( &hmac,
|
||||
&attributes,
|
||||
tls12_prf->secret,
|
||||
tls12_prf->secret_length,
|
||||
PSA_ALG_HMAC( hash_alg ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
|
||||
|
@ -3412,59 +3427,61 @@ static psa_status_t psa_key_derivation_tls12_prf_generate_next_block(
|
|||
/* A(1) = HMAC_hash(secret, A(0)), where A(0) = seed. (The RFC overloads
|
||||
* the variable seed and in this instance means it in the context of the
|
||||
* P_hash function, where seed = label + seed.) */
|
||||
status = psa_hmac_update_internal( &tls12_prf->hmac,
|
||||
tls12_prf->label,
|
||||
tls12_prf->label_length );
|
||||
status = psa_mac_update( &hmac,
|
||||
tls12_prf->label,
|
||||
tls12_prf->label_length );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
status = psa_hmac_update_internal( &tls12_prf->hmac,
|
||||
tls12_prf->seed,
|
||||
tls12_prf->seed_length );
|
||||
status = psa_mac_update( &hmac,
|
||||
tls12_prf->seed,
|
||||
tls12_prf->seed_length );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A(i) = HMAC_hash(secret, A(i-1)) */
|
||||
status = psa_hmac_update_internal( &tls12_prf->hmac,
|
||||
tls12_prf->Ai, hash_length );
|
||||
status = psa_mac_update( &hmac, tls12_prf->Ai, hash_length );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = psa_hmac_finish_internal( &tls12_prf->hmac,
|
||||
tls12_prf->Ai, hash_length );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
status = psa_hmac_clone_internal( &backup, &tls12_prf->hmac );
|
||||
status = psa_mac_sign_finish( &hmac,
|
||||
tls12_prf->Ai, hash_length,
|
||||
&hmac_output_length );
|
||||
if( hmac_output_length != hash_length )
|
||||
status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
|
||||
/* Calculate HMAC_hash(secret, A(i) + label + seed). */
|
||||
status = psa_hmac_update_internal( &tls12_prf->hmac,
|
||||
tls12_prf->Ai, hash_length );
|
||||
status = psa_driver_wrapper_mac_sign_setup( &hmac,
|
||||
&attributes,
|
||||
tls12_prf->secret,
|
||||
tls12_prf->secret_length,
|
||||
PSA_ALG_HMAC( hash_alg ) );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
status = psa_hmac_update_internal( &tls12_prf->hmac,
|
||||
tls12_prf->label, tls12_prf->label_length );
|
||||
status = psa_mac_update( &hmac, tls12_prf->Ai, hash_length );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
status = psa_hmac_update_internal( &tls12_prf->hmac,
|
||||
tls12_prf->seed, tls12_prf->seed_length );
|
||||
status = psa_mac_update( &hmac, tls12_prf->label, tls12_prf->label_length );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
status = psa_hmac_finish_internal( &tls12_prf->hmac,
|
||||
tls12_prf->output_block, hash_length );
|
||||
status = psa_mac_update( &hmac, tls12_prf->seed, tls12_prf->seed_length );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
status = psa_hmac_clone_internal( &backup, &tls12_prf->hmac );
|
||||
status = psa_mac_sign_finish( &hmac,
|
||||
tls12_prf->output_block, hash_length,
|
||||
&hmac_output_length );
|
||||
if( status != PSA_SUCCESS )
|
||||
goto cleanup;
|
||||
|
||||
|
||||
cleanup:
|
||||
psa_reset_key_attributes( &attributes );
|
||||
|
||||
cleanup_status = psa_hmac_abort_internal( &backup );
|
||||
cleanup_status = psa_mac_abort( &hmac );
|
||||
if( status == PSA_SUCCESS && cleanup_status != PSA_SUCCESS )
|
||||
status = cleanup_status;
|
||||
|
||||
|
@ -3561,8 +3578,8 @@ psa_status_t psa_key_derivation_output_bytes(
|
|||
PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
|
||||
{
|
||||
status = psa_key_derivation_tls12_prf_read( &operation->ctx.tls12_prf,
|
||||
kdf_alg, output,
|
||||
output_length );
|
||||
kdf_alg, output,
|
||||
output_length );
|
||||
}
|
||||
else
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PRF ||
|
||||
|
@ -3891,17 +3908,21 @@ static psa_status_t psa_tls12_prf_set_seed( psa_tls12_prf_key_derivation_t *prf,
|
|||
}
|
||||
|
||||
static psa_status_t psa_tls12_prf_set_key( psa_tls12_prf_key_derivation_t *prf,
|
||||
psa_algorithm_t hash_alg,
|
||||
const uint8_t *data,
|
||||
size_t data_length )
|
||||
{
|
||||
psa_status_t status;
|
||||
if( prf->state != PSA_TLS12_PRF_STATE_SEED_SET )
|
||||
return( PSA_ERROR_BAD_STATE );
|
||||
|
||||
status = psa_hmac_setup_internal( &prf->hmac, data, data_length, hash_alg );
|
||||
if( status != PSA_SUCCESS )
|
||||
return( status );
|
||||
if( data_length != 0 )
|
||||
{
|
||||
prf->secret = mbedtls_calloc( 1, data_length );
|
||||
if( prf->secret == NULL )
|
||||
return( PSA_ERROR_INSUFFICIENT_MEMORY );
|
||||
|
||||
memcpy( prf->secret, data, data_length );
|
||||
prf->secret_length = data_length;
|
||||
}
|
||||
|
||||
prf->state = PSA_TLS12_PRF_STATE_KEY_SET;
|
||||
|
||||
|
@ -3931,7 +3952,6 @@ static psa_status_t psa_tls12_prf_set_label( psa_tls12_prf_key_derivation_t *prf
|
|||
}
|
||||
|
||||
static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf,
|
||||
psa_algorithm_t hash_alg,
|
||||
psa_key_derivation_step_t step,
|
||||
const uint8_t *data,
|
||||
size_t data_length )
|
||||
|
@ -3941,7 +3961,7 @@ static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf,
|
|||
case PSA_KEY_DERIVATION_INPUT_SEED:
|
||||
return( psa_tls12_prf_set_seed( prf, data, data_length ) );
|
||||
case PSA_KEY_DERIVATION_INPUT_SECRET:
|
||||
return( psa_tls12_prf_set_key( prf, hash_alg, data, data_length ) );
|
||||
return( psa_tls12_prf_set_key( prf, data, data_length ) );
|
||||
case PSA_KEY_DERIVATION_INPUT_LABEL:
|
||||
return( psa_tls12_prf_set_label( prf, data, data_length ) );
|
||||
default:
|
||||
|
@ -3954,7 +3974,6 @@ static psa_status_t psa_tls12_prf_input( psa_tls12_prf_key_derivation_t *prf,
|
|||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS)
|
||||
static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
|
||||
psa_tls12_prf_key_derivation_t *prf,
|
||||
psa_algorithm_t hash_alg,
|
||||
const uint8_t *data,
|
||||
size_t data_length )
|
||||
{
|
||||
|
@ -3981,7 +4000,7 @@ static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
|
|||
memcpy( cur, data, data_length );
|
||||
cur += data_length;
|
||||
|
||||
status = psa_tls12_prf_set_key( prf, hash_alg, pms, cur - pms );
|
||||
status = psa_tls12_prf_set_key( prf, pms, cur - pms );
|
||||
|
||||
mbedtls_platform_zeroize( pms, sizeof( pms ) );
|
||||
return( status );
|
||||
|
@ -3989,18 +4008,17 @@ static psa_status_t psa_tls12_prf_psk_to_ms_set_key(
|
|||
|
||||
static psa_status_t psa_tls12_prf_psk_to_ms_input(
|
||||
psa_tls12_prf_key_derivation_t *prf,
|
||||
psa_algorithm_t hash_alg,
|
||||
psa_key_derivation_step_t step,
|
||||
const uint8_t *data,
|
||||
size_t data_length )
|
||||
{
|
||||
if( step == PSA_KEY_DERIVATION_INPUT_SECRET )
|
||||
{
|
||||
return( psa_tls12_prf_psk_to_ms_set_key( prf, hash_alg,
|
||||
return( psa_tls12_prf_psk_to_ms_set_key( prf,
|
||||
data, data_length ) );
|
||||
}
|
||||
|
||||
return( psa_tls12_prf_input( prf, hash_alg, step, data, data_length ) );
|
||||
return( psa_tls12_prf_input( prf, step, data, data_length ) );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */
|
||||
|
||||
|
@ -4065,7 +4083,6 @@ static psa_status_t psa_key_derivation_input_internal(
|
|||
if( PSA_ALG_IS_TLS12_PRF( kdf_alg ) )
|
||||
{
|
||||
status = psa_tls12_prf_input( &operation->ctx.tls12_prf,
|
||||
PSA_ALG_HKDF_GET_HASH( kdf_alg ),
|
||||
step, data, data_length );
|
||||
}
|
||||
else
|
||||
|
@ -4074,7 +4091,6 @@ static psa_status_t psa_key_derivation_input_internal(
|
|||
if( PSA_ALG_IS_TLS12_PSK_TO_MS( kdf_alg ) )
|
||||
{
|
||||
status = psa_tls12_prf_psk_to_ms_input( &operation->ctx.tls12_prf,
|
||||
PSA_ALG_HKDF_GET_HASH( kdf_alg ),
|
||||
step, data, data_length );
|
||||
}
|
||||
else
|
||||
|
|
|
@ -69,16 +69,18 @@ static size_t psa_get_hash_block_size( psa_algorithm_t alg )
|
|||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_hmac_abort_internal( mbedtls_psa_hmac_operation_t *hmac )
|
||||
static psa_status_t psa_hmac_abort_internal(
|
||||
mbedtls_psa_hmac_operation_t *hmac )
|
||||
{
|
||||
mbedtls_platform_zeroize( hmac->opad, sizeof( hmac->opad ) );
|
||||
return( psa_hash_abort( &hmac->hash_ctx ) );
|
||||
}
|
||||
|
||||
psa_status_t psa_hmac_setup_internal( mbedtls_psa_hmac_operation_t *hmac,
|
||||
const uint8_t *key,
|
||||
size_t key_length,
|
||||
psa_algorithm_t hash_alg )
|
||||
static psa_status_t psa_hmac_setup_internal(
|
||||
mbedtls_psa_hmac_operation_t *hmac,
|
||||
const uint8_t *key,
|
||||
size_t key_length,
|
||||
psa_algorithm_t hash_alg )
|
||||
{
|
||||
uint8_t ipad[PSA_HMAC_MAX_HASH_BLOCK_SIZE];
|
||||
size_t i;
|
||||
|
@ -139,16 +141,18 @@ cleanup:
|
|||
return( status );
|
||||
}
|
||||
|
||||
psa_status_t psa_hmac_update_internal( mbedtls_psa_hmac_operation_t *hmac,
|
||||
const uint8_t *data,
|
||||
size_t data_length )
|
||||
static psa_status_t psa_hmac_update_internal(
|
||||
mbedtls_psa_hmac_operation_t *hmac,
|
||||
const uint8_t *data,
|
||||
size_t data_length )
|
||||
{
|
||||
return( psa_hash_update( &hmac->hash_ctx, data, data_length ) );
|
||||
}
|
||||
|
||||
psa_status_t psa_hmac_finish_internal( mbedtls_psa_hmac_operation_t *hmac,
|
||||
uint8_t *mac,
|
||||
size_t mac_size )
|
||||
static psa_status_t psa_hmac_finish_internal(
|
||||
mbedtls_psa_hmac_operation_t *hmac,
|
||||
uint8_t *mac,
|
||||
size_t mac_size )
|
||||
{
|
||||
uint8_t tmp[MBEDTLS_MD_MAX_SIZE];
|
||||
psa_algorithm_t hash_alg = hmac->alg;
|
||||
|
@ -183,23 +187,6 @@ exit:
|
|||
mbedtls_platform_zeroize( tmp, hash_size );
|
||||
return( status );
|
||||
}
|
||||
|
||||
psa_status_t psa_hmac_clone_internal(
|
||||
const mbedtls_psa_hmac_operation_t *source,
|
||||
mbedtls_psa_hmac_operation_t *destination )
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
destination->alg = source->alg;
|
||||
destination->hash_ctx = psa_hash_operation_init();
|
||||
status = psa_hash_clone( &source->hash_ctx, &destination->hash_ctx );
|
||||
memcpy( destination->opad, source->opad, sizeof( destination->opad ) );
|
||||
|
||||
if( status != PSA_SUCCESS )
|
||||
memset( destination, 0, sizeof( *destination ) );
|
||||
|
||||
return( status );
|
||||
}
|
||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_HMAC || PSA_CRYPTO_DRIVER_TEST */
|
||||
|
||||
/* Implement the PSA driver MAC interface on top of mbed TLS if either the
|
||||
|
@ -457,8 +444,8 @@ static psa_status_t mac_update(
|
|||
#if defined(BUILTIN_ALG_HMAC)
|
||||
if( PSA_ALG_IS_HMAC( operation->alg ) )
|
||||
{
|
||||
return( psa_hash_update( &operation->ctx.hmac.hash_ctx, input,
|
||||
input_length ) );
|
||||
return( psa_hmac_update_internal( &operation->ctx.hmac,
|
||||
input, input_length ) );
|
||||
}
|
||||
else
|
||||
#endif /* BUILTIN_ALG_HMAC */
|
||||
|
|
|
@ -23,96 +23,6 @@
|
|||
|
||||
#include <psa/crypto.h>
|
||||
|
||||
/** Internal API for starting an HMAC operation, using PSA hash primitives.
|
||||
*
|
||||
* \note This API is not meant for application use. Applications should always
|
||||
* use the top-level psa_mac_xxx APIs for doing HMAC operations.
|
||||
*
|
||||
* \param[in] hmac Context structure for this HMAC operation. Needs to have
|
||||
* been zero-initialized prior to calling this function.
|
||||
* \param[in] key Key to initialize the HMAC operation with.
|
||||
* \param key_length Length (in bytes) of key \p key.
|
||||
* \param hash_alg Hash algorithm to use for calculating the HMAC.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \return Any error code reported by psa_hash_compute(), psa_hash_setup() or
|
||||
* psa_hash_update().
|
||||
*/
|
||||
psa_status_t psa_hmac_setup_internal( mbedtls_psa_hmac_operation_t *hmac,
|
||||
const uint8_t *key,
|
||||
size_t key_length,
|
||||
psa_algorithm_t hash_alg );
|
||||
|
||||
/** Internal API for adding data to an HMAC operation, using PSA hash primitives.
|
||||
*
|
||||
* \note This API is not meant for application use. Applications should always
|
||||
* use the top-level psa_mac_xxx APIs for doing HMAC operations.
|
||||
*
|
||||
* \param[in] hmac Context structure for this HMAC operation. Needs to have
|
||||
* been initialized with psa_hmac_setup_internal().
|
||||
* \param[in] data Buffer containing the data to add to the current HMAC
|
||||
* calculation.
|
||||
* \param data_length Length (in bytes) of the input buffer \p data.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \return Any error code reported by psa_hash_update().
|
||||
*/
|
||||
psa_status_t psa_hmac_update_internal( mbedtls_psa_hmac_operation_t *hmac,
|
||||
const uint8_t *data,
|
||||
size_t data_length );
|
||||
|
||||
/** Internal API for finalizing an HMAC operation, using PSA hash primitives.
|
||||
*
|
||||
* \note This API is not meant for application use. Applications should always
|
||||
* use the top-level psa_mac_xxx APIs for doing HMAC operations.
|
||||
*
|
||||
* \param[in] hmac Context structure for this HMAC operation. Needs to have
|
||||
* been initialized with psa_hmac_setup_internal().
|
||||
* \param[out] mac Buffer to output the calculated HMAC into.
|
||||
* \param mac_size Size (in bytes) of the output buffer \p mac.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \return Any error code reported by psa_hash_setup(), psa_hash_update() or
|
||||
* psa_hash_finish().
|
||||
*/
|
||||
psa_status_t psa_hmac_finish_internal( mbedtls_psa_hmac_operation_t *hmac,
|
||||
uint8_t *mac,
|
||||
size_t mac_size );
|
||||
|
||||
/** Internal API for cloning an HMAC operation, using PSA hash primitives.
|
||||
*
|
||||
* \note This API is not meant for application use. Applications should always
|
||||
* use the top-level psa_mac_xxx APIs for doing HMAC operations.
|
||||
*
|
||||
* \param[in] source Context structure to clone from. Needs to have been
|
||||
* initialized with psa_hmac_setup_internal().
|
||||
* \param[out] destination Context structure to clone to. Needs to have been
|
||||
* zero-initialized.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \return Any error code reported by psa_hash_clone().
|
||||
*/
|
||||
psa_status_t psa_hmac_clone_internal(
|
||||
const mbedtls_psa_hmac_operation_t *source,
|
||||
mbedtls_psa_hmac_operation_t *destination );
|
||||
|
||||
/** Internal API for aborting an HMAC operation, using PSA hash primitives.
|
||||
*
|
||||
* \note This API is not meant for application use. Applications should always
|
||||
* use the top-level psa_mac_xxx APIs for doing HMAC operations.
|
||||
*
|
||||
* \param[in] hmac Context structure for the HMAC operation to abort.
|
||||
*
|
||||
* \retval #PSA_SUCCESS
|
||||
* Success.
|
||||
* \return Any error code reported by psa_hash_abort().
|
||||
*/
|
||||
psa_status_t psa_hmac_abort_internal( mbedtls_psa_hmac_operation_t *hmac );
|
||||
|
||||
/** Calculate the MAC (message authentication code) of a message using Mbed TLS.
|
||||
*
|
||||
* \note The signature of this function is that of a PSA driver mac_compute
|
||||
|
|
Loading…
Reference in a new issue