From 74a07ccbb4eb573269672a0c1f61b9165a592b44 Mon Sep 17 00:00:00 2001
From: Satish Kumar <satish.kumar01@arm.com>
Date: Mon, 14 Feb 2022 08:22:25 +0000
Subject: [PATCH 02/12] Fix in AEAD for psa-arch test 254

PSA crypto test 254 fails at checkpoint 6.
Fix output arguments in various crypto AEAD functions
to match crypto service implementation in TF-M. AEAD API's
in TF-M start expecting output size as an argument.

Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TS/trusted-services/+/31176]
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
Signed-off-by: Satish Kumar <satish.kumar01@arm.com>
Signed-off-by: Rui Miguel Silva <rui.silva@linaro.org>
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
 .../crypto/client/caller/packed-c/crypto_caller_aead.h |  1 +
 components/service/crypto/include/psa/crypto_sizes.h   |  2 +-
 .../crypto/provider/extension/aead/aead_provider.c     | 10 ++++++++--
 .../aead/serializer/aead_provider_serializer.h         |  1 +
 .../packed-c/packedc_aead_provider_serializer.c        |  2 ++
 protocols/service/crypto/packed-c/aead.h               |  1 +
 6 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
index 417189e87..236d3e258 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
@@ -314,6 +314,7 @@ static inline psa_status_t crypto_caller_aead_update(struct service_client *cont
 	size_t req_len = req_fixed_len;
 
 	*output_length = 0;
+        req_msg.output_size = output_size;
 	req_msg.op_handle = op_handle;
 
 	/* Mandatory input data parameter */
diff --git a/components/service/crypto/include/psa/crypto_sizes.h b/components/service/crypto/include/psa/crypto_sizes.h
index 30aa102da..130d27295 100644
--- a/components/service/crypto/include/psa/crypto_sizes.h
+++ b/components/service/crypto/include/psa/crypto_sizes.h
@@ -351,7 +351,7 @@
  *       just the largest size that may be generated by
  *       #psa_aead_generate_nonce().
  */
-#define PSA_AEAD_NONCE_MAX_SIZE 12
+#define PSA_AEAD_NONCE_MAX_SIZE 16
 
 /** A sufficient output buffer size for psa_aead_update().
  *
diff --git a/components/service/crypto/provider/extension/aead/aead_provider.c b/components/service/crypto/provider/extension/aead/aead_provider.c
index b73d88d32..510cffa34 100644
--- a/components/service/crypto/provider/extension/aead/aead_provider.c
+++ b/components/service/crypto/provider/extension/aead/aead_provider.c
@@ -283,10 +283,11 @@ static rpc_status_t aead_update_handler(void *context, struct rpc_request *req)
 	uint32_t op_handle;
 	const uint8_t *input;
 	size_t input_len;
+        uint32_t recv_output_size;
 
 	if (serializer)
 		rpc_status = serializer->deserialize_aead_update_req(req_buf, &op_handle,
-			&input, &input_len);
+			&recv_output_size, &input, &input_len);
 
 	if (rpc_status == RPC_SUCCESS) {
 
@@ -300,9 +301,14 @@ static rpc_status_t aead_update_handler(void *context, struct rpc_request *req)
 		if (crypto_context) {
 
 			size_t output_len = 0;
-			size_t output_size = PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(input_len);
+			size_t output_size = PSA_AEAD_UPDATE_OUTPUT_MAX_SIZE(24);
+			/* Always allocate maximum size to be more robust to implementations of psa_aead_update() */
 			uint8_t *output = malloc(output_size);
 
+                        if (recv_output_size < output_size) {
+                            output_size = recv_output_size;
+                        }
+
 			if (output) {
 
 				psa_status = psa_aead_update(&crypto_context->op.aead,
diff --git a/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h b/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h
index be76d2bc6..590973048 100644
--- a/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h
+++ b/components/service/crypto/provider/extension/aead/serializer/aead_provider_serializer.h
@@ -51,6 +51,7 @@ struct aead_provider_serializer {
 	/* Operation: aead_update */
 	rpc_status_t (*deserialize_aead_update_req)(const struct rpc_buffer *req_buf,
 		uint32_t *op_handle,
+                uint32_t *output_size,
 		const uint8_t **input, size_t *input_len);
 
 	rpc_status_t (*serialize_aead_update_resp)(struct rpc_buffer *resp_buf,
diff --git a/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c b/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c
index 8f8c3c7f2..922a7b651 100644
--- a/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c
+++ b/components/service/crypto/provider/extension/aead/serializer/packed-c/packedc_aead_provider_serializer.c
@@ -192,6 +192,7 @@ static rpc_status_t deserialize_aead_update_ad_req(const struct rpc_buffer *req_
 /* Operation: aead_update */
 static rpc_status_t deserialize_aead_update_req(const struct rpc_buffer *req_buf,
 	uint32_t *op_handle,
+        uint32_t *output_size,
 	const uint8_t **input, size_t *input_len)
 {
 	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
@@ -208,6 +209,7 @@ static rpc_status_t deserialize_aead_update_req(const struct rpc_buffer *req_buf
 		memcpy(&recv_msg, req_buf->data, expected_fixed_len);
 
 		*op_handle = recv_msg.op_handle;
+                *output_size = recv_msg.output_size;
 
 		tlv_const_iterator_begin(&req_iter,
 			(uint8_t*)req_buf->data + expected_fixed_len,
diff --git a/protocols/service/crypto/packed-c/aead.h b/protocols/service/crypto/packed-c/aead.h
index 0be266b52..435fd3b52 100644
--- a/protocols/service/crypto/packed-c/aead.h
+++ b/protocols/service/crypto/packed-c/aead.h
@@ -98,6 +98,7 @@ enum
 struct __attribute__ ((__packed__)) ts_crypto_aead_update_in
 {
   uint32_t op_handle;
+  uint32_t output_size;
 };
 
 /* Variable length input parameter tags */
-- 
2.25.1

