mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-03-22 13:20:50 +00:00
Merge pull request #1167 from gabor-mezei-arm/buffer_protection_for_cipher
Buffer protection for cipher functions
This commit is contained in:
commit
714418f2dc
@ -234,6 +234,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 */
|
||||
@ -4389,14 +4391,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;
|
||||
@ -4418,33 +4421,40 @@ psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
status = psa_generate_random_internal(local_iv, default_iv_length);
|
||||
LOCAL_OUTPUT_ALLOC(iv_external, default_iv_length, iv);
|
||||
|
||||
status = psa_generate_random_internal(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) {
|
||||
memcpy(iv, local_iv, default_iv_length);
|
||||
*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;
|
||||
}
|
||||
|
||||
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;
|
||||
@ -4460,6 +4470,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);
|
||||
@ -4470,18 +4482,24 @@ exit:
|
||||
} else {
|
||||
psa_cipher_abort(operation);
|
||||
}
|
||||
|
||||
LOCAL_INPUT_FREE(iv_external, iv);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (operation->id == 0) {
|
||||
status = PSA_ERROR_BAD_STATE;
|
||||
goto exit;
|
||||
@ -4492,6 +4510,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(output_external, output_size, output);
|
||||
|
||||
status = psa_driver_wrapper_cipher_update(operation,
|
||||
input,
|
||||
input_length,
|
||||
@ -4504,16 +4525,21 @@ exit:
|
||||
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);
|
||||
|
||||
if (operation->id == 0) {
|
||||
status = PSA_ERROR_BAD_STATE;
|
||||
goto exit;
|
||||
@ -4524,6 +4550,8 @@ psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
|
||||
goto exit;
|
||||
}
|
||||
|
||||
LOCAL_OUTPUT_ALLOC(output_external, output_size, output);
|
||||
|
||||
status = psa_driver_wrapper_cipher_finish(operation,
|
||||
output,
|
||||
output_size,
|
||||
@ -4531,13 +4559,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)
|
||||
@ -4576,9 +4606,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;
|
||||
@ -4613,6 +4640,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,
|
||||
@ -4642,9 +4672,9 @@ exit:
|
||||
|
||||
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)
|
||||
{
|
||||
@ -4653,6 +4683,9 @@ psa_status_t psa_cipher_decrypt(mbedtls_svc_key_id_t key,
|
||||
psa_key_slot_t *slot = NULL;
|
||||
psa_key_attributes_t attributes;
|
||||
|
||||
LOCAL_INPUT_DECLARE(input_external, input);
|
||||
LOCAL_OUTPUT_DECLARE(output_external, output);
|
||||
|
||||
if (!PSA_ALG_IS_CIPHER(alg)) {
|
||||
status = PSA_ERROR_INVALID_ARGUMENT;
|
||||
goto exit;
|
||||
@ -4678,6 +4711,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,
|
||||
@ -4693,6 +4729,9 @@ exit:
|
||||
*output_length = 0;
|
||||
}
|
||||
|
||||
LOCAL_INPUT_FREE(input_external, input);
|
||||
LOCAL_OUTPUT_FREE(output_external, output);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -532,7 +532,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));
|
||||
|
@ -145,7 +145,9 @@ class PSAWrapperGenerator(c_wrapper_generator.Base):
|
||||
#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',
|
||||
'psa_cipher_generate_iv', 'psa_cipher_set_iv'}:
|
||||
return True
|
||||
if function_name in ('psa_key_derivation_output_bytes',
|
||||
'psa_key_derivation_input_bytes'):
|
||||
|
@ -329,7 +329,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;
|
||||
}
|
||||
|
||||
@ -382,7 +390,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;
|
||||
}
|
||||
|
||||
@ -393,7 +407,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;
|
||||
}
|
||||
|
||||
@ -403,7 +423,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;
|
||||
}
|
||||
|
||||
@ -416,7 +442,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;
|
||||
}
|
||||
|
||||
|
@ -1559,14 +1559,6 @@ void cipher_entry_points(int alg_arg, int key_type_arg,
|
||||
TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits_set_iv, 1);
|
||||
TEST_EQUAL(status, mbedtls_test_driver_cipher_hooks.forced_status_set_iv);
|
||||
mbedtls_test_driver_cipher_hooks.forced_status_set_iv = PSA_SUCCESS;
|
||||
/*
|
||||
* 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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user