blob: 0c93a26c6e7bd92b6eb75e056f7dca43b1da7b52 [file] [log] [blame]
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;