diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 6b4cda60a..fc7e7785c 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -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. */ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 03792fc39..959549785 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3274,6 +3274,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, @@ -3288,7 +3295,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. */ @@ -3418,7 +3425,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 @@ -3450,10 +3458,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; @@ -3463,59 +3478,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; @@ -3612,8 +3629,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 || @@ -3942,17 +3959,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; @@ -3982,7 +4003,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 ) @@ -3992,7 +4012,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: @@ -4005,7 +4025,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 ) { @@ -4032,7 +4051,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 ); @@ -4040,18 +4059,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 */ @@ -4116,7 +4134,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 @@ -4125,7 +4142,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 diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index ac026ff4c..ca40b03bf 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -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 */ diff --git a/library/psa_crypto_mac.h b/library/psa_crypto_mac.h index b7f2a6c3b..4da60bf40 100644 --- a/library/psa_crypto_mac.h +++ b/library/psa_crypto_mac.h @@ -23,96 +23,6 @@ #include -/** 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