TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
attest_token_test.c
Go to the documentation of this file.
1 /*
2  * attest_token_test.c
3  *
4  * Copyright (c) 2018-2019, Laurence Lundblade.
5  * Copyright (c) 2020, Arm Limited.
6  *
7  * SPDX-License-Identifier: BSD-3-Clause
8  *
9  * See BSD-3-Clause license in README.md
10  */
11 
12 #include "attest_token_test.h"
13 #include "q_useful_buf.h"
15 #include "attest_token_decode.h"
17 #include "psa/crypto.h"
18 
19 
52 int token_main_alt(uint32_t option_flags,
53  struct q_useful_buf_c nonce,
54  struct q_useful_buf buffer,
55  struct q_useful_buf_c *completed_token)
56 {
57  psa_status_t return_value;
58  size_t token_buf_size;
59  size_t completed_token_size;
60  struct q_useful_buf_c actual_nonce;
61  Q_USEFUL_BUF_MAKE_STACK_UB( actual_nonce_storage, 64);
62 
63  if(nonce.len == 64 && q_useful_buf_is_value(nonce, 0)) {
64  /* Go into special option-packed nonce mode */
65  actual_nonce = q_useful_buf_copy(actual_nonce_storage, nonce);
66  /* Use memcpy as it always works and avoids type punning */
67  memcpy((uint8_t *)actual_nonce_storage.ptr,
68  &option_flags,
69  sizeof(uint32_t));
70  } else {
71  actual_nonce = nonce;
72  }
73 
74  token_buf_size = buffer.len;
75  return_value = psa_initial_attest_get_token(actual_nonce.ptr,
76  actual_nonce.len,
77  buffer.ptr,
78  token_buf_size,
79  &completed_token_size);
80 
81  *completed_token =
82  (struct q_useful_buf_c){buffer.ptr, completed_token_size};
83 
84  if (return_value != PSA_SUCCESS) {
85  return (int)return_value;
86  }
87 
88  return 0;
89 }
90 
91 #ifdef INCLUDE_TEST_CODE /* Remove them from release build */
92 #ifdef SYMMETRIC_INITIAL_ATTESTATION
93 
119 static const uint8_t expected_minimal_token_bytes[] = {
120  0xD1, 0x84, 0x43, 0xA1, 0x01, 0x05, 0xA0, 0x58,
121  0x48, 0xA1, 0x3A, 0x00, 0x01, 0x24, 0xFF, 0x58,
122  0x40, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
123  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130  0x00, 0x58, 0x20, 0x96, 0x68, 0x40, 0xFC, 0x0A,
131  0x60, 0xAE, 0x96, 0x8F, 0x90, 0x6D, 0x70, 0x92,
132  0xE5, 0x7B, 0x20, 0x5D, 0x3B, 0xBE, 0x83, 0xED,
133  0x47, 0xEB, 0xBC, 0x2A, 0xD9, 0xD1, 0xCF, 0xB4,
134  0x1C, 0x87, 0xF3
135 };
136 #else /* SYMMETRIC_INITIAL_ATTESTATION */
137 
165 static const uint8_t expected_minimal_token_bytes[] = {
166  0xD2, 0x84, 0x43, 0xA1, 0x01, 0x26, 0xA1, 0x04,
167  0x58, 0x20, 0xEF, 0x95, 0x4B, 0x4B, 0xD9, 0xBD,
168  0xF6, 0x70, 0xD0, 0x33, 0x60, 0x82, 0xF5, 0xEF,
169  0x15, 0x2A, 0xF8, 0xF3, 0x5B, 0x6A, 0x6C, 0x00,
170  0xEF, 0xA6, 0xA9, 0xA7, 0x1F, 0x49, 0x51, 0x7E,
171  0x18, 0xC6, 0x58, 0x48, 0xA1, 0x3A, 0x00, 0x01,
172  0x24, 0xFF, 0x58, 0x40, 0x00, 0x00, 0x00, 0xC0,
173  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
175  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
176  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180  0x00, 0x00, 0x00, 0x00, 0x58, 0x40, 0x45, 0x0B,
181  0x2C, 0x09, 0x68, 0xA1, 0x92, 0xA8, 0x85, 0xBE,
182  0x59, 0xE5, 0xA0, 0x9B, 0xDA, 0x4A, 0x8B, 0xA3,
183  0xA6, 0xFC, 0x7F, 0x51, 0x90, 0x35, 0x2D, 0x3A,
184  0x16, 0xBC, 0x30, 0x7B, 0x50, 0x3D, 0x45, 0x0B,
185  0x2C, 0x09, 0x68, 0xA1, 0x92, 0xA8, 0x85, 0xBE,
186  0x59, 0xE5, 0xA0, 0x9B, 0xDA, 0x4A, 0x8B, 0xA3,
187  0xA6, 0xFC, 0x7F, 0x51, 0x90, 0x35, 0x2D, 0x3A,
188  0x16, 0xBC, 0x30, 0x7B, 0x50, 0x3D
189 };
190 #endif /* SYMMETRIC_INITIAL_ATTESTATION */
191 
192 
193 /*
194  * Public function. See token_test.h
195  */
196 int_fast16_t minimal_test()
197 {
198  int_fast16_t return_value = 0;
199  Q_USEFUL_BUF_MAKE_STACK_UB(token_storage,
200  sizeof(expected_minimal_token_bytes));
201  struct q_useful_buf_c completed_token;
202  struct q_useful_buf_c expected_token;
203 
204  return_value =
208  token_storage,
209  &completed_token);
210  if(return_value) {
211  goto Done;
212  }
213 
214  expected_token =
215  Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(expected_minimal_token_bytes);
216 
217  if(q_useful_buf_compare(completed_token, expected_token)) {
218  return_value = -3;
219  }
220 
221 Done:
222  return return_value;
223 }
224 
225 
226 /*
227  * Public function. See token_test.h
228  */
229 int_fast16_t minimal_get_size_test()
230 {
231  int_fast16_t return_value = 0;
232  size_t length;
233  struct q_useful_buf_c expected_token;
234  struct q_useful_buf_c nonce;
235 
236  nonce = TOKEN_TEST_VALUE_NONCE;
237  expected_token =
238  Q_USEFUL_BUF_FROM_BYTE_ARRAY_LITERAL(expected_minimal_token_bytes);
239 
240 
241  return_value = psa_initial_attest_get_token_size(nonce.len,
242  &length);
243 
244  /*
245  * It is not possible to predict the size of the token returned
246  * here because options like TOKEN_OPT_OMIT_CLAIMS and
247  * TOKEN_OPT_SHORT_CIRCUIT_SIGN cannot be passed to limit what it
248  * does. Instead check to see if the size is in a reasonable
249  * range. The minimal_test() will actually check the size for
250  * exactitude because it can pass those options,
251  */
252  if(length < expected_token.len || length > 10000) {
253  return_value = -1;
254  }
255 
256  return return_value;
257 }
258 
259 
260 /*
261  * Public function. See token_test.h
262  */
263 int_fast16_t buffer_too_small_test()
264 {
265  int_fast16_t return_value = 0;
266  /*
267  * Construct a buffer with enough capacity in case buffer size check fails
268  * and the token is generated. If a smaller buffer is allocated, the
269  * incorrectly generated token may overwrite and corrupt the data following
270  * this buffer.
271  */
272  Q_USEFUL_BUF_MAKE_STACK_UB(token_storage,
273  sizeof(expected_minimal_token_bytes));
274  struct q_useful_buf_c completed_token;
275  struct q_useful_buf_c nonce;
276 
277 
278  nonce = TOKEN_TEST_VALUE_NONCE;
279  /* Fake the size and cheat the token generation process. */
280  token_storage.len = sizeof(expected_minimal_token_bytes) - 1;
281 
284  nonce,
285  token_storage,
286  &completed_token);
287 
288  if(return_value != PSA_ERROR_BUFFER_TOO_SMALL) {
289  return_value = -1;
290  } else {
291  return_value = 0;
292  }
293 
294  return return_value;
295 }
296 #endif /* INCLUDE_TEST_CODE */
297 
298 
316 static int_fast16_t check_simple_claims(
317  const struct attest_token_iat_simple_t *simple_claims)
318 {
319  int_fast16_t return_value;
320  /* Use temp variables to make lines less than 80 columns below. */
321  struct q_useful_buf_c tmp;
322  struct q_useful_buf_c tail;
323  /* Use a temporary string variable to make the static analyzer
324  * happy. It doesn't like comparing a string literal to NULL
325  */
326  const char *tmp_string;
327 
328  return_value = 0;
329 
330  /* -- check value of the nonce claim -- */
331  if(!IS_ITEM_FLAG_SET(NONCE_FLAG, simple_claims->item_flags)) {
332  /* Claim is not present in token */
334  /* It should have been present */
335  return_value = -50;
336  goto Done;
337  }
338  } else {
339  /* Claim is present */
340  /* Don't have to check if its presence is required */
342  if(!q_useful_buf_c_is_null(tmp)) {
343  /* request to check for the nonce */
344  if(q_useful_buf_compare(simple_claims->nonce, tmp)) {
345  /* Didn't match in the standard way. See if it is a
346  * special option-packed nonce by checking for length
347  * 64 and all bytes except the first four are 0.
348  * nonce_tail is everything after the first 4 bytes.
349  */
350  tail = q_useful_buf_tail(simple_claims->nonce, 4);
351  if(simple_claims->nonce.len == 64 &&
352  q_useful_buf_is_value(tail, 0) == SIZE_MAX){
353  /* It is an option-packed nonce.
354  * Don't compare the first four bytes.
355  */
356  if(q_useful_buf_compare(q_useful_buf_tail(tmp, 4), tail)) {
357  /* The option-packed nonce didn't match */
358  return_value = -51;
359  goto Done;
360  }
361  } else {
362  /* Just a normal nonce that didn't match */
363  return_value = -51;
364  goto Done;
365  }
366  }
367  }
368  }
369 
370  /* -- check value of the UEID claim -- */
371  if(!IS_ITEM_FLAG_SET(UEID_FLAG, simple_claims->item_flags)) {
372  /* Claim is not present in token */
374  /* It should have been present */
375  return_value = -52;
376  goto Done;
377  }
378  } else {
379  /* Claim is present */
380  /* Don't have to check if its presence is required */
381  tmp = TOKEN_TEST_VALUE_UEID;
382  if(!q_useful_buf_c_is_null(tmp) &&
383  q_useful_buf_compare(simple_claims->ueid, tmp)) {
384  /* Check of its value was requested and failed */
385  return_value = -53;
386  goto Done;
387  }
388  }
389 
390  /* -- check value of the boot seed claim -- */
391  if(!IS_ITEM_FLAG_SET(BOOT_SEED_FLAG, simple_claims->item_flags)) {
392  /* Claim is not present in token */
394  /* It should have been present */
395  return_value = -54;
396  goto Done;
397  }
398  } else {
399  /* Claim is present */
400  /* Don't have to check if its presence is required */
402  if(!q_useful_buf_c_is_null(tmp) &&
403  q_useful_buf_compare(simple_claims->boot_seed, tmp)) {
404  /* Check of its value was requested and failed */
405  return_value = -55;
406  goto Done;
407  }
408  }
409 
410  /* -- check value of the hw_version claim -- */
411  if(!IS_ITEM_FLAG_SET(HW_VERSION_FLAG, simple_claims->item_flags)) {
412  /* Claim is not present in token */
414  /* It should have been present */
415  return_value = -56;
416  goto Done;
417  }
418  } else {
419  /* Claim is present */
420  /* Don't have to check if its presence is required */
421  tmp_string = TOKEN_TEST_VALUE_HW_VERSION;
422  if(tmp_string != NULL) {
423  tmp = Q_USEFUL_BUF_FROM_SZ_LITERAL(TOKEN_TEST_VALUE_HW_VERSION);
424  if(q_useful_buf_compare(simple_claims->hw_version, tmp)) {
425  /* Check of its value was requested and failed */
426  return_value = -57;
427  goto Done;
428  }
429  }
430  }
431 
432  /* -- check value of the implementation ID -- */
433  if(!IS_ITEM_FLAG_SET(IMPLEMENTATION_ID_FLAG,simple_claims->item_flags)) {
434  /* Claim is not present in token */
436  return_value = -58;
437  goto Done;
438  }
439  } else {
440  /* Claim is present */
441  /* Don't have to check if its presence is required */
443  if(!q_useful_buf_c_is_null(tmp) &&
444  q_useful_buf_compare(simple_claims->implementation_id, tmp)) {
445  /* Check of its value was requested and failed */
446  return_value = -59;
447  goto Done;
448  }
449  }
450 
451  /* -- check value of the security lifecycle claim -- */
453  /* Claim is not present in token */
455  /* It should have been present */
456  return_value = -60;
457  goto Done;
458  }
459  } else {
460  /* Claim is present */
461  /* Don't have to check if its presence is required */
462  if(TOKEN_TEST_VALUE_SECURITY_LIFECYCLE != INT32_MAX &&
463  simple_claims->security_lifecycle !=
465  /* Check of its value was requested and failed */
466  return_value = -61;
467  goto Done;
468  }
469  }
470 
471  /* -- check value of the client_id claim -- */
472  if(!IS_ITEM_FLAG_SET(CLIENT_ID_FLAG, simple_claims->item_flags)) {
473  /* Claim is not present in token */
475  return_value = -62;
476  goto Done;
477  }
478  } else {
479  /* Claim is present */
480  /* Don't have to check if its presence is required */
481  if(TOKEN_TEST_VALUE_CLIENT_ID != INT32_MAX &&
482  simple_claims->client_id != TOKEN_TEST_VALUE_CLIENT_ID) {
483 #if DOMAIN_NS == 1U
484  /* Non-secure caller client ID has to be negative */
485  if(simple_claims->client_id > -1) {
486 #else
487  /* Secure caller client ID has to be positive */
488  if(simple_claims->client_id < 1) {
489 #endif
490  return_value = -63;
491  goto Done;
492  }
493  }
494  }
495 
496  /* -- check value of the profile_definition claim -- */
497  if(!IS_ITEM_FLAG_SET(PROFILE_DEFINITION_FLAG, simple_claims->item_flags)) {
498  /* Claim is not present in token */
500  /* It should have been present */
501  return_value = -64;
502  goto Done;
503  }
504  } else {
505  /* Claim is present */
506  /* Don't have to check if its presence is required */
508  if(tmp_string != NULL) {
509  tmp = Q_USEFUL_BUF_FROM_SZ_LITERAL(
511  if(q_useful_buf_compare(simple_claims->profile_definition, tmp)) {
512  /* Check of its value was requested and failed */
513  return_value = -65;
514  goto Done;
515  }
516  }
517  }
518 
519  /* -- check value of the origination claim -- */
520  if(!IS_ITEM_FLAG_SET(ORIGINATION_FLAG, simple_claims->item_flags)) {
521  /* Claim is not present in token */
523  /* It should have been present */
524  return_value = -66;
525  goto Done;
526  }
527  } else {
528  /* Claim is present */
529  /* Don't have to check if its presence is required */
530  tmp_string = TOKEN_TEST_VALUE_ORIGINATION;
531  if(tmp_string != NULL) {
532  tmp = Q_USEFUL_BUF_FROM_SZ_LITERAL(TOKEN_TEST_VALUE_ORIGINATION);
533  if(q_useful_buf_compare(simple_claims->origination, tmp)) {
534  /* Check of its value was requested and failed */
535  return_value = -67;
536  goto Done;
537  }
538  }
539  }
540 
541 Done:
542  return return_value;
543 }
544 
545 
565 static int_fast16_t check_sw_component_1(
566  const struct attest_token_sw_component_t *sw_component)
567 {
568  int_fast16_t return_value;
569  /* Use a temp variable to make lines less than 80 columns below. */
570  struct q_useful_buf_c tmp;
571  /* Use a temporary string variable to make the static analyzer
572  * happy. It doesn't like comparing a string literal to NULL
573  */
574  const char *tmp_string;
575 
576  return_value = 0;
577 
578  /* -- Check first type -- */
580  /* Claim is not present in token */
582  /* It should have been present */
583  return_value = -100;
584  goto Done;
585  }
586  } else {
587  /* Claim is present */
588  /* Don't have to check if its presence is required */
590  if(tmp_string != NULL) {
591  tmp = Q_USEFUL_BUF_FROM_SZ_LITERAL(
593  if(q_useful_buf_compare(sw_component->measurement_type, tmp)) {
594  /* Check of its value was requested and failed */
595  return_value = -101;
596  goto Done;
597  }
598  }
599  }
600 
601  /* -- Check first measurement -- */
602  if(!IS_ITEM_FLAG_SET(SW_MEASURMENT_VAL_FLAG, sw_component->item_flags)) {
603  /* Claim is not present in token */
605  /* It should have been present */
606  return_value = -102;
607  goto Done;
608  }
609  } else {
610  /* Claim is present */
611  /* Don't have to check if its presence is required */
613  if(!q_useful_buf_c_is_null(tmp) &&
614  q_useful_buf_compare(sw_component->measurement_val, tmp)) {
615  /* Check of its value was requested and failed */
616  return_value = -103;
617  goto Done;
618  }
619  }
620 
621  /* -- Check first version -- */
622  if(!IS_ITEM_FLAG_SET(SW_VERSION_FLAG, sw_component->item_flags)) {
623  /* Claim is not present in token */
625  /* It should have been present */
626  return_value = -106;
627  goto Done;
628  }
629  } else {
630  /* Claim is present */
631  /* Don't have to check if its presence is required */
632  tmp_string = TOKEN_TEST_VALUE_SWC1_VERSION;
633  if(tmp_string != NULL) {
634  tmp = Q_USEFUL_BUF_FROM_SZ_LITERAL(TOKEN_TEST_VALUE_SWC1_VERSION);
635  if(q_useful_buf_compare(sw_component->version, tmp)) {
636  /* Check of its value was requested and failed */
637  return_value = -107;
638  goto Done;
639  }
640  }
641  }
642 
643  /* -- Check first signer ID -- */
644  if(!IS_ITEM_FLAG_SET(SW_SIGNER_ID_FLAG, sw_component->item_flags)) {
645  /* Claim is not present in token */
647  /* It should have been present */
648  return_value = -108;
649  goto Done;
650  }
651  } else {
652  /* Claim is present */
653  /* Don't have to check if its presence is required */
655  if(!q_useful_buf_c_is_null(tmp) &&
656  q_useful_buf_compare(sw_component->signer_id, tmp)) {
657  /* Check of its value was requested and failed */
658  return_value = -109;
659  goto Done;
660  }
661  }
662 
663  /* -- Check first measurement description -- */
665  /* Claim is not present in token */
667  /* It should have been present */
668  return_value = -110;
669  goto Done;
670  }
671  } else {
672  /* Claim is present */
673  /* Don't have to check if its presence is required */
675  if(tmp_string != NULL) {
676  tmp = Q_USEFUL_BUF_FROM_SZ_LITERAL(
678  if(q_useful_buf_compare(sw_component->measurement_desc, tmp)) {
679  /* Check of its value was requested and failed */
680  return_value = -111;
681  goto Done;
682  }
683  }
684  }
685 
686  Done:
687  return return_value;
688 }
689 
690 
710 static int_fast16_t check_sw_component_2(
711  const struct attest_token_sw_component_t *sw_component)
712 {
713  int_fast16_t return_value;
714 
715  /* Use a temp variable to make lines less than 80 columns below. */
716  struct q_useful_buf_c tmp;
717  /* Use a temporary string variable to make the static analyzer
718  * happy. It doesn't like comparing a string literal to NULL
719  */
720  const char *tmp_string;
721 
722  return_value = 0;
723 
724  /* -- Check second type -- */
726  /* Claim is not present in token */
728  /* It should have been present */
729  return_value = -100;
730  goto Done;
731  }
732  } else {
733  /* Claim is present */
734  /* Don't have to check if its presence is required */
736  if(tmp_string != NULL) {
737  tmp = Q_USEFUL_BUF_FROM_SZ_LITERAL(
739  if(q_useful_buf_compare(sw_component->measurement_type, tmp)) {
740  /* Check of its value was requested and failed */
741  return_value = -101;
742  goto Done;
743  }
744  }
745  }
746 
747  /* -- Check second measurement -- */
748  if(!IS_ITEM_FLAG_SET(SW_MEASURMENT_VAL_FLAG, sw_component->item_flags)) {
749  /* Claim is not present in token */
751  /* It should have been present */
752  return_value = -102;
753  goto Done;
754  }
755  } else {
756  /* Claim is present */
757  /* Don't have to check if its presence is required */
759  if(!q_useful_buf_c_is_null(tmp) &&
760  q_useful_buf_compare(sw_component->measurement_val, tmp)) {
761  /* Check of its value was requested and failed */
762  return_value = -103;
763  goto Done;
764  }
765  }
766 
767  /* -- Check second version -- */
768  if(!IS_ITEM_FLAG_SET(SW_VERSION_FLAG, sw_component->item_flags)) {
769  /* Claim is not present in token */
771  /* It should have been present */
772  return_value = -106;
773  goto Done;
774  }
775  } else {
776  /* Claim is present */
777  /* Don't have to check if its presence is required */
778  tmp_string = TOKEN_TEST_VALUE_SWC2_VERSION;
779  if(tmp_string != NULL) {
780  tmp = Q_USEFUL_BUF_FROM_SZ_LITERAL(TOKEN_TEST_VALUE_SWC2_VERSION);
781  if(q_useful_buf_compare(sw_component->version, tmp)) {
782  /* Check of its value was requested and failed */
783  return_value = -107;
784  goto Done;
785  }
786  }
787  }
788 
789  /* -- Check second signer ID -- */
790  if(!IS_ITEM_FLAG_SET(SW_SIGNER_ID_FLAG, sw_component->item_flags)) {
791  /* Claim is not present in token */
793  /* It should have been present */
794  return_value = -108;
795  goto Done;
796  }
797  } else {
798  /* Claim is present */
799  /* Don't have to check if its presence is required */
801  if(!q_useful_buf_c_is_null(tmp) &&
802  q_useful_buf_compare(sw_component->signer_id, tmp)) {
803  /* Check of its value was requested and failed */
804  return_value = -109;
805  goto Done;
806  }
807  }
808 
809  /* -- Check second measurement description -- */
811  /* Claim is not present in token */
813  /* It should have been present */
814  return_value = -110;
815  goto Done;
816  }
817  } else {
818  /* Claim is present */
819  /* Don't have to check if its presence is required */
821  if(tmp_string != NULL) {
822  tmp = Q_USEFUL_BUF_FROM_SZ_LITERAL(
824  if(q_useful_buf_compare(sw_component->measurement_desc, tmp)) {
825  /* Check of its value was requested and failed */
826  return_value = -111;
827  goto Done;
828  }
829  }
830  }
831 
832 Done:
833  return return_value;
834 }
835 
848 };
849 
859 static int_fast16_t decode_test_internal(enum decode_test_mode_t mode)
860 {
861  int_fast16_t return_value;
862  Q_USEFUL_BUF_MAKE_STACK_UB( token_storage, ATTEST_TOKEN_MAX_SIZE);
863  struct q_useful_buf_c completed_token;
864  struct attest_token_decode_context token_decode;
865  struct attest_token_iat_simple_t simple_claims;
866  struct attest_token_sw_component_t sw_component;
867  uint32_t num_sw_components;
868  int32_t num_sw_components_signed;
869  struct q_useful_buf_c tmp;
870  uint32_t token_encode_options;
871  uint32_t token_decode_options;
872 
873  switch(mode) {
874  case SHORT_CIRCUIT_SIGN:
875  token_encode_options = TOKEN_OPT_SHORT_CIRCUIT_SIGN;
876  token_decode_options = TOKEN_OPT_SHORT_CIRCUIT_SIGN;
877  break;
878 
879  case NORMAL_SIGN:
880  token_encode_options = 0;
881  token_decode_options = 0;
882  break;
883 
884  case COSE_MAC0:
885  token_encode_options = 0;
886  token_decode_options = 0;
887  break;
888 
890  token_encode_options = TOKEN_OPT_SHORT_CIRCUIT_SIGN;
891  token_decode_options = TOKEN_OPT_SHORT_CIRCUIT_SIGN;
892  break;
893 
894  default:
895  return_value = -1000;
896  goto Done;
897  }
898 
899  /* -- Make a token with all the claims -- */
901  return_value = token_main_alt(token_encode_options,
902  tmp,
903  token_storage,
904  &completed_token);
905  if(return_value) {
906  goto Done;
907  }
908 
909  /* -- Initialize and validate the signature on the token -- */
910  attest_token_decode_init(&token_decode, token_decode_options);
911  return_value = attest_token_decode_validate_token(&token_decode,
912  completed_token);
913  if(return_value != ATTEST_TOKEN_ERR_SUCCESS) {
914  goto Done;
915  }
916 
917  /* -- Get the all simple claims at once and check them -- */
918  return_value = attest_token_decode_get_iat_simple(&token_decode,
919  &simple_claims);
920  if(return_value != ATTEST_TOKEN_ERR_SUCCESS) {
921  goto Done;
922  }
923 
924 
925  return_value = check_simple_claims(&simple_claims);
926  if(return_value != ATTEST_TOKEN_ERR_SUCCESS) {
927  goto Done;
928  }
929 
930  /* -- SW components -- */
931  if(TOKEN_TEST_REQUIRED_NUM_SWC != INT32_MAX) {
932  /* -- Configured to check for SW components, so do that -- */
933 
934  /* -- Get num SW components -- */
935  return_value = attest_token_get_num_sw_components(&token_decode,
936  &num_sw_components);
937  if(return_value) {
938  goto Done;
939  }
940  /* This conversion to signed avoids a compiler warning
941  * when TOKEN_TEST_REQUIRED_NUM_SWC is defined as 0 */
942  num_sw_components_signed = (int32_t)num_sw_components;
943  if(num_sw_components_signed < TOKEN_TEST_REQUIRED_NUM_SWC) {
944  return_value = -5;
945  goto Done;
946  }
947 
948  if(num_sw_components >= 1) {
949  /* -- Get the first SW component and check it -- */
950  return_value = attest_token_get_sw_component(&token_decode,
951  0,
952  &sw_component);
953  if(return_value) {
954  goto Done;
955  }
956 
957  return_value = check_sw_component_1(&sw_component);
958  if(return_value) {
959  goto Done;
960  }
961 
962  if(num_sw_components >= 2) {
963  /* -- Get the second SW component and check it -- */
964  return_value = attest_token_get_sw_component(&token_decode,
965  1,
966  &sw_component);
967  if(return_value) {
968  goto Done;
969  }
970 
971  return_value = check_sw_component_2(&sw_component);
972  if(return_value) {
973  goto Done;
974  }
975  }
976  }
977  }
978  return_value = 0;
979 
980 Done:
981  return return_value;
982 }
983 
984 #ifdef SYMMETRIC_INITIAL_ATTESTATION
985 int_fast16_t decode_test_symmetric_initial_attest(void)
986 {
987  return decode_test_internal(COSE_MAC0);
988 }
989 
990 int_fast16_t decode_test_symmetric_iat_short_circuit_tag(void)
991 {
992  return decode_test_internal(COSE_MAC0_SHORT_CIRCUIT_TAG);
993 }
994 #else /* SYMMETRIC_INITIAL_ATTESTATION */
995 /*
996  * Public function. See token_test.h
997  */
999 {
1000  return decode_test_internal(SHORT_CIRCUIT_SIGN);
1001 }
1002 
1003 
1004 /*
1005  * Public function. See token_test.h
1006  */
1007 int_fast16_t decode_test_normal_sig(void)
1008 {
1009  return decode_test_internal(NORMAL_SIGN);
1010 }
1011 #endif /* SYMMETRIC_INITIAL_ATTESTATION */
decode_test_mode_t
#define IS_ITEM_FLAG_SET(item_index, item_flags)
struct q_useful_buf_c implementation_id
#define TOKEN_TEST_REQUIRE_BOOT_SEED
#define TOKEN_TEST_VALUE_SWC2_MEASUREMENT_DESC
#define TOKEN_TEST_REQUIRE_PROFILE_DEFINITION
#define TOKEN_TEST_REQUIRE_SWC1_MEASUREMENT_VAL
#define TOKEN_TEST_VALUE_BOOT_SEED
int_fast16_t decode_test_short_circuit_sig(void)
Test by checking short-circuit signed values of claims.
#define TOKEN_TEST_REQUIRE_ORIGINATION
enum attest_token_err_t attest_token_get_sw_component(struct attest_token_decode_context *me, uint32_t requested_index, struct attest_token_sw_component_t *sw_components)
Get the nth SW component.
#define PSA_SUCCESS
Definition: crypto_values.h:35
#define PSA_ERROR_BUFFER_TOO_SMALL
Definition: crypto_values.h:77
#define TOKEN_TEST_REQUIRE_CLIENT_ID
Attestation Token Decoding Interface.
int token_main_alt(uint32_t option_flags, struct q_useful_buf_c nonce, struct q_useful_buf buffer, struct q_useful_buf_c *completed_token)
An alternate token_main() that packs the option flags into the nonce.
Platform Security Architecture cryptography module.
#define TOKEN_TEST_REQUIRE_IMPLEMENTATION_ID
#define TOKEN_TEST_REQUIRE_SWC2_MEASUREMENT_TYPE
#define TOKEN_TEST_REQUIRE_SWC1_MEASUREMENT_DESC
#define TOKEN_TEST_VALUE_HW_VERSION
#define TOKEN_TEST_VALUE_SWC1_MEASUREMENT_VAL
#define TOKEN_TEST_REQUIRE_SECURITY_LIFECYCLE
enum attest_token_err_t attest_token_get_num_sw_components(struct attest_token_decode_context *me, uint32_t *num_sw_components)
Get the number of SW components in the token.
#define TOKEN_TEST_REQUIRE_SWC2_MEASUREMENT_DESC
#define TOKEN_TEST_REQUIRE_SWC2_MEASUREMENT_VAL
#define TOKEN_TEST_REQUIRE_NONCE
struct q_useful_buf_c measurement_type
#define TOKEN_OPT_OMIT_CLAIMS
Definition: attest_token.h:107
#define TOKEN_TEST_VALUE_SWC1_SIGNER_ID
#define TOKEN_TEST_VALUE_SWC2_MEASUREMENT_TYPE
#define TOKEN_TEST_REQUIRE_SWC1_SIGNER_ID
int_fast16_t minimal_get_size_test(void)
Test token size calculation.
struct q_useful_buf_c version
void attest_token_decode_init(struct attest_token_decode_context *me, uint32_t options)
Initialize token decoder.
#define TOKEN_TEST_VALUE_SWC2_SIGNER_ID
#define TOKEN_TEST_VALUE_SWC2_VERSION
#define TOKEN_TEST_REQUIRE_UEID
#define TOKEN_TEST_REQUIRE_SWC1_VERSION
psa_status_t psa_initial_attest_get_token_size(size_t challenge_size, size_t *token_size)
Get the exact size of initial attestation token in bytes.
struct q_useful_buf_c hw_version
struct q_useful_buf_c origination
int_fast16_t buffer_too_small_test(void)
Pass too small a buffer and confirm correct error result.
#define TOKEN_TEST_VALUE_CLIENT_ID
#define TOKEN_TEST_REQUIRED_NUM_SWC
#define TOKEN_TEST_REQUIRE_SWC2_SIGNER_ID
Expected values for test suite.
enum attest_token_err_t attest_token_decode_validate_token(struct attest_token_decode_context *me, struct q_useful_buf_c token)
Set the token to work on and validate its signature.
#define TOKEN_TEST_VALUE_SWC1_VERSION
#define TOKEN_TEST_REQUIRE_HW_VERSION
#define TOKEN_TEST_REQUIRE_SWC1_MEASUREMENT_TYPE
Entry points for attestation token tests.
#define TOKEN_TEST_VALUE_SWC1_MEASUREMENT_DESC
#define TOKEN_TEST_VALUE_SWC1_MEASUREMENT_TYPE
int_fast16_t minimal_test(void)
Minimal token creation test using a short-circuit signature.
#define TOKEN_OPT_SHORT_CIRCUIT_SIGN
Definition: attest_token.h:117
struct q_useful_buf_c signer_id
#define TOKEN_TEST_VALUE_UEID
struct q_useful_buf_c measurement_val
void * memcpy(void *dest, const void *src, size_t n)
Definition: crt_memcpy.c:10
psa_status_t psa_initial_attest_get_token(const uint8_t *auth_challenge, size_t challenge_size, uint8_t *token_buf, size_t token_buf_size, size_t *token_size)
Get initial attestation token.
struct q_useful_buf_c nonce
#define TOKEN_TEST_REQUIRE_SWC2_VERSION
#define ATTEST_TOKEN_MAX_SIZE
#define TOKEN_TEST_VALUE_ORIGINATION
int_fast16_t decode_test_normal_sig(void)
Test by checking signed values of claims.
#define TOKEN_TEST_VALUE_SECURITY_LIFECYCLE
struct q_useful_buf_c ueid
enum attest_token_err_t attest_token_decode_get_iat_simple(struct attest_token_decode_context *me, struct attest_token_iat_simple_t *items)
Batch fetch of all simple data items in a token.
#define TOKEN_TEST_VALUE_SWC2_MEASUREMENT_VAL
struct q_useful_buf_c boot_seed
int32_t psa_status_t
Function return status.
Definition: crypto_types.h:43
struct q_useful_buf_c measurement_desc
#define TOKEN_TEST_VALUE_IMPLEMENTATION_ID
#define TOKEN_TEST_VALUE_PROFILE_DEFINITION
#define TOKEN_TEST_VALUE_NONCE
struct q_useful_buf_c profile_definition