1 /*
2  * attest_token_decode.h
3  *
4  * Copyright (c) 2019, Laurence Lundblade.
5  * Copyright (c) 2020-2022, 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 #ifndef __ATTEST_TOKEN_DECODE_H__
12 #define __ATTEST_TOKEN_DECODE_H__
13 
14 #include "q_useful_buf.h"
15 #include <stdbool.h>
16 #include "attest_token.h"
17 #include "tfm_attest_iat_defs.h"
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 /**
24  * \file attest_token_decode.h
25  *
26  * \brief Attestation Token Decoding Interface
27  *
28  * The context and functions here are used to decode an attestation
29  * token as follows:
30  *
31  * -# Create a \ref attest_token_decode_context, most likely as a
32  *    stack variable.
33  *
34  * -# Initialize it by calling attest_token_decode_init()
35  *
36  * -# Tell it which public key to use for verification using
37  *    attest_token_decode_set_cose_pub_key() or
38  *    attest_token_decode_set_pub_key_select().
39  *
40  * -# Pass the token in and validate it by calling
41  *    attest_token_decode_validate_token().
42  *
43  * -# Call the various \c attest_token_get_xxx() methods in any
44  * order. The strings returned by the these functions will point into
45  * the token passed to attest_token_decode_validate_token(). A copy is
46  * NOT made.
47  *
48  * The entire token is validated and decoded in place.  No copies are
49  * made internally. The data returned by the \c attest_token_get_xxx()
50  * methods is not a copy so the lifetime of the \c struct \c
51  * q_useful_buf_c containing the token must be maintained.
52  *
53  * Aside from the cryptographic functions, this allocates no
54  * memory. It works entirely off the stack. It makes use of t_cose to
55  * validate the signature and QCBOR for CBOR decoding.
56  *
57  * This decoder only works with labels (keys) that are integers even
58  * though labels can be any data type in CBOR. The presumption is that
59  * this is for small embedded use cases where space is a premium and
60  * only integer labels will be used.
61  *
62  * All claims are optional in tokens. This decoder will ignore all
63  * CBOR encoded data that it doesn't understand without error.
64  *
65  * This interface is primarily for the claims defined by Arm for
66  * TF-M. It includes only some of the claims from the EAT IETF draft,
67  * https://tools.ietf.org/html/draft-mandyam-eat-01.
68  *
69  * The claims are not described in detail here. That is left to the
70  * definition documents and eventually an IETF standard.
71  *
72  * If a method to get the claim you are interested in doesn't exist,
73  * there are several methods where you can give the label (the key)
74  * for the claim and have it returned. This only works for simple
75  * claims (strings and integers).
76  *
77  * The entire payload can be retrieved unparsed. Then you can use a
78  * separate CBOR parser to decode the claims out of it.  Future work may
79  * include more general facilities for handling claims with complex
80  * structures made up of maps and arrays.
81  *
82  * This should not yet be considered a real commercial
83  * implementation of token decoding. It is
84  * close, but not there yet. It's purpose is to test
85  * token encoding. The main thing this needs to become
86  * a real commercial implementation is code that
87  * tests this. It is a parser / decoder, so a
88  * proper test involves a lot of hostile input.
89  */
90 
91 
92 /**
93  * The context for decoding an attestation token. The caller of must
94  * create one of these and pass it to the functions here. It is small
95  * enough that it can go on the stack. It is most of the memory needed
96  * to create a token except the output buffer and any memory
97  * requirements for the cryptographic operations.
98  *
99  * The structure is opaque for the caller.
100  *
101  */
102 struct attest_token_decode_context {
103     /* PRIVATE DATA STRUCTURE. USE ACCESSOR FUNCTIONS. */
104     struct q_useful_buf_c   payload;
105     uint32_t                options;
106     enum attest_token_err_t last_error;
107     /* FIXME: This will have to expand when the pub key
108        handling functions are implemented */
109 };
110 
111 
112 /**
113  * \brief Initialize token decoder.
114  *
115  * \param[in] me      The token decoder context to be initialized.
116  * \param[in] options Decoding options.
117  *
118  * Must be called on a \ref attest_token_decode_context before
119  * use. An instance of \ref attest_token_decode_context can
120  * be used again by calling this on it again.
121  **/
122 void attest_token_decode_init(struct attest_token_decode_context *me,
123                               uint32_t options);
124 
125 
126 
127 /**
128  * \brief Set specific public key to use for verification.
129  *
130  * \param[in] me           The token decoder context to configure.
131  * \param[in] cose_pub_key A CBOR-encoded \c COSE_Key containing
132  *                         the public key to use for signature
133  *                         verification.
134  *
135  * \return An error from \ref attest_token_err_t.
136  *
137  * (This has not been implemented yet)
138  *
139  * The key type must work with the signing algorithm in the token
140  * being verified.
141  *
142  * The \c kid in the \c COSE_Key must match the one in the token.
143  *
144  * If there is no kid in the \c COSE_Key it will be used no matter
145  * what kid is indicated in the token.
146  *
147  * Once set, a key can be used for multiple verifications.
148  *
149  * Calling this again will replace the previous key that was
150  * configured. It will also replace the key set by
151  * attest_token_decode_set_pub_key_select().
152  */
153 enum attest_token_err_t
154 attest_token_decode_set_cose_pub_key(struct attest_token_decode_context *me,
155                                      struct q_useful_buf cose_pub_key);
156 
157 
158 /**
159  * \brief Set specific public key to use for verification.
160  *
161  * \param[in] me         The token decoder context to configure.
162  * \param[in] key_select Selects the key to verify.
163  *
164  * \return An error from \ref attest_token_err_t.
165  *
166  * (This has not been implemented yet)
167  *
168  * The key type must work with the signing algorithm in the token
169  * being verified.
170  *
171  * The meaning of key_select depends on the platform this is running
172  * on.
173  *
174  * Once set, a key can be used for multiple verifications.
175  *
176  * Calling this again will replace the previous key that was
177  * configured. It will also replace the key set by
178  * attest_token_decode_set_cose_pub_key().
179  *
180  */
181 enum attest_token_err_t
182 attest_token_decode_set_pub_key_select(struct attest_token_decode_context *me,
183                                        int32_t key_select);
184 
185 
186 /**
187  * \brief Set the token to work on and validate its signature.
188  *
189  * \param[in] me     The token decoder context to validate with.
190  * \param[in] token  The CBOR-encoded token to validate and decode.
191  *
192  * \return An error from \ref attest_token_err_t.
193  *
194  * The signature on the token is validated. If it is successful the
195  * token and its payload is remembered in the \ref
196  * attest_token_decode_context \c me so the \c
197  * attest_token_decode_get_xxx() functions can be called to get the
198  * various claims out of it.
199  *
200  * Generally, a public key has to be configured for this to work. It
201  * can however validate short-circuit signatures even if one is not
202  * set.
203  *
204  * The code for any error that occurs during validation is remembered
205  * in decode context. The \c attest_token_decode_get_xxx() functions
206  * can be called and they will just return this error. The \c
207  * attest_token_decode_get_xxx() functions will generally return 0 or
208  * \c NULL if the token is in error.
209  *
210  * It is thus possible to call attest_token_decode_validate_token()
211  * and all the \c attest_token_decode_get_xxx() functions to parse the
212  * token and ignore the error codes as long as
213  * attest_token_decode_get_error() is called before any of the claim
214  * data returned is used.
215  */
216 enum attest_token_err_t
217 attest_token_decode_validate_token(struct attest_token_decode_context *me,
218                                    struct q_useful_buf_c token);
219 
220 
221 /**
222  * \brief Get the last decode error.
223  *
224  * \param[in] me The token decoder context.
225  *
226  * \return An error from \ref attest_token_err_t.
227  */
228 static enum attest_token_err_t
229 attest_token_decode_get_error(struct attest_token_decode_context *me);
230 
231 
232 /**
233  * \brief Get undecoded CBOR payload from the token.
234  *
235  * \param[in]  me      The token decoder context.
236  * \param[out] payload The returned, verified token payload.
237  *
238  * \return An error from \ref attest_token_err_t.
239  *
240  * This will return an error if the signature over the payload did not
241  * validate.
242  *
243  * This allows the caller to parse the payload with any CBOR decoder
244  * they wish to use. It also an "escape hatch" to get to claims in the
245  * token not supported by decoding in this implementation, for example
246  * claims that have non-integer labels.
247  */
248 enum attest_token_err_t
249 attest_token_decode_get_payload(struct attest_token_decode_context *me,
250                                 struct q_useful_buf_c *payload);
251 
252 
253 /** Label for bits in \c item_flags in \ref
254     attest_token_iat_simple_t */
255 enum attest_token_item_index_t {
256     NONCE_FLAG =                0,
257     INSTANCE_ID_FLAG  =         1,
258     BOOT_SEED_FLAG =            2,
259     CERT_REF_FLAG =             3,
260     IMPLEMENTATION_ID_FLAG =    4,
261     CLIENT_ID_FLAG =            5,
262     SECURITY_LIFECYCLE_FLAG =   6,
263     PROFILE_DEFINITION_FLAG =   7,
264     VERIFICATION_SERVICE_FLAG = 8,
265     PLAT_HASH_ALGO_ID =         9,
266     PLAT_CONFIG =              10,
267     NUMBER_OF_ITEMS
268 };
269 
270 
271 /**
272  * This structure holds the simple-to-get fields from the
273  * token that can be bundled into one structure.
274  *
275  * This is 9 * 8 + 12 = 84 bytes on a 32-bit machine.
276  */
277 struct attest_token_iat_simple_t {
278     struct q_useful_buf_c nonce; /* byte string */
279     struct q_useful_buf_c instance_id; /* byte string */
280     struct q_useful_buf_c boot_seed; /* byte string */
281     struct q_useful_buf_c cert_ref; /* text string */
282     struct q_useful_buf_c implementation_id; /* byte string */
283     uint32_t              security_lifecycle;
284     int32_t               client_id;
285     struct q_useful_buf_c profile_definition; /* text string */
286     struct q_useful_buf_c verif_serv; /* text string */
287     struct q_useful_buf_c hash_algo_id; /* text string */
288     struct q_useful_buf_c plat_config; /* byte string */
289     uint32_t              item_flags;
290 };
291 
292 
293 /**
294  * Macro to determine if data item is present in \ref
295  * attest_token_iat_simple_t
296  */
297  #define IS_ITEM_FLAG_SET(item_index, item_flags) \
298      (((0x01U << (item_index))) & (item_flags))
299 
300 
301 /**
302  * \brief Batch fetch of all simple data items in a token.
303  *
304  * \param[in]  me     The token decoder context.
305  * \param[out] items  Structure into which all found items are placed.
306  *
307  * \return An error from \ref attest_token_err_t.
308  *
309  * \retval ATTEST_TOKEN_ERR_SUCCESS
310  *         Indicates that the token was successfully searched. It
311  *         could mean that all the data item were found, only
312  *         some were found, or even none were found.
313  *
314  * This searches the token for the simple unstructured data items all
315  * at once. It can be a little more efficient than getting them one by
316  * one.
317  *
318  * Use \ref IS_ITEM_FLAG_SET on \c item_flags in \c
319  * attest_token_iat_simple_t to determine if the data item was found or
320  * not and whether the corresponding member in the structure is valid.
321  */
322 enum attest_token_err_t
323 attest_token_decode_get_iat_simple(struct attest_token_decode_context *me,
324                                    struct attest_token_iat_simple_t *items);
325 
326 
327 /**
328  \brief Get the nonce out of the token.
329  *
330  * \param[in]  me     The token decoder context.
331  * \param[out] nonce  Returned pointer and length of nonce.
332  *
333  * \return An error from \ref attest_token_err_t.
334  *
335  * The nonce is a byte string. The nonce is also known as the
336  * challenge.
337  */
338 static enum attest_token_err_t
339 attest_token_decode_get_nonce(struct attest_token_decode_context *me,
340                               struct q_useful_buf_c *nonce);
341 
342 
343 /**
344  * \brief Get the boot seed out of the token.
345  *
346  * \param[in]  me         The token decoder context.
347  * \param[out] boot_seed  Returned pointer and length of boot_seed.
348  *
349  * \return An error from \ref attest_token_err_t.
350  *
351  * The boot seed is a byte string.
352  */
353 static enum attest_token_err_t
354 attest_token_decode_get_boot_seed(struct attest_token_decode_context *me,
355                                   struct q_useful_buf_c *boot_seed);
356 
357 
358 /**
359  * \brief Get the instance id out of the token.
360  *
361  * \param[in]  me           The token decoder context.
362  * \param[out] instance_id  Returned pointer and length of instance_id.
363  *
364  * \return An error from \ref attest_token_err_t.
365  *
366  * The instance id is a byte string.
367  */
368 static enum attest_token_err_t
369 attest_token_decode_get_instance_id(struct attest_token_decode_context *me,
370                                     struct q_useful_buf_c *instance_id);
371 
372 
373 
374 /**
375  * \brief Get the certification reference out of the token
376  *
377  * \param[in]  me          The token decoder context.
378  * \param[out] cert_ref    Returned pointer and length of \c cert_ref.
379  *
380  * \return An error from \ref attest_token_err_t.
381  *
382  * The certification reference is a UTF-8 text string. It is returned as a
383  * pointer and length. It is NOT \c NULL terminated.
384  */
385 static enum attest_token_err_t
386 attest_token_decode_get_cert_ref(struct attest_token_decode_context *me,
387                                 struct q_useful_buf_c *cert_ref);
388 
389 
390 /**
391  * \brief Get the implementation ID out of the token.
392  *
393  * \param[in]  me                 The token decoder context.
394  * \param[out] implementation_id  Returned pointer and length of
395  *                                implementation_id.
396  *
397  * \return An error from \ref attest_token_err_t.
398  *
399  * The implementation ID is a byte string.
400  */
401 static enum attest_token_err_t
402 attest_token_decode_get_implementation_id(struct attest_token_decode_context*me,
403                                       struct q_useful_buf_c *implementation_id);
404 
405 
406 /**
407  * \brief Get the verification service identification out of the token.
408  *
409  * \param[in]  me           The token decoder context.
410  * \param[out] verif_serv   Returned pointer and length of verif_serv.
411  *
412  * \return An error from \ref attest_token_err_t.
413  *
414  * This is also known as the Verification Service Indicator.
415  *
416  * The \c verif_serv is a UTF-8 text string. It is returned as a
417  * pointer* and length. It is NOT \c NULL terminated.
418  */
419 static enum attest_token_err_t
420 attest_token_decode_get_verif_serv(struct attest_token_decode_context *me,
421                                     struct q_useful_buf_c *verif_serv);
422 
423 
424 /**
425  * \brief Get the profile definition out of the token.
426  *
427  * \param[in]  me                  The token decoder context.
428  * \param[out] profile_definition  Returned pointer and length of
429  *                                 profile_definition.
430  *
431  * \return An error from \ref attest_token_err_t.
432  *
433  * The profile definition is a UTF-8 text string. It is returned as a
434  * pointer and length. It is NOT \c NULL terminated.
435  */
436 static enum attest_token_err_t
437 attest_token_decode_get_profile_definition(
438                                     struct attest_token_decode_context *me,
439                                     struct q_useful_buf_c *profile_definition);
440 
441 
442 /**
443  * \brief Get the client ID out of the token.
444  *
445  * \param[in]  me         The token decoder context.
446  * \param[out] client_id  Returned pointer and length of client_id.
447  *
448  * \return An error from \ref attest_token_err_t.
449  *
450  * \retval ATTEST_TOKEN_ERR_INTEGER_VALUE
451  *         If integer is larger or smaller than will fit
452  *         in an \c int32_t.
453  *
454  * Also called the caller ID.
455  */
456 static enum attest_token_err_t
457 attest_token_decode_get_client_id(struct attest_token_decode_context *me,
458                                   int32_t *client_id);
459 
460 
461 /**
462  * \brief Get the security lifecycle out of the token.
463  *
464  * \param[in]  me         The token decoder context.
465  * \param[out] lifecycle  Returned pointer and length of lifecycle.
466  *
467  * \return An error from \ref attest_token_err_t.
468  *
469  * \retval ATTEST_TOKEN_ERR_INTEGER_VALUE
470  *         If integer is larger
471  *         or smaller than will fit in a \c uint32_t.
472  */
473 static enum attest_token_err_t
474 attest_token_decode_get_security_lifecycle(
475     struct attest_token_decode_context *me,
476     uint32_t *lifecycle);
477 
478 
479 /**
480  * Use \ref IS_ITEM_FLAG_SET macro with these values and \c
481  * attest_token_sw_component_t.item_flags to find out if the
482  * data item is filled in in the attest_token_sw_component_t structure.
483  *
484  * Items that are of type \c struct \c q_useful_buf_c will also be \c
485  * NULL_Q_USEFUL_BUF_C when they are absent.
486  */
487 enum attest_token_sw_index_t {
488     SW_MEASUREMENT_TYPE_FLAG = 0,
489     SW_MEASURMENT_VAL_FLAG = 1,
490     /* Reserved: 2 */
491     SW_VERSION_FLAG = 3,
492     SW_SIGNER_ID_FLAG = 5,
493     SW_MEASUREMENT_DESC_FLAG = 6,
494 };
495 
496 /**
497  * Structure to hold one SW component
498  *
499  * This is about 50 bytes on a 32-bit machine and 100 on a 64-bit
500  * machine.
501  *
502  * There will probably be an expanded version of this when more is
503  * added to describe a SW component.
504  */
505 struct attest_token_sw_component_t {
506     struct q_useful_buf_c measurement_type; /* text string */
507     struct q_useful_buf_c measurement_val; /* binary string */
508     struct q_useful_buf_c version; /* text string */
509     struct q_useful_buf_c signer_id; /* binary string */
510     struct q_useful_buf_c measurement_desc; /* text string */
511     uint32_t              item_flags;
512 };
513 
514 
515 /**
516  * \brief Get the number of SW components in the token
517  *
518  * \param[in]  me                The token decoder context.
519  * \param[out] num_sw_components The number of SW components in the
520  *                               token.
521  *
522  * \return An error from \ref attest_token_err_t.
523  *
524  * If there are explicitly no SW components, this will return successfully
525  * and the \c num_sw_components will be zero.
526  *
527  * Per Arm's IAT specification the only two ways this will succeed
528  * are.
529  * - The SW components array is present and has one or more (not zero)
530  * SW components and the "no SW Components" claim is absent.
531  * - The "no SW Components" integer claim is present, its value
532  * is 1, and the SW Components array is absent.
533  */
534 enum attest_token_err_t
535 attest_token_get_num_sw_components(struct attest_token_decode_context *me,
536                                    uint32_t *num_sw_components);
537 
538 
539 /**
540  * \brief Get the nth SW component.
541  *
542  * \param[in] me              The token decoder context.
543  * \param[in] requested_index Index, from 0 to num_sw_components,
544  *                            of request component.
545  * \param[out] sw_components  Place to return the details of the
546  *                            SW component
547  *
548  * \retval ATTEST_TOKEN_ERR_NOT_FOUND
549  *         There were not \c requested_index in the token.
550  *
551  * \retval ATTEST_TOKEN_ERR_CBOR_TYPE
552  *         The claim labeled to contain SW components is not an array.
553  */
554 enum attest_token_err_t
555 attest_token_get_sw_component(struct attest_token_decode_context *me,
556                        uint32_t requested_index,
557                        struct attest_token_sw_component_t *sw_components);
558 
559 
560 /**
561  *
562  * \brief Get a top-level claim, by integer label that is a byte
563  * string.
564  *
565  * \param[in]  me    The token decoder context.
566  * \param[in]  label The integer label identifying the claim.
567  * \param[out] claim The byte string or \c NULL_Q_USEFUL_BUF_C.
568  *
569  * \return An error from \ref attest_token_err_t.
570  *
571  * \retval ATTEST_TOKEN_ERR_CBOR_STRUCTURE
572  *         General structure of the token is incorrect, for example
573  *         the top level is not a map or some map wasn't closed.
574  *
575  * \retval ATTEST_TOKEN_ERR_CBOR_NOT_WELL_FORMED
576  *         CBOR syntax is wrong and it is not decodable.
577  *
578  * \retval ATTEST_TOKEN_ERR_CBOR_TYPE
579  *         Returned if the claim is not a byte string.
580  *
581  * \retval ATTEST_TOKEN_ERR_NOT_FOUND
582  *         Data item for \c label was not found in token.
583  *
584  * If an error occurs, the claim will be set to \c NULL_Q_USEFUL_BUF_C
585  * and the error state inside \c attest_token_decode_context will
586  * be set.
587  */
588 enum attest_token_err_t
589 attest_token_decode_get_bstr(struct attest_token_decode_context *me,
590                              int32_t label,
591                              struct q_useful_buf_c *claim);
592 
593 
594 /**
595  * \brief Get a top-level claim, by integer label that is a text
596  * string.
597  *
598  * \param[in] me     The token decoder context.
599  * \param[in] label  The integer label identifying the claim.
600  * \param[out] claim The byte string or \c NULL_Q_USEFUL_BUF_C.
601  *
602  * \return An error from \ref attest_token_err_t.
603  *
604  * \retval ATTEST_TOKEN_ERR_CBOR_STRUCTURE
605  *         General structure of the token is incorrect, for example
606  *         the top level is not a map or some map wasn't closed.
607  *
608  * \retval ATTEST_TOKEN_ERR_CBOR_NOT_WELL_FORMED
609  *         CBOR syntax is wrong and it is not decodable.
610  *
611  * \retval ATTEST_TOKEN_ERR_CBOR_TYPE
612  *         Returned if the claim is not a byte string.
613  *
614  * \retval ATTEST_TOKEN_ERR_NOT_FOUND
615  *         Data item for \c label was not found in token.
616  *
617  * Even though this is a text string, it is not NULL-terminated.
618  *
619  * If an error occurs, the claim will be set to \c NULL_Q_USEFUL_BUF_C
620  * and the error state inside \c attest_token_decode_context will
621  * be set.
622  */
623 enum attest_token_err_t
624 attest_token_decode_get_tstr(struct attest_token_decode_context *me,
625                              int32_t label,
626                              struct q_useful_buf_c *claim);
627 
628 
629 
630 /**
631  * \brief Get a top-level claim by integer label who's value is a
632  * signed integer
633  *
634  * \param[in]  me    The token decoder context.
635  * \param[in]  label The integer label identifying the claim.
636  * \param[out] claim The signed integer or 0.
637  *
638  * \return An error from \ref attest_token_err_t.
639  *
640  * \retval ATTEST_TOKEN_ERR_CBOR_STRUCTURE
641  *         General structure of the token is incorrect, for example
642  *         the top level is not a map or some map wasn't closed.
643  *
644  * \retval ATTEST_TOKEN_ERR_CBOR_NOT_WELL_FORMED
645  *         CBOR syntax is wrong and it is not decodable.
646  *
647  * \retval ATTEST_TOKEN_ERR_CBOR_TYPE
648  *         Returned if the claim is not a byte string.
649  *
650  * \retval ATTEST_TOKEN_ERR_NOT_FOUND
651  *         Data item for \c label was not found in token.
652  *
653  * \retval ATTEST_TOKEN_ERR_INTEGER_VALUE
654  *         Returned if the integer value is larger
655  *         than \c INT64_MAX.
656  *
657  * This will succeed if the CBOR type of the claim is either a
658  * positive or negative integer as long as the value is between \c
659  * INT64_MIN and \c INT64_MAX.
660  *
661  * See also attest_token_decode_get_uint().
662  *
663  * If an error occurs the value 0 will be returned and the error
664  * inside the \c attest_token_decode_context will be set.
665  */
666 enum attest_token_err_t
667 attest_token_decode_get_int(struct attest_token_decode_context *me,
668                             int32_t label,
669                             int64_t *claim);
670 
671 
672 /**
673  * \brief Get a top-level claim by integer label who's value is an
674  * unsigned integer
675  *
676  * \param[in]  me    The token decoder context.
677  * \param[in]  label The integer label identifying the claim.
678  * \param[out] claim The unsigned integer or 0.
679  *
680  * \return An error from \ref attest_token_err_t.
681  *
682  * \retval ATTEST_TOKEN_ERR_CBOR_STRUCTURE
683  *         General structure of the token is incorrect, for example
684  *         the top level is not a map or some map wasn't closed.
685  *
686  * \retval ATTEST_TOKEN_ERR_CBOR_NOT_WELL_FORMED
687  *         CBOR syntax is wrong and it is not decodable.
688  *
689  * \retval ATTEST_TOKEN_ERR_CBOR_TYPE
690  *         Returned if the claim is not a byte string.
691  *
692  * \retval ATTEST_TOKEN_ERR_NOT_FOUND
693  *         Data item for \c label was not found in token.
694  *
695  * \retval ATTEST_TOKEN_ERR_INTEGER_VALUE
696  *         Returned if the integer value is negative.
697  *
698  * This will succeed if the CBOR type of the claim is either a
699  * positive or negative integer as long as the value is between 0 and
700  * \c MAX_UINT64.
701  *
702  * See also attest_token_decode_get_int().
703  *
704  *  If an error occurs the value 0 will be returned and the error
705  *  inside the \c attest_token_decode_context will be set.
706  */
707 enum attest_token_err_t
708 attest_token_decode_get_uint(struct attest_token_decode_context *me,
709                              int32_t label,
710                              uint64_t *claim);
711 
712 
713 
714 
715 /* ====================================================================
716  *   Inline Implementations
717  *   Typically, these are small and called only once.
718  * ==================================================================== */
719 
720 static inline enum attest_token_err_t
attest_token_decode_get_error(struct attest_token_decode_context * me)721 attest_token_decode_get_error(struct attest_token_decode_context *me)
722 {
723     return me->last_error;
724 }
725 
726 
727 static inline enum attest_token_err_t
attest_token_decode_get_nonce(struct attest_token_decode_context * me,struct q_useful_buf_c * nonce)728 attest_token_decode_get_nonce(struct attest_token_decode_context *me,
729                               struct q_useful_buf_c *nonce)
730 {
731     return attest_token_decode_get_bstr(me,
732                                         IAT_NONCE,
733                                         nonce);
734 }
735 
736 
737 static inline enum attest_token_err_t
attest_token_decode_get_instance_id(struct attest_token_decode_context * me,struct q_useful_buf_c * instance_id)738 attest_token_decode_get_instance_id(struct attest_token_decode_context *me,
739                                     struct q_useful_buf_c *instance_id)
740 {
741     return attest_token_decode_get_bstr(me, IAT_INSTANCE_ID, instance_id);
742 }
743 
744 
745 static inline enum attest_token_err_t
attest_token_decode_get_boot_seed(struct attest_token_decode_context * me,struct q_useful_buf_c * boot_seed)746 attest_token_decode_get_boot_seed(struct attest_token_decode_context *me,
747                                   struct q_useful_buf_c *boot_seed)
748 {
749     return attest_token_decode_get_bstr(me,
750                                         IAT_BOOT_SEED,
751                                         boot_seed);
752 }
753 
754 
755 static inline enum attest_token_err_t
attest_token_decode_get_cert_ref(struct attest_token_decode_context * me,struct q_useful_buf_c * cert_ref)756 attest_token_decode_get_cert_ref(struct attest_token_decode_context *me,
757                                  struct q_useful_buf_c *cert_ref)
758 {
759     return attest_token_decode_get_tstr(me,
760                                         IAT_CERTIFICATION_REFERENCE,
761                                         cert_ref);
762 }
763 
764 
765 static inline enum attest_token_err_t
attest_token_decode_get_implementation_id(struct attest_token_decode_context * me,struct q_useful_buf_c * implementation_id)766 attest_token_decode_get_implementation_id(
767                                        struct attest_token_decode_context *me,
768                                        struct q_useful_buf_c*implementation_id)
769 {
770     return attest_token_decode_get_bstr(me,
771                                         IAT_IMPLEMENTATION_ID,
772                                         implementation_id);
773 }
774 
775 
776 static inline enum attest_token_err_t
attest_token_decode_get_client_id(struct attest_token_decode_context * me,int32_t * caller_id)777 attest_token_decode_get_client_id(struct attest_token_decode_context *me,
778                                   int32_t *caller_id)
779 {
780     enum attest_token_err_t return_value;
781     int64_t caller_id_64;
782 
783     return_value = attest_token_decode_get_int(me,
784                                                IAT_CLIENT_ID,
785                                                &caller_id_64);
786     if(return_value != ATTEST_TOKEN_ERR_SUCCESS) {
787         goto Done;
788     }
789     if(caller_id_64 > INT32_MAX || caller_id_64 < INT32_MIN) {
790         return_value = ATTEST_TOKEN_ERR_INTEGER_VALUE;
791         goto Done;
792     }
793     *caller_id = (int32_t)caller_id_64;
794 
795 Done:
796     return return_value;
797 }
798 
799 
800 static inline enum attest_token_err_t
attest_token_decode_get_security_lifecycle(struct attest_token_decode_context * me,uint32_t * security_lifecycle)801 attest_token_decode_get_security_lifecycle(
802                                  struct attest_token_decode_context *me,
803                                  uint32_t *security_lifecycle)
804 {
805     enum attest_token_err_t return_value;
806     uint64_t security_lifecycle_64;
807 
808     return_value = attest_token_decode_get_uint(me,
809                                        IAT_SECURITY_LIFECYCLE,
810                                        &security_lifecycle_64);
811     if(security_lifecycle_64 > UINT32_MAX) {
812         return_value = ATTEST_TOKEN_ERR_INTEGER_VALUE;
813         goto Done;
814     }
815 
816     *security_lifecycle = (uint32_t)security_lifecycle_64;
817 
818 Done:
819     return return_value;
820 }
821 
822 static inline enum attest_token_err_t
attest_token_decode_get_profile_definition(struct attest_token_decode_context * me,struct q_useful_buf_c * profile_definition)823 attest_token_decode_get_profile_definition(
824                                     struct attest_token_decode_context *me,
825                                     struct q_useful_buf_c *profile_definition)
826 {
827     return attest_token_decode_get_tstr(me,
828                                         IAT_PROFILE_DEFINITION,
829                                         profile_definition);
830 }
831 
832 static inline enum attest_token_err_t
attest_token_decode_get_verif_serv(struct attest_token_decode_context * me,struct q_useful_buf_c * verif_serv)833 attest_token_decode_get_verif_serv(struct attest_token_decode_context*me,
834                                     struct q_useful_buf_c *verif_serv)
835 {
836     return attest_token_decode_get_tstr(me,
837                                         IAT_VERIFICATION_SERVICE,
838                                         verif_serv);
839 }
840 
841 /**
842 
843  \brief Map t_cose errors into attestation token errors
844 
845  \param[in] t_cose_error  The t_cose error to map
846 
847  \return The attestation token error.
848  */
849 static inline enum attest_token_err_t
map_t_cose_errors(enum t_cose_err_t t_cose_error)850 map_t_cose_errors(enum t_cose_err_t t_cose_error)
851 {
852     switch (t_cose_error) {
853     case T_COSE_SUCCESS:
854         return ATTEST_TOKEN_ERR_SUCCESS;
855         break;
856     case T_COSE_ERR_UNSUPPORTED_SIGNING_ALG:
857         return ATTEST_TOKEN_ERR_UNSUPPORTED_SIG_ALG;
858         break;
859     case T_COSE_ERR_UNSUPPORTED_HASH:
860         return ATTEST_TOKEN_ERR_HASH_UNAVAILABLE;
861         break;
862     case T_COSE_ERR_CBOR_NOT_WELL_FORMED:
863         return ATTEST_TOKEN_ERR_CBOR_NOT_WELL_FORMED;
864         break;
865     case T_COSE_ERR_INSUFFICIENT_MEMORY:
866         return ATTEST_TOKEN_ERR_INSUFFICIENT_MEMORY;
867         break;
868     case T_COSE_ERR_TAMPERING_DETECTED:
869         return ATTEST_TOKEN_ERR_TAMPERING_DETECTED;
870         break;
871     case T_COSE_ERR_CBOR_FORMATTING:
872         return ATTEST_TOKEN_ERR_CBOR_FORMATTING;
873         break;
874     case T_COSE_ERR_TOO_SMALL:
875         return ATTEST_TOKEN_ERR_TOO_SMALL;
876         break;
877 
878     case T_COSE_ERR_PARAMETER_CBOR:
879     case T_COSE_ERR_NON_INTEGER_ALG_ID:
880         return ATTEST_TOKEN_ERR_CBOR_STRUCTURE;
881         break;
882 
883     case T_COSE_ERR_SIG_VERIFY:
884     case T_COSE_ERR_SHORT_CIRCUIT_SIG:
885         return ATTEST_TOKEN_ERR_COSE_VALIDATION;
886         break;
887 
888     case T_COSE_ERR_SIGN1_FORMAT:
889         return ATTEST_TOKEN_ERR_COSE_FORMAT;
890         break;
891 
892     case T_COSE_ERR_MAC0_FORMAT:
893         return ATTEST_TOKEN_ERR_COSE_FORMAT;
894         break;
895 
896     case T_COSE_ERR_NO_ALG_ID:
897     case T_COSE_ERR_NO_KID:
898     case T_COSE_ERR_BAD_SHORT_CIRCUIT_KID:
899     case T_COSE_ERR_SIG_STRUCT:
900         return ATTEST_TOKEN_ERR_COSE_FORMAT;
901         break;
902 
903     case T_COSE_ERR_UNKNOWN_KEY:
904     case T_COSE_ERR_WRONG_TYPE_OF_KEY:
905         return ATTEST_TOKEN_ERR_VERIFICATION_KEY;
906         break;
907 
908     case T_COSE_ERR_MAKING_PROTECTED:
909     case T_COSE_ERR_HASH_GENERAL_FAIL:
910     case T_COSE_ERR_HASH_BUFFER_SIZE:
911     case T_COSE_ERR_SIG_BUFFER_SIZE:
912     case T_COSE_ERR_INVALID_ARGUMENT:
913     case T_COSE_ERR_FAIL:
914     case T_COSE_ERR_SIG_FAIL:
915     case T_COSE_ERR_TOO_MANY_PARAMETERS:
916     case T_COSE_ERR_UNKNOWN_CRITICAL_PARAMETER:
917     case T_COSE_ERR_SHORT_CIRCUIT_SIG_DISABLED:
918     case T_COSE_ERR_INCORRECT_KEY_FOR_LIB:
919     case T_COSE_ERR_BAD_CONTENT_TYPE:
920     case T_COSE_ERR_INCORRECTLY_TAGGED:
921     case T_COSE_ERR_EMPTY_KEY:
922     case T_COSE_ERR_DUPLICATE_PARAMETER:
923     case T_COSE_ERR_PARAMETER_NOT_PROTECTED:
924     case T_COSE_ERR_CRIT_PARAMETER:
925     default:
926         return ATTEST_TOKEN_ERR_GENERAL;
927     }
928 }
929 
930 #ifdef __cplusplus
931 }
932 #endif
933 
934 
935 #endif /* __ATTEST_TOKEN_DECODE_H__ */
936