1 /*
2 * t_cose_crypto.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_CRYPTO_H__
14 #define __T_COSE_CRYPTO_H__
15
16 #include "t_cose_common.h"
17 #include "q_useful_buf.h"
18 #include <stdint.h>
19 #include <stdbool.h>
20 #include "t_cose_standard_constants.h"
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26
27
28
29 /**
30 * \file t_cose_crypto.h
31 *
32 * \brief This defines the adaptation layer for cryptographic
33 * functions needed by t_cose.
34 *
35 * This is small wrapper around the cryptographic functions to:
36 * - Map COSE algorithm IDs to cryptographic library IDs
37 * - Map cryptographic library errors to \ref t_cose_err_t errors
38 * - Have inputs and outputs be \c struct \c q_useful_buf_c and
39 * \c struct \c q_useful_buf
40 * - Handle key selection
41 *
42 * An implementation must be made of these functions
43 * for the various cryptographic libraries that are used on
44 * various platforms and OSs. The functions are:
45 * - t_cose_t_crypto_sig_size()
46 * - t_cose_crypto_pub_key_sign()
47 * - t_cose_crypto_pub_key_verify()
48 * - t_cose_crypto_hash_start()
49 * - t_cose_crypto_hash_update()
50 * - t_cose_crypto_hash_finish()
51 *
52 * This runs entirely off of COSE-style algorithm identifiers. They
53 * are simple integers and thus work nice as function parameters. An
54 * initial set is defined by [COSE (RFC 8152)]
55 * (https://tools.ietf.org/html/rfc8152). New ones can be registered
56 * in the [IANA COSE Registry]
57 * (https://www.iana.org/assignments/cose/cose.xhtml). Local use new
58 * ones can also be defined (\c \#define) if what is needed is not in
59 * the IANA registry.
60 *
61 * \anchor useful_buf_use
62 * Binary data is returned to the caller using a \c struct \c
63 * q_useful_buf to pass the buffer to receive the data and its length in
64 * and a \c q_useful_buf_c to return the pointer and length of the
65 * returned data. The point of this is coding hygiene. The buffer
66 * passed in is not const as it is to be modified. The \c
67 * q_useful_buf_c returned is const. The lengths of buffers are
68 * handled in a clear, consistent and enforced manner.
69 *
70 * The pointer in the \c q_useful_buf_c will always point to the
71 * buffer passed in via the \c q_useful_buf so the lifetime of the
72 * data is under control of the caller.
73 *
74 * This is not intended as any sort of general cryptographic API. It
75 * is just the functions needed by t_cose in the form that is most
76 * useful for t_cose.
77 *
78 * No other file in t_cose should need modification for new algorithms,
79 * new key types and sizes or the integration of cryptographic libraries
80 * except on some occasions, this file as follows:
81 *
82 * - Support for a new COSE_ALGORITHM_XXX signature algorithm
83 * - See t_cose_algorithm_is_ecdsa()
84 * - If not ECDSA add another function like t_cose_algorithm_is_ecdsa()
85 * - Support for a new COSE_ALGORITHM_XXX signature algorithm is added
86 * - See \ref T_COSE_CRYPTO_MAX_HASH_SIZE for additional hashes
87 * - Support larger key sizes (and thus signature sizes)
88 * - See \ref T_COSE_MAX_SIG_SIZE
89 * - Support another hash implementation that is not a service
90 * - See struct \ref t_cose_crypto_hash
91 *
92 * To reduce stack usage and save a little code these can be defined.
93 * - T_COSE_DISABLE_ES384
94 * - T_COSE_DISABLE_ES512
95 *
96 * The actual code that implements these hashes in the crypto library may
97 * or may not be saved with these defines depending on how the library
98 * works, whether dead stripping of object code is on and such.
99 */
100
101
102
103
104 #define T_COSE_EC_P256_SIG_SIZE 64 /* size for secp256r1 */
105 #define T_COSE_EC_P384_SIG_SIZE 96 /* size for secp384r1 */
106 #define T_COSE_EC_P512_SIG_SIZE 132 /* size for secp521r1 */
107
108
109 /**
110 * There is a stack variable to hold the output of the signing
111 * operation. This sets the maximum signature size this code can
112 * handle based on the COSE algorithms configured. The size of the
113 * signature goes with the size of the key, not the algorithm, so a
114 * key could be given for signing or verification that is larger than
115 * this. However, it is not typical to do so. If the key or signature
116 * is too large the failure will be graceful with an error.
117 *
118 * For ECDSA the signature format used is defined in RFC 8152 section
119 * 8.1. It is the concatenation of r and s, each of which is the key
120 * size in bits rounded up to the nearest byte. That is twice the key
121 * size in bytes.
122 */
123 #ifndef T_COSE_DISABLE_ES512
124 #define T_COSE_MAX_SIG_SIZE T_COSE_EC_P512_SIG_SIZE
125 #else
126 #ifndef T_COSE_DISABLE_ES384
127 #define T_COSE_MAX_SIG_SIZE T_COSE_EC_P384_SIG_SIZE
128 #else
129 #define T_COSE_MAX_SIG_SIZE T_COSE_EC_P256_SIG_SIZE
130 #endif
131 #endif
132
133
134
135
136 /**
137 * \brief Returns the size of a signature given the key and algorithm.
138 *
139 * \param[in] cose_algorithm_id The algorithm ID
140 * \param[in] signing_key Key to compute size of
141 * \param[out] sig_size The returned size in bytes.
142 *
143 * \return An error code or \ref T_COSE_SUCCESS.
144 *
145 * This is used the caller wishes to compute the size of a token in
146 * order to allocate memory for it.
147 *
148 * The size of a signature depends primarily on the key size but it is
149 * usually necessary to know the algorithm too.
150 *
151 * This always returns the exact size of the signature.
152 */
153 enum t_cose_err_t
154 t_cose_crypto_sig_size(int32_t cose_algorithm_id,
155 struct t_cose_key signing_key,
156 size_t *sig_size);
157
158
159 /**
160 * \brief Perform public key signing. Part of the t_cose crypto
161 * adaptation layer.
162 *
163 * \param[in] cose_algorithm_id The algorithm to sign with. The IDs are
164 * defined in [COSE (RFC 8152)]
165 * (https://tools.ietf.org/html/rfc8152) or
166 * in the [IANA COSE Registry]
167 * (https://www.iana.org/assignments/cose/cose.xhtml).
168 * A proprietary ID can also be defined
169 * locally (\c \#define) if the needed
170 * one hasn't been registered.
171 * \param[in] signing_key Indicates or contains key to sign with.
172 * \param[in] hash_to_sign The bytes to sign. Typically, a hash of
173 * a payload.
174 * \param[in] signature_buffer Pointer and length of buffer into which
175 * the resulting signature is put.
176 * \param[in] signature Pointer and length of the signature
177 * returned.
178 *
179 * \retval T_COSE_SUCCESS
180 * Successfully created the signature.
181 * \retval T_COSE_ERR_SIG_BUFFER_SIZE
182 * The \c signature_buffer too small.
183 * \retval T_COSE_ERR_UNSUPPORTED_SIGNING_ALG
184 * The requested signing algorithm, \c cose_algorithm_id, is not
185 * supported.
186 * \retval T_COSE_ERR_UNKNOWN_KEY
187 * The key identified by \c key_select was not found.
188 * \retval T_COSE_ERR_WRONG_TYPE_OF_KEY
189 * The key was found, but it was the wrong type.
190 * \retval T_COSE_ERR_INVALID_ARGUMENT
191 * Some (unspecified) argument was not valid.
192 * \retval T_COSE_ERR_INSUFFICIENT_MEMORY
193 * Insufficient heap memory.
194 * \retval T_COSE_ERR_FAIL
195 * General unspecific failure.
196 * \retval T_COSE_ERR_TAMPERING_DETECTED
197 * Equivalent to \c PSA_ERROR_CORRUPTION_DETECTED.
198 *
199 * This is called to do public key signing. The implementation will
200 * vary from one platform / OS to another but should conform to the
201 * description here.
202 *
203 * The contents of signing_key is usually the type that holds
204 * a key for the cryptographic library.
205 *
206 * See the note in the Detailed Description (the \\file comment block)
207 * for details on how \c q_useful_buf and \c q_useful_buf_c are used
208 * to return the signature.
209 *
210 * To find out the size of the signature buffer needed, call this with
211 * \c signature_buffer->ptr \c NULL and \c signature_buffer->len a
212 * very large number like \c UINT32_MAX. The size will be returned in
213 * \c signature->len.
214 */
215 enum t_cose_err_t
216 t_cose_crypto_pub_key_sign(int32_t cose_algorithm_id,
217 struct t_cose_key signing_key,
218 struct q_useful_buf_c hash_to_sign,
219 struct q_useful_buf signature_buffer,
220 struct q_useful_buf_c *signature);
221
222
223 /**
224 * \brief Perform public key signature verification. Part of the
225 * t_cose crypto adaptation layer.
226 *
227 * \param[in] cose_algorithm_id The algorithm to use for verification.
228 * The IDs are defined in [COSE (RFC 8152)]
229 * (https://tools.ietf.org/html/rfc8152)
230 * or in the [IANA COSE Registry]
231 * (https://www.iana.org/assignments/cose/cose.xhtml).
232 * A proprietary ID can also be defined
233 * locally (\c \#define) if the needed one
234 * hasn't been registered.
235 * \param[in] verification_key The verification key to use.
236 * \param[in] kid The COSE kid (key ID) or \c NULL_Q_USEFUL_BUF_C.
237 * \param[in] hash_to_verify The data or hash that is to be verified.
238 * \param[in] signature The signature.
239 *
240 * This verifies that the \c signature passed in was over the \c
241 * hash_to_verify passed in.
242 *
243 * The public key used to verify the signature is selected by the \c
244 * kid if it is not \c NULL_Q_USEFUL_BUF_C or the \c key_select if it
245 * is.
246 *
247 * The key selected must be, or include, a public key of the correct
248 * type for \c cose_algorithm_id.
249 *
250 * \retval T_COSE_SUCCESS
251 * The signature is valid
252 * \retval T_COSE_ERR_SIG_VERIFY
253 * Signature verification failed. For example, the
254 * cryptographic operations completed successfully but hash
255 * wasn't as expected.
256 * \retval T_COSE_ERR_UNKNOWN_KEY
257 * The key identified by \c key_select or a \c kid was
258 * not found.
259 * \retval T_COSE_ERR_WRONG_TYPE_OF_KEY
260 * The key was found, but it was the wrong type
261 * for the operation.
262 * \retval T_COSE_ERR_UNSUPPORTED_SIGNING_ALG
263 * The requested signing algorithm is not supported.
264 * \retval T_COSE_ERR_INVALID_ARGUMENT
265 * Some (unspecified) argument was not valid.
266 * \retval T_COSE_ERR_INSUFFICIENT_MEMORY
267 * Out of heap memory.
268 * \retval T_COSE_ERR_FAIL
269 * General unspecific failure.
270 * \retval T_COSE_ERR_TAMPERING_DETECTED
271 * Equivalent to \c PSA_ERROR_CORRUPTION_DETECTED.
272 */
273 enum t_cose_err_t
274 t_cose_crypto_pub_key_verify(int32_t cose_algorithm_id,
275 struct t_cose_key verification_key,
276 struct q_useful_buf_c kid,
277 struct q_useful_buf_c hash_to_verify,
278 struct q_useful_buf_c signature);
279
280
281
282
283 #ifdef T_COSE_USE_PSA_CRYPTO
284 #include "psa/crypto.h"
285
286 #elif T_COSE_USE_OPENSSL_CRYPTO
287 #include "openssl/sha.h"
288
289 #elif T_COSE_USE_B_CON_SHA256
290 /* This is code for use with Brad Conte's crypto. See
291 * https://github.com/B-Con/crypto-algorithms and see the description
292 * of t_cose_crypto_hash
293 */
294 #include "sha256.h"
295 #endif
296
297
298 /**
299 * The context for use with the hash adaptation layer here.
300 *
301 * Hash implementations for this porting layer are put into two
302 * different categories.
303 *
304 * The first can be supported generically without any dependency on
305 * the actual hash implementation in this header. These only need a
306 * pointer or handle for the hash context. Usually these are
307 * implemented by a service, system API or crypto HW that runs in a
308 * separate context or process. They probably allocate memory
309 * internally. These can use context.ptr or context.handle to hold the
310 * pointer or handle to the hash context.
311 *
312 * The second sort of hash implementations need more than just a
313 * pointer or handle. Typically these are libraries that are linked
314 * with this code and run in the same process / context / thread as
315 * this code. These can be efficient requiring no context switches or
316 * memory allocations. These type require this header be modified for
317 * the #include which defines the hash context and so this struct
318 * includes that context as a member. This context is allocated on the
319 * stack, so any members added here should be small enough to go on
320 * the stack. USE_B_CON_SHA256 is an example of this type.
321 *
322 * The actual implementation of the hash is in a separate .c file
323 * that will be specific to the particular platform, library,
324 * service or such used.
325 */
326 struct t_cose_crypto_hash {
327
328 #ifdef T_COSE_USE_PSA_CRYPTO
329 /* --- The context for PSA Crypto (MBed Crypto) --- */
330
331 /* psa_hash_operation_t actually varied by the implementation of
332 * the crypto library. Sometimes the implementation is inline and
333 * thus the context is a few hundred bytes, sometimes it is not.
334 * This varies by what is in crypto_struct.h (which is not quite
335 * a public interface).
336 *
337 * This can be made smaller for PSA implementations that work inline
338 * by disabling the larger algorithms using PSA / MBed configuration.
339 */
340 psa_hash_operation_t ctx;
341 psa_status_t status;
342
343 #elif T_COSE_USE_OPENSSL_CRYPTO
344 /* --- The context for PSA Crypto (MBed Crypto) --- */
345
346 /* What is needed for a full proper integration of OpenSSL's hashes */
347 union {
348 SHA256_CTX sha_256;
349 #if !defined T_COSE_DISABLE_ES512 || !defined T_COSE_DISABLE_ES384
350 /* SHA 384 uses the sha_512 context
351 * This uses about 100 bytes above SHA-256 */
352 SHA512_CTX sha_512;
353 #endif
354 } ctx;
355
356 int update_error; /* Used to track error return by SHAXXX_Upate() */
357 int32_t cose_hash_alg_id; /* COSE integer ID for the hash alg */
358
359 #elif T_COSE_USE_B_CON_SHA256
360 /* --- Specific context for Brad Conte's sha256.c --- */
361 SHA256_CTX b_con_hash_context;
362
363 #else
364 /* --- Default: generic pointer / handle --- */
365
366 union {
367 void *ptr;
368 uint64_t handle;
369 } context;
370 int64_t status;
371 #endif
372
373 };
374
375 /**
376 * The context for use with the HMAC adaptation layer here.
377 * Borrow the structure of t_cose_crypto_hash.
378 */
379 struct t_cose_crypto_hmac {
380 #ifdef T_COSE_USE_PSA_CRYPTO
381 /* --- The context for PSA Crypto (MBed Crypto) --- */
382 psa_mac_operation_t op_ctx;
383 #else
384 /* --- Default: generic pointer / handle --- */
385 union {
386 void *ptr;
387 uint64_t handle;
388 } context;
389 int64_t status;
390 #endif
391 };
392
393 /**
394 * The size of the output of SHA-256.
395 *
396 * (It is safe to define these independently here as they are
397 * well-known and fixed. There is no need to reference
398 * platform-specific headers and incur messy dependence.)
399 */
400 #define T_COSE_CRYPTO_SHA256_SIZE 32
401
402 /**
403 * The size of the output of SHA-384 in bytes.
404 */
405 #define T_COSE_CRYPTO_SHA384_SIZE 48
406
407 /**
408 * The size of the output of SHA-512 in bytes.
409 */
410 #define T_COSE_CRYPTO_SHA512_SIZE 64
411
412 /**
413 * Size of the signature (tag) output for the HMAC-SHA256.
414 */
415 #define T_COSE_CRYPTO_HMAC256_TAG_SIZE T_COSE_CRYPTO_SHA256_SIZE
416
417 /**
418 * Size of the signature (tag) output for the HMAC-SHA384.
419 */
420 #define T_COSE_CRYPTO_HMAC384_TAG_SIZE T_COSE_CRYPTO_SHA384_SIZE
421
422 /**
423 * Size of the signature (tag) output for the HMAC-SHA512.
424 */
425 #define T_COSE_CRYPTO_HMAC512_TAG_SIZE T_COSE_CRYPTO_SHA512_SIZE
426
427 /**
428 * Max size of the tag output for the HMAC operations.
429 */
430 #define T_COSE_CRYPTO_HMAC_TAG_MAX_SIZE T_COSE_CRYPTO_SHA512_SIZE
431
432
433 /**
434 * The maximum needed to hold a hash. It is smaller and less stack is used
435 * if the larger hashes are disabled.
436 */
437 #ifndef T_COSE_DISABLE_ES512
438 #define T_COSE_CRYPTO_MAX_HASH_SIZE T_COSE_CRYPTO_SHA512_SIZE
439 #else
440 #ifndef T_COSE_DISABLE_ES384
441 #define T_COSE_CRYPTO_MAX_HASH_SIZE T_COSE_CRYPTO_SHA384_SIZE
442 #else
443 #define T_COSE_CRYPTO_MAX_HASH_SIZE T_COSE_CRYPTO_SHA256_SIZE
444 #endif
445 #endif
446
447
448 /**
449 * \brief Start cryptographic hash. Part of the t_cose crypto
450 * adaptation layer.
451 *
452 * \param[in,out] hash_ctx Pointer to the hash context that
453 * will be initialized.
454 * \param[in] cose_hash_alg_id Algorithm ID that identifies the
455 * hash to use. This is from the
456 * [IANA COSE Registry]
457 * (https://www.iana.org/assignments/cose/cose.xhtml)
458 *
459 * \retval T_COSE_ERR_UNSUPPORTED_HASH
460 * The requested algorithm is unknown or unsupported.
461 *
462 * \retval T_COSE_ERR_HASH_GENERAL_FAIL
463 * Some general failure of the hash function
464 *
465 * \retval T_COSE_SUCCESS
466 * Success.
467 *
468 * This initializes the hash context for the particular algorithm. It
469 * must be called first. A \c hash_ctx can be reused if it is
470 * reinitialized.
471 *
472 * \ref T_COSE_INVALID_ALGORITHM_ID may be passed to this function, in which
473 * case \ref T_COSE_ERR_UNSUPPORTED_HASH must be returned.
474 *
475 * Other errors can be returned and will usually be propagated up, but hashes
476 * generally don't fail so it is suggested not to bother (and to reduce
477 * object code size for mapping errors).
478 */
479 enum t_cose_err_t
480 t_cose_crypto_hash_start(struct t_cose_crypto_hash *hash_ctx,
481 int32_t cose_hash_alg_id);
482
483
484 /**
485 * \brief Feed data into a cryptographic hash. Part of the t_cose
486 * crypto adaptation layer.
487 *
488 * \param[in,out] hash_ctx Pointer to the hash context in which
489 * accumulate the hash.
490 * \param[in] data_to_hash Pointer and length of data to feed into
491 * hash. The pointer may by \c NULL in which
492 * case no hashing is performed.
493 *
494 * There is no return value. If an error occurs it is remembered in \c
495 * hash_ctx and returned when t_cose_crypto_hash_finish() is called.
496 * Once in the error state, this function may be called, but it will
497 * not do anything.
498 *
499 * This function can be called with \c data_to_hash.ptr NULL and it
500 * will pretend to hash. This allows the same code that is used to
501 * produce the real hash to be used to return a length of the would-be
502 * hash for encoded data structure size calculations.
503 */
504 void t_cose_crypto_hash_update(struct t_cose_crypto_hash *hash_ctx,
505 struct q_useful_buf_c data_to_hash);
506
507
508 /**
509 * \brief Finish a cryptographic hash. Part of the t_cose crypto
510 * adaptation layer.
511 *
512 * \param[in,out] hash_ctx Pointer to the hash context.
513 * \param[in] buffer_to_hold_result Pointer and length into which
514 * the resulting hash is put.
515 * \param[out] hash_result Pointer and length of the
516 * resulting hash.
517 *
518 * \retval T_COSE_ERR_HASH_GENERAL_FAIL
519 * Some general failure of the hash function.
520 * \retval T_COSE_ERR_HASH_BUFFER_SIZE
521 * The size of the buffer to hold the hash result was
522 * too small.
523 * \retval T_COSE_SUCCESS
524 * Success.
525 *
526 * Call this to complete the hashing operation. If the everything
527 * completed correctly, the resulting hash is returned. Note that any
528 * errors that occurred during t_cose_crypto_hash_update() are
529 * returned here.
530 *
531 * See \ref useful_buf_use for details on how \c q_useful_buf and
532 * \c q_useful_buf_c are used to return the hash.
533 *
534 * Other errors can be returned and will usually be propagated up, but
535 * hashes generally don't fail so it is suggested not to bother (and
536 * to reduce object code size for mapping errors).
537 */
538 enum t_cose_err_t
539 t_cose_crypto_hash_finish(struct t_cose_crypto_hash *hash_ctx,
540 struct q_useful_buf buffer_to_hold_result,
541 struct q_useful_buf_c *hash_result);
542
543 /**
544 * \brief Set up a multipart HMAC calculation operation
545 *
546 * \param[in,out] hmac_ctx Pointer to the HMAC context.
547 * \param[in] signing_key The key for the HMAC operation
548 * \param[in] cose_alg_id The algorithm used in HMAC.
549 *
550 * \retval T_COSE_SUCCESS
551 * Tag calculation succeeds.
552 * \retval T_COSE_ERR_UNSUPPORTED_SIGNING_ALG
553 * The algorithm is unsupported.
554 * \retval T_COSE_ERR_INVALID_ARGUMENT
555 * Invalid arguments.
556 * \retval T_COSE_ERR_FAIL
557 * Some general failure of the HMAC function.
558 */
559 enum t_cose_err_t
560 t_cose_crypto_hmac_sign_setup(struct t_cose_crypto_hmac *hmac_ctx,
561 struct t_cose_key signing_key,
562 const int32_t cose_alg_id);
563
564 /**
565 * \brief Add a message fragment to a multipart HMAC operation
566 *
567 * \param[in,out] hmac_ctx Pointer to the HMAC context.
568 * \param[in] payload Pointer and length of payload
569 *
570 * \retval T_COSE_SUCCESS
571 * Tag calculation succeeds.
572 * \retval T_COSE_ERR_SIG_BUFFER_SIZE
573 * The size of the buffer to hold the tag result was too small.
574 * \retval T_COSE_ERR_INVALID_ARGUMENT
575 * Invalid arguments.
576 * \retval T_COSE_ERR_FAIL
577 * Some general failure of the HMAC function.
578 */
579 enum t_cose_err_t
580 t_cose_crypto_hmac_update(struct t_cose_crypto_hmac *hmac_ctx,
581 struct q_useful_buf_c payload);
582
583 /**
584 * \brief Finish the calculation of the HMAC of a message.
585 *
586 * \param[in,out] hmac_ctx Pointer to the HMAC context.
587 * \param[in] tag_buf Pointer and length into which
588 * the resulting tag is put.
589 * \param[out] tag Pointer and length of the
590 * resulting tag.
591 *
592 * \retval T_COSE_SUCCESS
593 * Tag calculation succeeds.
594 * \retval T_COSE_ERR_SIG_BUFFER_SIZE
595 * The size of the buffer to hold the tag result was too small.
596 * \retval T_COSE_ERR_INVALID_ARGUMENT
597 * Invalid arguments.
598 * \retval T_COSE_ERR_FAIL
599 * Some general failure of the HMAC function.
600 */
601 enum t_cose_err_t
602 t_cose_crypto_hmac_sign_finish(struct t_cose_crypto_hmac *hmac_ctx,
603 struct q_useful_buf tag_buf,
604 struct q_useful_buf_c *tag);
605
606 /**
607 * \brief Set up a multipart HMAC verification operation
608 *
609 * \param[in,out] hmac_ctx Pointer to the HMAC context.
610 * \param[in] cose_alg_id The algorithm used in HMAC.
611 * \param[in] verify_key Key for HMAC verification
612 *
613 * \retval T_COSE_SUCCESS
614 * Operation succeeds.
615 * \retval T_COSE_ERR_UNSUPPORTED_SIGNING_ALG
616 * The algorithm is unsupported.
617 * \retval T_COSE_ERR_INVALID_ARGUMENT
618 * Invalid arguments.
619 * \retval T_COSE_ERR_FAIL
620 * Some general failure of the HMAC function.
621 */
622 enum t_cose_err_t
623 t_cose_crypto_hmac_verify_setup(struct t_cose_crypto_hmac *hmac_ctx,
624 const int cose_alg_id,
625 struct t_cose_key verify_key);
626
627 /**
628 * \brief Finish the verification of the HMAC of a message.
629 *
630 * \param[in,out] hmac_ctx Pointer to the HMAC context.
631 * \param[in] tag Pointer and length of the tag.
632 *
633 * \retval T_COSE_SUCCESS
634 * Tag calculation succeeds.
635 * \retval T_COSE_ERR_INVALID_ARGUMENT
636 * Invalid arguments.
637 * \retval T_COSE_ERR_FAIL
638 * Some general failure of the HMAC function.
639 * \retval PSA_ERROR_INVALID_SIGNATURE
640 * HMAC verification failed.
641 */
642 enum t_cose_err_t
643 t_cose_crypto_hmac_verify_finish(struct t_cose_crypto_hmac *hmac_ctx,
644 struct q_useful_buf_c tag);
645
646 /**
647 * \brief Indicate whether a COSE algorithm is ECDSA or not.
648 *
649 * \param[in] cose_algorithm_id The algorithm ID to check.
650 *
651 * \returns This returns \c true if the algorithm is ECDSA and \c false if not.
652 *
653 * This is a convenience function to check whether a given
654 * integer COSE algorithm ID uses the ECDSA signing algorithm
655 * or not.
656 *
657 * (As other types of signing algorithms are added, RSA for example,
658 * a similar function can be added for them.)
659 */
660 static bool t_cose_algorithm_is_ecdsa(int32_t cose_algorithm_id);
661
662
663
664
665 /*
666 * Inline implementations. See documentation above.
667 */
668
669 /**
670 * \brief Look for an integer in a zero-terminated list of integers.
671 *
672 * \param[in] cose_algorithm_id The algorithm ID to check.
673 * \param[in] list zero-terminated list of algorithm IDs.
674 *
675 * \returns This returns \c true if an integer is in the list, \c false if not.
676 *
677 * Used to implement t_cose_algorithm_is_ecdsa() and in the future
678 * _is_rsa() and such.
679 *
680 * Typically used once in the crypto adaptation layer, so defining it
681 * inline rather than in a .c file is OK and saves creating a whole
682 * new .c file just for this.
683 */
684 static inline bool
t_cose_check_list(int32_t cose_algorithm_id,const int32_t * list)685 t_cose_check_list(int32_t cose_algorithm_id, const int32_t *list)
686 {
687 while(*list) {
688 if(*list == cose_algorithm_id) {
689 return true;
690 }
691 list++;
692 }
693
694 return false;
695 }
696
t_cose_algorithm_is_ecdsa(int32_t cose_algorithm_id)697 static inline bool t_cose_algorithm_is_ecdsa(int32_t cose_algorithm_id)
698 {
699 /* The simple list of COSE alg IDs that use ECDSA */
700 static const int32_t ecdsa_list[] = {
701 COSE_ALGORITHM_ES256,
702 #ifndef T_COSE_DISABLE_ES384
703 COSE_ALGORITHM_ES384,
704 #endif
705 #ifndef T_COSE_DISABLE_ES512
706 COSE_ALGORITHM_ES512,
707 #endif
708 0}; /* 0 is a reserved COSE alg ID ans will never be used */
709
710 return t_cose_check_list(cose_algorithm_id, ecdsa_list);
711 }
712
t_cose_tag_size(int32_t cose_alg_id)713 static inline size_t t_cose_tag_size(int32_t cose_alg_id)
714 {
715 switch(cose_alg_id) {
716 case T_COSE_ALGORITHM_HMAC256:
717 return T_COSE_CRYPTO_HMAC256_TAG_SIZE;
718 case T_COSE_ALGORITHM_HMAC384:
719 return T_COSE_CRYPTO_HMAC384_TAG_SIZE;
720 case T_COSE_ALGORITHM_HMAC512:
721 return T_COSE_CRYPTO_HMAC512_TAG_SIZE;
722 default:
723 return INT32_MAX;
724 }
725 }
726
727 #ifndef T_COSE_DISABLE_SHORT_CIRCUIT_SIGN
728 /*
729 * Get the COSE Hash algorithm ID from the corresponding
730 * COSE HMAC algorithm ID
731 */
t_cose_hmac_to_hash_alg_id(int32_t cose_hamc_alg_id)732 static inline int32_t t_cose_hmac_to_hash_alg_id(int32_t cose_hamc_alg_id)
733 {
734 switch(cose_hamc_alg_id) {
735 case T_COSE_ALGORITHM_HMAC256:
736 return COSE_ALGORITHM_SHA_256;
737
738 default:
739 return INT32_MAX;
740 }
741 }
742 #endif
743
744 #ifdef __cplusplus
745 }
746 #endif
747
748 #endif /* __T_COSE_CRYPTO_H__ */
749