From af45b8333a51d34a4b34c4b5b083cd8a22bf368b Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 30 Oct 2023 19:48:13 +0000 Subject: [PATCH 01/58] Add function prototypes for copying functions Signed-off-by: David Horstmann --- library/psa_crypto_core.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 29b3b94bfe..4c38a7566f 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -854,4 +854,34 @@ psa_status_t mbedtls_psa_verify_hash_complete( psa_status_t mbedtls_psa_verify_hash_abort( mbedtls_psa_verify_hash_interruptible_operation_t *operation); +/** Copy from an input buffer to a local copy. + * + * \param[in] input Pointer to input buffer. + * \param[in] input_len Length of the input buffer. + * \param[out] input_copy Pointer to a local copy in which to store the input data. + * \param[out] input_copy_len Length of the local copy buffer. + * \return #PSA_SUCCESS, if the buffer was successfully + * copied. + * \return #PSA_ERROR_BUFFER_TOO_SMALL, if the local copy + * is too small to hold contents of the + * input buffer. + */ +psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, + uint8_t *input_copy, size_t input_copy_len); + +/** Copy from a local output buffer into a user-supplied one. + * + * \param[in] output_copy Pointer to a local buffer containing the output. + * \param[in] output_copy_len Length of the local buffer. + * \param[out] output Pointer to user-supplied output buffer. + * \param[out] output_len Length of the user-supplied output buffer. + * \return #PSA_SUCCESS, if the buffer was successfully + * copied. + * \return #PSA_ERROR_BUFFER_TOO_SMALL, if the + * user-supplied output buffer is too small to + * hold the contents of the local buffer. + */ +psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len, + uint8_t *output, size_t output_len); + #endif /* PSA_CRYPTO_CORE_H */ From 0b241ee584d74d1782163786fac300273ee4e430 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 30 Oct 2023 20:16:41 +0000 Subject: [PATCH 02/58] Add testcases for psa_crypto_copy_input() Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.data | 9 ++++++ tests/suites/test_suite_psa_crypto.function | 31 ++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 7b1974865a..757b614bde 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7406,3 +7406,12 @@ 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 +psa_crypto_copy_input:20:20:PSA_SUCCESS + +PSA input buffer copy: copy buffer larger than required +psa_crypto_copy_input:10:20:PSA_SUCCESS + +PSA input buffer copy: copy buffer too small +psa_crypto_copy_input:20:10:PSA_ERROR_BUFFER_TOO_SMALL diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 2dfc7a4bfc..21aa3fc610 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -13,7 +13,7 @@ #include "psa/crypto.h" #include "psa_crypto_slot_management.h" -/* For psa_can_do_hash() */ +/* For psa_can_do_hash() and buffer copying functions */ #include "psa_crypto_core.h" #include "test/asn1_helpers.h" @@ -10305,3 +10305,32 @@ void ecjpake_size_macros() PSA_PAKE_INPUT_MAX_SIZE); } /* END_CASE */ + +/* BEGIN_CASE */ +void psa_crypto_copy_input(int src_len, int dst_len, int exp_ret) +{ + uint8_t data[] = {0x12, 0x34, 0x56, 0x78}; + uint8_t *src_buffer = NULL; + uint8_t *dst_buffer = NULL; + psa_status_t ret; + + TEST_CALLOC(src_buffer, src_len); + TEST_CALLOC(dst_buffer, dst_len); + + for (int i = 0; i < src_len; i++) { + src_buffer[i] = data[i % sizeof(data)]; + } + + ret = psa_crypto_copy_input(src_buffer, src_len, dst_buffer, dst_len); + TEST_EQUAL((int) ret, exp_ret); + + if (exp_ret == (int) 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 */ From fde97394a07721b277aa895a51175268848f4bfc Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 30 Oct 2023 20:29:43 +0000 Subject: [PATCH 03/58] Add implementation of psa_crypto_copy_input() Signed-off-by: David Horstmann --- library/psa_crypto.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 1faf1dd6ca..33040faf69 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8441,4 +8441,17 @@ psa_status_t psa_pake_abort( } #endif /* PSA_WANT_ALG_SOME_PAKE */ + +psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, + uint8_t *input_copy, size_t input_copy_len) +{ + if (input_len > input_copy_len) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + + memcpy(input_copy, input, input_len); + + return PSA_SUCCESS; +} + #endif /* MBEDTLS_PSA_CRYPTO_C */ From 2f964231471b11d47f33821783b48a7bb280e1c3 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 30 Oct 2023 20:34:41 +0000 Subject: [PATCH 04/58] Add testcases for psa_crypto_copy_output() Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.data | 9 +++++++ tests/suites/test_suite_psa_crypto.function | 29 +++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 757b614bde..ced02afe8a 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7415,3 +7415,12 @@ psa_crypto_copy_input:10:20:PSA_SUCCESS PSA input buffer copy: copy buffer too small psa_crypto_copy_input:20:10:PSA_ERROR_BUFFER_TOO_SMALL + +PSA output buffer copy: straightforward copy +psa_crypto_copy_output:20:20:PSA_SUCCESS + +PSA output buffer copy: output buffer larger than required +psa_crypto_copy_output:10:20:PSA_SUCCESS + +PSA output buffer copy: output buffer too small +psa_crypto_copy_output:20:10:PSA_ERROR_BUFFER_TOO_SMALL diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 21aa3fc610..c8bbcdbfe4 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10334,3 +10334,32 @@ exit: mbedtls_free(dst_buffer); } /* END_CASE */ + +/* BEGIN_CASE */ +void psa_crypto_copy_output(int src_len, int dst_len, int exp_ret) +{ + uint8_t data[] = {0x12, 0x34, 0x56, 0x78}; + uint8_t *src_buffer = NULL; + uint8_t *dst_buffer = NULL; + psa_status_t ret; + + TEST_CALLOC(src_buffer, src_len); + TEST_CALLOC(dst_buffer, dst_len); + + for (int i = 0; i < src_len; i++) { + src_buffer[i] = data[i % sizeof(data)]; + } + + ret = psa_crypto_copy_output(src_buffer, src_len, dst_buffer, dst_len); + TEST_EQUAL((int) ret, exp_ret); + + if (exp_ret == (int) 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 */ From 8978f5c32a2f09fff67746a6f08d2f31a9034ee8 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 30 Oct 2023 20:37:12 +0000 Subject: [PATCH 05/58] Add implementation of psa_crypto_copy_output() Signed-off-by: David Horstmann --- library/psa_crypto.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 33040faf69..56f02a9b41 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8454,4 +8454,14 @@ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, return PSA_SUCCESS; } +psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len, + uint8_t *output, size_t output_len) +{ + if (output_len < output_copy_len) { + return PSA_ERROR_BUFFER_TOO_SMALL; + } + memcpy(output, output_copy, output_copy_len); + return PSA_SUCCESS; +} + #endif /* MBEDTLS_PSA_CRYPTO_C */ From 1d838b27b1b770534a79c58c5db819e38beee5a9 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 31 Oct 2023 15:41:45 +0000 Subject: [PATCH 06/58] Add buffers struct and prototypes for alloc API Add function prototypes for psa_crypto_alloc_and_copy() and psa_crypto_alloc_and_free(), along with the necessary state struct. Signed-off-by: David Horstmann --- library/psa_crypto_core.h | 53 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 4c38a7566f..78550f8ee5 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -884,4 +884,57 @@ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len, uint8_t *output, size_t output_len); +/** + * \brief Structure to store a pair of copied buffers (input, output) with a + * reference to the original output to be used during copy-back. + */ +struct psa_crypto_buffer_copy_s { + uint8_t *input; + size_t input_len; + + uint8_t *output_original; + uint8_t *output; + size_t output_len; +}; +typedef struct psa_crypto_buffer_copy_s psa_crypto_buffer_copy_t; + +/** + * \brief Allocate copies of provided input and output + * buffers and store references to them along with + * the original output buffer in the provided + * psa_crypto_buffer_copy_t struct. + * Either or both buffers may be NULL, in which case + * they are not copied. + * + * \note The input and output buffers may overlap. + * + * \param[in] input Pointer to the input buffer. + * \param[in] input_len Length of the input buffer. + * \param[in] output Pointer to the output buffer. + * \param[in] output_len Length of the output buffer. + * \param[out] buffers Struct containing pointers to the allocated + * copies and the original output buffer. + * \retval #PSA_SUCCESS + * The buffers were successfully allocated and copied. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * Failed to allocate buffers. + */ +psa_status_t psa_crypto_alloc_and_copy(const uint8_t *input, size_t input_len, + uint8_t *output, size_t output_len, + psa_crypto_buffer_copy_t *buffers); + +/** + * \brief Free an allocated pair of buffers after first + * copying the output buffer back to its original. + * + * \param[in] buffers psa_crypto_buffer_copy_t created by a previous + * call to psa_crypto_alloc_and_copy(). + * \retval #PSA_SUCCESS + * The buffers were successfully copied-back and the + * copies freed. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * Could not copy-back as \p buffers is invalid. + */ +psa_status_t psa_crypto_copy_and_free(psa_crypto_buffer_copy_t *buffers); + #endif /* PSA_CRYPTO_CORE_H */ From 24f11f9cc7c3224ab06ea52bf238369961965586 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 31 Oct 2023 17:40:59 +0000 Subject: [PATCH 07/58] Add testcases for psa_crypto_alloc_and_copy() Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.data | 12 ++++++ tests/suites/test_suite_psa_crypto.function | 41 +++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index ced02afe8a..ca13b51e84 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7424,3 +7424,15 @@ psa_crypto_copy_output:10:20:PSA_SUCCESS PSA output buffer copy: output buffer too small psa_crypto_copy_output:20:10:PSA_ERROR_BUFFER_TOO_SMALL + +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 diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index c8bbcdbfe4..cd46fef13b 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10363,3 +10363,44 @@ exit: 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 data[] = {0x12, 0x34, 0x56, 0x78}; + uint8_t *input_buffer = NULL; + uint8_t *output_buffer = NULL; + psa_crypto_buffer_copy_t buffer_copies = { 0 }; + psa_status_t ret; + + if (!input_null) { + TEST_CALLOC(input_buffer, input_len); + for (int i = 0; i < input_len; i++) { + input_buffer[i] = data[i % sizeof(data)]; + } + } + if (!output_null) { + TEST_CALLOC(output_buffer, output_len); + for (int i = 0; i < output_len; i++) { + output_buffer[i] = data[i % sizeof(data)]; + } + } + 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 */ From 83eef383c700148d6fab57f0a57bacf9680c535f Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 31 Oct 2023 18:03:06 +0000 Subject: [PATCH 08/58] Add implementation of psa_crypto_alloc_and_copy() Signed-off-by: David Horstmann --- library/psa_crypto.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 56f02a9b41..fc5e241900 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8464,4 +8464,49 @@ psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_co return PSA_SUCCESS; } +psa_status_t psa_crypto_alloc_and_copy(const uint8_t *input, size_t input_len, + uint8_t *output, size_t output_len, + psa_crypto_buffer_copy_t *buffers) +{ + psa_status_t ret; + /* Zeroize the buffers struct to ensure we can call free() + * on any pointers safely. */ + memset(buffers, 0, sizeof(*buffers)); + + if (output != NULL) { + buffers->output = mbedtls_calloc(output_len, 1); + if (buffers->output == NULL) { + ret = PSA_ERROR_INSUFFICIENT_MEMORY; + goto error; + } + buffers->output_len = output_len; + + buffers->output_original = output; + } + + if (input != NULL) { + buffers->input = mbedtls_calloc(input_len, 1); + if (buffers->input == NULL) { + ret = PSA_ERROR_INSUFFICIENT_MEMORY; + goto error; + } + buffers->input_len = input_len; + + if (psa_crypto_copy_input(input, input_len, + buffers->input, buffers->input_len) + != PSA_SUCCESS) { + ret = PSA_ERROR_CORRUPTION_DETECTED; + goto error; + } + } + + return PSA_SUCCESS; + +error: + mbedtls_free(buffers->input); + mbedtls_free(buffers->output); + memset(buffers, 0, sizeof(*buffers)); + return ret; +} + #endif /* MBEDTLS_PSA_CRYPTO_C */ From f06ac88284e7305be6614bf59b882a5af55f9025 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 31 Oct 2023 18:43:09 +0000 Subject: [PATCH 09/58] Add extra testcases for buffer copying Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.data | 12 ++++++++++++ tests/suites/test_suite_psa_crypto.function | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index ca13b51e84..be32882513 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7416,6 +7416,12 @@ psa_crypto_copy_input:10:20:PSA_SUCCESS PSA input buffer copy: copy buffer too small psa_crypto_copy_input:20:10:PSA_ERROR_BUFFER_TOO_SMALL +PSA input buffer copy: zero-length source buffer +psa_crypto_copy_input:0:10:PSA_SUCCESS + +PSA input buffer copy: zero-length both buffers +psa_crypto_copy_input:0:0:PSA_SUCCESS + PSA output buffer copy: straightforward copy psa_crypto_copy_output:20:20:PSA_SUCCESS @@ -7425,6 +7431,12 @@ psa_crypto_copy_output:10:20:PSA_SUCCESS PSA output buffer copy: output buffer too small psa_crypto_copy_output:20:10:PSA_ERROR_BUFFER_TOO_SMALL +PSA output buffer copy: zero-length source buffer +psa_crypto_copy_output:0:10:PSA_SUCCESS + +PSA output buffer copy: zero-length both buffers +psa_crypto_copy_output:0:0:PSA_SUCCESS + PSA buffers alloc and copy psa_crypto_alloc_and_copy:0:20:0:20:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index cd46fef13b..1e9e8d9565 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10314,8 +10314,12 @@ void psa_crypto_copy_input(int src_len, int dst_len, int exp_ret) uint8_t *dst_buffer = NULL; psa_status_t ret; - TEST_CALLOC(src_buffer, src_len); - TEST_CALLOC(dst_buffer, dst_len); + /* Special case, when src_len or dst_len is 0, we want to test on a real + * buffer. Calling TEST_CALLOC with 0 will return NULL. */ + size_t src_calloc_len = (src_len == 0 ? 1 : src_len); + size_t dst_calloc_len = (dst_len == 0 ? 1 : dst_len); + TEST_CALLOC(src_buffer, src_calloc_len); + TEST_CALLOC(dst_buffer, dst_calloc_len); for (int i = 0; i < src_len; i++) { src_buffer[i] = data[i % sizeof(data)]; @@ -10343,8 +10347,12 @@ void psa_crypto_copy_output(int src_len, int dst_len, int exp_ret) uint8_t *dst_buffer = NULL; psa_status_t ret; - TEST_CALLOC(src_buffer, src_len); - TEST_CALLOC(dst_buffer, dst_len); + /* Special case, when src_len or dst_len is 0, we want to test on a real + * buffer. Calling TEST_CALLOC with 0 will return NULL. */ + size_t src_calloc_len = (src_len == 0 ? 1 : src_len); + size_t dst_calloc_len = (dst_len == 0 ? 1 : dst_len); + TEST_CALLOC(src_buffer, src_calloc_len); + TEST_CALLOC(dst_buffer, dst_calloc_len); for (int i = 0; i < src_len; i++) { src_buffer[i] = data[i % sizeof(data)]; From 03b0472413e8479e01d839e51d05df69312ad882 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 1 Nov 2023 12:30:24 +0000 Subject: [PATCH 10/58] Zero-length test for psa_crypto_alloc_and_copy() Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.data | 9 +++++++ tests/suites/test_suite_psa_crypto.function | 26 +++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index be32882513..ac679f9d33 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7448,3 +7448,12 @@ 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 diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 1e9e8d9565..073bb6b4f3 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10412,3 +10412,29 @@ exit: 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 }; + + psa_crypto_buffer_copy_t buffer_copies; + + size_t input_len = input_zero_length ? 0 : 1; + size_t output_len = output_zero_length ? 0 : 1; + + psa_status_t ret = psa_crypto_alloc_and_copy(input_buffer, input_len, + output_buffer, output_len, + &buffer_copies); + TEST_EQUAL(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(buffer_copies.input); + mbedtls_free(buffer_copies.output); +} +/* END_CASE */ From 0fee689e574a0be51ac4113564210936d6b7434a Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 1 Nov 2023 14:46:02 +0000 Subject: [PATCH 11/58] Simplify zero-length buffers to always be NULL Since it is implementation-dependent whether malloc(0) returns NULL or a pointer, explicitly represent zero-length buffers as NULL in the buffer-copy struct, so as to have a uniform behaviour. Signed-off-by: David Horstmann --- library/psa_crypto.c | 10 ++++++++++ tests/suites/test_suite_psa_crypto.function | 12 ++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index fc5e241900..7b4fc6c9d3 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8473,6 +8473,16 @@ psa_status_t psa_crypto_alloc_and_copy(const uint8_t *input, size_t input_len, * on any pointers safely. */ memset(buffers, 0, sizeof(*buffers)); + /* Since calloc() may return NULL if we try to allocate zero-length + * buffers anyway, deal with this corner case explicitly to ensure + * predictable behaviour. Represent zero-length buffers as NULL. */ + if (input_len == 0) { + input = NULL; + } + if (output_len == 0) { + output = NULL; + } + if (output != NULL) { buffers->output = mbedtls_calloc(output_len, 1); if (buffers->output == NULL) { diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 073bb6b4f3..8057763283 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10430,8 +10430,16 @@ void psa_crypto_alloc_and_copy_zero_length(int input_zero_length, &buffer_copies); TEST_EQUAL(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); + 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); From 9700876520ef3200bcd29783b65e76cdf3c25421 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 1 Nov 2023 15:41:54 +0000 Subject: [PATCH 12/58] Add testcases for psa_crypto_copy_and_free() Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.data | 9 +++ tests/suites/test_suite_psa_crypto.function | 71 +++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index ac679f9d33..d6b2942805 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7457,3 +7457,12 @@ 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 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 diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 8057763283..4d945c3ff6 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10446,3 +10446,74 @@ exit: 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 data[] = {0x12, 0x34, 0x56, 0x78}; + psa_crypto_buffer_copy_t buffer_copies = { 0 }; + + 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; + + 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); + + for (int i = 0; i < output_len; i++) { + output[i] = data[i % sizeof(data)]; + } + /* 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 */ From f4bbb632cdf52aca747e7eed306413b836519321 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 1 Nov 2023 17:47:39 +0000 Subject: [PATCH 13/58] Add implementation of psa_crypto_copy_and_free() Signed-off-by: David Horstmann --- library/psa_crypto.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 7b4fc6c9d3..25cc23893f 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8519,4 +8519,18 @@ error: return ret; } +psa_status_t psa_crypto_copy_and_free(psa_crypto_buffer_copy_t *buffers) +{ + if (buffers->output != NULL) { + memcpy(buffers->output_original, buffers->output, buffers->output_len); + } + + mbedtls_free(buffers->input); + buffers->input = NULL; + mbedtls_free(buffers->output); + buffers->output = NULL; + + return PSA_SUCCESS; +} + #endif /* MBEDTLS_PSA_CRYPTO_C */ From 2b79cbaa17ce2e190888b13c95b961668cc22d8e Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 1 Nov 2023 17:55:43 +0000 Subject: [PATCH 14/58] Reject NULL original_output with non-NULL output If we have a copy buffer but no original to copy back to, there is not much sensible we can do. The psa_crypto_buffer_copy_t state is invalid. Signed-off-by: David Horstmann --- library/psa_crypto.c | 6 ++++++ tests/suites/test_suite_psa_crypto.data | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 25cc23893f..02aa0eb279 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8522,6 +8522,12 @@ error: psa_status_t psa_crypto_copy_and_free(psa_crypto_buffer_copy_t *buffers) { if (buffers->output != NULL) { + if (buffers->output_original == NULL) { + /* Output is non-NULL but original output is NULL. The argument + * buffers is invalid. Return an error as we have no original to + * copy back to. */ + return PSA_ERROR_INVALID_ARGUMENT; + } memcpy(buffers->output_original, buffers->output, buffers->output_len); } diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index d6b2942805..81ad333b67 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7466,3 +7466,9 @@ 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 From 72ab8ad44a386e1aa0cb20ae60379afccffb7d09 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 2 Nov 2023 12:00:02 +0000 Subject: [PATCH 15/58] Reject zero-lengths in psa_crypto_copy_and_free() Zero-length buffers should be represented in the psa_crypto_buffer_copy_t struct as NULL if it was created in psa_crypto_alloc_and_copy(), so reject non-NULL zero-length buffers. Signed-off-by: David Horstmann --- library/psa_crypto.c | 10 ++++++++++ tests/suites/test_suite_psa_crypto.data | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 02aa0eb279..33068af385 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8521,7 +8521,17 @@ error: psa_status_t psa_crypto_copy_and_free(psa_crypto_buffer_copy_t *buffers) { + if ((buffers->input != NULL) && (buffers->input_len == 0)) { + /* Reject zero-length buffers, these should have been represented by + * NULL in psa_crypto_alloc_and_copy() */ + return PSA_ERROR_INVALID_ARGUMENT; + } if (buffers->output != NULL) { + if (buffers->output_len == 0) { + /* Reject zero-length buffers, these should have been represented + * by NULL in psa_crypto_alloc_and_copy() */ + return PSA_ERROR_INVALID_ARGUMENT; + } if (buffers->output_original == NULL) { /* Output is non-NULL but original output is NULL. The argument * buffers is invalid. Return an error as we have no original to diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 81ad333b67..f27a9beab4 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7472,3 +7472,9 @@ 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 From 5b9c21756a96360a716ef7735f1149dc291039f2 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 2 Nov 2023 14:39:00 +0000 Subject: [PATCH 16/58] Add test case for overlapping buffers Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.data | 15 +++ tests/suites/test_suite_psa_crypto.function | 103 ++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index f27a9beab4..948196e052 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7458,6 +7458,21 @@ 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 diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 4d945c3ff6..600c8ea22e 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1253,6 +1253,63 @@ static void interruptible_signverify_get_minmax_completes(uint32_t max_ops, } #endif /* MBEDTLS_ECP_RESTARTABLE */ +/* 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 @@ -10447,6 +10504,52 @@ exit: } /* 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 data[] = {0x12, 0x34, 0x56, 0x78}; + psa_crypto_buffer_copy_t buffer_copies = { 0 }; + + uint8_t *full_buffer = NULL; + uint8_t *input = NULL; + uint8_t *output = NULL; + + psa_status_t ret; + + TEST_EQUAL(setup_overlapping_buffers(input_len, output_len, ptr_diff, + &full_buffer, &input, &output), 0); + + for (int i = 0; i < input_len; i++) { + input[i] = data[i % sizeof(data)]; + } + + 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, From 70fda48670eeb63e91f8f71d8e27bc4ad595bd1d Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 2 Nov 2023 17:07:16 +0000 Subject: [PATCH 17/58] Add full round-trip tests for buffer copying Test that a buffer pair can be created with psa_crypto_alloc_and_copy() and destroyed with psa_crypto_copy_and_free() correctly. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.data | 3 ++ tests/suites/test_suite_psa_crypto.function | 44 +++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 948196e052..d197023394 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7493,3 +7493,6 @@ 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 600c8ea22e..23d25eddb4 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10620,3 +10620,47 @@ exit: mbedtls_free(orig_output); } /* END_CASE */ + +/* BEGIN_CASE */ +void psa_crypto_buffer_copy_round_trip() +{ + uint8_t data[] = {0x12, 0x34, 0x56, 0x78}; + uint8_t input[100]; + uint8_t output[100]; + uint8_t output_for_comparison[100]; + psa_crypto_buffer_copy_t buffer_copies = { 0 }; + psa_status_t ret; + + for (size_t i = 0; i < sizeof(input); i++) { + input[i] = data[i % sizeof(data)]; + } + + 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. */ + for (size_t i = 0; i < buffer_copies.output_len; i++) { + buffer_copies.output[i] = data[i % sizeof(data)]; + } + /* 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 */ From 8f77dc7f681951b3f1690c58ff6c17d29d4ca0b8 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 2 Nov 2023 17:48:07 +0000 Subject: [PATCH 18/58] Refactor: move buffer pattern fills into helper Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.function | 51 +++++++++------------ 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 23d25eddb4..d58864f593 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -1253,6 +1253,18 @@ 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. */ @@ -10366,7 +10378,6 @@ void ecjpake_size_macros() /* BEGIN_CASE */ void psa_crypto_copy_input(int src_len, int dst_len, int exp_ret) { - uint8_t data[] = {0x12, 0x34, 0x56, 0x78}; uint8_t *src_buffer = NULL; uint8_t *dst_buffer = NULL; psa_status_t ret; @@ -10378,9 +10389,7 @@ void psa_crypto_copy_input(int src_len, int dst_len, int exp_ret) TEST_CALLOC(src_buffer, src_calloc_len); TEST_CALLOC(dst_buffer, dst_calloc_len); - for (int i = 0; i < src_len; i++) { - src_buffer[i] = data[i % sizeof(data)]; - } + fill_buffer_pattern(src_buffer, src_len); ret = psa_crypto_copy_input(src_buffer, src_len, dst_buffer, dst_len); TEST_EQUAL((int) ret, exp_ret); @@ -10399,7 +10408,6 @@ exit: /* BEGIN_CASE */ void psa_crypto_copy_output(int src_len, int dst_len, int exp_ret) { - uint8_t data[] = {0x12, 0x34, 0x56, 0x78}; uint8_t *src_buffer = NULL; uint8_t *dst_buffer = NULL; psa_status_t ret; @@ -10411,9 +10419,7 @@ void psa_crypto_copy_output(int src_len, int dst_len, int exp_ret) TEST_CALLOC(src_buffer, src_calloc_len); TEST_CALLOC(dst_buffer, dst_calloc_len); - for (int i = 0; i < src_len; i++) { - src_buffer[i] = data[i % sizeof(data)]; - } + fill_buffer_pattern(src_buffer, src_len); ret = psa_crypto_copy_output(src_buffer, src_len, dst_buffer, dst_len); TEST_EQUAL((int) ret, exp_ret); @@ -10434,7 +10440,6 @@ void psa_crypto_alloc_and_copy(int input_null, int input_len, int output_null, int output_len, int exp_ret) { - uint8_t data[] = {0x12, 0x34, 0x56, 0x78}; uint8_t *input_buffer = NULL; uint8_t *output_buffer = NULL; psa_crypto_buffer_copy_t buffer_copies = { 0 }; @@ -10442,15 +10447,11 @@ void psa_crypto_alloc_and_copy(int input_null, int input_len, if (!input_null) { TEST_CALLOC(input_buffer, input_len); - for (int i = 0; i < input_len; i++) { - input_buffer[i] = data[i % sizeof(data)]; - } + fill_buffer_pattern(input_buffer, input_len); } if (!output_null) { TEST_CALLOC(output_buffer, output_len); - for (int i = 0; i < output_len; i++) { - output_buffer[i] = data[i % sizeof(data)]; - } + fill_buffer_pattern(output_buffer, output_len); } ret = psa_crypto_alloc_and_copy(input_buffer, input_len, output_buffer, output_len, @@ -10509,7 +10510,6 @@ exit: void psa_crypto_alloc_and_copy_overlapping(int input_len, int output_len, int ptr_diff, int exp_ret) { - uint8_t data[] = {0x12, 0x34, 0x56, 0x78}; psa_crypto_buffer_copy_t buffer_copies = { 0 }; uint8_t *full_buffer = NULL; @@ -10521,9 +10521,7 @@ void psa_crypto_alloc_and_copy_overlapping(int input_len, int output_len, TEST_EQUAL(setup_overlapping_buffers(input_len, output_len, ptr_diff, &full_buffer, &input, &output), 0); - for (int i = 0; i < input_len; i++) { - input[i] = data[i % sizeof(data)]; - } + fill_buffer_pattern(input, input_len); ret = psa_crypto_alloc_and_copy(input, input_len, output, output_len, &buffer_copies); @@ -10556,7 +10554,6 @@ void psa_crypto_copy_and_free(int input_null, int input_len, int orig_output_null, int exp_ret) { - uint8_t data[] = {0x12, 0x34, 0x56, 0x78}; psa_crypto_buffer_copy_t buffer_copies = { 0 }; uint8_t *input = NULL; @@ -10579,9 +10576,7 @@ void psa_crypto_copy_and_free(int input_null, int input_len, TEST_CALLOC(output, calloc_len); TEST_CALLOC(output_for_comparison, calloc_len); - for (int i = 0; i < output_len; i++) { - output[i] = data[i % sizeof(data)]; - } + 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); @@ -10624,16 +10619,13 @@ exit: /* BEGIN_CASE */ void psa_crypto_buffer_copy_round_trip() { - uint8_t data[] = {0x12, 0x34, 0x56, 0x78}; uint8_t input[100]; uint8_t output[100]; uint8_t output_for_comparison[100]; psa_crypto_buffer_copy_t buffer_copies = { 0 }; psa_status_t ret; - for (size_t i = 0; i < sizeof(input); i++) { - input[i] = data[i % sizeof(data)]; - } + fill_buffer_pattern(input, sizeof(input)); ret = psa_crypto_alloc_and_copy(input, sizeof(input), output, sizeof(output), @@ -10645,9 +10637,8 @@ void psa_crypto_buffer_copy_round_trip() TEST_EQUAL(sizeof(output), buffer_copies.output_len); /* Simulate the PSA function filling the (internal) output buffer. */ - for (size_t i = 0; i < buffer_copies.output_len; i++) { - buffer_copies.output[i] = data[i % sizeof(data)]; - } + 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)); From 676cfdd0eab65abb30dc24f30d63985d3da76ef2 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 2 Nov 2023 20:47:04 +0000 Subject: [PATCH 19/58] Replace compound-initializers with memset This should eliminate some pedantic compiler warnings. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.function | 23 ++++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index d58864f593..1dab4e055f 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10442,9 +10442,11 @@ void psa_crypto_alloc_and_copy(int input_null, int input_len, { uint8_t *input_buffer = NULL; uint8_t *output_buffer = NULL; - psa_crypto_buffer_copy_t buffer_copies = { 0 }; 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); @@ -10478,11 +10480,12 @@ void psa_crypto_alloc_and_copy_zero_length(int input_zero_length, uint8_t input_buffer[] = { 0x12 }; uint8_t output_buffer[] = { 0x34 }; - psa_crypto_buffer_copy_t buffer_copies; - 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); @@ -10510,14 +10513,15 @@ exit: void psa_crypto_alloc_and_copy_overlapping(int input_len, int output_len, int ptr_diff, int exp_ret) { - psa_crypto_buffer_copy_t buffer_copies = { 0 }; - 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); @@ -10554,8 +10558,6 @@ void psa_crypto_copy_and_free(int input_null, int input_len, int orig_output_null, int exp_ret) { - psa_crypto_buffer_copy_t buffer_copies = { 0 }; - uint8_t *input = NULL; uint8_t *output = NULL; uint8_t *output_for_comparison = NULL; @@ -10563,6 +10565,9 @@ void psa_crypto_copy_and_free(int input_null, int input_len, 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. */ @@ -10622,9 +10627,11 @@ void psa_crypto_buffer_copy_round_trip() uint8_t input[100]; uint8_t output[100]; uint8_t output_for_comparison[100]; - psa_crypto_buffer_copy_t buffer_copies = { 0 }; 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), From 8995b50cf4aabf76227d3feacc192fcee95b5145 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 19:20:33 +0000 Subject: [PATCH 20/58] Remove superfluous comment Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.function | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 1dab4e055f..890a0448a8 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -13,7 +13,6 @@ #include "psa/crypto.h" #include "psa_crypto_slot_management.h" -/* For psa_can_do_hash() and buffer copying functions */ #include "psa_crypto_core.h" #include "test/asn1_helpers.h" From ac12d2dc69451dda421586cc9f4fead37b2ef582 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 19:23:49 +0000 Subject: [PATCH 21/58] Remove psa_crypto_ prefix from test functions This ensures they have a different name to the functions they test. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.data | 20 ++++++++++---------- tests/suites/test_suite_psa_crypto.function | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index d197023394..6b112462b4 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7408,34 +7408,34 @@ 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 -psa_crypto_copy_input:20:20:PSA_SUCCESS +copy_input:20:20:PSA_SUCCESS PSA input buffer copy: copy buffer larger than required -psa_crypto_copy_input:10:20:PSA_SUCCESS +copy_input:10:20:PSA_SUCCESS PSA input buffer copy: copy buffer too small -psa_crypto_copy_input:20:10:PSA_ERROR_BUFFER_TOO_SMALL +copy_input:20:10:PSA_ERROR_BUFFER_TOO_SMALL PSA input buffer copy: zero-length source buffer -psa_crypto_copy_input:0:10:PSA_SUCCESS +copy_input:0:10:PSA_SUCCESS PSA input buffer copy: zero-length both buffers -psa_crypto_copy_input:0:0:PSA_SUCCESS +copy_input:0:0:PSA_SUCCESS PSA output buffer copy: straightforward copy -psa_crypto_copy_output:20:20:PSA_SUCCESS +copy_output:20:20:PSA_SUCCESS PSA output buffer copy: output buffer larger than required -psa_crypto_copy_output:10:20:PSA_SUCCESS +copy_output:10:20:PSA_SUCCESS PSA output buffer copy: output buffer too small -psa_crypto_copy_output:20:10:PSA_ERROR_BUFFER_TOO_SMALL +copy_output:20:10:PSA_ERROR_BUFFER_TOO_SMALL PSA output buffer copy: zero-length source buffer -psa_crypto_copy_output:0:10:PSA_SUCCESS +copy_output:0:10:PSA_SUCCESS PSA output buffer copy: zero-length both buffers -psa_crypto_copy_output:0:0:PSA_SUCCESS +copy_output:0:0:PSA_SUCCESS PSA buffers alloc and copy psa_crypto_alloc_and_copy:0:20:0:20:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 890a0448a8..4f57e05229 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10375,7 +10375,7 @@ void ecjpake_size_macros() /* END_CASE */ /* BEGIN_CASE */ -void psa_crypto_copy_input(int src_len, int dst_len, int exp_ret) +void copy_input(int src_len, int dst_len, int exp_ret) { uint8_t *src_buffer = NULL; uint8_t *dst_buffer = NULL; @@ -10405,7 +10405,7 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -void psa_crypto_copy_output(int src_len, int dst_len, int exp_ret) +void copy_output(int src_len, int dst_len, int exp_ret) { uint8_t *src_buffer = NULL; uint8_t *dst_buffer = NULL; From 8075c7faf7a9cf828756530fd46332e4298df435 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 19:28:08 +0000 Subject: [PATCH 22/58] Switch from int to psa_status_t for test args Remove unnecessary casts as well. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.function | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 4f57e05229..6f757fd3fb 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10375,7 +10375,7 @@ void ecjpake_size_macros() /* END_CASE */ /* BEGIN_CASE */ -void copy_input(int src_len, int dst_len, int exp_ret) +void copy_input(int src_len, int dst_len, psa_status_t exp_ret) { uint8_t *src_buffer = NULL; uint8_t *dst_buffer = NULL; @@ -10391,9 +10391,9 @@ void copy_input(int src_len, int dst_len, int exp_ret) fill_buffer_pattern(src_buffer, src_len); ret = psa_crypto_copy_input(src_buffer, src_len, dst_buffer, dst_len); - TEST_EQUAL((int) ret, exp_ret); + TEST_EQUAL(ret, exp_ret); - if (exp_ret == (int) PSA_SUCCESS) { + if (exp_ret == 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); } @@ -10405,7 +10405,7 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -void copy_output(int src_len, int dst_len, int exp_ret) +void copy_output(int src_len, int dst_len, psa_status_t exp_ret) { uint8_t *src_buffer = NULL; uint8_t *dst_buffer = NULL; @@ -10421,9 +10421,9 @@ void copy_output(int src_len, int dst_len, int exp_ret) fill_buffer_pattern(src_buffer, src_len); ret = psa_crypto_copy_output(src_buffer, src_len, dst_buffer, dst_len); - TEST_EQUAL((int) ret, exp_ret); + TEST_EQUAL(ret, exp_ret); - if (exp_ret == (int) PSA_SUCCESS) { + if (exp_ret == 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); } From b8381513c19a440c2e28c4c14ecc10e6a96cce2d Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 19:31:35 +0000 Subject: [PATCH 23/58] Switch from ret to status as naming convention Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.function | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 6f757fd3fb..8747660391 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10375,11 +10375,11 @@ void ecjpake_size_macros() /* END_CASE */ /* BEGIN_CASE */ -void copy_input(int src_len, int dst_len, psa_status_t exp_ret) +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 ret; + psa_status_t status; /* Special case, when src_len or dst_len is 0, we want to test on a real * buffer. Calling TEST_CALLOC with 0 will return NULL. */ @@ -10390,10 +10390,10 @@ void copy_input(int src_len, int dst_len, psa_status_t exp_ret) fill_buffer_pattern(src_buffer, src_len); - ret = psa_crypto_copy_input(src_buffer, src_len, dst_buffer, dst_len); - TEST_EQUAL(ret, exp_ret); + status = psa_crypto_copy_input(src_buffer, src_len, dst_buffer, dst_len); + TEST_EQUAL(status, exp_status); - if (exp_ret == PSA_SUCCESS) { + 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); } @@ -10405,11 +10405,11 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -void copy_output(int src_len, int dst_len, psa_status_t exp_ret) +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 ret; + psa_status_t status; /* Special case, when src_len or dst_len is 0, we want to test on a real * buffer. Calling TEST_CALLOC with 0 will return NULL. */ @@ -10420,10 +10420,10 @@ void copy_output(int src_len, int dst_len, psa_status_t exp_ret) fill_buffer_pattern(src_buffer, src_len); - ret = psa_crypto_copy_output(src_buffer, src_len, dst_buffer, dst_len); - TEST_EQUAL(ret, exp_ret); + status = psa_crypto_copy_output(src_buffer, src_len, dst_buffer, dst_len); + TEST_EQUAL(status, exp_status); - if (exp_ret == PSA_SUCCESS) { + 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); } From 86cdc7646de5ace463d8727c0e36827bc796f198 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 19:45:39 +0000 Subject: [PATCH 24/58] Switch to TEST_CALLOC_NONNULL() This removes some gubbins related to making sure the buffer is not NULL that was previously cluttering the test case. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.function | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 8747660391..41d7009296 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10381,12 +10381,8 @@ void copy_input(int src_len, int dst_len, psa_status_t exp_status) uint8_t *dst_buffer = NULL; psa_status_t status; - /* Special case, when src_len or dst_len is 0, we want to test on a real - * buffer. Calling TEST_CALLOC with 0 will return NULL. */ - size_t src_calloc_len = (src_len == 0 ? 1 : src_len); - size_t dst_calloc_len = (dst_len == 0 ? 1 : dst_len); - TEST_CALLOC(src_buffer, src_calloc_len); - TEST_CALLOC(dst_buffer, dst_calloc_len); + TEST_CALLOC_NONNULL(src_buffer, src_len); + TEST_CALLOC_NONNULL(dst_buffer, dst_len); fill_buffer_pattern(src_buffer, src_len); @@ -10411,12 +10407,8 @@ void copy_output(int src_len, int dst_len, psa_status_t exp_status) uint8_t *dst_buffer = NULL; psa_status_t status; - /* Special case, when src_len or dst_len is 0, we want to test on a real - * buffer. Calling TEST_CALLOC with 0 will return NULL. */ - size_t src_calloc_len = (src_len == 0 ? 1 : src_len); - size_t dst_calloc_len = (dst_len == 0 ? 1 : dst_len); - TEST_CALLOC(src_buffer, src_calloc_len); - TEST_CALLOC(dst_buffer, dst_calloc_len); + TEST_CALLOC_NONNULL(src_buffer, src_len); + TEST_CALLOC_NONNULL(dst_buffer, dst_len); fill_buffer_pattern(src_buffer, src_len); From 49a7276c497b466d4eea7dd283ba940dbb297c2a Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 19:51:40 +0000 Subject: [PATCH 25/58] Switch error code to more appropriate value Since we are internal rather than user-facing, PSA_ERROR_CORRUPTION_DETECTED makes more sense than PSA_ERROR_BUFFER_TOO_SMALL. Whilst it really is a buffer that is too small, this error code is intended to indicate that a user-supplied buffer is too small, not an internal one. Signed-off-by: David Horstmann --- library/psa_crypto.c | 4 ++-- library/psa_crypto_core.h | 6 +++--- tests/suites/test_suite_psa_crypto.data | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 33068af385..09180b3c3a 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8446,7 +8446,7 @@ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, uint8_t *input_copy, size_t input_copy_len) { if (input_len > input_copy_len) { - return PSA_ERROR_BUFFER_TOO_SMALL; + return PSA_ERROR_CORRUPTION_DETECTED; } memcpy(input_copy, input, input_len); @@ -8458,7 +8458,7 @@ psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_co uint8_t *output, size_t output_len) { if (output_len < output_copy_len) { - return PSA_ERROR_BUFFER_TOO_SMALL; + return PSA_ERROR_CORRUPTION_DETECTED; } memcpy(output, output_copy, output_copy_len); return PSA_SUCCESS; diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 78550f8ee5..00d9e9eedd 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -862,8 +862,8 @@ psa_status_t mbedtls_psa_verify_hash_abort( * \param[out] input_copy_len Length of the local copy buffer. * \return #PSA_SUCCESS, if the buffer was successfully * copied. - * \return #PSA_ERROR_BUFFER_TOO_SMALL, if the local copy - * is too small to hold contents of the + * \return #PSA_ERROR_CORRUPTION_DETECTED, if the local + * copy is too small to hold contents of the * input buffer. */ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, @@ -877,7 +877,7 @@ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, * \param[out] output_len Length of the user-supplied output buffer. * \return #PSA_SUCCESS, if the buffer was successfully * copied. - * \return #PSA_ERROR_BUFFER_TOO_SMALL, if the + * \return #PSA_ERROR_CORRUPTION_DETECTED, if the * user-supplied output buffer is too small to * hold the contents of the local buffer. */ diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 6b112462b4..594c609e3c 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -7414,7 +7414,7 @@ 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_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 @@ -7429,7 +7429,7 @@ 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_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 From ad33ab376b619fffeb6d2b4a8f10f22bf8994c33 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 20:01:37 +0000 Subject: [PATCH 26/58] Move buffer copy tests into new testsuite Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.data | 90 ----- tests/suites/test_suite_psa_crypto.function | 348 ----------------- .../suites/test_suite_psa_crypto_memory.data | 89 +++++ .../test_suite_psa_crypto_memory.function | 365 ++++++++++++++++++ 4 files changed, 454 insertions(+), 438 deletions(-) create mode 100644 tests/suites/test_suite_psa_crypto_memory.data create mode 100644 tests/suites/test_suite_psa_crypto_memory.function 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 */ From 7dd8205423c443d149798f7cc95b8c6910a6b185 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 6 Nov 2023 17:43:40 +0000 Subject: [PATCH 27/58] Remove extra blank line at end of file (This causes code style checks to fail) Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.function | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index be773da8fa..4e8853d8e4 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -10304,4 +10304,3 @@ void ecjpake_size_macros() PSA_PAKE_INPUT_MAX_SIZE); } /* END_CASE */ - From b3de69493c8770eff88a7c65e3a38bcd3d219a48 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 6 Nov 2023 14:22:28 +0000 Subject: [PATCH 28/58] Remove psa_crypto_alloc_and_copy() API This tied input and output buffers together in awkward pairs, which made the API more difficult to use. Signed-off-by: David Horstmann --- library/psa_crypto.c | 85 ------ library/psa_crypto_core.h | 53 ---- .../suites/test_suite_psa_crypto_memory.data | 60 ---- .../test_suite_psa_crypto_memory.function | 285 ------------------ 4 files changed, 483 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 09180b3c3a..b6533496c6 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8464,89 +8464,4 @@ psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_co return PSA_SUCCESS; } -psa_status_t psa_crypto_alloc_and_copy(const uint8_t *input, size_t input_len, - uint8_t *output, size_t output_len, - psa_crypto_buffer_copy_t *buffers) -{ - psa_status_t ret; - /* Zeroize the buffers struct to ensure we can call free() - * on any pointers safely. */ - memset(buffers, 0, sizeof(*buffers)); - - /* Since calloc() may return NULL if we try to allocate zero-length - * buffers anyway, deal with this corner case explicitly to ensure - * predictable behaviour. Represent zero-length buffers as NULL. */ - if (input_len == 0) { - input = NULL; - } - if (output_len == 0) { - output = NULL; - } - - if (output != NULL) { - buffers->output = mbedtls_calloc(output_len, 1); - if (buffers->output == NULL) { - ret = PSA_ERROR_INSUFFICIENT_MEMORY; - goto error; - } - buffers->output_len = output_len; - - buffers->output_original = output; - } - - if (input != NULL) { - buffers->input = mbedtls_calloc(input_len, 1); - if (buffers->input == NULL) { - ret = PSA_ERROR_INSUFFICIENT_MEMORY; - goto error; - } - buffers->input_len = input_len; - - if (psa_crypto_copy_input(input, input_len, - buffers->input, buffers->input_len) - != PSA_SUCCESS) { - ret = PSA_ERROR_CORRUPTION_DETECTED; - goto error; - } - } - - return PSA_SUCCESS; - -error: - mbedtls_free(buffers->input); - mbedtls_free(buffers->output); - memset(buffers, 0, sizeof(*buffers)); - return ret; -} - -psa_status_t psa_crypto_copy_and_free(psa_crypto_buffer_copy_t *buffers) -{ - if ((buffers->input != NULL) && (buffers->input_len == 0)) { - /* Reject zero-length buffers, these should have been represented by - * NULL in psa_crypto_alloc_and_copy() */ - return PSA_ERROR_INVALID_ARGUMENT; - } - if (buffers->output != NULL) { - if (buffers->output_len == 0) { - /* Reject zero-length buffers, these should have been represented - * by NULL in psa_crypto_alloc_and_copy() */ - return PSA_ERROR_INVALID_ARGUMENT; - } - if (buffers->output_original == NULL) { - /* Output is non-NULL but original output is NULL. The argument - * buffers is invalid. Return an error as we have no original to - * copy back to. */ - return PSA_ERROR_INVALID_ARGUMENT; - } - memcpy(buffers->output_original, buffers->output, buffers->output_len); - } - - mbedtls_free(buffers->input); - buffers->input = NULL; - mbedtls_free(buffers->output); - buffers->output = NULL; - - return PSA_SUCCESS; -} - #endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 00d9e9eedd..c9e277c2d3 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -884,57 +884,4 @@ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len, uint8_t *output, size_t output_len); -/** - * \brief Structure to store a pair of copied buffers (input, output) with a - * reference to the original output to be used during copy-back. - */ -struct psa_crypto_buffer_copy_s { - uint8_t *input; - size_t input_len; - - uint8_t *output_original; - uint8_t *output; - size_t output_len; -}; -typedef struct psa_crypto_buffer_copy_s psa_crypto_buffer_copy_t; - -/** - * \brief Allocate copies of provided input and output - * buffers and store references to them along with - * the original output buffer in the provided - * psa_crypto_buffer_copy_t struct. - * Either or both buffers may be NULL, in which case - * they are not copied. - * - * \note The input and output buffers may overlap. - * - * \param[in] input Pointer to the input buffer. - * \param[in] input_len Length of the input buffer. - * \param[in] output Pointer to the output buffer. - * \param[in] output_len Length of the output buffer. - * \param[out] buffers Struct containing pointers to the allocated - * copies and the original output buffer. - * \retval #PSA_SUCCESS - * The buffers were successfully allocated and copied. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * Failed to allocate buffers. - */ -psa_status_t psa_crypto_alloc_and_copy(const uint8_t *input, size_t input_len, - uint8_t *output, size_t output_len, - psa_crypto_buffer_copy_t *buffers); - -/** - * \brief Free an allocated pair of buffers after first - * copying the output buffer back to its original. - * - * \param[in] buffers psa_crypto_buffer_copy_t created by a previous - * call to psa_crypto_alloc_and_copy(). - * \retval #PSA_SUCCESS - * The buffers were successfully copied-back and the - * copies freed. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * Could not copy-back as \p buffers is invalid. - */ -psa_status_t psa_crypto_copy_and_free(psa_crypto_buffer_copy_t *buffers); - #endif /* PSA_CRYPTO_CORE_H */ diff --git a/tests/suites/test_suite_psa_crypto_memory.data b/tests/suites/test_suite_psa_crypto_memory.data index 33623afdc1..0d44fb35d5 100644 --- a/tests/suites/test_suite_psa_crypto_memory.data +++ b/tests/suites/test_suite_psa_crypto_memory.data @@ -27,63 +27,3 @@ 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 index a27f76b88a..7e59bb96f9 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -20,63 +20,6 @@ static void fill_buffer_pattern(uint8_t *buffer, size_t len) 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 @@ -135,231 +78,3 @@ exit: 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 */ From 6fd4c7cff2b37584e176dce71b950ecb08e61fc0 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 6 Nov 2023 17:27:16 +0000 Subject: [PATCH 29/58] Add prototypes for psa_crypto_input_copy API This includes: * The psa_crypto_input_copy_t struct * psa_crypto_input_copy_alloc() * psa_crypto_input_copy_free() Signed-off-by: David Horstmann --- library/psa_crypto_core.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index c9e277c2d3..a53824ec3e 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -884,4 +884,31 @@ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len, uint8_t *output, size_t output_len); +typedef struct psa_crypto_input_copy_s { + uint8_t *buffer; + size_t len; +} psa_crypto_input_copy_t; + +/** Allocate a local copy of an input buffer. + * + * \param[in] input Pointer to input buffer. + * \param[in] input_len Length of the input buffer. + * \param[out] input_copy Pointer to a psa_crypto_input_copy_t struct to + * populate with the input copy. + * \return #PSA_SUCCESS, if the buffer was successfully + * copied. + * \return #PSA_ERROR_INSUFFICIENT_MEMORY, if a copy of + * the buffer cannot be allocated. + */ +psa_status_t psa_crypto_input_copy_alloc(const uint8_t *input, size_t input_len, + psa_crypto_input_copy_t *input_copy); + +/** Free a local copy of an input buffer. + * + * \param[in] input_copy Pointer to a psa_crypto_input_copy_t struct + * populated by a previous call to + * psa_crypto_input_copy_alloc(). + */ +void psa_crypto_input_copy_free(psa_crypto_input_copy_t *input_copy); + #endif /* PSA_CRYPTO_CORE_H */ From 1ac7e24fb72a54ebdab56f5e492663115bd81858 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 6 Nov 2023 18:18:59 +0000 Subject: [PATCH 30/58] Add testcase for psa_crypto_input_copy_alloc() Signed-off-by: David Horstmann --- .../suites/test_suite_psa_crypto_memory.data | 6 ++++ .../test_suite_psa_crypto_memory.function | 31 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_memory.data b/tests/suites/test_suite_psa_crypto_memory.data index 0d44fb35d5..85fed8f0e1 100644 --- a/tests/suites/test_suite_psa_crypto_memory.data +++ b/tests/suites/test_suite_psa_crypto_memory.data @@ -27,3 +27,9 @@ copy_output:0:10:PSA_SUCCESS PSA output buffer copy: zero-length both buffers copy_output:0:0:PSA_SUCCESS + +PSA crypto input copy alloc +input_copy_alloc:200:PSA_SUCCESS + +PSA crypto input copy alloc, NULL buffer +input_copy_alloc:0:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 7e59bb96f9..837ff06e9e 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -78,3 +78,34 @@ exit: mbedtls_free(dst_buffer); } /* END_CASE */ + +/* BEGIN_CASE */ +void input_copy_alloc(int input_len, psa_status_t exp_status) +{ + uint8_t *input = NULL; + psa_crypto_input_copy_t input_copy; + psa_status_t status; + + input_copy.buffer = NULL; + + TEST_CALLOC(input, input_len); + fill_buffer_pattern(input, input_len); + + status = psa_crypto_input_copy_alloc(input, input_len, &input_copy); + TEST_EQUAL(status, exp_status); + + if (exp_status == PSA_SUCCESS) { + if (input == NULL) { + TEST_ASSERT(input_copy.buffer == NULL); + } else { + TEST_ASSERT(input_copy.buffer != input); + TEST_MEMORY_COMPARE(input, input_len, + input_copy.buffer, input_copy.len); + } + } + +exit: + mbedtls_free(input_copy.buffer); + mbedtls_free(input); +} +/* END_CASE */ From 4ac788573b620387e7afe74148cf1974451e9dc7 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 7 Nov 2023 16:36:48 +0000 Subject: [PATCH 31/58] Add psa_crypto_input_copy_alloc() implementation Signed-off-by: David Horstmann --- library/psa_crypto.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index b6533496c6..2c37aebf79 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8464,4 +8464,43 @@ psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_co return PSA_SUCCESS; } +psa_status_t psa_crypto_input_copy_alloc(const uint8_t *input, size_t input_len, + psa_crypto_input_copy_t *input_copy) +{ + psa_status_t status; + + input_copy->buffer = NULL; + input_copy->len = 0; + + /* Treat NULL and zero-length input the same. + * This is simpler than potentially calling calloc(0). */ + if (input == NULL || input_len == 0) { + return PSA_SUCCESS; + } + + input_copy->buffer = mbedtls_calloc(input_len, 1); + if (input_copy->buffer == NULL) { + /* Since we dealt with the zero-length case above, we know that + * a NULL return value means a failure of allocation. */ + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + /* From now on, we must free input_copy->buffer on error. */ + + input_copy->len = input_len; + + status = psa_crypto_copy_input(input, input_len, + input_copy->buffer, input_copy->len); + if (status != PSA_SUCCESS) { + goto error; + } + + return PSA_SUCCESS; + +error: + mbedtls_free(input_copy->buffer); + input_copy->buffer = NULL; + input_copy->len = 0; + return status; +} + #endif /* MBEDTLS_PSA_CRYPTO_C */ From 47001448171368d9fce2be31716423ffebd27a36 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 7 Nov 2023 17:30:25 +0000 Subject: [PATCH 32/58] Add testcase for psa_crypto_input_copy_free() Signed-off-by: David Horstmann --- .../suites/test_suite_psa_crypto_memory.data | 6 ++++++ .../test_suite_psa_crypto_memory.function | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_memory.data b/tests/suites/test_suite_psa_crypto_memory.data index 85fed8f0e1..6591ba755c 100644 --- a/tests/suites/test_suite_psa_crypto_memory.data +++ b/tests/suites/test_suite_psa_crypto_memory.data @@ -33,3 +33,9 @@ input_copy_alloc:200:PSA_SUCCESS PSA crypto input copy alloc, NULL buffer input_copy_alloc:0:PSA_SUCCESS + +PSA crypto input copy free +input_copy_free:200 + +PSA crypto input copy free, NULL buffer +input_copy_free:0 diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 837ff06e9e..c40ba67f5c 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -109,3 +109,24 @@ exit: mbedtls_free(input); } /* END_CASE */ + +/* BEGIN_CASE */ +void input_copy_free(int input_len) +{ + psa_crypto_input_copy_t input_copy; + + input_copy.buffer = NULL; + input_copy.len = input_len; + TEST_CALLOC(input_copy.buffer, input_copy.len); + + psa_crypto_input_copy_free(&input_copy); + + TEST_ASSERT(input_copy.buffer == NULL); + TEST_EQUAL(input_copy.len, 0); + +exit: + mbedtls_free(input_copy.buffer); + input_copy.buffer = NULL; + input_copy.len = 0; +} +/* END_CASE */ From e6042ffc49e1f96fc6b4e3cdcc49731b7e382f83 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 7 Nov 2023 18:00:41 +0000 Subject: [PATCH 33/58] Add implementation of psa_crypto_input_copy_free() Signed-off-by: David Horstmann --- library/psa_crypto.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 2c37aebf79..d4138e0c41 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8503,4 +8503,11 @@ error: return status; } +void psa_crypto_input_copy_free(psa_crypto_input_copy_t *input_copy) +{ + mbedtls_free(input_copy->buffer); + input_copy->buffer = NULL; + input_copy->len = 0; +} + #endif /* MBEDTLS_PSA_CRYPTO_C */ From dfa14cbbcd00dab45c87f71e86f90864bf252835 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 14:33:05 +0000 Subject: [PATCH 34/58] Add function prototypes for psa_crypto_output fns Signed-off-by: David Horstmann --- library/psa_crypto_core.h | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index a53824ec3e..f3f7dfba01 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -911,4 +911,43 @@ psa_status_t psa_crypto_input_copy_alloc(const uint8_t *input, size_t input_len, */ void psa_crypto_input_copy_free(psa_crypto_input_copy_t *input_copy); +typedef struct psa_crypto_output_copy_s { + uint8_t *original; + uint8_t *buffer; + size_t len; +} psa_crypto_output_copy_t; + +/** Allocate a local copy of an output buffer. + * + * \note This does not copy any data from the original + * output buffer but only allocates a buffer + * whose contents will be copied back to the + * original in a future call to + * psa_crypto_output_copy_free(). + * + * \param[in] output Pointer to output buffer. + * \param[in] output_len Length of the output buffer. + * \param[out] output_copy Pointer to a psa_crypto_output_copy_t struct to + * populate with the output copy. + * \return #PSA_SUCCESS, if the buffer was successfully + * copied. + * \return #PSA_ERROR_INSUFFICIENT_MEMORY, if a copy of + * the buffer cannot be allocated. + */ +psa_status_t psa_crypto_output_copy_alloc(uint8_t *output, size_t output_len, + psa_crypto_output_copy_t *output_copy); + +/** Copy from a local copy of an output buffer back to the original, then + * free the local copy. + * + * \param[in] output_copy Pointer to a psa_crypto_output_copy_t struct + * populated by a previous call to + * psa_crypto_output_copy_alloc(). + * \return #PSA_SUCCESS, if the output copy was + * successfully copied back to the original. + * \return #PSA_ERROR_CORRUPTION_DETECTED, if the output + * could not be copied back to the original. + */ +psa_status_t psa_crypto_output_copy_free(psa_crypto_output_copy_t *output_copy); + #endif /* PSA_CRYPTO_CORE_H */ From 70b82256b51ae0d3d088a3fa48c2051eb057bc6b Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 15:10:41 +0000 Subject: [PATCH 35/58] Add testcase for psa_crypto_output_copy_alloc() Signed-off-by: David Horstmann --- .../suites/test_suite_psa_crypto_memory.data | 6 ++++ .../test_suite_psa_crypto_memory.function | 33 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_memory.data b/tests/suites/test_suite_psa_crypto_memory.data index 6591ba755c..fcd60fb803 100644 --- a/tests/suites/test_suite_psa_crypto_memory.data +++ b/tests/suites/test_suite_psa_crypto_memory.data @@ -39,3 +39,9 @@ input_copy_free:200 PSA crypto input copy free, NULL buffer input_copy_free:0 + +PSA crypto output copy alloc +output_copy_alloc:200:PSA_SUCCESS + +PSA crypto output copy alloc, NULL buffer +output_copy_alloc:0:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index c40ba67f5c..6fd58cd0af 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -130,3 +130,36 @@ exit: input_copy.len = 0; } /* END_CASE */ + +/* BEGIN_CASE */ +void output_copy_alloc(int output_len, psa_status_t exp_status) +{ + uint8_t *output = NULL; + psa_crypto_output_copy_t output_copy; + psa_status_t status; + + output_copy.buffer = NULL; + + TEST_CALLOC(output, output_len); + + status = psa_crypto_output_copy_alloc(output, output_len, &output_copy); + TEST_EQUAL(status, exp_status); + + if (exp_status == PSA_SUCCESS) { + TEST_ASSERT(output_copy.original == output); + if (output == NULL) { + TEST_ASSERT(output_copy.buffer == NULL); + } else { + TEST_EQUAL(output_copy.len, output_len); + } + } + +exit: + mbedtls_free(output_copy.buffer); + output_copy.original = NULL; + output_copy.buffer = NULL; + output_copy.len = 0; + mbedtls_free(output); + output = NULL; +} +/* END_CASE */ From ba3c7d649c0d916d7af8f1b32c3bf17b5e5db2f7 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 15:19:43 +0000 Subject: [PATCH 36/58] Add implementation of psa_crypto_output_alloc() Signed-off-by: David Horstmann --- library/psa_crypto.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index d4138e0c41..c733b28ff8 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8510,4 +8510,28 @@ void psa_crypto_input_copy_free(psa_crypto_input_copy_t *input_copy) input_copy->len = 0; } +psa_status_t psa_crypto_output_copy_alloc(uint8_t *output, size_t output_len, + psa_crypto_output_copy_t *output_copy) +{ + output_copy->original = NULL; + output_copy->buffer = NULL; + output_copy->len = 0; + + /* Treat NULL and zero-length input the same. + * This is simpler than potentially calling calloc(0). */ + if (output == NULL || output_len == 0) { + return PSA_SUCCESS; + } + output_copy->buffer = mbedtls_calloc(output_len, 1); + if (output_copy->buffer == NULL) { + /* Since we dealt with the zero-length case above, we know that + * a NULL return value means a failure of allocation. */ + return PSA_ERROR_INSUFFICIENT_MEMORY; + } + output_copy->len = output_len; + output_copy->original = output; + + return PSA_SUCCESS; +} + #endif /* MBEDTLS_PSA_CRYPTO_C */ From 63a73588cf03624a8099b960a88d45f85ef6a63f Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 17:25:45 +0000 Subject: [PATCH 37/58] Add testcase for psa_crypto_output_copy_free() Signed-off-by: David Horstmann --- .../suites/test_suite_psa_crypto_memory.data | 9 ++++ .../test_suite_psa_crypto_memory.function | 45 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_memory.data b/tests/suites/test_suite_psa_crypto_memory.data index fcd60fb803..2ca7e15abf 100644 --- a/tests/suites/test_suite_psa_crypto_memory.data +++ b/tests/suites/test_suite_psa_crypto_memory.data @@ -45,3 +45,12 @@ output_copy_alloc:200:PSA_SUCCESS PSA crypto output copy alloc, NULL buffer output_copy_alloc:0:PSA_SUCCESS + +PSA crypto output copy free +output_copy_free:200:0:PSA_SUCCESS + +PSA crypto output copy free, NULL buffer +output_copy_free:0:0:PSA_SUCCESS + +PSA crypto output copy free, NULL original buffer +output_copy_free:200:1:PSA_ERROR_CORRUPTION_DETECTED diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 6fd58cd0af..57a10ae791 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -163,3 +163,48 @@ exit: output = NULL; } /* END_CASE */ + +/* BEGIN_CASE */ +void output_copy_free(int output_len, int original_is_null, + psa_status_t exp_status) +{ + uint8_t *output = NULL; + uint8_t *buffer_copy_for_comparison = NULL; + psa_crypto_output_copy_t output_copy; + psa_status_t status; + + output_copy.buffer = NULL; + output_copy.len = 0; + + if (!original_is_null) { + TEST_CALLOC(output, output_len); + } + TEST_CALLOC(buffer_copy_for_comparison, output_len); + TEST_CALLOC(output_copy.buffer, output_len); + output_copy.len = output_len; + output_copy.original = output; + + if (output_copy.buffer != NULL) { + fill_buffer_pattern(output_copy.buffer, output_copy.len); + memcpy(buffer_copy_for_comparison, output_copy.buffer, output_copy.len); + } + + status = psa_crypto_output_copy_free(&output_copy); + TEST_EQUAL(status, exp_status); + + if (exp_status == PSA_SUCCESS) { + TEST_ASSERT(output_copy.buffer == NULL); + TEST_EQUAL(output_copy.len, 0); + if (output != NULL) { + TEST_MEMORY_COMPARE(buffer_copy_for_comparison, output_len, + output, output_len); + } + } + +exit: + mbedtls_free(output); + mbedtls_free(buffer_copy_for_comparison); + mbedtls_free(output_copy.buffer); + output_copy.len = 0; +} +/* END_CASE */ From 9467ea343b182e38449f787c24852a805e5c67d6 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 17:44:18 +0000 Subject: [PATCH 38/58] Add psa_crypto_output_copy_free() implementation Signed-off-by: David Horstmann --- library/psa_crypto.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index c733b28ff8..0e2fb3f946 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8534,4 +8534,24 @@ psa_status_t psa_crypto_output_copy_alloc(uint8_t *output, size_t output_len, return PSA_SUCCESS; } +psa_status_t psa_crypto_output_copy_free(psa_crypto_output_copy_t *output_copy) +{ + if (output_copy->buffer == NULL) { + output_copy->len = 0; + return PSA_SUCCESS; + } + if (output_copy->original == NULL) { + /* We have an internal copy but nothing to copy back to. */ + return PSA_ERROR_CORRUPTION_DETECTED; + } + + memcpy(output_copy->original, output_copy->buffer, output_copy->len); + + mbedtls_free(output_copy->buffer); + output_copy->buffer = NULL; + output_copy->len = 0; + + return PSA_SUCCESS; +} + #endif /* MBEDTLS_PSA_CRYPTO_C */ From 35dd103688acdb4e01da7c2dff8c3dde319add51 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 18:01:40 +0000 Subject: [PATCH 39/58] Add input round-trip testcase Signed-off-by: David Horstmann --- .../suites/test_suite_psa_crypto_memory.data | 3 +++ .../test_suite_psa_crypto_memory.function | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_memory.data b/tests/suites/test_suite_psa_crypto_memory.data index 2ca7e15abf..3d14ba35dc 100644 --- a/tests/suites/test_suite_psa_crypto_memory.data +++ b/tests/suites/test_suite_psa_crypto_memory.data @@ -40,6 +40,9 @@ input_copy_free:200 PSA crypto input copy free, NULL buffer input_copy_free:0 +PSA crypto input copy round-trip +input_copy_round_trip + PSA crypto output copy alloc output_copy_alloc:200:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 57a10ae791..3c7b8425eb 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -131,6 +131,27 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void input_copy_round_trip() +{ + psa_crypto_input_copy_t input_copy; + uint8_t input[200]; + psa_status_t status; + + fill_buffer_pattern(input, sizeof(input)); + + status = psa_crypto_input_copy_alloc(input, sizeof(input), &input_copy); + TEST_EQUAL(status, PSA_SUCCESS); + TEST_MEMORY_COMPARE(input_copy.buffer, input_copy.len, + input, sizeof(input)); + TEST_ASSERT(input_copy.buffer != input); + + psa_crypto_input_copy_free(&input_copy); + TEST_ASSERT(input_copy.buffer == NULL); + TEST_EQUAL(input_copy.len, 0); +} +/* END_CASE */ + /* BEGIN_CASE */ void output_copy_alloc(int output_len, psa_status_t exp_status) { From 0a57ed25c4344653544ce92a32fa1315b8b03e6a Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 18:11:29 +0000 Subject: [PATCH 40/58] Add output round-trip testcase Signed-off-by: David Horstmann --- .../suites/test_suite_psa_crypto_memory.data | 3 ++ .../test_suite_psa_crypto_memory.function | 31 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_memory.data b/tests/suites/test_suite_psa_crypto_memory.data index 3d14ba35dc..357d3423d3 100644 --- a/tests/suites/test_suite_psa_crypto_memory.data +++ b/tests/suites/test_suite_psa_crypto_memory.data @@ -57,3 +57,6 @@ output_copy_free:0:0:PSA_SUCCESS PSA crypto output copy free, NULL original buffer output_copy_free:200:1:PSA_ERROR_CORRUPTION_DETECTED + +PSA crypto output copy round-trip +output_copy_round_trip diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 3c7b8425eb..df08bf45f3 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -229,3 +229,34 @@ exit: output_copy.len = 0; } /* END_CASE */ + +/* BEGIN_CASE */ +void output_copy_round_trip() +{ + psa_crypto_output_copy_t output_copy; + uint8_t output[200]; + uint8_t *buffer_copy_for_comparison = NULL; + psa_status_t status; + + status = psa_crypto_output_copy_alloc(output, sizeof(output), &output_copy); + TEST_EQUAL(status, PSA_SUCCESS); + TEST_ASSERT(output_copy.buffer != output); + + /* Simulate the function generating output */ + fill_buffer_pattern(output_copy.buffer, output_copy.len); + + TEST_CALLOC(buffer_copy_for_comparison, output_copy.len); + memcpy(buffer_copy_for_comparison, output_copy.buffer, output_copy.len); + + psa_crypto_output_copy_free(&output_copy); + TEST_ASSERT(output_copy.buffer == NULL); + TEST_EQUAL(output_copy.len, 0); + + /* Check that the buffer was correctly copied back */ + TEST_MEMORY_COMPARE(output, sizeof(output), + buffer_copy_for_comparison, sizeof(output)); + +exit: + mbedtls_free(buffer_copy_for_comparison); +} +/* END_CASE */ From c335a4e1865d31f9183870ccde0d3d2f1f256cdb Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 15 Nov 2023 15:57:32 +0000 Subject: [PATCH 41/58] Fix unintentional direct use of memcpy() Change psa_crypto_output_copy_free() to use psa_crypto_copy_output() rather than calling memcpy directly as was erroneously done previously. Signed-off-by: David Horstmann --- library/psa_crypto.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 0e2fb3f946..6787b03e2f 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8536,6 +8536,8 @@ psa_status_t psa_crypto_output_copy_alloc(uint8_t *output, size_t output_len, psa_status_t psa_crypto_output_copy_free(psa_crypto_output_copy_t *output_copy) { + psa_status_t status; + if (output_copy->buffer == NULL) { output_copy->len = 0; return PSA_SUCCESS; @@ -8545,7 +8547,11 @@ psa_status_t psa_crypto_output_copy_free(psa_crypto_output_copy_t *output_copy) return PSA_ERROR_CORRUPTION_DETECTED; } - memcpy(output_copy->original, output_copy->buffer, output_copy->len); + status = psa_crypto_copy_output(output_copy->buffer, output_copy->len, + output_copy->original, output_copy->len); + if (status != PSA_SUCCESS) { + return status; + } mbedtls_free(output_copy->buffer); output_copy->buffer = NULL; From 1b7279a849783babc2fac2c726ed014db7fbc76a Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 15 Nov 2023 15:18:30 +0000 Subject: [PATCH 42/58] Make copy functions static-testable This allows greater compiler optimisation. Signed-off-by: David Horstmann --- library/psa_crypto.c | 26 ++++++++++++++++ library/psa_crypto_core.h | 30 ------------------- library/psa_crypto_invasive.h | 7 +++++ .../test_suite_psa_crypto_memory.function | 3 +- 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 6787b03e2f..e03e2ae122 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8442,6 +8442,19 @@ psa_status_t psa_pake_abort( #endif /* PSA_WANT_ALG_SOME_PAKE */ +/** Copy from an input buffer to a local copy. + * + * \param[in] input Pointer to input buffer. + * \param[in] input_len Length of the input buffer. + * \param[out] input_copy Pointer to a local copy in which to store the input data. + * \param[out] input_copy_len Length of the local copy buffer. + * \return #PSA_SUCCESS, if the buffer was successfully + * copied. + * \return #PSA_ERROR_CORRUPTION_DETECTED, if the local + * copy is too small to hold contents of the + * input buffer. + */ +MBEDTLS_STATIC_TESTABLE psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, uint8_t *input_copy, size_t input_copy_len) { @@ -8454,6 +8467,19 @@ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, return PSA_SUCCESS; } +/** Copy from a local output buffer into a user-supplied one. + * + * \param[in] output_copy Pointer to a local buffer containing the output. + * \param[in] output_copy_len Length of the local buffer. + * \param[out] output Pointer to user-supplied output buffer. + * \param[out] output_len Length of the user-supplied output buffer. + * \return #PSA_SUCCESS, if the buffer was successfully + * copied. + * \return #PSA_ERROR_CORRUPTION_DETECTED, if the + * user-supplied output buffer is too small to + * hold the contents of the local buffer. + */ +MBEDTLS_STATIC_TESTABLE psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len, uint8_t *output, size_t output_len) { diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index f3f7dfba01..125f7ec4c9 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -854,36 +854,6 @@ psa_status_t mbedtls_psa_verify_hash_complete( psa_status_t mbedtls_psa_verify_hash_abort( mbedtls_psa_verify_hash_interruptible_operation_t *operation); -/** Copy from an input buffer to a local copy. - * - * \param[in] input Pointer to input buffer. - * \param[in] input_len Length of the input buffer. - * \param[out] input_copy Pointer to a local copy in which to store the input data. - * \param[out] input_copy_len Length of the local copy buffer. - * \return #PSA_SUCCESS, if the buffer was successfully - * copied. - * \return #PSA_ERROR_CORRUPTION_DETECTED, if the local - * copy is too small to hold contents of the - * input buffer. - */ -psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, - uint8_t *input_copy, size_t input_copy_len); - -/** Copy from a local output buffer into a user-supplied one. - * - * \param[in] output_copy Pointer to a local buffer containing the output. - * \param[in] output_copy_len Length of the local buffer. - * \param[out] output Pointer to user-supplied output buffer. - * \param[out] output_len Length of the user-supplied output buffer. - * \return #PSA_SUCCESS, if the buffer was successfully - * copied. - * \return #PSA_ERROR_CORRUPTION_DETECTED, if the - * user-supplied output buffer is too small to - * hold the contents of the local buffer. - */ -psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len, - uint8_t *output, size_t output_len); - typedef struct psa_crypto_input_copy_s { uint8_t *buffer; size_t len; diff --git a/library/psa_crypto_invasive.h b/library/psa_crypto_invasive.h index 408c39bfec..29d4e3dd13 100644 --- a/library/psa_crypto_invasive.h +++ b/library/psa_crypto_invasive.h @@ -84,6 +84,13 @@ psa_status_t mbedtls_psa_crypto_configure_entropy_sources( psa_status_t psa_mac_key_can_do( psa_algorithm_t algorithm, psa_key_type_t key_type); + +psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, + uint8_t *input_copy, size_t input_copy_len); + +psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_copy_len, + uint8_t *output, size_t output_len); + #endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_PSA_CRYPTO_C */ #endif /* PSA_CRYPTO_INVASIVE_H */ diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index df08bf45f3..29cb3eca13 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -6,6 +6,7 @@ #include "psa/crypto.h" #include "psa_crypto_core.h" +#include "psa_crypto_invasive.h" #include "test/psa_crypto_helpers.h" @@ -23,7 +24,7 @@ static void fill_buffer_pattern(uint8_t *buffer, size_t len) /* END_HEADER */ /* BEGIN_DEPENDENCIES - * depends_on:MBEDTLS_PSA_CRYPTO_C + * depends_on:MBEDTLS_PSA_CRYPTO_C:MBEDTLS_TEST_HOOKS * END_DEPENDENCIES */ From 777e74130f409ab69e47d7110c1b81ae0e5d0520 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 15 Nov 2023 17:33:47 +0000 Subject: [PATCH 43/58] Skip call to memcpy if buffer length is zero This allows the copy functions to work when passed a (NULL, 0) buffer. Signed-off-by: David Horstmann --- library/psa_crypto.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index e03e2ae122..43495e247e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8462,7 +8462,9 @@ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, return PSA_ERROR_CORRUPTION_DETECTED; } - memcpy(input_copy, input, input_len); + if (input_len > 0) { + memcpy(input_copy, input, input_len); + } return PSA_SUCCESS; } @@ -8486,7 +8488,11 @@ psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_co if (output_len < output_copy_len) { return PSA_ERROR_CORRUPTION_DETECTED; } - memcpy(output, output_copy, output_copy_len); + + if (output_copy_len > 0) { + memcpy(output, output_copy, output_copy_len); + } + return PSA_SUCCESS; } From c5cc1c3a92b1a80bb93e484a9c954066afd3a123 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 15 Nov 2023 18:11:26 +0000 Subject: [PATCH 44/58] Remove redundant NULL check A NULL buffer with a non-zero length is an internal error, so just check the length. Signed-off-by: David Horstmann --- library/psa_crypto.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 43495e247e..167ce2d173 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8504,9 +8504,7 @@ psa_status_t psa_crypto_input_copy_alloc(const uint8_t *input, size_t input_len, input_copy->buffer = NULL; input_copy->len = 0; - /* Treat NULL and zero-length input the same. - * This is simpler than potentially calling calloc(0). */ - if (input == NULL || input_len == 0) { + if (input_len == 0) { return PSA_SUCCESS; } @@ -8549,9 +8547,7 @@ psa_status_t psa_crypto_output_copy_alloc(uint8_t *output, size_t output_len, output_copy->buffer = NULL; output_copy->len = 0; - /* Treat NULL and zero-length input the same. - * This is simpler than potentially calling calloc(0). */ - if (output == NULL || output_len == 0) { + if (output_len == 0) { return PSA_SUCCESS; } output_copy->buffer = mbedtls_calloc(output_len, 1); From b4e3f36918e8022b7f6cb2100c3bd7e316daad5f Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 16 Nov 2023 19:57:25 +0000 Subject: [PATCH 45/58] Change data pattern to simpler one Just use the index modulo 256, as this has a greater stride and is simpler to use. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto_memory.function | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 29cb3eca13..81c52a3f7a 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -15,10 +15,8 @@ * 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)]; + buffer[i] = (uint8_t) (i % 256); } } /* END_HEADER */ From 23f1122838c001beb980a64d68d173e8e2d8686c Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 16 Nov 2023 20:01:32 +0000 Subject: [PATCH 46/58] Use TEST_CALLOC_NONNULL Check that input/output copying works for zero-length NULL input buffers. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto_memory.function | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 81c52a3f7a..e92cbb157f 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -33,8 +33,8 @@ void copy_input(int src_len, int dst_len, psa_status_t exp_status) uint8_t *dst_buffer = NULL; psa_status_t status; - TEST_CALLOC_NONNULL(src_buffer, src_len); - TEST_CALLOC_NONNULL(dst_buffer, dst_len); + TEST_CALLOC(src_buffer, src_len); + TEST_CALLOC(dst_buffer, dst_len); fill_buffer_pattern(src_buffer, src_len); @@ -59,8 +59,8 @@ void copy_output(int src_len, int dst_len, psa_status_t exp_status) uint8_t *dst_buffer = NULL; psa_status_t status; - TEST_CALLOC_NONNULL(src_buffer, src_len); - TEST_CALLOC_NONNULL(dst_buffer, dst_len); + TEST_CALLOC(src_buffer, src_len); + TEST_CALLOC(dst_buffer, dst_len); fill_buffer_pattern(src_buffer, src_len); From 0fca150b8146f69d624d5e94a057a21e50c20ed3 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 16 Nov 2023 20:12:17 +0000 Subject: [PATCH 47/58] Compare buffers even for zero-length cases This enables us to test that lengths are correctly zero when the buffer pointer is NULL. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto_memory.function | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index e92cbb157f..593825823c 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -98,9 +98,9 @@ void input_copy_alloc(int input_len, psa_status_t exp_status) TEST_ASSERT(input_copy.buffer == NULL); } else { TEST_ASSERT(input_copy.buffer != input); - TEST_MEMORY_COMPARE(input, input_len, - input_copy.buffer, input_copy.len); } + TEST_MEMORY_COMPARE(input, input_len, + input_copy.buffer, input_copy.len); } exit: @@ -169,9 +169,8 @@ void output_copy_alloc(int output_len, psa_status_t exp_status) TEST_ASSERT(output_copy.original == output); if (output == NULL) { TEST_ASSERT(output_copy.buffer == NULL); - } else { - TEST_EQUAL(output_copy.len, output_len); } + TEST_EQUAL(output_copy.len, output_len); } exit: @@ -215,10 +214,8 @@ void output_copy_free(int output_len, int original_is_null, if (exp_status == PSA_SUCCESS) { TEST_ASSERT(output_copy.buffer == NULL); TEST_EQUAL(output_copy.len, 0); - if (output != NULL) { - TEST_MEMORY_COMPARE(buffer_copy_for_comparison, output_len, - output, output_len); - } + TEST_MEMORY_COMPARE(buffer_copy_for_comparison, output_len, + output, output_len); } exit: From bab3e76da5888268ace5a18417d3f5480f0c77bc Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 16 Nov 2023 20:21:19 +0000 Subject: [PATCH 48/58] Fix code style in psa_crypto_core.h Signed-off-by: David Horstmann --- library/psa_crypto_core.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 125f7ec4c9..5cdd9141ff 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -882,9 +882,9 @@ psa_status_t psa_crypto_input_copy_alloc(const uint8_t *input, size_t input_len, void psa_crypto_input_copy_free(psa_crypto_input_copy_t *input_copy); typedef struct psa_crypto_output_copy_s { - uint8_t *original; - uint8_t *buffer; - size_t len; + uint8_t *original; + uint8_t *buffer; + size_t len; } psa_crypto_output_copy_t; /** Allocate a local copy of an output buffer. From 58909704e33679517075c947e6b097ec51ba3cca Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 16 Nov 2023 20:26:16 +0000 Subject: [PATCH 49/58] Check for len == 0 rather than buffer == NULL This makes the intention clearer Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto_memory.function | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 593825823c..83fa6cbd86 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -94,7 +94,7 @@ void input_copy_alloc(int input_len, psa_status_t exp_status) TEST_EQUAL(status, exp_status); if (exp_status == PSA_SUCCESS) { - if (input == NULL) { + if (input_len == 0) { TEST_ASSERT(input_copy.buffer == NULL); } else { TEST_ASSERT(input_copy.buffer != input); @@ -167,7 +167,7 @@ void output_copy_alloc(int output_len, psa_status_t exp_status) if (exp_status == PSA_SUCCESS) { TEST_ASSERT(output_copy.original == output); - if (output == NULL) { + if (output_len == 0) { TEST_ASSERT(output_copy.buffer == NULL); } TEST_EQUAL(output_copy.len, output_len); @@ -203,7 +203,7 @@ void output_copy_free(int output_len, int original_is_null, output_copy.len = output_len; output_copy.original = output; - if (output_copy.buffer != NULL) { + if (output_copy.len != 0) { fill_buffer_pattern(output_copy.buffer, output_copy.len); memcpy(buffer_copy_for_comparison, output_copy.buffer, output_copy.len); } From 365df3f16c2d91fcdeb0680fc168284aa39b4b06 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 16 Nov 2023 20:30:36 +0000 Subject: [PATCH 50/58] Remove unnecessary checks for NULL-ness of copies Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto_memory.function | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 83fa6cbd86..7b6b7f189c 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -94,9 +94,7 @@ void input_copy_alloc(int input_len, psa_status_t exp_status) TEST_EQUAL(status, exp_status); if (exp_status == PSA_SUCCESS) { - if (input_len == 0) { - TEST_ASSERT(input_copy.buffer == NULL); - } else { + if (input_len != 0) { TEST_ASSERT(input_copy.buffer != input); } TEST_MEMORY_COMPARE(input, input_len, @@ -167,9 +165,6 @@ void output_copy_alloc(int output_len, psa_status_t exp_status) if (exp_status == PSA_SUCCESS) { TEST_ASSERT(output_copy.original == output); - if (output_len == 0) { - TEST_ASSERT(output_copy.buffer == NULL); - } TEST_EQUAL(output_copy.len, output_len); } From 9abf5350784cb72713667fda4835c01c284b833e Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 20 Nov 2023 12:16:08 +0000 Subject: [PATCH 51/58] Add initializers for input / output copies Signed-off-by: David Horstmann --- library/psa_crypto_core.h | 4 ++++ tests/suites/test_suite_psa_crypto_memory.function | 5 +---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 5cdd9141ff..940748edd9 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -859,6 +859,8 @@ typedef struct psa_crypto_input_copy_s { size_t len; } psa_crypto_input_copy_t; +#define PSA_CRYPTO_INPUT_COPY_INIT { NULL, 0 } + /** Allocate a local copy of an input buffer. * * \param[in] input Pointer to input buffer. @@ -887,6 +889,8 @@ typedef struct psa_crypto_output_copy_s { size_t len; } psa_crypto_output_copy_t; +#define PSA_CRYPTO_OUTPUT_COPY_INIT { NULL, NULL, 0 } + /** Allocate a local copy of an output buffer. * * \note This does not copy any data from the original diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 7b6b7f189c..e9e529989e 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -184,12 +184,9 @@ void output_copy_free(int output_len, int original_is_null, { uint8_t *output = NULL; uint8_t *buffer_copy_for_comparison = NULL; - psa_crypto_output_copy_t output_copy; + psa_crypto_output_copy_t output_copy = PSA_CRYPTO_OUTPUT_COPY_INIT; psa_status_t status; - output_copy.buffer = NULL; - output_copy.len = 0; - if (!original_is_null) { TEST_CALLOC(output, output_len); } From 671f5f539ea30b6506c0b74c9c156344b24ccc38 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 20 Nov 2023 12:39:38 +0000 Subject: [PATCH 52/58] Change psa_crypto_copy_output error code When we are copying output, it makes sense to return PSA_ERROR_BUFFER_TOO_SMALL since the buffer we are copying to is a user output buffer. Signed-off-by: David Horstmann --- library/psa_crypto.c | 4 ++-- tests/suites/test_suite_psa_crypto_memory.data | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 167ce2d173..3327c30c43 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8477,7 +8477,7 @@ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, * \param[out] output_len Length of the user-supplied output buffer. * \return #PSA_SUCCESS, if the buffer was successfully * copied. - * \return #PSA_ERROR_CORRUPTION_DETECTED, if the + * \return #PSA_ERROR_BUFFER_TOO_SMALL, if the * user-supplied output buffer is too small to * hold the contents of the local buffer. */ @@ -8486,7 +8486,7 @@ psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_co uint8_t *output, size_t output_len) { if (output_len < output_copy_len) { - return PSA_ERROR_CORRUPTION_DETECTED; + return PSA_ERROR_BUFFER_TOO_SMALL; } if (output_copy_len > 0) { diff --git a/tests/suites/test_suite_psa_crypto_memory.data b/tests/suites/test_suite_psa_crypto_memory.data index 357d3423d3..94fb407f9b 100644 --- a/tests/suites/test_suite_psa_crypto_memory.data +++ b/tests/suites/test_suite_psa_crypto_memory.data @@ -20,7 +20,7 @@ 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 +copy_output:20:10:PSA_ERROR_BUFFER_TOO_SMALL PSA output buffer copy: zero-length source buffer copy_output:0:10:PSA_SUCCESS From 2f307b4216105a603ab9c19b3598e9b8818d85f6 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 20 Nov 2023 12:54:09 +0000 Subject: [PATCH 53/58] De-abbreviate "len" -> "length" Signed-off-by: David Horstmann --- library/psa_crypto.c | 22 +++++------ library/psa_crypto_core.h | 4 +- .../test_suite_psa_crypto_memory.function | 38 +++++++++---------- 3 files changed, 32 insertions(+), 32 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 3327c30c43..bad55b1c65 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8502,7 +8502,7 @@ psa_status_t psa_crypto_input_copy_alloc(const uint8_t *input, size_t input_len, psa_status_t status; input_copy->buffer = NULL; - input_copy->len = 0; + input_copy->length = 0; if (input_len == 0) { return PSA_SUCCESS; @@ -8516,10 +8516,10 @@ psa_status_t psa_crypto_input_copy_alloc(const uint8_t *input, size_t input_len, } /* From now on, we must free input_copy->buffer on error. */ - input_copy->len = input_len; + input_copy->length = input_len; status = psa_crypto_copy_input(input, input_len, - input_copy->buffer, input_copy->len); + input_copy->buffer, input_copy->length); if (status != PSA_SUCCESS) { goto error; } @@ -8529,7 +8529,7 @@ psa_status_t psa_crypto_input_copy_alloc(const uint8_t *input, size_t input_len, error: mbedtls_free(input_copy->buffer); input_copy->buffer = NULL; - input_copy->len = 0; + input_copy->length = 0; return status; } @@ -8537,7 +8537,7 @@ void psa_crypto_input_copy_free(psa_crypto_input_copy_t *input_copy) { mbedtls_free(input_copy->buffer); input_copy->buffer = NULL; - input_copy->len = 0; + input_copy->length = 0; } psa_status_t psa_crypto_output_copy_alloc(uint8_t *output, size_t output_len, @@ -8545,7 +8545,7 @@ psa_status_t psa_crypto_output_copy_alloc(uint8_t *output, size_t output_len, { output_copy->original = NULL; output_copy->buffer = NULL; - output_copy->len = 0; + output_copy->length = 0; if (output_len == 0) { return PSA_SUCCESS; @@ -8556,7 +8556,7 @@ psa_status_t psa_crypto_output_copy_alloc(uint8_t *output, size_t output_len, * a NULL return value means a failure of allocation. */ return PSA_ERROR_INSUFFICIENT_MEMORY; } - output_copy->len = output_len; + output_copy->length = output_len; output_copy->original = output; return PSA_SUCCESS; @@ -8567,7 +8567,7 @@ psa_status_t psa_crypto_output_copy_free(psa_crypto_output_copy_t *output_copy) psa_status_t status; if (output_copy->buffer == NULL) { - output_copy->len = 0; + output_copy->length = 0; return PSA_SUCCESS; } if (output_copy->original == NULL) { @@ -8575,15 +8575,15 @@ psa_status_t psa_crypto_output_copy_free(psa_crypto_output_copy_t *output_copy) return PSA_ERROR_CORRUPTION_DETECTED; } - status = psa_crypto_copy_output(output_copy->buffer, output_copy->len, - output_copy->original, output_copy->len); + status = psa_crypto_copy_output(output_copy->buffer, output_copy->length, + output_copy->original, output_copy->length); if (status != PSA_SUCCESS) { return status; } mbedtls_free(output_copy->buffer); output_copy->buffer = NULL; - output_copy->len = 0; + output_copy->length = 0; return PSA_SUCCESS; } diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 940748edd9..21d4bf3786 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -856,7 +856,7 @@ psa_status_t mbedtls_psa_verify_hash_abort( typedef struct psa_crypto_input_copy_s { uint8_t *buffer; - size_t len; + size_t length; } psa_crypto_input_copy_t; #define PSA_CRYPTO_INPUT_COPY_INIT { NULL, 0 } @@ -886,7 +886,7 @@ void psa_crypto_input_copy_free(psa_crypto_input_copy_t *input_copy); typedef struct psa_crypto_output_copy_s { uint8_t *original; uint8_t *buffer; - size_t len; + size_t length; } psa_crypto_output_copy_t; #define PSA_CRYPTO_OUTPUT_COPY_INIT { NULL, NULL, 0 } diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index e9e529989e..8421604e9d 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -98,7 +98,7 @@ void input_copy_alloc(int input_len, psa_status_t exp_status) TEST_ASSERT(input_copy.buffer != input); } TEST_MEMORY_COMPARE(input, input_len, - input_copy.buffer, input_copy.len); + input_copy.buffer, input_copy.length); } exit: @@ -113,18 +113,18 @@ void input_copy_free(int input_len) psa_crypto_input_copy_t input_copy; input_copy.buffer = NULL; - input_copy.len = input_len; - TEST_CALLOC(input_copy.buffer, input_copy.len); + input_copy.length = input_len; + TEST_CALLOC(input_copy.buffer, input_copy.length); psa_crypto_input_copy_free(&input_copy); TEST_ASSERT(input_copy.buffer == NULL); - TEST_EQUAL(input_copy.len, 0); + TEST_EQUAL(input_copy.length, 0); exit: mbedtls_free(input_copy.buffer); input_copy.buffer = NULL; - input_copy.len = 0; + input_copy.length = 0; } /* END_CASE */ @@ -139,13 +139,13 @@ void input_copy_round_trip() status = psa_crypto_input_copy_alloc(input, sizeof(input), &input_copy); TEST_EQUAL(status, PSA_SUCCESS); - TEST_MEMORY_COMPARE(input_copy.buffer, input_copy.len, + TEST_MEMORY_COMPARE(input_copy.buffer, input_copy.length, input, sizeof(input)); TEST_ASSERT(input_copy.buffer != input); psa_crypto_input_copy_free(&input_copy); TEST_ASSERT(input_copy.buffer == NULL); - TEST_EQUAL(input_copy.len, 0); + TEST_EQUAL(input_copy.length, 0); } /* END_CASE */ @@ -165,14 +165,14 @@ void output_copy_alloc(int output_len, psa_status_t exp_status) if (exp_status == PSA_SUCCESS) { TEST_ASSERT(output_copy.original == output); - TEST_EQUAL(output_copy.len, output_len); + TEST_EQUAL(output_copy.length, output_len); } exit: mbedtls_free(output_copy.buffer); output_copy.original = NULL; output_copy.buffer = NULL; - output_copy.len = 0; + output_copy.length = 0; mbedtls_free(output); output = NULL; } @@ -192,12 +192,12 @@ void output_copy_free(int output_len, int original_is_null, } TEST_CALLOC(buffer_copy_for_comparison, output_len); TEST_CALLOC(output_copy.buffer, output_len); - output_copy.len = output_len; + output_copy.length = output_len; output_copy.original = output; - if (output_copy.len != 0) { - fill_buffer_pattern(output_copy.buffer, output_copy.len); - memcpy(buffer_copy_for_comparison, output_copy.buffer, output_copy.len); + if (output_copy.length != 0) { + fill_buffer_pattern(output_copy.buffer, output_copy.length); + memcpy(buffer_copy_for_comparison, output_copy.buffer, output_copy.length); } status = psa_crypto_output_copy_free(&output_copy); @@ -205,7 +205,7 @@ void output_copy_free(int output_len, int original_is_null, if (exp_status == PSA_SUCCESS) { TEST_ASSERT(output_copy.buffer == NULL); - TEST_EQUAL(output_copy.len, 0); + TEST_EQUAL(output_copy.length, 0); TEST_MEMORY_COMPARE(buffer_copy_for_comparison, output_len, output, output_len); } @@ -214,7 +214,7 @@ exit: mbedtls_free(output); mbedtls_free(buffer_copy_for_comparison); mbedtls_free(output_copy.buffer); - output_copy.len = 0; + output_copy.length = 0; } /* END_CASE */ @@ -231,14 +231,14 @@ void output_copy_round_trip() TEST_ASSERT(output_copy.buffer != output); /* Simulate the function generating output */ - fill_buffer_pattern(output_copy.buffer, output_copy.len); + fill_buffer_pattern(output_copy.buffer, output_copy.length); - TEST_CALLOC(buffer_copy_for_comparison, output_copy.len); - memcpy(buffer_copy_for_comparison, output_copy.buffer, output_copy.len); + TEST_CALLOC(buffer_copy_for_comparison, output_copy.length); + memcpy(buffer_copy_for_comparison, output_copy.buffer, output_copy.length); psa_crypto_output_copy_free(&output_copy); TEST_ASSERT(output_copy.buffer == NULL); - TEST_EQUAL(output_copy.len, 0); + TEST_EQUAL(output_copy.length, 0); /* Check that the buffer was correctly copied back */ TEST_MEMORY_COMPARE(output, sizeof(output), From f1734054fa3fbc40d16d57d867dbee7a3adbd23a Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 20 Nov 2023 17:15:32 +0000 Subject: [PATCH 54/58] Rename "input_copy" -> "local_input" This helps to prevent confusion as it avoids overloading the word "copy" as both an action and an object. Signed-off-by: David Horstmann --- library/psa_crypto.c | 32 ++++++------ library/psa_crypto_core.h | 20 +++---- .../suites/test_suite_psa_crypto_memory.data | 20 +++---- .../test_suite_psa_crypto_memory.function | 52 +++++++++---------- 4 files changed, 62 insertions(+), 62 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index bad55b1c65..b51b3b9398 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8496,30 +8496,30 @@ psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_co return PSA_SUCCESS; } -psa_status_t psa_crypto_input_copy_alloc(const uint8_t *input, size_t input_len, - psa_crypto_input_copy_t *input_copy) +psa_status_t psa_crypto_local_input_alloc(const uint8_t *input, size_t input_len, + psa_crypto_local_input_t *local_input) { psa_status_t status; - input_copy->buffer = NULL; - input_copy->length = 0; + local_input->buffer = NULL; + local_input->length = 0; if (input_len == 0) { return PSA_SUCCESS; } - input_copy->buffer = mbedtls_calloc(input_len, 1); - if (input_copy->buffer == NULL) { + local_input->buffer = mbedtls_calloc(input_len, 1); + if (local_input->buffer == NULL) { /* Since we dealt with the zero-length case above, we know that * a NULL return value means a failure of allocation. */ return PSA_ERROR_INSUFFICIENT_MEMORY; } - /* From now on, we must free input_copy->buffer on error. */ + /* From now on, we must free local_input->buffer on error. */ - input_copy->length = input_len; + local_input->length = input_len; status = psa_crypto_copy_input(input, input_len, - input_copy->buffer, input_copy->length); + local_input->buffer, local_input->length); if (status != PSA_SUCCESS) { goto error; } @@ -8527,17 +8527,17 @@ psa_status_t psa_crypto_input_copy_alloc(const uint8_t *input, size_t input_len, return PSA_SUCCESS; error: - mbedtls_free(input_copy->buffer); - input_copy->buffer = NULL; - input_copy->length = 0; + mbedtls_free(local_input->buffer); + local_input->buffer = NULL; + local_input->length = 0; return status; } -void psa_crypto_input_copy_free(psa_crypto_input_copy_t *input_copy) +void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input) { - mbedtls_free(input_copy->buffer); - input_copy->buffer = NULL; - input_copy->length = 0; + mbedtls_free(local_input->buffer); + local_input->buffer = NULL; + local_input->length = 0; } psa_status_t psa_crypto_output_copy_alloc(uint8_t *output, size_t output_len, diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 21d4bf3786..ea34aab747 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -854,34 +854,34 @@ psa_status_t mbedtls_psa_verify_hash_complete( psa_status_t mbedtls_psa_verify_hash_abort( mbedtls_psa_verify_hash_interruptible_operation_t *operation); -typedef struct psa_crypto_input_copy_s { +typedef struct psa_crypto_local_input_s { uint8_t *buffer; size_t length; -} psa_crypto_input_copy_t; +} psa_crypto_local_input_t; -#define PSA_CRYPTO_INPUT_COPY_INIT { NULL, 0 } +#define PSA_CRYPTO_LOCAL_INPUT_INIT { NULL, 0 } /** Allocate a local copy of an input buffer. * * \param[in] input Pointer to input buffer. * \param[in] input_len Length of the input buffer. - * \param[out] input_copy Pointer to a psa_crypto_input_copy_t struct to - * populate with the input copy. + * \param[out] local_input Pointer to a psa_crypto_local_input_t struct to + * populate with the local input copy. * \return #PSA_SUCCESS, if the buffer was successfully * copied. * \return #PSA_ERROR_INSUFFICIENT_MEMORY, if a copy of * the buffer cannot be allocated. */ -psa_status_t psa_crypto_input_copy_alloc(const uint8_t *input, size_t input_len, - psa_crypto_input_copy_t *input_copy); +psa_status_t psa_crypto_local_input_alloc(const uint8_t *input, size_t input_len, + psa_crypto_local_input_t *local_input); /** Free a local copy of an input buffer. * - * \param[in] input_copy Pointer to a psa_crypto_input_copy_t struct + * \param[in] local_input Pointer to a psa_crypto_local_input_t struct * populated by a previous call to - * psa_crypto_input_copy_alloc(). + * psa_crypto_local_input_alloc(). */ -void psa_crypto_input_copy_free(psa_crypto_input_copy_t *input_copy); +void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input); typedef struct psa_crypto_output_copy_s { uint8_t *original; diff --git a/tests/suites/test_suite_psa_crypto_memory.data b/tests/suites/test_suite_psa_crypto_memory.data index 94fb407f9b..d758bda0d4 100644 --- a/tests/suites/test_suite_psa_crypto_memory.data +++ b/tests/suites/test_suite_psa_crypto_memory.data @@ -28,20 +28,20 @@ copy_output:0:10:PSA_SUCCESS PSA output buffer copy: zero-length both buffers copy_output:0:0:PSA_SUCCESS -PSA crypto input copy alloc -input_copy_alloc:200:PSA_SUCCESS +PSA crypto local input alloc +local_input_alloc:200:PSA_SUCCESS -PSA crypto input copy alloc, NULL buffer -input_copy_alloc:0:PSA_SUCCESS +PSA crypto local input alloc, NULL buffer +local_input_alloc:0:PSA_SUCCESS -PSA crypto input copy free -input_copy_free:200 +PSA crypto local input free +local_input_free:200 -PSA crypto input copy free, NULL buffer -input_copy_free:0 +PSA crypto local input free, NULL buffer +local_input_free:0 -PSA crypto input copy round-trip -input_copy_round_trip +PSA crypto local input round-trip +local_input_round_trip PSA crypto output copy alloc output_copy_alloc:200:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 8421604e9d..3d606bbb66 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -79,73 +79,73 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -void input_copy_alloc(int input_len, psa_status_t exp_status) +void local_input_alloc(int input_len, psa_status_t exp_status) { uint8_t *input = NULL; - psa_crypto_input_copy_t input_copy; + psa_crypto_local_input_t local_input; psa_status_t status; - input_copy.buffer = NULL; + local_input.buffer = NULL; TEST_CALLOC(input, input_len); fill_buffer_pattern(input, input_len); - status = psa_crypto_input_copy_alloc(input, input_len, &input_copy); + status = psa_crypto_local_input_alloc(input, input_len, &local_input); TEST_EQUAL(status, exp_status); if (exp_status == PSA_SUCCESS) { if (input_len != 0) { - TEST_ASSERT(input_copy.buffer != input); + TEST_ASSERT(local_input.buffer != input); } TEST_MEMORY_COMPARE(input, input_len, - input_copy.buffer, input_copy.length); + local_input.buffer, local_input.length); } exit: - mbedtls_free(input_copy.buffer); + mbedtls_free(local_input.buffer); mbedtls_free(input); } /* END_CASE */ /* BEGIN_CASE */ -void input_copy_free(int input_len) +void local_input_free(int input_len) { - psa_crypto_input_copy_t input_copy; + psa_crypto_local_input_t local_input; - input_copy.buffer = NULL; - input_copy.length = input_len; - TEST_CALLOC(input_copy.buffer, input_copy.length); + local_input.buffer = NULL; + local_input.length = input_len; + TEST_CALLOC(local_input.buffer, local_input.length); - psa_crypto_input_copy_free(&input_copy); + psa_crypto_local_input_free(&local_input); - TEST_ASSERT(input_copy.buffer == NULL); - TEST_EQUAL(input_copy.length, 0); + TEST_ASSERT(local_input.buffer == NULL); + TEST_EQUAL(local_input.length, 0); exit: - mbedtls_free(input_copy.buffer); - input_copy.buffer = NULL; - input_copy.length = 0; + mbedtls_free(local_input.buffer); + local_input.buffer = NULL; + local_input.length = 0; } /* END_CASE */ /* BEGIN_CASE */ -void input_copy_round_trip() +void local_input_round_trip() { - psa_crypto_input_copy_t input_copy; + psa_crypto_local_input_t local_input; uint8_t input[200]; psa_status_t status; fill_buffer_pattern(input, sizeof(input)); - status = psa_crypto_input_copy_alloc(input, sizeof(input), &input_copy); + status = psa_crypto_local_input_alloc(input, sizeof(input), &local_input); TEST_EQUAL(status, PSA_SUCCESS); - TEST_MEMORY_COMPARE(input_copy.buffer, input_copy.length, + TEST_MEMORY_COMPARE(local_input.buffer, local_input.length, input, sizeof(input)); - TEST_ASSERT(input_copy.buffer != input); + TEST_ASSERT(local_input.buffer != input); - psa_crypto_input_copy_free(&input_copy); - TEST_ASSERT(input_copy.buffer == NULL); - TEST_EQUAL(input_copy.length, 0); + psa_crypto_local_input_free(&local_input); + TEST_ASSERT(local_input.buffer == NULL); + TEST_EQUAL(local_input.length, 0); } /* END_CASE */ From 89875a4f20faf17a61d17bd80c287f938b6b4a0e Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 20 Nov 2023 12:54:09 +0000 Subject: [PATCH 55/58] Rename "output_copy" -> "local_output" This helps to prevent confusion as it avoids overloading the word "copy" as both an action and an object. Signed-off-by: David Horstmann --- library/psa_crypto.c | 36 +++++----- library/psa_crypto_core.h | 24 +++---- .../suites/test_suite_psa_crypto_memory.data | 24 +++---- .../test_suite_psa_crypto_memory.function | 68 +++++++++---------- 4 files changed, 76 insertions(+), 76 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index b51b3b9398..781034d05f 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8540,50 +8540,50 @@ void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input) local_input->length = 0; } -psa_status_t psa_crypto_output_copy_alloc(uint8_t *output, size_t output_len, - psa_crypto_output_copy_t *output_copy) +psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len, + psa_crypto_local_output_t *local_output) { - output_copy->original = NULL; - output_copy->buffer = NULL; - output_copy->length = 0; + local_output->original = NULL; + local_output->buffer = NULL; + local_output->length = 0; if (output_len == 0) { return PSA_SUCCESS; } - output_copy->buffer = mbedtls_calloc(output_len, 1); - if (output_copy->buffer == NULL) { + local_output->buffer = mbedtls_calloc(output_len, 1); + if (local_output->buffer == NULL) { /* Since we dealt with the zero-length case above, we know that * a NULL return value means a failure of allocation. */ return PSA_ERROR_INSUFFICIENT_MEMORY; } - output_copy->length = output_len; - output_copy->original = output; + local_output->length = output_len; + local_output->original = output; return PSA_SUCCESS; } -psa_status_t psa_crypto_output_copy_free(psa_crypto_output_copy_t *output_copy) +psa_status_t psa_crypto_local_output_free(psa_crypto_local_output_t *local_output) { psa_status_t status; - if (output_copy->buffer == NULL) { - output_copy->length = 0; + if (local_output->buffer == NULL) { + local_output->length = 0; return PSA_SUCCESS; } - if (output_copy->original == NULL) { + if (local_output->original == NULL) { /* We have an internal copy but nothing to copy back to. */ return PSA_ERROR_CORRUPTION_DETECTED; } - status = psa_crypto_copy_output(output_copy->buffer, output_copy->length, - output_copy->original, output_copy->length); + status = psa_crypto_copy_output(local_output->buffer, local_output->length, + local_output->original, local_output->length); if (status != PSA_SUCCESS) { return status; } - mbedtls_free(output_copy->buffer); - output_copy->buffer = NULL; - output_copy->length = 0; + mbedtls_free(local_output->buffer); + local_output->buffer = NULL; + local_output->length = 0; return PSA_SUCCESS; } diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index ea34aab747..9f76f3329d 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -883,13 +883,13 @@ psa_status_t psa_crypto_local_input_alloc(const uint8_t *input, size_t input_len */ void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input); -typedef struct psa_crypto_output_copy_s { +typedef struct psa_crypto_local_output_s { uint8_t *original; uint8_t *buffer; size_t length; -} psa_crypto_output_copy_t; +} psa_crypto_local_output_t; -#define PSA_CRYPTO_OUTPUT_COPY_INIT { NULL, NULL, 0 } +#define PSA_CRYPTO_LOCAL_OUTPUT_INIT { NULL, NULL, 0 } /** Allocate a local copy of an output buffer. * @@ -897,31 +897,31 @@ typedef struct psa_crypto_output_copy_s { * output buffer but only allocates a buffer * whose contents will be copied back to the * original in a future call to - * psa_crypto_output_copy_free(). + * psa_crypto_local_output_free(). * * \param[in] output Pointer to output buffer. * \param[in] output_len Length of the output buffer. - * \param[out] output_copy Pointer to a psa_crypto_output_copy_t struct to - * populate with the output copy. + * \param[out] local_output Pointer to a psa_crypto_local_output_t struct to + * populate with the local output copy. * \return #PSA_SUCCESS, if the buffer was successfully * copied. * \return #PSA_ERROR_INSUFFICIENT_MEMORY, if a copy of * the buffer cannot be allocated. */ -psa_status_t psa_crypto_output_copy_alloc(uint8_t *output, size_t output_len, - psa_crypto_output_copy_t *output_copy); +psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len, + psa_crypto_local_output_t *local_output); /** Copy from a local copy of an output buffer back to the original, then * free the local copy. * - * \param[in] output_copy Pointer to a psa_crypto_output_copy_t struct + * \param[in] local_output Pointer to a psa_crypto_local_output_t struct * populated by a previous call to - * psa_crypto_output_copy_alloc(). - * \return #PSA_SUCCESS, if the output copy was + * psa_crypto_local_output_alloc(). + * \return #PSA_SUCCESS, if the local output was * successfully copied back to the original. * \return #PSA_ERROR_CORRUPTION_DETECTED, if the output * could not be copied back to the original. */ -psa_status_t psa_crypto_output_copy_free(psa_crypto_output_copy_t *output_copy); +psa_status_t psa_crypto_local_output_free(psa_crypto_local_output_t *local_output); #endif /* PSA_CRYPTO_CORE_H */ diff --git a/tests/suites/test_suite_psa_crypto_memory.data b/tests/suites/test_suite_psa_crypto_memory.data index d758bda0d4..2a828f573a 100644 --- a/tests/suites/test_suite_psa_crypto_memory.data +++ b/tests/suites/test_suite_psa_crypto_memory.data @@ -43,20 +43,20 @@ local_input_free:0 PSA crypto local input round-trip local_input_round_trip -PSA crypto output copy alloc -output_copy_alloc:200:PSA_SUCCESS +PSA crypto local output alloc +local_output_alloc:200:PSA_SUCCESS -PSA crypto output copy alloc, NULL buffer -output_copy_alloc:0:PSA_SUCCESS +PSA crypto local output alloc, NULL buffer +local_output_alloc:0:PSA_SUCCESS -PSA crypto output copy free -output_copy_free:200:0:PSA_SUCCESS +PSA crypto local output free +local_output_free:200:0:PSA_SUCCESS -PSA crypto output copy free, NULL buffer -output_copy_free:0:0:PSA_SUCCESS +PSA crypto local output free, NULL buffer +local_output_free:0:0:PSA_SUCCESS -PSA crypto output copy free, NULL original buffer -output_copy_free:200:1:PSA_ERROR_CORRUPTION_DETECTED +PSA crypto local output free, NULL original buffer +local_output_free:200:1:PSA_ERROR_CORRUPTION_DETECTED -PSA crypto output copy round-trip -output_copy_round_trip +PSA crypto local output round-trip +local_output_round_trip diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 3d606bbb66..2bb0f0d7ce 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -150,62 +150,62 @@ void local_input_round_trip() /* END_CASE */ /* BEGIN_CASE */ -void output_copy_alloc(int output_len, psa_status_t exp_status) +void local_output_alloc(int output_len, psa_status_t exp_status) { uint8_t *output = NULL; - psa_crypto_output_copy_t output_copy; + psa_crypto_local_output_t local_output; psa_status_t status; - output_copy.buffer = NULL; + local_output.buffer = NULL; TEST_CALLOC(output, output_len); - status = psa_crypto_output_copy_alloc(output, output_len, &output_copy); + status = psa_crypto_local_output_alloc(output, output_len, &local_output); TEST_EQUAL(status, exp_status); if (exp_status == PSA_SUCCESS) { - TEST_ASSERT(output_copy.original == output); - TEST_EQUAL(output_copy.length, output_len); + TEST_ASSERT(local_output.original == output); + TEST_EQUAL(local_output.length, output_len); } exit: - mbedtls_free(output_copy.buffer); - output_copy.original = NULL; - output_copy.buffer = NULL; - output_copy.length = 0; + mbedtls_free(local_output.buffer); + local_output.original = NULL; + local_output.buffer = NULL; + local_output.length = 0; mbedtls_free(output); output = NULL; } /* END_CASE */ /* BEGIN_CASE */ -void output_copy_free(int output_len, int original_is_null, - psa_status_t exp_status) +void local_output_free(int output_len, int original_is_null, + psa_status_t exp_status) { uint8_t *output = NULL; uint8_t *buffer_copy_for_comparison = NULL; - psa_crypto_output_copy_t output_copy = PSA_CRYPTO_OUTPUT_COPY_INIT; + psa_crypto_local_output_t local_output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; psa_status_t status; if (!original_is_null) { TEST_CALLOC(output, output_len); } TEST_CALLOC(buffer_copy_for_comparison, output_len); - TEST_CALLOC(output_copy.buffer, output_len); - output_copy.length = output_len; - output_copy.original = output; + TEST_CALLOC(local_output.buffer, output_len); + local_output.length = output_len; + local_output.original = output; - if (output_copy.length != 0) { - fill_buffer_pattern(output_copy.buffer, output_copy.length); - memcpy(buffer_copy_for_comparison, output_copy.buffer, output_copy.length); + if (local_output.length != 0) { + fill_buffer_pattern(local_output.buffer, local_output.length); + memcpy(buffer_copy_for_comparison, local_output.buffer, local_output.length); } - status = psa_crypto_output_copy_free(&output_copy); + status = psa_crypto_local_output_free(&local_output); TEST_EQUAL(status, exp_status); if (exp_status == PSA_SUCCESS) { - TEST_ASSERT(output_copy.buffer == NULL); - TEST_EQUAL(output_copy.length, 0); + TEST_ASSERT(local_output.buffer == NULL); + TEST_EQUAL(local_output.length, 0); TEST_MEMORY_COMPARE(buffer_copy_for_comparison, output_len, output, output_len); } @@ -213,32 +213,32 @@ void output_copy_free(int output_len, int original_is_null, exit: mbedtls_free(output); mbedtls_free(buffer_copy_for_comparison); - mbedtls_free(output_copy.buffer); - output_copy.length = 0; + mbedtls_free(local_output.buffer); + local_output.length = 0; } /* END_CASE */ /* BEGIN_CASE */ -void output_copy_round_trip() +void local_output_round_trip() { - psa_crypto_output_copy_t output_copy; + psa_crypto_local_output_t local_output; uint8_t output[200]; uint8_t *buffer_copy_for_comparison = NULL; psa_status_t status; - status = psa_crypto_output_copy_alloc(output, sizeof(output), &output_copy); + status = psa_crypto_local_output_alloc(output, sizeof(output), &local_output); TEST_EQUAL(status, PSA_SUCCESS); - TEST_ASSERT(output_copy.buffer != output); + TEST_ASSERT(local_output.buffer != output); /* Simulate the function generating output */ - fill_buffer_pattern(output_copy.buffer, output_copy.length); + fill_buffer_pattern(local_output.buffer, local_output.length); - TEST_CALLOC(buffer_copy_for_comparison, output_copy.length); - memcpy(buffer_copy_for_comparison, output_copy.buffer, output_copy.length); + TEST_CALLOC(buffer_copy_for_comparison, local_output.length); + memcpy(buffer_copy_for_comparison, local_output.buffer, local_output.length); - psa_crypto_output_copy_free(&output_copy); - TEST_ASSERT(output_copy.buffer == NULL); - TEST_EQUAL(output_copy.length, 0); + psa_crypto_local_output_free(&local_output); + TEST_ASSERT(local_output.buffer == NULL); + TEST_EQUAL(local_output.length, 0); /* Check that the buffer was correctly copied back */ TEST_MEMORY_COMPARE(output, sizeof(output), From 31003ffa46ada17c67e6ab544b2195b31e312535 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 23 Nov 2023 15:45:29 +0000 Subject: [PATCH 56/58] Add casts to local input / output initializers Signed-off-by: David Horstmann --- library/psa_crypto_core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 9f76f3329d..3d7198ac47 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -859,7 +859,7 @@ typedef struct psa_crypto_local_input_s { size_t length; } psa_crypto_local_input_t; -#define PSA_CRYPTO_LOCAL_INPUT_INIT { NULL, 0 } +#define PSA_CRYPTO_LOCAL_INPUT_INIT ((psa_crypto_local_input_t) { NULL, 0 }) /** Allocate a local copy of an input buffer. * @@ -889,7 +889,7 @@ typedef struct psa_crypto_local_output_s { size_t length; } psa_crypto_local_output_t; -#define PSA_CRYPTO_LOCAL_OUTPUT_INIT { NULL, NULL, 0 } +#define PSA_CRYPTO_LOCAL_OUTPUT_INIT ((psa_crypto_local_output_t) { NULL, NULL, 0 }) /** Allocate a local copy of an output buffer. * From 9db14486daf3545370cb0bef32849947611f6ed0 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 23 Nov 2023 15:50:37 +0000 Subject: [PATCH 57/58] Use initializers in alloc functions Signed-off-by: David Horstmann --- library/psa_crypto.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 781034d05f..e444c0c650 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -8501,8 +8501,7 @@ psa_status_t psa_crypto_local_input_alloc(const uint8_t *input, size_t input_len { psa_status_t status; - local_input->buffer = NULL; - local_input->length = 0; + *local_input = PSA_CRYPTO_LOCAL_INPUT_INIT; if (input_len == 0) { return PSA_SUCCESS; @@ -8543,9 +8542,7 @@ void psa_crypto_local_input_free(psa_crypto_local_input_t *local_input) psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len, psa_crypto_local_output_t *local_output) { - local_output->original = NULL; - local_output->buffer = NULL; - local_output->length = 0; + *local_output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; if (output_len == 0) { return PSA_SUCCESS; From a575a5a26ad206b5c35f80ffbcb2fe8ddb54abcc Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 23 Nov 2023 15:59:30 +0000 Subject: [PATCH 58/58] Improve description of psa_crypto_input_copy_alloc Signed-off-by: David Horstmann --- library/psa_crypto_core.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 3d7198ac47..87b0035521 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -861,12 +861,12 @@ typedef struct psa_crypto_local_input_s { #define PSA_CRYPTO_LOCAL_INPUT_INIT ((psa_crypto_local_input_t) { NULL, 0 }) -/** Allocate a local copy of an input buffer. +/** Allocate a local copy of an input buffer and copy the contents into it. * * \param[in] input Pointer to input buffer. * \param[in] input_len Length of the input buffer. - * \param[out] local_input Pointer to a psa_crypto_local_input_t struct to - * populate with the local input copy. + * \param[out] local_input Pointer to a psa_crypto_local_input_t struct + * containing a local input copy. * \return #PSA_SUCCESS, if the buffer was successfully * copied. * \return #PSA_ERROR_INSUFFICIENT_MEMORY, if a copy of