diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 6dfaa1300..93ff6fb9d 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -224,65 +224,6 @@ void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats ); psa_status_t mbedtls_psa_inject_entropy(uint8_t *seed, size_t seed_size); -#if defined(PSA_PRE_1_0_KEY_DERIVATION) -/** Set up a key derivation operation. - * - * FIMXE This function is no longer part of the official API. Its prototype - * is only kept around for the sake of tests that haven't been updated yet. - * - * A key derivation algorithm takes three inputs: a secret input \p handle and - * two non-secret inputs \p label and p salt. - * The result of this function is a byte generator which can - * be used to produce keys and other cryptographic material. - * - * The role of \p label and \p salt is as follows: - * - For HKDF (#PSA_ALG_HKDF), \p salt is the salt used in the "extract" step - * and \p label is the info string used in the "expand" step. - * - * \param[in,out] operation The key derivation object to set up. It must - * have been initialized as per the documentation - * for #psa_key_derivation_operation_t and not - * yet be in use. - * \param handle Handle to the secret key. - * \param alg The key derivation algorithm to compute - * (\c PSA_ALG_XXX value such that - * #PSA_ALG_IS_KEY_DERIVATION(\p alg) is true). - * \param[in] salt Salt to use. - * \param salt_length Size of the \p salt buffer in bytes. - * \param[in] label Label to use. - * \param label_length Size of the \p label buffer in bytes. - * \param capacity The maximum number of bytes that the - * operation will be able to provide. - * - * \retval #PSA_SUCCESS - * Success. - * \retval #PSA_ERROR_INVALID_HANDLE - * \retval #PSA_ERROR_EMPTY_SLOT - * \retval #PSA_ERROR_NOT_PERMITTED - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \c key is not compatible with \c alg, - * or \p capacity is too large for the specified algorithm and key. - * \retval #PSA_ERROR_NOT_SUPPORTED - * \c alg is not supported or is not a key derivation algorithm. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * \retval #PSA_ERROR_COMMUNICATION_FAILURE - * \retval #PSA_ERROR_HARDWARE_FAILURE - * \retval #PSA_ERROR_CORRUPTION_DETECTED - * \retval #PSA_ERROR_BAD_STATE - * The library has not been previously initialized by psa_crypto_init(). - * It is implementation-dependent whether a failure to initialize - * results in this error code. - */ -psa_status_t psa_key_derivation(psa_key_derivation_operation_t *operation, - psa_key_handle_t handle, - psa_algorithm_t alg, - const uint8_t *salt, - size_t salt_length, - const uint8_t *label, - size_t label_length, - size_t capacity); -#endif /* PSA_PRE_1_0_KEY_DERIVATION */ - /** \addtogroup crypto_types * @{ */ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index bd801441a..787b5a737 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -4804,284 +4804,6 @@ psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attribut /* Key derivation */ /****************************************************************/ -#if defined(MBEDTLS_MD_C) -#if defined(PSA_PRE_1_0_KEY_DERIVATION) -/* Set up an HKDF-based operation. This is exactly the extract phase - * of the HKDF algorithm. - * - * Note that if this function fails, you must call psa_key_derivation_abort() - * to potentially free embedded data structures and wipe confidential data. - */ -static psa_status_t psa_key_derivation_hkdf_setup( psa_hkdf_key_derivation_t *hkdf, - const uint8_t *secret, - size_t secret_length, - psa_algorithm_t hash_alg, - const uint8_t *salt, - size_t salt_length, - const uint8_t *label, - size_t label_length ) -{ - psa_status_t status; - status = psa_hmac_setup_internal( &hkdf->hmac, - salt, salt_length, - hash_alg ); - if( status != PSA_SUCCESS ) - return( status ); - status = psa_hash_update( &hkdf->hmac.hash_ctx, secret, secret_length ); - if( status != PSA_SUCCESS ) - return( status ); - status = psa_hmac_finish_internal( &hkdf->hmac, - hkdf->prk, - sizeof( hkdf->prk ) ); - if( status != PSA_SUCCESS ) - return( status ); - hkdf->offset_in_block = PSA_HASH_SIZE( hash_alg ); - hkdf->block_number = 0; - hkdf->info_length = label_length; - if( label_length != 0 ) - { - hkdf->info = mbedtls_calloc( 1, label_length ); - if( hkdf->info == NULL ) - return( PSA_ERROR_INSUFFICIENT_MEMORY ); - memcpy( hkdf->info, label, label_length ); - } - hkdf->state = HKDF_STATE_KEYED; - hkdf->info_set = 1; - return( PSA_SUCCESS ); -} -#endif /* PSA_PRE_1_0_KEY_DERIVATION */ -#endif /* MBEDTLS_MD_C */ - -#if defined(MBEDTLS_MD_C) -#if defined(PSA_PRE_1_0_KEY_DERIVATION) -/* Set up a TLS-1.2-prf-based operation (see RFC 5246, Section 5). - * - * Note that if this function fails, you must call psa_key_derivation_abort() - * to potentially free embedded data structures and wipe confidential data. - */ -static psa_status_t psa_key_derivation_tls12_prf_setup( - psa_tls12_prf_key_derivation_t *tls12_prf, - const uint8_t *key, - size_t key_len, - psa_algorithm_t hash_alg, - const uint8_t *salt, - size_t salt_length, - const uint8_t *label, - size_t label_length ) -{ - uint8_t hash_length = PSA_HASH_SIZE( hash_alg ); - size_t Ai_with_seed_len = hash_length + salt_length + label_length; - int overflow; - - tls12_prf->key = mbedtls_calloc( 1, key_len ); - if( tls12_prf->key == NULL ) - return( PSA_ERROR_INSUFFICIENT_MEMORY ); - tls12_prf->key_len = key_len; - memcpy( tls12_prf->key, key, key_len ); - - overflow = ( salt_length + label_length < salt_length ) || - ( salt_length + label_length + hash_length < hash_length ); - if( overflow ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - tls12_prf->Ai_with_seed = mbedtls_calloc( 1, Ai_with_seed_len ); - if( tls12_prf->Ai_with_seed == NULL ) - return( PSA_ERROR_INSUFFICIENT_MEMORY ); - tls12_prf->Ai_with_seed_len = Ai_with_seed_len; - - /* Write `label + seed' at the end of the `A(i) + seed` buffer, - * leaving the initial `hash_length` bytes unspecified for now. */ - if( label_length != 0 ) - { - memcpy( tls12_prf->Ai_with_seed + hash_length, - label, label_length ); - } - - if( salt_length != 0 ) - { - memcpy( tls12_prf->Ai_with_seed + hash_length + label_length, - salt, salt_length ); - } - - /* The first block gets generated when - * psa_key_derivation_output_bytes() is called. */ - tls12_prf->block_number = 0; - tls12_prf->offset_in_block = hash_length; - - return( PSA_SUCCESS ); -} -#endif /* PSA_PRE_1_0_KEY_DERIVATION */ - -#if defined(PSA_PRE_1_0_KEY_DERIVATION) -/* Set up a TLS-1.2-PSK-to-MS-based operation. */ -static psa_status_t psa_key_derivation_tls12_psk_to_ms_setup( - psa_tls12_prf_key_derivation_t *tls12_prf, - const uint8_t *psk, - size_t psk_len, - psa_algorithm_t hash_alg, - const uint8_t *salt, - size_t salt_length, - const uint8_t *label, - size_t label_length ) -{ - psa_status_t status; - uint8_t pms[ 4 + 2 * PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ]; - - if( psk_len > PSA_ALG_TLS12_PSK_TO_MS_MAX_PSK_LEN ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - /* Quoting RFC 4279, Section 2: - * - * The premaster secret is formed as follows: if the PSK is N octets - * long, concatenate a uint16 with the value N, N zero octets, a second - * uint16 with the value N, and the PSK itself. - */ - - pms[0] = ( psk_len >> 8 ) & 0xff; - pms[1] = ( psk_len >> 0 ) & 0xff; - memset( pms + 2, 0, psk_len ); - pms[2 + psk_len + 0] = pms[0]; - pms[2 + psk_len + 1] = pms[1]; - memcpy( pms + 4 + psk_len, psk, psk_len ); - - status = psa_key_derivation_tls12_prf_setup( tls12_prf, - pms, 4 + 2 * psk_len, - hash_alg, - salt, salt_length, - label, label_length ); - - mbedtls_platform_zeroize( pms, sizeof( pms ) ); - return( status ); -} -#endif /* PSA_PRE_1_0_KEY_DERIVATION */ -#endif /* MBEDTLS_MD_C */ - -#if defined(PSA_PRE_1_0_KEY_DERIVATION) -/* Note that if this function fails, you must call psa_key_derivation_abort() - * to potentially free embedded data structures and wipe confidential data. - */ -static psa_status_t psa_key_derivation_internal( - psa_key_derivation_operation_t *operation, - const uint8_t *secret, size_t secret_length, - psa_algorithm_t alg, - const uint8_t *salt, size_t salt_length, - const uint8_t *label, size_t label_length, - size_t capacity ) -{ - psa_status_t status; - size_t max_capacity; - - /* Set operation->alg even on failure so that abort knows what to do. */ - operation->alg = alg; - -#if defined(MBEDTLS_MD_C) - if( PSA_ALG_IS_HKDF( alg ) ) - { - psa_algorithm_t hash_alg = PSA_ALG_HKDF_GET_HASH( alg ); - size_t hash_size = PSA_HASH_SIZE( hash_alg ); - if( hash_size == 0 ) - return( PSA_ERROR_NOT_SUPPORTED ); - max_capacity = 255 * hash_size; - status = psa_key_derivation_hkdf_setup( &operation->ctx.hkdf, - secret, secret_length, - hash_alg, - salt, salt_length, - label, label_length ); - } - /* TLS-1.2 PRF and TLS-1.2 PSK-to-MS are very similar, so share code. */ - else if( PSA_ALG_IS_TLS12_PRF( alg ) || - PSA_ALG_IS_TLS12_PSK_TO_MS( alg ) ) - { - psa_algorithm_t hash_alg = PSA_ALG_TLS12_PRF_GET_HASH( alg ); - size_t hash_size = PSA_HASH_SIZE( hash_alg ); - - /* TLS-1.2 PRF supports only SHA-256 and SHA-384. */ - if( hash_alg != PSA_ALG_SHA_256 && - hash_alg != PSA_ALG_SHA_384 ) - { - return( PSA_ERROR_NOT_SUPPORTED ); - } - - max_capacity = 255 * hash_size; - - if( PSA_ALG_IS_TLS12_PRF( alg ) ) - { - status = psa_key_derivation_tls12_prf_setup( &operation->ctx.tls12_prf, - secret, secret_length, - hash_alg, salt, salt_length, - label, label_length ); - } - else - { - status = psa_key_derivation_tls12_psk_to_ms_setup( - &operation->ctx.tls12_prf, - secret, secret_length, - hash_alg, salt, salt_length, - label, label_length ); - } - } - else -#endif - { - return( PSA_ERROR_NOT_SUPPORTED ); - } - - if( status != PSA_SUCCESS ) - return( status ); - - if( capacity <= max_capacity ) - operation->capacity = capacity; - else if( capacity == PSA_KEY_DERIVATION_UNLIMITED_CAPACITY ) - operation->capacity = max_capacity; - else - return( PSA_ERROR_INVALID_ARGUMENT ); - - return( PSA_SUCCESS ); -} -#endif /* PSA_PRE_1_0_KEY_DERIVATION */ - -#if defined(PSA_PRE_1_0_KEY_DERIVATION) -psa_status_t psa_key_derivation( psa_key_derivation_operation_t *operation, - psa_key_handle_t handle, - psa_algorithm_t alg, - const uint8_t *salt, - size_t salt_length, - const uint8_t *label, - size_t label_length, - size_t capacity ) -{ - psa_key_slot_t *slot; - psa_status_t status; - - if( operation->alg != 0 ) - return( PSA_ERROR_BAD_STATE ); - - /* Make sure that alg is a key derivation algorithm. This prevents - * key selection algorithms, which psa_key_derivation_internal - * accepts for the sake of key agreement. */ - if( ! PSA_ALG_IS_KEY_DERIVATION( alg ) ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_DERIVE, alg ); - if( status != PSA_SUCCESS ) - return( status ); - - if( slot->attr.type != PSA_KEY_TYPE_DERIVE ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - status = psa_key_derivation_internal( operation, - slot->data.raw.data, - slot->data.raw.bytes, - alg, - salt, salt_length, - label, label_length, - capacity ); - if( status != PSA_SUCCESS ) - psa_key_derivation_abort( operation ); - return( status ); -} -#endif /* PSA_PRE_1_0_KEY_DERIVATION */ - static psa_status_t psa_key_derivation_setup_kdf( psa_key_derivation_operation_t *operation, psa_algorithm_t kdf_alg )