From 1cc21c31a9e1f4cbc175963a70611e96c0c409c3 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 30 Oct 2023 19:48:13 +0000 Subject: [PATCH 001/211] 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 781c9d2f43bf..79f5650dd830 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -515,4 +515,34 @@ psa_status_t psa_verify_hash_builtin( psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, const uint8_t *signature, size_t signature_length); +/** 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 b0a01b18af5a525d426f84f423921057b8c68bc2 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 30 Oct 2023 20:16:41 +0000 Subject: [PATCH 002/211] 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 | 32 +++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 03cc2ffe67e0..5b8a4eade979 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4020,3 +4020,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 0db5bff79aff..b9ebe6766f6c 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -13,6 +13,9 @@ #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" #include "test/psa_crypto_helpers.h" #include "test/psa_exercise_key.h" @@ -5639,3 +5642,32 @@ exit: PSA_DONE(); } /* 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 957f9803793f4e02e5be95b7ea5b69a1ad8474c5 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 30 Oct 2023 20:29:43 +0000 Subject: [PATCH 003/211] Add implementation of psa_crypto_copy_input() Signed-off-by: David Horstmann --- library/psa_crypto.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index e4b865ec971f..a8ef564cd7cc 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5523,4 +5523,16 @@ psa_status_t psa_crypto_init(void) return status; } +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 438cd4811acc198f4acb78d7e5a13239e0ab0d13 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 30 Oct 2023 20:34:41 +0000 Subject: [PATCH 004/211] 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 5b8a4eade979..dd19e7cfc654 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4029,3 +4029,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 b9ebe6766f6c..5ef168eb7069 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5671,3 +5671,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 2bd296e890c050dc05ac41fdb0b8ae05f8c610f3 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 30 Oct 2023 20:37:12 +0000 Subject: [PATCH 005/211] 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 a8ef564cd7cc..d48ad91a3bef 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5535,4 +5535,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 a707a6f56db119ece49320207599769d5761bf83 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 31 Oct 2023 15:41:45 +0000 Subject: [PATCH 006/211] 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 79f5650dd830..9e20480181ff 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -545,4 +545,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 0684069e44279d93da61c683c0c5d9974107ee0b Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 31 Oct 2023 17:40:59 +0000 Subject: [PATCH 007/211] 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 dd19e7cfc654..f747af41ab84 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4038,3 +4038,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 5ef168eb7069..5383ae4849bc 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5700,3 +5700,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 cc4dfa6892cb81c36c8eb852e19cf670b95c6cd9 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 31 Oct 2023 18:03:06 +0000 Subject: [PATCH 008/211] 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 d48ad91a3bef..f3273928681e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5545,4 +5545,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 41966d74332c965688e07ab4ea6685eae9a13858 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 31 Oct 2023 18:43:09 +0000 Subject: [PATCH 009/211] 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 f747af41ab84..9eee9be5d3f5 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4030,6 +4030,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 @@ -4039,6 +4045,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 5383ae4849bc..bd8f80d5fede 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5651,8 +5651,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)]; @@ -5680,8 +5684,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 ea08ab775d4a9966f8780fd8ec73e6c5867b9957 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 1 Nov 2023 12:30:24 +0000 Subject: [PATCH 010/211] 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 9eee9be5d3f5..3ced4f3b5267 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4062,3 +4062,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 bd8f80d5fede..1fcb421a46ec 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5749,3 +5749,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 0e38180e1d665aaa3e4c5b00016eff1648a13d82 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 1 Nov 2023 14:46:02 +0000 Subject: [PATCH 011/211] 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 f3273928681e..9def0a793818 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5554,6 +5554,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 1fcb421a46ec..4af5f692636a 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5767,8 +5767,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 9ecd53d1bb90e31b53387581f5426f20069aa07d Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 1 Nov 2023 15:41:54 +0000 Subject: [PATCH 012/211] 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 3ced4f3b5267..7e4069e57c72 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4071,3 +4071,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 4af5f692636a..790483c2e77c 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5783,3 +5783,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 5847b7082994a7e1869eeed4ec88dc5178d533e0 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 1 Nov 2023 17:47:39 +0000 Subject: [PATCH 013/211] 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 9def0a793818..f0599d751095 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5600,4 +5600,18 @@ psa_status_t psa_crypto_alloc_and_copy(const uint8_t *input, size_t input_len, 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 0368d20d5185cbadf3a33fbe6b0610565c46cbb8 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 1 Nov 2023 17:55:43 +0000 Subject: [PATCH 014/211] 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 f0599d751095..a3283ab1004d 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5603,6 +5603,12 @@ psa_status_t psa_crypto_alloc_and_copy(const uint8_t *input, size_t input_len, 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 7e4069e57c72..fc8969325d88 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4080,3 +4080,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 7131b8eecc0fb7986156bac9bd67081528e5f50d Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 2 Nov 2023 12:00:02 +0000 Subject: [PATCH 015/211] 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 a3283ab1004d..b498a1a7c5a8 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5602,7 +5602,17 @@ psa_status_t psa_crypto_alloc_and_copy(const uint8_t *input, size_t input_len, 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 fc8969325d88..b49224168bd1 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4086,3 +4086,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 406d28ba8709ab007058522f8646dd4b96eb8634 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 2 Nov 2023 14:39:00 +0000 Subject: [PATCH 016/211] 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 | 102 ++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index b49224168bd1..1d3169468eaa 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4072,6 +4072,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 790483c2e77c..5cdb55300193 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -279,6 +279,62 @@ typedef enum { DERIVE_KEY = 2 } generate_method; +/* 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 @@ -5784,6 +5840,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 5e0b4f8b42d0127026afa0f8c8f5d18ecab157a1 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 2 Nov 2023 17:07:16 +0000 Subject: [PATCH 017/211] 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 1d3169468eaa..89d2e28cc115 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4107,3 +4107,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 5cdb55300193..7bca4b37fd49 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5956,3 +5956,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 121994f33eb61c9fed339b347b281d61bc70864d Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 2 Nov 2023 17:48:07 +0000 Subject: [PATCH 018/211] 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 7bca4b37fd49..cd8fe5f30d17 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -279,6 +279,18 @@ typedef enum { DERIVE_KEY = 2 } generate_method; +/* 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. */ @@ -5702,7 +5714,6 @@ exit: /* 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; @@ -5714,9 +5725,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); @@ -5735,7 +5744,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; @@ -5747,9 +5755,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); @@ -5770,7 +5776,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 }; @@ -5778,15 +5783,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, @@ -5845,7 +5846,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; @@ -5857,9 +5857,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); @@ -5892,7 +5890,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; @@ -5915,9 +5912,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); @@ -5960,16 +5955,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), @@ -5981,9 +5973,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 f38eb76b34798b0f2d5907b7d473b5543ca4ab24 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 2 Nov 2023 20:47:04 +0000 Subject: [PATCH 019/211] 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 cd8fe5f30d17..fc9603cb9e72 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5778,9 +5778,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); @@ -5814,11 +5816,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); @@ -5846,14 +5849,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); @@ -5890,8 +5894,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; @@ -5899,6 +5901,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. */ @@ -5958,9 +5963,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 34342a2410de6723b77429a2dc938d4302df8571 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 19:20:33 +0000 Subject: [PATCH 020/211] 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 fc9603cb9e72..94ebe1b1b099 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 818b39dbc33ca5ed0ba5e6885294001f2f420941 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 19:23:49 +0000 Subject: [PATCH 021/211] 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 89d2e28cc115..eaeaaa57a74e 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4022,34 +4022,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 94ebe1b1b099..a9c9d0543c44 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5711,7 +5711,7 @@ exit: /* 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; @@ -5741,7 +5741,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 7a31ac02ab55deebf7325793383308c663da4f21 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 19:28:08 +0000 Subject: [PATCH 022/211] 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 a9c9d0543c44..b698f113a990 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5711,7 +5711,7 @@ exit: /* 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; @@ -5727,9 +5727,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); } @@ -5741,7 +5741,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; @@ -5757,9 +5757,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 113f2d46b018d8797243b092b7896506dd0b8fa2 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 19:31:35 +0000 Subject: [PATCH 023/211] 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 b698f113a990..e325ca1f1928 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5711,11 +5711,11 @@ exit: /* 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. */ @@ -5726,10 +5726,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); } @@ -5741,11 +5741,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. */ @@ -5756,10 +5756,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 89b4caab53d42e938b71de276f64dc8b359772fc Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 19:45:39 +0000 Subject: [PATCH 024/211] 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 e325ca1f1928..9176657c8dd2 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5717,12 +5717,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); @@ -5747,12 +5743,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 8684ad548f2921490e7eec0d7273cfac2bc91854 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 19:51:40 +0000 Subject: [PATCH 025/211] 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 b498a1a7c5a8..359f8da7d4d9 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5527,7 +5527,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); @@ -5539,7 +5539,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 9e20480181ff..a05f6990cc42 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -523,8 +523,8 @@ psa_status_t psa_verify_hash_builtin( * \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, @@ -538,7 +538,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 eaeaaa57a74e..4c24e50af3f8 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4028,7 +4028,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 @@ -4043,7 +4043,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 93e08c6db6d1056af1eff7f0ae7a4a6b461db3b4 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 3 Nov 2023 20:01:37 +0000 Subject: [PATCH 026/211] 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 4c24e50af3f8..03cc2ffe67e0 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -4020,93 +4020,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 9176657c8dd2..796a62a5f143 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -278,74 +278,6 @@ typedef enum { DERIVE_KEY = 2 } generate_method; -/* 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 @@ -5709,283 +5641,3 @@ exit: PSA_DONE(); } /* 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 000000000000..33623afdc184 --- /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 000000000000..a27f76b88a82 --- /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 cbdec9e4701cbfea0180f1a418f8bf0415ec53c2 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 6 Nov 2023 14:22:28 +0000 Subject: [PATCH 027/211] 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 359f8da7d4d9..66d0f7dc6a3a 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5545,89 +5545,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 a05f6990cc42..c317465f002c 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -545,57 +545,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 33623afdc184..0d44fb35d569 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 a27f76b88a82..7e59bb96f962 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 f0ec6e87b12863457db6c79dfd2e4b8eaed8e503 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 6 Nov 2023 17:27:16 +0000 Subject: [PATCH 028/211] 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 c317465f002c..5d62c1805bae 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -545,4 +545,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 89299c476c86cbfba622340c7dc395c69736266f Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 6 Nov 2023 18:18:59 +0000 Subject: [PATCH 029/211] 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 0d44fb35d569..85fed8f0e1b1 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 7e59bb96f962..837ff06e9ebf 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 8d9d4fe20daca8d7e0390fa8d350ad80be7cca83 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 7 Nov 2023 16:36:48 +0000 Subject: [PATCH 030/211] 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 66d0f7dc6a3a..b828e990030a 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5545,4 +5545,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 6790a6d36fc4d4170821ea1818630f9e1ecd00a4 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 7 Nov 2023 17:30:25 +0000 Subject: [PATCH 031/211] 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 85fed8f0e1b1..6591ba755c4e 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 837ff06e9ebf..c40ba67f5c30 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 fa2d75d30ab9a37d5560cb75c980be9fef5a8418 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 7 Nov 2023 18:00:41 +0000 Subject: [PATCH 032/211] 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 b828e990030a..d4c566dd47d1 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5584,4 +5584,11 @@ psa_status_t psa_crypto_input_copy_alloc(const uint8_t *input, size_t input_len, 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 b80367e3b4f203f96f7a12b6e4d2a30459385cb2 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 14:33:05 +0000 Subject: [PATCH 033/211] 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 5d62c1805bae..25320fcfaf53 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -572,4 +572,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 1acf7afa836fc45219d39bf39c02cfe38c436aeb Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 15:10:41 +0000 Subject: [PATCH 034/211] 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 6591ba755c4e..fcd60fb8031f 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 c40ba67f5c30..6fd58cd0af01 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 953cd5b372ffb0bbe15e52d5faed139d5252af0b Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 15:19:43 +0000 Subject: [PATCH 035/211] 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 d4c566dd47d1..669087cdb18b 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5591,4 +5591,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 3bc1316ceb5672a1daf11089c2516d51f585fc72 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 17:25:45 +0000 Subject: [PATCH 036/211] 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 fcd60fb8031f..2ca7e15abffa 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 6fd58cd0af01..57a10ae79124 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 aeeb2740a94848c565f0e66c12d9474f1c11a4d0 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 17:44:18 +0000 Subject: [PATCH 037/211] 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 669087cdb18b..9330d40af206 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5615,4 +5615,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 aca210d4c776d774b5a00c9066263e8adb9f865b Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 18:01:40 +0000 Subject: [PATCH 038/211] 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 2ca7e15abffa..3d14ba35dc5c 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 57a10ae79124..3c7b8425eb56 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 ba65bd79e83b85fe6532289bda817cbea44666d6 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 8 Nov 2023 18:11:29 +0000 Subject: [PATCH 039/211] 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 3d14ba35dc5c..357d3423d3f3 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 3c7b8425eb56..df08bf45f36f 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 761761ff64bb6aab091c668e9380e719582a2e60 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 15 Nov 2023 15:57:32 +0000 Subject: [PATCH 040/211] 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 9330d40af206..4cea3a905399 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5617,6 +5617,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; @@ -5626,7 +5628,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 df49355faaa92ddd94ea57c6caaa47fceec8e310 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 15 Nov 2023 15:18:30 +0000 Subject: [PATCH 041/211] 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 4cea3a905399..0cf1716994d5 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5523,6 +5523,19 @@ psa_status_t psa_crypto_init(void) return status; } +/** 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) { @@ -5535,6 +5548,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 25320fcfaf53..ca3d835cf1e0 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -515,36 +515,6 @@ psa_status_t psa_verify_hash_builtin( psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, const uint8_t *signature, size_t signature_length); -/** 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 58e357e3799c..ec7183d6dcea 100644 --- a/library/psa_crypto_invasive.h +++ b/library/psa_crypto_invasive.h @@ -81,6 +81,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 df08bf45f36f..29cb3eca135b 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 660027f3107f3b4babac5fcb9e4b19a7a735d227 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 15 Nov 2023 17:33:47 +0000 Subject: [PATCH 042/211] 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 0cf1716994d5..6b65d603604e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5543,7 +5543,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; } @@ -5567,7 +5569,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 726bf058fe8cb625d190b6aa07150ec53e51865e Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 15 Nov 2023 18:11:26 +0000 Subject: [PATCH 043/211] 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 6b65d603604e..0679368df175 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5585,9 +5585,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; } @@ -5630,9 +5628,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 e8a92227dc736035c6c2e0b0e029c404c0c09a6e Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 16 Nov 2023 19:57:25 +0000 Subject: [PATCH 044/211] 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 29cb3eca135b..81c52a3f7ae5 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 0ee4d18bc6ca7d60b98f096b435f64b243edfb57 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 16 Nov 2023 20:01:32 +0000 Subject: [PATCH 045/211] 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 81c52a3f7ae5..e92cbb157f39 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 2d730c015eedd6e1721ef15653b27a6c0cd0553b Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 16 Nov 2023 20:12:17 +0000 Subject: [PATCH 046/211] 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 e92cbb157f39..593825823c94 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 c3be8cb24a7be7bebf7f9c88e5440356fb6c82a7 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 16 Nov 2023 20:21:19 +0000 Subject: [PATCH 047/211] 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 ca3d835cf1e0..1a5a38908495 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -543,9 +543,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 d79d5e7ed0cb285e5c4cbb0cb797a9d276de4fac Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 16 Nov 2023 20:26:16 +0000 Subject: [PATCH 048/211] 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 593825823c94..83fa6cbd8619 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 37e3fc6c76d0baa873e490413926ee0989d5978a Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 16 Nov 2023 20:30:36 +0000 Subject: [PATCH 049/211] 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 83fa6cbd8619..7b6b7f189cf9 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 34c434a3cadbe1525fea72e362d70962e341cdbf Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 20 Nov 2023 12:16:08 +0000 Subject: [PATCH 050/211] 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 1a5a38908495..d3785054fa8c 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -520,6 +520,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. @@ -548,6 +550,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 7b6b7f189cf9..e9e529989ea0 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 232ab25bcd264c6d4973f41a6854f7d69fdc0468 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 20 Nov 2023 12:39:38 +0000 Subject: [PATCH 051/211] 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 0679368df175..b3bb394a258b 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5558,7 +5558,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. */ @@ -5567,7 +5567,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 357d3423d3f3..94fb407f9b3d 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 48ffb93d7f93800e17a6a9b54fb0bf82d8eb7246 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 20 Nov 2023 12:54:09 +0000 Subject: [PATCH 052/211] 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 b3bb394a258b..c40c6d7c6d5e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5583,7 +5583,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; @@ -5597,10 +5597,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; } @@ -5610,7 +5610,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; } @@ -5618,7 +5618,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, @@ -5626,7 +5626,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; @@ -5637,7 +5637,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; @@ -5648,7 +5648,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) { @@ -5656,15 +5656,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 d3785054fa8c..f7cda62bbde8 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -517,7 +517,7 @@ psa_status_t psa_verify_hash_builtin( 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 } @@ -547,7 +547,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 e9e529989ea0..8421604e9d58 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 81a0d57e36066f80e6dea72ee2223ff352d18896 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 20 Nov 2023 17:15:32 +0000 Subject: [PATCH 053/211] 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 c40c6d7c6d5e..2beef5f4e75c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5577,30 +5577,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; } @@ -5608,17 +5608,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 f7cda62bbde8..a830d30046e7 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -515,34 +515,34 @@ psa_status_t psa_verify_hash_builtin( psa_algorithm_t alg, const uint8_t *hash, size_t hash_length, const uint8_t *signature, size_t signature_length); -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 94fb407f9b3d..d758bda0d43d 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 8421604e9d58..3d606bbb6647 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 1a76ab1c34c9bec505d0d52300e51ecd3af6e6c7 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 20 Nov 2023 12:54:09 +0000 Subject: [PATCH 054/211] 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 2beef5f4e75c..3be67fc182a3 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5621,50 +5621,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 a830d30046e7..215b22710e4d 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -544,13 +544,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. * @@ -558,31 +558,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 d758bda0d43d..2a828f573ab2 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 3d606bbb6647..2bb0f0d7ceef 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 45221ffdc4a38f5fe84963ce81e1ffacf49370a0 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 23 Nov 2023 15:45:29 +0000 Subject: [PATCH 055/211] 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 215b22710e4d..91d2059e81f8 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -520,7 +520,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. * @@ -550,7 +550,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 0d52c71ccd1aa98f403c74d808f50d12556c5f37 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 23 Nov 2023 15:50:37 +0000 Subject: [PATCH 056/211] 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 3be67fc182a3..dbcbcc26945b 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5582,8 +5582,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; @@ -5624,9 +5623,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 8e1f0d0d315242103b70e297de9bf419c853969b Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 23 Nov 2023 15:59:30 +0000 Subject: [PATCH 057/211] 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 91d2059e81f8..1e39e3264b94 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -522,12 +522,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 From 87270e533783e291baf734ab856b6bde978f24cd Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 2 Nov 2023 17:14:01 +0100 Subject: [PATCH 058/211] New files for memory-related test functions Signed-off-by: Gilles Peskine --- tests/include/test/memory.h | 18 ++++++++++++++++++ tests/src/test_memory.c | 15 +++++++++++++++ visualc/VS2010/mbedTLS.vcxproj | 2 ++ 3 files changed, 35 insertions(+) create mode 100644 tests/include/test/memory.h create mode 100644 tests/src/test_memory.c diff --git a/tests/include/test/memory.h b/tests/include/test/memory.h new file mode 100644 index 000000000000..fa5516539705 --- /dev/null +++ b/tests/include/test/memory.h @@ -0,0 +1,18 @@ +/** + * \file memory.h + * + * \brief Helper macros and functions related to testing memory management. + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef TEST_MEMORY_H +#define TEST_MEMORY_H + +#include "test/helpers.h" +#include "mbedtls/platform.h" + +#endif /* TEST_MEMORY_H */ diff --git a/tests/src/test_memory.c b/tests/src/test_memory.c new file mode 100644 index 000000000000..cda91e5eaf87 --- /dev/null +++ b/tests/src/test_memory.c @@ -0,0 +1,15 @@ +/** + * \file memory.c + * + * \brief Helper functions related to testing memory management. + */ + +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include +#include +#include + diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index c75b3535485b..ccabcfd3dfbf 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -243,6 +243,7 @@ + @@ -390,6 +391,7 @@ + From 071d144a2ed1f8bbbaa2a59b3278e9fafcefa2ce Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 2 Nov 2023 20:49:34 +0100 Subject: [PATCH 059/211] Add memory poisoning framework While an area of memory is poisoned, reading or writing from it triggers a sanitizer violation. Implemented for ASan. Signed-off-by: Gilles Peskine --- programs/test/metatest.c | 41 ++++++++++++++++++++ tests/include/test/memory.h | 75 +++++++++++++++++++++++++++++++++++++ tests/src/test_memory.c | 22 +++++++++++ 3 files changed, 138 insertions(+) diff --git a/programs/test/metatest.c b/programs/test/metatest.c index b8dffa9bbd12..6ab240c59225 100644 --- a/programs/test/metatest.c +++ b/programs/test/metatest.c @@ -32,6 +32,7 @@ #include #include "test/helpers.h" #include "test/macros.h" +#include "test/memory.h" #include #include @@ -143,6 +144,45 @@ void memory_leak(const char *name) /* Leak of a heap object */ } +/* name = "test_memory_poison_%(start)_%(offset)_%(count)" + * Poison a region starting at start from an 8-byte aligned origin, + * encompassing count bytes. Access the region at offset from the start. + */ +void test_memory_poison(const char *name) +{ + size_t start = 0, offset = 0, count = 0; + if (sscanf(name, "%*[^0-9]%zu%*[^0-9]%zu%*[^0-9]%zu", + &start, &offset, &count) != 3) { + mbedtls_fprintf(stderr, "%s: Bad name format: %s\n", __func__, name); + return; + } + + union { + long long ll; + unsigned char buf[32]; + } aligned; + memset(aligned.buf, 'a', sizeof(aligned.buf)); + + if (start > sizeof(aligned.buf)) { + mbedtls_fprintf(stderr, "%s: start=%zu > size=%zu", __func__, + start, sizeof(aligned.buf)); + return; + } + if (start + count > sizeof(aligned.buf)) { + mbedtls_fprintf(stderr, "%s: start+count=%zu > size=%zu", __func__, + start + count, sizeof(aligned.buf)); + return; + } + if (offset >= count) { + mbedtls_fprintf(stderr, "%s: offset=%zu >= count=%zu", __func__, + offset, count); + return; + } + + MBEDTLS_TEST_MEMORY_POISON(aligned.buf + start, count); + mbedtls_printf("%u\n", (unsigned) aligned.buf[start + offset]); +} + /****************************************************************/ /* Threading */ @@ -291,6 +331,7 @@ metatest_t metatests[] = { { "double_free", "asan", double_free }, { "read_uninitialized_stack", "msan", read_uninitialized_stack }, { "memory_leak", "asan", memory_leak }, + { "test_memory_poison_0_0_8", "asan", test_memory_poison }, { "mutex_lock_not_initialized", "pthread", mutex_lock_not_initialized }, { "mutex_unlock_not_initialized", "pthread", mutex_unlock_not_initialized }, { "mutex_free_not_initialized", "pthread", mutex_free_not_initialized }, diff --git a/tests/include/test/memory.h b/tests/include/test/memory.h index fa5516539705..8bba02dbdd9e 100644 --- a/tests/include/test/memory.h +++ b/tests/include/test/memory.h @@ -15,4 +15,79 @@ #include "test/helpers.h" #include "mbedtls/platform.h" +/** \def MBEDTLS_TEST_MEMORY_CAN_POISON + * + * This macro is defined if the tests are compiled with a method to mark + * memory as poisoned, which can be used to enforce some memory access + * policies. + * + * Currently, only Asan (Address Sanitizer) is supported. + */ +#if defined(__SANITIZE_ADDRESS__) +# define MBEDTLS_TEST_HAVE_ASAN +#endif +#if defined(__has_feature) +# if __has_feature(address_sanitizer) +# define MBEDTLS_TEST_HAVE_ASAN +# endif +#endif +#if defined(MBEDTLS_TEST_HAVE_ASAN) +# define MBEDTLS_TEST_MEMORY_CAN_POISON +#endif + +/** \def MBEDTLS_TEST_MEMORY_POISON(buf, size) + * + * Poison a memory area so that any attempt to read or write from it will + * cause a runtime failure. + * + * The behavior is undefined if any part of the memory area is invalid. + * + * This is a no-op in builds without a poisoning method. + * See #MBEDTLS_TEST_MEMORY_CAN_POISON. + * + * \param buf Pointer to the beginning of the memory area to poison. + * \param size Size of the memory area in bytes. + */ + +/** \def MBEDTLS_TEST_MEMORY_UNPOISON(buf, size) + * + * Undo the effect of #MBEDTLS_TEST_MEMORY_POISON. + * + * The behavior is undefined if any part of the memory area is invalid, + * or if the memory area contains a mixture of poisoned and unpoisoned parts. + * + * This is a no-op in builds without a poisoning method. + * See #MBEDTLS_TEST_MEMORY_CAN_POISON. + * + * \param buf Pointer to the beginning of the memory area to unpoison. + * \param size Size of the memory area in bytes. + */ + +#if defined(MBEDTLS_TEST_MEMORY_CAN_POISON) + +/** Poison a memory area so that any attempt to read or write from it will + * cause a runtime failure. + * + * The behavior is undefined if any part of the memory area is invalid. + */ +void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size); +#define MBEDTLS_TEST_MEMORY_POISON(ptr, size) \ + mbedtls_test_memory_poison(ptr, size) + +/** Undo the effect of mbedtls_test_memory_poison(). + * + * This is a no-op if the given area is entirely valid, unpoisoned memory. + * + * The behavior is undefined if any part of the memory area is invalid, + * or if the memory area contains a mixture of poisoned and unpoisoned parts. + */ +void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size); +#define MBEDTLS_TEST_MEMORY_UNPOISON(ptr, size) \ + mbedtls_test_memory_unpoison(ptr, size) + +#else /* MBEDTLS_TEST_MEMORY_CAN_POISON */ +#define MBEDTLS_TEST_MEMORY_POISON(ptr, size) ((void) 0) +#define MBEDTLS_TEST_MEMORY_UNPOISON(ptr, size) ((void) 0) +#endif /* MBEDTLS_TEST_MEMORY_CAN_POISON */ + #endif /* TEST_MEMORY_H */ diff --git a/tests/src/test_memory.c b/tests/src/test_memory.c index cda91e5eaf87..6b1404bc3cdd 100644 --- a/tests/src/test_memory.c +++ b/tests/src/test_memory.c @@ -13,3 +13,25 @@ #include #include +#if defined(MBEDTLS_TEST_HAVE_ASAN) +#include +#include +#endif + +#if defined(MBEDTLS_TEST_HAVE_ASAN) +void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size) +{ + if (size == 0) { + return; + } + __asan_poison_memory_region(ptr, size); +} + +void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size) +{ + if (size == 0) { + return; + } + __asan_unpoison_memory_region(ptr, size); +} +#endif /* Asan */ From 962c5da52a27b24aa944bd8ffef3222943e0e1be Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 2 Nov 2023 22:44:32 +0100 Subject: [PATCH 060/211] Fix memory poisoning with Asan on arbitrary byte boundaries Asan poisons memory with an 8-byte granularity. We want to make sure that the whole specified region is poisoned (our typical use case is a heap-allocated object, and we want to poison the whole object, and we don't care about the bytes after the end of the object and up to the beginning of the next object). So align the start and end of the region to (un)poison to an 8-byte boundary. Signed-off-by: Gilles Peskine --- programs/test/metatest.c | 7 +++++++ tests/include/test/memory.h | 4 ++++ tests/src/test_memory.c | 17 +++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/programs/test/metatest.c b/programs/test/metatest.c index 6ab240c59225..a3d9d4095ae3 100644 --- a/programs/test/metatest.c +++ b/programs/test/metatest.c @@ -332,6 +332,13 @@ metatest_t metatests[] = { { "read_uninitialized_stack", "msan", read_uninitialized_stack }, { "memory_leak", "asan", memory_leak }, { "test_memory_poison_0_0_8", "asan", test_memory_poison }, + { "test_memory_poison_0_7_8", "asan", test_memory_poison }, + { "test_memory_poison_0_0_1", "asan", test_memory_poison }, + { "test_memory_poison_0_1_2", "asan", test_memory_poison }, + { "test_memory_poison_7_0_8", "asan", test_memory_poison }, + { "test_memory_poison_7_7_8", "asan", test_memory_poison }, + { "test_memory_poison_7_0_1", "asan", test_memory_poison }, + { "test_memory_poison_7_1_2", "asan", test_memory_poison }, { "mutex_lock_not_initialized", "pthread", mutex_lock_not_initialized }, { "mutex_unlock_not_initialized", "pthread", mutex_unlock_not_initialized }, { "mutex_free_not_initialized", "pthread", mutex_free_not_initialized }, diff --git a/tests/include/test/memory.h b/tests/include/test/memory.h index 8bba02dbdd9e..a10e985479c4 100644 --- a/tests/include/test/memory.h +++ b/tests/include/test/memory.h @@ -40,6 +40,10 @@ * Poison a memory area so that any attempt to read or write from it will * cause a runtime failure. * + * Depending on the implementation, this may poison a few bytes beyond the + * indicated region, but will never poison a separate object on the heap + * or a separate object with more than the alignment of a long long. + * * The behavior is undefined if any part of the memory area is invalid. * * This is a no-op in builds without a poisoning method. diff --git a/tests/src/test_memory.c b/tests/src/test_memory.c index 6b1404bc3cdd..c277be85abd9 100644 --- a/tests/src/test_memory.c +++ b/tests/src/test_memory.c @@ -19,11 +19,27 @@ #endif #if defined(MBEDTLS_TEST_HAVE_ASAN) +static void align_for_asan(const unsigned char **p_ptr, size_t *p_size) +{ + uintptr_t start = (uintptr_t) *p_ptr; + uintptr_t end = start + (uintptr_t) *p_size; + /* ASan can only poison regions with 8-byte alignment, and only poisons a + * region if it's fully within the requested range. We want to poison the + * whole requested region and don't mind a few extra bytes. Therefore, + * align start down to an 8-byte boundary, and end up to an 8-byte + * boundary. */ + start = start & ~(uintptr_t) 7; + end = (end + 7) & ~(uintptr_t) 7; + *p_ptr = (const unsigned char *) start; + *p_size = end - start; +} + void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size) { if (size == 0) { return; } + align_for_asan(&ptr, &size); __asan_poison_memory_region(ptr, size); } @@ -32,6 +48,7 @@ void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size) if (size == 0) { return; } + align_for_asan(&ptr, &size); __asan_unpoison_memory_region(ptr, size); } #endif /* Asan */ From 721a64463ad3eb40a69355ce87d489b0a1d32465 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 2 Nov 2023 23:07:33 +0100 Subject: [PATCH 061/211] Basic functional test for memory poisoning Signed-off-by: Gilles Peskine --- tests/suites/test_suite_test_helpers.data | 23 +++++++++++ tests/suites/test_suite_test_helpers.function | 40 +++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 tests/suites/test_suite_test_helpers.data create mode 100644 tests/suites/test_suite_test_helpers.function diff --git a/tests/suites/test_suite_test_helpers.data b/tests/suites/test_suite_test_helpers.data new file mode 100644 index 000000000000..1d221d7bf18d --- /dev/null +++ b/tests/suites/test_suite_test_helpers.data @@ -0,0 +1,23 @@ +Memory poison+unpoison: offset=0 len=42 +memory_poison_unpoison:0:42 + +Memory poison+unpoison: offset=0 len=1 +memory_poison_unpoison:0:1 + +Memory poison+unpoison: offset=0 len=2 +memory_poison_unpoison:0:2 + +Memory poison+unpoison: offset=1 len=1 +memory_poison_unpoison:1:1 + +Memory poison+unpoison: offset=1 len=2 +memory_poison_unpoison:1:2 + +Memory poison+unpoison: offset=7 len=1 +memory_poison_unpoison:7:1 + +Memory poison+unpoison: offset=7 len=2 +memory_poison_unpoison:7:2 + +Memory poison+unpoison: offset=0 len=0 +memory_poison_unpoison:0:0 diff --git a/tests/suites/test_suite_test_helpers.function b/tests/suites/test_suite_test_helpers.function new file mode 100644 index 000000000000..8c5d5adf654d --- /dev/null +++ b/tests/suites/test_suite_test_helpers.function @@ -0,0 +1,40 @@ +/* BEGIN_HEADER */ + +/* Test some parts of the test framework. */ + +#include +#include + +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES */ + +/* END_DEPENDENCIES */ + +/* BEGIN_CASE depends_on:MBEDTLS_TEST_MEMORY_CAN_POISON */ +/* Test that poison+unpoison leaves the memory accessible. */ +/* We can't test that poisoning makes the memory inaccessible: + * there's no sane way to catch an Asan/Valgrind complaint. + * That negative testing is done in programs/test/metatest.c. */ +void memory_poison_unpoison(int align, int size) +{ + unsigned char *buf = NULL; + const size_t buffer_size = align + size; + TEST_CALLOC(buf, buffer_size); + + for (size_t i = 0; i < buffer_size; i++) { + buf[i] = (unsigned char) (i & 0xff); + } + + const unsigned char *start = buf == NULL ? NULL : buf + align; + mbedtls_test_memory_poison(start, (size_t) size); + mbedtls_test_memory_unpoison(start, (size_t) size); + + for (size_t i = 0; i < buffer_size; i++) { + TEST_EQUAL(buf[i], (unsigned char) (i & 0xff)); + } + +exit: + mbedtls_free(buf); +} +/* END_CASE */ From ac8cd66bda0b52988ea604fc1ce92e03f7a3206b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 3 Nov 2023 17:01:32 +0100 Subject: [PATCH 062/211] Fix MSVC build failure Signed-off-by: Gilles Peskine --- programs/test/metatest.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/programs/test/metatest.c b/programs/test/metatest.c index a3d9d4095ae3..6a3e7a911be0 100644 --- a/programs/test/metatest.c +++ b/programs/test/metatest.c @@ -41,6 +41,11 @@ #include #endif +/* C99 feature missing from older versions of MSVC */ +#if (defined(_MSC_VER) && (_MSC_VER <= 1900)) +#define /*no-check-names*/ __func__ __FUNCTION__ +#endif + /* This is an external variable, so the compiler doesn't know that we're never * changing its value. From d751406f8d1d17f96d49321ed53951312e640d89 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 3 Nov 2023 19:41:44 +0100 Subject: [PATCH 063/211] Port to platforms where printf doesn't have %zu Reuse the existing abstraction from include/mbedtls/debug.h. Signed-off-by: Gilles Peskine --- programs/test/metatest.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/programs/test/metatest.c b/programs/test/metatest.c index 6a3e7a911be0..6e476b7b32c8 100644 --- a/programs/test/metatest.c +++ b/programs/test/metatest.c @@ -28,6 +28,7 @@ #define MBEDTLS_ALLOW_PRIVATE_ACCESS +#include #include #include #include "test/helpers.h" @@ -156,7 +157,10 @@ void memory_leak(const char *name) void test_memory_poison(const char *name) { size_t start = 0, offset = 0, count = 0; - if (sscanf(name, "%*[^0-9]%zu%*[^0-9]%zu%*[^0-9]%zu", + if (sscanf(name, + "%*[^0-9]%" MBEDTLS_PRINTF_SIZET + "%*[^0-9]%" MBEDTLS_PRINTF_SIZET + "%*[^0-9]%" MBEDTLS_PRINTF_SIZET, &start, &offset, &count) != 3) { mbedtls_fprintf(stderr, "%s: Bad name format: %s\n", __func__, name); return; @@ -169,18 +173,24 @@ void test_memory_poison(const char *name) memset(aligned.buf, 'a', sizeof(aligned.buf)); if (start > sizeof(aligned.buf)) { - mbedtls_fprintf(stderr, "%s: start=%zu > size=%zu", __func__, - start, sizeof(aligned.buf)); + mbedtls_fprintf(stderr, + "%s: start=%" MBEDTLS_PRINTF_SIZET + " > size=%" MBEDTLS_PRINTF_SIZET, + __func__, start, sizeof(aligned.buf)); return; } if (start + count > sizeof(aligned.buf)) { - mbedtls_fprintf(stderr, "%s: start+count=%zu > size=%zu", __func__, - start + count, sizeof(aligned.buf)); + mbedtls_fprintf(stderr, + "%s: start+count=%" MBEDTLS_PRINTF_SIZET + " > size=%" MBEDTLS_PRINTF_SIZET, + __func__, start + count, sizeof(aligned.buf)); return; } if (offset >= count) { - mbedtls_fprintf(stderr, "%s: offset=%zu >= count=%zu", __func__, - offset, count); + mbedtls_fprintf(stderr, + "%s: offset=%" MBEDTLS_PRINTF_SIZET + " >= count=%" MBEDTLS_PRINTF_SIZET, + __func__, offset, count); return; } From 5e8740576c1e715a560e1db904838fb8d9e4d079 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 22 Nov 2023 18:13:23 +0100 Subject: [PATCH 064/211] Use the existing definition of MBEDTLS_TEST_HAVE_ASAN A definition now exists in tests/helpers.h, which is a better place. Signed-off-by: Gilles Peskine --- tests/include/test/memory.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/include/test/memory.h b/tests/include/test/memory.h index a10e985479c4..8080f98be07b 100644 --- a/tests/include/test/memory.h +++ b/tests/include/test/memory.h @@ -23,14 +23,6 @@ * * Currently, only Asan (Address Sanitizer) is supported. */ -#if defined(__SANITIZE_ADDRESS__) -# define MBEDTLS_TEST_HAVE_ASAN -#endif -#if defined(__has_feature) -# if __has_feature(address_sanitizer) -# define MBEDTLS_TEST_HAVE_ASAN -# endif -#endif #if defined(MBEDTLS_TEST_HAVE_ASAN) # define MBEDTLS_TEST_MEMORY_CAN_POISON #endif From 014d89b782c1dc3b360b36d05047012af2477151 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 22 Nov 2023 18:13:46 +0100 Subject: [PATCH 065/211] Avoid unused variable warnings in some plausible usage Signed-off-by: Gilles Peskine --- tests/include/test/memory.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/include/test/memory.h b/tests/include/test/memory.h index 8080f98be07b..43fbb6350f09 100644 --- a/tests/include/test/memory.h +++ b/tests/include/test/memory.h @@ -82,8 +82,8 @@ void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size); mbedtls_test_memory_unpoison(ptr, size) #else /* MBEDTLS_TEST_MEMORY_CAN_POISON */ -#define MBEDTLS_TEST_MEMORY_POISON(ptr, size) ((void) 0) -#define MBEDTLS_TEST_MEMORY_UNPOISON(ptr, size) ((void) 0) +#define MBEDTLS_TEST_MEMORY_POISON(ptr, size) ((void) (ptr), (void) (size)) +#define MBEDTLS_TEST_MEMORY_UNPOISON(ptr, size) ((void) (ptr), (void) (size)) #endif /* MBEDTLS_TEST_MEMORY_CAN_POISON */ #endif /* TEST_MEMORY_H */ From 0c7d3eda0a25a2e94fd30b5494ecc97c766d9814 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 22 Nov 2023 18:22:07 +0100 Subject: [PATCH 066/211] Memory poisoning: meta-test writes as well as reads Signed-off-by: Gilles Peskine --- programs/test/metatest.c | 41 ++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/programs/test/metatest.c b/programs/test/metatest.c index 6e476b7b32c8..0910798e1c98 100644 --- a/programs/test/metatest.c +++ b/programs/test/metatest.c @@ -150,18 +150,22 @@ void memory_leak(const char *name) /* Leak of a heap object */ } -/* name = "test_memory_poison_%(start)_%(offset)_%(count)" +/* name = "test_memory_poison_%(start)_%(offset)_%(count)_%(direction)" * Poison a region starting at start from an 8-byte aligned origin, * encompassing count bytes. Access the region at offset from the start. + * %(start), %(offset) and %(count) are decimal integers. + * %(direction) is either the character 'r' for read or 'w' for write. */ void test_memory_poison(const char *name) { size_t start = 0, offset = 0, count = 0; + char direction = 'r'; if (sscanf(name, "%*[^0-9]%" MBEDTLS_PRINTF_SIZET "%*[^0-9]%" MBEDTLS_PRINTF_SIZET - "%*[^0-9]%" MBEDTLS_PRINTF_SIZET, - &start, &offset, &count) != 3) { + "%*[^0-9]%" MBEDTLS_PRINTF_SIZET + "_%c", + &start, &offset, &count, &direction) != 4) { mbedtls_fprintf(stderr, "%s: Bad name format: %s\n", __func__, name); return; } @@ -195,7 +199,12 @@ void test_memory_poison(const char *name) } MBEDTLS_TEST_MEMORY_POISON(aligned.buf + start, count); - mbedtls_printf("%u\n", (unsigned) aligned.buf[start + offset]); + + if (direction == 'w') { + aligned.buf[start + offset] = 'b'; + } else { + mbedtls_printf("%u\n", (unsigned) aligned.buf[start + offset]); + } } @@ -346,14 +355,22 @@ metatest_t metatests[] = { { "double_free", "asan", double_free }, { "read_uninitialized_stack", "msan", read_uninitialized_stack }, { "memory_leak", "asan", memory_leak }, - { "test_memory_poison_0_0_8", "asan", test_memory_poison }, - { "test_memory_poison_0_7_8", "asan", test_memory_poison }, - { "test_memory_poison_0_0_1", "asan", test_memory_poison }, - { "test_memory_poison_0_1_2", "asan", test_memory_poison }, - { "test_memory_poison_7_0_8", "asan", test_memory_poison }, - { "test_memory_poison_7_7_8", "asan", test_memory_poison }, - { "test_memory_poison_7_0_1", "asan", test_memory_poison }, - { "test_memory_poison_7_1_2", "asan", test_memory_poison }, + { "test_memory_poison_0_0_8_r", "asan", test_memory_poison }, + { "test_memory_poison_0_0_8_w", "asan", test_memory_poison }, + { "test_memory_poison_0_7_8_r", "asan", test_memory_poison }, + { "test_memory_poison_0_7_8_w", "asan", test_memory_poison }, + { "test_memory_poison_0_0_1_r", "asan", test_memory_poison }, + { "test_memory_poison_0_0_1_w", "asan", test_memory_poison }, + { "test_memory_poison_0_1_2_r", "asan", test_memory_poison }, + { "test_memory_poison_0_1_2_w", "asan", test_memory_poison }, + { "test_memory_poison_7_0_8_r", "asan", test_memory_poison }, + { "test_memory_poison_7_0_8_w", "asan", test_memory_poison }, + { "test_memory_poison_7_7_8_r", "asan", test_memory_poison }, + { "test_memory_poison_7_7_8_w", "asan", test_memory_poison }, + { "test_memory_poison_7_0_1_r", "asan", test_memory_poison }, + { "test_memory_poison_7_0_1_w", "asan", test_memory_poison }, + { "test_memory_poison_7_1_2_r", "asan", test_memory_poison }, + { "test_memory_poison_7_1_2_w", "asan", test_memory_poison }, { "mutex_lock_not_initialized", "pthread", mutex_lock_not_initialized }, { "mutex_unlock_not_initialized", "pthread", mutex_unlock_not_initialized }, { "mutex_free_not_initialized", "pthread", mutex_free_not_initialized }, From 7d68a1954c99581059432291b00d1aa332c715ab Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 23 Nov 2023 12:33:39 +0100 Subject: [PATCH 067/211] Protect against compiler optimizations GCC 5.4 optimized the write after poisoning (the surprising thing is that 11.4 doesn't). Signed-off-by: Gilles Peskine --- programs/test/metatest.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/programs/test/metatest.c b/programs/test/metatest.c index 0910798e1c98..1724aed0bd11 100644 --- a/programs/test/metatest.c +++ b/programs/test/metatest.c @@ -66,6 +66,15 @@ static void set_to_zero_but_the_compiler_does_not_know(volatile void *p, size_t memset((void *) p, false_but_the_compiler_does_not_know, n); } +/* Simulate an access to the given object, to avoid compiler optimizations + * in code that prepares or consumes the object. */ +static void do_nothing_with_object(void *p) +{ + (void) p; +} +void(*volatile do_nothing_with_object_but_the_compiler_does_not_know)(void *) = + do_nothing_with_object; + /****************************************************************/ /* Test framework features */ @@ -202,7 +211,9 @@ void test_memory_poison(const char *name) if (direction == 'w') { aligned.buf[start + offset] = 'b'; + do_nothing_with_object_but_the_compiler_does_not_know(aligned.buf); } else { + do_nothing_with_object_but_the_compiler_does_not_know(aligned.buf); mbedtls_printf("%u\n", (unsigned) aligned.buf[start + offset]); } } From e369fcb23a0fb29a52484a46821a958408f10df0 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 20 Dec 2023 14:43:18 +0000 Subject: [PATCH 068/211] Disable check_mbedtls_calloc overallocation under ASan This test case exercises an integer overflow in calloc. Under Asan, with a modern Clang, this triggers an Asan complaint. The complaint can be avoided with ASAN_OPTIONS=allocator_may_return_null=1, but this has to be set in the environment before the program starts, and could hide other errors. Reproduced from a commit in mbedtls#8286 Signed-off-by: David Horstmann --- tests/suites/test_suite_debug.data | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/suites/test_suite_debug.data b/tests/suites/test_suite_debug.data index 87ec67c8ce39..0b88695623cd 100644 --- a/tests/suites/test_suite_debug.data +++ b/tests/suites/test_suite_debug.data @@ -67,4 +67,10 @@ depends_on:MBEDTLS_PEM_PARSE_C:MBEDTLS_BASE64_C:MBEDTLS_ECDSA_C:MBEDTLS_ECP_C:MB mbedtls_debug_print_crt:"data_files/test-ca2.crt":"MyFile":999:"PREFIX_":"MyFile(0999)\: PREFIX_ #1\:\nMyFile(0999)\: cert. version \: 3\nMyFile(0999)\: serial number \: C1\:43\:E2\:7E\:62\:43\:CC\:E8\nMyFile(0999)\: issuer name \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nMyFile(0999)\: subject name \: C=NL, O=PolarSSL, CN=Polarssl Test EC CA\nMyFile(0999)\: issued on \: 2019-02-10 14\:44\:00\nMyFile(0999)\: expires on \: 2029-02-10 14\:44\:00\nMyFile(0999)\: signed using \: ECDSA with SHA256\nMyFile(0999)\: EC key size \: 384 bits\nMyFile(0999)\: basic constraints \: CA=true\nMyFile(0999)\: value of 'crt->eckey.Q(X)' (384 bits) is\:\nMyFile(0999)\: c3 da 2b 34 41 37 58 2f 87 56 fe fc 89 ba 29 43\nMyFile(0999)\: 4b 4e e0 6e c3 0e 57 53 33 39 58 d4 52 b4 91 95\nMyFile(0999)\: 39 0b 23 df 5f 17 24 62 48 fc 1a 95 29 ce 2c 2d\nMyFile(0999)\: value of 'crt->eckey.Q(Y)' (384 bits) is\:\nMyFile(0999)\: 87 c2 88 52 80 af d6 6a ab 21 dd b8 d3 1c 6e 58\nMyFile(0999)\: b8 ca e8 b2 69 8e f3 41 ad 29 c3 b4 5f 75 a7 47\nMyFile(0999)\: 6f d5 19 29 55 69 9a 53 3b 20 b4 66 16 60 33 1e\n" Check mbedtls_calloc overallocation +# This test case exercises an integer overflow in calloc. Under Asan, with +# a modern Clang, this triggers an ASan/MSan/TSan complaint. The complaint +# can be avoided with e.g. ASAN_OPTIONS=allocator_may_return_null=1, +# but this has to be set in the environment before the program starts, +# and could hide other errors. +depends_on:!MBEDTLS_TEST_HAVE_ASAN:!MBEDTLS_TEST_HAVE_MSAN:!MBEDTLS_TEST_HAVE_TSAN check_mbedtls_calloc_overallocation:1:1 From 0760b15d4564a2925f9a88272ec3a75a6792986d Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 24 Nov 2023 16:21:04 +0000 Subject: [PATCH 069/211] Add memory poisoning hooks Signed-off-by: David Horstmann --- library/CMakeLists.txt | 5 ++++- library/psa_crypto.c | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index c7105a1fdfd0..80a323702cce 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -226,7 +226,10 @@ foreach(target IN LISTS target_libraries) PUBLIC ${MBEDTLS_DIR}/include/ PUBLIC ${thirdparty_inc_public} PRIVATE ${MBEDTLS_DIR}/library/ - PRIVATE ${thirdparty_inc}) + PRIVATE ${thirdparty_inc} + # Needed to include psa_crypto_driver_wrappers.h + ${CMAKE_CURRENT_BINARY_DIR} + ${MBEDTLS_DIR}/tests/include/) target_compile_definitions(${target} PRIVATE ${thirdparty_def}) # Pass-through MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 094b52631106..60c81a572d2c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -73,6 +73,10 @@ #include "mbedtls/sha512.h" #include "mbedtls/xtea.h" +#if defined(MBEDTLS_TEST_HOOKS) +#include "test/memory.h" +#endif + #define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array))) /****************************************************************/ @@ -5531,10 +5535,18 @@ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, return PSA_ERROR_CORRUPTION_DETECTED; } +#if defined(MBEDTLS_TEST_HOOKS) + MBEDTLS_TEST_MEMORY_UNPOISON(input, input_len); +#endif + if (input_len > 0) { memcpy(input_copy, input, input_len); } +#if defined(MBEDTLS_TEST_HOOKS) + MBEDTLS_TEST_MEMORY_POISON(input, input_len); +#endif + return PSA_SUCCESS; } @@ -5558,10 +5570,18 @@ psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_co return PSA_ERROR_BUFFER_TOO_SMALL; } +#if defined(MBEDTLS_TEST_HOOKS) + MBEDTLS_TEST_MEMORY_UNPOISON(output, output_len); +#endif + if (output_copy_len > 0) { memcpy(output, output_copy, output_copy_len); } +#if defined(MBEDTLS_TEST_HOOKS) + MBEDTLS_TEST_MEMORY_POISON(output, output_len); +#endif + return PSA_SUCCESS; } From 96a18f2168e5c919f745104f53448e9a9ad61a6e Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 24 Nov 2023 18:26:47 +0000 Subject: [PATCH 070/211] Add explicit UNPOISON calls to memory tests These are needed to allow them to operate on buffer copies without triggering ASan use-after-poison detection. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto_memory.function | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_memory.function b/tests/suites/test_suite_psa_crypto_memory.function index 2bb0f0d7ceef..55c00921b2f1 100644 --- a/tests/suites/test_suite_psa_crypto_memory.function +++ b/tests/suites/test_suite_psa_crypto_memory.function @@ -9,6 +9,7 @@ #include "psa_crypto_invasive.h" #include "test/psa_crypto_helpers.h" +#include "test/memory.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 @@ -42,6 +43,7 @@ void copy_input(int src_len, int dst_len, psa_status_t exp_status) TEST_EQUAL(status, exp_status); if (exp_status == PSA_SUCCESS) { + MBEDTLS_TEST_MEMORY_UNPOISON(src_buffer, src_len); /* 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); } @@ -68,6 +70,7 @@ void copy_output(int src_len, int dst_len, psa_status_t exp_status) TEST_EQUAL(status, exp_status); if (exp_status == PSA_SUCCESS) { + MBEDTLS_TEST_MEMORY_UNPOISON(dst_buffer, dst_len); /* 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); } @@ -94,6 +97,7 @@ void local_input_alloc(int input_len, psa_status_t exp_status) TEST_EQUAL(status, exp_status); if (exp_status == PSA_SUCCESS) { + MBEDTLS_TEST_MEMORY_UNPOISON(input, input_len); if (input_len != 0) { TEST_ASSERT(local_input.buffer != input); } @@ -139,6 +143,8 @@ void local_input_round_trip() status = psa_crypto_local_input_alloc(input, sizeof(input), &local_input); TEST_EQUAL(status, PSA_SUCCESS); + + MBEDTLS_TEST_MEMORY_UNPOISON(input, sizeof(input)); TEST_MEMORY_COMPARE(local_input.buffer, local_input.length, input, sizeof(input)); TEST_ASSERT(local_input.buffer != input); @@ -204,6 +210,7 @@ void local_output_free(int output_len, int original_is_null, TEST_EQUAL(status, exp_status); if (exp_status == PSA_SUCCESS) { + MBEDTLS_TEST_MEMORY_UNPOISON(output, output_len); TEST_ASSERT(local_output.buffer == NULL); TEST_EQUAL(local_output.length, 0); TEST_MEMORY_COMPARE(buffer_copy_for_comparison, output_len, @@ -240,6 +247,7 @@ void local_output_round_trip() TEST_ASSERT(local_output.buffer == NULL); TEST_EQUAL(local_output.length, 0); + MBEDTLS_TEST_MEMORY_UNPOISON(output, sizeof(output)); /* Check that the buffer was correctly copied back */ TEST_MEMORY_COMPARE(output, sizeof(output), buffer_copy_for_comparison, sizeof(output)); From 96f4d4c6f38b63129c23f9a9737933a654f53d99 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 27 Nov 2023 17:32:47 +0000 Subject: [PATCH 071/211] Create memory poisoning wrapper for cipher encrypt Use the preprocessor to wrap psa_cipher_encrypt in a wrapper that poisons the input and output buffers. Signed-off-by: David Horstmann --- .../test/psa_memory_poisoning_wrappers.h | 27 +++++++++++++++++++ tests/suites/test_suite_psa_crypto.function | 4 +++ 2 files changed, 31 insertions(+) create mode 100644 tests/include/test/psa_memory_poisoning_wrappers.h diff --git a/tests/include/test/psa_memory_poisoning_wrappers.h b/tests/include/test/psa_memory_poisoning_wrappers.h new file mode 100644 index 000000000000..08234b49487e --- /dev/null +++ b/tests/include/test/psa_memory_poisoning_wrappers.h @@ -0,0 +1,27 @@ +#include "psa/crypto.h" + +#include "test/memory.h" + +psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length) +{ + MBEDTLS_TEST_MEMORY_POISON(input, input_length); + MBEDTLS_TEST_MEMORY_POISON(output, output_size); + psa_status_t status = psa_cipher_encrypt(key, + alg, + input, + input_length, + output, + output_size, + output_length); + MBEDTLS_TEST_MEMORY_UNPOISON(input, input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(output, output_size); + return status; +} + +#define psa_cipher_encrypt(...) wrap_psa_cipher_encrypt(__VA_ARGS__) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 796a62a5f143..8ebb3950b280 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -19,6 +19,10 @@ #include "test/psa_crypto_helpers.h" #include "test/psa_exercise_key.h" +#if defined(MBEDTLS_TEST_HOOKS) +#include "test/psa_memory_poisoning_wrappers.h" +#endif + /* If this comes up, it's a bug in the test code or in the test data. */ #define UNUSED 0xdeadbeef From d2ad886258e66a29a1889828df9b615d5aa47237 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 27 Nov 2023 17:43:05 +0000 Subject: [PATCH 072/211] Copy input and output in psa_cipher_encrypt() Signed-off-by: David Horstmann --- library/psa_crypto.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 60c81a572d2c..55adfa769872 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3563,6 +3563,20 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE]; size_t default_iv_length = 0; + psa_crypto_local_input_t local_input = PSA_CRYPTO_LOCAL_INPUT_INIT; + status = psa_crypto_local_input_alloc(input, input_length, &local_input); + if (status != PSA_SUCCESS) { + goto exit; + } + input = local_input.buffer; + + psa_crypto_local_output_t local_output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; + status = psa_crypto_local_output_alloc(output, output_size, &local_output); + if (status != PSA_SUCCESS) { + goto exit; + } + output = local_output.buffer; + if (!PSA_ALG_IS_CIPHER(alg)) { status = PSA_ERROR_INVALID_ARGUMENT; goto exit; @@ -3618,6 +3632,9 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, *output_length = 0; } + psa_crypto_local_input_free(&local_input); + psa_crypto_local_output_free(&local_output); + return status; } From 63f82f7c0c2ec6c7aa08a57daaf0e8c398dae796 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 28 Nov 2023 15:21:56 +0000 Subject: [PATCH 073/211] Change to use test-hook-based approach Since we are applying hooks transparently to all tests, we cannot setup and teardown test hooks in the tests. Instead we must do this in the test wrappers which are used to pre-poison and unpoison memory. Signed-off-by: David Horstmann --- library/psa_crypto.c | 28 +++++++++++++------ library/psa_crypto_invasive.h | 8 ++++++ .../test/psa_memory_poisoning_wrappers.h | 24 ++++++++++++++++ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 55adfa769872..458affd2e8bf 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -73,10 +73,6 @@ #include "mbedtls/sha512.h" #include "mbedtls/xtea.h" -#if defined(MBEDTLS_TEST_HOOKS) -#include "test/memory.h" -#endif - #define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array))) /****************************************************************/ @@ -5532,6 +5528,14 @@ psa_status_t psa_crypto_init(void) return status; } +/* Memory copying test hooks */ +#if defined(MBEDTLS_TEST_HOOKS) +void (*psa_input_pre_copy_hook)(const uint8_t *input, size_t input_len) = NULL; +void (*psa_input_post_copy_hook)(const uint8_t *input, size_t input_len) = NULL; +void (*psa_output_pre_copy_hook)(const uint8_t *output, size_t output_len) = NULL; +void (*psa_output_post_copy_hook)(const uint8_t *output, size_t output_len) = NULL; +#endif + /** Copy from an input buffer to a local copy. * * \param[in] input Pointer to input buffer. @@ -5553,7 +5557,9 @@ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, } #if defined(MBEDTLS_TEST_HOOKS) - MBEDTLS_TEST_MEMORY_UNPOISON(input, input_len); + if (psa_input_pre_copy_hook != NULL) { + psa_input_pre_copy_hook(input, input_len); + } #endif if (input_len > 0) { @@ -5561,7 +5567,9 @@ psa_status_t psa_crypto_copy_input(const uint8_t *input, size_t input_len, } #if defined(MBEDTLS_TEST_HOOKS) - MBEDTLS_TEST_MEMORY_POISON(input, input_len); + if (psa_input_post_copy_hook != NULL) { + psa_input_post_copy_hook(input, input_len); + } #endif return PSA_SUCCESS; @@ -5588,7 +5596,9 @@ psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_co } #if defined(MBEDTLS_TEST_HOOKS) - MBEDTLS_TEST_MEMORY_UNPOISON(output, output_len); + if (psa_output_pre_copy_hook != NULL) { + psa_output_pre_copy_hook(output, output_len); + } #endif if (output_copy_len > 0) { @@ -5596,7 +5606,9 @@ psa_status_t psa_crypto_copy_output(const uint8_t *output_copy, size_t output_co } #if defined(MBEDTLS_TEST_HOOKS) - MBEDTLS_TEST_MEMORY_POISON(output, output_len); + if (psa_output_post_copy_hook != NULL) { + psa_output_post_copy_hook(output, output_len); + } #endif return PSA_SUCCESS; diff --git a/library/psa_crypto_invasive.h b/library/psa_crypto_invasive.h index e7ab9b313386..a1281d14fd75 100644 --- a/library/psa_crypto_invasive.h +++ b/library/psa_crypto_invasive.h @@ -76,6 +76,14 @@ 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); +/* + * Test hooks to use for memory unpoisoning/poisoning in copy functions. + */ +extern void (*psa_input_pre_copy_hook)(const uint8_t *input, size_t input_len); +extern void (*psa_input_post_copy_hook)(const uint8_t *input, size_t input_len); +extern void (*psa_output_pre_copy_hook)(const uint8_t *output, size_t output_len); +extern void (*psa_output_post_copy_hook)(const uint8_t *output, size_t output_len); + #endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_PSA_CRYPTO_C */ #endif /* PSA_CRYPTO_INVASIVE_H */ diff --git a/tests/include/test/psa_memory_poisoning_wrappers.h b/tests/include/test/psa_memory_poisoning_wrappers.h index 08234b49487e..e1642d2c179b 100644 --- a/tests/include/test/psa_memory_poisoning_wrappers.h +++ b/tests/include/test/psa_memory_poisoning_wrappers.h @@ -2,6 +2,26 @@ #include "test/memory.h" +#include "psa_crypto_invasive.h" + +#if defined(MBEDTLS_TEST_MEMORY_CAN_POISON) + +static void setup_test_hooks(void) +{ + psa_input_pre_copy_hook = mbedtls_test_memory_unpoison; + psa_input_post_copy_hook = mbedtls_test_memory_poison; + psa_output_pre_copy_hook = mbedtls_test_memory_unpoison; + psa_output_post_copy_hook = mbedtls_test_memory_poison; +} + +static void teardown_test_hooks(void) +{ + psa_input_pre_copy_hook = NULL; + psa_input_post_copy_hook = NULL; + psa_output_pre_copy_hook = NULL; + psa_output_post_copy_hook = NULL; +} + psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *input, @@ -10,6 +30,7 @@ psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, size_t output_size, size_t *output_length) { + setup_test_hooks(); MBEDTLS_TEST_MEMORY_POISON(input, input_length); MBEDTLS_TEST_MEMORY_POISON(output, output_size); psa_status_t status = psa_cipher_encrypt(key, @@ -21,7 +42,10 @@ psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, output_length); MBEDTLS_TEST_MEMORY_UNPOISON(input, input_length); MBEDTLS_TEST_MEMORY_UNPOISON(output, output_size); + teardown_test_hooks(); return status; } #define psa_cipher_encrypt(...) wrap_psa_cipher_encrypt(__VA_ARGS__) + +#endif /* MBEDTLS_TEST_MEMORY_CAN_POISON */ From f24151a333d7ee88e5fd97bd120bed225e015d76 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 30 Nov 2023 17:55:15 +0000 Subject: [PATCH 074/211] Remove write check in driver wrappers tests This check is intended to ensure that we do not write intermediate results to the shared output buffer. This check will be made obselete by generic memory-poisoning-based testing for all functions. Signed-off-by: David Horstmann --- .../test_suite_psa_crypto_driver_wrappers.function | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function index b789908d0f5a..75f5490b9bcd 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function @@ -920,14 +920,7 @@ void cipher_entry_points(int alg_arg, int key_type_arg, output, output_buffer_size, &function_output_length); TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1); TEST_EQUAL(status, PSA_ERROR_GENERIC_ERROR); - /* - * Check that the output buffer is still in the same state. - * This will fail if the output buffer is used by the core to pass the IV - * it generated to the driver (and is not restored). - */ - for (size_t i = 0; i < output_buffer_size; i++) { - TEST_EQUAL(output[i], 0xa5); - } + mbedtls_test_driver_cipher_hooks.hits = 0; /* Test setup call, encrypt */ From 34980bd832e231a578e2fa5904c53f037bae6426 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 29 Nov 2023 17:07:13 +0000 Subject: [PATCH 075/211] Use macros to manage buffer copies Signed-off-by: David Horstmann --- library/psa_crypto.c | 57 ++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 458affd2e8bf..1531c70eda74 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -106,6 +106,44 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = if (global_data.initialized == 0) \ return PSA_ERROR_BAD_STATE; +/* Substitute an input buffer for a local copy of itself. + * Assumptions: + * - psa_status_t status exists + * - An exit label is declared + * - The name _copy is not used for the given value of + */ +#define SWAP_FOR_LOCAL_INPUT(input, length) \ + psa_crypto_local_input_t input ## _copy = PSA_CRYPTO_LOCAL_INPUT_INIT; \ + status = psa_crypto_local_input_alloc(input, length, &input ## _copy); \ + if (status != PSA_SUCCESS) { \ + goto exit; \ + } \ + input = input ## _copy.buffer; + +#define FREE_LOCAL_INPUT(input) \ + psa_crypto_local_input_free(&input ## _copy); + +/* Substitute an output buffer for a local copy of itself. + * Assumptions: + * - psa_status_t status exists + * - An exit label is declared + * - The name _copy is not used for the given value of + */ +#define SWAP_FOR_LOCAL_OUTPUT(output, length) \ + psa_crypto_local_output_t output ## _copy = PSA_CRYPTO_LOCAL_OUTPUT_INIT; \ + status = psa_crypto_local_output_alloc(output, length, &output ## _copy); \ + if (status != PSA_SUCCESS) { \ + goto exit; \ + } \ + output = output ## _copy.buffer; + +#define FREE_LOCAL_OUTPUT(output) \ + psa_status_t local_output_free_status; \ + local_output_free_status = psa_crypto_local_output_free(&output ## _copy); \ + if (local_output_free_status != PSA_SUCCESS) { \ + status = local_output_free_status; \ + } + psa_status_t mbedtls_to_psa_error(int ret) { /* Mbed TLS error codes can combine a high-level error code and a @@ -3559,19 +3597,8 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE]; size_t default_iv_length = 0; - psa_crypto_local_input_t local_input = PSA_CRYPTO_LOCAL_INPUT_INIT; - status = psa_crypto_local_input_alloc(input, input_length, &local_input); - if (status != PSA_SUCCESS) { - goto exit; - } - input = local_input.buffer; - - psa_crypto_local_output_t local_output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; - status = psa_crypto_local_output_alloc(output, output_size, &local_output); - if (status != PSA_SUCCESS) { - goto exit; - } - output = local_output.buffer; + SWAP_FOR_LOCAL_INPUT(input, input_length); + SWAP_FOR_LOCAL_OUTPUT(output, output_size); if (!PSA_ALG_IS_CIPHER(alg)) { status = PSA_ERROR_INVALID_ARGUMENT; @@ -3628,8 +3655,8 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, *output_length = 0; } - psa_crypto_local_input_free(&local_input); - psa_crypto_local_output_free(&local_output); + FREE_LOCAL_INPUT(input); + FREE_LOCAL_OUTPUT(output); return status; } From c0a2c30252bf85bca92d2158ae5f23c63187006a Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 29 Nov 2023 17:24:08 +0000 Subject: [PATCH 076/211] Add MBEDTLS_PSA_COPY_CALLER_BUFFERS config option This allows us to entirely remove copying code, where the convenience macros are used for copying. Signed-off-by: David Horstmann --- include/mbedtls/config.h | 13 +++++++++++++ library/psa_crypto.c | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index ac2146ea114b..d9e7dc2b723e 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1570,6 +1570,19 @@ */ //#define MBEDTLS_PSA_INJECT_ENTROPY +/** + * \def MBEDTLS_PSA_COPY_CALLER_BUFFERS + * + * Make local copies of buffers supplied by the callers of PSA functions. + * + * This should be enabled whenever caller-supplied buffers are owned by + * an untrusted party, for example where arguments to PSA calls are passed + * across a trust boundary. + * + * Note: Enabling this option increases memory usage and code size. + */ +#define MBEDTLS_PSA_COPY_CALLER_BUFFERS + /** * \def MBEDTLS_RSA_NO_CRT * diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 1531c70eda74..84928ecff804 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -106,6 +106,7 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = if (global_data.initialized == 0) \ return PSA_ERROR_BAD_STATE; +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) /* Substitute an input buffer for a local copy of itself. * Assumptions: * - psa_status_t status exists @@ -143,6 +144,12 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = if (local_output_free_status != PSA_SUCCESS) { \ status = local_output_free_status; \ } +#else /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ +#define SWAP_FOR_LOCAL_INPUT(input, length) +#define FREE_LOCAL_INPUT(input) +#define SWAP_FOR_LOCAL_OUTPUT(output, length) +#define FREE_LOCAL_OUTPUT(output) +#endif /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ psa_status_t mbedtls_to_psa_error(int ret) { From 2b10b3713da9abf6f72773d19a56e9972914e0bf Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 7 Dec 2023 14:09:32 +0000 Subject: [PATCH 077/211] Remove unnecessary include directory from CMake Since psa_crypto.c does not include tests/include/test/memory.h, we do not need the tests/include include path. Signed-off-by: David Horstmann --- library/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 80a323702cce..230fe15439a7 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -228,8 +228,7 @@ foreach(target IN LISTS target_libraries) PRIVATE ${MBEDTLS_DIR}/library/ PRIVATE ${thirdparty_inc} # Needed to include psa_crypto_driver_wrappers.h - ${CMAKE_CURRENT_BINARY_DIR} - ${MBEDTLS_DIR}/tests/include/) + ${CMAKE_CURRENT_BINARY_DIR}) target_compile_definitions(${target} PRIVATE ${thirdparty_def}) # Pass-through MBEDTLS_CONFIG_FILE and MBEDTLS_USER_CONFIG_FILE From 3e77e982d572680e1e3c253514735936683e5b5e Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 7 Dec 2023 18:34:49 +0000 Subject: [PATCH 078/211] Add missing license header Signed-off-by: David Horstmann --- tests/include/test/psa_memory_poisoning_wrappers.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/include/test/psa_memory_poisoning_wrappers.h b/tests/include/test/psa_memory_poisoning_wrappers.h index e1642d2c179b..3422339fd5f9 100644 --- a/tests/include/test/psa_memory_poisoning_wrappers.h +++ b/tests/include/test/psa_memory_poisoning_wrappers.h @@ -1,3 +1,8 @@ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + #include "psa/crypto.h" #include "test/memory.h" From 114d82407c30c18bc12b7d9964e1deeece4f9c88 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 7 Dec 2023 18:39:17 +0000 Subject: [PATCH 079/211] Add more information to comment on test hooks Signed-off-by: David Horstmann --- library/psa_crypto.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 84928ecff804..414ed1d8a94d 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5562,7 +5562,10 @@ psa_status_t psa_crypto_init(void) return status; } -/* Memory copying test hooks */ +/* Memory copying test hooks. These are called before input copy, after input + * copy, before output copy and after output copy, respectively. + * They are used by memory-poisoning tests to temporarily unpoison buffers + * while they are copied. */ #if defined(MBEDTLS_TEST_HOOKS) void (*psa_input_pre_copy_hook)(const uint8_t *input, size_t input_len) = NULL; void (*psa_input_post_copy_hook)(const uint8_t *input, size_t input_len) = NULL; From 0bfaee301aa8aad18b100c1eff58e35b580ccfea Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 8 Dec 2023 12:09:04 +0000 Subject: [PATCH 080/211] Add comment explaining the purpose of header Explain why we have the wrappers in psa_memory_poisoning_wrappers.h Signed-off-by: David Horstmann --- tests/include/test/psa_memory_poisoning_wrappers.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/include/test/psa_memory_poisoning_wrappers.h b/tests/include/test/psa_memory_poisoning_wrappers.h index 3422339fd5f9..5192597a35a1 100644 --- a/tests/include/test/psa_memory_poisoning_wrappers.h +++ b/tests/include/test/psa_memory_poisoning_wrappers.h @@ -1,3 +1,9 @@ +/** Memory poisoning wrappers for PSA functions. + * + * These wrappers poison the input and output buffers of each function + * before calling it, to ensure that it does not access the buffers + * except by calling the approved buffer-copying functions. + */ /* * Copyright The Mbed TLS Contributors * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later From 1f53213830208e5d6b77d5b77a95232e9b758d0c Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 8 Dec 2023 14:08:18 +0000 Subject: [PATCH 081/211] Improve FREE_LOCAL_INPUT() and FREE_LOCAL_OUTPUT() * Set swapped pointers to NULL when the buffers are freed. * Change example name to and to reduce confusion. * Document assumptions of FREE_LOCAL_ macros. * Add comment on error case in FREE_LOCAL_OUTPUT(), explaining why it's okay to mask the existing status code. Signed-off-by: David Horstmann --- library/psa_crypto.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 414ed1d8a94d..4e14cba1bb3c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -111,7 +111,7 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = * Assumptions: * - psa_status_t status exists * - An exit label is declared - * - The name _copy is not used for the given value of + * - The name _copy is not used for the given value of */ #define SWAP_FOR_LOCAL_INPUT(input, length) \ psa_crypto_local_input_t input ## _copy = PSA_CRYPTO_LOCAL_INPUT_INIT; \ @@ -121,14 +121,23 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = } \ input = input ## _copy.buffer; +/* Free the substituted input buffer copy created by SWAP_FOR_LOCAL_INPUT(). + * Note that this does not restore the pointer to the original buffer. + * Assumptions: + * - psa_crypto_local_input_t _copy exists, for the given value of + * + * - _copy was previously allocated by psa_crypto_local_input_alloc() + * - points to _copy.buffer + */ #define FREE_LOCAL_INPUT(input) \ + input = NULL; \ psa_crypto_local_input_free(&input ## _copy); /* Substitute an output buffer for a local copy of itself. * Assumptions: * - psa_status_t status exists * - An exit label is declared - * - The name _copy is not used for the given value of + * - The name _copy is not used for the given value of */ #define SWAP_FOR_LOCAL_OUTPUT(output, length) \ psa_crypto_local_output_t output ## _copy = PSA_CRYPTO_LOCAL_OUTPUT_INIT; \ @@ -138,10 +147,24 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = } \ output = output ## _copy.buffer; +/* Free the substituted output buffer copy created by SWAP_FOR_LOCAL_OUTPUT() + * after first copying back its contents to the original buffer. + * Note that this does not restore the pointer to the original buffer. + * Assumptions: + * - psa_crypto_local_output_t _copy exists, for the given value of + * + * - _copy was previously allocated by psa_crypto_local_output_alloc() + * - points to _copy.buffer + * - psa_status_t status exists + */ #define FREE_LOCAL_OUTPUT(output) \ + output = NULL; \ psa_status_t local_output_free_status; \ local_output_free_status = psa_crypto_local_output_free(&output ## _copy); \ if (local_output_free_status != PSA_SUCCESS) { \ + /* Since this error case is an internal error, it's more serious than \ + * any existing error code and so it's fine to overwrite the existing \ + * status. */ \ status = local_output_free_status; \ } #else /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ From e800aa8d34f32e1ed04f0bd0b000f1b1d303fa53 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 11 Dec 2023 15:45:20 +0000 Subject: [PATCH 082/211] Make return statuses unique in FREE_LOCAL_OUTPUT() Previously the return from psa_crypto_local_output_free() had a fixed name, which meant that multiple outputs would cause redefinitions of the same variable. Signed-off-by: David Horstmann --- library/psa_crypto.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 4e14cba1bb3c..790fb556c2bb 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -156,16 +156,18 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = * - _copy was previously allocated by psa_crypto_local_output_alloc() * - points to _copy.buffer * - psa_status_t status exists + * - The name _local_output_status is not used for the given value of + * */ #define FREE_LOCAL_OUTPUT(output) \ output = NULL; \ - psa_status_t local_output_free_status; \ - local_output_free_status = psa_crypto_local_output_free(&output ## _copy); \ - if (local_output_free_status != PSA_SUCCESS) { \ + psa_status_t output ## _local_output_status; \ + output ## _local_output_status = psa_crypto_local_output_free(&output ## _copy); \ + if (output ## _local_output_status != PSA_SUCCESS) { \ /* Since this error case is an internal error, it's more serious than \ * any existing error code and so it's fine to overwrite the existing \ * status. */ \ - status = local_output_free_status; \ + status = output ## _local_output_status; \ } #else /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ #define SWAP_FOR_LOCAL_INPUT(input, length) From f96ae67a763301865feb2a942e788f4c4c1b0beb Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 13 Dec 2023 14:03:40 +0000 Subject: [PATCH 083/211] Remove spaces around token-pasting macro operator Signed-off-by: David Horstmann --- library/psa_crypto.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 790fb556c2bb..d0dd61b32a6b 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -114,12 +114,12 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = * - The name _copy is not used for the given value of */ #define SWAP_FOR_LOCAL_INPUT(input, length) \ - psa_crypto_local_input_t input ## _copy = PSA_CRYPTO_LOCAL_INPUT_INIT; \ - status = psa_crypto_local_input_alloc(input, length, &input ## _copy); \ + psa_crypto_local_input_t input##_copy = PSA_CRYPTO_LOCAL_INPUT_INIT; \ + status = psa_crypto_local_input_alloc(input, length, &input##_copy); \ if (status != PSA_SUCCESS) { \ goto exit; \ } \ - input = input ## _copy.buffer; + input = input##_copy.buffer; /* Free the substituted input buffer copy created by SWAP_FOR_LOCAL_INPUT(). * Note that this does not restore the pointer to the original buffer. @@ -131,7 +131,7 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = */ #define FREE_LOCAL_INPUT(input) \ input = NULL; \ - psa_crypto_local_input_free(&input ## _copy); + psa_crypto_local_input_free(&input##_copy); /* Substitute an output buffer for a local copy of itself. * Assumptions: @@ -140,12 +140,12 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = * - The name _copy is not used for the given value of */ #define SWAP_FOR_LOCAL_OUTPUT(output, length) \ - psa_crypto_local_output_t output ## _copy = PSA_CRYPTO_LOCAL_OUTPUT_INIT; \ - status = psa_crypto_local_output_alloc(output, length, &output ## _copy); \ + psa_crypto_local_output_t output##_copy = PSA_CRYPTO_LOCAL_OUTPUT_INIT; \ + status = psa_crypto_local_output_alloc(output, length, &output##_copy); \ if (status != PSA_SUCCESS) { \ goto exit; \ } \ - output = output ## _copy.buffer; + output = output##_copy.buffer; /* Free the substituted output buffer copy created by SWAP_FOR_LOCAL_OUTPUT() * after first copying back its contents to the original buffer. @@ -161,13 +161,13 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = */ #define FREE_LOCAL_OUTPUT(output) \ output = NULL; \ - psa_status_t output ## _local_output_status; \ - output ## _local_output_status = psa_crypto_local_output_free(&output ## _copy); \ - if (output ## _local_output_status != PSA_SUCCESS) { \ + psa_status_t output##_local_output_status; \ + output##_local_output_status = psa_crypto_local_output_free(&output##_copy); \ + if (output##_local_output_status != PSA_SUCCESS) { \ /* Since this error case is an internal error, it's more serious than \ * any existing error code and so it's fine to overwrite the existing \ * status. */ \ - status = output ## _local_output_status; \ + status = output##_local_output_status; \ } #else /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ #define SWAP_FOR_LOCAL_INPUT(input, length) From 2b70a661182473e45e3090f54515d07fc5ad1e8b Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 13 Dec 2023 14:09:08 +0000 Subject: [PATCH 084/211] Put local output status in scope This means that a unique name is no longer needed. Signed-off-by: David Horstmann --- library/psa_crypto.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index d0dd61b32a6b..e4a6b5ac80f5 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -161,14 +161,16 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = */ #define FREE_LOCAL_OUTPUT(output) \ output = NULL; \ - psa_status_t output##_local_output_status; \ - output##_local_output_status = psa_crypto_local_output_free(&output##_copy); \ - if (output##_local_output_status != PSA_SUCCESS) { \ - /* Since this error case is an internal error, it's more serious than \ - * any existing error code and so it's fine to overwrite the existing \ - * status. */ \ - status = output##_local_output_status; \ - } + do { \ + psa_status_t local_output_status; \ + local_output_status = psa_crypto_local_output_free(&output##_copy); \ + if (local_output_status != PSA_SUCCESS) { \ + /* Since this error case is an internal error, it's more serious than \ + * any existing error code and so it's fine to overwrite the existing \ + * status. */ \ + status = local_output_status; \ + } \ + } while (0) #else /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ #define SWAP_FOR_LOCAL_INPUT(input, length) #define FREE_LOCAL_INPUT(input) From 926193a93d52208adbcceb71042eefddb27131aa Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 13 Dec 2023 15:55:25 +0000 Subject: [PATCH 085/211] Redesign local copy handling macros * Separate initialization from allocation. * Rewrite description of macros to fit the new interface. * Use a longer name to store the local copy objects, to reduce the risk of shadowing. * Use different names for the original and the copy. Append the suffix '_external' to the original argument and use the previous name for the copy. Signed-off-by: David Horstmann --- library/psa_crypto.c | 120 ++++++++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 42 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index e4a6b5ac80f5..0010c66ab3e0 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -107,63 +107,90 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = return PSA_ERROR_BAD_STATE; #if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) -/* Substitute an input buffer for a local copy of itself. + +/* Declare a local copy of an input buffer. + * + * Note: This macro must be called before any operations which may jump to + * the exit label, so that the local input copy object is safe to be freed. + * + * Assumptions: + * - input is the name of a pointer to the buffer to be copied + * - The name LOCAL_INPUT_COPY_OF_input is unused in the current scope + */ +#define LOCAL_INPUT_DECLARE(input) \ + psa_crypto_local_input_t LOCAL_INPUT_COPY_OF_##input = PSA_CRYPTO_LOCAL_INPUT_INIT; + +/* Allocate a copy of the buffer input and create a pointer with the name + * input_copy_name that points to the start of the copy. + * * Assumptions: * - psa_status_t status exists * - An exit label is declared - * - The name _copy is not used for the given value of + * - input is the name of a pointer to the buffer to be copied + * - LOCAL_INPUT_DECLARE(input) has previously been called + * - input_copy_name is a name that is not used in the current scope */ -#define SWAP_FOR_LOCAL_INPUT(input, length) \ - psa_crypto_local_input_t input##_copy = PSA_CRYPTO_LOCAL_INPUT_INIT; \ - status = psa_crypto_local_input_alloc(input, length, &input##_copy); \ +#define LOCAL_INPUT_ALLOC(input, length, input_copy_name) \ + status = psa_crypto_local_input_alloc(input, length, \ + &LOCAL_INPUT_COPY_OF_##input); \ if (status != PSA_SUCCESS) { \ goto exit; \ } \ - input = input##_copy.buffer; + const uint8_t *input_copy_name = LOCAL_INPUT_COPY_OF_##input.buffer; + +/* Free the local input copy allocated previously by LOCAL_INPUT_ALLOC() + * + * Assumptions: + * - input_copy_name is the name of the input copy created by LOCAL_INPUT_ALLOC() + * - input is the name of the original buffer that was copied + */ +#define LOCAL_INPUT_FREE(input_copy_name, input) \ + input_copy_name = NULL; \ + psa_crypto_local_input_free(&LOCAL_INPUT_COPY_OF_##input); -/* Free the substituted input buffer copy created by SWAP_FOR_LOCAL_INPUT(). - * Note that this does not restore the pointer to the original buffer. +/* Declare a local copy of an output buffer. + * + * Note: This macro must be called before any operations which may jump to + * the exit label, so that the local output copy object is safe to be freed. + * * Assumptions: - * - psa_crypto_local_input_t _copy exists, for the given value of - * - * - _copy was previously allocated by psa_crypto_local_input_alloc() - * - points to _copy.buffer + * - output is the name of a pointer to the buffer to be copied + * - The name LOCAL_OUTPUT_COPY_OF_output is unused in the current scope */ -#define FREE_LOCAL_INPUT(input) \ - input = NULL; \ - psa_crypto_local_input_free(&input##_copy); +#define LOCAL_OUTPUT_DECLARE(output) \ + psa_crypto_local_output_t LOCAL_OUTPUT_COPY_OF_##output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; -/* Substitute an output buffer for a local copy of itself. +/* Allocate a copy of the buffer output and create a pointer with the name + * output_copy_name that points to the start of the copy. + * * Assumptions: * - psa_status_t status exists * - An exit label is declared - * - The name _copy is not used for the given value of + * - output is the name of a pointer to the buffer to be copied + * - LOCAL_OUTPUT_DECLARE(output) has previously been called + * - output_copy_name is a name that is not used in the current scope */ -#define SWAP_FOR_LOCAL_OUTPUT(output, length) \ - psa_crypto_local_output_t output##_copy = PSA_CRYPTO_LOCAL_OUTPUT_INIT; \ - status = psa_crypto_local_output_alloc(output, length, &output##_copy); \ +#define LOCAL_OUTPUT_ALLOC(output, length, output_copy_name) \ + status = psa_crypto_local_output_alloc(output, length, \ + &LOCAL_OUTPUT_COPY_OF_##output); \ if (status != PSA_SUCCESS) { \ goto exit; \ } \ - output = output##_copy.buffer; + uint8_t *output_copy_name = LOCAL_OUTPUT_COPY_OF_##output.buffer; -/* Free the substituted output buffer copy created by SWAP_FOR_LOCAL_OUTPUT() +/* Free the local input copy allocated previously by LOCAL_INPUT_ALLOC() * after first copying back its contents to the original buffer. - * Note that this does not restore the pointer to the original buffer. + * * Assumptions: - * - psa_crypto_local_output_t _copy exists, for the given value of - * - * - _copy was previously allocated by psa_crypto_local_output_alloc() - * - points to _copy.buffer * - psa_status_t status exists - * - The name _local_output_status is not used for the given value of - * + * - input_copy_name is the name of the input copy created by LOCAL_INPUT_ALLOC() + * - input is the name of the original buffer that was copied */ -#define FREE_LOCAL_OUTPUT(output) \ - output = NULL; \ +#define LOCAL_OUTPUT_FREE(output_copy_name, output) \ + output_copy_name = NULL; \ do { \ psa_status_t local_output_status; \ - local_output_status = psa_crypto_local_output_free(&output##_copy); \ + local_output_status = psa_crypto_local_output_free(&LOCAL_OUTPUT_COPY_OF_##output); \ if (local_output_status != PSA_SUCCESS) { \ /* Since this error case is an internal error, it's more serious than \ * any existing error code and so it's fine to overwrite the existing \ @@ -172,10 +199,17 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = } \ } while (0) #else /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ -#define SWAP_FOR_LOCAL_INPUT(input, length) -#define FREE_LOCAL_INPUT(input) -#define SWAP_FOR_LOCAL_OUTPUT(output, length) -#define FREE_LOCAL_OUTPUT(output) +#define LOCAL_INPUT_DECLARE(input) +#define LOCAL_INPUT_ALLOC(input, length, input_copy_name) \ + const uint8_t *input_copy_name = input; +#define LOCAL_INPUT_FREE(input_copy_name, input) \ + input_copy_name = NULL; +#define LOCAL_OUTPUT_DECLARE(output) +#define LOCAL_OUTPUT_ALLOC(output, length, output_copy_name) \ + uint8_t *output_copy_name = output; +#define LOCAL_OUTPUT_FREE(output_copy_name, output) \ + output_copy_name = NULL; + #endif /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ psa_status_t mbedtls_to_psa_error(int ret) @@ -3618,9 +3652,9 @@ psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation) psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *input, + const uint8_t *input_external, size_t input_length, - uint8_t *output, + uint8_t *output_external, size_t output_size, size_t *output_length) { @@ -3631,8 +3665,10 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE]; size_t default_iv_length = 0; - SWAP_FOR_LOCAL_INPUT(input, input_length); - SWAP_FOR_LOCAL_OUTPUT(output, output_size); + LOCAL_INPUT_DECLARE(input_external); + LOCAL_INPUT_ALLOC(input_external, input_length, input); + LOCAL_OUTPUT_DECLARE(output_external); + LOCAL_OUTPUT_ALLOC(output_external, output_size, output); if (!PSA_ALG_IS_CIPHER(alg)) { status = PSA_ERROR_INVALID_ARGUMENT; @@ -3689,8 +3725,8 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, *output_length = 0; } - FREE_LOCAL_INPUT(input); - FREE_LOCAL_OUTPUT(output); + LOCAL_INPUT_FREE(input, input_external); + LOCAL_OUTPUT_FREE(output, output_external); return status; } From 8c2d029661d20b6255f30b82695e2d293d457276 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 13 Dec 2023 17:07:23 +0000 Subject: [PATCH 086/211] Move test hook setup functions into a C file Signed-off-by: David Horstmann --- .../test/psa_memory_poisoning_wrappers.h | 55 +++++++------------ tests/src/psa_memory_poisoning_wrappers.c | 53 ++++++++++++++++++ 2 files changed, 73 insertions(+), 35 deletions(-) create mode 100644 tests/src/psa_memory_poisoning_wrappers.c diff --git a/tests/include/test/psa_memory_poisoning_wrappers.h b/tests/include/test/psa_memory_poisoning_wrappers.h index 5192597a35a1..8b2dcfa04ee9 100644 --- a/tests/include/test/psa_memory_poisoning_wrappers.h +++ b/tests/include/test/psa_memory_poisoning_wrappers.h @@ -9,29 +9,28 @@ * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ +#ifndef PSA_MEMORY_POISONING_WRAPPERS_H +#define PSA_MEMORY_POISONING_WRAPPERS_H + #include "psa/crypto.h" #include "test/memory.h" -#include "psa_crypto_invasive.h" - -#if defined(MBEDTLS_TEST_MEMORY_CAN_POISON) +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) -static void setup_test_hooks(void) -{ - psa_input_pre_copy_hook = mbedtls_test_memory_unpoison; - psa_input_post_copy_hook = mbedtls_test_memory_poison; - psa_output_pre_copy_hook = mbedtls_test_memory_unpoison; - psa_output_post_copy_hook = mbedtls_test_memory_poison; -} +/** + * \brief Setup the memory poisoning test hooks used by + * psa_crypto_copy_input() and psa_crypto_copy_output() for + * memory poisoning. + */ +void mbedtls_poison_test_hooks_setup(void); -static void teardown_test_hooks(void) -{ - psa_input_pre_copy_hook = NULL; - psa_input_post_copy_hook = NULL; - psa_output_pre_copy_hook = NULL; - psa_output_post_copy_hook = NULL; -} +/** + * \brief Teardown the memory poisoning test hooks used by + * psa_crypto_copy_input() and psa_crypto_copy_output() for + * memory poisoning. + */ +void mbedtls_poison_test_hooks_teardown(void); psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, @@ -39,24 +38,10 @@ psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, size_t input_length, uint8_t *output, size_t output_size, - size_t *output_length) -{ - setup_test_hooks(); - MBEDTLS_TEST_MEMORY_POISON(input, input_length); - MBEDTLS_TEST_MEMORY_POISON(output, output_size); - psa_status_t status = psa_cipher_encrypt(key, - alg, - input, - input_length, - output, - output_size, - output_length); - MBEDTLS_TEST_MEMORY_UNPOISON(input, input_length); - MBEDTLS_TEST_MEMORY_UNPOISON(output, output_size); - teardown_test_hooks(); - return status; -} + size_t *output_length); #define psa_cipher_encrypt(...) wrap_psa_cipher_encrypt(__VA_ARGS__) -#endif /* MBEDTLS_TEST_MEMORY_CAN_POISON */ +#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_TEST_MEMORY_CAN_POISON */ + +#endif /* PSA_MEMORY_POISONING_WRAPPERS_H */ \ No newline at end of file diff --git a/tests/src/psa_memory_poisoning_wrappers.c b/tests/src/psa_memory_poisoning_wrappers.c new file mode 100644 index 000000000000..7af84dd765f6 --- /dev/null +++ b/tests/src/psa_memory_poisoning_wrappers.c @@ -0,0 +1,53 @@ +/** Helper functions for memory poisoning in tests. + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +#include "test/memory.h" + +#include "psa_crypto_invasive.h" + +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) + +void mbedtls_poison_test_hooks_setup(void) +{ + psa_input_pre_copy_hook = mbedtls_test_memory_unpoison; + psa_input_post_copy_hook = mbedtls_test_memory_poison; + psa_output_pre_copy_hook = mbedtls_test_memory_unpoison; + psa_output_post_copy_hook = mbedtls_test_memory_poison; +} + +void mbedtls_poison_test_hooks_teardown(void) +{ + psa_input_pre_copy_hook = NULL; + psa_input_post_copy_hook = NULL; + psa_output_pre_copy_hook = NULL; + psa_output_post_copy_hook = NULL; +} + +psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *input, + size_t input_length, + uint8_t *output, + size_t output_size, + size_t *output_length) +{ + mbedtls_poison_test_hooks_setup(); + MBEDTLS_TEST_MEMORY_POISON(input, input_length); + MBEDTLS_TEST_MEMORY_POISON(output, output_size); + psa_status_t status = psa_cipher_encrypt(key, + alg, + input, + input_length, + output, + output_size, + output_length); + MBEDTLS_TEST_MEMORY_UNPOISON(input, input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(output, output_size); + mbedtls_poison_test_hooks_teardown(); + return status; +} + +#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_TEST_MEMORY_CAN_POISON */ From f3c57149d1d997e5f49d50a35960631c1b299ad8 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 14 Dec 2023 14:17:04 +0000 Subject: [PATCH 087/211] Move test hook setup and teardown to helpers.c Setup and teardown test hooks during full test platform setup. Signed-off-by: David Horstmann --- tests/src/helpers.c | 12 ++++++++++++ tests/src/psa_memory_poisoning_wrappers.c | 2 -- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/src/helpers.c b/tests/src/helpers.c index 2df3ce5b907c..9d9ab08e55ff 100644 --- a/tests/src/helpers.c +++ b/tests/src/helpers.c @@ -17,6 +17,10 @@ #include #endif +#if defined(MBEDTLS_TEST_HOOKS) +#include +#endif + /*----------------------------------------------------------------------------*/ /* Static global variables */ @@ -46,6 +50,10 @@ int mbedtls_test_platform_setup(void) { int ret = 0; +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) + mbedtls_poison_test_hooks_setup(); +#endif + #if defined(MBEDTLS_PSA_INJECT_ENTROPY) /* Make sure that injected entropy is present. Otherwise * psa_crypto_init() will fail. This is not necessary for test suites @@ -66,6 +74,10 @@ int mbedtls_test_platform_setup(void) void mbedtls_test_platform_teardown(void) { +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) + mbedtls_poison_test_hooks_teardown(); +#endif + #if defined(MBEDTLS_PLATFORM_C) mbedtls_platform_teardown(&platform_ctx); #endif /* MBEDTLS_PLATFORM_C */ diff --git a/tests/src/psa_memory_poisoning_wrappers.c b/tests/src/psa_memory_poisoning_wrappers.c index 7af84dd765f6..c865d1f90868 100644 --- a/tests/src/psa_memory_poisoning_wrappers.c +++ b/tests/src/psa_memory_poisoning_wrappers.c @@ -34,7 +34,6 @@ psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, size_t output_size, size_t *output_length) { - mbedtls_poison_test_hooks_setup(); MBEDTLS_TEST_MEMORY_POISON(input, input_length); MBEDTLS_TEST_MEMORY_POISON(output, output_size); psa_status_t status = psa_cipher_encrypt(key, @@ -46,7 +45,6 @@ psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, output_length); MBEDTLS_TEST_MEMORY_UNPOISON(input, input_length); MBEDTLS_TEST_MEMORY_UNPOISON(output, output_size); - mbedtls_poison_test_hooks_teardown(); return status; } From 9c97fda0ab9e70ff8cd548abda0e1c5964ffa387 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 14 Dec 2023 14:27:50 +0000 Subject: [PATCH 088/211] Move wrapper include to psa_crypto_helpers.h This makes memory poisoning wrappers available to (almost) all tests. Signed-off-by: David Horstmann --- tests/include/test/psa_crypto_helpers.h | 4 ++++ tests/suites/test_suite_psa_crypto.function | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index 8d0f7e69d3d8..c29134a924fd 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -21,6 +21,10 @@ #include "mbedtls/psa_util.h" #endif +#if defined(MBEDTLS_TEST_HOOKS) +#include "test/psa_memory_poisoning_wrappers.h" +#endif + #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) /* Internal function for #TEST_USES_KEY_ID. Return 1 on success, 0 on failure. */ diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 8ebb3950b280..796a62a5f143 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -19,10 +19,6 @@ #include "test/psa_crypto_helpers.h" #include "test/psa_exercise_key.h" -#if defined(MBEDTLS_TEST_HOOKS) -#include "test/psa_memory_poisoning_wrappers.h" -#endif - /* If this comes up, it's a bug in the test code or in the test data. */ #define UNUSED 0xdeadbeef From 93b2dc7853e20452a444ca9ac7d9a9ee1842ca95 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 14 Dec 2023 16:14:41 +0000 Subject: [PATCH 089/211] Add note about support for buffer overlap Note that enabling MBEDTLS_PSA_COPY_CALLER_BUFFERS allows full buffer overlap support, whereas without it, overlap support is reduced to that documented in the function descriptions. Signed-off-by: David Horstmann --- include/mbedtls/config.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index d9e7dc2b723e..a8bc45ea9b3c 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1579,7 +1579,10 @@ * an untrusted party, for example where arguments to PSA calls are passed * across a trust boundary. * - * Note: Enabling this option increases memory usage and code size. + * \note Enabling this option increases memory usage and code size. + * + * \note Enabling this option enables full support for overlap of input and + * output buffers passed to PSA functions. */ #define MBEDTLS_PSA_COPY_CALLER_BUFFERS From 7cb734370a8a8adc0d80f9482126bcec51f8d8cb Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 14 Dec 2023 17:17:20 +0000 Subject: [PATCH 090/211] Add missing newline at end of file Signed-off-by: David Horstmann --- include/mbedtls/config.h | 2 +- tests/include/test/psa_memory_poisoning_wrappers.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index a8bc45ea9b3c..62d9d4baee8f 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -2243,7 +2243,7 @@ * * Uncomment to enable invasive tests. */ -//#define MBEDTLS_TEST_HOOKS +#define MBEDTLS_TEST_HOOKS /** * \def MBEDTLS_THREADING_ALT diff --git a/tests/include/test/psa_memory_poisoning_wrappers.h b/tests/include/test/psa_memory_poisoning_wrappers.h index 8b2dcfa04ee9..0052c2fae062 100644 --- a/tests/include/test/psa_memory_poisoning_wrappers.h +++ b/tests/include/test/psa_memory_poisoning_wrappers.h @@ -44,4 +44,4 @@ psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, #endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_TEST_MEMORY_CAN_POISON */ -#endif /* PSA_MEMORY_POISONING_WRAPPERS_H */ \ No newline at end of file +#endif /* PSA_MEMORY_POISONING_WRAPPERS_H */ From b80e35a54a7e2e1b23e85f09ac7b9f61130e3540 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 14 Dec 2023 18:12:47 +0000 Subject: [PATCH 091/211] Tweak the behaviour of copy handling macros Specifically: * Move the creation of the pointer to the copied buffer into the DECLARE() macro, to solve warnings about potentially skipping initialization. * Reorder the arguments of the FREE() macro - having a different order made it confusing, so keep the order the same throughout. Signed-off-by: David Horstmann --- library/psa_crypto.c | 88 +++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 41 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 0010c66ab3e0..00e4f2aa987e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -108,7 +108,8 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = #if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) -/* Declare a local copy of an input buffer. +/* Declare a local copy of an input buffer and a variable that will be used + * to store a pointer to the start of the buffer. * * Note: This macro must be called before any operations which may jump to * the exit label, so that the local input copy object is safe to be freed. @@ -116,39 +117,41 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = * Assumptions: * - input is the name of a pointer to the buffer to be copied * - The name LOCAL_INPUT_COPY_OF_input is unused in the current scope + * - input_copy_name is a name that is unused in the current scope */ -#define LOCAL_INPUT_DECLARE(input) \ - psa_crypto_local_input_t LOCAL_INPUT_COPY_OF_##input = PSA_CRYPTO_LOCAL_INPUT_INIT; +#define LOCAL_INPUT_DECLARE(input, input_copy_name) \ + psa_crypto_local_input_t LOCAL_INPUT_COPY_OF_##input = PSA_CRYPTO_LOCAL_INPUT_INIT; \ + const uint8_t *input_copy_name = NULL; -/* Allocate a copy of the buffer input and create a pointer with the name - * input_copy_name that points to the start of the copy. +/* Allocate a copy of the buffer input and set the pointer input_copy to + * point to the start of the copy. * * Assumptions: * - psa_status_t status exists * - An exit label is declared * - input is the name of a pointer to the buffer to be copied - * - LOCAL_INPUT_DECLARE(input) has previously been called - * - input_copy_name is a name that is not used in the current scope + * - LOCAL_INPUT_DECLARE(input, input_copy) has previously been called */ -#define LOCAL_INPUT_ALLOC(input, length, input_copy_name) \ +#define LOCAL_INPUT_ALLOC(input, length, input_copy) \ status = psa_crypto_local_input_alloc(input, length, \ &LOCAL_INPUT_COPY_OF_##input); \ if (status != PSA_SUCCESS) { \ goto exit; \ } \ - const uint8_t *input_copy_name = LOCAL_INPUT_COPY_OF_##input.buffer; + input_copy = LOCAL_INPUT_COPY_OF_##input.buffer; /* Free the local input copy allocated previously by LOCAL_INPUT_ALLOC() * * Assumptions: - * - input_copy_name is the name of the input copy created by LOCAL_INPUT_ALLOC() + * - input_copy is the name of the input copy pointer set by LOCAL_INPUT_ALLOC() * - input is the name of the original buffer that was copied */ -#define LOCAL_INPUT_FREE(input_copy_name, input) \ - input_copy_name = NULL; \ +#define LOCAL_INPUT_FREE(input, input_copy) \ + input_copy = NULL; \ psa_crypto_local_input_free(&LOCAL_INPUT_COPY_OF_##input); -/* Declare a local copy of an output buffer. +/* Declare a local copy of an output buffer and a variable that will be used + * to store a pointer to the start of the buffer. * * Note: This macro must be called before any operations which may jump to * the exit label, so that the local output copy object is safe to be freed. @@ -156,38 +159,39 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = * Assumptions: * - output is the name of a pointer to the buffer to be copied * - The name LOCAL_OUTPUT_COPY_OF_output is unused in the current scope + * - output_copy_name is a name that is unused in the current scope */ -#define LOCAL_OUTPUT_DECLARE(output) \ - psa_crypto_local_output_t LOCAL_OUTPUT_COPY_OF_##output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; +#define LOCAL_OUTPUT_DECLARE(output, output_copy_name) \ + psa_crypto_local_output_t LOCAL_OUTPUT_COPY_OF_##output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; \ + uint8_t *output_copy_name = NULL; -/* Allocate a copy of the buffer output and create a pointer with the name - * output_copy_name that points to the start of the copy. +/* Allocate a copy of the buffer output and set the pointer output_copy to + * point to the start of the copy. * * Assumptions: * - psa_status_t status exists * - An exit label is declared * - output is the name of a pointer to the buffer to be copied - * - LOCAL_OUTPUT_DECLARE(output) has previously been called - * - output_copy_name is a name that is not used in the current scope + * - LOCAL_OUTPUT_DECLARE(output, output_copy) has previously been called */ -#define LOCAL_OUTPUT_ALLOC(output, length, output_copy_name) \ +#define LOCAL_OUTPUT_ALLOC(output, length, output_copy) \ status = psa_crypto_local_output_alloc(output, length, \ &LOCAL_OUTPUT_COPY_OF_##output); \ if (status != PSA_SUCCESS) { \ goto exit; \ } \ - uint8_t *output_copy_name = LOCAL_OUTPUT_COPY_OF_##output.buffer; + output_copy = LOCAL_OUTPUT_COPY_OF_##output.buffer; -/* Free the local input copy allocated previously by LOCAL_INPUT_ALLOC() +/* Free the local output copy allocated previously by LOCAL_OUTPUT_ALLOC() * after first copying back its contents to the original buffer. * * Assumptions: * - psa_status_t status exists - * - input_copy_name is the name of the input copy created by LOCAL_INPUT_ALLOC() - * - input is the name of the original buffer that was copied + * - output_copy is the name of the output copy pointer set by LOCAL_OUTPUT_ALLOC() + * - output is the name of the original buffer that was copied */ -#define LOCAL_OUTPUT_FREE(output_copy_name, output) \ - output_copy_name = NULL; \ +#define LOCAL_OUTPUT_FREE(output, output_copy) \ + output_copy = NULL; \ do { \ psa_status_t local_output_status; \ local_output_status = psa_crypto_local_output_free(&LOCAL_OUTPUT_COPY_OF_##output); \ @@ -199,17 +203,18 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = } \ } while (0) #else /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ -#define LOCAL_INPUT_DECLARE(input) -#define LOCAL_INPUT_ALLOC(input, length, input_copy_name) \ - const uint8_t *input_copy_name = input; -#define LOCAL_INPUT_FREE(input_copy_name, input) \ - input_copy_name = NULL; -#define LOCAL_OUTPUT_DECLARE(output) -#define LOCAL_OUTPUT_ALLOC(output, length, output_copy_name) \ - uint8_t *output_copy_name = output; -#define LOCAL_OUTPUT_FREE(output_copy_name, output) \ - output_copy_name = NULL; - +#define LOCAL_INPUT_DECLARE(input, input_copy_name) \ + const uint8_t *input_copy_name = NULL; +#define LOCAL_INPUT_ALLOC(input, length, input_copy) \ + input_copy = input; +#define LOCAL_INPUT_FREE(input, input_copy) \ + input_copy = NULL; +#define LOCAL_OUTPUT_DECLARE(output, output_copy_name) \ + uint8_t *output_copy_name = NULL; +#define LOCAL_OUTPUT_ALLOC(output, length, output_copy) \ + output_copy = output; +#define LOCAL_OUTPUT_FREE(output, output_copy) \ + output_copy = NULL; #endif /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ psa_status_t mbedtls_to_psa_error(int ret) @@ -3665,9 +3670,10 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE]; size_t default_iv_length = 0; - LOCAL_INPUT_DECLARE(input_external); + LOCAL_INPUT_DECLARE(input_external, input); + LOCAL_OUTPUT_DECLARE(output_external, output); + LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_OUTPUT_DECLARE(output_external); LOCAL_OUTPUT_ALLOC(output_external, output_size, output); if (!PSA_ALG_IS_CIPHER(alg)) { @@ -3725,8 +3731,8 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, *output_length = 0; } - LOCAL_INPUT_FREE(input, input_external); - LOCAL_OUTPUT_FREE(output, output_external); + LOCAL_INPUT_FREE(input_external, input); + LOCAL_OUTPUT_FREE(output_external, output); return status; } From ffcc76918488a2ea456153a68a8ec8b36e0d24ea Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 15 Dec 2023 18:29:54 +0000 Subject: [PATCH 092/211] Improve guards around memory poisoning setup We should not setup or teardown test hooks when we do not have MBEDTLS_PSA_CRYPTO_C. Signed-off-by: David Horstmann --- tests/src/helpers.c | 6 ++++-- tests/src/psa_memory_poisoning_wrappers.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/src/helpers.c b/tests/src/helpers.c index 9d9ab08e55ff..41f805ed3550 100644 --- a/tests/src/helpers.c +++ b/tests/src/helpers.c @@ -50,7 +50,8 @@ int mbedtls_test_platform_setup(void) { int ret = 0; -#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \ + && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) mbedtls_poison_test_hooks_setup(); #endif @@ -74,7 +75,8 @@ int mbedtls_test_platform_setup(void) void mbedtls_test_platform_teardown(void) { -#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \ + && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) mbedtls_poison_test_hooks_teardown(); #endif diff --git a/tests/src/psa_memory_poisoning_wrappers.c b/tests/src/psa_memory_poisoning_wrappers.c index c865d1f90868..89830a596bde 100644 --- a/tests/src/psa_memory_poisoning_wrappers.c +++ b/tests/src/psa_memory_poisoning_wrappers.c @@ -8,7 +8,8 @@ #include "psa_crypto_invasive.h" -#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \ + && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) void mbedtls_poison_test_hooks_setup(void) { @@ -48,4 +49,5 @@ psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, return status; } -#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_TEST_MEMORY_CAN_POISON */ +#endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_PSA_CRYPTO_C && + MBEDTLS_TEST_MEMORY_CAN_POISON */ \ No newline at end of file From fcad4d5939bd31bb9c8fa69d3f47035f7e34c7ac Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Fri, 15 Dec 2023 19:05:40 +0000 Subject: [PATCH 093/211] Remove accidental addition of MBEDTLS_TEST_HOOKS Remove MBEDTLS_TEST_HOOKS from the default config, to which it was erroneously added. Signed-off-by: David Horstmann --- include/mbedtls/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index 62d9d4baee8f..a8bc45ea9b3c 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -2243,7 +2243,7 @@ * * Uncomment to enable invasive tests. */ -#define MBEDTLS_TEST_HOOKS +//#define MBEDTLS_TEST_HOOKS /** * \def MBEDTLS_THREADING_ALT From cb229db971f04ae6c3f034525f9d0d60280ef9dc Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 18 Dec 2023 15:30:46 +0000 Subject: [PATCH 094/211] Add extra MBEDTLS_PSA_CRYPTO_C guard for header Do not include psa_memory_poisoning_wrappers.h unless MBEDTLS_PSA_CRYPTO_C is set. Signed-off-by: David Horstmann --- tests/include/test/psa_crypto_helpers.h | 2 +- tests/src/helpers.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index c29134a924fd..55f24e0f89c4 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -21,7 +21,7 @@ #include "mbedtls/psa_util.h" #endif -#if defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) #include "test/psa_memory_poisoning_wrappers.h" #endif diff --git a/tests/src/helpers.c b/tests/src/helpers.c index 41f805ed3550..27a7a7a1524f 100644 --- a/tests/src/helpers.c +++ b/tests/src/helpers.c @@ -17,7 +17,7 @@ #include #endif -#if defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) #include #endif From 4dc176a4304d7b0a07431ff486bc53f128b8e7fe Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 18 Dec 2023 15:58:17 +0000 Subject: [PATCH 095/211] Add missing newline at end of file Signed-off-by: David Horstmann --- tests/src/psa_memory_poisoning_wrappers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/psa_memory_poisoning_wrappers.c b/tests/src/psa_memory_poisoning_wrappers.c index 89830a596bde..a53e875d4b92 100644 --- a/tests/src/psa_memory_poisoning_wrappers.c +++ b/tests/src/psa_memory_poisoning_wrappers.c @@ -50,4 +50,4 @@ psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, } #endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_PSA_CRYPTO_C && - MBEDTLS_TEST_MEMORY_CAN_POISON */ \ No newline at end of file + MBEDTLS_TEST_MEMORY_CAN_POISON */ From 823f9a9e18da6f11e273f48ad5f73f30a2a14149 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 20 Dec 2023 10:57:43 +0000 Subject: [PATCH 096/211] Invert note about buffer overlap support When MBEDTLS_PSA_COPY_CALLER_BUFFERS is disabled, it causes overlap to not be supported. Signed-off-by: David Horstmann --- include/mbedtls/config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index a8bc45ea9b3c..d48df66e5b71 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1581,8 +1581,8 @@ * * \note Enabling this option increases memory usage and code size. * - * \note Enabling this option enables full support for overlap of input and - * output buffers passed to PSA functions. + * \note Disabling this option causes overlap of input and output buffers + * not to be supported by PSA functions. */ #define MBEDTLS_PSA_COPY_CALLER_BUFFERS From dda52ae1c6521f6079a7edfda1f49c5acaaabc8a Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 20 Dec 2023 11:10:16 +0000 Subject: [PATCH 097/211] Add all.sh coponent to test with copying disabled Signed-off-by: David Horstmann --- tests/scripts/all.sh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index aae020976d61..02513e903ab7 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -922,6 +922,17 @@ component_test_psa_crypto_key_id_encodes_owner () { make test } +component_test_no_psa_copy_caller_buffers () { + msg "build: full config - MBEDTLS_PSA_COPY_CALLER_BUFFERS, cmake, gcc, ASan" + scripts/config.py full + scripts/config.py unset MBEDTLS_PSA_COPY_CALLER_BUFFERS + CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . + make + + msg "test: full config - MBEDTLS_PSA_COPY_CALLER_BUFFERS, cmake, gcc, ASan" + make test +} + # check_renamed_symbols HEADER LIB # Check that if HEADER contains '#define MACRO ...' then MACRO is not a symbol # name is LIB. From 5d05b47844c935e34eb7a07185113093b2fc115c Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 20 Dec 2023 11:26:40 +0000 Subject: [PATCH 098/211] Only poison memory when buffer copying is enabled Make sure that we don't enable memory poisoning when MBEDTLS_PSA_COPY_CALLER_BUFFERS is disabled. Signed-off-by: David Horstmann --- tests/include/test/psa_crypto_helpers.h | 3 ++- tests/src/helpers.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index 55f24e0f89c4..18d46d8b2bed 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -21,7 +21,8 @@ #include "mbedtls/psa_util.h" #endif -#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) +#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \ + && defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) #include "test/psa_memory_poisoning_wrappers.h" #endif diff --git a/tests/src/helpers.c b/tests/src/helpers.c index 27a7a7a1524f..fd7b548d112b 100644 --- a/tests/src/helpers.c +++ b/tests/src/helpers.c @@ -51,6 +51,7 @@ int mbedtls_test_platform_setup(void) int ret = 0; #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \ + && defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) \ && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) mbedtls_poison_test_hooks_setup(); #endif @@ -76,6 +77,7 @@ int mbedtls_test_platform_setup(void) void mbedtls_test_platform_teardown(void) { #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \ + && defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) \ && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) mbedtls_poison_test_hooks_teardown(); #endif From 3ce3e7a193f664bbc54298dea04a3164e54d4616 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 20 Dec 2023 15:18:18 +0000 Subject: [PATCH 099/211] Add new config option to generated files Add MBEDTLS_PSA_COPY_CALLER_BUFFERS to query_config.c, version_features.c and mbedTLS.vcxproj via their respective scripts. Signed-off-by: David Horstmann --- library/version_features.c | 3 +++ programs/test/query_config.c | 12 ++++++++++++ visualc/VS2010/mbedTLS.vcxproj | 2 ++ 3 files changed, 17 insertions(+) diff --git a/library/version_features.c b/library/version_features.c index 779325744b1b..170e7fae847c 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -456,6 +456,9 @@ static const char * const features[] = { #if defined(MBEDTLS_PSA_INJECT_ENTROPY) "MBEDTLS_PSA_INJECT_ENTROPY", #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + "MBEDTLS_PSA_COPY_CALLER_BUFFERS", +#endif /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ #if defined(MBEDTLS_RSA_NO_CRT) "MBEDTLS_RSA_NO_CRT", #endif /* MBEDTLS_RSA_NO_CRT */ diff --git a/programs/test/query_config.c b/programs/test/query_config.c index 859d824f84d5..cd798f7c7d45 100644 --- a/programs/test/query_config.c +++ b/programs/test/query_config.c @@ -1296,6 +1296,14 @@ int query_config(const char *config) } #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + if( strcmp( "MBEDTLS_PSA_COPY_CALLER_BUFFERS", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_COPY_CALLER_BUFFERS ); + return( 0 ); + } +#endif /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ + #if defined(MBEDTLS_RSA_NO_CRT) if( strcmp( "MBEDTLS_RSA_NO_CRT", config ) == 0 ) { @@ -3458,6 +3466,10 @@ void list_config(void) OUTPUT_MACRO_NAME_VALUE(MBEDTLS_PSA_INJECT_ENTROPY); #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + OUTPUT_MACRO_NAME_VALUE(MBEDTLS_PSA_COPY_CALLER_BUFFERS); +#endif /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ + #if defined(MBEDTLS_RSA_NO_CRT) OUTPUT_MACRO_NAME_VALUE(MBEDTLS_RSA_NO_CRT); #endif /* MBEDTLS_RSA_NO_CRT */ diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index ccabcfd3dfbf..1ffc1f6e0557 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -247,6 +247,7 @@ + @@ -390,6 +391,7 @@ + From cedb112359a3e431a772d510dfd51f980b0d680b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 22 Nov 2023 19:24:31 +0100 Subject: [PATCH 100/211] Python module to parse function declarations from a header file Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/c_parsing_helper.py | 127 ++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 scripts/mbedtls_dev/c_parsing_helper.py diff --git a/scripts/mbedtls_dev/c_parsing_helper.py b/scripts/mbedtls_dev/c_parsing_helper.py new file mode 100644 index 000000000000..3bb6f0405e87 --- /dev/null +++ b/scripts/mbedtls_dev/c_parsing_helper.py @@ -0,0 +1,127 @@ +"""Helper functions to parse C code in heavily constrained scenarios. + +Currently supported functionality: + +* read_function_declarations: read function declarations from a header file. +""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +import re +from typing import Dict, Iterable, Iterator, List, Optional, Tuple + + +class ArgumentInfo: + """Information about an argument to an API function.""" + #pylint: disable=too-few-public-methods + + _KEYWORDS = [ + 'const', 'register', 'restrict', + 'int', 'long', 'short', 'signed', 'unsigned', + ] + _DECLARATION_RE = re.compile( + r'(?P\w[\w\s*]*?)\s*' + + r'(?!(?:' + r'|'.join(_KEYWORDS) + r'))(?P\b\w+\b)?' + + r'\s*(?P\[[^][]*\])?\Z', + re.A | re.S) + + @classmethod + def normalize_type(cls, typ: str) -> str: + """Normalize whitespace in a type.""" + typ = re.sub(r'\s+', r' ', typ) + typ = re.sub(r'\s*\*', r' *', typ) + return typ + + def __init__(self, decl: str) -> None: + self.decl = decl.strip() + m = self._DECLARATION_RE.match(self.decl) + if not m: + raise ValueError(self.decl) + self.type = self.normalize_type(m.group('type')) #type: str + self.name = m.group('name') #type: Optional[str] + self.suffix = m.group('suffix') if m.group('suffix') else '' #type: str + + +class FunctionInfo: + """Information about an API function.""" + #pylint: disable=too-few-public-methods + + # Regex matching the declaration of a function that returns void. + VOID_RE = re.compile(r'\s*\bvoid\s*\Z', re.A) + + def __init__(self, #pylint: disable=too-many-arguments + filename: str, + line_number: int, + qualifiers: Iterable[str], + return_type: str, + name: str, + arguments: List[str]) -> None: + self.filename = filename + self.line_number = line_number + self.qualifiers = frozenset(qualifiers) + self.return_type = return_type + self.name = name + self.arguments = [ArgumentInfo(arg) for arg in arguments] + + def returns_void(self) -> bool: + """Whether the function returns void.""" + return bool(self.VOID_RE.search(self.return_type)) + + +# Match one C comment. +# Note that we match both comment types, so things like // in a /*...*/ +# comment are handled correctly. +_C_COMMENT_RE = re.compile(r'//[^n]*|/\*.*?\*/', re.S) +_NOT_NEWLINES_RE = re.compile(r'[^\n]+') + +def read_logical_lines(filename: str) -> Iterator[Tuple[int, str]]: + """Read logical lines from a file. + + Logical lines are one or more physical line, with balanced parentheses. + """ + with open(filename, encoding='utf-8') as inp: + content = inp.read() + # Strip comments, but keep newlines for line numbering + content = re.sub(_C_COMMENT_RE, + lambda m: re.sub(_NOT_NEWLINES_RE, "", m.group(0)), + content) + lines = enumerate(content.splitlines(), 1) + for line_number, line in lines: + # Read a logical line, containing balanced parentheses. + # We assume that parentheses are balanced (this should be ok + # since comments have been stripped), otherwise there will be + # a gigantic logical line at the end. + paren_level = line.count('(') - line.count(')') + while paren_level > 0: + _, more = next(lines) #pylint: disable=stop-iteration-return + paren_level += more.count('(') - more.count(')') + line += '\n' + more + yield line_number, line + +_C_FUNCTION_DECLARATION_RE = re.compile( + r'(?P(?:(?:extern|inline|static)\b\s*)*)' + r'(?P\w[\w\s*]*?)\s*' + + r'\b(?P\w+)' + + r'\s*\((?P.*)\)\s*;', + re.A | re.S) + +def read_function_declarations(functions: Dict[str, FunctionInfo], + filename: str) -> None: + """Collect function declarations from a C header file.""" + for line_number, line in read_logical_lines(filename): + m = _C_FUNCTION_DECLARATION_RE.match(line) + if not m: + continue + qualifiers = m.group('qualifiers').split() + return_type = m.group('return_type') + name = m.group('name') + arguments = m.group('arguments').split(',') + if len(arguments) == 1 and re.match(FunctionInfo.VOID_RE, arguments[0]): + arguments = [] + # Note: we replace any existing declaration for the same name. + functions[name] = FunctionInfo(filename, line_number, + qualifiers, + return_type, + name, + arguments) From 15d32bb60f178a55905e30e21a4ddafe2a9bd76c Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 22 Nov 2023 19:24:59 +0100 Subject: [PATCH 101/211] C function wrapper generator The Base class generates trivial wrappers that just call the underlying function. It is meant as a base class to construct useful wrapper generators. The Logging class generates wrappers that can log the inputs and outputs to a function. Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/c_wrapper_generator.py | 459 +++++++++++++++++++++ 1 file changed, 459 insertions(+) create mode 100644 scripts/mbedtls_dev/c_wrapper_generator.py diff --git a/scripts/mbedtls_dev/c_wrapper_generator.py b/scripts/mbedtls_dev/c_wrapper_generator.py new file mode 100644 index 000000000000..26da9b2f261f --- /dev/null +++ b/scripts/mbedtls_dev/c_wrapper_generator.py @@ -0,0 +1,459 @@ +"""Generate C wrapper functions. +""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +import os +import re +import sys +import typing +from typing import Dict, List, Optional, Tuple + +from .c_parsing_helper import ArgumentInfo, FunctionInfo +from . import typing_util + + +def c_declare(prefix: str, name: str, suffix: str) -> str: + """Format a declaration of name with the given type prefix and suffix.""" + if not prefix.endswith('*'): + prefix += ' ' + return prefix + name + suffix + + +WrapperInfo = typing.NamedTuple('WrapperInfo', [ + ('argument_names', List[str]), + ('guard', Optional[str]), + ('wrapper_name', str), +]) + + +class Base: + """Generate a C source file containing wrapper functions.""" + + # This class is designed to have many methods potentially overloaded. + # Tell pylint not to complain about methods that have unused arguments: + # child classes are likely to override those methods and need the + # arguments in question. + #pylint: disable=no-self-use,unused-argument + + # Prefix prepended to the function's name to form the wrapper name. + _WRAPPER_NAME_PREFIX = '' + # Suffix appended to the function's name to form the wrapper name. + _WRAPPER_NAME_SUFFIX = '_wrap' + + # Functions with one of these qualifiers are skipped. + _SKIP_FUNCTION_WITH_QUALIFIERS = frozenset(['inline', 'static']) + + def __init__(self): + """Construct a wrapper generator object. + """ + self.program_name = os.path.basename(sys.argv[0]) + # To be populated in a derived class + self.functions = {} #type: Dict[str, FunctionInfo] + # Preprocessor symbol used as a guard against multiple inclusion in the + # header. Must be set before writing output to a header. + # Not used when writing .c output. + self.header_guard = None #type: Optional[str] + + def _write_prologue(self, out: typing_util.Writable, header: bool) -> None: + """Write the prologue of a C file. + + This includes a description comment and some include directives. + """ + out.write("""/* Automatically generated by {}, do not edit! */ + +/* Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ +""" + .format(self.program_name)) + if header: + out.write(""" +#ifndef {guard} +#define {guard} + +#ifdef __cplusplus +extern "C" {{ +#endif +""" + .format(guard=self.header_guard)) + out.write(""" +#include +""") + + def _write_epilogue(self, out: typing_util.Writable, header: bool) -> None: + """Write the epilogue of a C file. + """ + if header: + out.write(""" +#ifdef __cplusplus +}} +#endif + +#endif /* {guard} */ +""" + .format(guard=self.header_guard)) + out.write(""" +/* End of automatically generated file. */ +""") + + def _wrapper_function_name(self, original_name: str) -> str: + """The name of the wrapper function. + + By default, this adds a suffix. + """ + return (self._WRAPPER_NAME_PREFIX + + original_name + + self._WRAPPER_NAME_SUFFIX) + + def _wrapper_declaration_start(self, + function: FunctionInfo, + wrapper_name: str) -> str: + """The beginning of the wrapper function declaration. + + This ends just before the opening parenthesis of the argument list. + + This is a string containing at least the return type and the + function name. It may start with additional qualifiers or attributes + such as `static`, `__attribute__((...))`, etc. + """ + return c_declare(function.return_type, wrapper_name, '') + + def _argument_name(self, + function_name: str, + num: int, + arg: ArgumentInfo) -> str: + """Name to use for the given argument in the wrapper function. + + Argument numbers count from 0. + """ + name = 'arg' + str(num) + if arg.name: + name += '_' + arg.name + return name + + def _wrapper_declaration_argument(self, + function_name: str, + num: int, name: str, + arg: ArgumentInfo) -> str: + """One argument definition in the wrapper function declaration. + + Argument numbers count from 0. + """ + return c_declare(arg.type, name, arg.suffix) + + def _underlying_function_name(self, function: FunctionInfo) -> str: + """The name of the underlying function. + + By default, this is the name of the wrapped function. + """ + return function.name + + def _return_variable_name(self, function: FunctionInfo) -> str: + """The name of the variable that will contain the return value.""" + return 'retval' + + def _write_function_call(self, out: typing_util.Writable, + function: FunctionInfo, + argument_names: List[str]) -> None: + """Write the call to the underlying function. + """ + # Note that the function name is in parentheses, to avoid calling + # a function-like macro with the same name, since in typical usage + # there is a function-like macro with the same name which is the + # wrapper. + call = '({})({})'.format(self._underlying_function_name(function), + ', '.join(argument_names)) + if function.returns_void(): + out.write(' {};\n'.format(call)) + else: + ret_name = self._return_variable_name(function) + ret_decl = c_declare(function.return_type, ret_name, '') + out.write(' {} = {};\n'.format(ret_decl, call)) + + def _write_function_return(self, out: typing_util.Writable, + function: FunctionInfo, + if_void: bool = False) -> None: + """Write a return statement. + + If the function returns void, only write a statement if if_void is true. + """ + if function.returns_void(): + if if_void: + out.write(' return;\n') + else: + ret_name = self._return_variable_name(function) + out.write(' return {};\n'.format(ret_name)) + + def _write_function_body(self, out: typing_util.Writable, + function: FunctionInfo, + argument_names: List[str]) -> None: + """Write the body of the wrapper code for the specified function. + """ + self._write_function_call(out, function, argument_names) + self._write_function_return(out, function) + + def _skip_function(self, function: FunctionInfo) -> bool: + """Whether to skip this function. + + By default, static or inline functions are skipped. + """ + if not self._SKIP_FUNCTION_WITH_QUALIFIERS.isdisjoint(function.qualifiers): + return True + return False + + _FUNCTION_GUARDS = { + } #type: Dict[str, str] + + def _function_guard(self, function: FunctionInfo) -> Optional[str]: + """A preprocessor condition for this function. + + The wrapper will be guarded with `#if` on this condition, if not None. + """ + return self._FUNCTION_GUARDS.get(function.name) + + def _wrapper_info(self, function: FunctionInfo) -> Optional[WrapperInfo]: + """Information about the wrapper for one function. + + Return None if the function should be skipped. + """ + if self._skip_function(function): + return None + argument_names = [self._argument_name(function.name, num, arg) + for num, arg in enumerate(function.arguments)] + return WrapperInfo( + argument_names=argument_names, + guard=self._function_guard(function), + wrapper_name=self._wrapper_function_name(function.name), + ) + + def _write_function_prototype(self, out: typing_util.Writable, + function: FunctionInfo, + wrapper: WrapperInfo, + header: bool) -> None: + """Write the prototype of a wrapper function. + + If header is true, write a function declaration, with a semicolon at + the end. Otherwise just write the prototype, intended to be followed + by the function's body. + """ + declaration_start = self._wrapper_declaration_start(function, + wrapper.wrapper_name) + arg_indent = ' ' + terminator = ';\n' if header else '\n' + if function.arguments: + out.write(declaration_start + '(\n') + for num in range(len(function.arguments)): + arg_def = self._wrapper_declaration_argument( + function.name, + num, wrapper.argument_names[num], function.arguments[num]) + arg_terminator = \ + (')' + terminator if num == len(function.arguments) - 1 else + ',\n') + out.write(arg_indent + arg_def + arg_terminator) + else: + out.write(declaration_start + '(void)' + terminator) + + def _write_c_function(self, out: typing_util.Writable, + function: FunctionInfo) -> None: + """Write wrapper code for one function. + + Do nothing if the function is skipped. + """ + wrapper = self._wrapper_info(function) + if wrapper is None: + return + out.write(""" +/* Wrapper for {} */ +""" + .format(function.name)) + if wrapper.guard is not None: + out.write('#if {}\n'.format(wrapper.guard)) + self._write_function_prototype(out, function, wrapper, False) + out.write('{\n') + self._write_function_body(out, function, wrapper.argument_names) + out.write('}\n') + if wrapper.guard is not None: + out.write('#endif /* {} */\n'.format(wrapper.guard)) + + def _write_h_function(self, out: typing_util.Writable, + function: FunctionInfo, + wrapper: WrapperInfo) -> None: + """Write the declaration of one wrapper function. + """ + out.write('\n') + if wrapper.guard is not None: + out.write('#if {}\n'.format(wrapper.guard)) + self._write_function_prototype(out, function, wrapper, True) + if wrapper.guard is not None: + out.write('#endif /* {} */\n'.format(wrapper.guard)) + + def _write_h_macro(self, out: typing_util.Writable, + function: FunctionInfo, + wrapper: WrapperInfo) -> None: + """Write the macro definition for one wrapper. + """ + arg_list = ', '.join(wrapper.argument_names) + out.write('#define {function_name}({args}) \\\n {wrapper_name}({args})\n' + .format(function_name=function.name, + wrapper_name=wrapper.wrapper_name, + args=arg_list)) + + def write_c_file(self, filename: str) -> None: + """Output a whole C file containing function wrapper definitions.""" + with open(filename, 'w', encoding='utf-8') as out: + self._write_prologue(out, False) + for name in sorted(self.functions): + self._write_c_function(out, self.functions[name]) + self._write_epilogue(out, False) + + def _header_guard_from_file_name(self, filename: str) -> str: + """Preprocessor symbol used as a guard against multiple inclusion.""" + # Heuristic to strip irrelevant leading directories + filename = re.sub(r'.*include[\\/]', r'', filename) + return re.sub(r'[^0-9A-Za-z]', r'_', filename, re.A).upper() + + def write_h_file(self, filename: str) -> None: + """Output a header file with function wrapper declarations and macro definitions.""" + self.header_guard = self._header_guard_from_file_name(filename) + with open(filename, 'w', encoding='utf-8') as out: + self._write_prologue(out, True) + for name in sorted(self.functions.keys()): + function = self.functions[name] + wrapper = self._wrapper_info(function) + if wrapper is None: + continue + self._write_h_function(out, function, wrapper) + self._write_h_macro(out, function, wrapper) + self._write_epilogue(out, True) + + +class UnknownTypeForPrintf(Exception): + """Exception raised when attempting to generate code that logs a value of an unknown type.""" + + def __init__(self, typ: str) -> None: + super().__init__("Unknown type for printf format generation: " + typ) + + +class Logging(Base): + """Generate wrapper functions that log the inputs and outputs.""" + + def __init__(self) -> None: + """Construct a wrapper generator including logging of inputs and outputs. + + Log to stdout by default. Call `set_stream` to change this. + """ + super().__init__() + self.stream = 'stdout' + + def set_stream(self, stream: str) -> None: + """Set the stdio stream to log to. + + Call this method before calling `write_c_output` or `write_h_output`. + """ + self.stream = stream + + def _write_prologue(self, out: typing_util.Writable, header: bool) -> None: + super()._write_prologue(out, header) + if not header: + out.write(""" +#if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_TEST_HOOKS) +#include +#include +#include // for MBEDTLS_PRINTF_SIZET +#include // for mbedtls_fprintf +#endif /* defined(MBEDTLS_FS_IO) && defined(MBEDTLS_TEST_HOOKS) */ +""") + + _PRINTF_SIMPLE_FORMAT = { + 'int': '%d', + 'long': '%ld', + 'long long': '%lld', + 'size_t': '%"MBEDTLS_PRINTF_SIZET"', + 'unsigned': '0x%08x', + 'unsigned int': '0x%08x', + 'unsigned long': '0x%08lx', + 'unsigned long long': '0x%016llx', + } + + def _printf_simple_format(self, typ: str) -> Optional[str]: + """Use this printf format for a value of typ. + + Return None if values of typ need more complex handling. + """ + return self._PRINTF_SIMPLE_FORMAT.get(typ) + + _PRINTF_TYPE_CAST = { + 'int32_t': 'int', + 'uint32_t': 'unsigned', + 'uint64_t': 'unsigned long long', + } #type: Dict[str, str] + + def _printf_type_cast(self, typ: str) -> Optional[str]: + """Cast values of typ to this type before passing them to printf. + + Return None if values of the given type do not need a cast. + """ + return self._PRINTF_TYPE_CAST.get(typ) + + _POINTER_TYPE_RE = re.compile(r'\s*\*\Z') + + def _printf_parameters(self, typ: str, var: str) -> Tuple[str, List[str]]: + """The printf format and arguments for a value of type typ stored in var. + """ + expr = var + base_type = typ + # For outputs via a pointer, get the value that has been written. + # Note: we don't support pointers to pointers here. + pointer_match = self._POINTER_TYPE_RE.search(base_type) + if pointer_match: + base_type = base_type[:pointer_match.start(0)] + expr = '*({})'.format(expr) + # Maybe cast the value to a standard type. + cast_to = self._printf_type_cast(base_type) + if cast_to is not None: + expr = '({}) {}'.format(cast_to, expr) + base_type = cast_to + # Try standard types. + fmt = self._printf_simple_format(base_type) + if fmt is not None: + return '{}={}'.format(var, fmt), [expr] + raise UnknownTypeForPrintf(typ) + + def _write_function_logging(self, out: typing_util.Writable, + function: FunctionInfo, + argument_names: List[str]) -> None: + """Write code to log the function's inputs and outputs.""" + formats, values = '%s', ['"' + function.name + '"'] + for arg_info, arg_name in zip(function.arguments, argument_names): + fmt, vals = self._printf_parameters(arg_info.type, arg_name) + if fmt: + formats += ' ' + fmt + values += vals + if not function.returns_void(): + ret_name = self._return_variable_name(function) + fmt, vals = self._printf_parameters(function.return_type, ret_name) + if fmt: + formats += ' ' + fmt + values += vals + out.write("""\ +#if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_TEST_HOOKS) + if ({stream}) {{ + mbedtls_fprintf({stream}, "{formats}\\n", + {values}); + }} +#endif /* defined(MBEDTLS_FS_IO) && defined(MBEDTLS_TEST_HOOKS) */ +""" + .format(stream=self.stream, + formats=formats, + values=', '.join(values))) + + def _write_function_body(self, out: typing_util.Writable, + function: FunctionInfo, + argument_names: List[str]) -> None: + """Write the body of the wrapper code for the specified function. + """ + self._write_function_call(out, function, argument_names) + self._write_function_logging(out, function, argument_names) + self._write_function_return(out, function) From 61a852216e85d8ccbd297b37c79f56d16cb1bfd0 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 23 Nov 2023 14:12:29 +0100 Subject: [PATCH 102/211] Guard the macro definition It doesn't make sense to define a macro expanding to a non-existent function. Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/c_wrapper_generator.py | 46 +++++++++++++--------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/scripts/mbedtls_dev/c_wrapper_generator.py b/scripts/mbedtls_dev/c_wrapper_generator.py index 26da9b2f261f..de99ddb9ae1b 100644 --- a/scripts/mbedtls_dev/c_wrapper_generator.py +++ b/scripts/mbedtls_dev/c_wrapper_generator.py @@ -277,21 +277,16 @@ def _write_c_function(self, out: typing_util.Writable, if wrapper.guard is not None: out.write('#endif /* {} */\n'.format(wrapper.guard)) - def _write_h_function(self, out: typing_util.Writable, - function: FunctionInfo, - wrapper: WrapperInfo) -> None: + def _write_h_function_declaration(self, out: typing_util.Writable, + function: FunctionInfo, + wrapper: WrapperInfo) -> None: """Write the declaration of one wrapper function. """ - out.write('\n') - if wrapper.guard is not None: - out.write('#if {}\n'.format(wrapper.guard)) self._write_function_prototype(out, function, wrapper, True) - if wrapper.guard is not None: - out.write('#endif /* {} */\n'.format(wrapper.guard)) - def _write_h_macro(self, out: typing_util.Writable, - function: FunctionInfo, - wrapper: WrapperInfo) -> None: + def _write_h_macro_definition(self, out: typing_util.Writable, + function: FunctionInfo, + wrapper: WrapperInfo) -> None: """Write the macro definition for one wrapper. """ arg_list = ', '.join(wrapper.argument_names) @@ -300,6 +295,26 @@ def _write_h_macro(self, out: typing_util.Writable, wrapper_name=wrapper.wrapper_name, args=arg_list)) + def _write_h_function(self, out: typing_util.Writable, + function: FunctionInfo) -> None: + """Write the complete header content for one wrapper. + + This is the declaration of the wrapper function, and the + definition of a function-like macro that calls the wrapper function. + + Do nothing if the function is skipped. + """ + wrapper = self._wrapper_info(function) + if wrapper is None: + return + out.write('\n') + if wrapper.guard is not None: + out.write('#if {}\n'.format(wrapper.guard)) + self._write_h_function_declaration(out, function, wrapper) + self._write_h_macro_definition(out, function, wrapper) + if wrapper.guard is not None: + out.write('#endif /* {} */\n'.format(wrapper.guard)) + def write_c_file(self, filename: str) -> None: """Output a whole C file containing function wrapper definitions.""" with open(filename, 'w', encoding='utf-8') as out: @@ -319,13 +334,8 @@ def write_h_file(self, filename: str) -> None: self.header_guard = self._header_guard_from_file_name(filename) with open(filename, 'w', encoding='utf-8') as out: self._write_prologue(out, True) - for name in sorted(self.functions.keys()): - function = self.functions[name] - wrapper = self._wrapper_info(function) - if wrapper is None: - continue - self._write_h_function(out, function, wrapper) - self._write_h_macro(out, function, wrapper) + for name in sorted(self.functions): + self._write_h_function(out, self.functions[name]) self._write_epilogue(out, True) From 8519dc9c7eefee20b54cf37cf7c16c001048fba3 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 16:38:17 +0100 Subject: [PATCH 103/211] PSA wrapper generator The new script `tests/scripts/generate_psa_wrappers.py` generates the implementation of wrapper functions for PSA API functions, as well as a header that defines macros that redirect calls to the wrapper functions. By default, the wrapper functions just call the underlying library function. With `--log`, the wrapper functions log the arguments and return values. This commit only introduces the new script. Subsequent commits will integrate the wrappers in the build. Signed-off-by: Gilles Peskine --- tests/scripts/generate_psa_wrappers.py | 159 +++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100755 tests/scripts/generate_psa_wrappers.py diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py new file mode 100755 index 000000000000..9bb6eb758b32 --- /dev/null +++ b/tests/scripts/generate_psa_wrappers.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 +"""Generate wrapper functions for PSA function calls. +""" + +# Copyright The Mbed TLS Contributors +# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + +import argparse +import os +from typing import List, Tuple + +import scripts_path #pylint: disable=unused-import +from mbedtls_dev import build_tree +from mbedtls_dev import c_parsing_helper +from mbedtls_dev import c_wrapper_generator +from mbedtls_dev import typing_util + + +class PSAWrapperGenerator(c_wrapper_generator.Base): + """Generate a C source file containing wrapper functions for PSA Crypto API calls.""" + + _CPP_GUARDS = 'defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS)' + _WRAPPER_NAME_PREFIX = 'mbedtls_test_wrap_' + _WRAPPER_NAME_SUFFIX = '' + + def gather_data(self) -> None: + root_dir = build_tree.guess_mbedtls_root() + for header_name in ['crypto.h', 'crypto_extra.h']: + header_path = os.path.join(root_dir, 'include', 'psa', header_name) + c_parsing_helper.read_function_declarations(self.functions, header_path) + + _SKIP_FUNCTIONS = frozenset([ + 'mbedtls_psa_external_get_random', # not a library function + 'psa_get_key_domain_parameters', # client-side function + 'psa_get_key_slot_number', # client-side function + 'psa_key_derivation_verify_bytes', # not implemented yet + 'psa_key_derivation_verify_key', # not implemented yet + 'psa_set_key_domain_parameters', # client-side function + ]) + + def _skip_function(self, function: c_wrapper_generator.FunctionInfo) -> bool: + if function.return_type != 'psa_status_t': + return True + if function.name in self._SKIP_FUNCTIONS: + return True + return False + + # PAKE stuff: not implemented yet + _PAKE_STUFF = frozenset([ + 'psa_crypto_driver_pake_inputs_t *', + 'psa_pake_cipher_suite_t *', + ]) + + def _return_variable_name(self, + function: c_wrapper_generator.FunctionInfo) -> str: + """The name of the variable that will contain the return value.""" + if function.return_type == 'psa_status_t': + return 'status' + return super()._return_variable_name(function) + + _FUNCTION_GUARDS = c_wrapper_generator.Base._FUNCTION_GUARDS.copy() \ + #pylint: disable=protected-access + _FUNCTION_GUARDS.update({ + 'mbedtls_psa_register_se_key': 'defined(MBEDTLS_PSA_CRYPTO_SE_C)', + 'mbedtls_psa_inject_entropy': 'defined(MBEDTLS_PSA_INJECT_ENTROPY)', + 'mbedtls_psa_external_get_random': 'defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)', + 'mbedtls_psa_platform_get_builtin_key': 'defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)', + }) + + def _write_prologue(self, out: typing_util.Writable, header: bool) -> None: + super()._write_prologue(out, header) + out.write(""" +#if {} + +#include + +#include +#include +""" + .format(self._CPP_GUARDS)) + + def _write_epilogue(self, out: typing_util.Writable, header: bool) -> None: + out.write(""" +#endif /* {} */ +""" + .format(self._CPP_GUARDS)) + super()._write_epilogue(out, header) + + +class PSALoggingWrapperGenerator(PSAWrapperGenerator, c_wrapper_generator.Logging): + """Generate a C source file containing wrapper functions that log PSA Crypto API calls.""" + + def __init__(self, stream: str) -> None: + super().__init__() + self.set_stream(stream) + + _PRINTF_TYPE_CAST = c_wrapper_generator.Logging._PRINTF_TYPE_CAST.copy() + _PRINTF_TYPE_CAST.update({ + 'mbedtls_svc_key_id_t': 'unsigned', + 'psa_algorithm_t': 'unsigned', + 'psa_drv_slot_number_t': 'unsigned long long', + 'psa_key_derivation_step_t': 'int', + 'psa_key_id_t': 'unsigned', + 'psa_key_slot_number_t': 'unsigned long long', + 'psa_key_lifetime_t': 'unsigned', + 'psa_key_type_t': 'unsigned', + 'psa_key_usage_flags_t': 'unsigned', + 'psa_pake_role_t': 'int', + 'psa_pake_step_t': 'int', + 'psa_status_t': 'int', + }) + + def _printf_parameters(self, typ: str, var: str) -> Tuple[str, List[str]]: + if typ.startswith('const '): + typ = typ[6:] + if typ == 'uint8_t *': + # Skip buffers + return '', [] + if typ.endswith('operation_t *'): + return '', [] + if typ in self._PAKE_STUFF: + return '', [] + if typ == 'psa_key_attributes_t *': + return (var + '={id=%u, lifetime=0x%08x, type=0x%08x, bits=%u, alg=%08x, usage=%08x}', + ['(unsigned) psa_get_key_{}({})'.format(field, var) + for field in ['id', 'lifetime', 'type', 'bits', 'algorithm', 'usage_flags']]) + return super()._printf_parameters(typ, var) + + +DEFAULT_C_OUTPUT_FILE_NAME = 'tests/src/psa_test_wrappers.c' +DEFAULT_H_OUTPUT_FILE_NAME = 'tests/include/test/psa_test_wrappers.h' + +def main() -> None: + parser = argparse.ArgumentParser(description=globals()['__doc__']) + parser.add_argument('--log', + help='Stream to log to (default: no logging code)') + parser.add_argument('--output-c', + metavar='FILENAME', + default=DEFAULT_C_OUTPUT_FILE_NAME, + help=('Output .c file path (default: {}; skip .c output if empty)' + .format(DEFAULT_C_OUTPUT_FILE_NAME))) + parser.add_argument('--output-h', + metavar='FILENAME', + default=DEFAULT_H_OUTPUT_FILE_NAME, + help=('Output .h file path (default: {}; skip .h output if empty)' + .format(DEFAULT_H_OUTPUT_FILE_NAME))) + options = parser.parse_args() + if options.log: + generator = PSALoggingWrapperGenerator(options.log) #type: PSAWrapperGenerator + else: + generator = PSAWrapperGenerator() + generator.gather_data() + if options.output_h: + generator.write_h_file(options.output_h) + if options.output_c: + generator.write_c_file(options.output_c) + +if __name__ == '__main__': + main() From 17a14f1711a2bd6d2473ddd3a8bf0cc1125a32aa Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 16:41:30 +0100 Subject: [PATCH 104/211] Adapt wrapper generators from 3.5 to 2.28 Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/c_wrapper_generator.py | 6 +++++- tests/scripts/generate_psa_wrappers.py | 12 ++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/scripts/mbedtls_dev/c_wrapper_generator.py b/scripts/mbedtls_dev/c_wrapper_generator.py index de99ddb9ae1b..2bed44b2cebe 100644 --- a/scripts/mbedtls_dev/c_wrapper_generator.py +++ b/scripts/mbedtls_dev/c_wrapper_generator.py @@ -79,7 +79,11 @@ def _write_prologue(self, out: typing_util.Writable, header: bool) -> None: """ .format(guard=self.header_guard)) out.write(""" -#include +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif """) def _write_epilogue(self, out: typing_util.Writable, header: bool) -> None: diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 9bb6eb758b32..f7a193adade2 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -31,10 +31,18 @@ def gather_data(self) -> None: _SKIP_FUNCTIONS = frozenset([ 'mbedtls_psa_external_get_random', # not a library function + 'psa_aead_abort', # not implemented yet + 'psa_aead_decrypt_setup', # not implemented yet + 'psa_aead_encrypt_setup', # not implemented yet + 'psa_aead_finish', # not implemented yet + 'psa_aead_generate_nonce', # not implemented yet + 'psa_aead_set_lengths', # not implemented yet + 'psa_aead_set_nonce', # not implemented yet + 'psa_aead_update', # not implemented yet + 'psa_aead_update_ad', # not implemented yet + 'psa_aead_verify', # not implemented yet 'psa_get_key_domain_parameters', # client-side function 'psa_get_key_slot_number', # client-side function - 'psa_key_derivation_verify_bytes', # not implemented yet - 'psa_key_derivation_verify_key', # not implemented yet 'psa_set_key_domain_parameters', # client-side function ]) From d5e5e6dbae89395c071eab7d224607467c7225bf Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 16:42:40 +0100 Subject: [PATCH 105/211] Commit generated PSA wrappers Commit files generated by `tests/scripts/generate_psa_wrappers.py`. As of this commit, the new code is neither useful (the wrappers just call the underlying functions) nor used (the wrapper functions are not called from anywhere). This will change in subsequent commits. Signed-off-by: Gilles Peskine --- tests/include/test/psa_test_wrappers.h | 486 +++++++++++++++++++ tests/src/psa_test_wrappers.c | 641 +++++++++++++++++++++++++ 2 files changed, 1127 insertions(+) create mode 100644 tests/include/test/psa_test_wrappers.h create mode 100644 tests/src/psa_test_wrappers.c diff --git a/tests/include/test/psa_test_wrappers.h b/tests/include/test/psa_test_wrappers.h new file mode 100644 index 000000000000..a7d459c8bd6f --- /dev/null +++ b/tests/include/test/psa_test_wrappers.h @@ -0,0 +1,486 @@ +/* Automatically generated by generate_psa_wrappers.py, do not edit! */ + +/* Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef TEST_PSA_TEST_WRAPPERS_H +#define TEST_PSA_TEST_WRAPPERS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) + +#include + +#include +#include + +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) +psa_status_t mbedtls_test_wrap_mbedtls_psa_inject_entropy( + const uint8_t *arg0_seed, + size_t arg1_seed_size); +#define mbedtls_psa_inject_entropy(arg0_seed, arg1_seed_size) \ + mbedtls_test_wrap_mbedtls_psa_inject_entropy(arg0_seed, arg1_seed_size) +#endif /* defined(MBEDTLS_PSA_INJECT_ENTROPY) */ + +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) +psa_status_t mbedtls_test_wrap_mbedtls_psa_platform_get_builtin_key( + mbedtls_svc_key_id_t arg0_key_id, + psa_key_lifetime_t *arg1_lifetime, + psa_drv_slot_number_t *arg2_slot_number); +#define mbedtls_psa_platform_get_builtin_key(arg0_key_id, arg1_lifetime, arg2_slot_number) \ + mbedtls_test_wrap_mbedtls_psa_platform_get_builtin_key(arg0_key_id, arg1_lifetime, arg2_slot_number) +#endif /* defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) */ + +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) +psa_status_t mbedtls_test_wrap_mbedtls_psa_register_se_key( + const psa_key_attributes_t *arg0_attributes); +#define mbedtls_psa_register_se_key(arg0_attributes) \ + mbedtls_test_wrap_mbedtls_psa_register_se_key(arg0_attributes) +#endif /* defined(MBEDTLS_PSA_CRYPTO_SE_C) */ + +psa_status_t mbedtls_test_wrap_psa_aead_decrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_nonce, + size_t arg3_nonce_length, + const uint8_t *arg4_additional_data, + size_t arg5_additional_data_length, + const uint8_t *arg6_ciphertext, + size_t arg7_ciphertext_length, + uint8_t *arg8_plaintext, + size_t arg9_plaintext_size, + size_t *arg10_plaintext_length); +#define psa_aead_decrypt(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_ciphertext, arg7_ciphertext_length, arg8_plaintext, arg9_plaintext_size, arg10_plaintext_length) \ + mbedtls_test_wrap_psa_aead_decrypt(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_ciphertext, arg7_ciphertext_length, arg8_plaintext, arg9_plaintext_size, arg10_plaintext_length) + +psa_status_t mbedtls_test_wrap_psa_aead_encrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_nonce, + size_t arg3_nonce_length, + const uint8_t *arg4_additional_data, + size_t arg5_additional_data_length, + const uint8_t *arg6_plaintext, + size_t arg7_plaintext_length, + uint8_t *arg8_ciphertext, + size_t arg9_ciphertext_size, + size_t *arg10_ciphertext_length); +#define psa_aead_encrypt(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_plaintext, arg7_plaintext_length, arg8_ciphertext, arg9_ciphertext_size, arg10_ciphertext_length) \ + mbedtls_test_wrap_psa_aead_encrypt(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_plaintext, arg7_plaintext_length, arg8_ciphertext, arg9_ciphertext_size, arg10_ciphertext_length) + +psa_status_t mbedtls_test_wrap_psa_asymmetric_decrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_salt, + size_t arg5_salt_length, + uint8_t *arg6_output, + size_t arg7_output_size, + size_t *arg8_output_length); +#define psa_asymmetric_decrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length) \ + mbedtls_test_wrap_psa_asymmetric_decrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length) + +psa_status_t mbedtls_test_wrap_psa_asymmetric_encrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_salt, + size_t arg5_salt_length, + uint8_t *arg6_output, + size_t arg7_output_size, + size_t *arg8_output_length); +#define psa_asymmetric_encrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length) \ + mbedtls_test_wrap_psa_asymmetric_encrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length) + +psa_status_t mbedtls_test_wrap_psa_cipher_abort( + psa_cipher_operation_t *arg0_operation); +#define psa_cipher_abort(arg0_operation) \ + mbedtls_test_wrap_psa_cipher_abort(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_cipher_decrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_output, + size_t arg5_output_size, + size_t *arg6_output_length); +#define psa_cipher_decrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length) \ + mbedtls_test_wrap_psa_cipher_decrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length) + +psa_status_t mbedtls_test_wrap_psa_cipher_decrypt_setup( + psa_cipher_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg); +#define psa_cipher_decrypt_setup(arg0_operation, arg1_key, arg2_alg) \ + mbedtls_test_wrap_psa_cipher_decrypt_setup(arg0_operation, arg1_key, arg2_alg) + +psa_status_t mbedtls_test_wrap_psa_cipher_encrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_output, + size_t arg5_output_size, + size_t *arg6_output_length); +#define psa_cipher_encrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length) \ + mbedtls_test_wrap_psa_cipher_encrypt(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length) + +psa_status_t mbedtls_test_wrap_psa_cipher_encrypt_setup( + psa_cipher_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg); +#define psa_cipher_encrypt_setup(arg0_operation, arg1_key, arg2_alg) \ + mbedtls_test_wrap_psa_cipher_encrypt_setup(arg0_operation, arg1_key, arg2_alg) + +psa_status_t mbedtls_test_wrap_psa_cipher_finish( + psa_cipher_operation_t *arg0_operation, + uint8_t *arg1_output, + size_t arg2_output_size, + size_t *arg3_output_length); +#define psa_cipher_finish(arg0_operation, arg1_output, arg2_output_size, arg3_output_length) \ + mbedtls_test_wrap_psa_cipher_finish(arg0_operation, arg1_output, arg2_output_size, arg3_output_length) + +psa_status_t mbedtls_test_wrap_psa_cipher_generate_iv( + psa_cipher_operation_t *arg0_operation, + uint8_t *arg1_iv, + size_t arg2_iv_size, + size_t *arg3_iv_length); +#define psa_cipher_generate_iv(arg0_operation, arg1_iv, arg2_iv_size, arg3_iv_length) \ + mbedtls_test_wrap_psa_cipher_generate_iv(arg0_operation, arg1_iv, arg2_iv_size, arg3_iv_length) + +psa_status_t mbedtls_test_wrap_psa_cipher_set_iv( + psa_cipher_operation_t *arg0_operation, + const uint8_t *arg1_iv, + size_t arg2_iv_length); +#define psa_cipher_set_iv(arg0_operation, arg1_iv, arg2_iv_length) \ + mbedtls_test_wrap_psa_cipher_set_iv(arg0_operation, arg1_iv, arg2_iv_length) + +psa_status_t mbedtls_test_wrap_psa_cipher_update( + psa_cipher_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length, + uint8_t *arg3_output, + size_t arg4_output_size, + size_t *arg5_output_length); +#define psa_cipher_update(arg0_operation, arg1_input, arg2_input_length, arg3_output, arg4_output_size, arg5_output_length) \ + mbedtls_test_wrap_psa_cipher_update(arg0_operation, arg1_input, arg2_input_length, arg3_output, arg4_output_size, arg5_output_length) + +psa_status_t mbedtls_test_wrap_psa_copy_key( + mbedtls_svc_key_id_t arg0_source_key, + const psa_key_attributes_t *arg1_attributes, + mbedtls_svc_key_id_t *arg2_target_key); +#define psa_copy_key(arg0_source_key, arg1_attributes, arg2_target_key) \ + mbedtls_test_wrap_psa_copy_key(arg0_source_key, arg1_attributes, arg2_target_key) + +psa_status_t mbedtls_test_wrap_psa_crypto_init(void); +#define psa_crypto_init() \ + mbedtls_test_wrap_psa_crypto_init() + +psa_status_t mbedtls_test_wrap_psa_destroy_key( + mbedtls_svc_key_id_t arg0_key); +#define psa_destroy_key(arg0_key) \ + mbedtls_test_wrap_psa_destroy_key(arg0_key) + +psa_status_t mbedtls_test_wrap_psa_export_key( + mbedtls_svc_key_id_t arg0_key, + uint8_t *arg1_data, + size_t arg2_data_size, + size_t *arg3_data_length); +#define psa_export_key(arg0_key, arg1_data, arg2_data_size, arg3_data_length) \ + mbedtls_test_wrap_psa_export_key(arg0_key, arg1_data, arg2_data_size, arg3_data_length) + +psa_status_t mbedtls_test_wrap_psa_export_public_key( + mbedtls_svc_key_id_t arg0_key, + uint8_t *arg1_data, + size_t arg2_data_size, + size_t *arg3_data_length); +#define psa_export_public_key(arg0_key, arg1_data, arg2_data_size, arg3_data_length) \ + mbedtls_test_wrap_psa_export_public_key(arg0_key, arg1_data, arg2_data_size, arg3_data_length) + +psa_status_t mbedtls_test_wrap_psa_generate_key( + const psa_key_attributes_t *arg0_attributes, + mbedtls_svc_key_id_t *arg1_key); +#define psa_generate_key(arg0_attributes, arg1_key) \ + mbedtls_test_wrap_psa_generate_key(arg0_attributes, arg1_key) + +psa_status_t mbedtls_test_wrap_psa_generate_random( + uint8_t *arg0_output, + size_t arg1_output_size); +#define psa_generate_random(arg0_output, arg1_output_size) \ + mbedtls_test_wrap_psa_generate_random(arg0_output, arg1_output_size) + +psa_status_t mbedtls_test_wrap_psa_get_key_attributes( + mbedtls_svc_key_id_t arg0_key, + psa_key_attributes_t *arg1_attributes); +#define psa_get_key_attributes(arg0_key, arg1_attributes) \ + mbedtls_test_wrap_psa_get_key_attributes(arg0_key, arg1_attributes) + +psa_status_t mbedtls_test_wrap_psa_hash_abort( + psa_hash_operation_t *arg0_operation); +#define psa_hash_abort(arg0_operation) \ + mbedtls_test_wrap_psa_hash_abort(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_hash_clone( + const psa_hash_operation_t *arg0_source_operation, + psa_hash_operation_t *arg1_target_operation); +#define psa_hash_clone(arg0_source_operation, arg1_target_operation) \ + mbedtls_test_wrap_psa_hash_clone(arg0_source_operation, arg1_target_operation) + +psa_status_t mbedtls_test_wrap_psa_hash_compare( + psa_algorithm_t arg0_alg, + const uint8_t *arg1_input, + size_t arg2_input_length, + const uint8_t *arg3_hash, + size_t arg4_hash_length); +#define psa_hash_compare(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_length) \ + mbedtls_test_wrap_psa_hash_compare(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_length) + +psa_status_t mbedtls_test_wrap_psa_hash_compute( + psa_algorithm_t arg0_alg, + const uint8_t *arg1_input, + size_t arg2_input_length, + uint8_t *arg3_hash, + size_t arg4_hash_size, + size_t *arg5_hash_length); +#define psa_hash_compute(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_size, arg5_hash_length) \ + mbedtls_test_wrap_psa_hash_compute(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_size, arg5_hash_length) + +psa_status_t mbedtls_test_wrap_psa_hash_finish( + psa_hash_operation_t *arg0_operation, + uint8_t *arg1_hash, + size_t arg2_hash_size, + size_t *arg3_hash_length); +#define psa_hash_finish(arg0_operation, arg1_hash, arg2_hash_size, arg3_hash_length) \ + mbedtls_test_wrap_psa_hash_finish(arg0_operation, arg1_hash, arg2_hash_size, arg3_hash_length) + +psa_status_t mbedtls_test_wrap_psa_hash_setup( + psa_hash_operation_t *arg0_operation, + psa_algorithm_t arg1_alg); +#define psa_hash_setup(arg0_operation, arg1_alg) \ + mbedtls_test_wrap_psa_hash_setup(arg0_operation, arg1_alg) + +psa_status_t mbedtls_test_wrap_psa_hash_update( + psa_hash_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length); +#define psa_hash_update(arg0_operation, arg1_input, arg2_input_length) \ + mbedtls_test_wrap_psa_hash_update(arg0_operation, arg1_input, arg2_input_length) + +psa_status_t mbedtls_test_wrap_psa_hash_verify( + psa_hash_operation_t *arg0_operation, + const uint8_t *arg1_hash, + size_t arg2_hash_length); +#define psa_hash_verify(arg0_operation, arg1_hash, arg2_hash_length) \ + mbedtls_test_wrap_psa_hash_verify(arg0_operation, arg1_hash, arg2_hash_length) + +psa_status_t mbedtls_test_wrap_psa_import_key( + const psa_key_attributes_t *arg0_attributes, + const uint8_t *arg1_data, + size_t arg2_data_length, + mbedtls_svc_key_id_t *arg3_key); +#define psa_import_key(arg0_attributes, arg1_data, arg2_data_length, arg3_key) \ + mbedtls_test_wrap_psa_import_key(arg0_attributes, arg1_data, arg2_data_length, arg3_key) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_abort( + psa_key_derivation_operation_t *arg0_operation); +#define psa_key_derivation_abort(arg0_operation) \ + mbedtls_test_wrap_psa_key_derivation_abort(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_get_capacity( + const psa_key_derivation_operation_t *arg0_operation, + size_t *arg1_capacity); +#define psa_key_derivation_get_capacity(arg0_operation, arg1_capacity) \ + mbedtls_test_wrap_psa_key_derivation_get_capacity(arg0_operation, arg1_capacity) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_input_bytes( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + const uint8_t *arg2_data, + size_t arg3_data_length); +#define psa_key_derivation_input_bytes(arg0_operation, arg1_step, arg2_data, arg3_data_length) \ + mbedtls_test_wrap_psa_key_derivation_input_bytes(arg0_operation, arg1_step, arg2_data, arg3_data_length) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_input_key( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + mbedtls_svc_key_id_t arg2_key); +#define psa_key_derivation_input_key(arg0_operation, arg1_step, arg2_key) \ + mbedtls_test_wrap_psa_key_derivation_input_key(arg0_operation, arg1_step, arg2_key) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_key_agreement( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + mbedtls_svc_key_id_t arg2_private_key, + const uint8_t *arg3_peer_key, + size_t arg4_peer_key_length); +#define psa_key_derivation_key_agreement(arg0_operation, arg1_step, arg2_private_key, arg3_peer_key, arg4_peer_key_length) \ + mbedtls_test_wrap_psa_key_derivation_key_agreement(arg0_operation, arg1_step, arg2_private_key, arg3_peer_key, arg4_peer_key_length) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_output_bytes( + psa_key_derivation_operation_t *arg0_operation, + uint8_t *arg1_output, + size_t arg2_output_length); +#define psa_key_derivation_output_bytes(arg0_operation, arg1_output, arg2_output_length) \ + mbedtls_test_wrap_psa_key_derivation_output_bytes(arg0_operation, arg1_output, arg2_output_length) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_output_key( + const psa_key_attributes_t *arg0_attributes, + psa_key_derivation_operation_t *arg1_operation, + mbedtls_svc_key_id_t *arg2_key); +#define psa_key_derivation_output_key(arg0_attributes, arg1_operation, arg2_key) \ + mbedtls_test_wrap_psa_key_derivation_output_key(arg0_attributes, arg1_operation, arg2_key) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_set_capacity( + psa_key_derivation_operation_t *arg0_operation, + size_t arg1_capacity); +#define psa_key_derivation_set_capacity(arg0_operation, arg1_capacity) \ + mbedtls_test_wrap_psa_key_derivation_set_capacity(arg0_operation, arg1_capacity) + +psa_status_t mbedtls_test_wrap_psa_key_derivation_setup( + psa_key_derivation_operation_t *arg0_operation, + psa_algorithm_t arg1_alg); +#define psa_key_derivation_setup(arg0_operation, arg1_alg) \ + mbedtls_test_wrap_psa_key_derivation_setup(arg0_operation, arg1_alg) + +psa_status_t mbedtls_test_wrap_psa_mac_abort( + psa_mac_operation_t *arg0_operation); +#define psa_mac_abort(arg0_operation) \ + mbedtls_test_wrap_psa_mac_abort(arg0_operation) + +psa_status_t mbedtls_test_wrap_psa_mac_compute( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_mac, + size_t arg5_mac_size, + size_t *arg6_mac_length); +#define psa_mac_compute(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_size, arg6_mac_length) \ + mbedtls_test_wrap_psa_mac_compute(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_size, arg6_mac_length) + +psa_status_t mbedtls_test_wrap_psa_mac_sign_finish( + psa_mac_operation_t *arg0_operation, + uint8_t *arg1_mac, + size_t arg2_mac_size, + size_t *arg3_mac_length); +#define psa_mac_sign_finish(arg0_operation, arg1_mac, arg2_mac_size, arg3_mac_length) \ + mbedtls_test_wrap_psa_mac_sign_finish(arg0_operation, arg1_mac, arg2_mac_size, arg3_mac_length) + +psa_status_t mbedtls_test_wrap_psa_mac_sign_setup( + psa_mac_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg); +#define psa_mac_sign_setup(arg0_operation, arg1_key, arg2_alg) \ + mbedtls_test_wrap_psa_mac_sign_setup(arg0_operation, arg1_key, arg2_alg) + +psa_status_t mbedtls_test_wrap_psa_mac_update( + psa_mac_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length); +#define psa_mac_update(arg0_operation, arg1_input, arg2_input_length) \ + mbedtls_test_wrap_psa_mac_update(arg0_operation, arg1_input, arg2_input_length) + +psa_status_t mbedtls_test_wrap_psa_mac_verify( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_mac, + size_t arg5_mac_length); +#define psa_mac_verify(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_length) \ + mbedtls_test_wrap_psa_mac_verify(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_length) + +psa_status_t mbedtls_test_wrap_psa_mac_verify_finish( + psa_mac_operation_t *arg0_operation, + const uint8_t *arg1_mac, + size_t arg2_mac_length); +#define psa_mac_verify_finish(arg0_operation, arg1_mac, arg2_mac_length) \ + mbedtls_test_wrap_psa_mac_verify_finish(arg0_operation, arg1_mac, arg2_mac_length) + +psa_status_t mbedtls_test_wrap_psa_mac_verify_setup( + psa_mac_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg); +#define psa_mac_verify_setup(arg0_operation, arg1_key, arg2_alg) \ + mbedtls_test_wrap_psa_mac_verify_setup(arg0_operation, arg1_key, arg2_alg) + +psa_status_t mbedtls_test_wrap_psa_purge_key( + mbedtls_svc_key_id_t arg0_key); +#define psa_purge_key(arg0_key) \ + mbedtls_test_wrap_psa_purge_key(arg0_key) + +psa_status_t mbedtls_test_wrap_psa_raw_key_agreement( + psa_algorithm_t arg0_alg, + mbedtls_svc_key_id_t arg1_private_key, + const uint8_t *arg2_peer_key, + size_t arg3_peer_key_length, + uint8_t *arg4_output, + size_t arg5_output_size, + size_t *arg6_output_length); +#define psa_raw_key_agreement(arg0_alg, arg1_private_key, arg2_peer_key, arg3_peer_key_length, arg4_output, arg5_output_size, arg6_output_length) \ + mbedtls_test_wrap_psa_raw_key_agreement(arg0_alg, arg1_private_key, arg2_peer_key, arg3_peer_key_length, arg4_output, arg5_output_size, arg6_output_length) + +psa_status_t mbedtls_test_wrap_psa_sign_hash( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_hash, + size_t arg3_hash_length, + uint8_t *arg4_signature, + size_t arg5_signature_size, + size_t *arg6_signature_length); +#define psa_sign_hash(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_size, arg6_signature_length) \ + mbedtls_test_wrap_psa_sign_hash(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_size, arg6_signature_length) + +psa_status_t mbedtls_test_wrap_psa_sign_message( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_signature, + size_t arg5_signature_size, + size_t *arg6_signature_length); +#define psa_sign_message(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_size, arg6_signature_length) \ + mbedtls_test_wrap_psa_sign_message(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_size, arg6_signature_length) + +psa_status_t mbedtls_test_wrap_psa_verify_hash( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_hash, + size_t arg3_hash_length, + const uint8_t *arg4_signature, + size_t arg5_signature_length); +#define psa_verify_hash(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_length) \ + mbedtls_test_wrap_psa_verify_hash(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_length) + +psa_status_t mbedtls_test_wrap_psa_verify_message( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_signature, + size_t arg5_signature_length); +#define psa_verify_message(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_length) \ + mbedtls_test_wrap_psa_verify_message(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_length) + +#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) */ + +#ifdef __cplusplus +} +#endif + +#endif /* TEST_PSA_TEST_WRAPPERS_H */ + +/* End of automatically generated file. */ diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c new file mode 100644 index 000000000000..86900bcfbb43 --- /dev/null +++ b/tests/src/psa_test_wrappers.c @@ -0,0 +1,641 @@ +/* Automatically generated by generate_psa_wrappers.py, do not edit! */ + +/* Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) + +#include + +#include +#include + +/* Wrapper for mbedtls_psa_inject_entropy */ +#if defined(MBEDTLS_PSA_INJECT_ENTROPY) +psa_status_t mbedtls_test_wrap_mbedtls_psa_inject_entropy( + const uint8_t *arg0_seed, + size_t arg1_seed_size) +{ + psa_status_t status = (mbedtls_psa_inject_entropy)(arg0_seed, arg1_seed_size); + return status; +} +#endif /* defined(MBEDTLS_PSA_INJECT_ENTROPY) */ + +/* Wrapper for mbedtls_psa_platform_get_builtin_key */ +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) +psa_status_t mbedtls_test_wrap_mbedtls_psa_platform_get_builtin_key( + mbedtls_svc_key_id_t arg0_key_id, + psa_key_lifetime_t *arg1_lifetime, + psa_drv_slot_number_t *arg2_slot_number) +{ + psa_status_t status = (mbedtls_psa_platform_get_builtin_key)(arg0_key_id, arg1_lifetime, arg2_slot_number); + return status; +} +#endif /* defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) */ + +/* Wrapper for mbedtls_psa_register_se_key */ +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) +psa_status_t mbedtls_test_wrap_mbedtls_psa_register_se_key( + const psa_key_attributes_t *arg0_attributes) +{ + psa_status_t status = (mbedtls_psa_register_se_key)(arg0_attributes); + return status; +} +#endif /* defined(MBEDTLS_PSA_CRYPTO_SE_C) */ + +/* Wrapper for psa_aead_decrypt */ +psa_status_t mbedtls_test_wrap_psa_aead_decrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_nonce, + size_t arg3_nonce_length, + const uint8_t *arg4_additional_data, + size_t arg5_additional_data_length, + const uint8_t *arg6_ciphertext, + size_t arg7_ciphertext_length, + uint8_t *arg8_plaintext, + size_t arg9_plaintext_size, + size_t *arg10_plaintext_length) +{ + psa_status_t status = (psa_aead_decrypt)(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_ciphertext, arg7_ciphertext_length, arg8_plaintext, arg9_plaintext_size, arg10_plaintext_length); + return status; +} + +/* Wrapper for psa_aead_encrypt */ +psa_status_t mbedtls_test_wrap_psa_aead_encrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_nonce, + size_t arg3_nonce_length, + const uint8_t *arg4_additional_data, + size_t arg5_additional_data_length, + const uint8_t *arg6_plaintext, + size_t arg7_plaintext_length, + uint8_t *arg8_ciphertext, + size_t arg9_ciphertext_size, + size_t *arg10_ciphertext_length) +{ + psa_status_t status = (psa_aead_encrypt)(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_plaintext, arg7_plaintext_length, arg8_ciphertext, arg9_ciphertext_size, arg10_ciphertext_length); + return status; +} + +/* Wrapper for psa_asymmetric_decrypt */ +psa_status_t mbedtls_test_wrap_psa_asymmetric_decrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_salt, + size_t arg5_salt_length, + uint8_t *arg6_output, + size_t arg7_output_size, + size_t *arg8_output_length) +{ + psa_status_t status = (psa_asymmetric_decrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length); + return status; +} + +/* Wrapper for psa_asymmetric_encrypt */ +psa_status_t mbedtls_test_wrap_psa_asymmetric_encrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_salt, + size_t arg5_salt_length, + uint8_t *arg6_output, + size_t arg7_output_size, + size_t *arg8_output_length) +{ + psa_status_t status = (psa_asymmetric_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length); + return status; +} + +/* Wrapper for psa_cipher_abort */ +psa_status_t mbedtls_test_wrap_psa_cipher_abort( + psa_cipher_operation_t *arg0_operation) +{ + psa_status_t status = (psa_cipher_abort)(arg0_operation); + return status; +} + +/* Wrapper for psa_cipher_decrypt */ +psa_status_t mbedtls_test_wrap_psa_cipher_decrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_output, + size_t arg5_output_size, + size_t *arg6_output_length) +{ + psa_status_t status = (psa_cipher_decrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); + return status; +} + +/* Wrapper for psa_cipher_decrypt_setup */ +psa_status_t mbedtls_test_wrap_psa_cipher_decrypt_setup( + psa_cipher_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg) +{ + psa_status_t status = (psa_cipher_decrypt_setup)(arg0_operation, arg1_key, arg2_alg); + return status; +} + +/* Wrapper for psa_cipher_encrypt */ +psa_status_t mbedtls_test_wrap_psa_cipher_encrypt( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_output, + size_t arg5_output_size, + size_t *arg6_output_length) +{ + psa_status_t status = (psa_cipher_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); + return status; +} + +/* Wrapper for psa_cipher_encrypt_setup */ +psa_status_t mbedtls_test_wrap_psa_cipher_encrypt_setup( + psa_cipher_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg) +{ + psa_status_t status = (psa_cipher_encrypt_setup)(arg0_operation, arg1_key, arg2_alg); + return status; +} + +/* Wrapper for psa_cipher_finish */ +psa_status_t mbedtls_test_wrap_psa_cipher_finish( + psa_cipher_operation_t *arg0_operation, + uint8_t *arg1_output, + size_t arg2_output_size, + size_t *arg3_output_length) +{ + psa_status_t status = (psa_cipher_finish)(arg0_operation, arg1_output, arg2_output_size, arg3_output_length); + return status; +} + +/* Wrapper for psa_cipher_generate_iv */ +psa_status_t mbedtls_test_wrap_psa_cipher_generate_iv( + psa_cipher_operation_t *arg0_operation, + uint8_t *arg1_iv, + size_t arg2_iv_size, + size_t *arg3_iv_length) +{ + psa_status_t status = (psa_cipher_generate_iv)(arg0_operation, arg1_iv, arg2_iv_size, arg3_iv_length); + return status; +} + +/* Wrapper for psa_cipher_set_iv */ +psa_status_t mbedtls_test_wrap_psa_cipher_set_iv( + psa_cipher_operation_t *arg0_operation, + const uint8_t *arg1_iv, + size_t arg2_iv_length) +{ + psa_status_t status = (psa_cipher_set_iv)(arg0_operation, arg1_iv, arg2_iv_length); + return status; +} + +/* Wrapper for psa_cipher_update */ +psa_status_t mbedtls_test_wrap_psa_cipher_update( + psa_cipher_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length, + uint8_t *arg3_output, + size_t arg4_output_size, + size_t *arg5_output_length) +{ + psa_status_t status = (psa_cipher_update)(arg0_operation, arg1_input, arg2_input_length, arg3_output, arg4_output_size, arg5_output_length); + return status; +} + +/* Wrapper for psa_copy_key */ +psa_status_t mbedtls_test_wrap_psa_copy_key( + mbedtls_svc_key_id_t arg0_source_key, + const psa_key_attributes_t *arg1_attributes, + mbedtls_svc_key_id_t *arg2_target_key) +{ + psa_status_t status = (psa_copy_key)(arg0_source_key, arg1_attributes, arg2_target_key); + return status; +} + +/* Wrapper for psa_crypto_init */ +psa_status_t mbedtls_test_wrap_psa_crypto_init(void) +{ + psa_status_t status = (psa_crypto_init)(); + return status; +} + +/* Wrapper for psa_destroy_key */ +psa_status_t mbedtls_test_wrap_psa_destroy_key( + mbedtls_svc_key_id_t arg0_key) +{ + psa_status_t status = (psa_destroy_key)(arg0_key); + return status; +} + +/* Wrapper for psa_export_key */ +psa_status_t mbedtls_test_wrap_psa_export_key( + mbedtls_svc_key_id_t arg0_key, + uint8_t *arg1_data, + size_t arg2_data_size, + size_t *arg3_data_length) +{ + psa_status_t status = (psa_export_key)(arg0_key, arg1_data, arg2_data_size, arg3_data_length); + return status; +} + +/* Wrapper for psa_export_public_key */ +psa_status_t mbedtls_test_wrap_psa_export_public_key( + mbedtls_svc_key_id_t arg0_key, + uint8_t *arg1_data, + size_t arg2_data_size, + size_t *arg3_data_length) +{ + psa_status_t status = (psa_export_public_key)(arg0_key, arg1_data, arg2_data_size, arg3_data_length); + return status; +} + +/* Wrapper for psa_generate_key */ +psa_status_t mbedtls_test_wrap_psa_generate_key( + const psa_key_attributes_t *arg0_attributes, + mbedtls_svc_key_id_t *arg1_key) +{ + psa_status_t status = (psa_generate_key)(arg0_attributes, arg1_key); + return status; +} + +/* Wrapper for psa_generate_random */ +psa_status_t mbedtls_test_wrap_psa_generate_random( + uint8_t *arg0_output, + size_t arg1_output_size) +{ + psa_status_t status = (psa_generate_random)(arg0_output, arg1_output_size); + return status; +} + +/* Wrapper for psa_get_key_attributes */ +psa_status_t mbedtls_test_wrap_psa_get_key_attributes( + mbedtls_svc_key_id_t arg0_key, + psa_key_attributes_t *arg1_attributes) +{ + psa_status_t status = (psa_get_key_attributes)(arg0_key, arg1_attributes); + return status; +} + +/* Wrapper for psa_hash_abort */ +psa_status_t mbedtls_test_wrap_psa_hash_abort( + psa_hash_operation_t *arg0_operation) +{ + psa_status_t status = (psa_hash_abort)(arg0_operation); + return status; +} + +/* Wrapper for psa_hash_clone */ +psa_status_t mbedtls_test_wrap_psa_hash_clone( + const psa_hash_operation_t *arg0_source_operation, + psa_hash_operation_t *arg1_target_operation) +{ + psa_status_t status = (psa_hash_clone)(arg0_source_operation, arg1_target_operation); + return status; +} + +/* Wrapper for psa_hash_compare */ +psa_status_t mbedtls_test_wrap_psa_hash_compare( + psa_algorithm_t arg0_alg, + const uint8_t *arg1_input, + size_t arg2_input_length, + const uint8_t *arg3_hash, + size_t arg4_hash_length) +{ + psa_status_t status = (psa_hash_compare)(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_length); + return status; +} + +/* Wrapper for psa_hash_compute */ +psa_status_t mbedtls_test_wrap_psa_hash_compute( + psa_algorithm_t arg0_alg, + const uint8_t *arg1_input, + size_t arg2_input_length, + uint8_t *arg3_hash, + size_t arg4_hash_size, + size_t *arg5_hash_length) +{ + psa_status_t status = (psa_hash_compute)(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_size, arg5_hash_length); + return status; +} + +/* Wrapper for psa_hash_finish */ +psa_status_t mbedtls_test_wrap_psa_hash_finish( + psa_hash_operation_t *arg0_operation, + uint8_t *arg1_hash, + size_t arg2_hash_size, + size_t *arg3_hash_length) +{ + psa_status_t status = (psa_hash_finish)(arg0_operation, arg1_hash, arg2_hash_size, arg3_hash_length); + return status; +} + +/* Wrapper for psa_hash_setup */ +psa_status_t mbedtls_test_wrap_psa_hash_setup( + psa_hash_operation_t *arg0_operation, + psa_algorithm_t arg1_alg) +{ + psa_status_t status = (psa_hash_setup)(arg0_operation, arg1_alg); + return status; +} + +/* Wrapper for psa_hash_update */ +psa_status_t mbedtls_test_wrap_psa_hash_update( + psa_hash_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length) +{ + psa_status_t status = (psa_hash_update)(arg0_operation, arg1_input, arg2_input_length); + return status; +} + +/* Wrapper for psa_hash_verify */ +psa_status_t mbedtls_test_wrap_psa_hash_verify( + psa_hash_operation_t *arg0_operation, + const uint8_t *arg1_hash, + size_t arg2_hash_length) +{ + psa_status_t status = (psa_hash_verify)(arg0_operation, arg1_hash, arg2_hash_length); + return status; +} + +/* Wrapper for psa_import_key */ +psa_status_t mbedtls_test_wrap_psa_import_key( + const psa_key_attributes_t *arg0_attributes, + const uint8_t *arg1_data, + size_t arg2_data_length, + mbedtls_svc_key_id_t *arg3_key) +{ + psa_status_t status = (psa_import_key)(arg0_attributes, arg1_data, arg2_data_length, arg3_key); + return status; +} + +/* Wrapper for psa_key_derivation_abort */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_abort( + psa_key_derivation_operation_t *arg0_operation) +{ + psa_status_t status = (psa_key_derivation_abort)(arg0_operation); + return status; +} + +/* Wrapper for psa_key_derivation_get_capacity */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_get_capacity( + const psa_key_derivation_operation_t *arg0_operation, + size_t *arg1_capacity) +{ + psa_status_t status = (psa_key_derivation_get_capacity)(arg0_operation, arg1_capacity); + return status; +} + +/* Wrapper for psa_key_derivation_input_bytes */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_input_bytes( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + const uint8_t *arg2_data, + size_t arg3_data_length) +{ + psa_status_t status = (psa_key_derivation_input_bytes)(arg0_operation, arg1_step, arg2_data, arg3_data_length); + return status; +} + +/* Wrapper for psa_key_derivation_input_key */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_input_key( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + mbedtls_svc_key_id_t arg2_key) +{ + psa_status_t status = (psa_key_derivation_input_key)(arg0_operation, arg1_step, arg2_key); + return status; +} + +/* Wrapper for psa_key_derivation_key_agreement */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_key_agreement( + psa_key_derivation_operation_t *arg0_operation, + psa_key_derivation_step_t arg1_step, + mbedtls_svc_key_id_t arg2_private_key, + const uint8_t *arg3_peer_key, + size_t arg4_peer_key_length) +{ + psa_status_t status = (psa_key_derivation_key_agreement)(arg0_operation, arg1_step, arg2_private_key, arg3_peer_key, arg4_peer_key_length); + return status; +} + +/* Wrapper for psa_key_derivation_output_bytes */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_output_bytes( + psa_key_derivation_operation_t *arg0_operation, + uint8_t *arg1_output, + size_t arg2_output_length) +{ + psa_status_t status = (psa_key_derivation_output_bytes)(arg0_operation, arg1_output, arg2_output_length); + return status; +} + +/* Wrapper for psa_key_derivation_output_key */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_output_key( + const psa_key_attributes_t *arg0_attributes, + psa_key_derivation_operation_t *arg1_operation, + mbedtls_svc_key_id_t *arg2_key) +{ + psa_status_t status = (psa_key_derivation_output_key)(arg0_attributes, arg1_operation, arg2_key); + return status; +} + +/* Wrapper for psa_key_derivation_set_capacity */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_set_capacity( + psa_key_derivation_operation_t *arg0_operation, + size_t arg1_capacity) +{ + psa_status_t status = (psa_key_derivation_set_capacity)(arg0_operation, arg1_capacity); + return status; +} + +/* Wrapper for psa_key_derivation_setup */ +psa_status_t mbedtls_test_wrap_psa_key_derivation_setup( + psa_key_derivation_operation_t *arg0_operation, + psa_algorithm_t arg1_alg) +{ + psa_status_t status = (psa_key_derivation_setup)(arg0_operation, arg1_alg); + return status; +} + +/* Wrapper for psa_mac_abort */ +psa_status_t mbedtls_test_wrap_psa_mac_abort( + psa_mac_operation_t *arg0_operation) +{ + psa_status_t status = (psa_mac_abort)(arg0_operation); + return status; +} + +/* Wrapper for psa_mac_compute */ +psa_status_t mbedtls_test_wrap_psa_mac_compute( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_mac, + size_t arg5_mac_size, + size_t *arg6_mac_length) +{ + psa_status_t status = (psa_mac_compute)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_size, arg6_mac_length); + return status; +} + +/* Wrapper for psa_mac_sign_finish */ +psa_status_t mbedtls_test_wrap_psa_mac_sign_finish( + psa_mac_operation_t *arg0_operation, + uint8_t *arg1_mac, + size_t arg2_mac_size, + size_t *arg3_mac_length) +{ + psa_status_t status = (psa_mac_sign_finish)(arg0_operation, arg1_mac, arg2_mac_size, arg3_mac_length); + return status; +} + +/* Wrapper for psa_mac_sign_setup */ +psa_status_t mbedtls_test_wrap_psa_mac_sign_setup( + psa_mac_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg) +{ + psa_status_t status = (psa_mac_sign_setup)(arg0_operation, arg1_key, arg2_alg); + return status; +} + +/* Wrapper for psa_mac_update */ +psa_status_t mbedtls_test_wrap_psa_mac_update( + psa_mac_operation_t *arg0_operation, + const uint8_t *arg1_input, + size_t arg2_input_length) +{ + psa_status_t status = (psa_mac_update)(arg0_operation, arg1_input, arg2_input_length); + return status; +} + +/* Wrapper for psa_mac_verify */ +psa_status_t mbedtls_test_wrap_psa_mac_verify( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_mac, + size_t arg5_mac_length) +{ + psa_status_t status = (psa_mac_verify)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_length); + return status; +} + +/* Wrapper for psa_mac_verify_finish */ +psa_status_t mbedtls_test_wrap_psa_mac_verify_finish( + psa_mac_operation_t *arg0_operation, + const uint8_t *arg1_mac, + size_t arg2_mac_length) +{ + psa_status_t status = (psa_mac_verify_finish)(arg0_operation, arg1_mac, arg2_mac_length); + return status; +} + +/* Wrapper for psa_mac_verify_setup */ +psa_status_t mbedtls_test_wrap_psa_mac_verify_setup( + psa_mac_operation_t *arg0_operation, + mbedtls_svc_key_id_t arg1_key, + psa_algorithm_t arg2_alg) +{ + psa_status_t status = (psa_mac_verify_setup)(arg0_operation, arg1_key, arg2_alg); + return status; +} + +/* Wrapper for psa_purge_key */ +psa_status_t mbedtls_test_wrap_psa_purge_key( + mbedtls_svc_key_id_t arg0_key) +{ + psa_status_t status = (psa_purge_key)(arg0_key); + return status; +} + +/* Wrapper for psa_raw_key_agreement */ +psa_status_t mbedtls_test_wrap_psa_raw_key_agreement( + psa_algorithm_t arg0_alg, + mbedtls_svc_key_id_t arg1_private_key, + const uint8_t *arg2_peer_key, + size_t arg3_peer_key_length, + uint8_t *arg4_output, + size_t arg5_output_size, + size_t *arg6_output_length) +{ + psa_status_t status = (psa_raw_key_agreement)(arg0_alg, arg1_private_key, arg2_peer_key, arg3_peer_key_length, arg4_output, arg5_output_size, arg6_output_length); + return status; +} + +/* Wrapper for psa_sign_hash */ +psa_status_t mbedtls_test_wrap_psa_sign_hash( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_hash, + size_t arg3_hash_length, + uint8_t *arg4_signature, + size_t arg5_signature_size, + size_t *arg6_signature_length) +{ + psa_status_t status = (psa_sign_hash)(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_size, arg6_signature_length); + return status; +} + +/* Wrapper for psa_sign_message */ +psa_status_t mbedtls_test_wrap_psa_sign_message( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + uint8_t *arg4_signature, + size_t arg5_signature_size, + size_t *arg6_signature_length) +{ + psa_status_t status = (psa_sign_message)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_size, arg6_signature_length); + return status; +} + +/* Wrapper for psa_verify_hash */ +psa_status_t mbedtls_test_wrap_psa_verify_hash( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_hash, + size_t arg3_hash_length, + const uint8_t *arg4_signature, + size_t arg5_signature_length) +{ + psa_status_t status = (psa_verify_hash)(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_length); + return status; +} + +/* Wrapper for psa_verify_message */ +psa_status_t mbedtls_test_wrap_psa_verify_message( + mbedtls_svc_key_id_t arg0_key, + psa_algorithm_t arg1_alg, + const uint8_t *arg2_input, + size_t arg3_input_length, + const uint8_t *arg4_signature, + size_t arg5_signature_length) +{ + psa_status_t status = (psa_verify_message)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_length); + return status; +} + +#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) */ + +/* End of automatically generated file. */ From 1b2aec260e847c791b5a5c36d7ad325975c82e12 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 16:46:50 +0100 Subject: [PATCH 106/211] Update generated Visual Studio project Signed-off-by: Gilles Peskine --- visualc/VS2010/mbedTLS.vcxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 1ffc1f6e0557..6a81ef64212f 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -248,6 +248,7 @@ + @@ -392,6 +393,7 @@ + From b7119c527c970ae45675fcca09e7a66d11a9a12b Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 16:46:00 +0100 Subject: [PATCH 107/211] Declare the outputs from generate_psa_wrappers.py as generated files Signed-off-by: Gilles Peskine --- tests/scripts/check-generated-files.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/scripts/check-generated-files.sh b/tests/scripts/check-generated-files.sh index 28719bd7a83a..b1b969f7ebb8 100755 --- a/tests/scripts/check-generated-files.sh +++ b/tests/scripts/check-generated-files.sh @@ -100,5 +100,6 @@ check scripts/generate_query_config.pl programs/test/query_config.c check scripts/generate_features.pl library/version_features.c check scripts/generate_visualc_files.pl visualc/VS2010 check scripts/generate_psa_constants.py programs/psa/psa_constant_names_generated.c +check tests/scripts/generate_psa_wrappers.py tests/include/test/psa_test_wrappers.h tests/src/psa_test_wrappers.c check tests/scripts/generate_bignum_tests.py $(tests/scripts/generate_bignum_tests.py --list) check tests/scripts/generate_psa_tests.py $(tests/scripts/generate_psa_tests.py --list) From 50580a51ff92f54d127fc58021eb15c671c195bf Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 16:44:16 +0100 Subject: [PATCH 108/211] Enable generated PSA wrappers Code in unit tests (`tests/suites/*.function`) and in test support code (`tests/src/**.c`) will now go through the wrapper functions when they call a PSA API function and `MBEDTLS_TEST_HOOKS` is enabled. Signed-off-by: Gilles Peskine --- tests/include/test/psa_crypto_helpers.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index 18d46d8b2bed..5648738da69e 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -17,6 +17,8 @@ #include +#include "test/psa_test_wrappers.h" + #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "mbedtls/psa_util.h" #endif From c8b22d07135835a744c14acf69211ce44e0e22f8 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 6 Dec 2023 19:32:52 +0100 Subject: [PATCH 109/211] Generated PSA wrappers: poison/unpoison buffer parameters For now, only instrument the one function for which buffer copying has been implemented, namely `psa_cipher_encrypt`. Signed-off-by: Gilles Peskine --- tests/scripts/generate_psa_wrappers.py | 78 +++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index f7a193adade2..656fcd8881fc 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -6,8 +6,9 @@ # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later import argparse +import itertools import os -from typing import List, Tuple +from typing import Iterator, List, Optional, Tuple import scripts_path #pylint: disable=unused-import from mbedtls_dev import build_tree @@ -16,6 +17,27 @@ from mbedtls_dev import typing_util +class BufferParameter: + """Description of an input or output buffer parameter sequence to a PSA function.""" + #pylint: disable=too-few-public-methods + + def __init__(self, i: int, is_output: bool, + buffer_name: str, size_name: str) -> None: + """Initialize the parameter information. + + i is the index of the function argument that is the pointer to the buffer. + The size is argument i+1. For a variable-size output, the actual length + goes in argument i+2. + + buffer_name and size_names are the names of arguments i and i+1. + This class does not yet help with the output length. + """ + self.index = i + self.buffer_name = buffer_name + self.size_name = size_name + self.is_output = is_output + + class PSAWrapperGenerator(c_wrapper_generator.Base): """Generate a C source file containing wrapper functions for PSA Crypto API calls.""" @@ -75,6 +97,59 @@ def _return_variable_name(self, 'mbedtls_psa_platform_get_builtin_key': 'defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS)', }) + @staticmethod + def _detect_buffer_parameters(arguments: List[c_parsing_helper.ArgumentInfo], + argument_names: List[str]) -> Iterator[BufferParameter]: + """Detect function arguments that are buffers (pointer, size [,length]).""" + types = ['' if arg.suffix else arg.type for arg in arguments] + # pairs = list of (type_of_arg_N, type_of_arg_N+1) + # where each type_of_arg_X is the empty string if the type is an array + # or there is no argument X. + pairs = enumerate(itertools.zip_longest(types, types[1:], fillvalue='')) + for i, t01 in pairs: + if (t01[0] == 'const uint8_t *' or t01[0] == 'uint8_t *') and \ + t01[1] == 'size_t': + yield BufferParameter(i, not t01[0].startswith('const '), + argument_names[i], argument_names[i+1]) + + @staticmethod + def _write_poison_buffer_parameter(out: typing_util.Writable, + param: BufferParameter, + poison: bool) -> None: + """Write poisoning or unpoisoning code for a buffer parameter. + + Write poisoning code if poison is true, unpoisoning code otherwise. + """ + out.write(' MBEDTLS_TEST_MEMORY_{}({}, {});\n'.format( + 'POISON' if poison else 'UNPOISON', + param.buffer_name, param.size_name + )) + + @staticmethod + def _parameter_should_be_copied(function_name: str, + _buffer_name: Optional[str]) -> bool: + """Whether the specified buffer argument to a PSA function should be copied. + """ + # Proof-of-concept: just instrument one function for now + if function_name == 'psa_cipher_encrypt': + return True + return False + + def _write_function_call(self, out: typing_util.Writable, + function: c_wrapper_generator.FunctionInfo, + argument_names: List[str]) -> None: + buffer_parameters = list( + param + for param in self._detect_buffer_parameters(function.arguments, + argument_names) + if self._parameter_should_be_copied(function.name, + function.arguments[param.index].name)) + for param in buffer_parameters: + self._write_poison_buffer_parameter(out, param, True) + super()._write_function_call(out, function, argument_names) + for param in buffer_parameters: + self._write_poison_buffer_parameter(out, param, False) + def _write_prologue(self, out: typing_util.Writable, header: bool) -> None: super()._write_prologue(out, header) out.write(""" @@ -82,6 +157,7 @@ def _write_prologue(self, out: typing_util.Writable, header: bool) -> None: #include +#include #include #include """ From 42fa8ea38c2a8ec81118a53acaf1b51ed599f823 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 16:59:28 +0100 Subject: [PATCH 110/211] Update generated PSA wrappers Signed-off-by: Gilles Peskine --- tests/include/test/psa_test_wrappers.h | 1 + tests/src/psa_test_wrappers.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/tests/include/test/psa_test_wrappers.h b/tests/include/test/psa_test_wrappers.h index a7d459c8bd6f..c0ffb415b614 100644 --- a/tests/include/test/psa_test_wrappers.h +++ b/tests/include/test/psa_test_wrappers.h @@ -21,6 +21,7 @@ extern "C" { #include +#include #include #include diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index 86900bcfbb43..0c4ce867ab5c 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -14,6 +14,7 @@ #include +#include #include #include @@ -160,7 +161,11 @@ psa_status_t mbedtls_test_wrap_psa_cipher_encrypt( size_t arg5_output_size, size_t *arg6_output_length) { + MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_output, arg5_output_size); psa_status_t status = (psa_cipher_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_output, arg5_output_size); return status; } From e5ebe5e1f5468fc0181b046b3f664d24bb6c02e1 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 17:11:54 +0100 Subject: [PATCH 111/211] Remove the manually written poisoning wrapper This fixes the build with ASan + MBEDTLS_TEST_HOOKS. Signed-off-by: Gilles Peskine --- .../test/psa_memory_poisoning_wrappers.h | 17 +++++--------- tests/src/psa_memory_poisoning_wrappers.c | 22 ------------------- 2 files changed, 5 insertions(+), 34 deletions(-) diff --git a/tests/include/test/psa_memory_poisoning_wrappers.h b/tests/include/test/psa_memory_poisoning_wrappers.h index 0052c2fae062..3f30b65c0471 100644 --- a/tests/include/test/psa_memory_poisoning_wrappers.h +++ b/tests/include/test/psa_memory_poisoning_wrappers.h @@ -1,8 +1,11 @@ -/** Memory poisoning wrappers for PSA functions. +/** Support for memory poisoning wrappers for PSA functions. * - * These wrappers poison the input and output buffers of each function + * The wrappers poison the input and output buffers of each function * before calling it, to ensure that it does not access the buffers * except by calling the approved buffer-copying functions. + * + * This header declares support functions. The wrappers themselves are + * decalred in the automatically generated file `test/psa_test_wrappers.h`. */ /* * Copyright The Mbed TLS Contributors @@ -32,16 +35,6 @@ void mbedtls_poison_test_hooks_setup(void); */ void mbedtls_poison_test_hooks_teardown(void); -psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length); - -#define psa_cipher_encrypt(...) wrap_psa_cipher_encrypt(__VA_ARGS__) - #endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_TEST_MEMORY_CAN_POISON */ #endif /* PSA_MEMORY_POISONING_WRAPPERS_H */ diff --git a/tests/src/psa_memory_poisoning_wrappers.c b/tests/src/psa_memory_poisoning_wrappers.c index a53e875d4b92..05cba18ee754 100644 --- a/tests/src/psa_memory_poisoning_wrappers.c +++ b/tests/src/psa_memory_poisoning_wrappers.c @@ -27,27 +27,5 @@ void mbedtls_poison_test_hooks_teardown(void) psa_output_post_copy_hook = NULL; } -psa_status_t wrap_psa_cipher_encrypt(mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *input, - size_t input_length, - uint8_t *output, - size_t output_size, - size_t *output_length) -{ - MBEDTLS_TEST_MEMORY_POISON(input, input_length); - MBEDTLS_TEST_MEMORY_POISON(output, output_size); - psa_status_t status = psa_cipher_encrypt(key, - alg, - input, - input_length, - output, - output_size, - output_length); - MBEDTLS_TEST_MEMORY_UNPOISON(input, input_length); - MBEDTLS_TEST_MEMORY_UNPOISON(output, output_size); - return status; -} - #endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_PSA_CRYPTO_C && MBEDTLS_TEST_MEMORY_CAN_POISON */ From 7c7b7d5db34be081a3717c22995bc92e42445196 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 17:28:59 +0100 Subject: [PATCH 112/211] Add review exception warning Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/c_parsing_helper.py | 4 ++++ scripts/mbedtls_dev/c_wrapper_generator.py | 4 ++++ tests/scripts/generate_psa_wrappers.py | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/scripts/mbedtls_dev/c_parsing_helper.py b/scripts/mbedtls_dev/c_parsing_helper.py index 3bb6f0405e87..72214d51c906 100644 --- a/scripts/mbedtls_dev/c_parsing_helper.py +++ b/scripts/mbedtls_dev/c_parsing_helper.py @@ -8,6 +8,10 @@ # Copyright The Mbed TLS Contributors # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +### WARNING: the code in this file has not been extensively reviewed yet. +### We do not think it is harmful, but it may be below our normal standards +### for robustness and maintainability. + import re from typing import Dict, Iterable, Iterator, List, Optional, Tuple diff --git a/scripts/mbedtls_dev/c_wrapper_generator.py b/scripts/mbedtls_dev/c_wrapper_generator.py index 2bed44b2cebe..71d3ba25e7a1 100644 --- a/scripts/mbedtls_dev/c_wrapper_generator.py +++ b/scripts/mbedtls_dev/c_wrapper_generator.py @@ -4,6 +4,10 @@ # Copyright The Mbed TLS Contributors # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +### WARNING: the code in this file has not been extensively reviewed yet. +### We do not think it is harmful, but it may be below our normal standards +### for robustness and maintainability. + import os import re import sys diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 656fcd8881fc..19864ab06ef1 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -5,6 +5,10 @@ # Copyright The Mbed TLS Contributors # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +### WARNING: the code in this file has not been extensively reviewed yet. +### We do not think it is harmful, but it may be below our normal standards +### for robustness and maintainability. + import argparse import itertools import os From b3d457ce2f12983a60c4a822a10d9d9c0a265419 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 20:33:29 +0100 Subject: [PATCH 113/211] PSA wrappers: don't poison buffers when buffer copying is disabled Signed-off-by: Gilles Peskine --- tests/scripts/generate_psa_wrappers.py | 20 ++++++++++++++++---- tests/src/psa_test_wrappers.c | 4 ++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 19864ab06ef1..cce758429143 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -129,6 +129,20 @@ def _write_poison_buffer_parameter(out: typing_util.Writable, param.buffer_name, param.size_name )) + def _write_poison_buffer_parameters(self, out: typing_util.Writable, + buffer_parameters: List[BufferParameter], + poison: bool) -> None: + """Write poisoning or unpoisoning code for the buffer parameters. + + Write poisoning code if poison is true, unpoisoning code otherwise. + """ + if not buffer_parameters: + return + out.write('#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS)\n') + for param in buffer_parameters: + self._write_poison_buffer_parameter(out, param, poison) + out.write('#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */\n') + @staticmethod def _parameter_should_be_copied(function_name: str, _buffer_name: Optional[str]) -> bool: @@ -148,11 +162,9 @@ def _write_function_call(self, out: typing_util.Writable, argument_names) if self._parameter_should_be_copied(function.name, function.arguments[param.index].name)) - for param in buffer_parameters: - self._write_poison_buffer_parameter(out, param, True) + self._write_poison_buffer_parameters(out, buffer_parameters, True) super()._write_function_call(out, function, argument_names) - for param in buffer_parameters: - self._write_poison_buffer_parameter(out, param, False) + self._write_poison_buffer_parameters(out, buffer_parameters, False) def _write_prologue(self, out: typing_util.Writable, header: bool) -> None: super()._write_prologue(out, header) diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index 0c4ce867ab5c..304aad60d63b 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -161,11 +161,15 @@ psa_status_t mbedtls_test_wrap_psa_cipher_encrypt( size_t arg5_output_size, size_t *arg6_output_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_POISON(arg4_output, arg5_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_cipher_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_output, arg5_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From a980aa0894b8eedab97fafc8e97f75c456594747 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 4 Jan 2024 20:51:38 +0100 Subject: [PATCH 114/211] Disable PSA wrappers psa_collect_statuses builds `psa_collect_statuses.py` runs `make RECORD_PSA_STATUS_COVERAGE_LOG=1`, which builds with `RECORD_PSA_STATUS_COVERAGE_LOG`. In this mode, the build includes wrappers for PSA functions, which conflict with the newly introduced wrappers that are enabled whenever `MBEDTLS_TEST_HOOKS` is enabled. In the future, the collect-statuses mechanism should use the new generic wrapper mechanism. For the time being, keep the old wrappers and avoid the new wrappers when doing the collect-statuses build. Signed-off-by: Gilles Peskine --- programs/Makefile | 4 ++++ tests/include/test/psa_test_wrappers.h | 6 ++++-- tests/scripts/generate_psa_wrappers.py | 4 +++- tests/src/psa_test_wrappers.c | 6 ++++-- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/programs/Makefile b/programs/Makefile index 2d32e0028830..255bd837dadd 100644 --- a/programs/Makefile +++ b/programs/Makefile @@ -27,6 +27,10 @@ endif include ../3rdparty/Makefile.inc LOCAL_CFLAGS+=$(THIRDPARTY_INCLUDES) +ifdef RECORD_PSA_STATUS_COVERAGE_LOG +LOCAL_CFLAGS += -Werror -DRECORD_PSA_STATUS_COVERAGE_LOG +endif + ifndef SHARED MBEDLIBS=../library/libmbedcrypto.a ../library/libmbedx509.a ../library/libmbedtls.a else diff --git a/tests/include/test/psa_test_wrappers.h b/tests/include/test/psa_test_wrappers.h index c0ffb415b614..293329642fcc 100644 --- a/tests/include/test/psa_test_wrappers.h +++ b/tests/include/test/psa_test_wrappers.h @@ -17,7 +17,8 @@ extern "C" { #include MBEDTLS_CONFIG_FILE #endif -#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) && \ + !defined(RECORD_PSA_STATUS_COVERAGE_LOG) #include @@ -476,7 +477,8 @@ psa_status_t mbedtls_test_wrap_psa_verify_message( #define psa_verify_message(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_length) \ mbedtls_test_wrap_psa_verify_message(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_length) -#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) */ +#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) && \ + !defined(RECORD_PSA_STATUS_COVERAGE_LOG) */ #ifdef __cplusplus } diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index cce758429143..d35598d26ae2 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -45,7 +45,9 @@ def __init__(self, i: int, is_output: bool, class PSAWrapperGenerator(c_wrapper_generator.Base): """Generate a C source file containing wrapper functions for PSA Crypto API calls.""" - _CPP_GUARDS = 'defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS)' + _CPP_GUARDS = ('defined(MBEDTLS_PSA_CRYPTO_C) && ' + + 'defined(MBEDTLS_TEST_HOOKS) && \\\n ' + + '!defined(RECORD_PSA_STATUS_COVERAGE_LOG)') _WRAPPER_NAME_PREFIX = 'mbedtls_test_wrap_' _WRAPPER_NAME_SUFFIX = '' diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index 304aad60d63b..56bbef03b358 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -10,7 +10,8 @@ #include MBEDTLS_CONFIG_FILE #endif -#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) +#if defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) && \ + !defined(RECORD_PSA_STATUS_COVERAGE_LOG) #include @@ -645,6 +646,7 @@ psa_status_t mbedtls_test_wrap_psa_verify_message( return status; } -#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) */ +#endif /* defined(MBEDTLS_PSA_CRYPTO_C) && defined(MBEDTLS_TEST_HOOKS) && \ + !defined(RECORD_PSA_STATUS_COVERAGE_LOG) */ /* End of automatically generated file. */ From 404160a533ff8d2226dd3591a3584436aaf95f0b Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 8 Jan 2024 13:45:49 +0000 Subject: [PATCH 115/211] Move calculating RR into a separate function So far we needed it only locally here, but we will need calculating RR for safe unblinding in RSA as well. Signed-off-by: Janos Follath --- library/bignum.c | 18 +++++++++++++++--- library/bignum_internal.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 library/bignum_internal.h diff --git a/library/bignum.c b/library/bignum.c index 3e1c48c3208e..551fd81dd95a 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -2039,6 +2039,20 @@ static int mpi_select(mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_ return ret; } +int mbedtls_mpi_get_mont_r2_unsafe(mbedtls_mpi *X, + const mbedtls_mpi *N) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 1)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(X, N->n * 2 * biL)); + MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N)); + MBEDTLS_MPI_CHK(mbedtls_mpi_shrink(X, N->n)); + +cleanup: + return ret; +} + /* * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) */ @@ -2153,9 +2167,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, * If 1st call, pre-compute R^2 mod N */ if (prec_RR == NULL || prec_RR->p == NULL) { - MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&RR, 1)); - MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&RR, N->n * 2 * biL)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&RR, &RR, N)); + mbedtls_mpi_get_mont_r2_unsafe(&RR, N); if (prec_RR != NULL) { memcpy(prec_RR, &RR, sizeof(mbedtls_mpi)); diff --git a/library/bignum_internal.h b/library/bignum_internal.h new file mode 100644 index 000000000000..39909f3dd859 --- /dev/null +++ b/library/bignum_internal.h @@ -0,0 +1,31 @@ +/** + * Low level bignum functions + * + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#ifndef MBEDTLS_BIGNUM_INTERNAL_H +#define MBEDTLS_BIGNUM_INTERNAL_H + +#include "mbedtls/bignum.h" + +/** + * \brief Calculate the square of the Montgomery constant. (Needed + * for conversion and operations in Montgomery form.) + * + * \param[out] X A pointer to the result of the calculation of + * the square of the Montgomery constant: + * 2^{2*n*biL} mod N. + * \param[in] N Little-endian presentation of the modulus, which must be odd. + * + * \return 0 if successful. + * \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if there is not enough space + * to store the value of Montgomery constant squared. + * \return #MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if \p N modulus is zero. + * \return #MBEDTLS_ERR_MPI_NEGATIVE_VALUE if \p N modulus is negative. + */ +int mbedtls_mpi_get_mont_r2_unsafe(mbedtls_mpi *X, + const mbedtls_mpi *N); + +#endif /* MBEDTLS_BIGNUM_INTERNAL_H */ From f9cc4763f1b882aa2be0b59a9e8ab957d34644b7 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 8 Jan 2024 14:08:17 +0000 Subject: [PATCH 116/211] Move some bignum functions to internal header We will need a couple of low level functions to implement safe unblinding in RSA. Signed-off-by: Janos Follath --- library/bignum.c | 67 ++++++++++++++------------------------- library/bignum_internal.h | 40 +++++++++++++++++++++++ 2 files changed, 63 insertions(+), 44 deletions(-) diff --git a/library/bignum.c b/library/bignum.c index 551fd81dd95a..50da6b33b565 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -1907,7 +1907,7 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_s /* * Fast Montgomery initialization (thanks to Tom St Denis) */ -static void mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N) +void mbedtls_mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N) { mbedtls_mpi_uint x, m0 = N->p[0]; unsigned int i; @@ -1922,33 +1922,11 @@ static void mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N) *mm = ~x + 1; } -/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) - * - * \param[in,out] A One of the numbers to multiply. - * It must have at least as many limbs as N - * (A->n >= N->n), and any limbs beyond n are ignored. - * On successful completion, A contains the result of - * the multiplication A * B * R^-1 mod N where - * R = (2^ciL)^n. - * \param[in] B One of the numbers to multiply. - * It must be nonzero and must not have more limbs than N - * (B->n <= N->n). - * \param[in] N The modulo. N must be odd. - * \param mm The value calculated by `mpi_montg_init(&mm, N)`. - * This is -N^-1 mod 2^ciL. - * \param[in,out] T A bignum for temporary storage. - * It must be at least twice the limb size of N plus 2 - * (T->n >= 2 * (N->n + 1)). - * Its initial content is unused and - * its final content is indeterminate. - * Note that unlike the usual convention in the library - * for `const mbedtls_mpi*`, the content of T can change. - */ -static void mpi_montmul(mbedtls_mpi *A, - const mbedtls_mpi *B, - const mbedtls_mpi *N, - mbedtls_mpi_uint mm, - const mbedtls_mpi *T) +void mbedtls_mpi_montmul(mbedtls_mpi *A, + const mbedtls_mpi *B, + const mbedtls_mpi *N, + mbedtls_mpi_uint mm, + const mbedtls_mpi *T) { size_t i, n, m; mbedtls_mpi_uint u0, u1, *d; @@ -1996,7 +1974,8 @@ static void mpi_montmul(mbedtls_mpi *A, /* * Montgomery reduction: A = A * R^-1 mod N * - * See mpi_montmul() regarding constraints and guarantees on the parameters. + * See mbedtls_mpi_montmul() regarding constraints and guarantees on the + * parameters. */ static void mpi_montred(mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T) @@ -2007,7 +1986,7 @@ static void mpi_montred(mbedtls_mpi *A, const mbedtls_mpi *N, U.n = U.s = (int) z; U.p = &z; - mpi_montmul(A, &U, N, mm, T); + mbedtls_mpi_montmul(A, &U, N, mm, T); } /** @@ -2090,7 +2069,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, /* * Init temps and window size */ - mpi_montg_init(&mm, N); + mbedtls_mpi_montg_init(&mm, N); mbedtls_mpi_init(&RR); mbedtls_mpi_init(&T); mbedtls_mpi_init(&Apos); mbedtls_mpi_init(&WW); @@ -2144,10 +2123,10 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, j = N->n + 1; /* All W[i] including the accumulator must have at least N->n limbs for - * the mpi_montmul() and mpi_montred() calls later. Here we ensure that - * W[1] and the accumulator W[x_index] are large enough. later we'll grow - * other W[i] to the same length. They must not be shrunk midway through - * this function! + * the mbedtls_mpi_montmul() and mpi_montred() calls later. Here we ensure + * that W[1] and the accumulator W[x_index] are large enough. later we'll + * grow other W[i] to the same length. They must not be shrunk midway + * through this function! */ MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[x_index], j)); MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], j)); @@ -2183,7 +2162,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&W[1], A, N)); /* This should be a no-op because W[1] is already that large before * mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow - * in mpi_montmul() below, so let's make sure. */ + * in mbedtls_mpi_montmul() below, so let's make sure. */ MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], N->n + 1)); } else { MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[1], A)); @@ -2191,7 +2170,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, /* Note that this is safe because W[1] always has at least N->n limbs * (it grew above and was preserved by mbedtls_mpi_copy()). */ - mpi_montmul(&W[1], &RR, N, mm, &T); + mbedtls_mpi_montmul(&W[1], &RR, N, mm, &T); /* * W[x_index] = R^2 * R^-1 mod N = R mod N @@ -2217,7 +2196,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[j], &W[1])); for (i = 0; i < window_bitsize - 1; i++) { - mpi_montmul(&W[j], &W[j], N, mm, &T); + mbedtls_mpi_montmul(&W[j], &W[j], N, mm, &T); } /* @@ -2227,7 +2206,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[i], N->n + 1)); MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[i], &W[i - 1])); - mpi_montmul(&W[i], &W[1], N, mm, &T); + mbedtls_mpi_montmul(&W[i], &W[1], N, mm, &T); } } @@ -2263,7 +2242,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, * out of window, square W[x_index] */ MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index)); - mpi_montmul(&W[x_index], &WW, N, mm, &T); + mbedtls_mpi_montmul(&W[x_index], &WW, N, mm, &T); continue; } @@ -2282,7 +2261,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, for (i = 0; i < window_bitsize; i++) { MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index)); - mpi_montmul(&W[x_index], &WW, N, mm, &T); + mbedtls_mpi_montmul(&W[x_index], &WW, N, mm, &T); } /* @@ -2290,7 +2269,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, */ MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, exponent_bits_in_window)); - mpi_montmul(&W[x_index], &WW, N, mm, &T); + mbedtls_mpi_montmul(&W[x_index], &WW, N, mm, &T); state--; nbits = 0; @@ -2303,13 +2282,13 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, */ for (i = 0; i < nbits; i++) { MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, x_index)); - mpi_montmul(&W[x_index], &WW, N, mm, &T); + mbedtls_mpi_montmul(&W[x_index], &WW, N, mm, &T); exponent_bits_in_window <<= 1; if ((exponent_bits_in_window & ((size_t) 1 << window_bitsize)) != 0) { MBEDTLS_MPI_CHK(mpi_select(&WW, W, w_table_used_size, 1)); - mpi_montmul(&W[x_index], &WW, N, mm, &T); + mbedtls_mpi_montmul(&W[x_index], &WW, N, mm, &T); } } diff --git a/library/bignum_internal.h b/library/bignum_internal.h index 39909f3dd859..f14c294a5a7a 100644 --- a/library/bignum_internal.h +++ b/library/bignum_internal.h @@ -28,4 +28,44 @@ int mbedtls_mpi_get_mont_r2_unsafe(mbedtls_mpi *X, const mbedtls_mpi *N); +/** + * \brief Calculate initialisation value for fast Montgomery modular + * multiplication. + * + * \param[out] mm The initialisation value for fast Montgomery modular + * multiplication. + * \param[in] N Little-endian presentation of the modulus. This must have + * at least one limb. + */ +void mbedtls_mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N); + +/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) + * + * \param[in,out] A One of the numbers to multiply. + * It must have at least as many limbs as N + * (A->n >= N->n), and any limbs beyond n are ignored. + * On successful completion, A contains the result of + * the multiplication A * B * R^-1 mod N where + * R = (2^ciL)^n. + * \param[in] B One of the numbers to multiply. + * It must be nonzero and must not have more limbs than N + * (B->n <= N->n). + * \param[in] N The modulo. N must be odd. + * \param mm The value calculated by + * `mbedtls_mpi_montg_init(&mm, N)`. + * This is -N^-1 mod 2^ciL. + * \param[in,out] T A bignum for temporary storage. + * It must be at least twice the limb size of N plus 2 + * (T->n >= 2 * (N->n + 1)). + * Its initial content is unused and + * its final content is indeterminate. + * Note that unlike the usual convention in the library + * for `const mbedtls_mpi*`, the content of T can change. + */ +void mbedtls_mpi_montmul(mbedtls_mpi *A, + const mbedtls_mpi *B, + const mbedtls_mpi *N, + mbedtls_mpi_uint mm, + const mbedtls_mpi *T); + #endif /* MBEDTLS_BIGNUM_INTERNAL_H */ From 8b246b3d16407bf2ee1cd33122538290157cb8f0 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 8 Jan 2024 15:09:34 +0000 Subject: [PATCH 117/211] Make RSA unblinding constant flow Signed-off-by: Janos Follath --- library/rsa.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index 84403c457953..937d4aacdbf5 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -34,6 +34,7 @@ #include "mbedtls/error.h" #include "constant_time_internal.h" #include "mbedtls/constant_time.h" +#include "bignum_internal.h" #include @@ -804,6 +805,47 @@ static int rsa_prepare_blinding(mbedtls_rsa_context *ctx, return ret; } +/* + * Unblind + * T = T * Vf mod N + */ +static int rsa_unblind(mbedtls_mpi *T, mbedtls_mpi *Vf, const mbedtls_mpi *N) +{ + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + const size_t nlimbs = N->n; + const size_t tlimbs = 2 * (nlimbs + 1); + + mbedtls_mpi_uint mm; + mbedtls_mpi_montg_init(&mm, N); + + mbedtls_mpi RR, M_T; + + mbedtls_mpi_init(&RR); + mbedtls_mpi_init(&M_T); + + MBEDTLS_MPI_CHK(mbedtls_mpi_get_mont_r2_unsafe(&RR, N)); + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&M_T, tlimbs)); + + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(T, nlimbs)); + MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Vf, nlimbs)); + + /* T = T * Vf mod N + * Reminder: montmul(A, B, N) = A * B * R^-1 mod N + * Usually both operands are multiplied by R mod N beforehand, yielding a + * result that's also * R mod N (aka "in the Montgomery domain"). Here we + * only multiply one operand by R mod N, so the result is directly what we + * want - no need to call `mpi_montred()` on it. */ + mbedtls_mpi_montmul(T, &RR, N, mm, &M_T); + mbedtls_mpi_montmul(T, Vf, N, mm, &M_T); + +cleanup: + + mbedtls_mpi_free(&RR); + mbedtls_mpi_free(&M_T); + + return ret; +} + /* * Exponent blinding supposed to prevent side-channel attacks using multiple * traces of measurements to recover the RSA key. The more collisions are there, @@ -1000,8 +1042,7 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, * Unblind * T = T * Vf mod N */ - MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &T, &ctx->Vf)); - MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, &T, &ctx->N)); + MBEDTLS_MPI_CHK(rsa_unblind(&T, &ctx->Vf, &ctx->N)); } /* Verify the result to prevent glitching attacks. */ From 24bb226232edfd0c31e54ad0ae36654428097230 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Mon, 8 Jan 2024 15:19:11 +0000 Subject: [PATCH 118/211] Extend blinding to RSA result check Signed-off-by: Janos Follath --- library/rsa.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/library/rsa.c b/library/rsa.c index 937d4aacdbf5..23fe84310b70 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -909,7 +909,7 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, /* Temporaries holding the initial input and the double * checked result; should be the same in the end. */ - mbedtls_mpi I, C; + mbedtls_mpi input_blinded, check_result_blinded; RSA_VALIDATE_RET(ctx != NULL); RSA_VALIDATE_RET(input != NULL); @@ -946,8 +946,8 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, mbedtls_mpi_init(&TP); mbedtls_mpi_init(&TQ); #endif - mbedtls_mpi_init(&I); - mbedtls_mpi_init(&C); + mbedtls_mpi_init(&input_blinded); + mbedtls_mpi_init(&check_result_blinded); /* End of MPI initialization */ @@ -957,8 +957,6 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, goto cleanup; } - MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&I, &T)); - if (f_rng != NULL) { /* * Blinding @@ -1010,6 +1008,9 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, #endif /* MBEDTLS_RSA_NO_CRT */ } + /* Make a copy of the input (after blinding if there was any) */ + MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&input_blinded, &T)); + #if defined(MBEDTLS_RSA_NO_CRT) MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&T, &T, D, &ctx->N, &ctx->RN)); #else @@ -1037,6 +1038,14 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&T, &TQ, &TP)); #endif /* MBEDTLS_RSA_NO_CRT */ + /* Verify the result to prevent glitching attacks. */ + MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&check_result_blinded, &T, &ctx->E, + &ctx->N, &ctx->RN)); + if (mbedtls_mpi_cmp_mpi(&check_result_blinded, &input_blinded) != 0) { + ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; + goto cleanup; + } + if (f_rng != NULL) { /* * Unblind @@ -1045,14 +1054,6 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, MBEDTLS_MPI_CHK(rsa_unblind(&T, &ctx->Vf, &ctx->N)); } - /* Verify the result to prevent glitching attacks. */ - MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&C, &T, &ctx->E, - &ctx->N, &ctx->RN)); - if (mbedtls_mpi_cmp_mpi(&C, &I) != 0) { - ret = MBEDTLS_ERR_RSA_VERIFY_FAILED; - goto cleanup; - } - olen = ctx->len; MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&T, output, olen)); @@ -1082,8 +1083,8 @@ int mbedtls_rsa_private(mbedtls_rsa_context *ctx, mbedtls_mpi_free(&TP); mbedtls_mpi_free(&TQ); #endif - mbedtls_mpi_free(&C); - mbedtls_mpi_free(&I); + mbedtls_mpi_free(&check_result_blinded); + mbedtls_mpi_free(&input_blinded); if (ret != 0 && ret >= -0x007f) { return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_RSA_PRIVATE_FAILED, ret); From 54b2edaa8b336da76a4439e7e93f310d18c87714 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Fri, 29 Dec 2023 11:14:58 +0000 Subject: [PATCH 119/211] Add warning for PKCS 1.5 decryption Any timing variance dependant on the output of this function enables a Bleichenbacher attack. It is extremely difficult to use safely. In the Marvin attack paper (https://people.redhat.com/~hkario/marvin/marvin-attack-paper.pdf) the author suggests that implementations of PKCS 1.5 decryption that don't include a countermeasure should be considered inherently dangerous. They suggest that all libraries implement the same countermeasure, as implementing different countermeasures across libraries enables the Bleichenbacher attack as well. This is extremely fragile and therefore we don't implement it. The use of PKCS 1.5 in Mbed TLS implements the countermeasures recommended in the TLS standard (7.4.7.1 of RFC 5246) and is not vulnerable. Add a warning to PKCS 1.5 decryption to warn users about this. Signed-off-by: Janos Follath --- include/mbedtls/rsa.h | 9 +++++++++ include/psa/crypto_values.h | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/include/mbedtls/rsa.h b/include/mbedtls/rsa.h index 667e6257e678..1779775155f3 100644 --- a/include/mbedtls/rsa.h +++ b/include/mbedtls/rsa.h @@ -712,6 +712,10 @@ int mbedtls_rsa_rsaes_oaep_encrypt(mbedtls_rsa_context *ctx, * It is the generic wrapper for performing a PKCS#1 decryption * operation using the \p mode from the context. * + * \warning When \p ctx->padding is set to #MBEDTLS_RSA_PKCS_V15, + * mbedtls_rsa_rsaes_pkcs1_v15_decrypt() is called, which is an + * inherently dangerous function (CWE-242). + * * \note The output buffer length \c output_max_len should be * as large as the size \p ctx->len of \p ctx->N (for example, * 128 Bytes if RSA-1024 is used) to be able to hold an @@ -761,6 +765,11 @@ int mbedtls_rsa_pkcs1_decrypt(mbedtls_rsa_context *ctx, * \brief This function performs a PKCS#1 v1.5 decryption * operation (RSAES-PKCS1-v1_5-DECRYPT). * + * \warning This is an inherently dangerous function (CWE-242). Unless + * it is used in a side channel free and safe way (eg. + * implementing the TLS protocol as per 7.4.7.1 of RFC 5246), + * the calling code is vulnerable. + * * \note The output buffer length \c output_max_len should be * as large as the size \p ctx->len of \p ctx->N, for example, * 128 Bytes if RSA-1024 is used, to be able to hold an diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index a3982499043a..c25fda63ec28 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -1659,6 +1659,13 @@ 0) /** RSA PKCS#1 v1.5 encryption. + * + * \warning Calling psa_asymmetric_decrypt() with this algorithm as a + * parameter is considered an inherently dangerous function + * (CWE-242). Unless it is used in a side channel free and safe + * way (eg. implementing the TLS protocol as per 7.4.7.1 of + * RFC 5246), the calling code is vulnerable. + * */ #define PSA_ALG_RSA_PKCS1V15_CRYPT ((psa_algorithm_t) 0x07000200) From d50f7a7a17bc7b64d16470d30656e0859121cfd0 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 21 Nov 2023 09:57:27 +0000 Subject: [PATCH 120/211] Add Changelog for the Marvin attack fix Signed-off-by: Janos Follath --- ChangeLog.d/fix-Marvin-attack.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ChangeLog.d/fix-Marvin-attack.txt diff --git a/ChangeLog.d/fix-Marvin-attack.txt b/ChangeLog.d/fix-Marvin-attack.txt new file mode 100644 index 000000000000..017f7b1f805f --- /dev/null +++ b/ChangeLog.d/fix-Marvin-attack.txt @@ -0,0 +1,6 @@ +Security + * Fix a timing side channel in RSA private operations. This side channel + could be sufficient for a local attacker to recover the plaintext. It + requires the attacker to send a large number of messages for decryption. + For details, see "Everlasting ROBOT: the Marvin Attack", Hubert Kario. + Reported by Hubert Kario, Red Hat. From f81f191770e9833a8e49d6c0cadd7f46daaa69da Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Mon, 8 Jan 2024 21:05:42 +0100 Subject: [PATCH 121/211] Fix parsing of C line comments Fix // comments stopping on 'n' instead of newlines. Also allow backslash-newline in // comments. Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/c_parsing_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mbedtls_dev/c_parsing_helper.py b/scripts/mbedtls_dev/c_parsing_helper.py index 72214d51c906..2657b7d230dd 100644 --- a/scripts/mbedtls_dev/c_parsing_helper.py +++ b/scripts/mbedtls_dev/c_parsing_helper.py @@ -76,7 +76,7 @@ def returns_void(self) -> bool: # Match one C comment. # Note that we match both comment types, so things like // in a /*...*/ # comment are handled correctly. -_C_COMMENT_RE = re.compile(r'//[^n]*|/\*.*?\*/', re.S) +_C_COMMENT_RE = re.compile(r'//(?:[^\n]|\\\n)*|/\*.*?\*/', re.S) _NOT_NEWLINES_RE = re.compile(r'[^\n]+') def read_logical_lines(filename: str) -> Iterator[Tuple[int, str]]: From 6f499b7ed4206b47259c9b413ae17082478c3dad Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 9 Jan 2024 09:28:48 +0000 Subject: [PATCH 122/211] Align Montgomery init with development The signature and naming of the Montgomrey initialisation function in development and in the LTS was different. Align them for easier readability and maintenance. Signed-off-by: Janos Follath --- library/bignum.c | 16 +++++++--------- library/bignum_internal.h | 12 ++++++------ library/rsa.c | 3 +-- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/library/bignum.c b/library/bignum.c index 50da6b33b565..74f10af8d5d3 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -1907,19 +1907,17 @@ int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_s /* * Fast Montgomery initialization (thanks to Tom St Denis) */ -void mbedtls_mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N) +mbedtls_mpi_uint mbedtls_mpi_montmul_init(const mbedtls_mpi_uint *N) { - mbedtls_mpi_uint x, m0 = N->p[0]; - unsigned int i; + mbedtls_mpi_uint x = N[0]; - x = m0; - x += ((m0 + 2) & 4) << 1; + x += ((N[0] + 2) & 4) << 1; - for (i = biL; i >= 8; i /= 2) { - x *= (2 - (m0 * x)); + for (unsigned int i = biL; i >= 8; i /= 2) { + x *= (2 - (N[0] * x)); } - *mm = ~x + 1; + return ~x + 1; } void mbedtls_mpi_montmul(mbedtls_mpi *A, @@ -2069,7 +2067,7 @@ int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A, /* * Init temps and window size */ - mbedtls_mpi_montg_init(&mm, N); + mm = mbedtls_mpi_montmul_init(N->p); mbedtls_mpi_init(&RR); mbedtls_mpi_init(&T); mbedtls_mpi_init(&Apos); mbedtls_mpi_init(&WW); diff --git a/library/bignum_internal.h b/library/bignum_internal.h index f14c294a5a7a..5435ebb46490 100644 --- a/library/bignum_internal.h +++ b/library/bignum_internal.h @@ -30,14 +30,14 @@ int mbedtls_mpi_get_mont_r2_unsafe(mbedtls_mpi *X, /** * \brief Calculate initialisation value for fast Montgomery modular - * multiplication. + * multiplication * - * \param[out] mm The initialisation value for fast Montgomery modular - * multiplication. - * \param[in] N Little-endian presentation of the modulus. This must have - * at least one limb. + * \param[in] N Little-endian presentation of the modulus. This must have + * at least one limb. + * + * \return The initialisation value for fast Montgomery modular multiplication */ -void mbedtls_mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N); +mbedtls_mpi_uint mbedtls_mpi_montmul_init(const mbedtls_mpi_uint *N); /** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) * diff --git a/library/rsa.c b/library/rsa.c index 23fe84310b70..0a0c2e388097 100644 --- a/library/rsa.c +++ b/library/rsa.c @@ -815,8 +815,7 @@ static int rsa_unblind(mbedtls_mpi *T, mbedtls_mpi *Vf, const mbedtls_mpi *N) const size_t nlimbs = N->n; const size_t tlimbs = 2 * (nlimbs + 1); - mbedtls_mpi_uint mm; - mbedtls_mpi_montg_init(&mm, N); + mbedtls_mpi_uint mm = mbedtls_mpi_montmul_init(N->p); mbedtls_mpi RR, M_T; From 8b736290adef79089084a8f3b8ba15c086805922 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Tue, 9 Jan 2024 09:37:06 +0000 Subject: [PATCH 123/211] Fix 'missing prototype' warnings Signed-off-by: Janos Follath --- library/bignum.c | 1 + 1 file changed, 1 insertion(+) diff --git a/library/bignum.c b/library/bignum.c index 74f10af8d5d3..fadd9e9cc2a2 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -30,6 +30,7 @@ #include "mbedtls/platform_util.h" #include "mbedtls/error.h" #include "constant_time_internal.h" +#include "bignum_internal.h" #include #include From ce4a3c25fe36003c76b4c05ae1fa5286b91b4178 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Wed, 10 Jan 2024 08:54:17 +0000 Subject: [PATCH 124/211] Add new internal header to visualc project Signed-off-by: Janos Follath --- visualc/VS2010/mbedTLS.vcxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 1ffc1f6e0557..18b613ee02e2 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -260,6 +260,7 @@ + From 756b4dcfa4859fd362ebd276cb1241719a93443a Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 10 Jan 2024 14:33:17 +0000 Subject: [PATCH 125/211] Use thread-local flag to enable memory poisoning Allow memory poisoning to be enabled and disabled at runtime using a thread-local flag. This allows poisoning to be disabled whenever a PSA function is called but not through the test wrappers, removing false positive use-after-poisons. Signed-off-by: David Horstmann --- tests/include/test/memory.h | 21 ++++++++++++++++++--- tests/src/test_memory.c | 12 +++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/tests/include/test/memory.h b/tests/include/test/memory.h index 43fbb6350f09..0bf8f469d546 100644 --- a/tests/include/test/memory.h +++ b/tests/include/test/memory.h @@ -21,9 +21,12 @@ * memory as poisoned, which can be used to enforce some memory access * policies. * + * Support for the C11 thread_local keyword is also required. + * * Currently, only Asan (Address Sanitizer) is supported. */ -#if defined(MBEDTLS_TEST_HAVE_ASAN) +#if defined(MBEDTLS_TEST_HAVE_ASAN) && \ + (__STDC_VERSION__ >= 201112L) # define MBEDTLS_TEST_MEMORY_CAN_POISON #endif @@ -61,6 +64,12 @@ #if defined(MBEDTLS_TEST_MEMORY_CAN_POISON) +/** Thread-local variable used to enable memory poisoning. This is set and + * unset in the test wrappers so that calls to PSA functions from the library + * do not poison memory. + */ +extern _Thread_local int mbedtls_test_memory_poisoning_enabled; + /** Poison a memory area so that any attempt to read or write from it will * cause a runtime failure. * @@ -68,7 +77,10 @@ */ void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size); #define MBEDTLS_TEST_MEMORY_POISON(ptr, size) \ - mbedtls_test_memory_poison(ptr, size) + do { \ + mbedtls_test_memory_poisoning_enabled = 1; \ + mbedtls_test_memory_poison(ptr, size); \ + } while (0) /** Undo the effect of mbedtls_test_memory_poison(). * @@ -79,7 +91,10 @@ void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size); */ void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size); #define MBEDTLS_TEST_MEMORY_UNPOISON(ptr, size) \ - mbedtls_test_memory_unpoison(ptr, size) + do { \ + mbedtls_test_memory_unpoison(ptr, size); \ + mbedtls_test_memory_poisoning_enabled = 0; \ + } while (0) #else /* MBEDTLS_TEST_MEMORY_CAN_POISON */ #define MBEDTLS_TEST_MEMORY_POISON(ptr, size) ((void) (ptr), (void) (size)) diff --git a/tests/src/test_memory.c b/tests/src/test_memory.c index c277be85abd9..dbb7b20de246 100644 --- a/tests/src/test_memory.c +++ b/tests/src/test_memory.c @@ -13,12 +13,15 @@ #include #include -#if defined(MBEDTLS_TEST_HAVE_ASAN) +#if defined(MBEDTLS_TEST_MEMORY_CAN_POISON) #include #include #endif -#if defined(MBEDTLS_TEST_HAVE_ASAN) +#if defined(MBEDTLS_TEST_MEMORY_CAN_POISON) + +_Thread_local int mbedtls_test_memory_poisoning_enabled = 0; + static void align_for_asan(const unsigned char **p_ptr, size_t *p_size) { uintptr_t start = (uintptr_t) *p_ptr; @@ -36,6 +39,9 @@ static void align_for_asan(const unsigned char **p_ptr, size_t *p_size) void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size) { + if (!mbedtls_test_memory_poisoning_enabled) { + return; + } if (size == 0) { return; } @@ -51,4 +57,4 @@ void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size) align_for_asan(&ptr, &size); __asan_unpoison_memory_region(ptr, size); } -#endif /* Asan */ +#endif /* Memory poisoning */ From d074a5a14709248b46c0d5c40ea73791735ee8a5 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 11 Jan 2024 16:33:46 +0000 Subject: [PATCH 126/211] Only run memory poisoning metatests when poisoning When we cannot memory poison due to platform constraints, do not attempt to run memory poisoning metatests (but still run other ASan metatests). Signed-off-by: David Horstmann --- programs/test/metatest.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/programs/test/metatest.c b/programs/test/metatest.c index 1724aed0bd11..6fcf52a50503 100644 --- a/programs/test/metatest.c +++ b/programs/test/metatest.c @@ -366,6 +366,7 @@ metatest_t metatests[] = { { "double_free", "asan", double_free }, { "read_uninitialized_stack", "msan", read_uninitialized_stack }, { "memory_leak", "asan", memory_leak }, +#if defined(MBEDTLS_TEST_MEMORY_CAN_POISON) { "test_memory_poison_0_0_8_r", "asan", test_memory_poison }, { "test_memory_poison_0_0_8_w", "asan", test_memory_poison }, { "test_memory_poison_0_7_8_r", "asan", test_memory_poison }, @@ -382,6 +383,7 @@ metatest_t metatests[] = { { "test_memory_poison_7_0_1_w", "asan", test_memory_poison }, { "test_memory_poison_7_1_2_r", "asan", test_memory_poison }, { "test_memory_poison_7_1_2_w", "asan", test_memory_poison }, +#endif /* MBEDTLS_TEST_MEMORY_CAN_POISON */ { "mutex_lock_not_initialized", "pthread", mutex_lock_not_initialized }, { "mutex_unlock_not_initialized", "pthread", mutex_unlock_not_initialized }, { "mutex_free_not_initialized", "pthread", mutex_free_not_initialized }, From 86bbb137798e134efe2e16ddfae15740c7242889 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 11 Jan 2024 14:24:02 +0000 Subject: [PATCH 127/211] Update Marvin fix Changelog entry Upon further consideration we think that a remote attacker close to the victim might be able to have precise enough timing information to exploit the side channel as well. Update the Changelog to reflect this. Signed-off-by: Janos Follath --- ChangeLog.d/fix-Marvin-attack.txt | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog.d/fix-Marvin-attack.txt b/ChangeLog.d/fix-Marvin-attack.txt index 017f7b1f805f..763533c25c2e 100644 --- a/ChangeLog.d/fix-Marvin-attack.txt +++ b/ChangeLog.d/fix-Marvin-attack.txt @@ -1,6 +1,8 @@ Security - * Fix a timing side channel in RSA private operations. This side channel - could be sufficient for a local attacker to recover the plaintext. It - requires the attacker to send a large number of messages for decryption. - For details, see "Everlasting ROBOT: the Marvin Attack", Hubert Kario. - Reported by Hubert Kario, Red Hat. + * Fix a timing side channel in private key RSA operations. This side channel + could be sufficient for an attacker to recover the plaintext. A local + attacker or a remote attacker who is close to the victim on the network + might have precise enough timing measurements to exploit this. It requires + the attacker to send a large number of messages for decryption. For + details, see "Everlasting ROBOT: the Marvin Attack", Hubert Kario. Reported + by Hubert Kario, Red Hat. From 6de58282888033f08efc7eff06193e3426af0a68 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 17 Jan 2024 14:23:20 +0000 Subject: [PATCH 128/211] Change memory poisoning flag to a count This allows unusually-nested memory poisoning to work correctly, since it keeps track of whether any buffers are still poisoned, rather than just disabling poisoning at the first call to the UNPOISON() macro. Signed-off-by: David Horstmann --- tests/include/test/memory.h | 6 +++--- tests/src/test_memory.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/include/test/memory.h b/tests/include/test/memory.h index 0bf8f469d546..6d0f76478a3a 100644 --- a/tests/include/test/memory.h +++ b/tests/include/test/memory.h @@ -68,7 +68,7 @@ * unset in the test wrappers so that calls to PSA functions from the library * do not poison memory. */ -extern _Thread_local int mbedtls_test_memory_poisoning_enabled; +extern _Thread_local unsigned int mbedtls_test_memory_poisoning_count; /** Poison a memory area so that any attempt to read or write from it will * cause a runtime failure. @@ -78,7 +78,7 @@ extern _Thread_local int mbedtls_test_memory_poisoning_enabled; void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size); #define MBEDTLS_TEST_MEMORY_POISON(ptr, size) \ do { \ - mbedtls_test_memory_poisoning_enabled = 1; \ + mbedtls_test_memory_poisoning_count++; \ mbedtls_test_memory_poison(ptr, size); \ } while (0) @@ -93,7 +93,7 @@ void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size); #define MBEDTLS_TEST_MEMORY_UNPOISON(ptr, size) \ do { \ mbedtls_test_memory_unpoison(ptr, size); \ - mbedtls_test_memory_poisoning_enabled = 0; \ + mbedtls_test_memory_poisoning_count--; \ } while (0) #else /* MBEDTLS_TEST_MEMORY_CAN_POISON */ diff --git a/tests/src/test_memory.c b/tests/src/test_memory.c index dbb7b20de246..ac9dde616366 100644 --- a/tests/src/test_memory.c +++ b/tests/src/test_memory.c @@ -20,7 +20,7 @@ #if defined(MBEDTLS_TEST_MEMORY_CAN_POISON) -_Thread_local int mbedtls_test_memory_poisoning_enabled = 0; +_Thread_local unsigned int mbedtls_test_memory_poisoning_count = 0; static void align_for_asan(const unsigned char **p_ptr, size_t *p_size) { @@ -39,7 +39,7 @@ static void align_for_asan(const unsigned char **p_ptr, size_t *p_size) void mbedtls_test_memory_poison(const unsigned char *ptr, size_t size) { - if (!mbedtls_test_memory_poisoning_enabled) { + if (mbedtls_test_memory_poisoning_count == 0) { return; } if (size == 0) { From 1b421b1005ccadf8678cf8b102c105c9eb86cffe Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 17 Jan 2024 14:53:08 +0000 Subject: [PATCH 129/211] Separate memory poisoning tests from generic ASan Some platforms may support ASan but be C99-only (no C11 support). These platforms will support ASan metatests but not memory poisoning, which requires C11 features. To allow for this, create a separate platform requirement, "poison", in metatest.c to distinguish generic ASan metatests from ones that require suppport for memory poisoning. In practice our platforms support both, so run "poison" tests in the same all.sh components where we run "asan" ones. Signed-off-by: David Horstmann --- programs/test/metatest.c | 34 ++++++++++++++++------------------ tests/scripts/all.sh | 4 ++-- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/programs/test/metatest.c b/programs/test/metatest.c index 6fcf52a50503..a0826219159f 100644 --- a/programs/test/metatest.c +++ b/programs/test/metatest.c @@ -366,24 +366,22 @@ metatest_t metatests[] = { { "double_free", "asan", double_free }, { "read_uninitialized_stack", "msan", read_uninitialized_stack }, { "memory_leak", "asan", memory_leak }, -#if defined(MBEDTLS_TEST_MEMORY_CAN_POISON) - { "test_memory_poison_0_0_8_r", "asan", test_memory_poison }, - { "test_memory_poison_0_0_8_w", "asan", test_memory_poison }, - { "test_memory_poison_0_7_8_r", "asan", test_memory_poison }, - { "test_memory_poison_0_7_8_w", "asan", test_memory_poison }, - { "test_memory_poison_0_0_1_r", "asan", test_memory_poison }, - { "test_memory_poison_0_0_1_w", "asan", test_memory_poison }, - { "test_memory_poison_0_1_2_r", "asan", test_memory_poison }, - { "test_memory_poison_0_1_2_w", "asan", test_memory_poison }, - { "test_memory_poison_7_0_8_r", "asan", test_memory_poison }, - { "test_memory_poison_7_0_8_w", "asan", test_memory_poison }, - { "test_memory_poison_7_7_8_r", "asan", test_memory_poison }, - { "test_memory_poison_7_7_8_w", "asan", test_memory_poison }, - { "test_memory_poison_7_0_1_r", "asan", test_memory_poison }, - { "test_memory_poison_7_0_1_w", "asan", test_memory_poison }, - { "test_memory_poison_7_1_2_r", "asan", test_memory_poison }, - { "test_memory_poison_7_1_2_w", "asan", test_memory_poison }, -#endif /* MBEDTLS_TEST_MEMORY_CAN_POISON */ + { "test_memory_poison_0_0_8_r", "poison", test_memory_poison }, + { "test_memory_poison_0_0_8_w", "poison", test_memory_poison }, + { "test_memory_poison_0_7_8_r", "poison", test_memory_poison }, + { "test_memory_poison_0_7_8_w", "poison", test_memory_poison }, + { "test_memory_poison_0_0_1_r", "poison", test_memory_poison }, + { "test_memory_poison_0_0_1_w", "poison", test_memory_poison }, + { "test_memory_poison_0_1_2_r", "poison", test_memory_poison }, + { "test_memory_poison_0_1_2_w", "poison", test_memory_poison }, + { "test_memory_poison_7_0_8_r", "poison", test_memory_poison }, + { "test_memory_poison_7_0_8_w", "poison", test_memory_poison }, + { "test_memory_poison_7_7_8_r", "poison", test_memory_poison }, + { "test_memory_poison_7_7_8_w", "poison", test_memory_poison }, + { "test_memory_poison_7_0_1_r", "poison", test_memory_poison }, + { "test_memory_poison_7_0_1_w", "poison", test_memory_poison }, + { "test_memory_poison_7_1_2_r", "poison", test_memory_poison }, + { "test_memory_poison_7_1_2_w", "poison", test_memory_poison }, { "mutex_lock_not_initialized", "pthread", mutex_lock_not_initialized }, { "mutex_unlock_not_initialized", "pthread", mutex_unlock_not_initialized }, { "mutex_free_not_initialized", "pthread", mutex_free_not_initialized }, diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 02513e903ab7..81be111fd5c8 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -876,7 +876,7 @@ component_test_default_cmake_gcc_asan () { programs/test/selftest msg "test: metatests (GCC, ASan build)" - tests/scripts/run-metatests.sh any asan + tests/scripts/run-metatests.sh any asan poison msg "test: ssl-opt.sh (ASan build)" # ~ 1 min tests/ssl-opt.sh @@ -1497,7 +1497,7 @@ component_test_everest () { make test msg "test: metatests (clang, ASan)" - tests/scripts/run-metatests.sh any asan + tests/scripts/run-metatests.sh any asan poison msg "test: Everest ECDH context - ECDH-related part of ssl-opt.sh (ASan build)" # ~ 5s tests/ssl-opt.sh -f ECDH From e7bfbc27bf0cbaf181b741dcf42a36758dd17840 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 17 Jan 2024 15:27:50 +0000 Subject: [PATCH 130/211] Add underflow check to UNPOISON counter decrement Make sure that extra UNPOISON calls do not cause the poisoning counter to underflow and wrap around. Memory that is unpoisoned multiple times should remain unpoisoned. Signed-off-by: David Horstmann --- tests/include/test/memory.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/include/test/memory.h b/tests/include/test/memory.h index 6d0f76478a3a..91be573b9b9b 100644 --- a/tests/include/test/memory.h +++ b/tests/include/test/memory.h @@ -93,7 +93,9 @@ void mbedtls_test_memory_unpoison(const unsigned char *ptr, size_t size); #define MBEDTLS_TEST_MEMORY_UNPOISON(ptr, size) \ do { \ mbedtls_test_memory_unpoison(ptr, size); \ - mbedtls_test_memory_poisoning_count--; \ + if (mbedtls_test_memory_poisoning_count != 0) { \ + mbedtls_test_memory_poisoning_count--; \ + } \ } while (0) #else /* MBEDTLS_TEST_MEMORY_CAN_POISON */ From 7dfb6121fc5b7fb8d088f67a46519795486c744d Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 23 Jan 2024 15:35:20 +0000 Subject: [PATCH 131/211] Remove _Thread_local variable for 2.28 We do not intend to support multithreaded testing in 2.28, so introducing a C11 feature here is an unnecessary burden. Signed-off-by: David Horstmann --- tests/include/test/memory.h | 13 +++++-------- tests/src/test_memory.c | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/include/test/memory.h b/tests/include/test/memory.h index 91be573b9b9b..d4bbeec0d4fe 100644 --- a/tests/include/test/memory.h +++ b/tests/include/test/memory.h @@ -21,12 +21,9 @@ * memory as poisoned, which can be used to enforce some memory access * policies. * - * Support for the C11 thread_local keyword is also required. - * * Currently, only Asan (Address Sanitizer) is supported. */ -#if defined(MBEDTLS_TEST_HAVE_ASAN) && \ - (__STDC_VERSION__ >= 201112L) +#if defined(MBEDTLS_TEST_HAVE_ASAN) # define MBEDTLS_TEST_MEMORY_CAN_POISON #endif @@ -64,11 +61,11 @@ #if defined(MBEDTLS_TEST_MEMORY_CAN_POISON) -/** Thread-local variable used to enable memory poisoning. This is set and - * unset in the test wrappers so that calls to PSA functions from the library - * do not poison memory. +/** Variable used to enable memory poisoning. This is set and unset in the + * test wrappers so that calls to PSA functions from the library do not + * poison memory. */ -extern _Thread_local unsigned int mbedtls_test_memory_poisoning_count; +extern unsigned int mbedtls_test_memory_poisoning_count; /** Poison a memory area so that any attempt to read or write from it will * cause a runtime failure. diff --git a/tests/src/test_memory.c b/tests/src/test_memory.c index ac9dde616366..9da7f20a36ce 100644 --- a/tests/src/test_memory.c +++ b/tests/src/test_memory.c @@ -20,7 +20,7 @@ #if defined(MBEDTLS_TEST_MEMORY_CAN_POISON) -_Thread_local unsigned int mbedtls_test_memory_poisoning_count = 0; +unsigned int mbedtls_test_memory_poisoning_count = 0; static void align_for_asan(const unsigned char **p_ptr, size_t *p_size) { From 21c1a948131b8d8eb18677172143417ac3736ed3 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 28 Nov 2023 19:25:00 +0000 Subject: [PATCH 132/211] Copy buffers in psa_aead_encrypt() Signed-off-by: David Horstmann --- library/psa_crypto.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 00e4f2aa987e..4221079be908 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3796,19 +3796,24 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *nonce, + const uint8_t *nonce_external, size_t nonce_length, - const uint8_t *additional_data, + const uint8_t *additional_data_external, size_t additional_data_length, - const uint8_t *plaintext, + const uint8_t *plaintext_external, size_t plaintext_length, - uint8_t *ciphertext, + uint8_t *ciphertext_external, size_t ciphertext_size, size_t *ciphertext_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; + LOCAL_INPUT_DECLARE(nonce_external, nonce); + LOCAL_INPUT_DECLARE(additional_data_external, additional_data); + LOCAL_INPUT_DECLARE(plaintext_external, plaintext); + LOCAL_OUTPUT_DECLARE(ciphertext_external, ciphertext); + *ciphertext_length = 0; if (!PSA_ALG_IS_AEAD(alg) || PSA_ALG_IS_WILDCARD(alg)) { @@ -3825,6 +3830,11 @@ psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, .core = slot->attr }; + LOCAL_INPUT_ALLOC(nonce_external, nonce_length, nonce); + LOCAL_INPUT_ALLOC(additional_data_external, additional_data_length, additional_data); + LOCAL_INPUT_ALLOC(plaintext_external, plaintext_length, plaintext); + LOCAL_OUTPUT_ALLOC(ciphertext_external, ciphertext_size, ciphertext); + status = psa_driver_wrapper_aead_encrypt( &attributes, slot->key.data, slot->key.bytes, alg, @@ -3837,6 +3847,15 @@ psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, memset(ciphertext, 0, ciphertext_size); } +/* Exit label is only used for buffer copying, prevent unused warnings. */ +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +exit: +#endif + LOCAL_INPUT_FREE(nonce_external, nonce); + LOCAL_INPUT_FREE(additional_data_external, additional_data); + LOCAL_INPUT_FREE(plaintext_external, plaintext); + LOCAL_OUTPUT_FREE(ciphertext_external, ciphertext); + psa_unlock_key_slot(slot); return status; From 6baf6e9a0632867325d9a22e4f1410488d3ffd9e Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 28 Nov 2023 19:43:53 +0000 Subject: [PATCH 133/211] Add buffer copying to psa_aead_decrypt() Signed-off-by: David Horstmann --- library/psa_crypto.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 4221079be908..3ca3be1cb8c0 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3863,19 +3863,24 @@ psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *nonce, + const uint8_t *nonce_external, size_t nonce_length, - const uint8_t *additional_data, + const uint8_t *additional_data_external, size_t additional_data_length, - const uint8_t *ciphertext, + const uint8_t *ciphertext_external, size_t ciphertext_length, - uint8_t *plaintext, + uint8_t *plaintext_external, size_t plaintext_size, size_t *plaintext_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; + LOCAL_INPUT_DECLARE(nonce_external, nonce); + LOCAL_INPUT_DECLARE(additional_data_external, additional_data); + LOCAL_INPUT_DECLARE(ciphertext_external, ciphertext); + LOCAL_OUTPUT_DECLARE(plaintext_external, plaintext); + *plaintext_length = 0; if (!PSA_ALG_IS_AEAD(alg) || PSA_ALG_IS_WILDCARD(alg)) { @@ -3892,6 +3897,12 @@ psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, .core = slot->attr }; + LOCAL_INPUT_ALLOC(nonce_external, nonce_length, nonce); + LOCAL_INPUT_ALLOC(additional_data_external, additional_data_length, + additional_data); + LOCAL_INPUT_ALLOC(ciphertext_external, ciphertext_length, ciphertext); + LOCAL_OUTPUT_ALLOC(plaintext_external, plaintext_size, plaintext); + status = psa_driver_wrapper_aead_decrypt( &attributes, slot->key.data, slot->key.bytes, alg, @@ -3904,6 +3915,15 @@ psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, memset(plaintext, 0, plaintext_size); } +/* Exit label is only used for buffer copying, prevent unused warnings. */ +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +exit: +#endif + LOCAL_INPUT_FREE(nonce_external, nonce); + LOCAL_INPUT_FREE(additional_data_external, additional_data); + LOCAL_INPUT_FREE(ciphertext_external, ciphertext); + LOCAL_OUTPUT_FREE(plaintext_external, plaintext); + psa_unlock_key_slot(slot); return status; From 436b2ef6338b1ea511e27640f27e6d68213280ca Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 22 Jan 2024 14:36:01 +0000 Subject: [PATCH 134/211] Generate poisoning wrappers for AEAD Modify wrapper generation script to generate poisoning calls and regenerate wrappers. Signed-off-by: David Horstmann --- tests/scripts/generate_psa_wrappers.py | 3 ++- tests/src/psa_test_wrappers.c | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index d35598d26ae2..cace6e3c3ba4 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -150,7 +150,8 @@ def _parameter_should_be_copied(function_name: str, _buffer_name: Optional[str]) -> bool: """Whether the specified buffer argument to a PSA function should be copied. """ - # Proof-of-concept: just instrument one function for now + if function_name.startswith('psa_aead'): + return True if function_name == 'psa_cipher_encrypt': return True return False diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index 56bbef03b358..b6815c1f6a62 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -66,7 +66,19 @@ psa_status_t mbedtls_test_wrap_psa_aead_decrypt( size_t arg9_plaintext_size, size_t *arg10_plaintext_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_nonce, arg3_nonce_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_additional_data, arg5_additional_data_length); + MBEDTLS_TEST_MEMORY_POISON(arg6_ciphertext, arg7_ciphertext_length); + MBEDTLS_TEST_MEMORY_POISON(arg8_plaintext, arg9_plaintext_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_aead_decrypt)(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_ciphertext, arg7_ciphertext_length, arg8_plaintext, arg9_plaintext_size, arg10_plaintext_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_nonce, arg3_nonce_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_additional_data, arg5_additional_data_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg6_ciphertext, arg7_ciphertext_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg8_plaintext, arg9_plaintext_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -84,7 +96,19 @@ psa_status_t mbedtls_test_wrap_psa_aead_encrypt( size_t arg9_ciphertext_size, size_t *arg10_ciphertext_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_nonce, arg3_nonce_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_additional_data, arg5_additional_data_length); + MBEDTLS_TEST_MEMORY_POISON(arg6_plaintext, arg7_plaintext_length); + MBEDTLS_TEST_MEMORY_POISON(arg8_ciphertext, arg9_ciphertext_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_aead_encrypt)(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_plaintext, arg7_plaintext_length, arg8_ciphertext, arg9_ciphertext_size, arg10_ciphertext_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_nonce, arg3_nonce_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_additional_data, arg5_additional_data_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg6_plaintext, arg7_plaintext_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg8_ciphertext, arg9_ciphertext_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From 3b0c371c04cc92e10a6f50b0adb5c0a96f68a5cc Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 24 Jan 2024 13:07:17 +0100 Subject: [PATCH 135/211] Add allocate and copy style output buffer handling Add a new macro `LOCAL_OUTPUT_ALLOC_WITH_COPY` to support the output buffer handling of the multipart operations like `psa_cipher_update`. This will allocate a local buffer and copy the content of the original buffer. Signed-off-by: Gabor Mezei --- library/psa_crypto.c | 50 +++++++++++++++++++++++++++++++++++++++ library/psa_crypto_core.h | 19 +++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 00e4f2aa987e..05467bdb7c95 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -182,6 +182,23 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = } \ output_copy = LOCAL_OUTPUT_COPY_OF_##output.buffer; +/* Allocate a copy of the buffer output and set the pointer output_copy to + * point to the start of the copy. + * + * Assumptions: + * - psa_status_t status exists + * - An exit label is declared + * - output is the name of a pointer to the buffer to be copied + * - LOCAL_OUTPUT_DECLARE(output, output_copy) has previously been called + */ +#define LOCAL_OUTPUT_ALLOC_WITH_COPY(output, length, output_copy) \ + status = psa_crypto_local_output_alloc_with_copy(output, length, \ + &LOCAL_OUTPUT_COPY_OF_##output); \ + if (status != PSA_SUCCESS) { \ + goto exit; \ + } \ + output_copy = LOCAL_OUTPUT_COPY_OF_##output.buffer; + /* Free the local output copy allocated previously by LOCAL_OUTPUT_ALLOC() * after first copying back its contents to the original buffer. * @@ -5783,6 +5800,39 @@ psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len, return PSA_SUCCESS; } +psa_status_t psa_crypto_local_output_alloc_with_copy(uint8_t *output, size_t output_len, + psa_crypto_local_output_t *local_output) +{ + psa_status_t status; + *local_output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; + + if (output_len == 0) { + return PSA_SUCCESS; + } + 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; + } + local_output->length = output_len; + local_output->original = output; + + status = psa_crypto_copy_input(output, output_len, + local_output->buffer, local_output->length); + if (status != PSA_SUCCESS) { + goto error; + } + + return PSA_SUCCESS; + +error: + mbedtls_free(local_output->buffer); + local_output->buffer = NULL; + local_output->length = 0; + return status; +} + psa_status_t psa_crypto_local_output_free(psa_crypto_local_output_t *local_output) { psa_status_t status; diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 4731064f85f3..ae8af09d91a6 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -560,6 +560,25 @@ typedef struct psa_crypto_local_output_s { psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len, psa_crypto_local_output_t *local_output); +/** Allocate a local copy of an output buffer and copy the contents into it. + * + * \note This allocates and copies a buffer + * whose contents will be copied back to the + * original in a future call to + * psa_crypto_local_output_free(). + * + * \param[in] output Pointer to output buffer. + * \param[in] output_len Length of the output buffer. + * \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_local_output_alloc_with_copy(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. * From 8e3a837e1be7fd1a44f165ee72adb4b3c7020440 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 26 Jan 2024 10:28:56 +0000 Subject: [PATCH 136/211] Remove already-assembled Changelog entries Signed-off-by: Dave Rodgman --- ChangeLog.d/fix-Marvin-attack.txt | 8 -------- ChangeLog.d/license.txt | 3 --- 2 files changed, 11 deletions(-) delete mode 100644 ChangeLog.d/fix-Marvin-attack.txt delete mode 100644 ChangeLog.d/license.txt diff --git a/ChangeLog.d/fix-Marvin-attack.txt b/ChangeLog.d/fix-Marvin-attack.txt deleted file mode 100644 index 763533c25c2e..000000000000 --- a/ChangeLog.d/fix-Marvin-attack.txt +++ /dev/null @@ -1,8 +0,0 @@ -Security - * Fix a timing side channel in private key RSA operations. This side channel - could be sufficient for an attacker to recover the plaintext. A local - attacker or a remote attacker who is close to the victim on the network - might have precise enough timing measurements to exploit this. It requires - the attacker to send a large number of messages for decryption. For - details, see "Everlasting ROBOT: the Marvin Attack", Hubert Kario. Reported - by Hubert Kario, Red Hat. diff --git a/ChangeLog.d/license.txt b/ChangeLog.d/license.txt deleted file mode 100644 index 0b6bb1f02258..000000000000 --- a/ChangeLog.d/license.txt +++ /dev/null @@ -1,3 +0,0 @@ -Changes - * Mbed TLS is now released under a dual Apache-2.0 OR GPL-2.0-or-later - license. Users may choose which license they take the code under. From 290aac472a95580506a2d9451e9f8c6e8f577135 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Thu, 18 Jan 2024 17:23:02 +0000 Subject: [PATCH 137/211] Implement safe buffer copying in asymmetric signature API Use local copy buffer macros to implement safe copy mechanism in asymmetric signature API. Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 83 +++++++++++++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 05467bdb7c95..a100b794a471 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3007,15 +3007,25 @@ psa_status_t psa_sign_message_builtin( psa_status_t psa_sign_message(mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *input, + const uint8_t *input_external, size_t input_length, - uint8_t *signature, + uint8_t *signature_external, size_t signature_size, size_t *signature_length) { - return psa_sign_internal( - key, 1, alg, input, input_length, - signature, signature_size, signature_length); + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(input_external, input); + LOCAL_OUTPUT_DECLARE(signature_external, signature); + + LOCAL_INPUT_ALLOC(input_external, input_length, input); + LOCAL_OUTPUT_ALLOC(signature_external, signature_size, signature); + status = psa_sign_internal(key, 1, alg, input, input_length, signature, + signature_size, signature_length); + +exit: + LOCAL_INPUT_FREE(input_external, input); + LOCAL_OUTPUT_FREE(signature_external, signature); + return status; } psa_status_t psa_verify_message_builtin( @@ -3054,14 +3064,25 @@ psa_status_t psa_verify_message_builtin( psa_status_t psa_verify_message(mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *input, + const uint8_t *input_external, size_t input_length, - const uint8_t *signature, + const uint8_t *signature_external, size_t signature_length) { - return psa_verify_internal( - key, 1, alg, input, input_length, - signature, signature_length); + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(input_external, input); + LOCAL_INPUT_DECLARE(signature_external, signature); + + LOCAL_INPUT_ALLOC(input_external, input_length, input); + LOCAL_INPUT_ALLOC(signature_external, signature_length, signature); + status = psa_verify_internal(key, 1, alg, input, input_length, signature, + signature_length); + +exit: + LOCAL_INPUT_FREE(input_external, input); + LOCAL_INPUT_FREE(signature_external, signature); + + return status; } psa_status_t psa_sign_hash_builtin( @@ -3114,15 +3135,26 @@ psa_status_t psa_sign_hash_builtin( psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *hash, + const uint8_t *hash_external, size_t hash_length, - uint8_t *signature, + uint8_t *signature_external, size_t signature_size, size_t *signature_length) { - return psa_sign_internal( - key, 0, alg, hash, hash_length, - signature, signature_size, signature_length); + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(hash_external, hash); + LOCAL_OUTPUT_DECLARE(signature_external, signature); + + LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); + LOCAL_OUTPUT_ALLOC(signature_external, signature_size, signature); + status = psa_sign_internal(key, 0, alg, hash, hash_length, signature, + signature_size, signature_length); + +exit: + LOCAL_INPUT_FREE(hash_external, hash); + LOCAL_OUTPUT_FREE(signature_external, signature); + + return status; } psa_status_t psa_verify_hash_builtin( @@ -3174,14 +3206,25 @@ psa_status_t psa_verify_hash_builtin( psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *hash, + const uint8_t *hash_external, size_t hash_length, - const uint8_t *signature, + const uint8_t *signature_external, size_t signature_length) { - return psa_verify_internal( - key, 0, alg, hash, hash_length, - signature, signature_length); + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(hash_external, hash); + LOCAL_INPUT_DECLARE(signature_external, signature); + + LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); + LOCAL_INPUT_ALLOC(signature_external, signature_length, signature); + status = psa_verify_internal(key, 0, alg, hash, hash_length, signature, + signature_length); + +exit: + LOCAL_INPUT_FREE(hash_external, hash); + LOCAL_INPUT_FREE(signature_external, signature); + + return status; } #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) From c63e31af8bf91e1f5a42b909987d709fbf578918 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Tue, 30 Jan 2024 13:33:14 +0000 Subject: [PATCH 138/211] Generate test wrappers Signed-off-by: Thomas Daubney --- tests/scripts/generate_psa_wrappers.py | 5 ++++ tests/src/psa_test_wrappers.c | 32 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index d35598d26ae2..7e746567831a 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -153,6 +153,11 @@ def _parameter_should_be_copied(function_name: str, # Proof-of-concept: just instrument one function for now if function_name == 'psa_cipher_encrypt': return True + if function_name in ('psa_sign_message', + 'psa_verify_message', + 'psa_sign_hash', + 'psa_verify_hash'): + return True return False def _write_function_call(self, out: typing_util.Writable, diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index 56bbef03b358..effd42b330f8 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -602,7 +602,15 @@ psa_status_t mbedtls_test_wrap_psa_sign_hash( size_t arg5_signature_size, size_t *arg6_signature_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_hash, arg3_hash_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_signature, arg5_signature_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_sign_hash)(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_size, arg6_signature_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_hash, arg3_hash_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_signature, arg5_signature_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -616,7 +624,15 @@ psa_status_t mbedtls_test_wrap_psa_sign_message( size_t arg5_signature_size, size_t *arg6_signature_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_signature, arg5_signature_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_sign_message)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_size, arg6_signature_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_signature, arg5_signature_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -629,7 +645,15 @@ psa_status_t mbedtls_test_wrap_psa_verify_hash( const uint8_t *arg4_signature, size_t arg5_signature_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_hash, arg3_hash_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_signature, arg5_signature_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_verify_hash)(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_hash, arg3_hash_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_signature, arg5_signature_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -642,7 +666,15 @@ psa_status_t mbedtls_test_wrap_psa_verify_message( const uint8_t *arg4_signature, size_t arg5_signature_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_signature, arg5_signature_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_verify_message)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_signature, arg5_signature_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From f446b8917db02a43054ce2573d879c24baa887b7 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Tue, 30 Jan 2024 13:36:01 +0000 Subject: [PATCH 139/211] Conditionally include exit label ...on functions where the label was only added due to the modifications required by this PR. Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a100b794a471..106e17425979 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3022,7 +3022,9 @@ psa_status_t psa_sign_message(mbedtls_svc_key_id_t key, status = psa_sign_internal(key, 1, alg, input, input_length, signature, signature_size, signature_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: +#endif LOCAL_INPUT_FREE(input_external, input); LOCAL_OUTPUT_FREE(signature_external, signature); return status; @@ -3078,7 +3080,9 @@ psa_status_t psa_verify_message(mbedtls_svc_key_id_t key, status = psa_verify_internal(key, 1, alg, input, input_length, signature, signature_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: +#endif LOCAL_INPUT_FREE(input_external, input); LOCAL_INPUT_FREE(signature_external, signature); @@ -3150,7 +3154,9 @@ psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key, status = psa_sign_internal(key, 0, alg, hash, hash_length, signature, signature_size, signature_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: +#endif LOCAL_INPUT_FREE(hash_external, hash); LOCAL_OUTPUT_FREE(signature_external, signature); @@ -3220,7 +3226,9 @@ psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key, status = psa_verify_internal(key, 0, alg, hash, hash_length, signature, signature_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: +#endif LOCAL_INPUT_FREE(hash_external, hash); LOCAL_INPUT_FREE(signature_external, signature); From 90b94ff85f73381a7ec819387d19de6eb037c264 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 1 Feb 2024 19:32:46 +0000 Subject: [PATCH 140/211] Allow GCM IV to be NULL if zero-length The operation will still return an error, but the assert-based validation checks will pass. This allows GCM to work with buffer copies / local inputs, which may be NULL when they are zero-length. Signed-off-by: David Horstmann --- library/gcm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/gcm.c b/library/gcm.c index 86d5fa2b5fce..d3e773278fbb 100644 --- a/library/gcm.c +++ b/library/gcm.c @@ -241,7 +241,7 @@ int mbedtls_gcm_starts(mbedtls_gcm_context *ctx, uint64_t iv_bits; GCM_VALIDATE_RET(ctx != NULL); - GCM_VALIDATE_RET(iv != NULL); + GCM_VALIDATE_RET(iv_len == 0 || iv != NULL); GCM_VALIDATE_RET(add_len == 0 || add != NULL); /* IV and AD are limited to 2^64 bits, so 2^61 bytes */ @@ -433,7 +433,7 @@ int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; GCM_VALIDATE_RET(ctx != NULL); - GCM_VALIDATE_RET(iv != NULL); + GCM_VALIDATE_RET(iv_len == 0 || iv != NULL); GCM_VALIDATE_RET(add_len == 0 || add != NULL); GCM_VALIDATE_RET(length == 0 || input != NULL); GCM_VALIDATE_RET(length == 0 || output != NULL); @@ -470,7 +470,7 @@ int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx, int diff; GCM_VALIDATE_RET(ctx != NULL); - GCM_VALIDATE_RET(iv != NULL); + GCM_VALIDATE_RET(iv_len == 0 || iv != NULL); GCM_VALIDATE_RET(add_len == 0 || add != NULL); GCM_VALIDATE_RET(tag != NULL); GCM_VALIDATE_RET(length == 0 || input != NULL); From 6b9702546653083100049bb97f81ae67898d1ce5 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 19 Jan 2024 16:02:59 +0000 Subject: [PATCH 141/211] Protect buffer in psa_import_key Signed-off-by: Ryan Everett --- library/psa_crypto.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 106e17425979..2b09d8f7566e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2063,11 +2063,12 @@ static psa_status_t psa_validate_optional_attributes( } psa_status_t psa_import_key(const psa_key_attributes_t *attributes, - const uint8_t *data, + const uint8_t *data_external, size_t data_length, mbedtls_svc_key_id_t *key) { psa_status_t status; + LOCAL_INPUT_DECLARE(data_external, data); psa_key_slot_t *slot = NULL; psa_se_drv_table_entry_t *driver = NULL; size_t bits; @@ -2081,6 +2082,8 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes, return PSA_ERROR_INVALID_ARGUMENT; } + LOCAL_INPUT_ALLOC(data_external, data_length, data); + status = psa_start_key_creation(PSA_KEY_CREATION_IMPORT, attributes, &slot, &driver); if (status != PSA_SUCCESS) { @@ -2122,6 +2125,7 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes, status = psa_finish_key_creation(slot, driver, key); exit: + LOCAL_INPUT_FREE(data_external, data); if (status != PSA_SUCCESS) { psa_fail_key_creation(slot, driver); } From e3e760cddbc56cdc0e05644780a0570033a3da2e Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 19 Jan 2024 16:03:50 +0000 Subject: [PATCH 142/211] Protect buffer in psa_export_key Signed-off-by: Ryan Everett --- library/psa_crypto.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 2b09d8f7566e..9690d531bf38 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1483,14 +1483,14 @@ psa_status_t psa_export_key_internal( } psa_status_t psa_export_key(mbedtls_svc_key_id_t key, - uint8_t *data, + uint8_t *data_external, size_t data_size, size_t *data_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - + LOCAL_OUTPUT_DECLARE(data_external, data); /* Reject a zero-length output buffer now, since this can never be a * valid key representation. This way we know that data must be a valid * pointer and we can do things like memset(data, ..., data_size). */ @@ -1514,6 +1514,8 @@ psa_status_t psa_export_key(mbedtls_svc_key_id_t key, return status; } + LOCAL_OUTPUT_ALLOC(data_external, data_size, data); + psa_key_attributes_t attributes = { .core = slot->attr }; @@ -1521,8 +1523,10 @@ psa_status_t psa_export_key(mbedtls_svc_key_id_t key, slot->key.data, slot->key.bytes, data, data_size, data_length); +exit: unlock_status = psa_unlock_key_slot(slot); + LOCAL_OUTPUT_FREE(data_external, data); return (status == PSA_SUCCESS) ? unlock_status : status; } From 30827915a47366b4621ab611f6576d543d6458b3 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 19 Jan 2024 16:05:00 +0000 Subject: [PATCH 143/211] Protect buffer in psa_export_public_key Signed-off-by: Ryan Everett --- library/psa_crypto.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 9690d531bf38..3e7fc9a1e4f8 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1586,7 +1586,7 @@ psa_status_t psa_export_public_key_internal( } psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, - uint8_t *data, + uint8_t *data_external, size_t data_size, size_t *data_length) { @@ -1594,6 +1594,7 @@ psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_attributes_t attributes; psa_key_slot_t *slot; + LOCAL_OUTPUT_DECLARE(data_external, data); /* Reject a zero-length output buffer now, since this can never be a * valid key representation. This way we know that data must be a valid @@ -1614,6 +1615,8 @@ psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, return status; } + LOCAL_OUTPUT_ALLOC(data_external, data_size, data); + if (!PSA_KEY_TYPE_IS_ASYMMETRIC(slot->attr.type)) { status = PSA_ERROR_INVALID_ARGUMENT; goto exit; @@ -1629,6 +1632,7 @@ psa_status_t psa_export_public_key(mbedtls_svc_key_id_t key, exit: unlock_status = psa_unlock_key_slot(slot); + LOCAL_OUTPUT_FREE(data_external, data); return (status == PSA_SUCCESS) ? unlock_status : status; } From dcbc1d3750cc915d2b187721c91abab914479cd0 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 25 Jan 2024 11:04:48 +0000 Subject: [PATCH 144/211] Generate test wrappers for key management Signed-off-by: Ryan Everett --- tests/scripts/generate_psa_wrappers.py | 2 +- tests/src/psa_test_wrappers.c | 26 ++++++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 7e746567831a..fa9419fc00fa 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -151,7 +151,7 @@ def _parameter_should_be_copied(function_name: str, """Whether the specified buffer argument to a PSA function should be copied. """ # Proof-of-concept: just instrument one function for now - if function_name == 'psa_cipher_encrypt': + if function_name == 'psa_import_key' or function_name == 'psa_export_key' or function_name == 'psa_export_public_key': return True if function_name in ('psa_sign_message', 'psa_verify_message', diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index effd42b330f8..dbe8b25050df 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -162,15 +162,7 @@ psa_status_t mbedtls_test_wrap_psa_cipher_encrypt( size_t arg5_output_size, size_t *arg6_output_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) - MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); - MBEDTLS_TEST_MEMORY_POISON(arg4_output, arg5_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_cipher_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) - MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); - MBEDTLS_TEST_MEMORY_UNPOISON(arg4_output, arg5_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -261,7 +253,13 @@ psa_status_t mbedtls_test_wrap_psa_export_key( size_t arg2_data_size, size_t *arg3_data_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_data, arg2_data_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_export_key)(arg0_key, arg1_data, arg2_data_size, arg3_data_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_data, arg2_data_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -272,7 +270,13 @@ psa_status_t mbedtls_test_wrap_psa_export_public_key( size_t arg2_data_size, size_t *arg3_data_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_data, arg2_data_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_export_public_key)(arg0_key, arg1_data, arg2_data_size, arg3_data_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_data, arg2_data_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -392,7 +396,13 @@ psa_status_t mbedtls_test_wrap_psa_import_key( size_t arg2_data_length, mbedtls_svc_key_id_t *arg3_key) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_data, arg2_data_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_import_key)(arg0_attributes, arg1_data, arg2_data_length, arg3_key); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_data, arg2_data_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From 3a4153a768b79c015471a3a79ca5c248545412db Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 25 Jan 2024 12:04:55 +0000 Subject: [PATCH 145/211] Conditionally guard exit label to stop unused label error Signed-off-by: Ryan Everett --- library/psa_crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 3e7fc9a1e4f8..cff9ccaf2b21 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1523,7 +1523,9 @@ psa_status_t psa_export_key(mbedtls_svc_key_id_t key, slot->key.data, slot->key.bytes, data, data_size, data_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: +#endif unlock_status = psa_unlock_key_slot(slot); LOCAL_OUTPUT_FREE(data_external, data); From 810421ccc61f932836e5341d1dbfc2424576ad29 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 25 Jan 2024 12:09:09 +0000 Subject: [PATCH 146/211] Re-add cipher_encrypt buffer copying Signed-off-by: Ryan Everett --- tests/scripts/generate_psa_wrappers.py | 2 ++ tests/src/psa_test_wrappers.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index fa9419fc00fa..a1c775adc0fe 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -151,6 +151,8 @@ def _parameter_should_be_copied(function_name: str, """Whether the specified buffer argument to a PSA function should be copied. """ # Proof-of-concept: just instrument one function for now + if function_name == 'psa_cipher_encrypt': + return True if function_name == 'psa_import_key' or function_name == 'psa_export_key' or function_name == 'psa_export_public_key': return True if function_name in ('psa_sign_message', diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index dbe8b25050df..c074e8d7cca5 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -162,7 +162,15 @@ psa_status_t mbedtls_test_wrap_psa_cipher_encrypt( size_t arg5_output_size, size_t *arg6_output_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_output, arg5_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_cipher_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_output, arg5_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From cb4f8554567078b346b64a06a018e6d314a64536 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Thu, 25 Jan 2024 14:40:16 +0000 Subject: [PATCH 147/211] Fix line-too-long in script Signed-off-by: Ryan Everett --- tests/scripts/generate_psa_wrappers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index a1c775adc0fe..7fc852edc1c2 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -153,7 +153,9 @@ def _parameter_should_be_copied(function_name: str, # Proof-of-concept: just instrument one function for now if function_name == 'psa_cipher_encrypt': return True - if function_name == 'psa_import_key' or function_name == 'psa_export_key' or function_name == 'psa_export_public_key': + if function_name in ('psa_import_key', + 'psa_export_key', + 'psa_export_public_key'): return True if function_name in ('psa_sign_message', 'psa_verify_message', From c8b6c050141fc24243bcd6c0a3c71b9cec44bb00 Mon Sep 17 00:00:00 2001 From: Ryan Everett <144035422+Ryan-Everett-arm@users.noreply.github.com> Date: Thu, 25 Jan 2024 15:20:09 +0000 Subject: [PATCH 148/211] Update tests/scripts/generate_psa_wrappers.py Co-authored-by: David Horstmann Signed-off-by: Ryan Everett --- tests/scripts/generate_psa_wrappers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 7fc852edc1c2..d7970c0e379b 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -153,9 +153,9 @@ def _parameter_should_be_copied(function_name: str, # Proof-of-concept: just instrument one function for now if function_name == 'psa_cipher_encrypt': return True - if function_name in ('psa_import_key', - 'psa_export_key', - 'psa_export_public_key'): + if function_name in ('psa_import_key', + 'psa_export_key', + 'psa_export_public_key'): return True if function_name in ('psa_sign_message', 'psa_verify_message', From 081803d6ec4044e4d2a19da65bd2b453c4ef486b Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 2 Feb 2024 10:48:49 +0000 Subject: [PATCH 149/211] Remove unnecessary dependencies from psa_crypto_helpers.h Signed-off-by: Ryan Everett --- tests/include/test/psa_crypto_helpers.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index 5648738da69e..e60c96669fca 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -17,16 +17,10 @@ #include -#include "test/psa_test_wrappers.h" - #if defined(MBEDTLS_USE_PSA_CRYPTO) #include "mbedtls/psa_util.h" #endif -#if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \ - && defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) -#include "test/psa_memory_poisoning_wrappers.h" -#endif #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) From 448bc018d0286cbd1fcdb60ad91c706b35c43df6 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 6 Feb 2024 16:46:38 +0000 Subject: [PATCH 150/211] Add testcase to fail multipart cipher tests Encrypt more than 2 blocks of data, causing both update() calls to output data as well as the call to finish(). This exposes a test bug where the pointer to a buffer is not updated as it is filled with data. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.data | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 03cc2ffe67e0..c5211f94aa5e 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1971,6 +1971,11 @@ PSA symmetric encrypt/decrypt multipart: AES-CBC-nopad, 16 bytes, good depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES cipher_verify_output_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":16 +# Encrypt 48 bytes total, initially 16. This forces both calls to update() to output data. +PSA symmetric encrypt/decrypt multipart: AES-CBC-nopad, 48 bytes, good +depends_on:PSA_WANT_ALG_CBC_NO_PADDING:PSA_WANT_KEY_TYPE_AES +cipher_verify_output_multipart:PSA_ALG_CBC_NO_PADDING:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a6bc1bee22e409f96e93d7e117393172a6bc1bee22e409f96e93d7e117393172a":16 + PSA symmetric encrypt/decrypt multipart: AES-CBC-PKCS#7, 16 bytes depends_on:PSA_WANT_ALG_CBC_PKCS7:PSA_WANT_KEY_TYPE_AES cipher_verify_output_multipart:PSA_ALG_CBC_PKCS7:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"6bc1bee22e409f96e93d7e117393172a":16 From 7274590ef6d3d5354bb4012731ee937f69a7490c Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 6 Feb 2024 17:03:13 +0000 Subject: [PATCH 151/211] Update buffer start and length in multipart test This fixes a test failure in which the buffer was not properly filled. Signed-off-by: David Horstmann --- tests/suites/test_suite_psa_crypto.function | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 796a62a5f143..26f7350f0e3b 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -3291,7 +3291,8 @@ void cipher_verify_output_multipart(int alg_arg, PSA_ASSERT(psa_cipher_update(&operation1, input->x + first_part_size, input->len - first_part_size, - output1, output1_buffer_size, + output1 + output1_length, + output1_buffer_size - output1_length, &function_output_length)); TEST_LE_U(function_output_length, PSA_CIPHER_UPDATE_OUTPUT_SIZE(key_type, @@ -3337,7 +3338,8 @@ void cipher_verify_output_multipart(int alg_arg, PSA_ASSERT(psa_cipher_update(&operation2, output1 + first_part_size, output1_length - first_part_size, - output2, output2_buffer_size, + output2 + output2_length, + output2_buffer_size - output2_length, &function_output_length)); TEST_LE_U(function_output_length, PSA_CIPHER_UPDATE_OUTPUT_SIZE(key_type, From 08bd24635d6db05275659eab0e3cb124db39e760 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 9 Feb 2024 16:15:32 +0000 Subject: [PATCH 152/211] Add buffer copying to psa_key_derivation_output_bytes Signed-off-by: Ryan Everett --- library/psa_crypto.c | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index cff9ccaf2b21..af80c0ceab0c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -4360,10 +4360,12 @@ static psa_status_t psa_key_derivation_tls12_prf_read( psa_status_t psa_key_derivation_output_bytes( psa_key_derivation_operation_t *operation, - uint8_t *output, + uint8_t *output_external, size_t output_length) { psa_status_t status; + LOCAL_OUTPUT_DECLARE(output_external, output); + psa_algorithm_t kdf_alg = psa_key_derivation_get_kdf_alg(operation); if (operation->alg == 0) { @@ -4371,13 +4373,6 @@ psa_status_t psa_key_derivation_output_bytes( return PSA_ERROR_BAD_STATE; } - if (output_length > operation->capacity) { - operation->capacity = 0; - /* Go through the error path to wipe all confidential data now - * that the operation object is useless. */ - status = PSA_ERROR_INSUFFICIENT_DATA; - goto exit; - } if (output_length == 0 && operation->capacity == 0) { /* Edge case: this is a finished operation, and 0 bytes * were requested. The right error in this case could @@ -4387,6 +4382,15 @@ psa_status_t psa_key_derivation_output_bytes( * output_length > 0. */ return PSA_ERROR_INSUFFICIENT_DATA; } + + LOCAL_OUTPUT_ALLOC(output_external, output_length, output); + if (output_length > operation->capacity) { + operation->capacity = 0; + /* Go through the error path to wipe all confidential data now + * that the operation object is useless. */ + status = PSA_ERROR_INSUFFICIENT_DATA; + goto exit; + } operation->capacity -= output_length; #if defined(MBEDTLS_PSA_BUILTIN_ALG_HKDF) @@ -4408,7 +4412,10 @@ psa_status_t psa_key_derivation_output_bytes( * MBEDTLS_PSA_BUILTIN_ALG_TLS12_PSK_TO_MS */ { (void) kdf_alg; - return PSA_ERROR_BAD_STATE; + status = PSA_ERROR_BAD_STATE; + LOCAL_OUTPUT_FREE(output_external, output); + + return status; } exit: @@ -4420,8 +4427,12 @@ psa_status_t psa_key_derivation_output_bytes( psa_algorithm_t alg = operation->alg; psa_key_derivation_abort(operation); operation->alg = alg; - memset(output, '!', output_length); + if (output != NULL) { + memset(output, '!', output_length); + } } + + LOCAL_OUTPUT_FREE(output_external, output); return status; } From 6f68206b1837ef71b3b22717f84e9b52f07b2fab Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 9 Feb 2024 16:18:39 +0000 Subject: [PATCH 153/211] Add buffer copying to psa_key_derivation_input_bytes Signed-off-by: Ryan Everett --- library/psa_crypto.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index af80c0ceab0c..2db317f55d77 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -4983,12 +4983,20 @@ static psa_status_t psa_key_derivation_input_internal( psa_status_t psa_key_derivation_input_bytes( psa_key_derivation_operation_t *operation, psa_key_derivation_step_t step, - const uint8_t *data, + const uint8_t *data_external, size_t data_length) { - return psa_key_derivation_input_internal(operation, step, - PSA_KEY_TYPE_NONE, - data, data_length); + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(data_external, data); + + LOCAL_INPUT_ALLOC(data_external, data_length, data); + + status = psa_key_derivation_input_internal(operation, step, + PSA_KEY_TYPE_NONE, + data, data_length); +exit: + LOCAL_INPUT_FREE(data_external, data); + return status; } psa_status_t psa_key_derivation_input_key( From 6c9e69d53bc4dd17d43ff838fc74be2867bfd3cd Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Fri, 9 Feb 2024 16:23:25 +0000 Subject: [PATCH 154/211] Add key derivation testing wrappers Signed-off-by: Ryan Everett --- tests/scripts/generate_psa_wrappers.py | 3 +++ tests/src/psa_test_wrappers.c | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index d7970c0e379b..c0ddebb50bc0 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -153,6 +153,9 @@ def _parameter_should_be_copied(function_name: str, # Proof-of-concept: just instrument one function for now if function_name == 'psa_cipher_encrypt': return True + if function_name in ('psa_key_derivation_output_bytes', + 'psa_key_derivation_input_bytes'): + return True if function_name in ('psa_import_key', 'psa_export_key', 'psa_export_public_key'): diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index c074e8d7cca5..301d374a7951 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -438,7 +438,13 @@ psa_status_t mbedtls_test_wrap_psa_key_derivation_input_bytes( const uint8_t *arg2_data, size_t arg3_data_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_data, arg3_data_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_key_derivation_input_bytes)(arg0_operation, arg1_step, arg2_data, arg3_data_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_data, arg3_data_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -470,7 +476,13 @@ psa_status_t mbedtls_test_wrap_psa_key_derivation_output_bytes( uint8_t *arg1_output, size_t arg2_output_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_output, arg2_output_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_key_derivation_output_bytes)(arg0_operation, arg1_output, arg2_output_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_output, arg2_output_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From d0d12fb42fdedbfa3eb271aa326dae753ed3a9b6 Mon Sep 17 00:00:00 2001 From: Ryan Everett Date: Mon, 12 Feb 2024 09:19:29 +0000 Subject: [PATCH 155/211] Conditionally guard exit label to deter unused label error Co-authored-by: David Horstmann Signed-off-by: Ryan Everett --- library/psa_crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 2db317f55d77..751e0f517260 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -4994,7 +4994,9 @@ psa_status_t psa_key_derivation_input_bytes( status = psa_key_derivation_input_internal(operation, step, PSA_KEY_TYPE_NONE, data, data_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: +#endif LOCAL_INPUT_FREE(data_external, data); return status; } From 62cb36a5f268cc947d5490561837f56282ffc194 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Fri, 12 Jan 2024 16:50:26 +0000 Subject: [PATCH 156/211] Implement safe buffer copying in hash API Use local copy buffer macros to implement safe copy mechanism in hash API. Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 75 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 13 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index cff9ccaf2b21..a75bcc60875a 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2320,10 +2320,11 @@ psa_status_t psa_hash_setup(psa_hash_operation_t *operation, } psa_status_t psa_hash_update(psa_hash_operation_t *operation, - const uint8_t *input, + const uint8_t *input_external, size_t input_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(input_external, input); if (operation->id == 0) { status = PSA_ERROR_BAD_STATE; @@ -2336,6 +2337,7 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation, return PSA_SUCCESS; } + LOCAL_INPUT_ALLOC(input_external, input_length, input); status = psa_driver_wrapper_hash_update(operation, input, input_length); exit: @@ -2343,32 +2345,55 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation, psa_hash_abort(operation); } + LOCAL_INPUT_FREE(input_external, input); return status; } -psa_status_t psa_hash_finish(psa_hash_operation_t *operation, +static psa_status_t psa_hash_finish_internal(psa_hash_operation_t *operation, uint8_t *hash, size_t hash_size, size_t *hash_length) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + *hash_length = 0; if (operation->id == 0) { return PSA_ERROR_BAD_STATE; } - psa_status_t status = psa_driver_wrapper_hash_finish( + status = psa_driver_wrapper_hash_finish( operation, hash, hash_size, hash_length); psa_hash_abort(operation); + + return status; +} + +psa_status_t psa_hash_finish(psa_hash_operation_t *operation, + uint8_t *hash_external, + size_t hash_size, + size_t *hash_length) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_OUTPUT_DECLARE(hash_external, hash); + + LOCAL_OUTPUT_ALLOC(hash_external, hash_size, hash); + status = psa_hash_finish_internal(operation, hash, hash_size, hash_length); + +exit: + LOCAL_OUTPUT_FREE(hash_external, hash); return status; } psa_status_t psa_hash_verify(psa_hash_operation_t *operation, - const uint8_t *hash, + const uint8_t *hash_external, size_t hash_length) { uint8_t actual_hash[PSA_HASH_MAX_SIZE]; size_t actual_hash_length; - psa_status_t status = psa_hash_finish( + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(hash_external, hash); + + status = psa_hash_finish_internal( operation, actual_hash, sizeof(actual_hash), &actual_hash_length); @@ -2382,6 +2407,7 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation, goto exit; } + LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); if (mbedtls_psa_safer_memcmp(hash, actual_hash, actual_hash_length) != 0) { status = PSA_ERROR_INVALID_SIGNATURE; } @@ -2391,36 +2417,53 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation, if (status != PSA_SUCCESS) { psa_hash_abort(operation); } - + LOCAL_INPUT_FREE(hash_external, hash); return status; } psa_status_t psa_hash_compute(psa_algorithm_t alg, - const uint8_t *input, size_t input_length, - uint8_t *hash, size_t hash_size, + const uint8_t *input_external, size_t input_length, + uint8_t *hash_external, size_t hash_size, size_t *hash_length) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(input_external, input); + LOCAL_OUTPUT_DECLARE(hash_external, hash); + *hash_length = 0; if (!PSA_ALG_IS_HASH(alg)) { return PSA_ERROR_INVALID_ARGUMENT; } - return psa_driver_wrapper_hash_compute(alg, input, input_length, + LOCAL_INPUT_ALLOC(input_external, input_length, input); + LOCAL_OUTPUT_ALLOC(hash_external, hash_size, hash); + status = psa_driver_wrapper_hash_compute(alg, input, input_length, hash, hash_size, hash_length); + +exit: + LOCAL_INPUT_FREE(input_external, input); + LOCAL_OUTPUT_FREE(hash_external, hash); + return status; } psa_status_t psa_hash_compare(psa_algorithm_t alg, - const uint8_t *input, size_t input_length, - const uint8_t *hash, size_t hash_length) + const uint8_t *input_external, size_t input_length, + const uint8_t *hash_external, size_t hash_length) { uint8_t actual_hash[PSA_HASH_MAX_SIZE]; size_t actual_hash_length; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + + LOCAL_INPUT_DECLARE(input_external, input); + LOCAL_INPUT_DECLARE(hash_external, hash); if (!PSA_ALG_IS_HASH(alg)) { - return PSA_ERROR_INVALID_ARGUMENT; + status = PSA_ERROR_INVALID_ARGUMENT; + return status; } - psa_status_t status = psa_driver_wrapper_hash_compute( + LOCAL_INPUT_ALLOC(input_external, input_length, input); + status = psa_driver_wrapper_hash_compute( alg, input, input_length, actual_hash, sizeof(actual_hash), &actual_hash_length); @@ -2431,12 +2474,18 @@ psa_status_t psa_hash_compare(psa_algorithm_t alg, status = PSA_ERROR_INVALID_SIGNATURE; goto exit; } + + LOCAL_INPUT_ALLOC(hash_external, hash_length, hash); if (mbedtls_psa_safer_memcmp(hash, actual_hash, actual_hash_length) != 0) { status = PSA_ERROR_INVALID_SIGNATURE; } exit: mbedtls_platform_zeroize(actual_hash, sizeof(actual_hash)); + + LOCAL_INPUT_FREE(input_external, input); + LOCAL_INPUT_FREE(hash_external, hash); + return status; } From ebf9329d88616a4b3f02e38e9e6be105540ecfe7 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Thu, 25 Jan 2024 17:09:10 +0000 Subject: [PATCH 157/211] Generate test wrappers for hash functions Signed-off-by: Thomas Daubney --- tests/scripts/generate_psa_wrappers.py | 6 +++++ tests/src/psa_test_wrappers.c | 34 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index d7970c0e379b..96b8995e11c3 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -162,6 +162,12 @@ def _parameter_should_be_copied(function_name: str, 'psa_sign_hash', 'psa_verify_hash'): return True + if function_name in ('psa_hash_update', + 'psa_hash_finish', + 'psa_hash_verify', + 'psa_hash_compute', + 'psa_hash_compare'): + return True return False def _write_function_call(self, out: typing_util.Writable, diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index c074e8d7cca5..5382d0325d9b 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -340,7 +340,15 @@ psa_status_t mbedtls_test_wrap_psa_hash_compare( const uint8_t *arg3_hash, size_t arg4_hash_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_input, arg2_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg3_hash, arg4_hash_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_hash_compare)(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_input, arg2_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg3_hash, arg4_hash_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -353,7 +361,15 @@ psa_status_t mbedtls_test_wrap_psa_hash_compute( size_t arg4_hash_size, size_t *arg5_hash_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_input, arg2_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg3_hash, arg4_hash_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_hash_compute)(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_size, arg5_hash_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_input, arg2_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg3_hash, arg4_hash_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -364,7 +380,13 @@ psa_status_t mbedtls_test_wrap_psa_hash_finish( size_t arg2_hash_size, size_t *arg3_hash_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_hash, arg2_hash_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_hash_finish)(arg0_operation, arg1_hash, arg2_hash_size, arg3_hash_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_hash, arg2_hash_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -383,7 +405,13 @@ psa_status_t mbedtls_test_wrap_psa_hash_update( const uint8_t *arg1_input, size_t arg2_input_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_input, arg2_input_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_hash_update)(arg0_operation, arg1_input, arg2_input_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_input, arg2_input_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -393,7 +421,13 @@ psa_status_t mbedtls_test_wrap_psa_hash_verify( const uint8_t *arg1_hash, size_t arg2_hash_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_hash, arg2_hash_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_hash_verify)(arg0_operation, arg1_hash, arg2_hash_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_hash, arg2_hash_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From 5e6b84ae120ade39ef20146d65dc0b5f16a5928b Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Thu, 25 Jan 2024 17:10:42 +0000 Subject: [PATCH 158/211] Conditionally include exit label ...on hash functions where the label was only added due to the modifications required by this PR. Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index a75bcc60875a..6112f0deaa72 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2379,7 +2379,9 @@ psa_status_t psa_hash_finish(psa_hash_operation_t *operation, LOCAL_OUTPUT_ALLOC(hash_external, hash_size, hash); status = psa_hash_finish_internal(operation, hash, hash_size, hash_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: +#endif LOCAL_OUTPUT_FREE(hash_external, hash); return status; } @@ -2440,7 +2442,9 @@ psa_status_t psa_hash_compute(psa_algorithm_t alg, status = psa_driver_wrapper_hash_compute(alg, input, input_length, hash, hash_size, hash_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: +#endif LOCAL_INPUT_FREE(input_external, input); LOCAL_OUTPUT_FREE(hash_external, hash); return status; From cbf092153019432878372b14e12e1453a30bee60 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Thu, 25 Jan 2024 17:14:29 +0000 Subject: [PATCH 159/211] Fix code style Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 6112f0deaa72..78737fd818a3 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2350,9 +2350,9 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation, } static psa_status_t psa_hash_finish_internal(psa_hash_operation_t *operation, - uint8_t *hash, - size_t hash_size, - size_t *hash_length) + uint8_t *hash, + size_t hash_size, + size_t *hash_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -2440,7 +2440,7 @@ psa_status_t psa_hash_compute(psa_algorithm_t alg, LOCAL_INPUT_ALLOC(input_external, input_length, input); LOCAL_OUTPUT_ALLOC(hash_external, hash_size, hash); status = psa_driver_wrapper_hash_compute(alg, input, input_length, - hash, hash_size, hash_length); + hash, hash_size, hash_length); #if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: From 324f7de1ddf7478bff540b896b993613435d4098 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Thu, 18 Jan 2024 13:18:58 +0000 Subject: [PATCH 160/211] Implement safe buffer copying in MAC API Use buffer local copy macros to implement safe copy mechanism in MAC API. Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 57 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index cff9ccaf2b21..2a52daaeda0c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2606,35 +2606,45 @@ psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation, } psa_status_t psa_mac_update(psa_mac_operation_t *operation, - const uint8_t *input, + const uint8_t *input_external, size_t input_length) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(input_external, input); + if (operation->id == 0) { - return PSA_ERROR_BAD_STATE; + status = PSA_ERROR_BAD_STATE; + return status; } /* Don't require hash implementations to behave correctly on a * zero-length input, which may have an invalid pointer. */ if (input_length == 0) { - return PSA_SUCCESS; + status = PSA_SUCCESS; + return status; } - psa_status_t status = psa_driver_wrapper_mac_update(operation, - input, input_length); + LOCAL_INPUT_ALLOC(input_external, input_length, input); + status = psa_driver_wrapper_mac_update(operation, input, input_length); + if (status != PSA_SUCCESS) { psa_mac_abort(operation); } +exit: + LOCAL_INPUT_FREE(input_external, input); + return status; } psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, - uint8_t *mac, + uint8_t *mac_external, size_t mac_size, size_t *mac_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_OUTPUT_DECLARE(mac_external, mac); if (operation->id == 0) { status = PSA_ERROR_BAD_STATE; @@ -2658,6 +2668,7 @@ psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, goto exit; } + LOCAL_OUTPUT_ALLOC(mac_external, mac_size, mac); status = psa_driver_wrapper_mac_sign_finish(operation, mac, operation->mac_size, mac_length); @@ -2680,16 +2691,18 @@ psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, } abort_status = psa_mac_abort(operation); + LOCAL_OUTPUT_FREE(mac_external, mac); return status == PSA_SUCCESS ? abort_status : status; } psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation, - const uint8_t *mac, + const uint8_t *mac_external, size_t mac_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(mac_external, mac); if (operation->id == 0) { status = PSA_ERROR_BAD_STATE; @@ -2706,11 +2719,13 @@ psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation, goto exit; } + LOCAL_INPUT_ALLOC(mac_external, mac_length, mac); status = psa_driver_wrapper_mac_verify_finish(operation, mac, mac_length); exit: abort_status = psa_mac_abort(operation); + LOCAL_INPUT_FREE(mac_external, mac); return status == PSA_SUCCESS ? abort_status : status; } @@ -2783,28 +2798,42 @@ static psa_status_t psa_mac_compute_internal(mbedtls_svc_key_id_t key, psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *input, + const uint8_t *input_external, size_t input_length, - uint8_t *mac, + uint8_t *mac_external, size_t mac_size, size_t *mac_length) { - return psa_mac_compute_internal(key, alg, + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(input_external, input); + LOCAL_OUTPUT_DECLARE(mac_external, mac); + + LOCAL_INPUT_ALLOC(input_external, input_length, input); + LOCAL_OUTPUT_ALLOC(mac_external, mac_size, mac); + status = psa_mac_compute_internal(key, alg, input, input_length, mac, mac_size, mac_length, 1); +exit: + LOCAL_INPUT_FREE(input_external, input); + LOCAL_OUTPUT_FREE(mac_external, mac); + + return status; } psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *input, + const uint8_t *input_external, size_t input_length, - const uint8_t *mac, + const uint8_t *mac_external, size_t mac_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; uint8_t actual_mac[PSA_MAC_MAX_SIZE]; size_t actual_mac_length; + LOCAL_INPUT_DECLARE(input_external, input); + LOCAL_INPUT_DECLARE(mac_external, mac); + LOCAL_INPUT_ALLOC(input_external, input_length, input); status = psa_mac_compute_internal(key, alg, input, input_length, actual_mac, sizeof(actual_mac), @@ -2817,6 +2846,8 @@ psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key, status = PSA_ERROR_INVALID_SIGNATURE; goto exit; } + + LOCAL_INPUT_ALLOC(mac_external, mac_length, mac); if (mbedtls_psa_safer_memcmp(mac, actual_mac, actual_mac_length) != 0) { status = PSA_ERROR_INVALID_SIGNATURE; goto exit; @@ -2824,6 +2855,8 @@ psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key, exit: mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac)); + LOCAL_INPUT_FREE(input_external, input); + LOCAL_INPUT_FREE(mac_external, mac); return status; } From 6b915036021f324869b645b73df83b29c5f0a681 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Tue, 30 Jan 2024 12:07:38 +0000 Subject: [PATCH 161/211] Generate test wrappers for MAC functions Signed-off-by: Thomas Daubney --- tests/scripts/generate_psa_wrappers.py | 6 +++++ tests/src/psa_test_wrappers.c | 34 ++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index d7970c0e379b..193132562c79 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -162,6 +162,12 @@ def _parameter_should_be_copied(function_name: str, 'psa_sign_hash', 'psa_verify_hash'): return True + if function_name in ('psa_mac_update', + 'psa_mac_sign_finish', + 'psa_mac_verify_finish', + 'psa_mac_compute', + 'psa_mac_verify'): + return True return False def _write_function_call(self, out: typing_util.Writable, diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index c074e8d7cca5..d229e28f7e5e 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -520,7 +520,15 @@ psa_status_t mbedtls_test_wrap_psa_mac_compute( size_t arg5_mac_size, size_t *arg6_mac_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_mac, arg5_mac_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_mac_compute)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_size, arg6_mac_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_mac, arg5_mac_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -531,7 +539,13 @@ psa_status_t mbedtls_test_wrap_psa_mac_sign_finish( size_t arg2_mac_size, size_t *arg3_mac_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_mac, arg2_mac_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_mac_sign_finish)(arg0_operation, arg1_mac, arg2_mac_size, arg3_mac_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_mac, arg2_mac_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -551,7 +565,13 @@ psa_status_t mbedtls_test_wrap_psa_mac_update( const uint8_t *arg1_input, size_t arg2_input_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_input, arg2_input_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_mac_update)(arg0_operation, arg1_input, arg2_input_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_input, arg2_input_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -564,7 +584,15 @@ psa_status_t mbedtls_test_wrap_psa_mac_verify( const uint8_t *arg4_mac, size_t arg5_mac_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_mac, arg5_mac_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_mac_verify)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_mac, arg5_mac_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -574,7 +602,13 @@ psa_status_t mbedtls_test_wrap_psa_mac_verify_finish( const uint8_t *arg1_mac, size_t arg2_mac_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_mac, arg2_mac_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_mac_verify_finish)(arg0_operation, arg1_mac, arg2_mac_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_mac, arg2_mac_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From 2bb3a1fa253dae68550e178ca0a08752583ab0cd Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Tue, 30 Jan 2024 12:12:56 +0000 Subject: [PATCH 162/211] Conditionally include exit label ...on functions where the label was only added due to the modifications required by this PR. Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 2a52daaeda0c..183b4a1c8d88 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2631,7 +2631,9 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation, psa_mac_abort(operation); } +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: +#endif LOCAL_INPUT_FREE(input_external, input); return status; @@ -2813,7 +2815,10 @@ psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key, status = psa_mac_compute_internal(key, alg, input, input_length, mac, mac_size, mac_length, 1); + +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: +#endif LOCAL_INPUT_FREE(input_external, input); LOCAL_OUTPUT_FREE(mac_external, mac); From f298f657c4f8e5b3031d127c92a713467943984b Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Tue, 30 Jan 2024 12:15:36 +0000 Subject: [PATCH 163/211] Fix code style Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 183b4a1c8d88..b478341f41af 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2813,8 +2813,8 @@ psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key, LOCAL_INPUT_ALLOC(input_external, input_length, input); LOCAL_OUTPUT_ALLOC(mac_external, mac_size, mac); status = psa_mac_compute_internal(key, alg, - input, input_length, - mac, mac_size, mac_length, 1); + input, input_length, + mac, mac_size, mac_length, 1); #if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: From 301491d70c7f9916cf930f8021bd12811a9129c0 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Thu, 1 Feb 2024 14:32:59 +0000 Subject: [PATCH 164/211] Modify allocation in sign_finish Allocate immediately after declaration. Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index b478341f41af..b6989127d4c6 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2647,6 +2647,7 @@ psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t abort_status = PSA_ERROR_CORRUPTION_DETECTED; LOCAL_OUTPUT_DECLARE(mac_external, mac); + LOCAL_OUTPUT_ALLOC(mac_external, mac_size, mac); if (operation->id == 0) { status = PSA_ERROR_BAD_STATE; @@ -2670,7 +2671,6 @@ psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, goto exit; } - LOCAL_OUTPUT_ALLOC(mac_external, mac_size, mac); status = psa_driver_wrapper_mac_sign_finish(operation, mac, operation->mac_size, mac_length); From 480347d682bb31bd75e1fbf6ab00c7a5707fdfa1 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Thu, 1 Feb 2024 19:00:26 +0000 Subject: [PATCH 165/211] Add mac not NULL check before calling memset Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index b6989127d4c6..90909243ca6f 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -2687,7 +2687,7 @@ psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, operation->mac_size = 0; } - if (mac_size > operation->mac_size) { + if ((mac != NULL) && (mac_size > operation->mac_size)) { memset(&mac[operation->mac_size], '!', mac_size - operation->mac_size); } From 1a6137bbac3163e680f775a77495bc35db90ea13 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Fri, 19 Jan 2024 10:26:26 +0000 Subject: [PATCH 166/211] Implement safe buffer copying in asymm. encryption Use local copy buffer macros to implement safe copy mechanism in asymmetric encryption API. Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index cff9ccaf2b21..00f99332da57 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3262,17 +3262,20 @@ static void psa_rsa_oaep_set_padding_mode(psa_algorithm_t alg, psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *input, + const uint8_t *input_external, size_t input_length, - const uint8_t *salt, + const uint8_t *salt_external, size_t salt_length, - uint8_t *output, + uint8_t *output_external, size_t output_size, size_t *output_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; + LOCAL_INPUT_DECLARE(input_external, input); + LOCAL_INPUT_DECLARE(salt_external, salt); + LOCAL_OUTPUT_DECLARE(output_external, output); (void) input; (void) input_length; @@ -3315,6 +3318,9 @@ psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, } #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ + LOCAL_INPUT_ALLOC(input_external, input_length, input); + LOCAL_INPUT_ALLOC(salt_external, salt_length, salt); + LOCAL_OUTPUT_ALLOC(output_external, output_size, output); if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) status = mbedtls_to_psa_error( @@ -3365,22 +3371,29 @@ psa_status_t psa_asymmetric_encrypt(mbedtls_svc_key_id_t key, exit: unlock_status = psa_unlock_key_slot(slot); + LOCAL_INPUT_FREE(input_external, input); + LOCAL_INPUT_FREE(salt_external, salt); + LOCAL_OUTPUT_FREE(output_external, output); + return (status == PSA_SUCCESS) ? unlock_status : status; } psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *input, + const uint8_t *input_external, size_t input_length, - const uint8_t *salt, + const uint8_t *salt_external, size_t salt_length, - uint8_t *output, + uint8_t *output_external, size_t output_size, size_t *output_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; + LOCAL_INPUT_DECLARE(input_external, input); + LOCAL_INPUT_DECLARE(salt_external, salt); + LOCAL_OUTPUT_DECLARE(output_external, output); (void) input; (void) input_length; @@ -3422,7 +3435,9 @@ psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, } #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) || * defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_OAEP) */ - + LOCAL_INPUT_ALLOC(input_external, input_length, input); + LOCAL_INPUT_ALLOC(salt_external, salt_length, salt); + LOCAL_OUTPUT_ALLOC(output_external, output_size, output); if (alg == PSA_ALG_RSA_PKCS1V15_CRYPT) { #if defined(MBEDTLS_PSA_BUILTIN_ALG_RSA_PKCS1V15_CRYPT) status = mbedtls_to_psa_error( @@ -3472,6 +3487,10 @@ psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, exit: unlock_status = psa_unlock_key_slot(slot); + LOCAL_INPUT_FREE(input_external, input); + LOCAL_INPUT_FREE(salt_external, salt); + LOCAL_OUTPUT_FREE(output_external, output); + return (status == PSA_SUCCESS) ? unlock_status : status; } From d8adccf45dbc72b9f1fdc616064b455c4af7d4ad Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Tue, 30 Jan 2024 14:41:05 +0000 Subject: [PATCH 167/211] Generate test wrappers Signed-off-by: Thomas Daubney --- tests/scripts/generate_psa_wrappers.py | 3 +++ tests/src/psa_test_wrappers.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index d7970c0e379b..74aec31f0986 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -162,6 +162,9 @@ def _parameter_should_be_copied(function_name: str, 'psa_sign_hash', 'psa_verify_hash'): return True + if function_name in ('psa_asymmetric_encrypt', + 'pas_asymmetric_decrypt'): + return True return False def _write_function_call(self, out: typing_util.Writable, diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index c074e8d7cca5..fdfd6d138df8 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -116,7 +116,17 @@ psa_status_t mbedtls_test_wrap_psa_asymmetric_encrypt( size_t arg7_output_size, size_t *arg8_output_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_salt, arg5_salt_length); + MBEDTLS_TEST_MEMORY_POISON(arg6_output, arg7_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_asymmetric_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_salt, arg5_salt_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg6_output, arg7_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From 2b614f9dad78a081fb1b467ac7abc5ee0b4f6dfd Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Wed, 31 Jan 2024 16:57:30 +0000 Subject: [PATCH 168/211] Generate all test wrappers One was missed due to typo Signed-off-by: Thomas Daubney --- tests/scripts/generate_psa_wrappers.py | 2 +- tests/src/psa_test_wrappers.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 74aec31f0986..74b855593185 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -163,7 +163,7 @@ def _parameter_should_be_copied(function_name: str, 'psa_verify_hash'): return True if function_name in ('psa_asymmetric_encrypt', - 'pas_asymmetric_decrypt'): + 'psa_asymmetric_decrypt'): return True return False diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index fdfd6d138df8..f944a2d54481 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -100,7 +100,17 @@ psa_status_t mbedtls_test_wrap_psa_asymmetric_decrypt( size_t arg7_output_size, size_t *arg8_output_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_salt, arg5_salt_length); + MBEDTLS_TEST_MEMORY_POISON(arg6_output, arg7_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_asymmetric_decrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_salt, arg5_salt_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg6_output, arg7_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From 4304276539eb0457d38d36c2b131ccdec2d99f3a Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Thu, 15 Feb 2024 12:57:26 +0000 Subject: [PATCH 169/211] Add buffer protection to psa_raw_key_agreement Signed-off-by: Thomas Daubney --- 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 d30462b6e837..16121926b08c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5278,9 +5278,9 @@ psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *op psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, mbedtls_svc_key_id_t private_key, - const uint8_t *peer_key, + const uint8_t *peer_key_external, size_t peer_key_length, - uint8_t *output, + uint8_t *output_external, size_t output_size, size_t *output_length) { @@ -5288,6 +5288,8 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot = NULL; size_t expected_length; + LOCAL_INPUT_DECLARE(peer_key_external, peer_key); + LOCAL_OUTPUT_DECLARE(output_external, output); if (!PSA_ALG_IS_KEY_AGREEMENT(alg)) { status = PSA_ERROR_INVALID_ARGUMENT; @@ -5314,6 +5316,8 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, goto exit; } + LOCAL_INPUT_ALLOC(peer_key_external, peer_key_length, peer_key); + LOCAL_OUTPUT_ALLOC(output_external, output_size, output); status = psa_key_agreement_raw_internal(alg, slot, peer_key, peer_key_length, output, output_size, @@ -5334,6 +5338,8 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, unlock_status = psa_unlock_key_slot(slot); + LOCAL_INPUT_FREE(peer_key_external, peer_key); + LOCAL_OUTPUT_FREE(output_external, output); return (status == PSA_SUCCESS) ? unlock_status : status; } From 9da359fc659936edd0d18be93cce00b89f169245 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Thu, 15 Feb 2024 13:15:47 +0000 Subject: [PATCH 170/211] Add buffer protection to psa_key_derivation_key_agreement Signed-off-by: Thomas Daubney --- 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 16121926b08c..d1973a59ab97 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5243,12 +5243,13 @@ static psa_status_t psa_key_agreement_internal(psa_key_derivation_operation_t *o psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *operation, psa_key_derivation_step_t step, mbedtls_svc_key_id_t private_key, - const uint8_t *peer_key, + const uint8_t *peer_key_external, size_t peer_key_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; + LOCAL_INPUT_DECLARE(peer_key_external, peer_key); if (!PSA_ALG_IS_KEY_AGREEMENT(operation->alg)) { return PSA_ERROR_INVALID_ARGUMENT; @@ -5258,9 +5259,13 @@ psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *op if (status != PSA_SUCCESS) { return status; } + + LOCAL_INPUT_ALLOC(peer_key_external, peer_key_length, peer_key) status = psa_key_agreement_internal(operation, step, slot, peer_key, peer_key_length); + +exit: if (status != PSA_SUCCESS) { psa_key_derivation_abort(operation); } else { @@ -5273,6 +5278,7 @@ psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *op unlock_status = psa_unlock_key_slot(slot); + LOCAL_INPUT_FREE(peer_key_external, peer_key); return (status == PSA_SUCCESS) ? unlock_status : status; } From db5d607cb170560a98d3fca09f5a81e15dbbf35b Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Thu, 15 Feb 2024 14:18:02 +0000 Subject: [PATCH 171/211] Generate test wrappers Signed-off-by: Thomas Daubney --- tests/scripts/generate_psa_wrappers.py | 3 +++ tests/src/psa_test_wrappers.c | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 0b7cf44292bf..92c931092636 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -171,6 +171,9 @@ def _parameter_should_be_copied(function_name: str, 'psa_hash_compute', 'psa_hash_compare'): return True + if function_name in ('psa_key_derivation_key_agreement', + 'psa_raw_key_agreement'): + return True return False def _write_function_call(self, out: typing_util.Writable, diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index c85b65d069f4..efb9f89cc1bf 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -500,7 +500,13 @@ psa_status_t mbedtls_test_wrap_psa_key_derivation_key_agreement( const uint8_t *arg3_peer_key, size_t arg4_peer_key_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg3_peer_key, arg4_peer_key_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_key_derivation_key_agreement)(arg0_operation, arg1_step, arg2_private_key, arg3_peer_key, arg4_peer_key_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg3_peer_key, arg4_peer_key_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -652,7 +658,15 @@ psa_status_t mbedtls_test_wrap_psa_raw_key_agreement( size_t arg5_output_size, size_t *arg6_output_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_peer_key, arg3_peer_key_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_output, arg5_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_raw_key_agreement)(arg0_alg, arg1_private_key, arg2_peer_key, arg3_peer_key_length, arg4_output, arg5_output_size, arg6_output_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_peer_key, arg3_peer_key_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_output, arg5_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From 3c0c6b1c4beaa75256eb7823d853ae30019035de Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Thu, 15 Feb 2024 14:25:08 +0000 Subject: [PATCH 172/211] Conditionally include exit label Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index d1973a59ab97..319ad83128f1 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5265,7 +5265,9 @@ psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *op slot, peer_key, peer_key_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: +#endif if (status != PSA_SUCCESS) { psa_key_derivation_abort(operation); } else { From 26d1c43821c0a4d5cc3edbae15ae5f9848f06409 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Tue, 20 Feb 2024 11:26:55 +0000 Subject: [PATCH 173/211] Check output allocated before randomising Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 319ad83128f1..994f9a950d6a 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5332,7 +5332,7 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, output_length); exit: - if (status != PSA_SUCCESS) { + if (status != PSA_SUCCESS && output != NULL) { /* If an error happens and is not handled properly, the output * may be used as a key to protect sensitive data. Arrange for such * a key to be random, which is likely to result in decryption or From 0736df33ac8c893c3e1f10d1c231754b803c3b95 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Wed, 21 Feb 2024 12:28:20 +0000 Subject: [PATCH 174/211] Check for output allocation before randomising Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 994f9a950d6a..964ae51bff73 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5298,6 +5298,7 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, size_t expected_length; LOCAL_INPUT_DECLARE(peer_key_external, peer_key); LOCAL_OUTPUT_DECLARE(output_external, output); + LOCAL_OUTPUT_ALLOC(output_external, output_size, output); if (!PSA_ALG_IS_KEY_AGREEMENT(alg)) { status = PSA_ERROR_INVALID_ARGUMENT; @@ -5325,23 +5326,29 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, } LOCAL_INPUT_ALLOC(peer_key_external, peer_key_length, peer_key); - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); status = psa_key_agreement_raw_internal(alg, slot, peer_key, peer_key_length, output, output_size, output_length); exit: - if (status != PSA_SUCCESS && output != NULL) { - /* If an error happens and is not handled properly, the output - * may be used as a key to protect sensitive data. Arrange for such - * a key to be random, which is likely to result in decryption or - * verification errors. This is better than filling the buffer with - * some constant data such as zeros, which would result in the data - * being protected with a reproducible, easily knowable key. - */ - psa_generate_random(output, output_size); - *output_length = output_size; + /* Check for successful allocation of output. */ + if (output != NULL && status != PSA_ERROR_INSUFFICIENT_MEMORY) { + /* output allocated. */ + if (status != PSA_SUCCESS) { + /* If an error happens and is not handled properly, the output + * may be used as a key to protect sensitive data. Arrange for such + * a key to be random, which is likely to result in decryption or + * verification errors. This is better than filling the buffer with + * some constant data such as zeros, which would result in the data + * being protected with a reproducible, easily knowable key. + */ + psa_generate_random(output, output_size); + *output_length = output_size; + } + } else { + /* output allocation failed. */ + *output_length = 0; } unlock_status = psa_unlock_key_slot(slot); From 2ea8d8fa3c1f95fa16cc4affa4cf858a4f75f632 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Wed, 21 Feb 2024 15:16:01 +0000 Subject: [PATCH 175/211] Revise how output allocation is checked Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 964ae51bff73..dac487efde65 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5332,20 +5332,16 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, output_length); exit: - /* Check for successful allocation of output. */ - if (output != NULL && status != PSA_ERROR_INSUFFICIENT_MEMORY) { - /* output allocated. */ - if (status != PSA_SUCCESS) { - /* If an error happens and is not handled properly, the output - * may be used as a key to protect sensitive data. Arrange for such - * a key to be random, which is likely to result in decryption or - * verification errors. This is better than filling the buffer with - * some constant data such as zeros, which would result in the data - * being protected with a reproducible, easily knowable key. - */ - psa_generate_random(output, output_size); - *output_length = output_size; - } + if (output != NULL && status != PSA_SUCCESS) { + /* If an error happens and is not handled properly, the output + * may be used as a key to protect sensitive data. Arrange for such + * a key to be random, which is likely to result in decryption or + * verification errors. This is better than filling the buffer with + * some constant data such as zeros, which would result in the data + * being protected with a reproducible, easily knowable key. + */ + psa_generate_random(output, output_size); + *output_length = output_size; } else { /* output allocation failed. */ *output_length = 0; From 09cf4f2e78e1dc93d8bb30e77f6f543dcec2caba Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Thu, 22 Feb 2024 11:08:22 +0000 Subject: [PATCH 176/211] Decouple if statement in psa_raw_key_agreement exit. Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index dac487efde65..e0b91c7f5473 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5332,17 +5332,21 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, output_length); exit: + /* Check for successful allocation of output, + * with an unsuccessful status. */ if (output != NULL && status != PSA_SUCCESS) { /* If an error happens and is not handled properly, the output - * may be used as a key to protect sensitive data. Arrange for such - * a key to be random, which is likely to result in decryption or - * verification errors. This is better than filling the buffer with - * some constant data such as zeros, which would result in the data - * being protected with a reproducible, easily knowable key. - */ + * may be used as a key to protect sensitive data. Arrange for such + * a key to be random, which is likely to result in decryption or + * verification errors. This is better than filling the buffer with + * some constant data such as zeros, which would result in the data + * being protected with a reproducible, easily knowable key. + */ psa_generate_random(output, output_size); *output_length = output_size; - } else { + } + + if (output == NULL) { /* output allocation failed. */ *output_length = 0; } From be060f1e85b3b710c9d1019e9ee0a8c180d37d51 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Mon, 26 Feb 2024 13:55:42 +0000 Subject: [PATCH 177/211] Suppress pylint Signed-off-by: Thomas Daubney --- tests/scripts/generate_psa_wrappers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index d0882888320c..e3842bfb067d 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -150,6 +150,7 @@ def _parameter_should_be_copied(function_name: str, _buffer_name: Optional[str]) -> bool: """Whether the specified buffer argument to a PSA function should be copied. """ + #pylint: disable=too-many-return-statements if function_name.startswith('psa_aead'): return True if function_name == 'psa_cipher_encrypt': From 65bf12ce6b0239974db31ba6c67d20f902fa564b Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 6 Feb 2024 15:27:49 +0000 Subject: [PATCH 178/211] Add buffer copying to psa_generate_random() Signed-off-by: David Horstmann --- library/psa_crypto.c | 94 +++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 37 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index f9fab48086a2..19daee957ba6 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3528,6 +3528,52 @@ psa_status_t psa_asymmetric_decrypt(mbedtls_svc_key_id_t key, return (status == PSA_SUCCESS) ? unlock_status : status; } +static psa_status_t psa_generate_random_internal(uint8_t *output, + size_t output_size) +{ + GUARD_MODULE_INITIALIZED; + + psa_status_t status; + +#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) + + size_t output_length = 0; + status = mbedtls_psa_external_get_random(&global_data.rng, + output, output_size, + &output_length); + if (status != PSA_SUCCESS) { + goto exit; + } + /* Breaking up a request into smaller chunks is currently not supported + * for the external RNG interface. */ + if (output_length != output_size) { + status = PSA_ERROR_INSUFFICIENT_ENTROPY; + goto exit; + } + status = PSA_SUCCESS; + +#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ + + while (output_size > 0) { + size_t request_size = + (output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ? + MBEDTLS_PSA_RANDOM_MAX_REQUEST : + output_size); + int ret = mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, + output, request_size); + if (ret != 0) { + status = mbedtls_to_psa_error(ret); + goto exit; + } + output_size -= request_size; + output += request_size; + } + status = PSA_SUCCESS; +#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ + +exit: + return status; +} /****************************************************************/ @@ -3650,7 +3696,7 @@ psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, goto exit; } - status = psa_generate_random(local_iv, default_iv_length); + status = psa_generate_random_internal(local_iv, default_iv_length); if (status != PSA_SUCCESS) { goto exit; } @@ -3839,7 +3885,7 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, goto exit; } - status = psa_generate_random(local_iv, default_iv_length); + status = psa_generate_random_internal(local_iv, default_iv_length); if (status != PSA_SUCCESS) { goto exit; } @@ -5367,7 +5413,7 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, * some constant data such as zeros, which would result in the data * being protected with a reproducible, easily knowable key. */ - psa_generate_random(output, output_size); + psa_generate_random_internal(output, output_size); *output_length = output_size; } @@ -5377,7 +5423,6 @@ psa_status_t psa_raw_key_agreement(psa_algorithm_t alg, } - /****************************************************************/ /* Random generation */ /****************************************************************/ @@ -5446,44 +5491,19 @@ static psa_status_t mbedtls_psa_random_seed(mbedtls_psa_random_context_t *rng) #endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ } -psa_status_t psa_generate_random(uint8_t *output, +psa_status_t psa_generate_random(uint8_t *output_external, size_t output_size) { - GUARD_MODULE_INITIALIZED; - -#if defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) + psa_status_t status; - size_t output_length = 0; - psa_status_t status = mbedtls_psa_external_get_random(&global_data.rng, - output, output_size, - &output_length); - if (status != PSA_SUCCESS) { - return status; - } - /* Breaking up a request into smaller chunks is currently not supported - * for the external RNG interface. */ - if (output_length != output_size) { - return PSA_ERROR_INSUFFICIENT_ENTROPY; - } - return PSA_SUCCESS; + LOCAL_OUTPUT_DECLARE(output_external, output); + LOCAL_OUTPUT_ALLOC(output_external, output_size, output); -#else /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ + status = psa_generate_random_internal(output, output_size); - while (output_size > 0) { - size_t request_size = - (output_size > MBEDTLS_PSA_RANDOM_MAX_REQUEST ? - MBEDTLS_PSA_RANDOM_MAX_REQUEST : - output_size); - int ret = mbedtls_psa_get_random(MBEDTLS_PSA_RANDOM_STATE, - output, request_size); - if (ret != 0) { - return mbedtls_to_psa_error(ret); - } - output_size -= request_size; - output += request_size; - } - return PSA_SUCCESS; -#endif /* MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */ +exit: + LOCAL_OUTPUT_FREE(output_external, output); + return status; } /* Wrapper function allowing the classic API to use the PSA RNG. From 4e8215057c4dfb2ea38dce1b3214f40ea6566665 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 6 Feb 2024 15:44:08 +0000 Subject: [PATCH 179/211] Generate test wrappers for psa_generate_random() Signed-off-by: David Horstmann --- tests/scripts/generate_psa_wrappers.py | 2 ++ tests/src/psa_test_wrappers.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 4f567bcfe108..0aaa7104e4c7 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -171,6 +171,8 @@ def _parameter_should_be_copied(function_name: str, 'psa_hash_verify', 'psa_hash_compute', 'psa_hash_compare'): + + if function_name == 'psa_generate_random': return True return False diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index 032df8d28bdd..1efa1bb6a6e1 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -326,7 +326,13 @@ psa_status_t mbedtls_test_wrap_psa_generate_random( uint8_t *arg0_output, size_t arg1_output_size) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg0_output, arg1_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_generate_random)(arg0_output, arg1_output_size); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg0_output, arg1_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From 10e44f3fd172d0381709ad274a7d56ac9e2a0c3a Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 28 Feb 2024 14:17:10 +0000 Subject: [PATCH 180/211] Add missing guards around exit label Signed-off-by: David Horstmann --- library/psa_crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 19daee957ba6..5c1a98db6fc3 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5501,7 +5501,9 @@ psa_status_t psa_generate_random(uint8_t *output_external, status = psa_generate_random_internal(output, output_size); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) exit: +#endif LOCAL_OUTPUT_FREE(output_external, output); return status; } From 80de1475a1eb935822a9377ef8f73583ac6aee26 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 28 Feb 2024 15:16:44 +0000 Subject: [PATCH 181/211] Fix incorrect conflict resolution A return statement was missing in the wrapper generation script. Signed-off-by: David Horstmann --- tests/scripts/generate_psa_wrappers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 0aaa7104e4c7..db7a55951829 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -171,7 +171,7 @@ def _parameter_should_be_copied(function_name: str, 'psa_hash_verify', 'psa_hash_compute', 'psa_hash_compare'): - + return True if function_name == 'psa_generate_random': return True return False From 13a15c2390b090eb11fba63dcc7cbcbec8eb4853 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 24 Jan 2024 16:56:00 +0100 Subject: [PATCH 182/211] Add buffer protection for cipher functions Signed-off-by: Gabor Mezei --- library/psa_crypto.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index e9c1facd6ada..909c0ad3b235 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3763,14 +3763,20 @@ psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, } psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, - const uint8_t *input, + const uint8_t *input_external, size_t input_length, - uint8_t *output, + uint8_t *output_external, size_t output_size, size_t *output_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(input_external, input); + LOCAL_OUTPUT_DECLARE(output_external, output); + + LOCAL_INPUT_ALLOC(input_external, input_length, input); + LOCAL_OUTPUT_ALLOC_WITH_COPY(output_external, output_size, output); + if (operation->id == 0) { status = PSA_ERROR_BAD_STATE; goto exit; @@ -3793,16 +3799,23 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, psa_cipher_abort(operation); } + LOCAL_INPUT_FREE(input_external, input); + LOCAL_OUTPUT_FREE(output_external, output); + return status; } psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, - uint8_t *output, + uint8_t *output_external, size_t output_size, size_t *output_length) { psa_status_t status = PSA_ERROR_GENERIC_ERROR; + LOCAL_OUTPUT_DECLARE(output_external, output); + + LOCAL_OUTPUT_ALLOC_WITH_COPY(output_external, output_size, output); + if (operation->id == 0) { status = PSA_ERROR_BAD_STATE; goto exit; @@ -3820,13 +3833,15 @@ psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, exit: if (status == PSA_SUCCESS) { - return psa_cipher_abort(operation); + status = psa_cipher_abort(operation); } else { *output_length = 0; (void) psa_cipher_abort(operation); - - return status; } + + LOCAL_OUTPUT_FREE(output_external, output); + + return status; } psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation) @@ -3931,9 +3946,9 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, psa_algorithm_t alg, - const uint8_t *input, + const uint8_t *input_external, size_t input_length, - uint8_t *output, + uint8_t *output_external, size_t output_size, size_t *output_length) { @@ -3942,6 +3957,12 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, psa_key_attributes_t attributes; psa_key_slot_t *slot = NULL; + LOCAL_INPUT_DECLARE(input_external, input); + LOCAL_OUTPUT_DECLARE(output_external, output); + + LOCAL_INPUT_ALLOC(input_external, input_length, input); + LOCAL_OUTPUT_ALLOC(output_external, output_size, output); + if (!PSA_ALG_IS_CIPHER(alg)) { status = PSA_ERROR_INVALID_ARGUMENT; goto exit; @@ -3978,6 +3999,9 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, *output_length = 0; } + LOCAL_INPUT_FREE(input_external, input); + LOCAL_OUTPUT_FREE(output_external, output); + return status; } From 143864c1218a042552f60ec27537cd11cdd06acf Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 24 Jan 2024 16:58:40 +0100 Subject: [PATCH 183/211] Add test wrapper functions for cipher buffer protection Signed-off-by: Gabor Mezei --- tests/scripts/generate_psa_wrappers.py | 3 ++- tests/src/psa_test_wrappers.c | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 12d34f9dcf26..c34402ad946f 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -153,7 +153,8 @@ def _parameter_should_be_copied(function_name: str, #pylint: disable=too-many-return-statements if function_name.startswith('psa_aead'): return True - if function_name == 'psa_cipher_encrypt': + if function_name in {'psa_cipher_encrypt', 'psa_cipher_decrypt', + 'psa_cipher_update', 'psa_cipher_finish'}: return True if function_name in ('psa_key_derivation_output_bytes', 'psa_key_derivation_input_bytes'): diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index 0f13cf5c61d0..53578d7a7262 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -182,7 +182,15 @@ psa_status_t mbedtls_test_wrap_psa_cipher_decrypt( size_t arg5_output_size, size_t *arg6_output_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg4_output, arg5_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_cipher_decrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg4_output, arg5_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -235,7 +243,13 @@ psa_status_t mbedtls_test_wrap_psa_cipher_finish( size_t arg2_output_size, size_t *arg3_output_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_output, arg2_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_cipher_finish)(arg0_operation, arg1_output, arg2_output_size, arg3_output_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_output, arg2_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -269,7 +283,15 @@ psa_status_t mbedtls_test_wrap_psa_cipher_update( size_t arg4_output_size, size_t *arg5_output_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_input, arg2_input_length); + MBEDTLS_TEST_MEMORY_POISON(arg3_output, arg4_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_cipher_update)(arg0_operation, arg1_input, arg2_input_length, arg3_output, arg4_output_size, arg5_output_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_input, arg2_input_length); + MBEDTLS_TEST_MEMORY_UNPOISON(arg3_output, arg4_output_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From 92905be298199fe1b0a63e7d8108a25063afd9d5 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 29 Jan 2024 13:33:58 +0100 Subject: [PATCH 184/211] Fix ASAN error for `psa_cipher_update` The ASAN gives an error for `psa_cipher_update` when the `input_length` is 0 and the `input` buffer is `NULL`. The root cause of this issue is `mbedtls_cipher_update` always need a valid pointer for the input buffer even if the length is 0. This fix avoids the `mbedtls_cipher_update` to be called if the input buffer length is 0. Signed-off-by: Gabor Mezei --- library/psa_crypto_cipher.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/psa_crypto_cipher.c b/library/psa_crypto_cipher.c index 545bb50cc879..93a6b93f1cba 100644 --- a/library/psa_crypto_cipher.c +++ b/library/psa_crypto_cipher.c @@ -402,7 +402,11 @@ psa_status_t mbedtls_psa_cipher_update( output_length); } else #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECB_NO_PADDING */ - { + if (input_length == 0) { + /* There is no input, nothing to be done */ + *output_length = 0; + status = PSA_SUCCESS; + } else { status = mbedtls_to_psa_error( mbedtls_cipher_update(&operation->ctx.cipher, input, input_length, output, output_length)); From 69f680ac9cbcf8982b0d8360935fad2247331e19 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 29 Jan 2024 17:27:44 +0100 Subject: [PATCH 185/211] Add `LOCAL_OUTPUT_ALLOC_WITH_COPY` macro if buffer protection is disabled Signed-off-by: Gabor Mezei --- library/psa_crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 909c0ad3b235..d745c46f7a18 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -230,6 +230,8 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = uint8_t *output_copy_name = NULL; #define LOCAL_OUTPUT_ALLOC(output, length, output_copy) \ output_copy = output; +#define LOCAL_OUTPUT_ALLOC_WITH_COPY(output, length, output_copy) \ + output_copy = output; #define LOCAL_OUTPUT_FREE(output, output_copy) \ output_copy = NULL; #endif /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ From ed96d687d773944666fe87f70d35485e8a10b8ae Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 31 Jan 2024 17:45:29 +0100 Subject: [PATCH 186/211] Move local buffer allocation just before usage Signed-off-by: Gabor Mezei --- library/psa_crypto.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index d745c46f7a18..c6a0a8baa26b 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3776,9 +3776,6 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, LOCAL_INPUT_DECLARE(input_external, input); LOCAL_OUTPUT_DECLARE(output_external, output); - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_OUTPUT_ALLOC_WITH_COPY(output_external, output_size, output); - if (operation->id == 0) { status = PSA_ERROR_BAD_STATE; goto exit; @@ -3789,6 +3786,9 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, goto exit; } + LOCAL_INPUT_ALLOC(input_external, input_length, input); + LOCAL_OUTPUT_ALLOC_WITH_COPY(output_external, output_size, output); + status = psa_driver_wrapper_cipher_update(operation, input, input_length, @@ -3816,8 +3816,6 @@ psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, LOCAL_OUTPUT_DECLARE(output_external, output); - LOCAL_OUTPUT_ALLOC_WITH_COPY(output_external, output_size, output); - if (operation->id == 0) { status = PSA_ERROR_BAD_STATE; goto exit; @@ -3828,6 +3826,8 @@ psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, goto exit; } + LOCAL_OUTPUT_ALLOC_WITH_COPY(output_external, output_size, output); + status = psa_driver_wrapper_cipher_finish(operation, output, output_size, @@ -3882,9 +3882,6 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, LOCAL_INPUT_DECLARE(input_external, input); LOCAL_OUTPUT_DECLARE(output_external, output); - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); - if (!PSA_ALG_IS_CIPHER(alg)) { status = PSA_ERROR_INVALID_ARGUMENT; goto exit; @@ -3919,6 +3916,9 @@ psa_status_t psa_cipher_encrypt(mbedtls_svc_key_id_t key, } } + LOCAL_INPUT_ALLOC(input_external, input_length, input); + LOCAL_OUTPUT_ALLOC(output_external, output_size, output); + status = psa_driver_wrapper_cipher_encrypt( &attributes, slot->key.data, slot->key.bytes, alg, local_iv, default_iv_length, input, input_length, @@ -3962,9 +3962,6 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, LOCAL_INPUT_DECLARE(input_external, input); LOCAL_OUTPUT_DECLARE(output_external, output); - LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_OUTPUT_ALLOC(output_external, output_size, output); - if (!PSA_ALG_IS_CIPHER(alg)) { status = PSA_ERROR_INVALID_ARGUMENT; goto exit; @@ -3986,6 +3983,9 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key, goto exit; } + LOCAL_INPUT_ALLOC(input_external, input_length, input); + LOCAL_OUTPUT_ALLOC(output_external, output_size, output); + status = psa_driver_wrapper_cipher_decrypt( &attributes, slot->key.data, slot->key.bytes, alg, input, input_length, From 282bb53edce2ce702e7381165c62a31039101950 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Thu, 1 Feb 2024 10:39:26 +0100 Subject: [PATCH 187/211] Add buffer protection for `cipher_generate_iv` and `cipher_set_iv` Signed-off-by: Gabor Mezei --- library/psa_crypto.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index c6a0a8baa26b..7ccf167968dc 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3719,7 +3719,7 @@ psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, exit: if (status == PSA_SUCCESS) { - memcpy(iv, local_iv, default_iv_length); + psa_crypto_copy_output(local_iv, default_iv_length, iv, iv_size); *iv_length = default_iv_length; operation->iv_set = 1; } else { @@ -3731,11 +3731,13 @@ psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, } psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, - const uint8_t *iv, + const uint8_t *iv_external, size_t iv_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + LOCAL_INPUT_DECLARE(iv_external, iv); + if (operation->id == 0) { status = PSA_ERROR_BAD_STATE; goto exit; @@ -3751,6 +3753,8 @@ psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, goto exit; } + LOCAL_INPUT_ALLOC(iv_external, iv_length, iv); + status = psa_driver_wrapper_cipher_set_iv(operation, iv, iv_length); @@ -3761,6 +3765,9 @@ psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, } else { psa_cipher_abort(operation); } + + LOCAL_INPUT_FREE(iv_external, iv); + return status; } From 50bcca26b307471b85812248ca7382785bbfb467 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Thu, 1 Feb 2024 10:39:56 +0100 Subject: [PATCH 188/211] Update test wrapper functions for ciper buffer protection Signed-off-by: Gabor Mezei --- tests/scripts/generate_psa_wrappers.py | 3 ++- tests/src/psa_test_wrappers.c | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index c34402ad946f..b93e156bbb2d 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -154,7 +154,8 @@ def _parameter_should_be_copied(function_name: str, if function_name.startswith('psa_aead'): return True if function_name in {'psa_cipher_encrypt', 'psa_cipher_decrypt', - 'psa_cipher_update', 'psa_cipher_finish'}: + 'psa_cipher_update', 'psa_cipher_finish', + 'psa_cipher_generate_iv', 'psa_cipher_set_iv'}: return True if function_name in ('psa_key_derivation_output_bytes', 'psa_key_derivation_input_bytes'): diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index 53578d7a7262..ff2a1d25f414 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -260,7 +260,13 @@ psa_status_t mbedtls_test_wrap_psa_cipher_generate_iv( size_t arg2_iv_size, size_t *arg3_iv_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_iv, arg2_iv_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_cipher_generate_iv)(arg0_operation, arg1_iv, arg2_iv_size, arg3_iv_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_iv, arg2_iv_size); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } @@ -270,7 +276,13 @@ psa_status_t mbedtls_test_wrap_psa_cipher_set_iv( const uint8_t *arg1_iv, size_t arg2_iv_length) { +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_POISON(arg1_iv, arg2_iv_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ psa_status_t status = (psa_cipher_set_iv)(arg0_operation, arg1_iv, arg2_iv_length); +#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) + MBEDTLS_TEST_MEMORY_UNPOISON(arg1_iv, arg2_iv_length); +#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ return status; } From 8677edda6efd0dc0d3ba46057ebf04d817dc22ae Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Wed, 7 Feb 2024 18:10:13 +0100 Subject: [PATCH 189/211] Fix buffer protection handling for `cipher_generate_iv` Use the `LOCAL_OUTPUT_` macros for buffer protection instead of the existing local variable. Signed-off-by: Gabor Mezei --- library/psa_crypto.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 7ccf167968dc..56796c2ae50d 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3680,14 +3680,15 @@ psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, } psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, - uint8_t *iv, + uint8_t *iv_external, size_t iv_size, size_t *iv_length) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - uint8_t local_iv[PSA_CIPHER_IV_MAX_SIZE]; size_t default_iv_length = 0; + LOCAL_OUTPUT_DECLARE(iv_external, iv); + if (operation->id == 0) { status = PSA_ERROR_BAD_STATE; goto exit; @@ -3709,24 +3710,29 @@ psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, goto exit; } - status = psa_generate_random(local_iv, default_iv_length); + LOCAL_OUTPUT_ALLOC(iv_external, default_iv_length, iv); + + status = psa_generate_random(iv, default_iv_length); if (status != PSA_SUCCESS) { goto exit; } status = psa_driver_wrapper_cipher_set_iv(operation, - local_iv, default_iv_length); + iv, default_iv_length); exit: if (status == PSA_SUCCESS) { - psa_crypto_copy_output(local_iv, default_iv_length, iv, iv_size); *iv_length = default_iv_length; operation->iv_set = 1; } else { *iv_length = 0; psa_cipher_abort(operation); + if (iv != NULL) { + mbedtls_platform_zeroize(iv, default_iv_length); + } } + LOCAL_OUTPUT_FREE(iv_external, iv); return status; } From 7f4b7dd382cf0369485b6d2c92144eb78a47e513 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Fri, 9 Feb 2024 17:25:47 +0100 Subject: [PATCH 190/211] Remove write check in driver wrappers tests This check is intended to ensure that we do not write intermediate results to the shared output buffer. This check will be made obselete by generic memory-poisoning-based testing for all functions. Signed-off-by: Gabor Mezei --- .../suites/test_suite_psa_crypto_driver_wrappers.function | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function index 75f5490b9bcd..0394735aab5a 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function @@ -983,14 +983,6 @@ void cipher_entry_points(int alg_arg, int key_type_arg, /* When generating the IV fails, it should call abort too */ TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 2); TEST_EQUAL(status, mbedtls_test_driver_cipher_hooks.forced_status); - /* - * Check that the output buffer is still in the same state. - * This will fail if the output buffer is used by the core to pass the IV - * it generated to the driver (and is not restored). - */ - for (size_t i = 0; i < 16; i++) { - TEST_EQUAL(output[i], 0xa5); - } /* Failure should prevent further operations from executing on the driver */ mbedtls_test_driver_cipher_hooks.hits = 0; status = psa_cipher_update(&operation, From ff783e0bda585a1eaf1e6c71758fe367d0e0d401 Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Thu, 29 Feb 2024 10:08:16 +0000 Subject: [PATCH 191/211] Do not copy the content to the local output buffer with allocation Signed-off-by: Gabor Mezei --- library/psa_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 56796c2ae50d..90c638301e6f 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3800,7 +3800,7 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, } LOCAL_INPUT_ALLOC(input_external, input_length, input); - LOCAL_OUTPUT_ALLOC_WITH_COPY(output_external, output_size, output); + LOCAL_OUTPUT_ALLOC(output_external, output_size, output); status = psa_driver_wrapper_cipher_update(operation, input, @@ -3839,7 +3839,7 @@ psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation, goto exit; } - LOCAL_OUTPUT_ALLOC_WITH_COPY(output_external, output_size, output); + LOCAL_OUTPUT_ALLOC(output_external, output_size, output); status = psa_driver_wrapper_cipher_finish(operation, output, From f3c3504f5aba31412adef5d095dd8ecbd697eddb Mon Sep 17 00:00:00 2001 From: Gabor Mezei Date: Mon, 4 Mar 2024 17:15:08 +0100 Subject: [PATCH 192/211] Fix merge Signed-off-by: Gabor Mezei --- library/psa_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index d634486fd7ef..514911d7a457 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3758,7 +3758,7 @@ psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation, LOCAL_OUTPUT_ALLOC(iv_external, default_iv_length, iv); - status = psa_generate_random_internal(local_iv, default_iv_length); + status = psa_generate_random_internal(iv, default_iv_length); if (status != PSA_SUCCESS) { goto exit; } From 9d0fe6e8df83dc4b50ad3412a4aa6b6814dfb465 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Wed, 6 Mar 2024 17:34:35 +0000 Subject: [PATCH 193/211] Fix issue with large allocation in tests In test_suite_psa_crypto_op_fail.generated.function the function key_agreement_fail was setting the public_key_length variable to SIZE_MAX which meant that a huge allocation was being attempted. Signed-off-by: Thomas Daubney --- tests/suites/test_suite_psa_crypto_op_fail.function | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/suites/test_suite_psa_crypto_op_fail.function b/tests/suites/test_suite_psa_crypto_op_fail.function index 0d5d53890fce..4e709a0a8ada 100644 --- a/tests/suites/test_suite_psa_crypto_op_fail.function +++ b/tests/suites/test_suite_psa_crypto_op_fail.function @@ -332,9 +332,9 @@ void key_agreement_fail(int key_type_arg, data_t *key_data, psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; mbedtls_svc_key_id_t key_id = MBEDTLS_SVC_KEY_ID_INIT; uint8_t public_key[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE] = { 0 }; - size_t public_key_length = SIZE_MAX; + size_t public_key_length = 0; uint8_t output[PSA_SIGNATURE_MAX_SIZE] = { 0 }; - size_t length = SIZE_MAX; + size_t length = 0; psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; PSA_INIT(); From c14cd0dc120b1a2a3cc9db28efba4b3f6a3ff00c Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 11 Mar 2024 17:21:54 +0000 Subject: [PATCH 194/211] Add ChangeLog for PSA buffer sharing fix Signed-off-by: David Horstmann --- ChangeLog.d/psa-shared-memory-protection.txt | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 ChangeLog.d/psa-shared-memory-protection.txt diff --git a/ChangeLog.d/psa-shared-memory-protection.txt b/ChangeLog.d/psa-shared-memory-protection.txt new file mode 100644 index 000000000000..f4f6ea0f466e --- /dev/null +++ b/ChangeLog.d/psa-shared-memory-protection.txt @@ -0,0 +1,8 @@ +Security + * Support calling PSA functions with buffer arguments that are in memory + shared with an untrusted party. The PSA core now makes copies of all + buffers before passing them to drivers to protect drivers against + modification of buffers during operations. + This feature increases code-size and memory usage. If buffers passed to + PSA functions are all trusted, buffer copying may be disabled by + unsetting MBEDTLS_PSA_COPY_CALLER_BUFFERS. From 4698e692e89d91c9c66c97f48ef61fb94fbfd24a Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Mon, 11 Mar 2024 15:21:06 +0000 Subject: [PATCH 195/211] Flip logic of PSA memory poisoning generation Change to excluding mbedtls_psa_inject_entropy() (not a PSA function) rather than explicitly including every PSA function. Signed-off-by: David Horstmann --- tests/scripts/generate_psa_wrappers.py | 43 ++------------------------ 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 31f0dadc437c..1ab71d31e29e 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -150,46 +150,9 @@ def _parameter_should_be_copied(function_name: str, _buffer_name: Optional[str]) -> bool: """Whether the specified buffer argument to a PSA function should be copied. """ - #pylint: disable=too-many-return-statements - if function_name.startswith('psa_aead'): - return True - if function_name in {'psa_cipher_encrypt', 'psa_cipher_decrypt', - 'psa_cipher_update', 'psa_cipher_finish', - 'psa_cipher_generate_iv', 'psa_cipher_set_iv'}: - return True - if function_name in ('psa_key_derivation_output_bytes', - 'psa_key_derivation_input_bytes'): - return True - if function_name in ('psa_import_key', - 'psa_export_key', - 'psa_export_public_key'): - return True - if function_name in ('psa_sign_message', - 'psa_verify_message', - 'psa_sign_hash', - 'psa_verify_hash'): - return True - if function_name in ('psa_hash_update', - 'psa_hash_finish', - 'psa_hash_verify', - 'psa_hash_compute', - 'psa_hash_compare'): - return True - if function_name in ('psa_key_derivation_key_agreement', - 'psa_raw_key_agreement'): - return True - if function_name == 'psa_generate_random': - return True - if function_name in ('psa_mac_update', - 'psa_mac_sign_finish', - 'psa_mac_verify_finish', - 'psa_mac_compute', - 'psa_mac_verify'): - return True - if function_name in ('psa_asymmetric_encrypt', - 'psa_asymmetric_decrypt'): - return True - return False + if function_name == 'mbedtls_psa_inject_entropy': + return False + return True def _write_function_call(self, out: typing_util.Writable, function: c_wrapper_generator.FunctionInfo, From 59c1f53088d05e10e69cc9259fd92f8e820ac032 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 12 Mar 2024 16:47:46 +0000 Subject: [PATCH 196/211] Reword ChangeLog entry for shared memory work Specifically: * Clarify that passing shared buffers is now secure by default (not newly supported) * Remove spurious hyphen * Clarify that we do not guarantee copying, but rather guarantee protection, allowing us to implement this differently in future if required. * Mention both protection of inputs from modification and outputs from exposure of intermediate results. * Invert the config option, from an enable-option to a disable-option. Signed-off-by: David Horstmann --- ChangeLog.d/psa-shared-memory-protection.txt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ChangeLog.d/psa-shared-memory-protection.txt b/ChangeLog.d/psa-shared-memory-protection.txt index f4f6ea0f466e..6322563b16c4 100644 --- a/ChangeLog.d/psa-shared-memory-protection.txt +++ b/ChangeLog.d/psa-shared-memory-protection.txt @@ -1,8 +1,10 @@ Security - * Support calling PSA functions with buffer arguments that are in memory - shared with an untrusted party. The PSA core now makes copies of all - buffers before passing them to drivers to protect drivers against - modification of buffers during operations. - This feature increases code-size and memory usage. If buffers passed to - PSA functions are all trusted, buffer copying may be disabled by - unsetting MBEDTLS_PSA_COPY_CALLER_BUFFERS. + * Passing buffers that are stored in untrusted memory as arguments + to PSA functions is now secure by default. + The PSA core now protects against modification of inputs or exposure + of intermediate outputs during operations. This is currently implemented + by copying buffers. + This feature increases code size and memory usage. If buffers passed to + PSA functions are owned exclusively by the PSA core for the duration of + the function call, copying may be disabled by setting + MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS. From 8b4cea2710af86cffa7777a19dafd65da0cf7a16 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Tue, 12 Mar 2024 16:56:49 +0000 Subject: [PATCH 197/211] Add bugfix section about buffer sharing Mention that arbitrary overlap is now supported, except whenever MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is set. Signed-off-by: David Horstmann --- ChangeLog.d/psa-shared-memory-protection.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog.d/psa-shared-memory-protection.txt b/ChangeLog.d/psa-shared-memory-protection.txt index 6322563b16c4..a158ae853707 100644 --- a/ChangeLog.d/psa-shared-memory-protection.txt +++ b/ChangeLog.d/psa-shared-memory-protection.txt @@ -8,3 +8,7 @@ Security PSA functions are owned exclusively by the PSA core for the duration of the function call, copying may be disabled by setting MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS. +Bugfix + * Fully support arbitrary overlap between inputs and outputs of PSA + functions. Note that overlap is only partial supported when + MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is set. From ca92831a60370624b26488b49a60735819715fc1 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Tue, 12 Mar 2024 17:53:30 +0000 Subject: [PATCH 198/211] Add missing semicolon Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 0a94c8fc1d7f..6a00a933dc13 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5464,7 +5464,7 @@ psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *op return status; } - LOCAL_INPUT_ALLOC(peer_key_external, peer_key_length, peer_key) + LOCAL_INPUT_ALLOC(peer_key_external, peer_key_length, peer_key); status = psa_key_agreement_internal(operation, step, slot, peer_key, peer_key_length); From 28fe6654d871cbc549b1d97d4326f2726e074d44 Mon Sep 17 00:00:00 2001 From: Thomas Daubney Date: Tue, 12 Mar 2024 17:42:16 +0000 Subject: [PATCH 199/211] Remove LOCAL_OUTPUT_ALLOC_WITH_COPY Signed-off-by: Thomas Daubney --- library/psa_crypto.c | 52 --------------------------------------- library/psa_crypto_core.h | 19 -------------- 2 files changed, 71 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 6a00a933dc13..8e981f61f69f 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -182,23 +182,6 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = } \ output_copy = LOCAL_OUTPUT_COPY_OF_##output.buffer; -/* Allocate a copy of the buffer output and set the pointer output_copy to - * point to the start of the copy. - * - * Assumptions: - * - psa_status_t status exists - * - An exit label is declared - * - output is the name of a pointer to the buffer to be copied - * - LOCAL_OUTPUT_DECLARE(output, output_copy) has previously been called - */ -#define LOCAL_OUTPUT_ALLOC_WITH_COPY(output, length, output_copy) \ - status = psa_crypto_local_output_alloc_with_copy(output, length, \ - &LOCAL_OUTPUT_COPY_OF_##output); \ - if (status != PSA_SUCCESS) { \ - goto exit; \ - } \ - output_copy = LOCAL_OUTPUT_COPY_OF_##output.buffer; - /* Free the local output copy allocated previously by LOCAL_OUTPUT_ALLOC() * after first copying back its contents to the original buffer. * @@ -230,8 +213,6 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = uint8_t *output_copy_name = NULL; #define LOCAL_OUTPUT_ALLOC(output, length, output_copy) \ output_copy = output; -#define LOCAL_OUTPUT_ALLOC_WITH_COPY(output, length, output_copy) \ - output_copy = output; #define LOCAL_OUTPUT_FREE(output, output_copy) \ output_copy = NULL; #endif /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ @@ -6140,39 +6121,6 @@ psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len, return PSA_SUCCESS; } -psa_status_t psa_crypto_local_output_alloc_with_copy(uint8_t *output, size_t output_len, - psa_crypto_local_output_t *local_output) -{ - psa_status_t status; - *local_output = PSA_CRYPTO_LOCAL_OUTPUT_INIT; - - if (output_len == 0) { - return PSA_SUCCESS; - } - 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; - } - local_output->length = output_len; - local_output->original = output; - - status = psa_crypto_copy_input(output, output_len, - local_output->buffer, local_output->length); - if (status != PSA_SUCCESS) { - goto error; - } - - return PSA_SUCCESS; - -error: - mbedtls_free(local_output->buffer); - local_output->buffer = NULL; - local_output->length = 0; - return status; -} - psa_status_t psa_crypto_local_output_free(psa_crypto_local_output_t *local_output) { psa_status_t status; diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index ae8af09d91a6..4731064f85f3 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -560,25 +560,6 @@ typedef struct psa_crypto_local_output_s { psa_status_t psa_crypto_local_output_alloc(uint8_t *output, size_t output_len, psa_crypto_local_output_t *local_output); -/** Allocate a local copy of an output buffer and copy the contents into it. - * - * \note This allocates and copies a buffer - * whose contents will be copied back to the - * original in a future call to - * psa_crypto_local_output_free(). - * - * \param[in] output Pointer to output buffer. - * \param[in] output_len Length of the output buffer. - * \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_local_output_alloc_with_copy(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. * From 3aff45584b0b85761a497bfe21649e7dcce090ab Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 13 Mar 2024 13:30:55 +0000 Subject: [PATCH 200/211] Reword ChangeLog entry. Specifically: * Fix a grammatical typo * Mention shared memory * Mention overlap support in the security section * Improve wording Signed-off-by: David Horstmann --- ChangeLog.d/psa-shared-memory-protection.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ChangeLog.d/psa-shared-memory-protection.txt b/ChangeLog.d/psa-shared-memory-protection.txt index a158ae853707..765c97c52f57 100644 --- a/ChangeLog.d/psa-shared-memory-protection.txt +++ b/ChangeLog.d/psa-shared-memory-protection.txt @@ -6,9 +6,12 @@ Security by copying buffers. This feature increases code size and memory usage. If buffers passed to PSA functions are owned exclusively by the PSA core for the duration of - the function call, copying may be disabled by setting + the function call (i.e. no buffer parameters are stored in memory shared + with an untrusted party), copying may be disabled by setting MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS. + Note that setting this option will cause input-output buffer overlap to + be only partially supported. Bugfix * Fully support arbitrary overlap between inputs and outputs of PSA - functions. Note that overlap is only partial supported when + functions. Note that overlap is still only partially supported when MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is set. From b3301390bd3b221db91965a6759e6430246ad35c Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 13 Mar 2024 13:34:31 +0000 Subject: [PATCH 201/211] Mention the CVE number that is fixed Signed-off-by: David Horstmann --- ChangeLog.d/psa-shared-memory-protection.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.d/psa-shared-memory-protection.txt b/ChangeLog.d/psa-shared-memory-protection.txt index 765c97c52f57..e5ee51397006 100644 --- a/ChangeLog.d/psa-shared-memory-protection.txt +++ b/ChangeLog.d/psa-shared-memory-protection.txt @@ -11,6 +11,7 @@ Security MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS. Note that setting this option will cause input-output buffer overlap to be only partially supported. + Fixes CVE-2024-28960 Bugfix * Fully support arbitrary overlap between inputs and outputs of PSA functions. Note that overlap is still only partially supported when From f70eceec036e141661f08568a535a63c17539322 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 13 Mar 2024 14:06:58 +0000 Subject: [PATCH 202/211] Use the exact phrase 'shared memory' This allows people searching for this phrase to find this ChangeLog entry. Signed-off-by: David Horstmann --- ChangeLog.d/psa-shared-memory-protection.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ChangeLog.d/psa-shared-memory-protection.txt b/ChangeLog.d/psa-shared-memory-protection.txt index e5ee51397006..e19c9bc1a6c2 100644 --- a/ChangeLog.d/psa-shared-memory-protection.txt +++ b/ChangeLog.d/psa-shared-memory-protection.txt @@ -6,9 +6,8 @@ Security by copying buffers. This feature increases code size and memory usage. If buffers passed to PSA functions are owned exclusively by the PSA core for the duration of - the function call (i.e. no buffer parameters are stored in memory shared - with an untrusted party), copying may be disabled by setting - MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS. + the function call (i.e. no buffer parameters are in shared memory), + copying may be disabled by setting MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS. Note that setting this option will cause input-output buffer overlap to be only partially supported. Fixes CVE-2024-28960 From 227189f6b382816868fb4398745c39186cfd5966 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 13 Mar 2024 14:09:41 +0000 Subject: [PATCH 203/211] Reference issue #3266 This is the issue that tracks incomplete support for buffer overlap, so we should refer to it when we discuss partial support whenever MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is set. Signed-off-by: David Horstmann --- ChangeLog.d/psa-shared-memory-protection.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog.d/psa-shared-memory-protection.txt b/ChangeLog.d/psa-shared-memory-protection.txt index e19c9bc1a6c2..09779b7d27b0 100644 --- a/ChangeLog.d/psa-shared-memory-protection.txt +++ b/ChangeLog.d/psa-shared-memory-protection.txt @@ -9,9 +9,9 @@ Security the function call (i.e. no buffer parameters are in shared memory), copying may be disabled by setting MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS. Note that setting this option will cause input-output buffer overlap to - be only partially supported. + be only partially supported (#3266). Fixes CVE-2024-28960 Bugfix * Fully support arbitrary overlap between inputs and outputs of PSA functions. Note that overlap is still only partially supported when - MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is set. + MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is set (#3266). From 4201533196cd4703a980f33d98606bdbc66412fe Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 13 Mar 2024 15:42:31 +0000 Subject: [PATCH 204/211] Invert and rename config option Replace MBEDTLS_PSA_COPY_CALLER_BUFFERS with inverse: !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS. This ensures that buffer protection is enabled by default without any change to the Mbed TLS config file. Signed-off-by: David Horstmann --- include/mbedtls/config.h | 18 +++++++++++------- library/psa_crypto.c | 34 +++++++++++++++++----------------- tests/scripts/all.sh | 8 ++++---- tests/src/helpers.c | 4 ++-- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index d48df66e5b71..4842fd494c9b 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1571,20 +1571,24 @@ //#define MBEDTLS_PSA_INJECT_ENTROPY /** - * \def MBEDTLS_PSA_COPY_CALLER_BUFFERS + * \def MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS * - * Make local copies of buffers supplied by the callers of PSA functions. + * Assume all buffers passed to PSA functions are owned exclusively by the + * PSA function and are not stored in shared memory. * - * This should be enabled whenever caller-supplied buffers are owned by - * an untrusted party, for example where arguments to PSA calls are passed + * This option may be enabled if all buffers passed to any PSA function reside + * in memory that is accessible only to the PSA function during its execution. + * + * This option MUST be disabled whenever buffer arguments are in memory shared + * with an untrusted party, for example where arguments to PSA calls are passed * across a trust boundary. * - * \note Enabling this option increases memory usage and code size. + * \note Enabling this option reduces memory usage and code size. * - * \note Disabling this option causes overlap of input and output buffers + * \note Enabling this option causes overlap of input and output buffers * not to be supported by PSA functions. */ -#define MBEDTLS_PSA_COPY_CALLER_BUFFERS +//#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS /** * \def MBEDTLS_RSA_NO_CRT diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 8e981f61f69f..e85e5792e2b8 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -106,7 +106,7 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = if (global_data.initialized == 0) \ return PSA_ERROR_BAD_STATE; -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) /* Declare a local copy of an input buffer and a variable that will be used * to store a pointer to the start of the buffer. @@ -202,7 +202,7 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = status = local_output_status; \ } \ } while (0) -#else /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ +#else /* !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */ #define LOCAL_INPUT_DECLARE(input, input_copy_name) \ const uint8_t *input_copy_name = NULL; #define LOCAL_INPUT_ALLOC(input, length, input_copy) \ @@ -215,7 +215,7 @@ mbedtls_psa_drbg_context_t *const mbedtls_psa_random_state = output_copy = output; #define LOCAL_OUTPUT_FREE(output, output_copy) \ output_copy = NULL; -#endif /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ +#endif /* !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */ psa_status_t mbedtls_to_psa_error(int ret) { @@ -1506,7 +1506,7 @@ psa_status_t psa_export_key(mbedtls_svc_key_id_t key, slot->key.data, slot->key.bytes, data, data_size, data_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif unlock_status = psa_unlock_key_slot(slot); @@ -2362,7 +2362,7 @@ psa_status_t psa_hash_finish(psa_hash_operation_t *operation, LOCAL_OUTPUT_ALLOC(hash_external, hash_size, hash); status = psa_hash_finish_internal(operation, hash, hash_size, hash_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif LOCAL_OUTPUT_FREE(hash_external, hash); @@ -2425,7 +2425,7 @@ psa_status_t psa_hash_compute(psa_algorithm_t alg, status = psa_driver_wrapper_hash_compute(alg, input, input_length, hash, hash_size, hash_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif LOCAL_INPUT_FREE(input_external, input); @@ -2667,7 +2667,7 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation, psa_mac_abort(operation); } -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif LOCAL_INPUT_FREE(input_external, input); @@ -2852,7 +2852,7 @@ psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key, input, input_length, mac, mac_size, mac_length, 1); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif LOCAL_INPUT_FREE(input_external, input); @@ -3110,7 +3110,7 @@ psa_status_t psa_sign_message(mbedtls_svc_key_id_t key, status = psa_sign_internal(key, 1, alg, input, input_length, signature, signature_size, signature_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif LOCAL_INPUT_FREE(input_external, input); @@ -3168,7 +3168,7 @@ psa_status_t psa_verify_message(mbedtls_svc_key_id_t key, status = psa_verify_internal(key, 1, alg, input, input_length, signature, signature_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif LOCAL_INPUT_FREE(input_external, input); @@ -3242,7 +3242,7 @@ psa_status_t psa_sign_hash(mbedtls_svc_key_id_t key, status = psa_sign_internal(key, 0, alg, hash, hash_length, signature, signature_size, signature_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif LOCAL_INPUT_FREE(hash_external, hash); @@ -3314,7 +3314,7 @@ psa_status_t psa_verify_hash(mbedtls_svc_key_id_t key, status = psa_verify_internal(key, 0, alg, hash, hash_length, signature, signature_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif LOCAL_INPUT_FREE(hash_external, hash); @@ -4106,7 +4106,7 @@ psa_status_t psa_aead_encrypt(mbedtls_svc_key_id_t key, } /* Exit label is only used for buffer copying, prevent unused warnings. */ -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif LOCAL_INPUT_FREE(nonce_external, nonce); @@ -4174,7 +4174,7 @@ psa_status_t psa_aead_decrypt(mbedtls_svc_key_id_t key, } /* Exit label is only used for buffer copying, prevent unused warnings. */ -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif LOCAL_INPUT_FREE(nonce_external, nonce); @@ -5232,7 +5232,7 @@ psa_status_t psa_key_derivation_input_bytes( status = psa_key_derivation_input_internal(operation, step, PSA_KEY_TYPE_NONE, data, data_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif LOCAL_INPUT_FREE(data_external, data); @@ -5450,7 +5450,7 @@ psa_status_t psa_key_derivation_key_agreement(psa_key_derivation_operation_t *op slot, peer_key, peer_key_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif if (status != PSA_SUCCESS) { @@ -5622,7 +5622,7 @@ psa_status_t psa_generate_random(uint8_t *output_external, status = psa_generate_random_internal(output, output_size); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) exit: #endif LOCAL_OUTPUT_FREE(output_external, output); diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index 345cfd67e4eb..6b4b4e4a3ecd 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -947,14 +947,14 @@ component_test_psa_crypto_key_id_encodes_owner () { make test } -component_test_no_psa_copy_caller_buffers () { - msg "build: full config - MBEDTLS_PSA_COPY_CALLER_BUFFERS, cmake, gcc, ASan" +component_test_psa_assume_exclusive_buffers () { + msg "build: full config + MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS, cmake, gcc, ASan" scripts/config.py full - scripts/config.py unset MBEDTLS_PSA_COPY_CALLER_BUFFERS + scripts/config.py set MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS CC=gcc cmake -D CMAKE_BUILD_TYPE:String=Asan . make - msg "test: full config - MBEDTLS_PSA_COPY_CALLER_BUFFERS, cmake, gcc, ASan" + msg "test: full config + MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS, cmake, gcc, ASan" make test } diff --git a/tests/src/helpers.c b/tests/src/helpers.c index fd7b548d112b..a1e1d459ce88 100644 --- a/tests/src/helpers.c +++ b/tests/src/helpers.c @@ -51,7 +51,7 @@ int mbedtls_test_platform_setup(void) int ret = 0; #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \ - && defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) \ + && !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) \ && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) mbedtls_poison_test_hooks_setup(); #endif @@ -77,7 +77,7 @@ int mbedtls_test_platform_setup(void) void mbedtls_test_platform_teardown(void) { #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_PSA_CRYPTO_C) \ - && defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) \ + && !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) \ && defined(MBEDTLS_TEST_MEMORY_CAN_POISON) mbedtls_poison_test_hooks_teardown(); #endif From 43c128db3ecb56d0e9b34b81107241e56704dee4 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Wed, 13 Mar 2024 15:57:46 +0000 Subject: [PATCH 205/211] Update wrapper generation script and regenerate Update the guards generated by the wrapper generation script to use !MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS and regenerate the PSA test wrappers. Signed-off-by: David Horstmann --- tests/scripts/generate_psa_wrappers.py | 4 +- tests/src/psa_test_wrappers.c | 256 ++++++++++++------------- 2 files changed, 130 insertions(+), 130 deletions(-) diff --git a/tests/scripts/generate_psa_wrappers.py b/tests/scripts/generate_psa_wrappers.py index 1ab71d31e29e..755a5842a73d 100755 --- a/tests/scripts/generate_psa_wrappers.py +++ b/tests/scripts/generate_psa_wrappers.py @@ -140,10 +140,10 @@ def _write_poison_buffer_parameters(self, out: typing_util.Writable, """ if not buffer_parameters: return - out.write('#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS)\n') + out.write('#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)\n') for param in buffer_parameters: self._write_poison_buffer_parameter(out, param, poison) - out.write('#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */\n') + out.write('#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */\n') @staticmethod def _parameter_should_be_copied(function_name: str, diff --git a/tests/src/psa_test_wrappers.c b/tests/src/psa_test_wrappers.c index 3aa802039c05..e70ffb34af46 100644 --- a/tests/src/psa_test_wrappers.c +++ b/tests/src/psa_test_wrappers.c @@ -66,19 +66,19 @@ psa_status_t mbedtls_test_wrap_psa_aead_decrypt( size_t arg9_plaintext_size, size_t *arg10_plaintext_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_nonce, arg3_nonce_length); MBEDTLS_TEST_MEMORY_POISON(arg4_additional_data, arg5_additional_data_length); MBEDTLS_TEST_MEMORY_POISON(arg6_ciphertext, arg7_ciphertext_length); MBEDTLS_TEST_MEMORY_POISON(arg8_plaintext, arg9_plaintext_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_aead_decrypt)(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_ciphertext, arg7_ciphertext_length, arg8_plaintext, arg9_plaintext_size, arg10_plaintext_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_nonce, arg3_nonce_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_additional_data, arg5_additional_data_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg6_ciphertext, arg7_ciphertext_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg8_plaintext, arg9_plaintext_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -96,19 +96,19 @@ psa_status_t mbedtls_test_wrap_psa_aead_encrypt( size_t arg9_ciphertext_size, size_t *arg10_ciphertext_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_nonce, arg3_nonce_length); MBEDTLS_TEST_MEMORY_POISON(arg4_additional_data, arg5_additional_data_length); MBEDTLS_TEST_MEMORY_POISON(arg6_plaintext, arg7_plaintext_length); MBEDTLS_TEST_MEMORY_POISON(arg8_ciphertext, arg9_ciphertext_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_aead_encrypt)(arg0_key, arg1_alg, arg2_nonce, arg3_nonce_length, arg4_additional_data, arg5_additional_data_length, arg6_plaintext, arg7_plaintext_length, arg8_ciphertext, arg9_ciphertext_size, arg10_ciphertext_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_nonce, arg3_nonce_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_additional_data, arg5_additional_data_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg6_plaintext, arg7_plaintext_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg8_ciphertext, arg9_ciphertext_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -124,17 +124,17 @@ psa_status_t mbedtls_test_wrap_psa_asymmetric_decrypt( size_t arg7_output_size, size_t *arg8_output_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_POISON(arg4_salt, arg5_salt_length); MBEDTLS_TEST_MEMORY_POISON(arg6_output, arg7_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_asymmetric_decrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_salt, arg5_salt_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg6_output, arg7_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -150,17 +150,17 @@ psa_status_t mbedtls_test_wrap_psa_asymmetric_encrypt( size_t arg7_output_size, size_t *arg8_output_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_POISON(arg4_salt, arg5_salt_length); MBEDTLS_TEST_MEMORY_POISON(arg6_output, arg7_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_asymmetric_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_salt, arg5_salt_length, arg6_output, arg7_output_size, arg8_output_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_salt, arg5_salt_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg6_output, arg7_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -182,15 +182,15 @@ psa_status_t mbedtls_test_wrap_psa_cipher_decrypt( size_t arg5_output_size, size_t *arg6_output_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_POISON(arg4_output, arg5_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_cipher_decrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_output, arg5_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -214,15 +214,15 @@ psa_status_t mbedtls_test_wrap_psa_cipher_encrypt( size_t arg5_output_size, size_t *arg6_output_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_POISON(arg4_output, arg5_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_cipher_encrypt)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_output, arg5_output_size, arg6_output_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_output, arg5_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -243,13 +243,13 @@ psa_status_t mbedtls_test_wrap_psa_cipher_finish( size_t arg2_output_size, size_t *arg3_output_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_output, arg2_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_cipher_finish)(arg0_operation, arg1_output, arg2_output_size, arg3_output_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_output, arg2_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -260,13 +260,13 @@ psa_status_t mbedtls_test_wrap_psa_cipher_generate_iv( size_t arg2_iv_size, size_t *arg3_iv_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_iv, arg2_iv_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_cipher_generate_iv)(arg0_operation, arg1_iv, arg2_iv_size, arg3_iv_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_iv, arg2_iv_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -276,13 +276,13 @@ psa_status_t mbedtls_test_wrap_psa_cipher_set_iv( const uint8_t *arg1_iv, size_t arg2_iv_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_iv, arg2_iv_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_cipher_set_iv)(arg0_operation, arg1_iv, arg2_iv_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_iv, arg2_iv_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -295,15 +295,15 @@ psa_status_t mbedtls_test_wrap_psa_cipher_update( size_t arg4_output_size, size_t *arg5_output_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_input, arg2_input_length); MBEDTLS_TEST_MEMORY_POISON(arg3_output, arg4_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_cipher_update)(arg0_operation, arg1_input, arg2_input_length, arg3_output, arg4_output_size, arg5_output_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_input, arg2_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg3_output, arg4_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -339,13 +339,13 @@ psa_status_t mbedtls_test_wrap_psa_export_key( size_t arg2_data_size, size_t *arg3_data_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_data, arg2_data_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_export_key)(arg0_key, arg1_data, arg2_data_size, arg3_data_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_data, arg2_data_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -356,13 +356,13 @@ psa_status_t mbedtls_test_wrap_psa_export_public_key( size_t arg2_data_size, size_t *arg3_data_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_data, arg2_data_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_export_public_key)(arg0_key, arg1_data, arg2_data_size, arg3_data_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_data, arg2_data_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -380,13 +380,13 @@ psa_status_t mbedtls_test_wrap_psa_generate_random( uint8_t *arg0_output, size_t arg1_output_size) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg0_output, arg1_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_generate_random)(arg0_output, arg1_output_size); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg0_output, arg1_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -424,15 +424,15 @@ psa_status_t mbedtls_test_wrap_psa_hash_compare( const uint8_t *arg3_hash, size_t arg4_hash_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_input, arg2_input_length); MBEDTLS_TEST_MEMORY_POISON(arg3_hash, arg4_hash_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_hash_compare)(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_input, arg2_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg3_hash, arg4_hash_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -445,15 +445,15 @@ psa_status_t mbedtls_test_wrap_psa_hash_compute( size_t arg4_hash_size, size_t *arg5_hash_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_input, arg2_input_length); MBEDTLS_TEST_MEMORY_POISON(arg3_hash, arg4_hash_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_hash_compute)(arg0_alg, arg1_input, arg2_input_length, arg3_hash, arg4_hash_size, arg5_hash_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_input, arg2_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg3_hash, arg4_hash_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -464,13 +464,13 @@ psa_status_t mbedtls_test_wrap_psa_hash_finish( size_t arg2_hash_size, size_t *arg3_hash_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_hash, arg2_hash_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_hash_finish)(arg0_operation, arg1_hash, arg2_hash_size, arg3_hash_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_hash, arg2_hash_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -489,13 +489,13 @@ psa_status_t mbedtls_test_wrap_psa_hash_update( const uint8_t *arg1_input, size_t arg2_input_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_input, arg2_input_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_hash_update)(arg0_operation, arg1_input, arg2_input_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_input, arg2_input_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -505,13 +505,13 @@ psa_status_t mbedtls_test_wrap_psa_hash_verify( const uint8_t *arg1_hash, size_t arg2_hash_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_hash, arg2_hash_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_hash_verify)(arg0_operation, arg1_hash, arg2_hash_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_hash, arg2_hash_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -522,13 +522,13 @@ psa_status_t mbedtls_test_wrap_psa_import_key( size_t arg2_data_length, mbedtls_svc_key_id_t *arg3_key) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_data, arg2_data_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_import_key)(arg0_attributes, arg1_data, arg2_data_length, arg3_key); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_data, arg2_data_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -556,13 +556,13 @@ psa_status_t mbedtls_test_wrap_psa_key_derivation_input_bytes( const uint8_t *arg2_data, size_t arg3_data_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_data, arg3_data_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_key_derivation_input_bytes)(arg0_operation, arg1_step, arg2_data, arg3_data_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_data, arg3_data_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -584,13 +584,13 @@ psa_status_t mbedtls_test_wrap_psa_key_derivation_key_agreement( const uint8_t *arg3_peer_key, size_t arg4_peer_key_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg3_peer_key, arg4_peer_key_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_key_derivation_key_agreement)(arg0_operation, arg1_step, arg2_private_key, arg3_peer_key, arg4_peer_key_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg3_peer_key, arg4_peer_key_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -600,13 +600,13 @@ psa_status_t mbedtls_test_wrap_psa_key_derivation_output_bytes( uint8_t *arg1_output, size_t arg2_output_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_output, arg2_output_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_key_derivation_output_bytes)(arg0_operation, arg1_output, arg2_output_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_output, arg2_output_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -656,15 +656,15 @@ psa_status_t mbedtls_test_wrap_psa_mac_compute( size_t arg5_mac_size, size_t *arg6_mac_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_POISON(arg4_mac, arg5_mac_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_mac_compute)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_size, arg6_mac_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_mac, arg5_mac_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -675,13 +675,13 @@ psa_status_t mbedtls_test_wrap_psa_mac_sign_finish( size_t arg2_mac_size, size_t *arg3_mac_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_mac, arg2_mac_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_mac_sign_finish)(arg0_operation, arg1_mac, arg2_mac_size, arg3_mac_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_mac, arg2_mac_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -701,13 +701,13 @@ psa_status_t mbedtls_test_wrap_psa_mac_update( const uint8_t *arg1_input, size_t arg2_input_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_input, arg2_input_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_mac_update)(arg0_operation, arg1_input, arg2_input_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_input, arg2_input_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -720,15 +720,15 @@ psa_status_t mbedtls_test_wrap_psa_mac_verify( const uint8_t *arg4_mac, size_t arg5_mac_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_POISON(arg4_mac, arg5_mac_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_mac_verify)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_mac, arg5_mac_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_mac, arg5_mac_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -738,13 +738,13 @@ psa_status_t mbedtls_test_wrap_psa_mac_verify_finish( const uint8_t *arg1_mac, size_t arg2_mac_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg1_mac, arg2_mac_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_mac_verify_finish)(arg0_operation, arg1_mac, arg2_mac_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg1_mac, arg2_mac_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -776,15 +776,15 @@ psa_status_t mbedtls_test_wrap_psa_raw_key_agreement( size_t arg5_output_size, size_t *arg6_output_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_peer_key, arg3_peer_key_length); MBEDTLS_TEST_MEMORY_POISON(arg4_output, arg5_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_raw_key_agreement)(arg0_alg, arg1_private_key, arg2_peer_key, arg3_peer_key_length, arg4_output, arg5_output_size, arg6_output_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_peer_key, arg3_peer_key_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_output, arg5_output_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -798,15 +798,15 @@ psa_status_t mbedtls_test_wrap_psa_sign_hash( size_t arg5_signature_size, size_t *arg6_signature_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_hash, arg3_hash_length); MBEDTLS_TEST_MEMORY_POISON(arg4_signature, arg5_signature_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_sign_hash)(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_size, arg6_signature_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_hash, arg3_hash_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_signature, arg5_signature_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -820,15 +820,15 @@ psa_status_t mbedtls_test_wrap_psa_sign_message( size_t arg5_signature_size, size_t *arg6_signature_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_POISON(arg4_signature, arg5_signature_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_sign_message)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_size, arg6_signature_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_signature, arg5_signature_size); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -841,15 +841,15 @@ psa_status_t mbedtls_test_wrap_psa_verify_hash( const uint8_t *arg4_signature, size_t arg5_signature_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_hash, arg3_hash_length); MBEDTLS_TEST_MEMORY_POISON(arg4_signature, arg5_signature_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_verify_hash)(arg0_key, arg1_alg, arg2_hash, arg3_hash_length, arg4_signature, arg5_signature_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_hash, arg3_hash_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_signature, arg5_signature_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } @@ -862,15 +862,15 @@ psa_status_t mbedtls_test_wrap_psa_verify_message( const uint8_t *arg4_signature, size_t arg5_signature_length) { -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_POISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_POISON(arg4_signature, arg5_signature_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ psa_status_t status = (psa_verify_message)(arg0_key, arg1_alg, arg2_input, arg3_input_length, arg4_signature, arg5_signature_length); -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) +#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) MBEDTLS_TEST_MEMORY_UNPOISON(arg2_input, arg3_input_length); MBEDTLS_TEST_MEMORY_UNPOISON(arg4_signature, arg5_signature_length); -#endif /* defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) */ +#endif /* !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) */ return status; } From c34fa81ea975f96996c37a867b4adf60977dfd43 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 14 Mar 2024 09:24:38 +0000 Subject: [PATCH 206/211] Remove MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS from full This option removes a feature (buffer protection) so should not be in the full config. Signed-off-by: David Horstmann --- scripts/config.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/config.py b/scripts/config.py index 604f8a847d41..c7563e4c9bf6 100755 --- a/scripts/config.py +++ b/scripts/config.py @@ -200,6 +200,7 @@ def realfull_adapter(_name, active, section): 'MBEDTLS_TEST_NULL_ENTROPY', # removes a feature 'MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION', # influences the use of X.509 in TLS 'MBEDTLS_ZLIB_SUPPORT', # build dependency (libz) + 'MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS', # removes a feature ]) def is_seamless_alt(name): From 5bada225ebb45f1cbe2dd32fc4fcba68bd6849c8 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 14 Mar 2024 11:20:47 +0000 Subject: [PATCH 207/211] Update generated files with inverted option Achieved by running: tests/scripts/check-generated-files.sh -u Signed-off-by: David Horstmann --- library/version_features.c | 6 +++--- programs/test/query_config.c | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/version_features.c b/library/version_features.c index 170e7fae847c..6f663b12a730 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -456,9 +456,9 @@ static const char * const features[] = { #if defined(MBEDTLS_PSA_INJECT_ENTROPY) "MBEDTLS_PSA_INJECT_ENTROPY", #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) - "MBEDTLS_PSA_COPY_CALLER_BUFFERS", -#endif /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ +#if defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) + "MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS", +#endif /* MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */ #if defined(MBEDTLS_RSA_NO_CRT) "MBEDTLS_RSA_NO_CRT", #endif /* MBEDTLS_RSA_NO_CRT */ diff --git a/programs/test/query_config.c b/programs/test/query_config.c index cd798f7c7d45..5d9886bcd93b 100644 --- a/programs/test/query_config.c +++ b/programs/test/query_config.c @@ -1296,13 +1296,13 @@ int query_config(const char *config) } #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) - if( strcmp( "MBEDTLS_PSA_COPY_CALLER_BUFFERS", config ) == 0 ) +#if defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) + if( strcmp( "MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS", config ) == 0 ) { - MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_COPY_CALLER_BUFFERS ); + MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS ); return( 0 ); } -#endif /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ +#endif /* MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */ #if defined(MBEDTLS_RSA_NO_CRT) if( strcmp( "MBEDTLS_RSA_NO_CRT", config ) == 0 ) @@ -3466,9 +3466,9 @@ void list_config(void) OUTPUT_MACRO_NAME_VALUE(MBEDTLS_PSA_INJECT_ENTROPY); #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ -#if defined(MBEDTLS_PSA_COPY_CALLER_BUFFERS) - OUTPUT_MACRO_NAME_VALUE(MBEDTLS_PSA_COPY_CALLER_BUFFERS); -#endif /* MBEDTLS_PSA_COPY_CALLER_BUFFERS */ +#if defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS) + OUTPUT_MACRO_NAME_VALUE(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS); +#endif /* MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS */ #if defined(MBEDTLS_RSA_NO_CRT) OUTPUT_MACRO_NAME_VALUE(MBEDTLS_RSA_NO_CRT); From a7cb1d0fc950a985b8e6a35714aeca45bd710fc9 Mon Sep 17 00:00:00 2001 From: David Horstmann Date: Thu, 14 Mar 2024 14:52:45 +0000 Subject: [PATCH 208/211] Preserve alphabetical sorting of config options In the list that is excluded from the full config. Signed-off-by: David Horstmann --- scripts/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/config.py b/scripts/config.py index c7563e4c9bf6..22bdb5e6d94a 100755 --- a/scripts/config.py +++ b/scripts/config.py @@ -185,6 +185,7 @@ def realfull_adapter(_name, active, section): 'MBEDTLS_NO_UDBL_DIVISION', # influences anything that uses bignum 'MBEDTLS_PKCS11_C', # build dependency (libpkcs11-helper) 'MBEDTLS_PLATFORM_NO_STD_FUNCTIONS', # removes a feature + 'MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS', # removes a feature 'MBEDTLS_PSA_CRYPTO_CONFIG', # toggles old/new style PSA config 'MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG', # behavior change + build dependency 'MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER', # incompatible with USE_PSA_CRYPTO @@ -200,7 +201,6 @@ def realfull_adapter(_name, active, section): 'MBEDTLS_TEST_NULL_ENTROPY', # removes a feature 'MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION', # influences the use of X.509 in TLS 'MBEDTLS_ZLIB_SUPPORT', # build dependency (libz) - 'MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS', # removes a feature ]) def is_seamless_alt(name): From 869821100813190d8bdb0722020a6b44e285a655 Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Thu, 21 Mar 2024 15:47:24 +0000 Subject: [PATCH 209/211] Assemble Changelog Signed-off-by: Minos Galanakis --- ChangeLog | 52 +++++++++++++++++++ ChangeLog.d/8372.txt | 3 -- ChangeLog.d/cmake_use_GnuInstallDirs.txt | 5 -- ChangeLog.d/fix-alpn-negotiating-bug.txt | 3 -- .../fix-cmake-3rdparty-custom-config.txt | 3 -- ChangeLog.d/fix-mingw32-build.txt | 4 -- .../fix-ssl-session-serialization-config.txt | 4 -- .../fix_kdf_incorrect_initial_capacity.txt | 3 -- ChangeLog.d/gen-key-segfault.txt | 3 -- ChangeLog.d/pkg-config-files-addition.txt | 3 -- ChangeLog.d/pkwrite-pem-use-heap.txt | 4 -- ChangeLog.d/psa-shared-memory-protection.txt | 17 ------ ChangeLog.d/rsa-bitlen.txt | 3 -- 13 files changed, 52 insertions(+), 55 deletions(-) delete mode 100644 ChangeLog.d/8372.txt delete mode 100644 ChangeLog.d/cmake_use_GnuInstallDirs.txt delete mode 100644 ChangeLog.d/fix-alpn-negotiating-bug.txt delete mode 100644 ChangeLog.d/fix-cmake-3rdparty-custom-config.txt delete mode 100644 ChangeLog.d/fix-mingw32-build.txt delete mode 100644 ChangeLog.d/fix-ssl-session-serialization-config.txt delete mode 100644 ChangeLog.d/fix_kdf_incorrect_initial_capacity.txt delete mode 100644 ChangeLog.d/gen-key-segfault.txt delete mode 100644 ChangeLog.d/pkg-config-files-addition.txt delete mode 100644 ChangeLog.d/pkwrite-pem-use-heap.txt delete mode 100644 ChangeLog.d/psa-shared-memory-protection.txt delete mode 100644 ChangeLog.d/rsa-bitlen.txt diff --git a/ChangeLog b/ChangeLog index 5434e5509b1e..497d7195254c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,57 @@ Mbed TLS ChangeLog (Sorted per branch, date) += Mbed TLS x.x.x branch released xxxx-xx-xx + +Features + * AES-NI is now supported in Windows builds with clang and clang-cl. + Resolves #8372. + * Add pc files for pkg-config. eg.: + pkg-config --cflags --libs (mbedtls|mbedcrypto|mbedx509) + +Security + * Passing buffers that are stored in untrusted memory as arguments + to PSA functions is now secure by default. + The PSA core now protects against modification of inputs or exposure + of intermediate outputs during operations. This is currently implemented + by copying buffers. + This feature increases code size and memory usage. If buffers passed to + PSA functions are owned exclusively by the PSA core for the duration of + the function call (i.e. no buffer parameters are in shared memory), + copying may be disabled by setting MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS. + Note that setting this option will cause input-output buffer overlap to + be only partially supported (#3266). + Fixes CVE-2024-28960 + +Bugfix + * Fix the build with CMake when Everest is enabled through + a user configuration file or the compiler command line. Fixes #8165. + * Fix an inconsistency between implementations and usages of `__cpuid`, + which mainly causes failures when building Windows target using + mingw or clang. Fixes #8334 & #8332. + * Correct initial capacities for key derivation algorithms:TLS12_PRF, + TLS12_PSK_TO_MS + * Fix mbedtls_pk_get_bitlen() for RSA keys whose size is not a + multiple of 8. Fixes #868. + * Avoid segmentation fault caused by releasing not initialized + entropy resource in gen_key example. Fixes #8809. + * Fix missing bitflags in SSL session serialization headers. Their absence + allowed SSL sessions saved in one configuration to be loaded in a + different, incompatible configuration. + * Fix the restoration of the ALPN when loading serialized connection with + * the mbedtls_ssl_context_load() API. + * Fully support arbitrary overlap between inputs and outputs of PSA + functions. Note that overlap is still only partially supported when + MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is set (#3266). + +Changes + * Use heap memory to allocate DER encoded public/private key. + This reduces stack usage significantly for writing a public/private + key to a PEM string. + * cmake: Use GnuInstallDirs to customize install directories + Replace custom LIB_INSTALL_DIR variable with standard CMAKE_INSTALL_LIBDIR + variable. For backward compatibility, set CMAKE_INSTALL_LIBDIR if + LIB_INSTALL_DIR is set. + = Mbed TLS 2.28.7 branch released 2024-01-26 Security diff --git a/ChangeLog.d/8372.txt b/ChangeLog.d/8372.txt deleted file mode 100644 index 4a72edfb1a95..000000000000 --- a/ChangeLog.d/8372.txt +++ /dev/null @@ -1,3 +0,0 @@ -Features - * AES-NI is now supported in Windows builds with clang and clang-cl. - Resolves #8372. diff --git a/ChangeLog.d/cmake_use_GnuInstallDirs.txt b/ChangeLog.d/cmake_use_GnuInstallDirs.txt deleted file mode 100644 index d8487555d161..000000000000 --- a/ChangeLog.d/cmake_use_GnuInstallDirs.txt +++ /dev/null @@ -1,5 +0,0 @@ -Changes - * cmake: Use GnuInstallDirs to customize install directories - Replace custom LIB_INSTALL_DIR variable with standard CMAKE_INSTALL_LIBDIR - variable. For backward compatibility, set CMAKE_INSTALL_LIBDIR if - LIB_INSTALL_DIR is set. diff --git a/ChangeLog.d/fix-alpn-negotiating-bug.txt b/ChangeLog.d/fix-alpn-negotiating-bug.txt deleted file mode 100644 index 3bceb37f38c8..000000000000 --- a/ChangeLog.d/fix-alpn-negotiating-bug.txt +++ /dev/null @@ -1,3 +0,0 @@ -Bugfix - * Fix the restoration of the ALPN when loading serialized connection with - * the mbedtls_ssl_context_load() API. diff --git a/ChangeLog.d/fix-cmake-3rdparty-custom-config.txt b/ChangeLog.d/fix-cmake-3rdparty-custom-config.txt deleted file mode 100644 index c52aa3deeed5..000000000000 --- a/ChangeLog.d/fix-cmake-3rdparty-custom-config.txt +++ /dev/null @@ -1,3 +0,0 @@ -Bugfix - * Fix the build with CMake when Everest is enabled through - a user configuration file or the compiler command line. Fixes #8165. diff --git a/ChangeLog.d/fix-mingw32-build.txt b/ChangeLog.d/fix-mingw32-build.txt deleted file mode 100644 index feef0a2c517f..000000000000 --- a/ChangeLog.d/fix-mingw32-build.txt +++ /dev/null @@ -1,4 +0,0 @@ -Bugfix - * Fix an inconsistency between implementations and usages of `__cpuid`, - which mainly causes failures when building Windows target using - mingw or clang. Fixes #8334 & #8332. diff --git a/ChangeLog.d/fix-ssl-session-serialization-config.txt b/ChangeLog.d/fix-ssl-session-serialization-config.txt deleted file mode 100644 index ca1cc81f5e21..000000000000 --- a/ChangeLog.d/fix-ssl-session-serialization-config.txt +++ /dev/null @@ -1,4 +0,0 @@ -Bugfix - * Fix missing bitflags in SSL session serialization headers. Their absence - allowed SSL sessions saved in one configuration to be loaded in a - different, incompatible configuration. diff --git a/ChangeLog.d/fix_kdf_incorrect_initial_capacity.txt b/ChangeLog.d/fix_kdf_incorrect_initial_capacity.txt deleted file mode 100644 index 11b82782fbea..000000000000 --- a/ChangeLog.d/fix_kdf_incorrect_initial_capacity.txt +++ /dev/null @@ -1,3 +0,0 @@ -Bugfix - * Correct initial capacities for key derivation algorithms:TLS12_PRF, - TLS12_PSK_TO_MS diff --git a/ChangeLog.d/gen-key-segfault.txt b/ChangeLog.d/gen-key-segfault.txt deleted file mode 100644 index fefc702726b9..000000000000 --- a/ChangeLog.d/gen-key-segfault.txt +++ /dev/null @@ -1,3 +0,0 @@ -Bugfix - * Avoid segmentation fault caused by releasing not initialized - entropy resource in gen_key example. Fixes #8809. diff --git a/ChangeLog.d/pkg-config-files-addition.txt b/ChangeLog.d/pkg-config-files-addition.txt deleted file mode 100644 index 5df6ffb3be20..000000000000 --- a/ChangeLog.d/pkg-config-files-addition.txt +++ /dev/null @@ -1,3 +0,0 @@ -Features - * Add pc files for pkg-config. eg.: - pkg-config --cflags --libs (mbedtls|mbedcrypto|mbedx509) diff --git a/ChangeLog.d/pkwrite-pem-use-heap.txt b/ChangeLog.d/pkwrite-pem-use-heap.txt deleted file mode 100644 index 11db7b6b06cf..000000000000 --- a/ChangeLog.d/pkwrite-pem-use-heap.txt +++ /dev/null @@ -1,4 +0,0 @@ -Changes - * Use heap memory to allocate DER encoded public/private key. - This reduces stack usage significantly for writing a public/private - key to a PEM string. diff --git a/ChangeLog.d/psa-shared-memory-protection.txt b/ChangeLog.d/psa-shared-memory-protection.txt deleted file mode 100644 index 09779b7d27b0..000000000000 --- a/ChangeLog.d/psa-shared-memory-protection.txt +++ /dev/null @@ -1,17 +0,0 @@ -Security - * Passing buffers that are stored in untrusted memory as arguments - to PSA functions is now secure by default. - The PSA core now protects against modification of inputs or exposure - of intermediate outputs during operations. This is currently implemented - by copying buffers. - This feature increases code size and memory usage. If buffers passed to - PSA functions are owned exclusively by the PSA core for the duration of - the function call (i.e. no buffer parameters are in shared memory), - copying may be disabled by setting MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS. - Note that setting this option will cause input-output buffer overlap to - be only partially supported (#3266). - Fixes CVE-2024-28960 -Bugfix - * Fully support arbitrary overlap between inputs and outputs of PSA - functions. Note that overlap is still only partially supported when - MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is set (#3266). diff --git a/ChangeLog.d/rsa-bitlen.txt b/ChangeLog.d/rsa-bitlen.txt deleted file mode 100644 index 9cb868947ae1..000000000000 --- a/ChangeLog.d/rsa-bitlen.txt +++ /dev/null @@ -1,3 +0,0 @@ -Bugfix - * Fix mbedtls_pk_get_bitlen() for RSA keys whose size is not a - multiple of 8. Fixes #868. From 6fe0ae026f4d3f2a082535a3f5162e993058544b Mon Sep 17 00:00:00 2001 From: Minos Galanakis Date: Thu, 21 Mar 2024 17:52:54 +0000 Subject: [PATCH 210/211] Version bump for 2.28.8 ./scripts/bump_version.sh --version 2.28.8 Signed-off-by: Minos Galanakis --- doxygen/input/doc_mainpage.h | 2 +- doxygen/mbedtls.doxyfile | 2 +- include/mbedtls/version.h | 8 ++++---- library/CMakeLists.txt | 6 +++--- pkgconfig/CMakeLists.txt | 2 +- tests/suites/test_suite_version.data | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doxygen/input/doc_mainpage.h b/doxygen/input/doc_mainpage.h index f22ca106d379..7a240216be33 100644 --- a/doxygen/input/doc_mainpage.h +++ b/doxygen/input/doc_mainpage.h @@ -10,7 +10,7 @@ */ /** - * @mainpage Mbed TLS v2.28.7 API Documentation + * @mainpage Mbed TLS v2.28.8 API Documentation * * This documentation describes the internal structure of Mbed TLS. It was * automatically generated from specially formatted comment blocks in diff --git a/doxygen/mbedtls.doxyfile b/doxygen/mbedtls.doxyfile index 2c710406beac..971a8b2af54b 100644 --- a/doxygen/mbedtls.doxyfile +++ b/doxygen/mbedtls.doxyfile @@ -1,4 +1,4 @@ -PROJECT_NAME = "Mbed TLS v2.28.7" +PROJECT_NAME = "Mbed TLS v2.28.8" OUTPUT_DIRECTORY = ../apidoc/ FULL_PATH_NAMES = NO OPTIMIZE_OUTPUT_FOR_C = YES diff --git a/include/mbedtls/version.h b/include/mbedtls/version.h index 0533bca68128..bbe76b173929 100644 --- a/include/mbedtls/version.h +++ b/include/mbedtls/version.h @@ -26,16 +26,16 @@ */ #define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MINOR 28 -#define MBEDTLS_VERSION_PATCH 7 +#define MBEDTLS_VERSION_PATCH 8 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x021C0700 -#define MBEDTLS_VERSION_STRING "2.28.7" -#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 2.28.7" +#define MBEDTLS_VERSION_NUMBER 0x021C0800 +#define MBEDTLS_VERSION_STRING "2.28.8" +#define MBEDTLS_VERSION_STRING_FULL "Mbed TLS 2.28.8" #if defined(MBEDTLS_VERSION_C) diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 5a9352c1cff3..48e51a1581db 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -204,15 +204,15 @@ endif(USE_STATIC_MBEDTLS_LIBRARY) if(USE_SHARED_MBEDTLS_LIBRARY) set(CMAKE_LIBRARY_PATH ${CMAKE_CURRENT_BINARY_DIR}) add_library(${mbedcrypto_target} SHARED ${src_crypto}) - set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 2.28.7 SOVERSION 7) + set_target_properties(${mbedcrypto_target} PROPERTIES VERSION 2.28.8 SOVERSION 7) target_link_libraries(${mbedcrypto_target} PUBLIC ${libs}) add_library(${mbedx509_target} SHARED ${src_x509}) - set_target_properties(${mbedx509_target} PROPERTIES VERSION 2.28.7 SOVERSION 1) + set_target_properties(${mbedx509_target} PROPERTIES VERSION 2.28.8 SOVERSION 1) target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target}) add_library(${mbedtls_target} SHARED ${src_tls}) - set_target_properties(${mbedtls_target} PROPERTIES VERSION 2.28.7 SOVERSION 14) + set_target_properties(${mbedtls_target} PROPERTIES VERSION 2.28.8 SOVERSION 14) target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target}) endif(USE_SHARED_MBEDTLS_LIBRARY) diff --git a/pkgconfig/CMakeLists.txt b/pkgconfig/CMakeLists.txt index 6def088d2e83..40ef9fd1582a 100644 --- a/pkgconfig/CMakeLists.txt +++ b/pkgconfig/CMakeLists.txt @@ -9,7 +9,7 @@ if(NOT DISABLE_PACKAGE_CONFIG_AND_INSTALL) set(PKGCONFIG_PROJECT_HOMEPAGE_URL "https://www.trustedfirmware.org/projects/mbed-tls/") # Following the conventsion for DESCRIPTION and HOMEPAGE_URL, VERSION wasn't added until 3.0 and depends on policy CMP0048 - set(PKGCONFIG_VERSION 2.28.7) + set(PKGCONFIG_VERSION 2.28.8) configure_file(mbedcrypto.pc.in mbedcrypto.pc @ONLY) install(FILES diff --git a/tests/suites/test_suite_version.data b/tests/suites/test_suite_version.data index 7d8f252ccefc..148aa463dc43 100644 --- a/tests/suites/test_suite_version.data +++ b/tests/suites/test_suite_version.data @@ -1,8 +1,8 @@ Check compile time library version -check_compiletime_version:"2.28.7" +check_compiletime_version:"2.28.8" Check runtime library version -check_runtime_version:"2.28.7" +check_runtime_version:"2.28.8" Check for MBEDTLS_VERSION_C check_feature:"MBEDTLS_VERSION_C":0 From c58cb5992c871e326fc138ebed90e0a58b8cebcd Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 22 Mar 2024 10:08:44 +0000 Subject: [PATCH 211/211] Fix some Changelog typos Signed-off-by: Dave Rodgman --- ChangeLog | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 497d7195254c..4df6a665346b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,11 @@ Mbed TLS ChangeLog (Sorted per branch, date) -= Mbed TLS x.x.x branch released xxxx-xx-xx += Mbed TLS 2.28.8 branch released 2024-03-28 Features - * AES-NI is now supported in Windows builds with clang and clang-cl. - Resolves #8372. - * Add pc files for pkg-config. eg.: + * AES-NI is now supported in Windows builds with clang and clang-cl. + Resolves #8372. + * Add pc files for pkg-config, e.g.: pkg-config --cflags --libs (mbedtls|mbedcrypto|mbedx509) Security @@ -20,16 +20,16 @@ Security copying may be disabled by setting MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS. Note that setting this option will cause input-output buffer overlap to be only partially supported (#3266). - Fixes CVE-2024-28960 + Fixes CVE-2024-28960. Bugfix * Fix the build with CMake when Everest is enabled through a user configuration file or the compiler command line. Fixes #8165. - * Fix an inconsistency between implementations and usages of `__cpuid`, - which mainly causes failures when building Windows target using - mingw or clang. Fixes #8334 & #8332. - * Correct initial capacities for key derivation algorithms:TLS12_PRF, - TLS12_PSK_TO_MS + * Fix an inconsistency between implementations and usages of `__cpuid`, + which mainly causes failures when building Windows target using + mingw or clang. Fixes #8334 & #8332. + * Correct initial capacities for key derivation algorithms: TLS12_PRF, + TLS12_PSK_TO_MS. * Fix mbedtls_pk_get_bitlen() for RSA keys whose size is not a multiple of 8. Fixes #868. * Avoid segmentation fault caused by releasing not initialized @@ -38,7 +38,7 @@ Bugfix allowed SSL sessions saved in one configuration to be loaded in a different, incompatible configuration. * Fix the restoration of the ALPN when loading serialized connection with - * the mbedtls_ssl_context_load() API. + the mbedtls_ssl_context_load() API. * Fully support arbitrary overlap between inputs and outputs of PSA functions. Note that overlap is still only partially supported when MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is set (#3266).