Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ChangeLog.d/psa-buffer-copying.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Features
* PSA hash, MAC and XOF functions no longer use intermediate buffers on
the heap for their inputs and outputs, even when
MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is disabled. Fixes #795.
137 changes: 23 additions & 114 deletions core/psa_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -2266,7 +2266,6 @@ psa_status_t psa_hash_update(psa_hash_operation_t *operation,
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;
Expand All @@ -2279,22 +2278,19 @@ 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);
status = psa_driver_wrapper_hash_update(operation, input_external, input_length);

exit:
if (status != PSA_SUCCESS) {
psa_hash_abort(operation);
}

LOCAL_INPUT_FREE(input_external, input);
return status;
}

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 psa_hash_finish(psa_hash_operation_t *operation,
uint8_t *hash,
size_t hash_size,
size_t *hash_length)
{
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

Expand All @@ -2310,34 +2306,15 @@ static psa_status_t psa_hash_finish_internal(psa_hash_operation_t *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);

#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
exit:
#endif
LOCAL_OUTPUT_FREE(hash_external, hash);
return status;
}

psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
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(hash_external, hash);

status = psa_hash_finish_internal(
status = psa_hash_finish(
operation,
actual_hash, sizeof(actual_hash),
&actual_hash_length);
Expand All @@ -2351,8 +2328,7 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
goto exit;
}

LOCAL_INPUT_ALLOC(hash_external, hash_length, hash);
if (mbedtls_ct_memcmp(hash, actual_hash, actual_hash_length) != 0) {
if (mbedtls_ct_memcmp(hash_external, actual_hash, actual_hash_length) != 0) {
status = PSA_ERROR_INVALID_SIGNATURE;
}

Expand All @@ -2361,7 +2337,6 @@ 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;
}

Expand All @@ -2371,24 +2346,14 @@ psa_status_t psa_hash_compute(psa_algorithm_t alg,
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;
}

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);

#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
exit:
#endif
LOCAL_INPUT_FREE(input_external, input);
LOCAL_OUTPUT_FREE(hash_external, hash);
status = psa_driver_wrapper_hash_compute(alg, input_external, input_length,
hash_external, hash_size, hash_length);
return status;
}

Expand All @@ -2400,17 +2365,13 @@ psa_status_t psa_hash_compare(psa_algorithm_t alg,
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)) {
status = PSA_ERROR_INVALID_ARGUMENT;
return status;
}

LOCAL_INPUT_ALLOC(input_external, input_length, input);
status = psa_driver_wrapper_hash_compute(
alg, input, input_length,
alg, input_external, input_length,
actual_hash, sizeof(actual_hash),
&actual_hash_length);
if (status != PSA_SUCCESS) {
Expand All @@ -2421,17 +2382,12 @@ psa_status_t psa_hash_compare(psa_algorithm_t alg,
goto exit;
}

LOCAL_INPUT_ALLOC(hash_external, hash_length, hash);
if (mbedtls_ct_memcmp(hash, actual_hash, actual_hash_length) != 0) {
if (mbedtls_ct_memcmp(hash_external, 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;
}

Expand Down Expand Up @@ -2578,7 +2534,6 @@ psa_status_t psa_xof_update(psa_xof_operation_t *operation,
}

psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
LOCAL_INPUT_DECLARE(input_external, input);

operation->has_input = 1;

Expand All @@ -2588,17 +2543,11 @@ psa_status_t psa_xof_update(psa_xof_operation_t *operation,
return PSA_SUCCESS;
}

LOCAL_INPUT_ALLOC(input_external, input_length, input);
status = psa_driver_wrapper_xof_update(operation, input, input_length);
// Label otherwise unused when MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is enabled
goto exit;
status = psa_driver_wrapper_xof_update(operation, input_external, input_length);

exit:
if (status != PSA_SUCCESS) {
psa_xof_abort(operation);
}

LOCAL_INPUT_FREE(input_external, input);
return status;
}

Expand All @@ -2617,7 +2566,6 @@ psa_status_t psa_xof_output(psa_xof_operation_t *operation,
}

psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
LOCAL_OUTPUT_DECLARE(output_external, output);

operation->has_output = 1;

Expand All @@ -2627,17 +2575,11 @@ psa_status_t psa_xof_output(psa_xof_operation_t *operation,
return PSA_SUCCESS;
}

LOCAL_OUTPUT_ALLOC(output_external, output_length, output);
status = psa_driver_wrapper_xof_output(operation, output, output_length);
// Label otherwise unused when MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS is enabled
goto exit;
status = psa_driver_wrapper_xof_output(operation, output_external, output_length);

exit:
if (status != PSA_SUCCESS) {
psa_xof_abort(operation);
}

LOCAL_OUTPUT_FREE(output_external, output);
return status;
}

Expand Down Expand Up @@ -2797,7 +2739,6 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation,
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;
Expand All @@ -2811,18 +2752,11 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation,
return status;
}

