DPE: Reuse command buffer to decrease stack usage
The goal to reuse the cmd_buf allocated in dpe_req_mngr.c
to create the big objects (certificate, certificate_chain)
in place rather then allocate a separate buffer on the stack
and later copy them to cmd_buf.
Change-Id: I337c4111794384588de955f1659426d043d80154
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/partitions/dice_protection_environment/dpe_cmd_decode.c b/partitions/dice_protection_environment/dpe_cmd_decode.c
index 5112063..2ba5cf7 100644
--- a/partitions/dice_protection_environment/dpe_cmd_decode.c
+++ b/partitions/dice_protection_environment/dpe_cmd_decode.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -16,6 +16,27 @@
#include "qcbor/qcbor_decode.h"
#include "qcbor/qcbor_spiffy_decode.h"
+/*
+ * The goal to reuse the cmd_buf allocated in dpe_req_mngr.c to create the
+ * big objects (certificate, certificate_chain) in place rather then allocate
+ * a separate buffer on the stack and later copy them to cmd_buf.
+ *
+ * The temporary buffer is allocated from the end of the cmd_buf. When the
+ * reply is encoded then the content of the temp buf is moved to its final
+ * place in the cmd_buf.
+ *
+ * Overlapping copy is not an issue because QCBOR relies on memmove under the
+ * hood which handles this scenario.
+ *
+ * Note:
+ * Make sure that the beginning of the encoded reply does not overwrite the
+ * data in the temp buf. That is why the temp buff is allocated at the end of
+ * cmd_buf.
+ */
+#define REUSE_CMD_BUF(size) (uint8_t *)encode_ctx->OutBuf.UB.ptr + \
+ encode_ctx->OutBuf.UB.len - \
+ (size)
+
static dpe_error_t decode_dice_inputs(QCBORDecodeContext *decode_ctx,
DiceInputValues *input)
{
@@ -122,7 +143,7 @@
DiceInputValues dice_inputs;
int new_context_handle;
int new_parent_context_handle;
- uint8_t new_certificate_buf[DICE_CERT_SIZE];
+ uint8_t *new_certificate_buf = REUSE_CMD_BUF(DICE_CERT_SIZE);
uint8_t exported_cdi_buf[DICE_MAX_ENCODED_CDI_SIZE];
size_t new_certificate_actual_size = 0;
size_t exported_cdi_actual_size = 0;
@@ -188,7 +209,7 @@
&new_context_handle,
&new_parent_context_handle,
new_certificate_buf,
- sizeof(new_certificate_buf),
+ DICE_CERT_SIZE,
&new_certificate_actual_size,
exported_cdi_buf,
sizeof(exported_cdi_buf),
@@ -287,7 +308,7 @@
size_t public_key_size;
const uint8_t *label;
size_t label_size;
- uint8_t certificate_buf[DICE_CERT_SIZE];
+ uint8_t *certificate_buf = REUSE_CMD_BUF(DICE_CERT_SIZE);
size_t certificate_actual_size;
uint8_t derived_public_key_buf[DPE_ATTEST_PUB_KEY_SIZE];
size_t derived_public_key_actual_size;
@@ -329,7 +350,7 @@
dpe_err = certify_key_request(context_handle, retain_context, public_key,
public_key_size, label, label_size,
certificate_buf,
- sizeof(certificate_buf),
+ DICE_CERT_SIZE,
&certificate_actual_size,
derived_public_key_buf,
sizeof(derived_public_key_buf),
@@ -376,7 +397,7 @@
int context_handle;
bool retain_context;
bool clear_from_context;
- uint8_t certificate_chain_buf[DICE_CERT_CHAIN_SIZE];
+ uint8_t *certificate_chain_buf = REUSE_CMD_BUF(DICE_CERT_CHAIN_SIZE);
size_t certificate_chain_actual_size;
int new_context_handle;
@@ -411,7 +432,7 @@
retain_context,
clear_from_context,
certificate_chain_buf,
- sizeof(certificate_chain_buf),
+ DICE_CERT_CHAIN_SIZE,
&certificate_chain_actual_size,
&new_context_handle);
if (dpe_err != DPE_NO_ERROR) {