diff options
-rw-r--r-- | lib/ext/t_cose/CMakeLists.txt | 10 | ||||
-rw-r--r-- | lib/ext/t_cose/crypto_adapters/t_cose_psa_crypto.c | 60 | ||||
-rw-r--r-- | lib/ext/t_cose/inc/t_cose_common.h | 78 | ||||
-rw-r--r-- | lib/ext/t_cose/inc/t_cose_mac0_verify.h | 116 | ||||
-rw-r--r-- | lib/ext/t_cose/inc/t_cose_sign1_verify.h | 82 | ||||
-rw-r--r-- | lib/ext/t_cose/src/t_cose_crypto.h | 40 | ||||
-rw-r--r-- | lib/ext/t_cose/src/t_cose_mac0_verify.c | 185 | ||||
-rw-r--r-- | lib/ext/t_cose/src/t_cose_parameters.h | 9 |
8 files changed, 492 insertions, 88 deletions
diff --git a/lib/ext/t_cose/CMakeLists.txt b/lib/ext/t_cose/CMakeLists.txt index 3bf3edf886..7b8c560f8d 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 c6e8749db4..f6036f9cf3 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 0481ac7e15..c6f2ec6b2b 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 0000000000..1b7c039a1f --- /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 11555d7eac..48ac7c9194 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 80263a90ba..8c98c48969 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 0000000000..ce47bb60c6 --- /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 8a17cd28a0..b51e8611b0 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. |