LOCAL_INPUT_ALLOC(input_external, input_length, input);
status = psa_driver_wrapper_mac_update(operation, input, input_length);
status = psa_driver_wrapper_mac_update(operation, input_external, input_length);

if (status != PSA_SUCCESS) {
psa_mac_abort(operation);
}

#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
exit:
#endif
LOCAL_INPUT_FREE(input_external, input);

return status;
}

Expand All @@ -2833,8 +2767,6 @@ 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;
Expand All @@ -2860,7 +2792,8 @@ psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation,


status = psa_driver_wrapper_mac_sign_finish(operation,
mac, operation->mac_size,
mac_external,
operation->mac_size,
mac_length);

exit:
Expand All @@ -2875,13 +2808,11 @@ psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation,
operation->mac_size = 0;
}

if (mac != NULL) {
psa_wipe_tag_output_buffer(mac, status, mac_size, *mac_length);
if (mac_external != NULL) {
psa_wipe_tag_output_buffer(mac_external, status, mac_size, *mac_length);
}

abort_status = psa_mac_abort(operation);
LOCAL_OUTPUT_FREE(mac_external, mac);

return status == PSA_SUCCESS ? abort_status : status;
}

Expand All @@ -2891,7 +2822,6 @@ psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation,
{
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;
Expand All @@ -2908,13 +2838,11 @@ 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);
mac_external, mac_length);

exit:
abort_status = psa_mac_abort(operation);
LOCAL_INPUT_FREE(mac_external, mac);

return status == PSA_SUCCESS ? abort_status : status;
}
Expand Down Expand Up @@ -2988,21 +2916,9 @@ psa_status_t psa_mac_compute(mbedtls_svc_key_id_t key,
size_t *mac_length)
{
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);

#if !defined(MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS)
exit:
#endif
LOCAL_INPUT_FREE(input_external, input);
LOCAL_OUTPUT_FREE(mac_external, mac);

input_external, input_length,
mac_external, mac_size, mac_length, 1);
return status;
}

Expand All @@ -3016,12 +2932,9 @@ psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key,
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,
input_external, input_length,
actual_mac, sizeof(actual_mac),
&actual_mac_length, 0);
if (status != PSA_SUCCESS) {
Expand All @@ -3033,17 +2946,13 @@ psa_status_t psa_mac_verify(mbedtls_svc_key_id_t key,
goto exit;
}

LOCAL_INPUT_ALLOC(mac_external, mac_length, mac);
if (mbedtls_ct_memcmp(mac, actual_mac, actual_mac_length) != 0) {
if (mbedtls_ct_memcmp(mac_external, actual_mac, actual_mac_length) != 0) {
status = PSA_ERROR_INVALID_SIGNATURE;
goto exit;
}

exit:
mbedtls_platform_zeroize(actual_mac, sizeof(actual_mac));
LOCAL_INPUT_FREE(input_external, input);
LOCAL_INPUT_FREE(mac_external, mac);

return status;
}

Expand Down
2 changes: 1 addition & 1 deletion framework
15 changes: 15 additions & 0 deletions tests/include/test/psa_test_wrappers.h
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,21 @@ psa_status_t mbedtls_test_wrap_psa_purge_key(
#define psa_purge_key(arg0_key) \
mbedtls_test_wrap_psa_purge_key(arg0_key)

psa_status_t mbedtls_test_wrap_psa_random_deplete(void);
#define psa_random_deplete() \
mbedtls_test_wrap_psa_random_deplete()

psa_status_t mbedtls_test_wrap_psa_random_reseed(
const uint8_t *arg0_perso,
size_t arg1_perso_size);
#define psa_random_reseed(arg0_perso, arg1_perso_size) \
mbedtls_test_wrap_psa_random_reseed(arg0_perso, arg1_perso_size)

psa_status_t mbedtls_test_wrap_psa_random_set_prediction_resistance(
unsigned arg0_enabled);
#define psa_random_set_prediction_resistance(arg0_enabled) \
mbedtls_test_wrap_psa_random_set_prediction_resistance(arg0_enabled)

psa_status_t mbedtls_test_wrap_psa_raw_key_agreement(
psa_algorithm_t arg0_alg,
mbedtls_svc_key_id_t arg1_private_key,
Expand Down
Loading