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