quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

test_suite_psa_its.function (9645B)


      1 /* BEGIN_HEADER */
      2 
      3 /* This test file is specific to the ITS implementation in PSA Crypto
      4  * on top of stdio. It expects to know what the stdio name of a file is
      5  * based on its keystore name.
      6  *
      7  * Note that if you need to make a change that affects how files are
      8  * stored, this may indicate that the key store is changing in a
      9  * backward-incompatible way! Think carefully about backward compatibility
     10  * before changing how test data is constructed or validated.
     11  */
     12 
     13 #include "psa_crypto_its.h"
     14 
     15 #include "test/psa_helpers.h"
     16 
     17 /* Internal definitions of the implementation, copied for the sake of
     18  * some of the tests and of the cleanup code. */
     19 #define PSA_ITS_STORAGE_PREFIX ""
     20 #define PSA_ITS_STORAGE_FILENAME_PATTERN "%08lx%08lx"
     21 #define PSA_ITS_STORAGE_SUFFIX ".psa_its"
     22 #define PSA_ITS_STORAGE_FILENAME_LENGTH                                         \
     23     (sizeof(PSA_ITS_STORAGE_PREFIX) - 1 +    /*prefix without terminating 0*/   \
     24      16 +  /*UID (64-bit number in hex)*/                                       \
     25      16 +  /*UID (64-bit number in hex)*/                                       \
     26      sizeof(PSA_ITS_STORAGE_SUFFIX) - 1 +    /*suffix without terminating 0*/   \
     27      1 /*terminating null byte*/)
     28 #define PSA_ITS_STORAGE_TEMP \
     29     PSA_ITS_STORAGE_PREFIX "tempfile" PSA_ITS_STORAGE_SUFFIX
     30 static void psa_its_fill_filename(psa_storage_uid_t uid, char *filename)
     31 {
     32     /* Break up the UID into two 32-bit pieces so as not to rely on
     33      * long long support in snprintf. */
     34     mbedtls_snprintf(filename, PSA_ITS_STORAGE_FILENAME_LENGTH,
     35                      "%s" PSA_ITS_STORAGE_FILENAME_PATTERN "%s",
     36                      PSA_ITS_STORAGE_PREFIX,
     37                      (unsigned long) (uid >> 32),
     38                      (unsigned long) (uid & 0xffffffff),
     39                      PSA_ITS_STORAGE_SUFFIX);
     40 }
     41 
     42 /* Maximum uid used by the test, recorded so that cleanup() can delete
     43  * all files. 0xffffffffffffffff is always cleaned up, so it does not
     44  * need to and should not be taken into account for uid_max. */
     45 static psa_storage_uid_t uid_max = 0;
     46 
     47 static void cleanup(void)
     48 {
     49     /* Call remove() on all the files that a test might have created.
     50      * We ignore the error if the file exists but remove() fails because
     51      * it can't be checked portably (except by attempting to open the file
     52      * first, which is needlessly slow and complicated here). A failure of
     53      * remove() on an existing file is very unlikely anyway and would not
     54      * have significant consequences other than perhaps failing the next
     55      * test case. */
     56     char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
     57     psa_storage_uid_t uid;
     58     for (uid = 0; uid < uid_max; uid++) {
     59         psa_its_fill_filename(uid, filename);
     60         (void) remove(filename);
     61     }
     62     psa_its_fill_filename((psa_storage_uid_t) (-1), filename);
     63     (void) remove(filename);
     64     (void) remove(PSA_ITS_STORAGE_TEMP);
     65     uid_max = 0;
     66 }
     67 
     68 static psa_status_t psa_its_set_wrap(psa_storage_uid_t uid,
     69                                      uint32_t data_length,
     70                                      const void *p_data,
     71                                      psa_storage_create_flags_t create_flags)
     72 {
     73     if (uid_max != (psa_storage_uid_t) (-1) && uid_max < uid) {
     74         uid_max = uid;
     75     }
     76     return psa_its_set(uid, data_length, p_data, create_flags);
     77 }
     78 
     79 /* END_HEADER */
     80 
     81 /* BEGIN_DEPENDENCIES
     82  * depends_on:MBEDTLS_PSA_ITS_FILE_C
     83  * END_DEPENDENCIES
     84  */
     85 
     86 /* BEGIN_CASE */
     87 void set_get_remove(int uid_arg, int flags_arg, data_t *data)
     88 {
     89     psa_storage_uid_t uid = uid_arg;
     90     uint32_t flags = flags_arg;
     91     struct psa_storage_info_t info;
     92     unsigned char *buffer = NULL;
     93     size_t ret_len = 0;
     94 
     95     TEST_CALLOC(buffer, data->len);
     96 
     97     PSA_ASSERT(psa_its_set_wrap(uid, data->len, data->x, flags));
     98 
     99     PSA_ASSERT(psa_its_get_info(uid, &info));
    100     TEST_ASSERT(info.size == data->len);
    101     TEST_ASSERT(info.flags == flags);
    102     PSA_ASSERT(psa_its_get(uid, 0, data->len, buffer, &ret_len));
    103     TEST_MEMORY_COMPARE(data->x, data->len, buffer, ret_len);
    104 
    105     PSA_ASSERT(psa_its_remove(uid));
    106 
    107 exit:
    108     mbedtls_free(buffer);
    109     cleanup();
    110 }
    111 /* END_CASE */
    112 
    113 /* BEGIN_CASE */
    114 void set_overwrite(int uid_arg,
    115                    int flags1_arg, data_t *data1,
    116                    int flags2_arg, data_t *data2)
    117 {
    118     psa_storage_uid_t uid = uid_arg;
    119     uint32_t flags1 = flags1_arg;
    120     uint32_t flags2 = flags2_arg;
    121     struct psa_storage_info_t info;
    122     unsigned char *buffer = NULL;
    123     size_t ret_len = 0;
    124 
    125     TEST_CALLOC(buffer, MAX(data1->len, data2->len));
    126 
    127     PSA_ASSERT(psa_its_set_wrap(uid, data1->len, data1->x, flags1));
    128     PSA_ASSERT(psa_its_get_info(uid, &info));
    129     TEST_ASSERT(info.size == data1->len);
    130     TEST_ASSERT(info.flags == flags1);
    131     PSA_ASSERT(psa_its_get(uid, 0, data1->len, buffer, &ret_len));
    132     TEST_MEMORY_COMPARE(data1->x, data1->len, buffer, ret_len);
    133 
    134     PSA_ASSERT(psa_its_set_wrap(uid, data2->len, data2->x, flags2));
    135     PSA_ASSERT(psa_its_get_info(uid, &info));
    136     TEST_ASSERT(info.size == data2->len);
    137     TEST_ASSERT(info.flags == flags2);
    138     ret_len = 0;
    139     PSA_ASSERT(psa_its_get(uid, 0, data2->len, buffer, &ret_len));
    140     TEST_MEMORY_COMPARE(data2->x, data2->len, buffer, ret_len);
    141 
    142     PSA_ASSERT(psa_its_remove(uid));
    143 
    144 exit:
    145     mbedtls_free(buffer);
    146     cleanup();
    147 }
    148 /* END_CASE */
    149 
    150 /* BEGIN_CASE */
    151 void set_multiple(int first_id, int count)
    152 {
    153     psa_storage_uid_t uid0 = first_id;
    154     psa_storage_uid_t uid;
    155     char stored[40];
    156     char retrieved[40];
    157     size_t ret_len = 0;
    158 
    159     memset(stored, '.', sizeof(stored));
    160     for (uid = uid0; uid < uid0 + count; uid++) {
    161         mbedtls_snprintf(stored, sizeof(stored),
    162                          "Content of file 0x%08lx", (unsigned long) uid);
    163         PSA_ASSERT(psa_its_set_wrap(uid, sizeof(stored), stored, 0));
    164     }
    165 
    166     for (uid = uid0; uid < uid0 + count; uid++) {
    167         mbedtls_snprintf(stored, sizeof(stored),
    168                          "Content of file 0x%08lx", (unsigned long) uid);
    169         PSA_ASSERT(psa_its_get(uid, 0, sizeof(stored), retrieved, &ret_len));
    170         TEST_MEMORY_COMPARE(retrieved, ret_len,
    171                             stored, sizeof(stored));
    172         PSA_ASSERT(psa_its_remove(uid));
    173         TEST_ASSERT(psa_its_get(uid, 0, 0, NULL, NULL) ==
    174                     PSA_ERROR_DOES_NOT_EXIST);
    175     }
    176 
    177 exit:
    178     cleanup();
    179 }
    180 /* END_CASE */
    181 
    182 /* BEGIN_CASE */
    183 void nonexistent(int uid_arg, int create_and_remove)
    184 {
    185     psa_storage_uid_t uid = uid_arg;
    186     struct psa_storage_info_t info;
    187 
    188     if (create_and_remove) {
    189         PSA_ASSERT(psa_its_set_wrap(uid, 0, NULL, 0));
    190         PSA_ASSERT(psa_its_remove(uid));
    191     }
    192 
    193     TEST_ASSERT(psa_its_remove(uid) == PSA_ERROR_DOES_NOT_EXIST);
    194     TEST_ASSERT(psa_its_get_info(uid, &info) ==
    195                 PSA_ERROR_DOES_NOT_EXIST);
    196     TEST_ASSERT(psa_its_get(uid, 0, 0, NULL, NULL) ==
    197                 PSA_ERROR_DOES_NOT_EXIST);
    198 
    199 exit:
    200     cleanup();
    201 }
    202 /* END_CASE */
    203 
    204 /* BEGIN_CASE */
    205 void get_at(int uid_arg, data_t *data,
    206             int offset, int length_arg,
    207             int expected_status)
    208 {
    209     psa_storage_uid_t uid = uid_arg;
    210     unsigned char *buffer = NULL;
    211     psa_status_t status;
    212     size_t length = length_arg >= 0 ? length_arg : 0;
    213     unsigned char *trailer;
    214     size_t i;
    215     size_t ret_len = 0;
    216 
    217     TEST_CALLOC(buffer, length + 16);
    218     trailer = buffer + length;
    219     memset(trailer, '-', 16);
    220 
    221     PSA_ASSERT(psa_its_set_wrap(uid, data->len, data->x, 0));
    222 
    223     status = psa_its_get(uid, offset, length_arg, buffer, &ret_len);
    224     TEST_ASSERT(status == (psa_status_t) expected_status);
    225     if (status == PSA_SUCCESS) {
    226         TEST_MEMORY_COMPARE(data->x + offset, (size_t) length_arg,
    227                             buffer, ret_len);
    228     }
    229     for (i = 0; i < 16; i++) {
    230         TEST_ASSERT(trailer[i] == '-');
    231     }
    232     PSA_ASSERT(psa_its_remove(uid));
    233 
    234 exit:
    235     mbedtls_free(buffer);
    236     cleanup();
    237 }
    238 /* END_CASE */
    239 
    240 /* BEGIN_CASE */
    241 void get_fail(int uid_arg, data_t *data,
    242               int overwrite_magic, int cut_header,
    243               int expected_status)
    244 {
    245     psa_storage_uid_t uid = uid_arg;
    246     unsigned char *buffer = NULL;
    247     psa_status_t status;
    248     size_t n;
    249     size_t ret_len = 0;
    250     char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
    251     FILE *stream = NULL;
    252     char bad_char = 'X';
    253 
    254     PSA_ASSERT(psa_its_set_wrap(uid, data->len, data->x, 0));
    255 
    256     psa_its_fill_filename(uid, filename);
    257     stream = fopen(filename, "rb+");
    258     TEST_ASSERT(NULL != stream);
    259     if (0 != overwrite_magic) {
    260         /* Overwrite the 1st byte of the file, the ITS magic number */
    261         TEST_ASSERT(fseek(stream, 0, SEEK_SET) == 0);
    262         n = fwrite(&bad_char, 1, 1, stream);
    263         TEST_ASSERT(1 == n);
    264     }
    265     if (0 != cut_header) {
    266         /* Reopen file and truncate it to 0 byte by specifying the 'w' flag */
    267         stream = freopen(filename, "wb", stream);
    268         TEST_ASSERT(NULL != stream);
    269     }
    270     fclose(stream);
    271     stream = NULL;
    272 
    273     status = psa_its_get(uid, 0, 0, buffer, &ret_len);
    274     TEST_ASSERT(status == (psa_status_t) expected_status);
    275     TEST_ASSERT(0 == ret_len);
    276     PSA_ASSERT(psa_its_remove(uid));
    277 
    278     /* Check if the file is really deleted. */
    279     stream = fopen(filename, "rb");
    280     TEST_ASSERT(NULL == stream);
    281 
    282 exit:
    283     if (stream != NULL) {
    284         fclose(stream);
    285     }
    286 
    287     mbedtls_free(buffer);
    288     cleanup();
    289 }
    290 /* END_CASE */
    291 
    292 /* BEGIN_CASE */
    293 void set_fail(int uid_arg, data_t *data,
    294               int expected_status)
    295 {
    296     psa_storage_uid_t uid = uid_arg;
    297     TEST_ASSERT(psa_its_set_wrap(uid, data->len, data->x, 0) ==
    298                 (psa_status_t) expected_status);
    299 
    300 exit:
    301     cleanup();
    302 }
    303 /* END_CASE */