DPE: Handle omission of optional parameters
If the optional parameters are not encoded by the client,
initialise them to their default values.
Signed-off-by: Maulik Patel <maulik.patel@arm.com>
Change-Id: I2eedf5ec7d9a0d66e1daaaeaaa0a43aa42c67845
diff --git a/partitions/dice_protection_environment/dpe_cmd_decode.c b/partitions/dice_protection_environment/dpe_cmd_decode.c
index c4f2623..b2381e1 100644
--- a/partitions/dice_protection_environment/dpe_cmd_decode.c
+++ b/partitions/dice_protection_environment/dpe_cmd_decode.c
@@ -16,6 +16,12 @@
#include "qcbor/qcbor_decode.h"
#include "qcbor/qcbor_spiffy_decode.h"
+#define CHECK_CBOR_ERROR(decode_ctx) \
+ qcbor_err = QCBORDecode_GetAndResetError(decode_ctx); \
+ if ((qcbor_err != QCBOR_SUCCESS) && (qcbor_err != QCBOR_ERR_LABEL_NOT_FOUND)) { \
+ return DPE_INVALID_COMMAND; \
+ }
+
/*
* 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
@@ -129,7 +135,6 @@
return DPE_NO_ERROR;
}
-//TODO: Handle the omission of parameters from DPE commands.
static dpe_error_t decode_derive_context(QCBORDecodeContext *decode_ctx,
QCBOREncodeContext *encode_ctx,
int32_t client_id)
@@ -154,6 +159,17 @@
size_t new_certificate_actual_size = 0;
size_t exported_cdi_actual_size = 0;
+ /* Initialise optional parameters with their default value in case
+ * they are not encoded in the input command
+ */
+ cert_id = DPE_CERT_ID_INVALID;
+ retain_parent_context = false;
+ allow_new_context_to_derive = true;
+ create_certificate = true;
+ return_certificate = false;
+ allow_new_context_to_export = false;
+ export_cdi = false;
+
/* Decode DeriveContext command */
QCBORDecode_EnterMap(decode_ctx, NULL);
@@ -167,19 +183,19 @@
QCBORDecode_GetUInt64InMapN(decode_ctx, DPE_DERIVE_CONTEXT_CERT_ID, &cert_id);
/* Check if cert_id was encoded in the received command buffer */
- qcbor_err = QCBORDecode_GetAndResetError(decode_ctx);
- if (qcbor_err != QCBOR_SUCCESS) {
- cert_id = DPE_CERT_ID_INVALID;
- }
+ CHECK_CBOR_ERROR(decode_ctx);
QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DERIVE_CONTEXT_RETAIN_PARENT_CONTEXT,
&retain_parent_context);
+ CHECK_CBOR_ERROR(decode_ctx);
QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_DERIVE,
&allow_new_context_to_derive);
+ CHECK_CBOR_ERROR(decode_ctx);
QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DERIVE_CONTEXT_CREATE_CERTIFICATE,
&create_certificate);
+ CHECK_CBOR_ERROR(decode_ctx);
dpe_err = decode_dice_inputs(decode_ctx, &dice_inputs);
if (dpe_err != DPE_NO_ERROR) {
@@ -195,12 +211,15 @@
QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DERIVE_CONTEXT_RETURN_CERTIFICATE,
&return_certificate);
+ CHECK_CBOR_ERROR(decode_ctx);
QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DERIVE_CONTEXT_ALLOW_NEW_CONTEXT_TO_EXPORT,
&allow_new_context_to_export);
+ CHECK_CBOR_ERROR(decode_ctx);
QCBORDecode_GetBoolInMapN(decode_ctx, DPE_DERIVE_CONTEXT_EXPORT_CDI,
&export_cdi);
+ CHECK_CBOR_ERROR(decode_ctx);
QCBORDecode_ExitMap(decode_ctx);
@@ -318,9 +337,9 @@
dpe_error_t dpe_err;
int context_handle;
bool retain_context;
- const uint8_t *public_key;
+ const uint8_t *public_key = NULL;
size_t public_key_size;
- const uint8_t *label;
+ const uint8_t *label = NULL;
size_t label_size;
uint8_t *certificate_buf = REUSE_CMD_BUF(DICE_CERT_SIZE);
size_t certificate_actual_size;
@@ -328,27 +347,50 @@
size_t derived_public_key_actual_size;
int new_context_handle;
+ /* Initialise optional parameters with their default value in case
+ * they are not encoded in the input command
+ */
+ retain_context = false;
+ public_key_size = 0;
+ label_size = 0;
+
/* Decode CertifyKey command */
QCBORDecode_EnterMap(decode_ctx, NULL);
QCBORDecode_GetByteStringInMapN(decode_ctx, DPE_CERTIFY_KEY_CONTEXT_HANDLE,
&out);
- if (out.len != sizeof(context_handle)) {
+ qcbor_err = QCBORDecode_GetAndResetError(decode_ctx);
+ if ((qcbor_err != QCBOR_SUCCESS) || (out.len != sizeof(context_handle))) {
return DPE_INVALID_COMMAND;
}
memcpy(&context_handle, out.ptr, out.len);
QCBORDecode_GetBoolInMapN(decode_ctx, DPE_CERTIFY_KEY_RETAIN_CONTEXT,
&retain_context);
+ CHECK_CBOR_ERROR(decode_ctx);
QCBORDecode_GetByteStringInMapN(decode_ctx, DPE_CERTIFY_KEY_PUBLIC_KEY,
&out);
- public_key = out.ptr;
- public_key_size = out.len;
+ qcbor_err = QCBORDecode_GetAndResetError(decode_ctx);
+ if (qcbor_err == QCBOR_SUCCESS) {
+ public_key = out.ptr;
+ public_key_size = out.len;
+ } else if (qcbor_err == QCBOR_ERR_LABEL_NOT_FOUND) {
+ /* Do nothing - argument already initialised to default value */
+ } else {
+ return DPE_INVALID_COMMAND;
+ }
QCBORDecode_GetByteStringInMapN(decode_ctx, DPE_CERTIFY_KEY_LABEL, &out);
- label = out.ptr;
- label_size = out.len;
+ qcbor_err = QCBORDecode_GetAndResetError(decode_ctx);
+ if (qcbor_err == QCBOR_SUCCESS) {
+ label = out.ptr;
+ label_size = out.len;
+ } else if (qcbor_err == QCBOR_ERR_LABEL_NOT_FOUND) {
+ /* Do nothing - argument already initialised to default value */
+ } else {
+ return DPE_INVALID_COMMAND;
+ }
QCBORDecode_ExitMap(decode_ctx);
@@ -415,21 +457,30 @@
size_t certificate_chain_actual_size;
int new_context_handle;
+ /* Initialise optional parameters with their default value in case
+ * they are not encoded in the input command
+ */
+ retain_context = false;
+ clear_from_context = false;
+
/* Decode GetCertificateChain command */
QCBORDecode_EnterMap(decode_ctx, NULL);
QCBORDecode_GetByteStringInMapN(decode_ctx, DPE_GET_CERTIFICATE_CHAIN_CONTEXT_HANDLE,
&out);
- if (out.len != sizeof(context_handle)) {
+ qcbor_err = QCBORDecode_GetAndResetError(decode_ctx);
+ if ((qcbor_err != QCBOR_SUCCESS) || (out.len != sizeof(context_handle))) {
return DPE_INVALID_COMMAND;
}
memcpy(&context_handle, out.ptr, out.len);
QCBORDecode_GetBoolInMapN(decode_ctx, DPE_GET_CERTIFICATE_CHAIN_RETAIN_CONTEXT,
&retain_context);
+ CHECK_CBOR_ERROR(decode_ctx);
QCBORDecode_GetBoolInMapN(decode_ctx, DPE_GET_CERTIFICATE_CHAIN_CLEAR_FROM_CONTEXT,
&clear_from_context);
+ CHECK_CBOR_ERROR(decode_ctx);
QCBORDecode_ExitMap(decode_ctx);