| From 43388a8e071980d9146f935f486a859d0a04322b Mon Sep 17 00:00:00 2001 |
| From: Julian Hall <julian.hall@arm.com> |
| Date: Tue, 15 Feb 2022 15:46:58 +0000 |
| Subject: [PATCH] Add IV generation to one-shot cipher operation |
| |
| The functions psa_cipher_encrypt and psa_cipher_decrypt are |
| one-shot operations that can take an arbitrary sized input. |
| These operations are implemented as client-side functions |
| that use multi-part cipher operations to allow large inputs |
| to be handled. The existing implementations were missing the |
| generation and setting of the IV at the start of the data. |
| This was leading to PSA Arch test failures (248 & 249). This |
| commit adds the missing IV handling and resolves the test |
| failures. |
| |
| Signed-off-by: Julian Hall <julian.hall@arm.com> |
| Change-Id: I4afb555ee7062ebb387e5bb27fb1e082288ad8c7 |
| |
| Upstream-Status: Pending [Not submitted to upstream yet] |
| Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com> |
| |
| |
| --- |
| .../service/crypto/client/psa/psa_cipher.c | 40 +++++++++++++++---- |
| 1 file changed, 33 insertions(+), 7 deletions(-) |
| |
| diff --git a/components/service/crypto/client/psa/psa_cipher.c b/components/service/crypto/client/psa/psa_cipher.c |
| index 3ab8ea21..111af829 100644 |
| --- a/components/service/crypto/client/psa/psa_cipher.c |
| +++ b/components/service/crypto/client/psa/psa_cipher.c |
| @@ -8,7 +8,6 @@ |
| #include "psa_crypto_client.h" |
| #include "crypto_caller_selector.h" |
| |
| - |
| psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, |
| psa_key_id_t key, |
| psa_algorithm_t alg) |
| @@ -171,9 +170,16 @@ psa_status_t psa_cipher_encrypt(psa_key_id_t key, |
| |
| if (psa_status == PSA_SUCCESS) { |
| |
| + size_t ciphertext_len = 0; |
| + size_t iv_len = 0; |
| + |
| + psa_cipher_generate_iv(&operation, output, output_size, &iv_len); |
| + |
| psa_status = multi_cipher_update(&operation, |
| input, input_length, |
| - output, output_size, output_length); |
| + &output[iv_len], output_size - iv_len, &ciphertext_len); |
| + |
| + *output_length = iv_len + ciphertext_len; |
| } |
| |
| return psa_status; |
| @@ -187,14 +193,34 @@ psa_status_t psa_cipher_decrypt(psa_key_id_t key, |
| size_t output_size, |
| size_t *output_length) |
| { |
| - psa_cipher_operation_t operation = psa_cipher_operation_init(); |
| - psa_status_t psa_status = psa_cipher_decrypt_setup(&operation, key, alg); |
| + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; |
| + psa_status_t psa_status = psa_get_key_attributes(key, &attributes); |
| |
| if (psa_status == PSA_SUCCESS) { |
| |
| - psa_status = multi_cipher_update(&operation, |
| - input, input_length, |
| - output, output_size, output_length); |
| + psa_cipher_operation_t operation = psa_cipher_operation_init(); |
| + psa_status = psa_cipher_decrypt_setup(&operation, key, alg); |
| + |
| + if (psa_status == PSA_SUCCESS) { |
| + |
| + size_t iv_len = PSA_CIPHER_IV_LENGTH(psa_get_key_type(&attributes), alg); |
| + |
| + if (input_length >= iv_len) { |
| + |
| + psa_cipher_set_iv(&operation, input, iv_len); |
| + |
| + psa_status = multi_cipher_update(&operation, |
| + &input[iv_len], input_length - iv_len, |
| + output, output_size, output_length); |
| + } |
| + else { |
| + |
| + psa_cipher_abort(&operation); |
| + psa_status = PSA_ERROR_INVALID_ARGUMENT; |
| + } |
| + } |
| + |
| + psa_reset_key_attributes(&attributes); |
| } |
| |
| return psa_status; |