From bc1f272750c56d9a52c1910831e2f66058f1c139 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 16 Nov 2018 22:24:38 +0100 Subject: [PATCH] Tests for PSA ITS over files --- library/psa_its_file.c | 4 +- tests/CMakeLists.txt | 1 + tests/suites/test_suite_psa_its.data | 65 +++++++ tests/suites/test_suite_psa_its.function | 208 +++++++++++++++++++++++ 4 files changed, 276 insertions(+), 2 deletions(-) create mode 100644 tests/suites/test_suite_psa_its.data create mode 100644 tests/suites/test_suite_psa_its.function diff --git a/library/psa_its_file.c b/library/psa_its_file.c index 3a854b5fd..de60ecfc9 100644 --- a/library/psa_its_file.c +++ b/library/psa_its_file.c @@ -133,7 +133,7 @@ psa_status_t psa_its_get( psa_storage_uid_t uid, status = psa_its_read_file( uid, &info, &stream ); if( status != PSA_SUCCESS ) goto exit; - status = PSA_ERROR_DATA_CORRUPT; + status = PSA_ERROR_INVALID_ARGUMENT; if( data_offset + data_length < data_offset ) goto exit; #if SIZE_MAX < 0xffffffff @@ -143,7 +143,7 @@ psa_status_t psa_its_get( psa_storage_uid_t uid, if( data_offset + data_length > info.size ) goto exit; - status = PSA_ERROR_DATA_CORRUPT; + status = PSA_ERROR_STORAGE_FAILURE; #if LONG_MAX < 0xffffffff while( data_offset > LONG_MAX ) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 76a4608e1..421fd7a75 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -142,6 +142,7 @@ add_test_suite(psa_crypto_metadata) add_test_suite(psa_crypto_persistent_key) add_test_suite(psa_crypto_slot_management) add_test_suite(psa_crypto_storage_file) +add_test_suite(psa_its) add_test_suite(shax) add_test_suite(timing) add_test_suite(rsa) diff --git a/tests/suites/test_suite_psa_its.data b/tests/suites/test_suite_psa_its.data new file mode 100644 index 000000000..d6c0e1545 --- /dev/null +++ b/tests/suites/test_suite_psa_its.data @@ -0,0 +1,65 @@ +Set/get/remove 0 bytes +set_get_remove:0:0:"" + +Set/get/remove 42 bytes +set_get_remove:0:0:"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829" + +Set/get/remove 1000 bytes +set_get_remove:0:0:"6a07ecfcc7c7bfe0129d56d2dcf2955a12845b9e6e0034b0ed7226764261c6222a07b9f654deb682130eb1cd07ed298324e60a46f9c76c8a5a0be000c69e93dd81054ca21fbc6190cef7745e9d5436f70e20e10cbf111d1d40c9ceb83be108775199d81abaf0fecfe30eaa08e7ed82517cba939de4449f7ac5c730fcbbf56e691640b0129db0e178045dd2034262de9138873d9bdca57685146a3d516ff13c29e6628a00097435a8e10fef7faff62d2963c303a93793e2211d8604556fec08cd59c0f5bd1f22eea64be13e88b3f454781e83fe6e771d3d81eb2fbe2021e276f42a93db5343d767d854115e74f5e129a8036b1e81aced9872709d515e00bcf2098ccdee23006b0e836b27dc8aaf30f53fe58a31a6408abb79b13098c22e262a98040f9b09809a3b43bd42eb01cf1d17bbc8b4dfe51fa6573d4d8741943e3ae71a649e194c1218f2e20556c7d8cfe8c64d8cc1aa94531fbf638768c7d19b3c079299cf4f26ed3f964efb8fd23d82b4157a51f46da11156c74e2d6e2fd788869ebb52429e12a82da2ba083e2e74565026162f29ca22582da72a2698e7c5d958b919bc2cdfe12f50364ccfed30efd5cd120a7d5f196b2bd7f911bb44d5871eb3dedcd70ece7faf464988f9fe361f23d7244b1e08bee921d0f28bdb4912675809d099876d4d15b7d13ece356e1f2a5dce64feb3d6749a07a4f2b7721190e17a9ab2966e48b6d25187070b81eb45b1c44608b2f0e175958ba57fcf1b2cd145eea5fd4de858d157ddac69dfbb5d5d6f0c1691b0fae5a143b6e58cdf5000f28d74b3322670ed11e740c828c7bfad4e2f392012da3ac931ea26ed15fd003e604071f5900c6e1329d021805d50da9f1e732a49bcc292d9f8e07737cfd59442e8d7aaa813b18183a68e22bf6b4519545dd7d2d519db3652be4131bad4f4b0625dbaa749e979f6ee8c1b97803cb50a2fa20dc883eac932a824b777b226e15294de6a80be3ddef41478fe18172d64407a004de6bae18bc60e90c902c1cbb0e1633395b42391f5011be0d480541987609b0cd8d902ea29f86f73e7362340119323eb0ea4f672b70d6e9a9df5235f9f1965f5cb0c2998c5a7f4754e83eeda5d95fefbbaaa0875fe37b7ca461e7281cc5479162627c5a709b45fd9ddcde4dfb40659e1d70fa7361d9fc7de24f9b8b13259423fdae4dbb98d691db687467a5a7eb027a4a0552a03e430ac8a32de0c30160ba60a036d6b9db2d6182193283337b92e7438dc5d6eb4fa00200d8efa9127f1c3a32ac8e202262773aaa5a965c6b8035b2e5706c32a55511560429ddf1df4ac34076b7eedd9cf94b6915a894fdd9084ffe3db0e7040f382c3cd04f0484595de95865c36b6bf20f46a78cdfb37228acbeb218de798b9586f6d99a0cbae47e80d" + +Set/get/remove with flags +set_get_remove:0:0x12345678:"abcdef" + +Overwrite 0 -> 3 +set_overwrite:0:0x12345678:"":0x01020304:"abcdef" + +Overwrite 3 -> 0 +set_overwrite:0:0x12345678:"abcdef":0x01020304:"" + +Overwrite 3 -> 3 +set_overwrite:0:0x12345678:"123456":0x01020304:"abcdef" + +Overwrite 3 -> 18 +set_overwrite:0:0x12345678:"abcdef":0x01020304:"404142434445464748494a4b4c4d4e4f5051" + +Overwrite 18 -> 3 +set_overwrite:0:0x12345678:"404142434445464748494a4b4c4d4e4f5051":0x01020304:"abcdef" + +Multiple files +set_multiple:0:5 + +Non-existent file +nonexistent:0:0 + +Removed file +nonexistent:0:1 + +Get 0 bytes of 10 at 10 +get_at:0:"40414243444546474849":10:0:PSA_ITS_SUCCESS + +Get 1 byte of 10 at 9 +get_at:0:"40414243444546474849":9:1:PSA_ITS_SUCCESS + +Get 0 bytes of 10 at 0 +get_at:0:"40414243444546474849":0:0:PSA_ITS_SUCCESS + +Get 1 byte of 10 at 0 +get_at:0:"40414243444546474849":1:0:PSA_ITS_SUCCESS + +Get 2 bytes of 10 at 1 +get_at:0:"40414243444546474849":1:2:PSA_ITS_SUCCESS + +Get 1 byte of 10 at 10: out of range +get_at:0:"40414243444546474849":10:1:PSA_ITS_ERROR_INCORRECT_SIZE + +Get 1 byte of 10 at 11: out of range +get_at:0:"40414243444546474849":11:1:PSA_ITS_ERROR_INCORRECT_SIZE + +Get 0 bytes of 10 at 11: out of range +get_at:0:"40414243444546474849":11:1:PSA_ITS_ERROR_INCORRECT_SIZE + +Get -1 byte of 10 at 10: out of range +get_at:0:"40414243444546474849":10:-1:PSA_ITS_ERROR_INCORRECT_SIZE + +Get 1 byte of 10 at -1: out of range +get_at:0:"40414243444546474849":-1:1:PSA_ITS_ERROR_INCORRECT_SIZE diff --git a/tests/suites/test_suite_psa_its.function b/tests/suites/test_suite_psa_its.function new file mode 100644 index 000000000..70d4578bd --- /dev/null +++ b/tests/suites/test_suite_psa_its.function @@ -0,0 +1,208 @@ +/* BEGIN_HEADER */ +#include "../library/psa_its_file.h" + +/* Internal definitions of the implementation, copied for the sake of + * some of the tests and of the cleanup code. */ +#define PSA_ITS_STORAGE_PREFIX "" +#define PSA_ITS_STORAGE_FILENAME_PATTERN "%08lx.psa_its" +#define PSA_ITS_STORAGE_FILENAME_LENGTH \ + ( sizeof( PSA_ITS_STORAGE_PREFIX ) + 16 ) +#define PSA_ITS_STORAGE_TEMP PSA_ITS_STORAGE_PREFIX "tempfile.psa_its" + +static void psa_its_fill_filename( uint32_t uid, char *filename ) +{ + snprintf( filename, PSA_ITS_STORAGE_FILENAME_LENGTH, + "%s" PSA_ITS_STORAGE_FILENAME_PATTERN, + PSA_ITS_STORAGE_PREFIX, (unsigned long) uid ); +} + +#define MAX( m, n ) ( ( m ) > ( n ) ? ( m ) : ( n ) ) + +#define ITS_ASSERT( expr ) \ + TEST_ASSERT( ( expr ) == PSA_ITS_SUCCESS ) + +/* Maximum uid used by the test, recorded so that cleanup() can delete + * all files. 0xffffffff is excluded. */ +static uint32_t uid_max = 0; + +static void cleanup( void ) +{ + char filename[PSA_ITS_STORAGE_FILENAME_LENGTH]; + uint32_t uid; + for( uid = 0; uid < uid_max; uid++ ) + { + psa_its_fill_filename( uid, filename ); + remove( filename ); + } + psa_its_fill_filename( 0xffffffff, filename ); + remove( filename ); + remove( PSA_ITS_STORAGE_TEMP ); + uid_max = 0; +} + +static psa_its_status_t psa_its_set_wrap( uint32_t uid, + uint32_t data_length, + const void *p_data, + psa_its_create_flags_t create_flags ) +{ + if( uid_max != 0xffffffff && uid_max < uid ) + uid_max = uid; + return psa_its_set( uid, data_length, p_data, create_flags ); +} + +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_PSA_ITS_FILE_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE */ +void set_get_remove( int uid_arg, int flags_arg, data_t *data ) +{ + uint32_t uid = uid_arg; + uint32_t flags = flags_arg; + struct psa_its_info_t info; + unsigned char *buffer = NULL; + + ASSERT_ALLOC( buffer, data->len ); + + ITS_ASSERT( psa_its_set_wrap( uid, data->len, data->x, flags ) ); + + ITS_ASSERT( psa_its_get_info( uid, &info ) ); + TEST_ASSERT( info.size == data->len ); + TEST_ASSERT( info.flags == flags ); + ITS_ASSERT( psa_its_get( uid, 0, data->len, buffer ) ); + ASSERT_COMPARE( data->x, data->len, buffer, data->len ); + + ITS_ASSERT( psa_its_remove( uid ) ); + +exit: + mbedtls_free( buffer ); + cleanup( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void set_overwrite( int uid_arg, + int flags1_arg, data_t *data1, + int flags2_arg, data_t *data2 ) +{ + uint32_t uid = uid_arg; + uint32_t flags1 = flags1_arg; + uint32_t flags2 = flags2_arg; + struct psa_its_info_t info; + unsigned char *buffer = NULL; + + ASSERT_ALLOC( buffer, MAX( data1->len, data2->len ) ); + + ITS_ASSERT( psa_its_set_wrap( uid, data1->len, data1->x, flags1 ) ); + ITS_ASSERT( psa_its_get_info( uid, &info ) ); + TEST_ASSERT( info.size == data1->len ); + TEST_ASSERT( info.flags == flags1 ); + ITS_ASSERT( psa_its_get( uid, 0, data1->len, buffer ) ); + ASSERT_COMPARE( data1->x, data1->len, buffer, data1->len ); + + ITS_ASSERT( psa_its_set_wrap( uid, data2->len, data2->x, flags2 ) ); + ITS_ASSERT( psa_its_get_info( uid, &info ) ); + TEST_ASSERT( info.size == data2->len ); + TEST_ASSERT( info.flags == flags2 ); + ITS_ASSERT( psa_its_get( uid, 0, data2->len, buffer ) ); + ASSERT_COMPARE( data2->x, data2->len, buffer, data2->len ); + + ITS_ASSERT( psa_its_remove( uid ) ); + +exit: + mbedtls_free( buffer ); + cleanup( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void set_multiple( int first_id, int count ) +{ + uint32_t uid0 = first_id; + uint32_t uid; + char stored[40]; + char retrieved[40]; + + memset( stored, '.', sizeof( stored ) ); + for( uid = uid0; uid < uid0 + count; uid++ ) + { + mbedtls_snprintf( stored, sizeof( stored ), + "Content of file 0x%08lx", (unsigned long) uid ); + ITS_ASSERT( psa_its_set_wrap( uid, sizeof( stored ), stored, 0 ) ); + } + + for( uid = uid0; uid < uid0 + count; uid++ ) + { + mbedtls_snprintf( stored, sizeof( stored ), + "Content of file 0x%08lx", (unsigned long) uid ); + ITS_ASSERT( psa_its_get( uid, 0, sizeof( stored ), retrieved ) ); + ASSERT_COMPARE( retrieved, sizeof( stored ), + stored, sizeof( stored ) ); + ITS_ASSERT( psa_its_remove( uid ) ); + TEST_ASSERT( psa_its_get( uid, 0, 0, NULL ) == + PSA_ITS_ERROR_KEY_NOT_FOUND ); + } + +exit: + cleanup( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void nonexistent( int uid_arg, int create_and_remove ) +{ + uint32_t uid = uid_arg; + struct psa_its_info_t info; + + if( create_and_remove ) + { + ITS_ASSERT( psa_its_set_wrap( uid, 0, NULL, 0 ) ); + ITS_ASSERT( psa_its_remove( uid ) ); + } + + TEST_ASSERT( psa_its_remove( uid ) == PSA_ITS_ERROR_KEY_NOT_FOUND ); + TEST_ASSERT( psa_its_get_info( uid, &info ) == + PSA_ITS_ERROR_KEY_NOT_FOUND ); + TEST_ASSERT( psa_its_get( uid, 0, 0, NULL ) == + PSA_ITS_ERROR_KEY_NOT_FOUND ); + +exit: + cleanup( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void get_at( int uid_arg, data_t *data, + int offset, int length_arg, + int expected_status ) +{ + uint32_t uid = uid_arg; + unsigned char *buffer = NULL; + psa_its_status_t ist; + size_t length = length_arg >= 0 ? length_arg : 0; + unsigned char *trailer; + size_t i; + + ASSERT_ALLOC( buffer, length + 16 ); + trailer = buffer + length; + memset( trailer, '-', 16 ); + + ITS_ASSERT( psa_its_set_wrap( uid, data->len, data->x, 0 ) ); + + ist = psa_its_get( uid, offset, length_arg, buffer ); + TEST_ASSERT( ist == (psa_its_status_t) expected_status ); + if( ist == PSA_ITS_SUCCESS ) + ASSERT_COMPARE( data->x + offset, length, + buffer, length ); + for( i = 0; i < 16; i++ ) + TEST_ASSERT( trailer[i] == '-' ); + ITS_ASSERT( psa_its_remove( uid ) ); + +exit: + mbedtls_free( buffer ); + cleanup( ); +} +/* END_CASE */