1 /* 2 * t_cose_util.h 3 * 4 * Copyright 2019, Laurence Lundblade 5 * Copyright (c) 2020, Arm Limited. All rights reserved. 6 * 7 * SPDX-License-Identifier: BSD-3-Clause 8 * 9 * See BSD-3-Clause license in README.md 10 */ 11 12 13 #ifndef __T_COSE_UTIL_H__ 14 #define __T_COSE_UTIL_H__ 15 16 #include <stdint.h> 17 #include "q_useful_buf.h" 18 #include "t_cose_common.h" 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 /** 25 * \file t_cose_util.h 26 * 27 * \brief Utility functions used internally by the t_cose implementation. 28 * 29 */ 30 31 32 /** 33 * The modes in which the payload is passed to create_tbs_hash(). 34 * This exists so the TBS bytes can be hashed in two separate chunks 35 * and avoids needing a second buffer the size of the payload in the 36 * t_cose implementation. 37 */ 38 enum t_cose_tbs_hash_mode_t { 39 /** The bytes passed for the payload include a wrapping bstr so 40 * one does not need to be added. 41 */ 42 T_COSE_TBS_PAYLOAD_IS_BSTR_WRAPPED, 43 /** The bytes passed for the payload do NOT have a wrapping bstr 44 * so one must be added. 45 */ 46 T_COSE_TBS_BARE_PAYLOAD 47 }; 48 49 50 /** 51 * The modes in which the payload is passed to create_tbm(). This 52 * exists so the ToBeMaced bytes can be hashed in two separate chunks and 53 * avoids needing a second buffer the size of the payload in the 54 * t_cose implementation. 55 */ 56 enum t_cose_tbm_payload_mode_t { 57 /** The bytes passed for the payload include a wrapping bstr so 58 * one does not need to be added. 59 */ 60 T_COSE_TBM_PAYLOAD_IS_BSTR_WRAPPED, 61 /** The bytes passed for the payload do NOT have a wrapping bstr 62 * so one must be added. 63 */ 64 T_COSE_TBM_BARE_PAYLOAD 65 }; 66 67 /** 68 * This value represents an invalid or in-error algorithm ID. The 69 * value selected is 0 as this is reserved in the IANA COSE algorithm 70 * registry and is very unlikely to ever be used. (It would take am 71 * IETF standards-action to put it to use). 72 */ 73 #define T_COSE_INVALID_ALGORITHM_ID COSE_ALGORITHM_RESERVED 74 75 76 /* 77 * Format of ToBeMaced bytes 78 * This is defined in COSE (RFC 8152) section 6.2. It is the input to the HMAC 79 * operation. 80 * 81 * MAC_structure = [ 82 * context : "MAC0", 83 * protected : empty_or_serialized_map, 84 * external_aad : bstr, 85 * payload : bstr 86 * ] 87 */ 88 89 /** 90 * This is the size of the first part of the CBOR encoded ToBeMaced 91 * bytes. It is around 30 bytes. 92 */ 93 #define T_COSE_SIZE_OF_TBM \ 94 1 + /* For opening the array */ \ 95 sizeof(COSE_MAC_CONTEXT_STRING_MAC0) + /* "MAC0" */ \ 96 2 + /* Overhead for encoding string */ \ 97 T_COSE_MAC0_MAX_SIZE_PROTECTED_PARAMETERS + /* entire protected headers */ \ 98 1 + /* Empty bstr for absent external_aad */ \ 99 9 /* The max CBOR length encoding for start of payload */ 100 101 102 /** 103 * \brief Return hash algorithm ID from a signature algorithm ID 104 * 105 * \param[in] cose_algorithm_id A COSE signature algorithm identifier. 106 * 107 * \return \c T_COSE_INVALID_ALGORITHM_ID when the signature algorithm ID 108 is not known. 109 * 110 * This works off of algorithm identifiers defined in the 111 * [IANA COSE Registry](https://www.iana.org/assignments/cose/cose.xhtml). 112 * Corresponding local integer constants are defined in 113 * t_cose_standard_constants.h. 114 * 115 * COSE signing algorithms are the combination of public key 116 * algorithm, hash algorithm and hash size and imply an appropriate 117 * key size. They are simple integers making them convenient for 118 * direct use in code. 119 * 120 * This function returns an identifier for only the hash algorithm 121 * from the combined identifier. 122 * 123 * If the needed algorithm identifiers are not in the IANA registry, 124 * they can be added to it. This will take some time and work. It is 125 * also fine to use algorithms in the COSE proprietary space. 126 */ 127 int32_t hash_alg_id_from_sig_alg_id(int32_t cose_algorithm_id); 128 129 /** 130 * \brief Create the ToBeMaced (TBM) structure bytes for COSE. 131 * 132 * \param[in] tbm_first_part_buf The buffer to contain the first part 133 * \param[in] protected_headers The CBOR encoded protected headers. 134 * \param[out] tbm_first_part Pointer and length of buffer into which 135 * the resulting TBM is put. 136 * \param[in] payload_mode See \ref t_cose_tbm_payload_mode_t. 137 * \param[in] payload The CBOR encoded payload. It may or may 138 * not have a wrapping bstr per 139 * \c payload_mode. 140 * 141 * \return This returns one of the error codes defined by \ref t_cose_err_t. 142 * 143 * \retval T_COSE_ERR_SIG_STRUCT 144 * Most likely this is because the protected_headers passed in 145 * is larger than \ref T_COSE_MAC0_MAX_PROT_HEADER. 146 * \retval T_COSE_ERR_UNSUPPORTED_HASH 147 * If the hash algorithm is not known. 148 * \retval T_COSE_ERR_HASH_GENERAL_FAIL 149 * In case of some general hash failure. 150 */ 151 enum t_cose_err_t create_tbm(UsefulBuf tbm_first_part_buf, 152 struct q_useful_buf_c protected_headers, 153 struct q_useful_buf_c *tbm_first_part, 154 enum t_cose_tbm_payload_mode_t payload_mode, 155 struct q_useful_buf_c payload); 156 157 /** 158 * \brief Create the hash of the to-be-signed (TBS) bytes for COSE. 159 * 160 * \param[in] cose_algorithm_id The COSE signing algorithm ID. Used to 161 * determine which hash function to use. 162 * \param[in] protected_parameters Full, CBOR encoded, protected parameters. 163 * \param[in] payload_mode See \ref t_cose_tbs_hash_mode_t. 164 * \param[in] payload The CBOR encoded payload. It may or may 165 * not have a wrapping bstr per 166 * \c payload_mode. 167 * \param[in] buffer_for_hash Pointer and length of buffer into which 168 * the resulting hash is put. 169 * \param[out] hash Pointer and length of the 170 * resulting hash. 171 * 172 * \return This returns one of the error codes defined by \ref t_cose_err_t. 173 * 174 * \retval T_COSE_ERR_SIG_STRUCT 175 * Most likely this is because the protected_parameters passed in 176 * is larger than \c T_COSE_SIGN1_MAX_SIZE_PROTECTED_PARAMETERS. 177 * \retval T_COSE_ERR_UNSUPPORTED_HASH 178 * If the hash algorithm is not known. 179 * \retval T_COSE_ERR_HASH_GENERAL_FAIL 180 * In case of some general hash failure. 181 * 182 * The input to the public key signature algorithm in COSE is the hash 183 * of a CBOR encoded structure containing the protected parameters 184 * algorithm ID and a few other things. This formats that structure 185 * and computes the hash of it. These are known as the to-be-signed or 186 * "TBS" bytes. The exact specification is in 187 * [RFC 8152 section 4.4](https://tools.ietf.org/html/rfc8152#section-4.4). 188 */ 189 enum t_cose_err_t create_tbs_hash(int32_t cose_algorithm_id, 190 struct q_useful_buf_c protected_parameters, 191 enum t_cose_tbs_hash_mode_t payload_mode, 192 struct q_useful_buf_c payload, 193 struct q_useful_buf buffer_for_hash, 194 struct q_useful_buf_c *hash); 195 196 197 198 199 #ifndef T_COSE_DISABLE_SHORT_CIRCUIT_SIGN 200 201 /** 202 * Size of the key returned by get_short_circuit_kid(). It is always 203 * this size. 204 */ 205 #define T_COSE_SHORT_CIRCUIT_KID_SIZE 32 206 207 208 /** 209 * \brief Get the special kid for short-circuit signing. 210 * 211 * \returns Buffer with the kid. 212 * 213 * This always returns the same kid. It always indicates short-circuit 214 * signing. It is OK to hard code this kid value as the probability of 215 * collision with this ID is extremely low and the same as for 216 * collision between any two key IDs (kids) of any sort. 217 * 218 * This always returns a pointer to the same memory as the result 219 * returned by this never changes. 220 * 221 * This is the value of the kid. 222 * 223 * 0xef, 0x95, 0x4b, 0x4b, 0xd9, 0xbd, 0xf6, 0x70, 224 * 0xd0, 0x33, 0x60, 0x82, 0xf5, 0xef, 0x15, 0x2a, 225 * 0xf8, 0xf3, 0x5b, 0x6a, 0x6c, 0x00, 0xef, 0xa6, 226 * 0xa9, 0xa7, 0x1f, 0x49, 0x51, 0x7e, 0x18, 0xc6 227 * 228 */ 229 struct q_useful_buf_c get_short_circuit_kid(void); 230 #endif 231 232 #ifdef __cplusplus 233 } 234 #endif 235 236 #endif /* __T_COSE_UTIL_H__ */ 237