Squashed 'lib/mbedtls/external/mbedtls/' content from commit 2ca6c285a0dd
git-subtree-dir: lib/mbedtls/external/mbedtls
git-subtree-split: 2ca6c285a0dd3f33982dd57299012dacab1ff206
diff --git a/tests/suites/test_suite_psa_its.function b/tests/suites/test_suite_psa_its.function
new file mode 100644
index 0000000..0f66c79
--- /dev/null
+++ b/tests/suites/test_suite_psa_its.function
@@ -0,0 +1,303 @@
+/* BEGIN_HEADER */
+
+/* This test file is specific to the ITS implementation in PSA Crypto
+ * on top of stdio. It expects to know what the stdio name of a file is
+ * based on its keystore name.
+ *
+ * Note that if you need to make a change that affects how files are
+ * stored, this may indicate that the key store is changing in a
+ * backward-incompatible way! Think carefully about backward compatibility
+ * before changing how test data is constructed or validated.
+ */
+
+#include "psa_crypto_its.h"
+
+#include "test/psa_helpers.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%08lx"
+#define PSA_ITS_STORAGE_SUFFIX ".psa_its"
+#define PSA_ITS_STORAGE_FILENAME_LENGTH \
+ (sizeof(PSA_ITS_STORAGE_PREFIX) - 1 + /*prefix without terminating 0*/ \
+ 16 + /*UID (64-bit number in hex)*/ \
+ 16 + /*UID (64-bit number in hex)*/ \
+ sizeof(PSA_ITS_STORAGE_SUFFIX) - 1 + /*suffix without terminating 0*/ \
+ 1 /*terminating null byte*/)
+#define PSA_ITS_STORAGE_TEMP \
+ PSA_ITS_STORAGE_PREFIX "tempfile" PSA_ITS_STORAGE_SUFFIX
+static void psa_its_fill_filename(psa_storage_uid_t uid, char *filename)
+{
+ /* Break up the UID into two 32-bit pieces so as not to rely on
+ * long long support in snprintf. */
+ mbedtls_snprintf(filename, PSA_ITS_STORAGE_FILENAME_LENGTH,
+ "%s" PSA_ITS_STORAGE_FILENAME_PATTERN "%s",
+ PSA_ITS_STORAGE_PREFIX,
+ (unsigned long) (uid >> 32),
+ (unsigned long) (uid & 0xffffffff),
+ PSA_ITS_STORAGE_SUFFIX);
+}
+
+/* Maximum uid used by the test, recorded so that cleanup() can delete
+ * all files. 0xffffffffffffffff is always cleaned up, so it does not
+ * need to and should not be taken into account for uid_max. */
+static psa_storage_uid_t uid_max = 0;
+
+static void cleanup(void)
+{
+ /* Call remove() on all the files that a test might have created.
+ * We ignore the error if the file exists but remove() fails because
+ * it can't be checked portably (except by attempting to open the file
+ * first, which is needlessly slow and complicated here). A failure of
+ * remove() on an existing file is very unlikely anyway and would not
+ * have significant consequences other than perhaps failing the next
+ * test case. */
+ char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
+ psa_storage_uid_t uid;
+ for (uid = 0; uid < uid_max; uid++) {
+ psa_its_fill_filename(uid, filename);
+ (void) remove(filename);
+ }
+ psa_its_fill_filename((psa_storage_uid_t) (-1), filename);
+ (void) remove(filename);
+ (void) remove(PSA_ITS_STORAGE_TEMP);
+ uid_max = 0;
+}
+
+static psa_status_t psa_its_set_wrap(psa_storage_uid_t uid,
+ uint32_t data_length,
+ const void *p_data,
+ psa_storage_create_flags_t create_flags)
+{
+ if (uid_max != (psa_storage_uid_t) (-1) && 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)
+{
+ psa_storage_uid_t uid = uid_arg;
+ uint32_t flags = flags_arg;
+ struct psa_storage_info_t info;
+ unsigned char *buffer = NULL;
+ size_t ret_len = 0;
+
+ TEST_CALLOC(buffer, data->len);
+
+ PSA_ASSERT(psa_its_set_wrap(uid, data->len, data->x, flags));
+
+ PSA_ASSERT(psa_its_get_info(uid, &info));
+ TEST_ASSERT(info.size == data->len);
+ TEST_ASSERT(info.flags == flags);
+ PSA_ASSERT(psa_its_get(uid, 0, data->len, buffer, &ret_len));
+ TEST_MEMORY_COMPARE(data->x, data->len, buffer, ret_len);
+
+ PSA_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)
+{
+ psa_storage_uid_t uid = uid_arg;
+ uint32_t flags1 = flags1_arg;
+ uint32_t flags2 = flags2_arg;
+ struct psa_storage_info_t info;
+ unsigned char *buffer = NULL;
+ size_t ret_len = 0;
+
+ TEST_CALLOC(buffer, MAX(data1->len, data2->len));
+
+ PSA_ASSERT(psa_its_set_wrap(uid, data1->len, data1->x, flags1));
+ PSA_ASSERT(psa_its_get_info(uid, &info));
+ TEST_ASSERT(info.size == data1->len);
+ TEST_ASSERT(info.flags == flags1);
+ PSA_ASSERT(psa_its_get(uid, 0, data1->len, buffer, &ret_len));
+ TEST_MEMORY_COMPARE(data1->x, data1->len, buffer, ret_len);
+
+ PSA_ASSERT(psa_its_set_wrap(uid, data2->len, data2->x, flags2));
+ PSA_ASSERT(psa_its_get_info(uid, &info));
+ TEST_ASSERT(info.size == data2->len);
+ TEST_ASSERT(info.flags == flags2);
+ ret_len = 0;
+ PSA_ASSERT(psa_its_get(uid, 0, data2->len, buffer, &ret_len));
+ TEST_MEMORY_COMPARE(data2->x, data2->len, buffer, ret_len);
+
+ PSA_ASSERT(psa_its_remove(uid));
+
+exit:
+ mbedtls_free(buffer);
+ cleanup();
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void set_multiple(int first_id, int count)
+{
+ psa_storage_uid_t uid0 = first_id;
+ psa_storage_uid_t uid;
+ char stored[40];
+ char retrieved[40];
+ size_t ret_len = 0;
+
+ memset(stored, '.', sizeof(stored));
+ for (uid = uid0; uid < uid0 + count; uid++) {
+ mbedtls_snprintf(stored, sizeof(stored),
+ "Content of file 0x%08lx", (unsigned long) uid);
+ PSA_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);
+ PSA_ASSERT(psa_its_get(uid, 0, sizeof(stored), retrieved, &ret_len));
+ TEST_MEMORY_COMPARE(retrieved, ret_len,
+ stored, sizeof(stored));
+ PSA_ASSERT(psa_its_remove(uid));
+ TEST_ASSERT(psa_its_get(uid, 0, 0, NULL, NULL) ==
+ PSA_ERROR_DOES_NOT_EXIST);
+ }
+
+exit:
+ cleanup();
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void nonexistent(int uid_arg, int create_and_remove)
+{
+ psa_storage_uid_t uid = uid_arg;
+ struct psa_storage_info_t info;
+
+ if (create_and_remove) {
+ PSA_ASSERT(psa_its_set_wrap(uid, 0, NULL, 0));
+ PSA_ASSERT(psa_its_remove(uid));
+ }
+
+ TEST_ASSERT(psa_its_remove(uid) == PSA_ERROR_DOES_NOT_EXIST);
+ TEST_ASSERT(psa_its_get_info(uid, &info) ==
+ PSA_ERROR_DOES_NOT_EXIST);
+ TEST_ASSERT(psa_its_get(uid, 0, 0, NULL, NULL) ==
+ PSA_ERROR_DOES_NOT_EXIST);
+
+exit:
+ cleanup();
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void get_at(int uid_arg, data_t *data,
+ int offset, int length_arg,
+ int expected_status)
+{
+ psa_storage_uid_t uid = uid_arg;
+ unsigned char *buffer = NULL;
+ psa_status_t status;
+ size_t length = length_arg >= 0 ? length_arg : 0;
+ unsigned char *trailer;
+ size_t i;
+ size_t ret_len = 0;
+
+ TEST_CALLOC(buffer, length + 16);
+ trailer = buffer + length;
+ memset(trailer, '-', 16);
+
+ PSA_ASSERT(psa_its_set_wrap(uid, data->len, data->x, 0));
+
+ status = psa_its_get(uid, offset, length_arg, buffer, &ret_len);
+ TEST_ASSERT(status == (psa_status_t) expected_status);
+ if (status == PSA_SUCCESS) {
+ TEST_MEMORY_COMPARE(data->x + offset, (size_t) length_arg,
+ buffer, ret_len);
+ }
+ for (i = 0; i < 16; i++) {
+ TEST_ASSERT(trailer[i] == '-');
+ }
+ PSA_ASSERT(psa_its_remove(uid));
+
+exit:
+ mbedtls_free(buffer);
+ cleanup();
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void get_fail(int uid_arg, data_t *data,
+ int overwrite_magic, int cut_header,
+ int expected_status)
+{
+ psa_storage_uid_t uid = uid_arg;
+ unsigned char *buffer = NULL;
+ psa_status_t status;
+ size_t n;
+ size_t ret_len = 0;
+ char filename[PSA_ITS_STORAGE_FILENAME_LENGTH];
+ FILE *stream = NULL;
+ char bad_char = 'X';
+
+ PSA_ASSERT(psa_its_set_wrap(uid, data->len, data->x, 0));
+
+ psa_its_fill_filename(uid, filename);
+ stream = fopen(filename, "rb+");
+ TEST_ASSERT(NULL != stream);
+ if (0 != overwrite_magic) {
+ /* Overwrite the 1st byte of the file, the ITS magic number */
+ TEST_ASSERT(fseek(stream, 0, SEEK_SET) == 0);
+ n = fwrite(&bad_char, 1, 1, stream);
+ TEST_ASSERT(1 == n);
+ }
+ if (0 != cut_header) {
+ /* Reopen file and truncate it to 0 byte by specifying the 'w' flag */
+ stream = freopen(filename, "wb", stream);
+ TEST_ASSERT(NULL != stream);
+ }
+ fclose(stream);
+ stream = NULL;
+
+ status = psa_its_get(uid, 0, 0, buffer, &ret_len);
+ TEST_ASSERT(status == (psa_status_t) expected_status);
+ TEST_ASSERT(0 == ret_len);
+ PSA_ASSERT(psa_its_remove(uid));
+
+ /* Check if the file is really deleted. */
+ stream = fopen(filename, "rb");
+ TEST_ASSERT(NULL == stream);
+
+exit:
+ if (stream != NULL) {
+ fclose(stream);
+ }
+
+ mbedtls_free(buffer);
+ cleanup();
+}
+/* END_CASE */
+
+/* BEGIN_CASE */
+void set_fail(int uid_arg, data_t *data,
+ int expected_status)
+{
+ psa_storage_uid_t uid = uid_arg;
+ TEST_ASSERT(psa_its_set_wrap(uid, data->len, data->x, 0) ==
+ (psa_status_t) expected_status);
+
+exit:
+ cleanup();
+}
+/* END_CASE */