Add multi-part mac sign/verify test
The test is based on the AEAD multi-part test, re-using the
design on aead_multipart_internal_func() to test differnet
sequence of psa_mac_update() for MAC update or verify.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function
index 97bb8e7..e7df346 100644
--- a/tests/suites/test_suite_psa_crypto.function
+++ b/tests/suites/test_suite_psa_crypto.function
@@ -589,6 +589,122 @@
return( test_ok );
}
+/*!
+ * \brief Internal Function for MAC multipart tests.
+ * \param key_type_arg Type of key passed in
+ * \param key_data The encryption / decryption key data
+ * \param alg_arg The type of algorithm used
+ * \param input_data Data to encrypt / decrypt
+ * \param data_part_len_arg If not -1, the length of chunks to feed
+ * the data in to be encrypted / decrypted. If
+ * -1, no chunking
+ * \param expected_output Expected output
+ * \param is_verify If non-zero this is an verify operation.
+ * \param do_zero_parts If non-zero, interleave zero length chunks
+ * with normal length chunks.
+ * \return int Zero on failure, non-zero on success.
+ */
+static int mac_multipart_internal_func( int key_type_arg, data_t *key_data,
+ int alg_arg,
+ data_t *input_data,
+ int data_part_len_arg,
+ data_t *expected_output,
+ int is_verify,
+ int do_zero_parts )
+{
+ mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT;
+ psa_key_type_t key_type = key_type_arg;
+ psa_algorithm_t alg = alg_arg;
+ psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
+ unsigned char mac[PSA_MAC_MAX_SIZE];
+ size_t part_offset = 0;
+ size_t part_length = 0;
+ size_t data_part_len = 0;
+ size_t mac_len = 0;
+ psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+ psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+
+ int test_ok = 0;
+ size_t part_count = 0;
+
+ PSA_ASSERT( psa_crypto_init( ) );
+
+ if( is_verify )
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_VERIFY_HASH );
+ else
+ psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_SIGN_HASH );
+
+ psa_set_key_algorithm( &attributes, alg );
+ psa_set_key_type( &attributes, key_type );
+
+ PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len,
+ &key ) );
+
+ if( is_verify )
+ status = psa_mac_verify_setup( &operation, key, alg );
+ else
+ status = psa_mac_sign_setup( &operation, key, alg );
+
+ PSA_ASSERT( status );
+
+ if( data_part_len_arg != -1 )
+ {
+ /* Pass data in parts */
+ data_part_len = ( size_t ) data_part_len_arg;
+
+ for( part_offset = 0, part_count = 0;
+ part_offset < input_data->len;
+ part_offset += part_length, part_count++ )
+ {
+ if( do_zero_parts && ( part_count & 0x01 ) )
+ {
+ part_length = 0;
+ }
+ else if( ( input_data->len - part_offset ) < data_part_len )
+ {
+ part_length = ( input_data->len - part_offset );
+ }
+ else
+ {
+ part_length = data_part_len;
+ }
+
+ PSA_ASSERT( psa_mac_update( &operation,
+ ( input_data->x + part_offset ),
+ part_length ) );
+ }
+ }
+ else
+ {
+ /* Pass all data in one go. */
+ PSA_ASSERT( psa_mac_update( &operation, input_data->x,
+ input_data->len ) );
+ }
+
+ if( is_verify )
+ {
+ PSA_ASSERT( psa_mac_verify_finish( &operation, expected_output->x,
+ expected_output->len ) );
+ }
+ else
+ {
+ PSA_ASSERT( psa_mac_sign_finish( &operation, mac,
+ PSA_MAC_MAX_SIZE, &mac_len ) );
+
+ ASSERT_COMPARE( expected_output->x, expected_output->len,
+ mac, mac_len );
+ }
+
+ test_ok = 1;
+
+exit:
+ psa_destroy_key( key );
+ psa_mac_abort( &operation );
+ PSA_DONE( );
+
+ return( test_ok );
+}
+
/* END_HEADER */
/* BEGIN_DEPENDENCIES
@@ -2591,6 +2707,45 @@
/* END_CASE */
/* BEGIN_CASE */
+void mac_sign_verify_multi( int key_type_arg,
+ data_t *key_data,
+ int alg_arg,
+ data_t *input,
+ int is_verify,
+ data_t *expected_mac )
+{
+ size_t data_part_len = 0;
+
+ for( data_part_len = 1; data_part_len <= input->len; data_part_len++ )
+ {
+ /* Split data into length(data_part_len) parts. */
+ mbedtls_test_set_step( 2000 + data_part_len );
+
+ if( !mac_multipart_internal_func( key_type_arg, key_data,
+ alg_arg,
+ input, data_part_len,
+ expected_mac,
+ is_verify, 0 ) )
+ break;
+
+ /* length(0) part, length(data_part_len) part, length(0) part... */
+ mbedtls_test_set_step( 3000 + data_part_len );
+
+ if( !mac_multipart_internal_func( key_type_arg, key_data,
+ alg_arg,
+ input, data_part_len,
+ expected_mac,
+ is_verify, 1 ) )
+ break;
+ }
+
+ /* Goto is required to silence warnings about unused labels, as we
+ * don't actually do any test assertions in this function. */
+ goto exit;
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
void mac_sign( int key_type_arg,
data_t *key_data,
int alg_arg,