test_suite_psa_its.function 9.3 KB

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