diff --git a/include/psa/crypto_accel_driver.h b/include/psa/crypto_accel_driver.h index 4a540f0fa..f60c2ec40 100644 --- a/include/psa/crypto_accel_driver.h +++ b/include/psa/crypto_accel_driver.h @@ -38,6 +38,107 @@ extern "C" { #endif +/** Import vendor defined key data into a slot. + * + * `slot->type` must have been set previously. + * This function assumes that the slot does not contain any key material yet. + * On failure, the slot content is unchanged. + * + * Persistent storage is not affected. + * + * \param[in,out] slot The key slot to import data into. + * Its `type` field must have previously been set to + * the desired key type. + * It must not contain any key material yet. + * \param[in] data Buffer containing the key material to parse and import. + * \param data_length Size of \p data in bytes. + * + * \retval PSA_SUCCESS + * \retval PSA_ERROR_INVALID_ARGUMENT + * \retval PSA_ERROR_NOT_SUPPORTED + * \retval PSA_ERROR_INSUFFICIENT_MEMORY + * \retval Implementation dependent + */ +psa_status_t psa_import_key_into_slot_vendor( psa_key_slot_t *slot, + const uint8_t *data, + size_t data_length ); + +/** + * \brief Generate a vendor defined key or key pair. + * + * \note This function has to be defined by the vendor if MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C + * is defined. Do not use this function directly; + * to generate a key, use psa_generate_key() instead. + * + * \param[in] slot + * \param[in] bits + * \param[in] domain_parameters + * \param[in] domain_parameters_size + * + * + * \retval #PSA_SUCCESS + * Success. + * If the key is persistent, the key material and the key's metadata + * have been saved to persistent storage. + * + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval Implementation dependent. + */ +psa_status_t psa_generate_key_vendor(psa_key_slot_t * slot, + size_t bits, + const uint8_t * domain_parameters, + size_t domain_parameters_size); + +/** + * \brief Generate symmetric key of vendor defined format. + * + * \warning This function **can** fail! Callers MUST check the return status + * and MUST NOT use the content of the output buffer if the return + * status is not #PSA_SUCCESS. + * + * \note This function has to be defined by the vendor if MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C + * is defined. + * A weakly linked version is provided by default and returns + * PSA_ERROR_NOT_SUPPORTED. Do not use this function directly; + * to generate a key, use psa_generate_key() instead. + * + * \param[in] type Type of symmetric key to be generated. + * \param[out] output Output buffer for the generated data. + * \param[out] output_size Number of bytes to generate and output. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_NOT_SUPPORTED + * \retval Implementation dependent + */ +psa_status_t psa_generate_symmetric_vendor(psa_key_type_t type, size_t bits, uint8_t * output, size_t output_size); + +/** + * \brief Perform vendor specific setup for cipher operations. + * + * + * \note This function has to be defined by the vendor if MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C + * is defined. + * A weakly linked version is provided by default and returns + * PSA_ERROR_NOT_SUPPORTED. Do not use this function directly; + * to generate a key, use psa_generate_key() instead. + * + * \param[in,out] operation The operation object to set up. It must have + * been initialized as per the documentation for + * #psa_cipher_operation_t and not yet in use. + * \param handle Handle to the key to use for the operation. + * It must remain valid until the operation + * terminates. + * \param alg The cipher algorithm to compute + * (\c PSA_ALG_XXX value such that + * #PSA_ALG_IS_CIPHER(\p alg) is true). + * + * \retval #PSA_SUCCESS + * Success. + * \retval #PSA_ERROR_NOT_SUPPORTED + * . + */ +psa_status_t psa_cipher_setup_vendor(psa_cipher_operation_t * operation, psa_key_handle_t handle, psa_algorithm_t alg, mbedtls_operation_t cipher_operation); + /** \defgroup driver_digest Hardware-Accelerated Message Digests * * Generation and authentication of Message Digests (aka hashes) must be done diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index f177d5d91..802d6ba97 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -378,7 +378,7 @@ static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes, psa_key_lifetime_t lifetime) { attributes->core.lifetime = lifetime; - if( lifetime == PSA_KEY_LIFETIME_VOLATILE ) + if (PSA_KEY_LIFETIME_IS_VOLATILE( lifetime) ) { #ifdef MBEDTLS_PSA_CRYPTO_KEY_FILE_ID_ENCODES_OWNER attributes->core.id.key_id = 0; diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index b53e1c769..bd7d14597 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -380,6 +380,9 @@ */ #define PSA_KEY_TYPE_AES ((psa_key_type_t)0x40000001) +/** Whether a key type is AES. */ +#define PSA_KEY_TYPE_IS_AES(type) (((type) == PSA_KEY_TYPE_AES) != 0) + /** Key for a cipher or MAC algorithm based on DES or 3DES (Triple-DES). * * The size of the key can be 8 bytes (single DES), 16 bytes (2-key 3DES) or @@ -1500,7 +1503,18 @@ * by other lifetime values as implementation-specific extensions. */ #define PSA_KEY_LIFETIME_PERSISTENT ((psa_key_lifetime_t)0x00000001) +#define PSA_KEY_LIFETIME_PERSISTENT_FLAG ((psa_key_lifetime_t)PSA_KEY_LIFETIME_PERSISTENT) +#define PSA_KEY_LIFETIME_IS_VOLATILE(lifetime) (((lifetime) & PSA_KEY_LIFETIME_PERSISTENT_FLAG) == 0) + +#define PSA_KEY_LIFETIME_IS_PERSISTENT(lifetime) \ + (((lifetime) & PSA_KEY_LIFETIME_PERSISTENT) != 0) + +#define PSA_KEY_LIFETIME_VENDOR_FLAG ((psa_key_lifetime_t)0x80000000) +#define PSA_KEY_LIFETIME_PERSISTENT_VENDOR (PSA_KEY_LIFETIME_VENDOR_FLAG | PSA_KEY_LIFETIME_PERSISTENT) +#define PSA_KEY_LIFETIME_VOLATILE_VENDOR (PSA_KEY_LIFETIME_VENDOR_FLAG | PSA_KEY_LIFETIME_VOLATILE) +#define PSA_KEY_LIFETIME_IS_VENDOR_DEFINED(lifetime) \ + (((lifetime) & PSA_KEY_LIFETIME_VENDOR_FLAG) != 0) /** The minimum value for a key identifier chosen by the application. */ #define PSA_KEY_ID_USER_MIN ((psa_app_key_id_t)0x00000001) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a80f13de3..5f5b43c1d 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -128,7 +128,7 @@ static psa_global_data_t global_data; if( global_data.initialized == 0 ) \ return( PSA_ERROR_BAD_STATE ); -static psa_status_t mbedtls_to_psa_error( int ret ) +psa_status_t mbedtls_to_psa_error( int ret ) { /* If there's both a high-level code and low-level code, dispatch on * the high-level code. */ @@ -407,7 +407,7 @@ static psa_ecc_curve_t mbedtls_ecc_group_to_psa( mbedtls_ecp_group_id grpid ) } } -static mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve ) +mbedtls_ecp_group_id mbedtls_ecc_group_of_psa( psa_ecc_curve_t curve ) { switch( curve ) { @@ -533,7 +533,7 @@ static psa_status_t psa_check_rsa_key_byte_aligned( return( status ); } -static psa_status_t psa_import_rsa_key( psa_key_type_t type, +psa_status_t psa_import_rsa_key( psa_key_type_t type, const uint8_t *data, size_t data_length, mbedtls_rsa_context **p_rsa ) @@ -594,7 +594,7 @@ static psa_status_t psa_import_rsa_key( psa_key_type_t type, /* Import a public key given as the uncompressed representation defined by SEC1 * 2.3.3 as the content of an ECPoint. */ -static psa_status_t psa_import_ec_public_key( psa_ecc_curve_t curve, +psa_status_t psa_import_ec_public_key( psa_ecc_curve_t curve, const uint8_t *data, size_t data_length, mbedtls_ecp_keypair **p_ecp ) @@ -1493,7 +1493,7 @@ static psa_status_t psa_validate_key_attributes( { psa_status_t status; - if( attributes->core.lifetime != PSA_KEY_LIFETIME_VOLATILE ) + if( PSA_KEY_LIFETIME_IS_PERSISTENT (attributes->core.lifetime)) { status = psa_validate_persistent_key_parameters( attributes->core.lifetime, attributes->core.id, @@ -1638,7 +1638,7 @@ static psa_status_t psa_start_key_creation( * \return If this function fails, the key slot is an invalid state. * You must call psa_fail_key_creation() to wipe and free the slot. */ -static psa_status_t psa_finish_key_creation( +psa_status_t psa_finish_key_creation( psa_key_slot_t *slot, psa_se_drv_table_entry_t *driver ) { @@ -1647,7 +1647,7 @@ static psa_status_t psa_finish_key_creation( (void) driver; #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - if( slot->attr.lifetime != PSA_KEY_LIFETIME_VOLATILE ) + if (PSA_KEY_LIFETIME_IS_PERSISTENT(slot->attr.lifetime )) { #if defined(MBEDTLS_PSA_CRYPTO_SE_C) if( driver != NULL ) @@ -1859,6 +1859,14 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes, } else #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ +#if defined (MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C) + if (PSA_KEY_LIFETIME_IS_VENDOR_DEFINED(slot->attr.lifetime)) + { + status = psa_import_key_into_slot_vendor( slot, data, data_length); + goto exit; + } + else +#endif /* MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C */ { status = psa_import_key_into_slot( slot, data, data_length ); if( status != PSA_SUCCESS ) @@ -2433,7 +2441,7 @@ psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation, /* MAC */ /****************************************************************/ -static const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( psa_algorithm_t alg, psa_key_type_t key_type, size_t key_bits, @@ -3120,7 +3128,7 @@ static psa_status_t psa_rsa_decode_md_type( psa_algorithm_t alg, return( PSA_SUCCESS ); } -static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa, +psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa, psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, @@ -3179,7 +3187,7 @@ static psa_status_t psa_rsa_sign( mbedtls_rsa_context *rsa, return( mbedtls_to_psa_error( ret ) ); } -static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa, +psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa, psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, @@ -3245,7 +3253,7 @@ static psa_status_t psa_rsa_verify( mbedtls_rsa_context *rsa, /* `ecp` cannot be const because `ecp->grp` needs to be non-const * for mbedtls_ecdsa_sign() and mbedtls_ecdsa_sign_det() * (even though these functions don't modify it). */ -static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp, +psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp, psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, @@ -3302,7 +3310,7 @@ static psa_status_t psa_ecdsa_sign( mbedtls_ecp_keypair *ecp, return( mbedtls_to_psa_error( ret ) ); } -static psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp, +psa_status_t psa_ecdsa_verify( mbedtls_ecp_keypair *ecp, const uint8_t *hash, size_t hash_length, const uint8_t *signature, @@ -3724,6 +3732,14 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, goto exit; key_bits = psa_get_key_slot_bits( slot ); +#if defined (MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C) + if (PSA_KEY_LIFETIME_IS_VENDOR_DEFINED(slot->attr.lifetime)) + { + status = psa_cipher_setup_vendor(operation, handle, alg, cipher_operation); + goto exit; + } +#endif /* MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C */ + cipher_info = mbedtls_cipher_info_from_psa( alg, slot->attr.type, key_bits, NULL ); if( cipher_info == NULL ) { @@ -3734,7 +3750,7 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, ret = mbedtls_cipher_setup( &operation->ctx.cipher, cipher_info ); if( ret != 0 ) goto exit; - + #if defined(MBEDTLS_DES_C) if( slot->attr.type == PSA_KEY_TYPE_DES && key_bits == 128 ) { @@ -3989,7 +4005,6 @@ psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation ) * always have been initialized to a valid value). */ if( ! PSA_ALG_IS_CIPHER( operation->alg ) ) return( PSA_ERROR_BAD_STATE ); - mbedtls_cipher_free( &operation->ctx.cipher ); operation->alg = 0; @@ -5375,7 +5390,7 @@ psa_status_t mbedtls_psa_inject_entropy( const uint8_t *seed, #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_GENPRIME) -static psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters, +psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters, size_t domain_parameters_size, int *exponent ) { @@ -5535,12 +5550,20 @@ psa_status_t psa_generate_key( const psa_key_attributes_t *attributes, } else #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ +#if defined (MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C) + if (PSA_KEY_LIFETIME_IS_VENDOR_DEFINED(slot->attr.lifetime)) + { + status = psa_generate_key_vendor(slot, attributes->core.bits, + attributes->domain_parameters, attributes->domain_parameters_size); + goto exit; + } + else +#endif /* MBEDTLS_PSA_CRYPTO_ACCEL_DRV_C */ { status = psa_generate_key_internal( slot, attributes->core.bits, attributes->domain_parameters, attributes->domain_parameters_size ); } - exit: if( status == PSA_SUCCESS ) status = psa_finish_key_creation( slot, driver ); diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index edf3ab603..3a08cbb43 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -109,7 +109,7 @@ static inline void psa_key_slot_set_flags( psa_key_slot_t *slot, uint16_t mask, uint16_t value ) { - slot->attr.flags = ( ( ~mask & slot->attr.flags ) | + slot->attr.flags = (psa_key_attributes_flag_t)( ( ~mask & slot->attr.flags ) | ( mask & value ) ); } @@ -132,7 +132,7 @@ static inline void psa_key_slot_set_bits_in_flags( psa_key_slot_t *slot, static inline void psa_key_slot_clear_bits( psa_key_slot_t *slot, uint16_t mask ) { - slot->attr.flags &= ~mask; + slot->attr.flags &= (psa_key_attributes_flag_t)~mask; } /** Completely wipe a slot in memory, including its policy.