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