aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hu <david.hu@arm.com>2020-01-26 21:34:20 +0800
committerDavid Hu <david.hu@arm.com>2020-06-22 02:33:00 +0000
commitaa342d5b4b70703cf9ad5f72752caa757f322ea3 (patch)
treea4d6be1720a4868816635fa600cb9068c63bdc4a
parent724a12d1627b74527508fb3812302e77630bf424 (diff)
downloadtrusted-firmware-m-aa342d5b4b70703cf9ad5f72752caa757f322ea3.tar.gz
COSE: Add verification routine of COSE_Mac0
Add verification routine of COSE_Mac0 message structure in t_cose. Move the definitions of structure t_cose_parameters and some flags from t_cose_sign1_verify.h to t_cose_common.h. Thus COSE_Mac0 verification can share those definitions. Also add HMAC verification functions to verify the tag in COSE_Mac0. Change-Id: Icfb69342f183739852ccff101c6fbf8d00395d85 Signed-off-by: David Hu <david.hu@arm.com>
-rw-r--r--lib/ext/t_cose/CMakeLists.txt10
-rw-r--r--lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c60
-rw-r--r--lib/ext/t_cose/inc/t_cose_common.h78
-rw-r--r--lib/ext/t_cose/inc/t_cose_mac0_verify.h116
-rw-r--r--lib/ext/t_cose/inc/t_cose_sign1_verify.h82
-rw-r--r--lib/ext/t_cose/src/t_cose_crypto.h40
-rw-r--r--lib/ext/t_cose/src/t_cose_mac0_verify.c185
-rw-r--r--lib/ext/t_cose/src/t_cose_parameters.h9
8 files changed, 492 insertions, 88 deletions
diff --git a/lib/ext/t_cose/CMakeLists.txt b/lib/ext/t_cose/CMakeLists.txt
index 3bf3edf88..7b8c560f8 100644
--- a/lib/ext/t_cose/CMakeLists.txt
+++ b/lib/ext/t_cose/CMakeLists.txt
@@ -46,13 +46,13 @@ endif()
list(APPEND ALL_SRC_C_VERIFY
"${T_COSE_DIR}/src/t_cose_util.c"
"${T_COSE_DIR}/src/t_cose_parameters.c"
+ "${T_COSE_DIR}/crypto_adapters/t_cose_psa_crypto.c"
)
-if (NOT SYMMETRIC_INITIAL_ATTESTATION)
- list(APPEND ALL_SRC_C_VERIFY
- "${T_COSE_DIR}/src/t_cose_sign1_verify.c"
- "${T_COSE_DIR}/crypto_adapters/t_cose_psa_crypto.c"
- )
+if (SYMMETRIC_INITIAL_ATTESTATION)
+ list(APPEND ALL_SRC_C_VERIFY "${T_COSE_DIR}/src/t_cose_mac0_verify.c")
+else()
+ list(APPEND ALL_SRC_C_VERIFY "${T_COSE_DIR}/src/t_cose_sign1_verify.c")
endif()
if (ENABLE_T_COSE_TESTS)
diff --git a/lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c b/lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c
index c6e8749db..f6036f9cf 100644
--- a/lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c
+++ b/lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c
@@ -451,6 +451,7 @@ psa_status_to_t_cose_error_hmac(psa_status_t status)
status == PSA_ERROR_INVALID_ARGUMENT ? T_COSE_ERR_INVALID_ARGUMENT :
status == PSA_ERROR_INSUFFICIENT_MEMORY ? T_COSE_ERR_INSUFFICIENT_MEMORY :
status == PSA_ERROR_BUFFER_TOO_SMALL ? T_COSE_ERR_TOO_SMALL :
+ status == PSA_ERROR_INVALID_SIGNATURE ? T_COSE_ERR_SIG_VERIFY :
T_COSE_ERR_FAIL;
}
@@ -537,4 +538,63 @@ t_cose_crypto_hmac_sign_finish(struct t_cose_crypto_hmac *hmac_ctx,
return psa_status_to_t_cose_error_hmac(psa_ret);
}
+
+/*
+ * See documentation in t_cose_crypto.h
+ */
+enum t_cose_err_t
+t_cose_crypto_hmac_verify_setup(struct t_cose_crypto_hmac *hmac_ctx,
+ const int cose_alg_id,
+ struct t_cose_key verify_key)
+{
+ psa_algorithm_t psa_alg;
+ psa_status_t psa_ret;
+
+ if(!hmac_ctx) {
+ return T_COSE_ERR_INVALID_ARGUMENT;
+ }
+
+ /* Map the algorithm ID */
+ psa_alg = cose_hmac_alg_id_to_psa(cose_alg_id);
+ if(!PSA_ALG_IS_MAC(psa_alg)) {
+ return T_COSE_ERR_UNSUPPORTED_SIGNING_ALG;
+ }
+
+ /*
+ * Verify if HMAC algorithm is valid.
+ * According to COSE (RFC 8152), only SHA-256, SHA-384 and SHA-512 are
+ * supported in HMAC.
+ */
+ if((psa_alg != PSA_ALG_HMAC(PSA_ALG_SHA_256)) && \
+ (psa_alg != PSA_ALG_HMAC(PSA_ALG_SHA_384)) && \
+ (psa_alg != PSA_ALG_HMAC(PSA_ALG_SHA_512))) {
+ return T_COSE_ERR_UNSUPPORTED_SIGNING_ALG;
+ }
+
+ hmac_ctx->op_ctx = psa_mac_operation_init();
+
+ psa_ret = psa_mac_verify_setup(&hmac_ctx->op_ctx,
+ (psa_key_handle_t)verify_key.k.key_handle,
+ psa_alg);
+
+ return psa_status_to_t_cose_error_hmac(psa_ret);
+}
+
+/*
+ * See documentation in t_cose_crypto.h
+ */
+enum t_cose_err_t
+t_cose_crypto_hmac_verify_finish(struct t_cose_crypto_hmac *hmac_ctx,
+ struct q_useful_buf_c tag)
+{
+ psa_status_t psa_ret;
+
+ if(!hmac_ctx) {
+ return T_COSE_ERR_INVALID_ARGUMENT;
+ }
+
+ psa_ret = psa_mac_verify_finish(&hmac_ctx->op_ctx, tag.ptr, tag.len);
+
+ return psa_status_to_t_cose_error_hmac(psa_ret);
+}
#endif /* !T_COSE_DISABLE_MAC0 */
diff --git a/lib/ext/t_cose/inc/t_cose_common.h b/lib/ext/t_cose/inc/t_cose_common.h
index 0481ac7e1..c6f2ec6b2 100644
--- a/lib/ext/t_cose/inc/t_cose_common.h
+++ b/lib/ext/t_cose/inc/t_cose_common.h
@@ -14,6 +14,7 @@
#define __T_COSE_COMMON_H__
#include <stdint.h>
+#include "q_useful_buf.h"
#ifdef __cplusplus
extern "C" {
@@ -364,6 +365,12 @@ enum t_cose_err_t {
/** Something is wrong with the crit parameter. */
T_COSE_ERR_CRIT_PARAMETER = 36,
+ /**
+ * When verifying a \c COSE_Mac0, something is wrong with the
+ * format of the CBOR. For example, it is missing something like
+ * the payload.
+ */
+ T_COSE_ERR_MAC0_FORMAT = 37,
};
@@ -393,6 +400,41 @@ enum t_cose_err_t {
*/
#define T_COSE_EMPTY_UINT_CONTENT_TYPE UINT16_MAX+1
+/**
+ * The result of parsing a set of COSE header parameters. The pointers
+ * are all back into the COSE structure blob passed in.
+ *
+ * Approximate size on a 64-bit machine is 80 bytes and on a 32-bit
+ * machine is 40.
+ */
+struct t_cose_parameters {
+ /** The algorithm ID. \ref T_COSE_UNSET_ALGORITHM_ID if the algorithm ID
+ * parameter is not present. String type algorithm IDs are not
+ * supported. See the
+ * [IANA COSE Registry](https://www.iana.org/assignments/cose/cose.xhtml)
+ * for the algorithms corresponding to the integer values.
+ */
+ int32_t cose_algorithm_id;
+ /** The COSE key ID. \c NULL_Q_USEFUL_BUF_C if parameter is not
+ * present */
+ struct q_useful_buf_c kid;
+ /** The initialization vector. \c NULL_Q_USEFUL_BUF_C if parameter
+ * is not present */
+ struct q_useful_buf_c iv;
+ /** The partial initialization vector. \c NULL_Q_USEFUL_BUF_C if
+ * parameter is not present */
+ struct q_useful_buf_c partial_iv;
+ /** The content type as a MIME type like
+ * "text/plain". \c NULL_Q_USEFUL_BUF_C if parameter is not present */
+#ifndef T_COSE_DISABLE_CONTENT_TYPE
+ struct q_useful_buf_c content_type_tstr;
+ /** The content type as a CoAP Content-Format
+ * integer. \ref T_COSE_EMPTY_UINT_CONTENT_TYPE if parameter is not
+ * present. Allowed range is 0 to UINT16_MAX per RFC 7252. */
+ uint32_t content_type_uint;
+#endif /* T_COSE_DISABLE_CONTENT_TYPE */
+};
+
@@ -409,6 +451,42 @@ enum t_cose_err_t {
#define T_COSE_OPT_OMIT_CBOR_TAG 0x00000002
+/**
+ * The error \ref T_COSE_ERR_NO_KID is returned if the kid parameter
+ * is missing. Note that the kid parameter is primarily passed on to
+ * the crypto layer so the crypto layer can look up the key. If the
+ * verification key is determined by other than the kid, then it is
+ * fine if there is no kid.
+ */
+#define T_COSE_OPT_REQUIRE_KID 0x00000002
+
+
+/**
+ * Normally this will decode the CBOR presented as a \c COSE_Sign1
+ * or a \c COSE_Mac0 message whether it is tagged using QCBOR tagging
+ * as such or not.
+ * If this option is set, then \ref T_COSE_ERR_INCORRECTLY_TAGGED is
+ * returned if it is not tagged.
+ */
+#define T_COSE_OPT_TAG_REQUIRED 0x00000004
+
+
+/**
+ * This option disables cryptographic signature verification. With
+ * this option the \c verification_key is not needed. This is useful
+ * to decode the a COSE message to get the kid (key ID). The
+ * verification key can be looked up or otherwise obtained by the
+ * caller. Once the key in in hand, the verification function can be
+ * called again to perform the full verification.
+ *
+ * The payload will always be returned whether this is option is given
+ * or not, but it should not be considered secure when this option is
+ * given.
+ *
+ */
+#define T_COSE_OPT_DECODE_ONLY 0x00000008
+
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/ext/t_cose/inc/t_cose_mac0_verify.h b/lib/ext/t_cose/inc/t_cose_mac0_verify.h
new file mode 100644
index 000000000..1b7c039a1
--- /dev/null
+++ b/lib/ext/t_cose/inc/t_cose_mac0_verify.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2019, Laurence Lundblade. All rights reserved.
+ * Copyright (c) 2020 Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __T_COSE_MAC0_VERIFY_H_
+#define __T_COSE_MAC0_VERIFY_H_
+
+#include <stdint.h>
+#include "qcbor.h"
+#include "t_cose_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Context for tag verification. It is about 24 bytes on a
+ * 64-bit machine and 12 bytes on a 32-bit machine.
+ */
+struct t_cose_mac0_verify_ctx {
+ /* Private data structure */
+ struct t_cose_key verification_key;
+ int32_t option_flags;
+};
+
+
+/**
+ * \brief Initialize for \c COSE_Mac0 message verification.
+ *
+ * \param[in,out] context The context to initialize.
+ * \param[in] option_flags Options controlling the verification.
+ *
+ * This must be called before using the verification context.
+ */
+static void
+t_cose_mac0_verify_init(struct t_cose_mac0_verify_ctx *context,
+ int32_t option_flags);
+
+
+/**
+ * \brief Set key for \c COSE_Mac0 message verification.
+ *
+ * \param[in,out] context The context of COSE_Mac0 verification
+ * \param[in] verify_key The verification key to use.
+ *
+ * Look up by kid parameter and fetch the key for MAC verification.
+ * Setup the \ref verify_key structure and fill it in \ref context.
+ */
+static void
+t_cose_mac0_set_verify_key(struct t_cose_mac0_verify_ctx *context,
+ struct t_cose_key verify_key);
+
+/**
+ * \brief Verify a COSE_Mac0
+ *
+ * \param[in] context The context of COSE_Mac0 verification
+ * \param[in] cose_mac0 Pointer and length of CBOR encoded \c COSE_Mac0
+ * that is to be verified.
+ * \param[out] payload Pointer and length of the still CBOR encoded
+ * payload
+ *
+ * \return This returns one of the error codes defined by \ref t_cose_err_t.
+ *
+ * Verification involves the following steps.
+ *
+ * The CBOR structure is parsed and verified. It makes sure \c COSE_Mac0
+ * is valid CBOR and that it is tagged as a \c COSE_Mac0.
+ *
+ * The signing algorithm is pulled out of the protected headers.
+ *
+ * The kid (key ID) is parsed out of the unprotected headers if it exists.
+ *
+ * The payload is identified. It doesn't have to be parsed in detail
+ * because it is wrapped in a bstr.
+ *
+ * Finally, the MAC verification is performed if \ref T_COSE_OPT_DECODE_ONLY
+ * is not set in option flag. Otherwise, the verification will be skipped.
+ * The MAC algorithm to use comes from the signing algorithm in the
+ * protected headers.
+ * If the algorithm is not known or not supported this will error out.
+ *
+ * If it is successful, the pointer of the CBOR-encoded payload is
+ * returned.
+ */
+enum t_cose_err_t t_cose_mac0_verify(struct t_cose_mac0_verify_ctx *context,
+ struct q_useful_buf_c cose_mac0,
+ struct q_useful_buf_c *payload,
+ struct t_cose_parameters *parameters);
+
+/* ------------------------------------------------------------------------
+ * Inline implementations of public functions defined above.
+ */
+static inline void
+t_cose_mac0_verify_init(struct t_cose_mac0_verify_ctx *context,
+ int32_t option_flags)
+{
+ context->option_flags = option_flags;
+ context->verification_key = T_COSE_NULL_KEY;
+}
+
+static inline void
+t_cose_mac0_set_verify_key(struct t_cose_mac0_verify_ctx *context,
+ struct t_cose_key verify_key)
+{
+ context->verification_key = verify_key;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __T_COSE_MAC0_VERIFY_H_ */
diff --git a/lib/ext/t_cose/inc/t_cose_sign1_verify.h b/lib/ext/t_cose/inc/t_cose_sign1_verify.h
index 11555d7ea..48ac7c919 100644
--- a/lib/ext/t_cose/inc/t_cose_sign1_verify.h
+++ b/lib/ext/t_cose/inc/t_cose_sign1_verify.h
@@ -52,51 +52,6 @@ extern "C" {
/**
- * The result of parsing a set of COSE header parameters. The pointers
- * are all back into the \c COSE_Sign1 blob passed in.
- *
- * Approximate size on a 64-bit machine is 80 bytes and on a 32-bit
- * machine is 40.
- */
-struct t_cose_parameters {
- /** The algorithm ID. \ref T_COSE_UNSET_ALGORITHM_ID if the algorithm ID
- * parameter is not present. String type algorithm IDs are not
- * supported. See the
- * [IANA COSE Registry](https://www.iana.org/assignments/cose/cose.xhtml)
- * for the algorithms corresponding to the integer values.
- */
- int32_t cose_algorithm_id;
- /** The COSE key ID. \c NULL_Q_USEFUL_BUF_C if parameter is not
- * present */
- struct q_useful_buf_c kid;
- /** The initialization vector. \c NULL_Q_USEFUL_BUF_C if parameter
- * is not present */
- struct q_useful_buf_c iv;
- /** The partial initialization vector. \c NULL_Q_USEFUL_BUF_C if
- * parameter is not present */
- struct q_useful_buf_c partial_iv;
- /** The content type as a MIME type like
- * "text/plain". \c NULL_Q_USEFUL_BUF_C if parameter is not present */
-#ifndef T_COSE_DISABLE_CONTENT_TYPE
- struct q_useful_buf_c content_type_tstr;
- /** The content type as a CoAP Content-Format
- * integer. \ref T_COSE_EMPTY_UINT_CONTENT_TYPE if parameter is not
- * present. Allowed range is 0 to UINT16_MAX per RFC 7252. */
- uint32_t content_type_uint;
-#endif /* T_COSE_DISABLE_CONTENT_TYPE */
-};
-
-
-/**
- * A special COSE algorithm ID that indicates no COSE algorithm ID or an unset
- * COSE algorithm ID.
- */
-#define T_COSE_UNSET_ALGORITHM_ID 0
-
-
-
-
-/**
* Pass this as \c option_flags to allow verification of short-circuit
* signatures. This should only be used as a test mode as
* short-circuit signatures are not secure.
@@ -106,43 +61,6 @@ struct t_cose_parameters {
#define T_COSE_OPT_ALLOW_SHORT_CIRCUIT 0x00000001
-/**
- * The error \ref T_COSE_ERR_NO_KID is returned if the kid parameter
- * is missing. Note that the kid parameter is primarily passed on to
- * the crypto layer so the crypto layer can look up the key. If the
- * verification key is determined by other than the kid, then it is
- * fine if there is no kid.
- */
-#define T_COSE_OPT_REQUIRE_KID 0x00000002
-
-
-/**
- * Normally this will decode the CBOR presented as a \c COSE_Sign1
- * message whether it is tagged using QCBOR tagging as such or not.
- * If this option is set, then \ref T_COSE_ERR_INCORRECTLY_TAGGED is
- * returned if it is not tagged.
- */
-#define T_COSE_OPT_TAG_REQUIRED 0x00000004
-
-
-/**
- * See t_cose_sign1_set_verification_key().
- *
- * This option disables cryptographic signature verification. With
- * this option the \c verification_key is not needed. This is useful
- * to decode the \c COSE_Sign1 message to get the kid (key ID). The
- * verification key can be looked up or otherwise obtained by the
- * caller. Once the key in in hand, t_cose_sign1_verify() can be
- * called again to perform the full verification.
- *
- * The payload will always be returned whether this is option is given
- * or not, but it should not be considered secure when this option is
- * given.
- *
- */
-#define T_COSE_OPT_DECODE_ONLY 0x00000008
-
-
/**
* Context for signature verification. It is about 24 bytes on a
diff --git a/lib/ext/t_cose/src/t_cose_crypto.h b/lib/ext/t_cose/src/t_cose_crypto.h
index 80263a90b..8c98c4896 100644
--- a/lib/ext/t_cose/src/t_cose_crypto.h
+++ b/lib/ext/t_cose/src/t_cose_crypto.h
@@ -604,6 +604,46 @@ t_cose_crypto_hmac_sign_finish(struct t_cose_crypto_hmac *hmac_ctx,
struct q_useful_buf_c *tag);
/**
+ * \brief Set up a multipart HMAC verification operation
+ *
+ * \param[in,out] hmac_ctx Pointer to the HMAC context.
+ * \param[in] cose_alg_id The algorithm used in HMAC.
+ * \param[in] verify_key Key for HMAC verification
+ *
+ * \retval T_COSE_SUCCESS
+ * Operation succeeds.
+ * \retval T_COSE_ERR_UNSUPPORTED_SIGNING_ALG
+ * The algorithm is unsupported.
+ * \retval T_COSE_ERR_INVALID_ARGUMENT
+ * Invalid arguments.
+ * \retval T_COSE_ERR_FAIL
+ * Some general failure of the HMAC function.
+ */
+enum t_cose_err_t
+t_cose_crypto_hmac_verify_setup(struct t_cose_crypto_hmac *hmac_ctx,
+ const int cose_alg_id,
+ struct t_cose_key verify_key);
+
+/**
+ * \brief Finish the verification of the HMAC of a message.
+ *
+ * \param[in,out] hmac_ctx Pointer to the HMAC context.
+ * \param[in] tag Pointer and length of the tag.
+ *
+ * \retval T_COSE_SUCCESS
+ * Tag calculation succeeds.
+ * \retval T_COSE_ERR_INVALID_ARGUMENT
+ * Invalid arguments.
+ * \retval T_COSE_ERR_FAIL
+ * Some general failure of the HMAC function.
+ * \retval PSA_ERROR_INVALID_SIGNATURE
+ * HMAC verification failed.
+ */
+enum t_cose_err_t
+t_cose_crypto_hmac_verify_finish(struct t_cose_crypto_hmac *hmac_ctx,
+ struct q_useful_buf_c tag);
+
+/**
* \brief Indicate whether a COSE algorithm is ECDSA or not.
*
* \param[in] cose_algorithm_id The algorithm ID to check.
diff --git a/lib/ext/t_cose/src/t_cose_mac0_verify.c b/lib/ext/t_cose/src/t_cose_mac0_verify.c
new file mode 100644
index 000000000..ce47bb60c
--- /dev/null
+++ b/lib/ext/t_cose/src/t_cose_mac0_verify.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2018-2019, Laurence Lundblade. All rights reserved.
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * See BSD-3-Clause license in README.md
+ */
+
+#include "qcbor.h"
+#include "t_cose_crypto.h"
+#include "t_cose_mac0_verify.h"
+#include "t_cose_parameters.h"
+#include "t_cose_util.h"
+
+/**
+ * \file t_cose_mac0_verify.c
+ *
+ * \brief This verifies t_cose Mac authentication structure without a recipient
+ * structure.
+ * Only HMAC is supported so far.
+ */
+
+/*
+ * Public function. See t_cose_mac0.h
+ */
+enum t_cose_err_t t_cose_mac0_verify(struct t_cose_mac0_verify_ctx *context,
+ struct q_useful_buf_c cose_mac0,
+ struct q_useful_buf_c *payload,
+ struct t_cose_parameters *parameters)
+{
+ QCBORDecodeContext decode_context;
+ QCBORItem item;
+ struct q_useful_buf_c protected_parameters;
+ struct t_cose_parameters parsed_protected_parameters;
+ struct t_cose_parameters unprotected_parameters;
+ struct t_cose_label_list critical_labels;
+ struct t_cose_label_list unknown_labels;
+ enum t_cose_err_t return_value;
+ struct q_useful_buf_c tag;
+ struct q_useful_buf_c tbm_first_part;
+ /* Buffer for the ToBeMaced */
+ Q_USEFUL_BUF_MAKE_STACK_UB( tbm_first_part_buf,
+ T_COSE_SIZE_OF_TBM);
+ struct t_cose_crypto_hmac hmac_ctx;
+
+ *payload = NULL_Q_USEFUL_BUF_C;
+
+ QCBORDecode_Init(&decode_context, cose_mac0, QCBOR_DECODE_MODE_NORMAL);
+ /* Calls to QCBORDecode_GetNext() rely on item.uDataType != QCBOR_TYPE_ARRAY
+ * to detect decoding errors rather than checking the return code.
+ */
+
+ /* -- The array of four -- */
+ (void)QCBORDecode_GetNext(&decode_context, &item);
+ if(item.uDataType != QCBOR_TYPE_ARRAY) {
+ return_value = T_COSE_ERR_MAC0_FORMAT;
+ goto Done;
+ }
+
+ if((context->option_flags & T_COSE_OPT_TAG_REQUIRED) &&
+ !QCBORDecode_IsTagged(&decode_context, &item, CBOR_TAG_COSE_MAC0)) {
+ return_value = T_COSE_ERR_INCORRECTLY_TAGGED;
+ goto Done;
+ }
+
+ /* -- Clear list where unknown labels are accumulated -- */
+ clear_label_list(&unknown_labels);
+
+ /* -- Get the protected header parameters -- */
+ (void)QCBORDecode_GetNext(&decode_context, &item);
+ if(item.uDataType != QCBOR_TYPE_BYTE_STRING) {
+ return_value = T_COSE_ERR_MAC0_FORMAT;
+ goto Done;
+ }
+
+ protected_parameters = item.val.string;
+
+ return_value = parse_protected_header_parameters(protected_parameters,
+ &parsed_protected_parameters,
+ &critical_labels,
+ &unknown_labels);
+ if(return_value != T_COSE_SUCCESS) {
+ goto Done;
+ }
+
+ /* -- Get the unprotected parameters -- */
+ return_value = parse_unprotected_header_parameters(&decode_context,
+ &unprotected_parameters,
+ &unknown_labels);
+ if(return_value != T_COSE_SUCCESS) {
+ goto Done;
+ }
+ if((context->option_flags & T_COSE_OPT_REQUIRE_KID) &&
+ q_useful_buf_c_is_null(unprotected_parameters.kid)) {
+ return_value = T_COSE_ERR_NO_KID;
+ goto Done;
+ }
+
+ /* -- Check critical parameter labels -- */
+ return_value = check_critical_labels(&critical_labels, &unknown_labels);
+ if(return_value != T_COSE_SUCCESS) {
+ goto Done;
+ }
+
+ /* -- Check for duplicate parameters and copy to returned parameters -- */
+ return_value = check_and_copy_parameters(&parsed_protected_parameters,
+ &unprotected_parameters,
+ parameters);
+ if(return_value != T_COSE_SUCCESS) {
+ goto Done;
+ }
+
+ /* -- Get the payload -- */
+ QCBORDecode_GetNext(&decode_context, &item);
+ if(item.uDataType != QCBOR_TYPE_BYTE_STRING) {
+ return_value = T_COSE_ERR_MAC0_FORMAT;
+ goto Done;
+ }
+ *payload = item.val.string;
+
+ /* -- Get the tag -- */
+ QCBORDecode_GetNext(&decode_context, &item);
+ if(item.uDataType != QCBOR_TYPE_BYTE_STRING) {
+ return_value = T_COSE_ERR_MAC0_FORMAT;
+ goto Done;
+ }
+ tag = item.val.string;
+
+ /* -- Finish up the CBOR decode -- */
+ /* This check make sure the array only had the expected four
+ * items. Works for definite and indefinite length arrays. Also
+ * make sure there were no extra bytes.
+ */
+ if(QCBORDecode_Finish(&decode_context) != QCBOR_SUCCESS) {
+ return_value = T_COSE_ERR_CBOR_NOT_WELL_FORMED;
+ goto Done;
+ }
+
+ /* -- Skip tag verification if such is requested --*/
+ if(context->option_flags & T_COSE_OPT_DECODE_ONLY) {
+ return_value = T_COSE_SUCCESS;
+ goto Done;
+ }
+
+ /* -- Compute the ToBeMaced -- */
+ return_value = create_tbm(tbm_first_part_buf,
+ protected_parameters,
+ &tbm_first_part,
+ T_COSE_TBM_BARE_PAYLOAD,
+ *payload);
+ if(return_value) {
+ goto Done;
+ }
+
+ /*
+ * Start the HMAC verification.
+ * Calculate the tag of the first part of ToBeMaced and the wrapped
+ * payload, to save a bigger buffer containing the entire ToBeMaced.
+ */
+ return_value = t_cose_crypto_hmac_verify_setup(&hmac_ctx,
+ parsed_protected_parameters.cose_algorithm_id,
+ context->verification_key);
+ if(return_value) {
+ goto Done;
+ }
+
+ /* Compute the tag of the first part. */
+ return_value = t_cose_crypto_hmac_update(&hmac_ctx,
+ q_useful_buf_head(tbm_first_part,
+ tbm_first_part.len));
+ if(return_value) {
+ goto Done;
+ }
+
+ return_value = t_cose_crypto_hmac_update(&hmac_ctx, *payload);
+ if(return_value) {
+ goto Done;
+ }
+
+ return_value = t_cose_crypto_hmac_verify_finish(&hmac_ctx, tag);
+
+Done:
+ return return_value;
+}
diff --git a/lib/ext/t_cose/src/t_cose_parameters.h b/lib/ext/t_cose/src/t_cose_parameters.h
index 8a17cd28a..b51e8611b 100644
--- a/lib/ext/t_cose/src/t_cose_parameters.h
+++ b/lib/ext/t_cose/src/t_cose_parameters.h
@@ -2,6 +2,7 @@
* t_cose_parameters.h
*
* Copyright 2019, Laurence Lundblade
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -12,7 +13,6 @@
#ifndef t_cose_parameters_h
#define t_cose_parameters_h
-#include "t_cose_sign1_verify.h"
#include "q_useful_buf.h"
#include "t_cose_common.h"
#include <stdint.h>
@@ -58,6 +58,13 @@ struct t_cose_label_list {
/**
+ * A special COSE algorithm ID that indicates no COSE algorithm ID or an unset
+ * COSE algorithm ID.
+ */
+#define T_COSE_UNSET_ALGORITHM_ID 0
+
+
+/**
* \brief Clear a label list to empty.
*
* \param[in,out] list The list to clear.