1 /* 2 * t_cose_common.h 3 * 4 * Copyright 2019, Laurence Lundblade 5 * Copyright (c) 2020-2021, 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_COMMON_H__ 14 #define __T_COSE_COMMON_H__ 15 16 #include <stdint.h> 17 #include "q_useful_buf.h" 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 /** 24 * \file t_cose_common.h 25 * 26 * \brief This file contains definitions common to all public t_cose 27 * interfaces. 28 * 29 * t_cose_common.h contains the definitions common to all public 30 * t_cose interfaces, particularly the error codes, algorithm 31 * identification constants and the structure containing a key. 32 * 33 * **Compile Time Configuration Options** 34 * 35 * \c T_COSE_DISABLE_SHORT_CIRCUIT_SIGN -- This disables short-circuit 36 * signing test mode. This saves a small amount of object code 37 * 38 * \c T_COSE_DISABLE_ES512 -- Disables the COSE algorithm ES512 39 * algorithm. This saves a tiny amount of code and a few hundred bytes 40 * of stack. It saves more than \c T_COSE_DISABLE_ES384. 41 * 42 * \c T_COSE_DISABLE_ES384 -- Disables the COSE algorithm ES384 43 * algorithm. This saves a tiny amount of code and a few hundred bytes 44 * of stack. No stack will be saved if \c T_COSE_DISABLE_ES512 is not 45 * also defined. 46 * 47 * \c T_COSE_DISABLE_CONTENT_TYPE -- Disables the content type 48 * parameters for both signing and verifying. 49 */ 50 51 52 53 54 /** 55 * \def T_COSE_ALGORITHM_ES256 56 * 57 * \brief Indicates ECDSA with SHA-256. 58 * 59 * This value comes from the 60 * [IANA COSE Registry](https://www.iana.org/assignments/cose/cose.xhtml). 61 * 62 * The COSE standard recommends a key using the secp256r1 curve with 63 * this algorithm. This curve is also known as prime256v1 and P-256. 64 */ 65 #define T_COSE_ALGORITHM_ES256 -7 66 67 /** 68 * \def T_COSE_ALGORITHM_ES384 69 * 70 * \brief Indicates ECDSA with SHA-384. 71 * 72 * This value comes from the 73 * [IANA COSE Registry](https://www.iana.org/assignments/cose/cose.xhtml). 74 * 75 * The COSE standard recommends a key using the secp384r1 curve with 76 * this algorithm. This curve is also known as P-384. 77 */ 78 #define T_COSE_ALGORITHM_ES384 -35 79 80 /** 81 * \def T_COSE_ALGORITHM_ES512 82 * 83 * \brief Indicates ECDSA with SHA-512. 84 * 85 * This value comes from the 86 * [IANA COSE Registry](https://www.iana.org/assignments/cose/cose.xhtml). 87 * 88 * The COSE standard recommends a key using the secp521r1 curve with 89 * this algorithm. This curve is also known as P-521. 90 */ 91 #define T_COSE_ALGORITHM_ES512 -36 92 93 /** 94 * \def T_COSE_ALGORITHM_HMAC256 95 * 96 * \brief Indicates HMAC with SHA256 97 * 98 * This value comes from the 99 * [IANA COSE Registry](https://www.iana.org/assignments/cose/cose.xhtml). 100 * 101 * Value for \ref COSE_HEADER_PARAM_ALG to indicate HMAC w/ SHA-256 102 */ 103 #define T_COSE_ALGORITHM_HMAC256 5 104 105 /** 106 * \def T_COSE_ALGORITHM_HMAC384 107 * 108 * \brief Indicates HMAC with SHA384 109 * 110 * This value comes from the 111 * [IANA COSE Registry](https://www.iana.org/assignments/cose/cose.xhtml). 112 * 113 * Value for \ref COSE_HEADER_PARAM_ALG to indicate HMAC w/ SHA-384 114 */ 115 #define T_COSE_ALGORITHM_HMAC384 6 116 117 /** 118 * \def T_COSE_ALGORITHM_HMAC512 119 * 120 * \brief Indicates HMAC with SHA512 121 * 122 * This value comes from the 123 * [IANA COSE Registry](https://www.iana.org/assignments/cose/cose.xhtml). 124 * 125 * Value for \ref COSE_HEADER_PARAM_ALG to indicate HMAC w/ SHA-512 126 */ 127 #define T_COSE_ALGORITHM_HMAC512 7 128 129 130 /** 131 * Indicates the cryptographic library the \ref t_cose_key is intended 132 * for. Usually only one cryptographic library is integrated so this 133 * serves as a cross-check. 134 */ 135 enum t_cose_crypto_lib_t { 136 /** can be used for integrations 137 * that don't have or don't want to have any cross-check. 138 */ 139 T_COSE_CRYPTO_LIB_UNIDENTIFIED = 0, 140 /** \c key_ptr points to a malloced OpenSSL EC_KEY. The caller 141 * needs to free it after the operation is done. */ 142 T_COSE_CRYPTO_LIB_OPENSSL = 1, 143 /** \c key_handle is a \c psa_key_handle_t in Arm's Platform Security 144 * Architecture */ 145 T_COSE_CRYPTO_LIB_PSA = 2 146 }; 147 148 149 /** 150 * This structure is used to indicate or pass a key through the t_cose 151 * implementation to the underlying, platform-specific cryptography 152 * libraries for signing and verifying signature. You must know the 153 * cryptographic library that is integrated with t_cose to know how to 154 * fill in this data structure. 155 * 156 * For example, in the OpenSSL integration, \ref key_ptr should point 157 * to an OpenSSL \c EC_KEY type. 158 */ 159 struct t_cose_key { 160 /** Identifies the crypto library this key was created for. The 161 * crypto library knows if it uses the handle or the pointer so 162 * this indirectly selects the union member. */ 163 enum t_cose_crypto_lib_t crypto_lib; 164 union { 165 /** For libraries that use a pointer to the key or key 166 * handle. \c NULL indicates empty. */ 167 void *key_ptr; 168 /** For libraries that use an integer handle to the key */ 169 uint64_t key_handle; 170 } k; 171 }; 172 173 /** An empty or \c NULL \c t_cose_key */ 174 #define T_COSE_NULL_KEY \ 175 ((struct t_cose_key){T_COSE_CRYPTO_LIB_UNIDENTIFIED, {0}}) 176 177 178 /* Private value. Intentionally not documented for Doxygen. This is 179 * the size allocated for the encoded protected header parameters. It 180 * needs to be big enough for encode_protected_parameters() to 181 * succeed. It currently sized for one parameter with an algorithm ID 182 * up to 32 bits long -- one byte for the wrapping map, one byte for 183 * the label, 5 bytes for the ID. If this is made accidentially too 184 * small, QCBOR will only return an error, and not overrun any 185 * buffers. 186 * 187 * 17 extra bytes are added, rounding it up to 24 total, in case some 188 * other protected header parameter is to be added and so the test 189 * using T_COSE_TEST_CRIT_PARAMETER_EXIST can work. 190 */ 191 #define T_COSE_SIGN1_MAX_SIZE_PROTECTED_PARAMETERS (1+1+5+17) 192 193 /* Private value. Intentionally not documented for Doxygen. 194 * This is the size allocated for the encoded protected headers. It 195 * needs to be big enough for make_protected_header() to succeed. It 196 * currently sized for one header with an algorithm ID up to 32 bits 197 * long -- one byte for the wrapping map, one byte for the label, 5 198 * bytes for the ID. If this is made accidentially too small, QCBOR will 199 * only return an error, and not overrun any buffers. 200 * 201 * 9 extra bytes are added, rounding it up to 16 total, in case some 202 * other protected header is to be added. 203 */ 204 #define T_COSE_MAC0_MAX_SIZE_PROTECTED_PARAMETERS (1 + 1 + 5 + 9) 205 206 /** 207 * Error codes return by t_cose. 208 */ 209 /* 210 * Do not reorder these. It is OK to add new ones at the end. 211 * 212 * Explicit values are included because some tools like debuggers show 213 * only the value, not the symbol, and it is hard to count up through 214 * 35 lines to figure out the actual value. 215 */ 216 enum t_cose_err_t { 217 /** Operation completed successfully. */ 218 T_COSE_SUCCESS = 0, 219 220 /** The requested signing algorithm is not supported. */ 221 T_COSE_ERR_UNSUPPORTED_SIGNING_ALG = 1, 222 223 /** Internal error when encoding protected parameters, usually 224 * because they are too big. It is internal because the caller 225 * can't really affect the size of the protected parameters. */ 226 T_COSE_ERR_MAKING_PROTECTED = 2, 227 228 /** The hash algorithm needed is not supported. Note that the 229 * signing algorithm identifier identifies the hash algorithm. */ 230 T_COSE_ERR_UNSUPPORTED_HASH = 3, 231 232 /** Some system failure when running the hash algorithm. */ 233 T_COSE_ERR_HASH_GENERAL_FAIL = 4, 234 235 /** The buffer to receive a hash result is too small. */ 236 T_COSE_ERR_HASH_BUFFER_SIZE = 5, 237 238 /** The buffer to receive result of a signing operation is too 239 * small. */ 240 T_COSE_ERR_SIG_BUFFER_SIZE = 6, 241 242 /** When verifying a \c COSE_Sign1, the CBOR is "well-formed", but 243 * something is wrong with the format of the CBOR outside of the 244 * header parameters. For example, it is missing something like 245 * the payload or something is of an unexpected type. */ 246 T_COSE_ERR_SIGN1_FORMAT = 8, 247 248 /** When decoding some CBOR like a \c COSE_Sign1, the CBOR was not 249 * "well-formed". Most likely what was supposed to be CBOR is 250 * either not or is corrupted. The CBOR is can't be decoded. */ 251 T_COSE_ERR_CBOR_NOT_WELL_FORMED = 9, 252 253 /** The CBOR is "well-formed", but something is wrong with format 254 * in the header parameters. For example, a parameter is labeled 255 * with other than an integer or string or the value is an integer 256 * when a byte string is expected. */ 257 T_COSE_ERR_PARAMETER_CBOR = 10, 258 259 /** No algorithm ID was found when one is needed. For example, 260 * when verifying a \c COSE_Sign1. */ 261 T_COSE_ERR_NO_ALG_ID = 11, 262 263 /** No kid (key ID) was found when one is needed. For example, 264 * when verifying a \c COSE_Sign1. */ 265 T_COSE_ERR_NO_KID = 12, 266 267 /** Signature verification failed. For example, the cryptographic 268 * operations completed successfully but hash wasn't as 269 * expected. */ 270 T_COSE_ERR_SIG_VERIFY = 13, 271 272 /** Verification of a short-circuit signature failed. */ 273 T_COSE_ERR_BAD_SHORT_CIRCUIT_KID = 14, 274 275 /** Some (unspecified) argument was not valid. */ 276 T_COSE_ERR_INVALID_ARGUMENT = 15, 277 278 /** Out of heap memory. This originates in crypto library as 279 * t_cose does not use malloc. */ 280 T_COSE_ERR_INSUFFICIENT_MEMORY = 16, 281 282 /** General unspecific failure. */ 283 T_COSE_ERR_FAIL = 17, 284 285 /** Equivalent to \c PSA_ERROR_CORRUPTION_DETECTED. */ 286 T_COSE_ERR_TAMPERING_DETECTED = 18, 287 288 /** The key identified by a \ref t_cose_key or a key ID was not 289 * found. */ 290 T_COSE_ERR_UNKNOWN_KEY = 19, 291 292 /** The key was found, but it was the wrong type for the 293 * operation. */ 294 T_COSE_ERR_WRONG_TYPE_OF_KEY = 20, 295 296 /** Error constructing the COSE \c Sig_structure when signing or 297 * verify. */ 298 T_COSE_ERR_SIG_STRUCT = 21, 299 300 /** Signature was short-circuit. The option \ref 301 * T_COSE_OPT_ALLOW_SHORT_CIRCUIT to allow verification of 302 * short-circuit signatures was not set. */ 303 T_COSE_ERR_SHORT_CIRCUIT_SIG = 22, 304 305 /** Something generally went wrong in the crypto adaptor when 306 * signing or verifying. */ 307 T_COSE_ERR_SIG_FAIL = 23, 308 309 /** Something went wrong formatting the CBOR. Possibly the 310 * payload has maps or arrays that are not closed when using 311 * t_cose_sign1_encode_parameters() and 312 * t_cose_sign1_encode_signature() to sign a \c COSE_Sign1. */ 313 T_COSE_ERR_CBOR_FORMATTING = 24, 314 315 /** The buffer passed in to receive the output is too small. */ 316 T_COSE_ERR_TOO_SMALL = 25, 317 318 /** More parameters (more than \ref T_COSE_PARAMETER_LIST_MAX) 319 * than this implementation can handle. Note that all parameters 320 * need to be checked for criticality so all parameters need to be 321 * examined. */ 322 T_COSE_ERR_TOO_MANY_PARAMETERS = 26, 323 324 /** A parameter was encountered that was unknown and also listed in 325 * the crit labels parameter. */ 326 T_COSE_ERR_UNKNOWN_CRITICAL_PARAMETER = 27, 327 328 /** A request was made to signed with a short-circuit sig, \ref 329 * T_COSE_OPT_SHORT_CIRCUIT_SIG, but short circuit signature are 330 * disabled (compiled out) for this implementation. */ 331 T_COSE_ERR_SHORT_CIRCUIT_SIG_DISABLED = 28, 332 333 /** The key type in a \ref t_cose_key is wrong for the 334 * cryptographic library used by this integration of t_cose. 335 */ 336 T_COSE_ERR_INCORRECT_KEY_FOR_LIB = 29, 337 /** This implementation only handles integer COSE algorithm IDs with 338 * values less than \c INT32_MAX. */ 339 340 T_COSE_ERR_NON_INTEGER_ALG_ID = 30, 341 /** The content type parameter contains a content type that is 342 * neither integer or text string or it is an integer not in the 343 * range of 0 to \c UINT16_MAX. */ 344 T_COSE_ERR_BAD_CONTENT_TYPE = 31, 345 346 /** If the option \ref T_COSE_OPT_TAG_REQUIRED is set for 347 * t_cose_sign1_verify() and the tag is absent, this error is 348 * returned. */ 349 T_COSE_ERR_INCORRECTLY_TAGGED = 32, 350 351 /** The signing or verification key given is empty. */ 352 T_COSE_ERR_EMPTY_KEY = 33, 353 354 /** A header parameter occurs twice, perhaps once in protected and 355 * once in unprotected. Duplicate header parameters are not 356 * allowed in COSE. 357 */ 358 T_COSE_ERR_DUPLICATE_PARAMETER = 34, 359 360 /** A header parameter that should be protected (alg id or crit) 361 * is not. This occurs when verifying a \c COSE_Sign1 that is 362 * improperly constructed. */ 363 T_COSE_ERR_PARAMETER_NOT_PROTECTED = 35, 364 365 /** Something is wrong with the crit parameter. */ 366 T_COSE_ERR_CRIT_PARAMETER = 36, 367 368 /** 369 * When verifying a \c COSE_Mac0, something is wrong with the 370 * format of the CBOR. For example, it is missing something like 371 * the payload. 372 */ 373 T_COSE_ERR_MAC0_FORMAT = 37, 374 }; 375 376 377 378 379 /** 380 * The maximum number of header parameters that can be handled during 381 * verification of a \c COSE_Sign1 message. \ref 382 * T_COSE_ERR_TOO_MANY_PARAMETERS will be returned by 383 * t_cose_sign1_verify() if the input message has more. 384 * 385 * There can be both \ref T_COSE_PARAMETER_LIST_MAX integer-labeled 386 * parameters and \ref T_COSE_PARAMETER_LIST_MAX string-labeled 387 * parameters. 388 * 389 * This is a hard maximum so the implementation doesn't need 390 * malloc. This constant can be increased if needed. Doing so will 391 * increase stack usage. 392 */ 393 #define T_COSE_PARAMETER_LIST_MAX 10 394 395 396 397 /** 398 * The value of an unsigned integer content type indicating no content 399 * type. See \ref t_cose_parameters. 400 */ 401 #define T_COSE_EMPTY_UINT_CONTENT_TYPE UINT16_MAX+1 402 403 /** 404 * The result of parsing a set of COSE header parameters. The pointers 405 * are all back into the COSE structure blob passed in. 406 * 407 * Approximate size on a 64-bit machine is 80 bytes and on a 32-bit 408 * machine is 40. 409 */ 410 struct t_cose_parameters { 411 /** The algorithm ID. \ref T_COSE_UNSET_ALGORITHM_ID if the algorithm ID 412 * parameter is not present. String type algorithm IDs are not 413 * supported. See the 414 * [IANA COSE Registry](https://www.iana.org/assignments/cose/cose.xhtml) 415 * for the algorithms corresponding to the integer values. 416 */ 417 int32_t cose_algorithm_id; 418 /** The COSE key ID. \c NULL_Q_USEFUL_BUF_C if parameter is not 419 * present */ 420 struct q_useful_buf_c kid; 421 /** The initialization vector. \c NULL_Q_USEFUL_BUF_C if parameter 422 * is not present */ 423 struct q_useful_buf_c iv; 424 /** The partial initialization vector. \c NULL_Q_USEFUL_BUF_C if 425 * parameter is not present */ 426 struct q_useful_buf_c partial_iv; 427 /** The content type as a MIME type like 428 * "text/plain". \c NULL_Q_USEFUL_BUF_C if parameter is not present */ 429 #ifndef T_COSE_DISABLE_CONTENT_TYPE 430 struct q_useful_buf_c content_type_tstr; 431 /** The content type as a CoAP Content-Format 432 * integer. \ref T_COSE_EMPTY_UINT_CONTENT_TYPE if parameter is not 433 * present. Allowed range is 0 to UINT16_MAX per RFC 7252. */ 434 uint32_t content_type_uint; 435 #endif /* T_COSE_DISABLE_CONTENT_TYPE */ 436 }; 437 438 439 440 441 /** 442 * An \c option_flag to not add the CBOR type 6 tag for a COSE message. 443 * Some uses of COSE may require this tag be absent because its COSE 444 * message type is known from surrounding context. 445 * 446 * Or said another way, per the COSE RFC, this code produces a \c 447 * COSE_Sign1_Tagged/ \c COSE_Mac0_Tagged by default and 448 * a \c COSE_Sign1/ \c COSE_Mac0 when this flag is set. 449 * The only difference between these two is the CBOR tag. 450 */ 451 #define T_COSE_OPT_OMIT_CBOR_TAG 0x00000002 452 453 454 /** 455 * Pass this as \c option_flags to allow verification of short-circuit 456 * signatures. This should only be used as a test mode as 457 * short-circuit signatures are not secure. 458 * 459 * See also \ref T_COSE_OPT_SHORT_CIRCUIT_SIG. 460 */ 461 #define T_COSE_OPT_ALLOW_SHORT_CIRCUIT 0x00000001 462 463 464 /** 465 * The error \ref T_COSE_ERR_NO_KID is returned if the kid parameter 466 * is missing. Note that the kid parameter is primarily passed on to 467 * the crypto layer so the crypto layer can look up the key. If the 468 * verification key is determined by other than the kid, then it is 469 * fine if there is no kid. 470 */ 471 #define T_COSE_OPT_REQUIRE_KID 0x00000002 472 473 474 /** 475 * Normally this will decode the CBOR presented as a \c COSE_Sign1 476 * or a \c COSE_Mac0 message whether it is tagged using QCBOR tagging 477 * as such or not. 478 * If this option is set, then \ref T_COSE_ERR_INCORRECTLY_TAGGED is 479 * returned if it is not tagged. 480 */ 481 #define T_COSE_OPT_TAG_REQUIRED 0x00000004 482 483 484 /** 485 * This option disables cryptographic signature verification. With 486 * this option the \c verification_key is not needed. This is useful 487 * to decode the a COSE message to get the kid (key ID). The 488 * verification key can be looked up or otherwise obtained by the 489 * caller. Once the key in in hand, the verification function can be 490 * called again to perform the full verification. 491 * 492 * The payload will always be returned whether this is option is given 493 * or not, but it should not be considered secure when this option is 494 * given. 495 * 496 */ 497 #define T_COSE_OPT_DECODE_ONLY 0x00000008 498 499 500 #ifdef __cplusplus 501 } 502 #endif 503 504 505 #endif /* __T_COSE_COMMON_H__ */ 506