diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 594c609e3c..7b1974865a 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7406,93 +7406,3 @@ persistent_key_load_key_from_storage:"":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY PSA derive persistent key: HKDF SHA-256, exportable persistent_key_load_key_from_storage:"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":PSA_KEY_TYPE_RAW_DATA:1024:PSA_KEY_USAGE_EXPORT:0:DERIVE_KEY - -PSA input buffer copy: straightforward copy -copy_input:20:20:PSA_SUCCESS - -PSA input buffer copy: copy buffer larger than required -copy_input:10:20:PSA_SUCCESS - -PSA input buffer copy: copy buffer too small -copy_input:20:10:PSA_ERROR_CORRUPTION_DETECTED - -PSA input buffer copy: zero-length source buffer -copy_input:0:10:PSA_SUCCESS - -PSA input buffer copy: zero-length both buffers -copy_input:0:0:PSA_SUCCESS - -PSA output buffer copy: straightforward copy -copy_output:20:20:PSA_SUCCESS - -PSA output buffer copy: output buffer larger than required -copy_output:10:20:PSA_SUCCESS - -PSA output buffer copy: output buffer too small -copy_output:20:10:PSA_ERROR_CORRUPTION_DETECTED - -PSA output buffer copy: zero-length source buffer -copy_output:0:10:PSA_SUCCESS - -PSA output buffer copy: zero-length both buffers -copy_output:0:0:PSA_SUCCESS - -PSA buffers alloc and copy -psa_crypto_alloc_and_copy:0:20:0:20:PSA_SUCCESS - -PSA buffers alloc and copy: null input -psa_crypto_alloc_and_copy:1:0:0:20:PSA_SUCCESS - -PSA buffers alloc and copy: null output -psa_crypto_alloc_and_copy:0:20:1:0:PSA_SUCCESS - -PSA buffers alloc and copy: null input and output -psa_crypto_alloc_and_copy:1:0:1:0:PSA_SUCCESS - -PSA buffers alloc and copy zero-length input -psa_crypto_alloc_and_copy_zero_length:1:0 - -PSA buffers alloc and copy zero-length output -psa_crypto_alloc_and_copy_zero_length:0:1 - -PSA buffers alloc and copy both zero length -psa_crypto_alloc_and_copy_zero_length:1:1 - -PSA buffers alloc and copy overlapping input first -psa_crypto_alloc_and_copy_overlapping:20:20:5:PSA_SUCCESS - -PSA buffers alloc and copy overlapping output first -psa_crypto_alloc_and_copy_overlapping:20:20:-5:PSA_SUCCESS - -PSA buffers alloc and copy overlapping output within input -psa_crypto_alloc_and_copy_overlapping:20:10:5:PSA_SUCCESS - -PSA buffers alloc and copy overlapping input within output -psa_crypto_alloc_and_copy_overlapping:10:20:-5:PSA_SUCCESS - -PSA buffers alloc and copy overlapping input equals output -psa_crypto_alloc_and_copy_overlapping:20:20:0:PSA_SUCCESS - -PSA buffers copy and free -psa_crypto_copy_and_free:0:20:0:20:0:PSA_SUCCESS - -PSA buffers copy and free, null input -psa_crypto_copy_and_free:1:0:0:20:0:PSA_SUCCESS - -PSA buffers copy and free, null output -psa_crypto_copy_and_free:0:20:1:0:0:PSA_SUCCESS - -PSA buffers copy and free, null output_original -psa_crypto_copy_and_free:0:20:0:20:1:PSA_ERROR_INVALID_ARGUMENT - -PSA buffers copy and free, null output_original and null output -psa_crypto_copy_and_free:0:20:1:0:1:PSA_SUCCESS - -PSA buffers copy and free, zero-length input -psa_crypto_copy_and_free:0:0:0:20:0:PSA_ERROR_INVALID_ARGUMENT - -PSA buffers copy and free, zero-length output -psa_crypto_copy_and_free:20:0:0:0:0:PSA_ERROR_INVALID_ARGUMENT - -PSA buffers round-trip -psa_crypto_buffer_copy_round_trip diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 41d7009296..be773da8fa 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1252,75 +1252,6 @@ static void interruptible_signverify_get_minmax_completes(uint32_t max_ops, } #endif /* MBEDTLS_ECP_RESTARTABLE */ -/* Helper to fill a buffer with a data pattern. The pattern is not - * important, it just allows a basic check that the correct thing has - * been written, in a way that will detect an error in offset. */ -static void fill_buffer_pattern(uint8_t *buffer, size_t len) -{ - uint8_t data[] = { 0x12, 0x34, 0x56, 0x78 }; - - for (size_t i = 0; i < len; i++) { - buffer[i] = data[i % sizeof(data)]; - } -} - -/* Helper to get 2 buffers that overlap by the specified amount. - * The parameter ptr_diff may be negative, in which case the start of - * buf2 is allocated before the start of buf1. */ -static int setup_overlapping_buffers(size_t buf1_len, size_t buf2_len, - int ptr_diff, - uint8_t **full_buffer, - uint8_t **buf1, uint8_t **buf2) -{ - size_t total_len; - int buf1_offset; - int buf2_offset; - - *full_buffer = NULL; - *buf1 = NULL; - *buf2 = NULL; - - if (ptr_diff >= 0) { - /* - * |---------- buf1 ----------| - * <-- ptr_diff -->|---------- buf2 ----------| - */ - total_len = ptr_diff + buf2_len; - if (buf1_len > total_len) { - total_len = buf1_len; - } - buf1_offset = 0; - buf2_offset = ptr_diff; - } else { - /* - * <-- (-ptr_diff) -->|---------- buf1 ----------| - * |---------- buf2 ----------| - */ - total_len = (-ptr_diff) + buf1_len; - if (buf2_len > total_len) { - total_len = buf2_len; - } - buf1_offset = -ptr_diff; - buf2_offset = 0; - } - - /* Edge case: if the length is zero, allocate a 1-byte buffer to avoid - * calloc returning NULL. */ - if (total_len == 0) { - total_len = 1; - } - - TEST_CALLOC(*full_buffer, total_len); - - *buf1 = *full_buffer + buf1_offset; - *buf2 = *full_buffer + buf2_offset; - - return 0; - -exit: - return -1; -} - /* END_HEADER */ /* BEGIN_DEPENDENCIES @@ -10374,282 +10305,3 @@ void ecjpake_size_macros() } /* END_CASE */ -/* BEGIN_CASE */ -void copy_input(int src_len, int dst_len, psa_status_t exp_status) -{ - uint8_t *src_buffer = NULL; - uint8_t *dst_buffer = NULL; - psa_status_t status; - - TEST_CALLOC_NONNULL(src_buffer, src_len); - TEST_CALLOC_NONNULL(dst_buffer, dst_len); - - fill_buffer_pattern(src_buffer, src_len); - - status = psa_crypto_copy_input(src_buffer, src_len, dst_buffer, dst_len); - TEST_EQUAL(status, exp_status); - - if (exp_status == PSA_SUCCESS) { - /* Note: We compare the first src_len bytes of each buffer, as this is what was copied. */ - TEST_MEMORY_COMPARE(src_buffer, src_len, dst_buffer, src_len); - } - -exit: - mbedtls_free(src_buffer); - mbedtls_free(dst_buffer); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void copy_output(int src_len, int dst_len, psa_status_t exp_status) -{ - uint8_t *src_buffer = NULL; - uint8_t *dst_buffer = NULL; - psa_status_t status; - - TEST_CALLOC_NONNULL(src_buffer, src_len); - TEST_CALLOC_NONNULL(dst_buffer, dst_len); - - fill_buffer_pattern(src_buffer, src_len); - - status = psa_crypto_copy_output(src_buffer, src_len, dst_buffer, dst_len); - TEST_EQUAL(status, exp_status); - - if (exp_status == PSA_SUCCESS) { - /* Note: We compare the first src_len bytes of each buffer, as this is what was copied. */ - TEST_MEMORY_COMPARE(src_buffer, src_len, dst_buffer, src_len); - } - -exit: - mbedtls_free(src_buffer); - mbedtls_free(dst_buffer); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void psa_crypto_alloc_and_copy(int input_null, int input_len, - int output_null, int output_len, - int exp_ret) -{ - uint8_t *input_buffer = NULL; - uint8_t *output_buffer = NULL; - psa_status_t ret; - - psa_crypto_buffer_copy_t buffer_copies; - memset(&buffer_copies, 0, sizeof(buffer_copies)); - - if (!input_null) { - TEST_CALLOC(input_buffer, input_len); - fill_buffer_pattern(input_buffer, input_len); - } - if (!output_null) { - TEST_CALLOC(output_buffer, output_len); - fill_buffer_pattern(output_buffer, output_len); - } - ret = psa_crypto_alloc_and_copy(input_buffer, input_len, - output_buffer, output_len, - &buffer_copies); - TEST_EQUAL(exp_ret, (int) ret); - - if (exp_ret == PSA_SUCCESS) { - TEST_MEMORY_COMPARE(input_buffer, input_len, buffer_copies.input, buffer_copies.input_len); - TEST_EQUAL(output_len, buffer_copies.output_len); - } - -exit: - mbedtls_free(input_buffer); - mbedtls_free(output_buffer); - mbedtls_free(buffer_copies.input); - mbedtls_free(buffer_copies.output); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void psa_crypto_alloc_and_copy_zero_length(int input_zero_length, - int output_zero_length) -{ - uint8_t input_buffer[] = { 0x12 }; - uint8_t output_buffer[] = { 0x34 }; - - size_t input_len = input_zero_length ? 0 : 1; - size_t output_len = output_zero_length ? 0 : 1; - - psa_crypto_buffer_copy_t buffer_copies; - memset(&buffer_copies, 0, sizeof(buffer_copies)); - - psa_status_t ret = psa_crypto_alloc_and_copy(input_buffer, input_len, - output_buffer, output_len, - &buffer_copies); - TEST_EQUAL(ret, PSA_SUCCESS); - - if (input_zero_length) { - TEST_ASSERT(buffer_copies.input == NULL); - } else { - TEST_MEMORY_COMPARE(input_buffer, input_len, buffer_copies.input, buffer_copies.input_len); - } - if (output_zero_length) { - TEST_ASSERT(buffer_copies.output == NULL); - } else { - TEST_EQUAL(output_len, buffer_copies.output_len); - } - -exit: - mbedtls_free(buffer_copies.input); - mbedtls_free(buffer_copies.output); -} -/* END_CASE */ - -/* BEGIN_CASE */ -/* Ensure that overlapping buffers can be copied correctly. */ -void psa_crypto_alloc_and_copy_overlapping(int input_len, int output_len, - int ptr_diff, int exp_ret) -{ - uint8_t *full_buffer = NULL; - uint8_t *input = NULL; - uint8_t *output = NULL; - - psa_status_t ret; - - psa_crypto_buffer_copy_t buffer_copies; - memset(&buffer_copies, 0, sizeof(buffer_copies)); - - TEST_EQUAL(setup_overlapping_buffers(input_len, output_len, ptr_diff, - &full_buffer, &input, &output), 0); - - fill_buffer_pattern(input, input_len); - - ret = psa_crypto_alloc_and_copy(input, input_len, output, output_len, - &buffer_copies); - - TEST_EQUAL((int) ret, exp_ret); - - if (exp_ret == PSA_SUCCESS) { - if (input_len == 0) { - TEST_ASSERT(buffer_copies.input == NULL); - } else { - TEST_MEMORY_COMPARE(input, input_len, buffer_copies.input, buffer_copies.input_len); - } - if (output_len == 0) { - TEST_ASSERT(buffer_copies.output == NULL); - } else { - TEST_EQUAL(output_len, buffer_copies.output_len); - } - } - -exit: - mbedtls_free(full_buffer); - mbedtls_free(buffer_copies.input); - mbedtls_free(buffer_copies.output); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void psa_crypto_copy_and_free(int input_null, int input_len, - int output_null, int output_len, - int orig_output_null, - int exp_ret) -{ - uint8_t *input = NULL; - uint8_t *output = NULL; - uint8_t *output_for_comparison = NULL; - uint8_t *orig_output = NULL; - size_t calloc_len; - psa_status_t ret; - - psa_crypto_buffer_copy_t buffer_copies; - memset(&buffer_copies, 0, sizeof(buffer_copies)); - - if (!input_null) { - /* If zero-length, ensure we actually allocate something - * rather than getting NULL. */ - calloc_len = input_len == 0 ? 1 : input_len; - TEST_CALLOC(input, calloc_len); - } - if (!output_null) { - /* If zero-length, ensure we actually allocate something - * rather than getting NULL. */ - calloc_len = output_len == 0 ? 1 : output_len; - TEST_CALLOC(output, calloc_len); - TEST_CALLOC(output_for_comparison, calloc_len); - - fill_buffer_pattern(output, output_len); - /* We expect the output buffer to be freed, so keep a copy - * for comparison. */ - memcpy(output_for_comparison, output, output_len); - } - if (!orig_output_null) { - /* If zero-length, ensure we actually allocate something - * rather than getting NULL. */ - calloc_len = output_len == 0 ? 1 : output_len; - TEST_CALLOC(orig_output, calloc_len); - } - - buffer_copies.input = input; - buffer_copies.input_len = input_len; - buffer_copies.output = output; - buffer_copies.output_len = output_len; - buffer_copies.output_original = orig_output; - - ret = psa_crypto_copy_and_free(&buffer_copies); - - TEST_EQUAL((int) ret, exp_ret); - - if (exp_ret == PSA_SUCCESS) { - TEST_ASSERT(buffer_copies.input == NULL); - TEST_ASSERT(buffer_copies.output == NULL); - - if (!output_null) { - TEST_MEMORY_COMPARE(output_for_comparison, output_len, - buffer_copies.output_original, buffer_copies.output_len); - } - } - -exit: - mbedtls_free(buffer_copies.input); - mbedtls_free(buffer_copies.output); - mbedtls_free(output_for_comparison); - mbedtls_free(orig_output); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void psa_crypto_buffer_copy_round_trip() -{ - uint8_t input[100]; - uint8_t output[100]; - uint8_t output_for_comparison[100]; - psa_status_t ret; - - psa_crypto_buffer_copy_t buffer_copies; - memset(&buffer_copies, 0, sizeof(buffer_copies)); - - fill_buffer_pattern(input, sizeof(input)); - - ret = psa_crypto_alloc_and_copy(input, sizeof(input), - output, sizeof(output), - &buffer_copies); - - TEST_ASSERT(ret == PSA_SUCCESS); - TEST_MEMORY_COMPARE(input, sizeof(input), - buffer_copies.input, buffer_copies.input_len); - TEST_EQUAL(sizeof(output), buffer_copies.output_len); - - /* Simulate the PSA function filling the (internal) output buffer. */ - fill_buffer_pattern(buffer_copies.output, buffer_copies.output_len); - - /* Make a copy of output to compare the copy-back */ - memcpy(output_for_comparison, buffer_copies.output, - sizeof(output_for_comparison)); - - ret = psa_crypto_copy_and_free(&buffer_copies); - - TEST_EQUAL(ret, PSA_SUCCESS); - /* Check that the output was copied back correctly. */ - TEST_MEMORY_COMPARE(output_for_comparison, sizeof(output_for_comparison), - output, sizeof(output)); - -exit: - mbedtls_free(buffer_copies.input); - mbedtls_free(buffer_copies.output); -} -/* END_CASE */ diff --git a/tests/suites/test_suite_psa_crypto_memory.data b/tests/suites/test_suite_psa_crypto_memory.data new file mode 100644 index 0000000000..33623afdc1 --- /dev/null +++ b/tests/suites/test_suite_psa_crypto_memory.data @@ -0,0 +1,89 @@ +PSA input buffer copy: straightforward copy +copy_input:20:20:PSA_SUCCESS + +PSA input buffer copy: copy buffer larger than required +copy_input:10:20:PSA_SUCCESS + +PSA input buffer copy: copy buffer too small +copy_input:20:10:PSA_ERROR_CORRUPTION_DETECTED + +PSA input buffer copy: zero-length source buffer +copy_input:0:10:PSA_SUCCESS + +PSA input buffer copy: zero-length both buffers +copy_input:0:0:PSA_SUCCESS + +PSA output buffer copy: straightforward copy +copy_output:20:20:PSA_SUCCESS + +PSA output buffer copy: output buffer larger than required +copy_output:10:20:PSA_SUCCESS + +PSA output buffer copy: output buffer too small +copy_output:20:10:PSA_ERROR_CORRUPTION_DETECTED + +PSA output buffer copy: zero-length source buffer +copy_output:0:10:PSA_SUCCESS + +PSA output buffer copy: zero-length both buffers +copy_output:0:0:PSA_SUCCESS + +PSA buffers alloc and copy +psa_crypto_alloc_and_copy:0:20:0:20:PSA_SUCCESS + +PSA buffers alloc and copy: null input +psa_crypto_alloc_and_copy:1:0:0:20:PSA_SUCCESS + +PSA buffers alloc and copy: null output +psa_crypto_alloc_and_copy:0:20:1:0:PSA_SUCCESS + +PSA buffers alloc and copy: null input and output +psa_crypto_alloc_and_copy:1:0:1:0:PSA_SUCCESS + +PSA buffers alloc and copy zero-length input +psa_crypto_alloc_and_copy_zero_length:1:0 + +PSA buffers alloc and copy zero-length output +psa_crypto_alloc_and_copy_zero_length:0:1 + +PSA buffers alloc and copy both zero length +psa_crypto_alloc_and_copy_zero_length:1:1 + +PSA buffers alloc and copy overlapping input first +psa_crypto_alloc_and_copy_overlapping:20:20:5:PSA_SUCCESS + +PSA buffers alloc and copy overlapping output first +psa_crypto_alloc_and_copy_overlapping:20:20:-5:PSA_SUCCESS + +PSA buffers alloc and copy overlapping output within input +psa_crypto_alloc_and_copy_overlapping:20:10:5:PSA_SUCCESS + +PSA buffers alloc and copy overlapping input within output +psa_crypto_alloc_and_copy_overlapping:10:20:-5:PSA_SUCCESS + +PSA buffers alloc and copy overlapping input equals output +psa_crypto_alloc_and_copy_overlapping:20:20:0:PSA_SUCCESS + +PSA buffers copy and free +psa_crypto_copy_and_free:0:20:0:20:0:PSA_SUCCESS + +PSA buffers copy and free, null input +psa_crypto_copy_and_free:1:0:0:20:0:PSA_SUCCESS + +PSA buffers copy and free, null output +psa_crypto_copy_and_free:0:20:1:0:0:PSA_SUCCESS + +PSA buffers copy and free, null output_original +psa_crypto_copy_and_free:0:20:0:20:1:PSA_ERROR_INVALID_ARGUMENT + +PSA buffers copy and free, null output_original and null output +psa_crypto_copy_and_free:0:20:1:0:1:PSA_SUCCESS + +PSA buffers copy and free, zero-length input +psa_crypto_copy_and_free:0:0:0:20:0:PSA_ERROR_INVALID_ARGUMENT + +PSA buffers copy and free, zero-length output +psa_crypto_copy_and_free:20:0:0:0:0:PSA_ERROR_INVALID_ARGUMENT + +PSA buffers round-trip +psa_crypto_buffer_copy_round_trip diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function new file mode 100644 index 0000000000..a27f76b88a --- /dev/null +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -0,0 +1,365 @@ +/* BEGIN_HEADER */ +#include + +#include "common.h" + +#include "psa/crypto.h" + +#include "psa_crypto_core.h" + +#include "test/psa_crypto_helpers.h" + +/* Helper to fill a buffer with a data pattern. The pattern is not + * important, it just allows a basic check that the correct thing has + * been written, in a way that will detect an error in offset. */ +static void fill_buffer_pattern(uint8_t *buffer, size_t len) +{ + uint8_t data[] = { 0x12, 0x34, 0x56, 0x78 }; + + for (size_t i = 0; i < len; i++) { + buffer[i] = data[i % sizeof(data)]; + } +} + +/* Helper to get 2 buffers that overlap by the specified amount. + * The parameter ptr_diff may be negative, in which case the start of + * buf2 is allocated before the start of buf1. */ +static int setup_overlapping_buffers(size_t buf1_len, size_t buf2_len, + int ptr_diff, + uint8_t **full_buffer, + uint8_t **buf1, uint8_t **buf2) +{ + size_t total_len; + int buf1_offset; + int buf2_offset; + + *full_buffer = NULL; + *buf1 = NULL; + *buf2 = NULL; + + if (ptr_diff >= 0) { + /* + * |---------- buf1 ----------| + * <-- ptr_diff -->|---------- buf2 ----------| + */ + total_len = ptr_diff + buf2_len; + if (buf1_len > total_len) { + total_len = buf1_len; + } + buf1_offset = 0; + buf2_offset = ptr_diff; + } else { + /* + * <-- (-ptr_diff) -->|---------- buf1 ----------| + * |---------- buf2 ----------| + */ + total_len = (-ptr_diff) + buf1_len; + if (buf2_len > total_len) { + total_len = buf2_len; + } + buf1_offset = -ptr_diff; + buf2_offset = 0; + } + + /* Edge case: if the length is zero, allocate a 1-byte buffer to avoid + * calloc returning NULL. */ + if (total_len == 0) { + total_len = 1; + } + + TEST_CALLOC(*full_buffer, total_len); + + *buf1 = *full_buffer + buf1_offset; + *buf2 = *full_buffer + buf2_offset; + + return 0; + +exit: + return -1; +} +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_PSA_CRYPTO_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE */ +void copy_input(int src_len, int dst_len, psa_status_t exp_status) +{ + uint8_t *src_buffer = NULL; + uint8_t *dst_buffer = NULL; + psa_status_t status; + + TEST_CALLOC_NONNULL(src_buffer, src_len); + TEST_CALLOC_NONNULL(dst_buffer, dst_len); + + fill_buffer_pattern(src_buffer, src_len); + + status = psa_crypto_copy_input(src_buffer, src_len, dst_buffer, dst_len); + TEST_EQUAL(status, exp_status); + + if (exp_status == PSA_SUCCESS) { + /* Note: We compare the first src_len bytes of each buffer, as this is what was copied. */ + TEST_MEMORY_COMPARE(src_buffer, src_len, dst_buffer, src_len); + } + +exit: + mbedtls_free(src_buffer); + mbedtls_free(dst_buffer); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void copy_output(int src_len, int dst_len, psa_status_t exp_status) +{ + uint8_t *src_buffer = NULL; + uint8_t *dst_buffer = NULL; + psa_status_t status; + + TEST_CALLOC_NONNULL(src_buffer, src_len); + TEST_CALLOC_NONNULL(dst_buffer, dst_len); + + fill_buffer_pattern(src_buffer, src_len); + + status = psa_crypto_copy_output(src_buffer, src_len, dst_buffer, dst_len); + TEST_EQUAL(status, exp_status); + + if (exp_status == PSA_SUCCESS) { + /* Note: We compare the first src_len bytes of each buffer, as this is what was copied. */ + TEST_MEMORY_COMPARE(src_buffer, src_len, dst_buffer, src_len); + } + +exit: + mbedtls_free(src_buffer); + mbedtls_free(dst_buffer); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void psa_crypto_alloc_and_copy(int input_null, int input_len, + int output_null, int output_len, + int exp_ret) +{ + uint8_t *input_buffer = NULL; + uint8_t *output_buffer = NULL; + psa_status_t ret; + + psa_crypto_buffer_copy_t buffer_copies; + memset(&buffer_copies, 0, sizeof(buffer_copies)); + + if (!input_null) { + TEST_CALLOC(input_buffer, input_len); + fill_buffer_pattern(input_buffer, input_len); + } + if (!output_null) { + TEST_CALLOC(output_buffer, output_len); + fill_buffer_pattern(output_buffer, output_len); + } + ret = psa_crypto_alloc_and_copy(input_buffer, input_len, + output_buffer, output_len, + &buffer_copies); + TEST_EQUAL(exp_ret, (int) ret); + + if (exp_ret == PSA_SUCCESS) { + TEST_MEMORY_COMPARE(input_buffer, input_len, buffer_copies.input, buffer_copies.input_len); + TEST_EQUAL(output_len, buffer_copies.output_len); + } + +exit: + mbedtls_free(input_buffer); + mbedtls_free(output_buffer); + mbedtls_free(buffer_copies.input); + mbedtls_free(buffer_copies.output); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void psa_crypto_alloc_and_copy_zero_length(int input_zero_length, + int output_zero_length) +{ + uint8_t input_buffer[] = { 0x12 }; + uint8_t output_buffer[] = { 0x34 }; + + size_t input_len = input_zero_length ? 0 : 1; + size_t output_len = output_zero_length ? 0 : 1; + + psa_crypto_buffer_copy_t buffer_copies; + memset(&buffer_copies, 0, sizeof(buffer_copies)); + + psa_status_t ret = psa_crypto_alloc_and_copy(input_buffer, input_len, + output_buffer, output_len, + &buffer_copies); + TEST_EQUAL(ret, PSA_SUCCESS); + + if (input_zero_length) { + TEST_ASSERT(buffer_copies.input == NULL); + } else { + TEST_MEMORY_COMPARE(input_buffer, input_len, buffer_copies.input, buffer_copies.input_len); + } + if (output_zero_length) { + TEST_ASSERT(buffer_copies.output == NULL); + } else { + TEST_EQUAL(output_len, buffer_copies.output_len); + } + +exit: + mbedtls_free(buffer_copies.input); + mbedtls_free(buffer_copies.output); +} +/* END_CASE */ + +/* BEGIN_CASE */ +/* Ensure that overlapping buffers can be copied correctly. */ +void psa_crypto_alloc_and_copy_overlapping(int input_len, int output_len, + int ptr_diff, int exp_ret) +{ + uint8_t *full_buffer = NULL; + uint8_t *input = NULL; + uint8_t *output = NULL; + + psa_status_t ret; + + psa_crypto_buffer_copy_t buffer_copies; + memset(&buffer_copies, 0, sizeof(buffer_copies)); + + TEST_EQUAL(setup_overlapping_buffers(input_len, output_len, ptr_diff, + &full_buffer, &input, &output), 0); + + fill_buffer_pattern(input, input_len); + + ret = psa_crypto_alloc_and_copy(input, input_len, output, output_len, + &buffer_copies); + + TEST_EQUAL((int) ret, exp_ret); + + if (exp_ret == PSA_SUCCESS) { + if (input_len == 0) { + TEST_ASSERT(buffer_copies.input == NULL); + } else { + TEST_MEMORY_COMPARE(input, input_len, buffer_copies.input, buffer_copies.input_len); + } + if (output_len == 0) { + TEST_ASSERT(buffer_copies.output == NULL); + } else { + TEST_EQUAL(output_len, buffer_copies.output_len); + } + } + +exit: + mbedtls_free(full_buffer); + mbedtls_free(buffer_copies.input); + mbedtls_free(buffer_copies.output); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void psa_crypto_copy_and_free(int input_null, int input_len, + int output_null, int output_len, + int orig_output_null, + int exp_ret) +{ + uint8_t *input = NULL; + uint8_t *output = NULL; + uint8_t *output_for_comparison = NULL; + uint8_t *orig_output = NULL; + size_t calloc_len; + psa_status_t ret; + + psa_crypto_buffer_copy_t buffer_copies; + memset(&buffer_copies, 0, sizeof(buffer_copies)); + + if (!input_null) { + /* If zero-length, ensure we actually allocate something + * rather than getting NULL. */ + calloc_len = input_len == 0 ? 1 : input_len; + TEST_CALLOC(input, calloc_len); + } + if (!output_null) { + /* If zero-length, ensure we actually allocate something + * rather than getting NULL. */ + calloc_len = output_len == 0 ? 1 : output_len; + TEST_CALLOC(output, calloc_len); + TEST_CALLOC(output_for_comparison, calloc_len); + + fill_buffer_pattern(output, output_len); + /* We expect the output buffer to be freed, so keep a copy + * for comparison. */ + memcpy(output_for_comparison, output, output_len); + } + if (!orig_output_null) { + /* If zero-length, ensure we actually allocate something + * rather than getting NULL. */ + calloc_len = output_len == 0 ? 1 : output_len; + TEST_CALLOC(orig_output, calloc_len); + } + + buffer_copies.input = input; + buffer_copies.input_len = input_len; + buffer_copies.output = output; + buffer_copies.output_len = output_len; + buffer_copies.output_original = orig_output; + + ret = psa_crypto_copy_and_free(&buffer_copies); + + TEST_EQUAL((int) ret, exp_ret); + + if (exp_ret == PSA_SUCCESS) { + TEST_ASSERT(buffer_copies.input == NULL); + TEST_ASSERT(buffer_copies.output == NULL); + + if (!output_null) { + TEST_MEMORY_COMPARE(output_for_comparison, output_len, + buffer_copies.output_original, buffer_copies.output_len); + } + } + +exit: + mbedtls_free(buffer_copies.input); + mbedtls_free(buffer_copies.output); + mbedtls_free(output_for_comparison); + mbedtls_free(orig_output); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void psa_crypto_buffer_copy_round_trip() +{ + uint8_t input[100]; + uint8_t output[100]; + uint8_t output_for_comparison[100]; + psa_status_t ret; + + psa_crypto_buffer_copy_t buffer_copies; + memset(&buffer_copies, 0, sizeof(buffer_copies)); + + fill_buffer_pattern(input, sizeof(input)); + + ret = psa_crypto_alloc_and_copy(input, sizeof(input), + output, sizeof(output), + &buffer_copies); + + TEST_ASSERT(ret == PSA_SUCCESS); + TEST_MEMORY_COMPARE(input, sizeof(input), + buffer_copies.input, buffer_copies.input_len); + TEST_EQUAL(sizeof(output), buffer_copies.output_len); + + /* Simulate the PSA function filling the (internal) output buffer. */ + fill_buffer_pattern(buffer_copies.output, buffer_copies.output_len); + + /* Make a copy of output to compare the copy-back */ + memcpy(output_for_comparison, buffer_copies.output, + sizeof(output_for_comparison)); + + ret = psa_crypto_copy_and_free(&buffer_copies); + + TEST_EQUAL(ret, PSA_SUCCESS); + /* Check that the output was copied back correctly. */ + TEST_MEMORY_COMPARE(output_for_comparison, sizeof(output_for_comparison), + output, sizeof(output)); + +exit: + mbedtls_free(buffer_copies.input); + mbedtls_free(buffer_copies.output); +} +/* END_CASE */