diff --git a/library/psa_crypto.c b/library/psa_crypto.c index f2c8415f2..4824b45a3 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -33,7 +33,6 @@ #include "psa_crypto_invasive.h" #include "psa_crypto_driver_wrappers.h" #include "psa_crypto_ecp.h" -#include "psa_crypto_hash.h" #include "psa_crypto_rsa.h" #include "psa_crypto_ecp.h" #if defined(MBEDTLS_PSA_CRYPTO_SE_C) @@ -2198,20 +2197,7 @@ const mbedtls_md_info_t *mbedtls_md_info_from_psa( psa_algorithm_t alg ) psa_status_t psa_hash_abort( psa_hash_operation_t *operation ) { if( operation != NULL ) - { - if( operation->ctx.ctx != NULL ) - { - psa_status_t status = mbedtls_psa_hash_abort( operation->ctx.ctx ); - mbedtls_free( operation->ctx.ctx ); - operation->ctx.ctx = NULL; - return( status ); - } - else - { - // Multiple consequent calls to abort return success - return( PSA_SUCCESS ); - } - } + return( psa_driver_wrapper_hash_abort( &operation->ctx ) ); else return( PSA_ERROR_INVALID_ARGUMENT ); } @@ -2219,20 +2205,10 @@ psa_status_t psa_hash_abort( psa_hash_operation_t *operation ) psa_status_t psa_hash_setup( psa_hash_operation_t *operation, psa_algorithm_t alg ) { - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - if( operation == NULL || !PSA_ALG_IS_HASH( alg ) ) return( PSA_ERROR_INVALID_ARGUMENT ); - /* A context must be freshly initialized before it can be set up. */ - if( operation->ctx.ctx != NULL ) - return( PSA_ERROR_BAD_STATE ); - - operation->ctx.ctx = mbedtls_calloc( 1, sizeof(mbedtls_psa_hash_operation_t) ); - status = mbedtls_psa_hash_setup( operation->ctx.ctx, alg ); - if( status != PSA_SUCCESS ) - psa_hash_abort( operation ); - return( status ); + return( psa_driver_wrapper_hash_setup( &operation->ctx, alg ) ); } psa_status_t psa_hash_update( psa_hash_operation_t *operation, @@ -2241,14 +2217,9 @@ psa_status_t psa_hash_update( psa_hash_operation_t *operation, { if( operation == NULL ) return( PSA_ERROR_INVALID_ARGUMENT ); - if( operation->ctx.ctx == NULL ) - return( PSA_ERROR_BAD_STATE ); - psa_status_t status = mbedtls_psa_hash_update( operation->ctx.ctx, - input, input_length ); - if( status != PSA_SUCCESS ) - psa_hash_abort( operation ); - return( status ); + return( psa_driver_wrapper_hash_update( &operation->ctx, + input, input_length ) ); } psa_status_t psa_hash_finish( psa_hash_operation_t *operation, @@ -2258,11 +2229,10 @@ psa_status_t psa_hash_finish( psa_hash_operation_t *operation, { if( operation == NULL ) return( PSA_ERROR_INVALID_ARGUMENT ); - if( operation->ctx.ctx == NULL ) - return( PSA_ERROR_BAD_STATE ); - psa_status_t status = mbedtls_psa_hash_finish( operation->ctx.ctx, - hash, hash_size, hash_length ); + psa_status_t status = psa_driver_wrapper_hash_finish( + &operation->ctx, + hash, hash_size, hash_length ); psa_hash_abort( operation ); return( status ); } @@ -2271,11 +2241,15 @@ psa_status_t psa_hash_verify( psa_hash_operation_t *operation, const uint8_t *hash, size_t hash_length ) { + if( operation == NULL ) + return( PSA_ERROR_INVALID_ARGUMENT ); + uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE]; size_t actual_hash_length; - psa_status_t status = psa_hash_finish( operation, - actual_hash, sizeof( actual_hash ), - &actual_hash_length ); + psa_status_t status = psa_driver_wrapper_hash_finish( + &operation->ctx, + actual_hash, sizeof( actual_hash ), + &actual_hash_length ); if( status != PSA_SUCCESS ) return( status ); if( actual_hash_length != hash_length ) @@ -2290,8 +2264,8 @@ psa_status_t psa_hash_compute( psa_algorithm_t alg, uint8_t *hash, size_t hash_size, size_t *hash_length ) { - return( mbedtls_psa_hash_compute( alg, input, input_length, - hash, hash_size, hash_length ) ); + return( psa_driver_wrapper_hash_compute( alg, input, input_length, + hash, hash_size, hash_length ) ); } psa_status_t psa_hash_compare( psa_algorithm_t alg, @@ -2300,9 +2274,10 @@ psa_status_t psa_hash_compare( psa_algorithm_t alg, { uint8_t actual_hash[MBEDTLS_MD_MAX_SIZE]; size_t actual_hash_length; - psa_status_t status = psa_hash_compute( alg, input, input_length, - actual_hash, sizeof(actual_hash), - &actual_hash_length ); + psa_status_t status = psa_driver_wrapper_hash_compute( + alg, input, input_length, + actual_hash, sizeof(actual_hash), + &actual_hash_length ); if( status != PSA_SUCCESS ) return( status ); if( actual_hash_length != hash_length ) @@ -2317,13 +2292,9 @@ psa_status_t psa_hash_clone( const psa_hash_operation_t *source_operation, { if( source_operation == NULL || target_operation == NULL ) return( PSA_ERROR_INVALID_ARGUMENT ); - if( source_operation->ctx.ctx == NULL ) - return( PSA_ERROR_BAD_STATE ); - if( target_operation->ctx.ctx != NULL ) - return( PSA_ERROR_BAD_STATE ); - target_operation->ctx.ctx = mbedtls_calloc(1, sizeof(mbedtls_psa_hash_operation_t)); - return( mbedtls_psa_hash_clone( source_operation->ctx.ctx, target_operation->ctx.ctx ) ); + return( psa_driver_wrapper_hash_clone( &source_operation->ctx, + &target_operation->ctx ) ); } diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 6cf23cef9..72077acd3 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -38,14 +38,17 @@ /* Repeat above block for each JSON-declared driver during autogeneration */ -/* Auto-generated values depending on which drivers are registered. ID 0 is - * reserved for unallocated operations. */ +/* Auto-generated values depending on which drivers are registered. + * ID 0 is reserved for unallocated operations. + * ID 1 is reserved for the Mbed TLS software driver. */ #if defined(PSA_CRYPTO_DRIVER_TEST) -#define PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID (1) -#define PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID (2) +#define PSA_CRYPTO_TRANSPARENT_TEST_DRIVER_ID (2) +#define PSA_CRYPTO_OPAQUE_TEST_DRIVER_ID (3) #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* MBEDTLS_PSA_CRYPTO_DRIVERS */ +#define PSA_CRYPTO_MBED_TLS_DRIVER_ID (1) + /* Support the 'old' SE interface when asked to */ #if defined(MBEDTLS_PSA_CRYPTO_SE_C) /* PSA_CRYPTO_DRIVER_PRESENT is defined when either a new-style or old-style @@ -56,6 +59,9 @@ #include "psa_crypto_se.h" #endif +/* Include software fallback when present */ +#include "psa_crypto_hash.h" + /* Start delegation functions */ psa_status_t psa_driver_wrapper_sign_hash( const psa_key_attributes_t *attributes, @@ -1066,4 +1072,207 @@ psa_status_t psa_driver_wrapper_cipher_abort( #endif /* PSA_CRYPTO_DRIVER_PRESENT */ } +/* + * Hashing functions + */ +psa_status_t psa_driver_wrapper_hash_compute( + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length) +{ + psa_status_t status = PSA_ERROR_NOT_SUPPORTED; + + /* Try accelerators first */ + + /* If software fallback is compiled in, try fallback */ +#if defined(MBEDTLS_PSA_BUILTIN_HASH) + status = mbedtls_psa_hash_compute( alg, input, input_length, + hash, hash_size, hash_length ); + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif + if( status == PSA_ERROR_NOT_SUPPORTED ) + { + (void) alg; + (void) input; + (void) input_length; + (void) hash; + (void) hash_size; + (void) hash_length; + + return( PSA_ERROR_NOT_SUPPORTED ); + } + return( status ); +} + +psa_status_t psa_driver_wrapper_hash_setup( + psa_operation_driver_context_t *operation, + psa_algorithm_t alg ) +{ + psa_status_t status = PSA_ERROR_NOT_SUPPORTED; + + /* A context must be freshly initialized before it can be set up. */ + if( operation->id != 0 || operation->ctx != NULL ) + return( PSA_ERROR_BAD_STATE ); + + /* Try setup on accelerators first */ + + /* If software fallback is compiled in, try fallback */ +#if defined(MBEDTLS_PSA_BUILTIN_HASH) + operation->ctx = mbedtls_calloc( 1, sizeof(mbedtls_psa_hash_operation_t) ); + status = mbedtls_psa_hash_setup( operation->ctx, alg ); + if( status == PSA_SUCCESS ) + { + operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; + } + else + { + mbedtls_free( operation->ctx ); + operation->ctx = NULL; + operation->id = 0; + } + + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif + /* Nothing left to try if we fall through here */ + (void) status; + (void) operation; + (void) alg; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t psa_driver_wrapper_hash_clone( + const psa_operation_driver_context_t *source_operation, + psa_operation_driver_context_t *target_operation ) +{ + psa_status_t status = PSA_ERROR_NOT_SUPPORTED; + + if( source_operation->ctx == NULL || source_operation->id == 0 ) + return( PSA_ERROR_BAD_STATE ); + if( target_operation->ctx != NULL || target_operation->id != 0 ) + return( PSA_ERROR_BAD_STATE ); + + switch( source_operation->id ) + { +#if defined(MBEDTLS_PSA_BUILTIN_HASH) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + target_operation->ctx = mbedtls_calloc( 1, sizeof(mbedtls_psa_hash_operation_t) ); + if( target_operation->ctx == NULL ) + { + status = PSA_ERROR_INSUFFICIENT_MEMORY; + break; + } + target_operation->id = PSA_CRYPTO_MBED_TLS_DRIVER_ID; + status = mbedtls_psa_hash_clone( source_operation->ctx, + target_operation->ctx ); + break; +#endif + default: + (void) status; + (void) source_operation; + (void) target_operation; + return( PSA_ERROR_BAD_STATE ); + } + + if( status != PSA_SUCCESS ) + psa_driver_wrapper_hash_abort( target_operation ); + return( status ); +} + +psa_status_t psa_driver_wrapper_hash_update( + psa_operation_driver_context_t *operation, + const uint8_t *input, + size_t input_length ) +{ + psa_status_t status = PSA_ERROR_NOT_SUPPORTED; + + if( operation->ctx == NULL || operation->id == 0 ) + return( PSA_ERROR_BAD_STATE ); + + switch( operation->id ) + { +#if defined(MBEDTLS_PSA_BUILTIN_HASH) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + status = mbedtls_psa_hash_update( operation->ctx, + input, input_length ); + break; +#endif + default: + (void) status; + (void) operation; + (void) input; + (void) input_length; + return( PSA_ERROR_BAD_STATE ); + } + + if( status != PSA_SUCCESS ) + psa_driver_wrapper_hash_abort( operation ); + return( status ); +} + +psa_status_t psa_driver_wrapper_hash_finish( + psa_operation_driver_context_t *operation, + uint8_t *hash, + size_t hash_size, + size_t *hash_length ) +{ + psa_status_t status = PSA_ERROR_NOT_SUPPORTED; + + if( operation->ctx == NULL || operation->id == 0 ) + return( PSA_ERROR_BAD_STATE ); + + switch( operation->id ) + { +#if defined(MBEDTLS_PSA_BUILTIN_HASH) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + status = mbedtls_psa_hash_finish( operation->ctx, + hash, hash_size, hash_length ); + break; +#endif + default: + (void) status; + (void) operation; + (void) hash; + (void) hash_size; + (void) hash_length; + return( PSA_ERROR_BAD_STATE ); + } + + psa_driver_wrapper_hash_abort( operation ); + return( status ); +} + +psa_status_t psa_driver_wrapper_hash_abort( + psa_operation_driver_context_t *operation ) +{ + psa_status_t status = PSA_ERROR_NOT_SUPPORTED; + + switch( operation->id ) + { + case 0: + if( operation->ctx == NULL ) + return( PSA_SUCCESS ); + else + return( PSA_ERROR_BAD_STATE ); +#if defined(MBEDTLS_PSA_BUILTIN_HASH) + case PSA_CRYPTO_MBED_TLS_DRIVER_ID: + if( operation->ctx != NULL ) + { + status = mbedtls_psa_hash_abort( operation->ctx ); + mbedtls_free( operation->ctx ); + operation->ctx = NULL; + } + operation->id = 0; + return( PSA_SUCCESS ); +#endif + default: + (void) status; + return( PSA_ERROR_BAD_STATE ); + } +} + /* End of automatically generated file. */ diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h index 22d22d61c..1190a0e1b 100644 --- a/library/psa_crypto_driver_wrappers.h +++ b/library/psa_crypto_driver_wrappers.h @@ -127,6 +127,39 @@ psa_status_t psa_driver_wrapper_cipher_finish( psa_status_t psa_driver_wrapper_cipher_abort( psa_operation_driver_context_t *operation ); +/* + * Hashing functions + */ +psa_status_t psa_driver_wrapper_hash_compute( + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *hash, + size_t hash_size, + size_t *hash_length); + +psa_status_t psa_driver_wrapper_hash_setup( + psa_operation_driver_context_t *operation, + psa_algorithm_t alg ); + +psa_status_t psa_driver_wrapper_hash_clone( + const psa_operation_driver_context_t *source_operation, + psa_operation_driver_context_t *target_operation ); + +psa_status_t psa_driver_wrapper_hash_update( + psa_operation_driver_context_t *operation, + const uint8_t *input, + size_t input_length ); + +psa_status_t psa_driver_wrapper_hash_finish( + psa_operation_driver_context_t *operation, + uint8_t *hash, + size_t hash_size, + size_t *hash_length ); + +psa_status_t psa_driver_wrapper_hash_abort( + psa_operation_driver_context_t *operation ); + #endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */ /* End of automatically generated file. */ diff --git a/library/psa_crypto_hash.h b/library/psa_crypto_hash.h index 42a8183b3..0181b4e16 100644 --- a/library/psa_crypto_hash.h +++ b/library/psa_crypto_hash.h @@ -30,6 +30,18 @@ #include "mbedtls/sha256.h" #include "mbedtls/sha512.h" +#if defined(MBEDTLS_PSA_BUILTIN_ALG_MD2) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_MD4) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_MD5) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_RIPEMD160) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_1) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_224) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_256) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_384) || \ + defined(MBEDTLS_PSA_BUILTIN_ALG_SHA_512) +#define MBEDTLS_PSA_BUILTIN_HASH +#endif + typedef struct { psa_algorithm_t alg;