From 4076d3e9f3b46318a9eb5be1175c7dce2a6e605c Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Mon, 1 Mar 2021 15:34:18 +0100 Subject: [PATCH 01/13] Implement one-shot MAC functions Implement one-shot MAC APIs, psa_mac_compute and psa_mac_verify, introduced in PSA Crypto API 1.0. Signed-off-by: gabor-mezei-arm --- library/psa_crypto.c | 61 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 7921eb2313..a6697f6f40 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2444,7 +2444,68 @@ cleanup: return( status == PSA_SUCCESS ? abort_status : status ); } +psa_status_t psa_mac_compute( mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + status = psa_mac_sign_setup( &operation, key, alg ); + if( status != PSA_SUCCESS ) + goto exit; + + status = psa_mac_update( &operation, input, input_length ); + if( status != PSA_SUCCESS ) + goto exit; + + status = psa_mac_sign_finish( &operation, mac, mac_size, mac_length ); + if( status != PSA_SUCCESS ) + goto exit; + +exit: + if ( status == PSA_SUCCESS ) + status = psa_mac_abort( &operation ); + else + psa_mac_abort( &operation ); + + return ( status ); +} + +psa_status_t psa_mac_verify( mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + const uint8_t *mac, + size_t mac_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + + status = psa_mac_verify_setup( &operation, key, alg ); + if( status != PSA_SUCCESS ) + goto exit; + + status = psa_mac_update( &operation, input, input_length ); + if( status != PSA_SUCCESS ) + goto exit; + + status = psa_mac_verify_finish( &operation, mac, mac_length ); + if( status != PSA_SUCCESS ) + goto exit; + +exit: + if ( status == PSA_SUCCESS ) + status = psa_mac_abort( &operation ); + else + psa_mac_abort( &operation ); + + return ( status ); +} /****************************************************************/ /* Asymmetric cryptography */ From 534bb99f17dac336b404c7db1b6512cbf5c40d7e Mon Sep 17 00:00:00 2001 From: gabor-mezei-arm Date: Mon, 1 Mar 2021 15:35:48 +0100 Subject: [PATCH 02/13] Add test for one-shot MAC functions Tests for psa_mac_compute and psa_mac_verify functions. Signed-off-by: gabor-mezei-arm Signed-off-by: Ronald Cron --- tests/suites/test_suite_psa_crypto.function | 45 +++++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 5b5531f037..10426302dd 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1984,7 +1984,21 @@ void mac_sign( int key_type_arg, mbedtls_test_set_step( output_size ); ASSERT_ALLOC( actual_mac, output_size ); - /* Calculate the MAC. */ + /* Calculate the MAC, one-shot case. */ + TEST_EQUAL( psa_mac_compute( key, alg, + input->x, input->len, + actual_mac, output_size, &mac_length ), + expected_status ); + if( expected_status == PSA_SUCCESS ) + { + ASSERT_COMPARE( expected_mac->x, expected_mac->len, + actual_mac, mac_length ); + } + + if( output_size > 0 ) + memset( actual_mac, 0, output_size ); + + /* Calculate the MAC, multi-part case. */ PSA_ASSERT( psa_mac_sign_setup( &operation, key, alg ) ); PSA_ASSERT( psa_mac_update( &operation, input->x, input->len ) ); @@ -2036,7 +2050,11 @@ void mac_verify( int key_type_arg, PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len, &key ) ); - /* Test the correct MAC. */ + /* Verify correct MAC, one-shot case. */ + PSA_ASSERT( psa_mac_verify( key, alg, input->x, input->len, + expected_mac->x, expected_mac->len ) ); + + /* Verify correct MAC, multi-part case. */ PSA_ASSERT( psa_mac_verify_setup( &operation, key, alg ) ); PSA_ASSERT( psa_mac_update( &operation, input->x, input->len ) ); @@ -2044,7 +2062,14 @@ void mac_verify( int key_type_arg, expected_mac->x, expected_mac->len ) ); - /* Test a MAC that's too short. */ + /* Test a MAC that's too short, one-shot case. */ + TEST_EQUAL( psa_mac_verify( key, alg, + input->x, input->len, + expected_mac->x, + expected_mac->len - 1 ), + PSA_ERROR_INVALID_SIGNATURE ); + + /* Test a MAC that's too short, multi-part case. */ PSA_ASSERT( psa_mac_verify_setup( &operation, key, alg ) ); PSA_ASSERT( psa_mac_update( &operation, input->x, input->len ) ); @@ -2053,9 +2078,15 @@ void mac_verify( int key_type_arg, expected_mac->len - 1 ), PSA_ERROR_INVALID_SIGNATURE ); - /* Test a MAC that's too long. */ + /* Test a MAC that's too long, one-shot case. */ ASSERT_ALLOC( perturbed_mac, expected_mac->len + 1 ); memcpy( perturbed_mac, expected_mac->x, expected_mac->len ); + TEST_EQUAL( psa_mac_verify( key, alg, + input->x, input->len, + perturbed_mac, expected_mac->len + 1 ), + PSA_ERROR_INVALID_SIGNATURE ); + + /* Test a MAC that's too long, multi-part case. */ PSA_ASSERT( psa_mac_verify_setup( &operation, key, alg ) ); PSA_ASSERT( psa_mac_update( &operation, input->x, input->len ) ); @@ -2069,6 +2100,12 @@ void mac_verify( int key_type_arg, { mbedtls_test_set_step( i ); perturbed_mac[i] ^= 1; + + TEST_EQUAL( psa_mac_verify( key, alg, + input->x, input->len, + perturbed_mac, expected_mac->len ), + PSA_ERROR_INVALID_SIGNATURE ); + PSA_ASSERT( psa_mac_verify_setup( &operation, key, alg ) ); PSA_ASSERT( psa_mac_update( &operation, input->x, input->len ) ); From 28ea050cf4c695e627b9e7285e8005d846f2fc38 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 17 Jun 2021 16:10:24 +0200 Subject: [PATCH 03/13] psa: mac: Re-organize psa_mac_setup() internal function Re-organize psa_mac_setup() to prepare the move to a dedicated function of the additional checks on the algorithm and the key attributes done by this function. We want to move those checks in a dedicated function to be able to do them without duplicating them in psa_mac_compute(). Signed-off-by: Ronald Cron --- library/psa_crypto.c | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a6697f6f40..02b2f99a9e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2248,14 +2248,12 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; + uint8_t mac_size; /* A context must be freshly initialized before it can be set up. */ if( operation->id != 0 ) return( PSA_ERROR_BAD_STATE ); - if( ! PSA_ALG_IS_MAC( alg ) ) - return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_and_lock_key_slot_with_policy( key, &slot, @@ -2264,24 +2262,28 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, if( status != PSA_SUCCESS ) return( status ); - psa_key_attributes_t attributes = { + psa_key_attributes_t key_attributes = { .core = slot->attr }; + psa_key_attributes_t *attributes = &key_attributes; + + if( ! PSA_ALG_IS_MAC( alg ) ) + { + status = PSA_ERROR_INVALID_ARGUMENT; + goto exit; + } /* Validate the combination of key type and algorithm */ - status = psa_mac_key_can_do( alg, psa_get_key_type( &attributes ) ); + status = psa_mac_key_can_do( alg, psa_get_key_type( attributes ) ); if( status != PSA_SUCCESS ) goto exit; - operation->is_sign = is_sign; - /* Get the output length for the algorithm and key combination */ - operation->mac_size = PSA_MAC_LENGTH( - psa_get_key_type( &attributes ), - psa_get_key_bits( &attributes ), - alg ); + mac_size = PSA_MAC_LENGTH( psa_get_key_type( attributes ), + psa_get_key_bits( attributes ), + alg ); - if( operation->mac_size < 4 ) + if( mac_size < 4 ) { /* A very short MAC is too short for security since it can be * brute-forced. Ancient protocols with 32-bit MACs do exist, @@ -2291,9 +2293,9 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, goto exit; } - if( operation->mac_size > PSA_MAC_LENGTH( psa_get_key_type( &attributes ), - psa_get_key_bits( &attributes ), - PSA_ALG_FULL_LENGTH_MAC( alg ) ) ) + if( mac_size > PSA_MAC_LENGTH( psa_get_key_type( attributes ), + psa_get_key_bits( attributes ), + PSA_ALG_FULL_LENGTH_MAC( alg ) ) ) { /* It's impossible to "truncate" to a larger length than the full length * of the algorithm. */ @@ -2301,11 +2303,14 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, goto exit; } + operation->is_sign = is_sign; + operation->mac_size = mac_size; + /* Dispatch the MAC setup call with validated input */ if( is_sign ) { status = psa_driver_wrapper_mac_sign_setup( operation, - &attributes, + &key_attributes, slot->key.data, slot->key.bytes, alg ); @@ -2313,7 +2318,7 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, else { status = psa_driver_wrapper_mac_verify_setup( operation, - &attributes, + &key_attributes, slot->key.data, slot->key.bytes, alg ); From 2dff3b2a1807fc4f9f28993b9b479486687d4f3a Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 17 Jun 2021 16:33:22 +0200 Subject: [PATCH 04/13] psa: mac: Split psa_mac_setup() Split out of psa_mac_setup() the final checks on the requested algorithm and the key attributes. Signed-off-by: Ronald Cron --- library/psa_crypto.c | 70 +++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 27 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 02b2f99a9e..e7320f7157 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2240,33 +2240,13 @@ psa_status_t psa_mac_abort( psa_mac_operation_t *operation ) return( status ); } -static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - int is_sign ) +static psa_status_t psa_mac_finalize_alg_and_key_validation( + psa_algorithm_t alg, + const psa_key_attributes_t *attributes ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; uint8_t mac_size; - /* A context must be freshly initialized before it can be set up. */ - if( operation->id != 0 ) - return( PSA_ERROR_BAD_STATE ); - - status = psa_get_and_lock_key_slot_with_policy( - key, - &slot, - is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH, - alg ); - if( status != PSA_SUCCESS ) - return( status ); - - psa_key_attributes_t key_attributes = { - .core = slot->attr - }; - psa_key_attributes_t *attributes = &key_attributes; - if( ! PSA_ALG_IS_MAC( alg ) ) { status = PSA_ERROR_INVALID_ARGUMENT; @@ -2303,14 +2283,50 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, goto exit; } - operation->is_sign = is_sign; - operation->mac_size = mac_size; + status = PSA_SUCCESS; +exit: + return( status ); +} + +static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, + mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + int is_sign ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_slot_t *slot; + + /* A context must be freshly initialized before it can be set up. */ + if( operation->id != 0 ) + return( PSA_ERROR_BAD_STATE ); + + status = psa_get_and_lock_key_slot_with_policy( + key, + &slot, + is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH, + alg ); + if( status != PSA_SUCCESS ) + return( status ); + + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + status = psa_mac_finalize_alg_and_key_validation( alg, &attributes ); + if( status != PSA_SUCCESS ) + goto exit; + + operation->is_sign = is_sign; + operation->mac_size = PSA_MAC_LENGTH( psa_get_key_type( &attributes ), + psa_get_key_bits( &attributes ), + alg ); /* Dispatch the MAC setup call with validated input */ if( is_sign ) { status = psa_driver_wrapper_mac_sign_setup( operation, - &key_attributes, + &attributes, slot->key.data, slot->key.bytes, alg ); @@ -2318,7 +2334,7 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, else { status = psa_driver_wrapper_mac_verify_setup( operation, - &key_attributes, + &attributes, slot->key.data, slot->key.bytes, alg ); From 79bdd82eaa18d0bdf19063272ae06f38c5c176b5 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 17 Jun 2021 16:46:44 +0200 Subject: [PATCH 05/13] psa: mac: Improve implementation of psa_mac_finalize_alg_and_key_validation() Signed-off-by: Ronald Cron --- library/psa_crypto.c | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index e7320f7157..9e5e009324 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2242,51 +2242,42 @@ psa_status_t psa_mac_abort( psa_mac_operation_t *operation ) static psa_status_t psa_mac_finalize_alg_and_key_validation( psa_algorithm_t alg, - const psa_key_attributes_t *attributes ) + const psa_key_attributes_t *attributes, + uint8_t *mac_size ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - uint8_t mac_size; + psa_key_type_t key_type = psa_get_key_type( attributes ); + size_t key_bits = psa_get_key_bits( attributes ); if( ! PSA_ALG_IS_MAC( alg ) ) - { - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; - } + return( PSA_ERROR_INVALID_ARGUMENT ); /* Validate the combination of key type and algorithm */ - status = psa_mac_key_can_do( alg, psa_get_key_type( attributes ) ); + status = psa_mac_key_can_do( alg, key_type ); if( status != PSA_SUCCESS ) - goto exit; + return( status ); /* Get the output length for the algorithm and key combination */ - mac_size = PSA_MAC_LENGTH( psa_get_key_type( attributes ), - psa_get_key_bits( attributes ), - alg ); + *mac_size = PSA_MAC_LENGTH( key_type, key_bits, alg ); - if( mac_size < 4 ) + if( *mac_size < 4 ) { /* A very short MAC is too short for security since it can be * brute-forced. Ancient protocols with 32-bit MACs do exist, * so we make this our minimum, even though 32 bits is still * too small for security. */ - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; + return( PSA_ERROR_NOT_SUPPORTED ); } - if( mac_size > PSA_MAC_LENGTH( psa_get_key_type( attributes ), - psa_get_key_bits( attributes ), - PSA_ALG_FULL_LENGTH_MAC( alg ) ) ) + if( *mac_size > PSA_MAC_LENGTH( key_type, key_bits, + PSA_ALG_FULL_LENGTH_MAC( alg ) ) ) { /* It's impossible to "truncate" to a larger length than the full length * of the algorithm. */ - status = PSA_ERROR_INVALID_ARGUMENT; - goto exit; + return( PSA_ERROR_INVALID_ARGUMENT ); } - status = PSA_SUCCESS; - -exit: - return( status ); + return( PSA_SUCCESS ); } static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, @@ -2314,14 +2305,12 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, .core = slot->attr }; - status = psa_mac_finalize_alg_and_key_validation( alg, &attributes ); + status = psa_mac_finalize_alg_and_key_validation( alg, &attributes, + &operation->mac_size ); if( status != PSA_SUCCESS ) goto exit; operation->is_sign = is_sign; - operation->mac_size = PSA_MAC_LENGTH( psa_get_key_type( &attributes ), - psa_get_key_bits( &attributes ), - alg ); /* Dispatch the MAC setup call with validated input */ if( is_sign ) { From 76be3e08a61141b4ee94c2e7779ee0b04db35b3a Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 17 Jun 2021 17:34:43 +0200 Subject: [PATCH 06/13] psa: mac: Add MAC compute builtin implementation Signed-off-by: Ronald Cron --- library/psa_crypto_mac.c | 62 ++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/library/psa_crypto_mac.c b/library/psa_crypto_mac.c index 20c56a0214..135fa352da 100644 --- a/library/psa_crypto_mac.c +++ b/library/psa_crypto_mac.c @@ -359,30 +359,6 @@ static psa_status_t mac_setup( mbedtls_psa_mac_operation_t *operation, return( status ); } -static psa_status_t mac_compute( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *mac, - size_t mac_size, - size_t *mac_length ) -{ - /* One-shot MAC has not been implemented in this PSA implementation yet. */ - (void) attributes; - (void) key_buffer; - (void) key_buffer_size; - (void) alg; - (void) input; - (void) input_length; - (void) mac; - (void) mac_size; - (void) mac_length; - return( PSA_ERROR_NOT_SUPPORTED ); -} - static psa_status_t mac_update( mbedtls_psa_mac_operation_t *operation, const uint8_t *input, @@ -497,6 +473,44 @@ cleanup: return( status ); } + +static psa_status_t mac_compute( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + mbedtls_psa_mac_operation_t operation = MBEDTLS_PSA_MAC_OPERATION_INIT; + + status = mac_setup( &operation, + attributes, key_buffer, key_buffer_size, + alg ); + if( status != PSA_SUCCESS ) + goto exit; + + if( input_length > 0 ) + { + status = mac_update( &operation, input, input_length ); + if( status != PSA_SUCCESS ) + goto exit; + } + + status = mac_finish_internal( &operation, mac, mac_size ); + if( status == PSA_SUCCESS ) + *mac_length = mac_size; + +exit: + mac_abort( &operation ); + + return( status ); +} + #endif /* BUILTIN_ALG_HMAC || BUILTIN_ALG_CMAC */ #if defined(MBEDTLS_PSA_BUILTIN_MAC) From 51131b53fe755c8e4f8801e6151a87e79fc06b75 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 17 Jun 2021 17:17:20 +0200 Subject: [PATCH 07/13] psa: mac: Add driver delegation support for psa_mac_compute() Signed-off-by: Ronald Cron --- library/psa_crypto.c | 50 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 9e5e009324..6d01b4c4b5 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2463,27 +2463,59 @@ psa_status_t psa_mac_compute( mbedtls_svc_key_id_t key, size_t *mac_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_slot_t *slot; + uint8_t operation_mac_size = 0; - status = psa_mac_sign_setup( &operation, key, alg ); + status = psa_get_and_lock_key_slot_with_policy( + key, &slot, PSA_KEY_USAGE_SIGN_HASH, alg ); if( status != PSA_SUCCESS ) goto exit; - status = psa_mac_update( &operation, input, input_length ); + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + status = psa_mac_finalize_alg_and_key_validation( alg, &attributes, + &operation_mac_size ); if( status != PSA_SUCCESS ) goto exit; - status = psa_mac_sign_finish( &operation, mac, mac_size, mac_length ); - if( status != PSA_SUCCESS ) + if( mac_size < operation_mac_size ) + { + status = PSA_ERROR_BUFFER_TOO_SMALL; goto exit; + } + + status = psa_driver_wrapper_mac_compute( + &attributes, + slot->key.data, slot->key.bytes, + alg, + input, input_length, + mac, operation_mac_size, mac_length ); exit: - if ( status == PSA_SUCCESS ) - status = psa_mac_abort( &operation ); + if( status == PSA_SUCCESS ) + { + /* Set the excess room in the output buffer to an invalid value, to + * avoid potentially leaking a longer MAC. */ + if( mac_size > operation_mac_size ) + memset( &mac[operation_mac_size], + '!', + mac_size - operation_mac_size ); + } else - psa_mac_abort( &operation ); + { + /* Set the output length and content to a safe default, such that in + * case the caller misses an error check, the output would be an + * unachievable MAC. */ + *mac_length = mac_size; + memset( mac, '!', mac_size ); + } - return ( status ); + unlock_status = psa_unlock_key_slot( slot ); + + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } psa_status_t psa_mac_verify( mbedtls_svc_key_id_t key, From c3dd75f71b7e0bef1e013ead0bbb15ca517b48e1 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 18 Jun 2021 13:05:48 +0200 Subject: [PATCH 08/13] psa: mac: Improve MAC finalization code Signed-off-by: Ronald Cron --- library/psa_crypto.c | 50 +++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 6d01b4c4b5..514ab40dad 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2403,24 +2403,22 @@ psa_status_t psa_mac_sign_finish( psa_mac_operation_t *operation, mac, operation->mac_size, mac_length ); - if( status == PSA_SUCCESS ) + /* In case of success, set the potential excess room in the output buffer + * to an invalid value, to avoid potentially leaking a longer MAC. + * In case of error, set the output length and content to a safe default, + * such that in case the caller misses an error check, the output would be + * an unachievable MAC. + */ + if( status != PSA_SUCCESS ) { - /* Set the excess room in the output buffer to an invalid value, to - * avoid potentially leaking a longer MAC. */ - if( mac_size > operation->mac_size ) - memset( &mac[operation->mac_size], - '!', - mac_size - operation->mac_size ); - } - else - { - /* Set the output length and content to a safe default, such that in - * case the caller misses an error check, the output would be an - * unachievable MAC. */ *mac_length = mac_size; - memset( mac, '!', mac_size ); + operation->mac_size = 0; } + if( mac_size > operation->mac_size ) + memset( &mac[operation->mac_size], '!', + mac_size - operation->mac_size ); + abort_status = psa_mac_abort( operation ); return( status == PSA_SUCCESS ? abort_status : status ); @@ -2495,23 +2493,19 @@ psa_status_t psa_mac_compute( mbedtls_svc_key_id_t key, mac, operation_mac_size, mac_length ); exit: - if( status == PSA_SUCCESS ) + /* In case of success, set the potential excess room in the output buffer + * to an invalid value, to avoid potentially leaking a longer MAC. + * In case of error, set the output length and content to a safe default, + * such that in case the caller misses an error check, the output would be + * an unachievable MAC. + */ + if( status != PSA_SUCCESS ) { - /* Set the excess room in the output buffer to an invalid value, to - * avoid potentially leaking a longer MAC. */ - if( mac_size > operation_mac_size ) - memset( &mac[operation_mac_size], - '!', - mac_size - operation_mac_size ); - } - else - { - /* Set the output length and content to a safe default, such that in - * case the caller misses an error check, the output would be an - * unachievable MAC. */ *mac_length = mac_size; - memset( mac, '!', mac_size ); + operation_mac_size = 0; } + if( mac_size > operation_mac_size ) + memset( &mac[operation_mac_size], '!', mac_size - operation_mac_size ); unlock_status = psa_unlock_key_slot( slot ); From 094b06a5729b98d047b8a13fe8409f9a3f509bf1 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 18 Jun 2021 14:01:50 +0200 Subject: [PATCH 09/13] psa: mac: Add driver dispatch tests for psa_mac_compute Signed-off-by: Ronald Cron --- ..._suite_psa_crypto_driver_wrappers.function | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function index e86309b065..c9a2a47de7 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function @@ -1118,7 +1118,31 @@ void mac_sign( int key_type_arg, ASSERT_ALLOC( actual_mac, mac_buffer_size ); mbedtls_test_driver_mac_hooks.forced_status = forced_status; - /* Calculate the MAC. */ + /* + * Calculate the MAC, one-shot case. + */ + status = psa_mac_compute( key, alg, + input->x, input->len, + actual_mac, mac_buffer_size, + &mac_length ); + + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); + if( forced_status == PSA_SUCCESS || + forced_status == PSA_ERROR_NOT_SUPPORTED ) + { + PSA_ASSERT( status ); + } + else + TEST_EQUAL( forced_status, status ); + + if( mac_buffer_size > 0 ) + memset( actual_mac, 0, mac_buffer_size ); + mbedtls_test_driver_mac_hooks = mbedtls_test_driver_mac_hooks_init(); + mbedtls_test_driver_mac_hooks.forced_status = forced_status; + + /* + * Calculate the MAC, multipart case. + */ status = psa_mac_sign_setup( &operation, key, alg ); TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); From cd989b55983363893c340a38fdb22a5bd8238491 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 18 Jun 2021 14:23:33 +0200 Subject: [PATCH 10/13] psa: mac: Introduce psa_mac_compute_internal Introduce psa_mac_compute_internal with an additional `is_sign` parameter compared to the psa_mac_compute API. The intent is to call psa_mac_compute_internal() from psa_mac_verify() as well to compute the message MAC. Signed-off-by: Ronald Cron --- library/psa_crypto.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 514ab40dad..ec4f7d94e9 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2452,13 +2452,14 @@ cleanup: return( status == PSA_SUCCESS ? abort_status : status ); } -psa_status_t psa_mac_compute( mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *mac, - size_t mac_size, - size_t *mac_length) +static psa_status_t psa_mac_compute_internal( mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length, + int is_sign ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2466,7 +2467,9 @@ psa_status_t psa_mac_compute( mbedtls_svc_key_id_t key, uint8_t operation_mac_size = 0; status = psa_get_and_lock_key_slot_with_policy( - key, &slot, PSA_KEY_USAGE_SIGN_HASH, alg ); + key, &slot, + is_sign ? PSA_KEY_USAGE_SIGN_HASH : PSA_KEY_USAGE_VERIFY_HASH, + alg ); if( status != PSA_SUCCESS ) goto exit; @@ -2512,6 +2515,19 @@ exit: return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } +psa_status_t psa_mac_compute( mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *mac, + size_t mac_size, + size_t *mac_length) +{ + return( psa_mac_compute_internal( key, alg, + input, input_length, + mac, mac_size, mac_length, 1 ) ); +} + psa_status_t psa_mac_verify( mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *input, From a587cbc3a4ae6063efc2aeacf6f5b43c043bb4c5 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 18 Jun 2021 14:51:29 +0200 Subject: [PATCH 11/13] psa: mac: Add driver delegation support for psa_mac_verify() Signed-off-by: Ronald Cron --- library/psa_crypto.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index ec4f7d94e9..466845d8a5 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2536,25 +2536,29 @@ psa_status_t psa_mac_verify( mbedtls_svc_key_id_t key, size_t mac_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT; + uint8_t actual_mac[PSA_MAC_MAX_SIZE]; + size_t actual_mac_length; - status = psa_mac_verify_setup( &operation, key, alg ); + status = psa_mac_compute_internal( key, alg, + input, input_length, + actual_mac, sizeof( actual_mac ), + &actual_mac_length, 0 ); if( status != PSA_SUCCESS ) goto exit; - status = psa_mac_update( &operation, input, input_length ); - if( status != PSA_SUCCESS ) + if( mac_length != actual_mac_length ) + { + status = PSA_ERROR_INVALID_SIGNATURE; goto exit; - - status = psa_mac_verify_finish( &operation, mac, mac_length ); - if( status != PSA_SUCCESS ) + } + if( mbedtls_psa_safer_memcmp( mac, actual_mac, actual_mac_length ) != 0 ) + { + status = PSA_ERROR_INVALID_SIGNATURE; goto exit; + } exit: - if ( status == PSA_SUCCESS ) - status = psa_mac_abort( &operation ); - else - psa_mac_abort( &operation ); + mbedtls_platform_zeroize( actual_mac, sizeof( actual_mac ) ); return ( status ); } From fb01081212814cf243aa9097c6d2f2ebd4c4efdd Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 18 Jun 2021 15:05:36 +0200 Subject: [PATCH 12/13] psa: mac: Add driver dispatch tests for psa_mac_verify Signed-off-by: Ronald Cron --- ..._suite_psa_crypto_driver_wrappers.function | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function index c9a2a47de7..3a9eff9557 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function @@ -1238,7 +1238,27 @@ void mac_verify( int key_type_arg, mbedtls_test_driver_mac_hooks.forced_status = forced_status; - /* Test the correct MAC. */ + /* + * Verify the MAC, one-shot case. + */ + status = psa_mac_verify( key, alg, + input->x, input->len, + expected_mac->x, expected_mac->len ); + TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); + if( forced_status == PSA_SUCCESS || + forced_status == PSA_ERROR_NOT_SUPPORTED ) + { + PSA_ASSERT( status ); + } + else + TEST_EQUAL( forced_status, status ); + + mbedtls_test_driver_mac_hooks = mbedtls_test_driver_mac_hooks_init(); + mbedtls_test_driver_mac_hooks.forced_status = forced_status; + + /* + * Verify the MAC, multi-part case. + */ status = psa_mac_verify_setup( &operation, key, alg ); TEST_EQUAL( mbedtls_test_driver_mac_hooks.hits, 1 ); From 4d91bcd4135587ecc62b18e0bb745bf7a5876b7c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 21 Jun 2021 09:58:03 +0200 Subject: [PATCH 13/13] Add change log Signed-off-by: Ronald Cron --- ChangeLog.d/one-shot-mac.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 ChangeLog.d/one-shot-mac.txt diff --git a/ChangeLog.d/one-shot-mac.txt b/ChangeLog.d/one-shot-mac.txt new file mode 100644 index 0000000000..112891decc --- /dev/null +++ b/ChangeLog.d/one-shot-mac.txt @@ -0,0 +1,3 @@ +Features + * Implement psa_mac_compute() and psa_mac_verify() as defined in the + PSA Cryptograpy API 1.0.0 specification.