TF-M Reference Manual  1.2.0
TrustedFirmware-M
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
attest_core.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <stdint.h>
9 #include <string.h>
10 #include <stddef.h>
11 #include "psa/client.h"
12 #include "attest.h"
13 #include "attest_key.h"
14 #include "tfm_boot_status.h"
15 #include "tfm_plat_defs.h"
16 #include "tfm_plat_device_id.h"
17 #include "tfm_plat_boot_seed.h"
18 #include "tfm_attest_hal.h"
19 #include "attest_token.h"
20 #include "attest_eat_defines.h"
21 #include "t_cose_common.h"
22 #include "tfm_memory_utils.h"
23 #include "tfm_plat_crypto_keys.h"
24 
25 #define MAX_BOOT_STATUS 512
26 
27 /* Indicates how to encode SW components' measurements in the CBOR map */
28 #define EAT_SW_COMPONENT_NESTED 1 /* Nested map */
29 #define EAT_SW_COMPONENT_NOT_NESTED 0 /* Flat structure */
30 
31 /* The algorithm used in COSE */
32 #ifdef SYMMETRIC_INITIAL_ATTESTATION
33 #define T_COSE_ALGORITHM T_COSE_ALGORITHM_HMAC256
34 #else
35 #define T_COSE_ALGORITHM T_COSE_ALGORITHM_ES256
36 #endif
37 
49 };
50 
61 __attribute__ ((aligned(4)))
62 static struct attest_boot_data boot_data;
63 
72 static inline psa_status_t
73 error_mapping_to_psa_status_t(enum psa_attest_err_t attest_err)
74 {
75  switch (attest_err) {
77  return PSA_SUCCESS;
78  break;
81  break;
84  break;
87  break;
90  break;
93  break;
94  default:
96  }
97 }
98 
100 {
101  enum psa_attest_err_t res;
102 
104  (struct tfm_boot_data *)&boot_data,
106 
107  return error_mapping_to_psa_status_t(res);
108 }
109 
118 static inline enum psa_attest_err_t
119 error_mapping_to_psa_attest_err_t(enum attest_token_err_t token_err)
120 {
121  switch (token_err) {
123  return PSA_ATTEST_ERR_SUCCESS;
124  break;
127  break;
128  default:
129  return PSA_ATTEST_ERR_GENERAL;
130  }
131 }
132 
148 static inline int32_t get_uint(const void *int_ptr,
149  size_t len,
150  uint32_t *value)
151 {
152  uint16_t uint16;
153 
154  switch (len) {
155  case 1:
156  *value = (uint32_t)(*(uint8_t *)(int_ptr));
157  break;
158  case 2:
159  /* Avoid unaligned access */
160  (void)tfm_memcpy(&uint16, int_ptr, sizeof(uint16));
161  *value = (uint32_t)uint16;
162  break;
163  case 4:
164  /* Avoid unaligned access */
165  (void)tfm_memcpy(value, int_ptr, sizeof(uint32_t));
166  break;
167  default:
168  return -1;
169  }
170 
171  return 0;
172 }
191 static int32_t attest_get_tlv_by_module(uint8_t module,
192  uint8_t *claim,
193  uint16_t *tlv_len,
194  uint8_t **tlv_ptr)
195 {
196  struct shared_data_tlv_entry tlv_entry;
197  uint8_t *tlv_end;
198  uint8_t *tlv_curr;
199 
200  if (boot_data.header.tlv_magic != SHARED_DATA_TLV_INFO_MAGIC) {
201  return -1;
202  }
203 
204  /* Get the boundaries of TLV section where to lookup*/
205  tlv_end = (uint8_t *)&boot_data + boot_data.header.tlv_tot_len;
206  if (*tlv_ptr == NULL) {
207  /* At first call set to the beginning of the TLV section */
208  tlv_curr = boot_data.data;
209  } else {
210  /* Any subsequent call set to the next TLV entry */
211  (void)tfm_memcpy(&tlv_entry, *tlv_ptr, SHARED_DATA_ENTRY_HEADER_SIZE);
212 
213  tlv_curr = (*tlv_ptr) + SHARED_DATA_ENTRY_HEADER_SIZE
214  + tlv_entry.tlv_len;
215  }
216 
217  /* Iterates over the TLV section and returns the address and size of TLVs
218  * with requested module identifier
219  */
220  while (tlv_curr < tlv_end) {
221  /* Create local copy to avoid unaligned access */
222  (void)tfm_memcpy(&tlv_entry, tlv_curr, SHARED_DATA_ENTRY_HEADER_SIZE);
223  if (GET_IAS_MODULE(tlv_entry.tlv_type) == module) {
224  *claim = GET_IAS_CLAIM(tlv_entry.tlv_type);
225  *tlv_ptr = tlv_curr;
226  *tlv_len = tlv_entry.tlv_len;
227  return 1;
228  }
229 
230  tlv_curr += (SHARED_DATA_ENTRY_HEADER_SIZE + tlv_entry.tlv_len);
231  }
232 
233  return 0;
234 }
235 
248 static int32_t attest_get_tlv_by_id(uint8_t claim,
249  uint16_t *tlv_len,
250  uint8_t **tlv_ptr)
251 {
252  uint8_t tlv_id;
253  uint8_t module = SW_GENERAL;
254  int32_t found;
255 
256  /* Ensure that look up starting from the beginning of the boot status */
257  *tlv_ptr = NULL;
258 
259  /* Look up specific TLV entry which belongs to SW_GENERAL module */
260  do {
261  /* Look up next entry */
262  found = attest_get_tlv_by_module(module, &tlv_id,
263  tlv_len, tlv_ptr);
264  if (found != 1) {
265  break;
266  }
267  /* At least one entry was found which belongs to SW_GENERAL,
268  * check whether this one is looked for
269  */
270  if (claim == tlv_id) {
271  break;
272  }
273  } while (found == 1);
274 
275  return found;
276 }
277 
286 static enum psa_attest_err_t
287 attest_add_all_sw_components(struct attest_token_encode_ctx *token_ctx)
288 {
289  uint16_t tlv_len;
290  uint8_t *tlv_ptr;
291  uint8_t tlv_id;
292  int32_t found;
293  uint32_t cnt = 0;
294  uint8_t module = 0;
295  QCBOREncodeContext *cbor_encode_ctx = NULL;
296  UsefulBufC encoded = NULLUsefulBufC;
297 
298  cbor_encode_ctx = attest_token_encode_borrow_cbor_cntxt(token_ctx);
299 
300  for (module = 0; module < SW_MAX; ++module) {
301  /* Indicates to restart the look up from the beginning of the shared
302  * data section
303  */
304  tlv_ptr = NULL;
305 
306  /* Look up the first TLV entry which belongs to the SW module */
307  found = attest_get_tlv_by_module(module, &tlv_id,
308  &tlv_len, &tlv_ptr);
309  if (found == -1) {
311  }
312 
313  if (found == 1) {
314  cnt++;
315  if (cnt == 1) {
316  /* Open array which stores SW components claims */
317  QCBOREncode_OpenArrayInMapN(cbor_encode_ctx,
319  }
320 
321  encoded.ptr = tlv_ptr + SHARED_DATA_ENTRY_HEADER_SIZE;
322  encoded.len = tlv_len;
323  QCBOREncode_AddEncoded(cbor_encode_ctx, encoded);
324  }
325  }
326 
327  if (cnt != 0) {
328  /* Close array which stores SW components claims*/
329  QCBOREncode_CloseArray(cbor_encode_ctx);
330  } else {
331  /* If there is not any SW components' measurement in the boot status
332  * then include this claim to indicate that this state is intentional
333  */
336  (int64_t)NO_SW_COMPONENT_FIXED_VALUE);
337  }
338 
339  return PSA_ATTEST_ERR_SUCCESS;
340 }
341 
349 static enum psa_attest_err_t
350 attest_add_boot_seed_claim(struct attest_token_encode_ctx *token_ctx)
351 {
352  uint8_t boot_seed[BOOT_SEED_SIZE];
353  enum tfm_plat_err_t res;
354  struct q_useful_buf_c claim_value = {0};
355  uint16_t tlv_len;
356  uint8_t *tlv_ptr = NULL;
357  int32_t found = 0;
358 
359  /* First look up BOOT_SEED in boot status, it might comes from bootloader */
360  found = attest_get_tlv_by_id(BOOT_SEED, &tlv_len, &tlv_ptr);
361  if (found == 1) {
362  claim_value.ptr = tlv_ptr + SHARED_DATA_ENTRY_HEADER_SIZE;
363  claim_value.len = tlv_len;
364  } else {
365  /* If not found in boot status then use callback function to get it
366  * from runtime SW
367  */
368  res = tfm_plat_get_boot_seed(sizeof(boot_seed), boot_seed);
369  if (res != TFM_PLAT_ERR_SUCCESS) {
371  }
372  claim_value.ptr = boot_seed;
373  claim_value.len = BOOT_SEED_SIZE;
374  }
375 
378  &claim_value);
379 
380  return PSA_ATTEST_ERR_SUCCESS;
381 }
382 
393 static enum psa_attest_err_t
394 attest_add_instance_id_claim(struct attest_token_encode_ctx *token_ctx)
395 {
396  struct q_useful_buf_c claim_value;
397  enum psa_attest_err_t err;
398 
399  /* Leave the first byte for UEID type byte */
400  err = attest_get_instance_id(&claim_value);
401  if (err != PSA_ATTEST_ERR_SUCCESS) {
402  return err;
403  }
404 
407  &claim_value);
408 
409  return PSA_ATTEST_ERR_SUCCESS;
410 }
411 
419 static enum psa_attest_err_t
420 attest_add_implementation_id_claim(struct attest_token_encode_ctx *token_ctx)
421 {
422  uint8_t implementation_id[IMPLEMENTATION_ID_MAX_SIZE];
423  enum tfm_plat_err_t res_plat;
424  uint32_t size = sizeof(implementation_id);
425  struct q_useful_buf_c claim_value;
426 
427  res_plat = tfm_plat_get_implementation_id(&size, implementation_id);
428  if (res_plat != TFM_PLAT_ERR_SUCCESS) {
430  }
431 
432  claim_value.ptr = implementation_id;
433  claim_value.len = size;
436  &claim_value);
437 
438  return PSA_ATTEST_ERR_SUCCESS;
439 }
440 
448 static enum psa_attest_err_t
449 attest_add_caller_id_claim(struct attest_token_encode_ctx *token_ctx)
450 {
451  enum psa_attest_err_t res;
452  int32_t caller_id;
453 
454  res = attest_get_caller_client_id(&caller_id);
455  if (res != PSA_ATTEST_ERR_SUCCESS) {
456  return res;
457  }
458 
461  (int64_t)caller_id);
462 
463  return PSA_ATTEST_ERR_SUCCESS;
464 }
465 
473 static enum psa_attest_err_t
474 attest_add_security_lifecycle_claim(struct attest_token_encode_ctx *token_ctx)
475 {
476  enum tfm_security_lifecycle_t security_lifecycle;
477  uint32_t slc_value;
478  int32_t res;
479  struct q_useful_buf_c claim_value = {0};
480  uint16_t tlv_len;
481  uint8_t *tlv_ptr = NULL;
482  int32_t found = 0;
483 
484  /* First look up lifecycle state in boot status, it might comes
485  * from bootloader
486  */
487  found = attest_get_tlv_by_id(SECURITY_LIFECYCLE, &tlv_len, &tlv_ptr);
488  if (found == 1) {
489  claim_value.ptr = tlv_ptr + SHARED_DATA_ENTRY_HEADER_SIZE;
490  claim_value.len = tlv_len;
491  res = get_uint(claim_value.ptr, claim_value.len, &slc_value);
492  if (res) {
493  return PSA_ATTEST_ERR_GENERAL;
494  }
495  security_lifecycle = (enum tfm_security_lifecycle_t)slc_value;
496  } else {
497  /* If not found in boot status then use callback function to get it
498  * from runtime SW
499  */
500  security_lifecycle = tfm_attest_hal_get_security_lifecycle();
501  }
502 
503  /* Sanity check */
504  if (security_lifecycle > TFM_SLC_MAX_VALUE) {
505  return PSA_ATTEST_ERR_GENERAL;
506  }
507 
510  (int64_t)security_lifecycle);
511 
512  return PSA_ATTEST_ERR_SUCCESS;
513 }
514 
523 static enum psa_attest_err_t
524 attest_add_challenge_claim(struct attest_token_encode_ctx *token_ctx,
525  const struct q_useful_buf_c *challenge)
526 {
529  challenge);
530 
531  return PSA_ATTEST_ERR_SUCCESS;
532 }
533 
534 #ifdef INCLUDE_OPTIONAL_CLAIMS /* Remove them from release build */
535 
543 static enum psa_attest_err_t
544 attest_add_verification_service(struct attest_token_encode_ctx *token_ctx)
545 {
546  struct q_useful_buf_c service;
547  uint32_t size;
548 
549  service.ptr = tfm_attest_hal_get_verification_service(&size);
550 
551  if (service.ptr) {
552  service.len = size;
555  &service);
556  }
557 
558  return PSA_ATTEST_ERR_SUCCESS;
559 }
560 
568 static enum psa_attest_err_t
569 attest_add_profile_definition(struct attest_token_encode_ctx *token_ctx)
570 {
571  struct q_useful_buf_c profile;
572  uint32_t size;
573 
574  profile.ptr = tfm_attest_hal_get_profile_definition(&size);
575 
576  if (profile.ptr) {
577  profile.len = size;
580  &profile);
581  }
582 
583  return PSA_ATTEST_ERR_SUCCESS;
584 }
585 
593 static enum psa_attest_err_t
594 attest_add_hw_version_claim(struct attest_token_encode_ctx *token_ctx)
595 {
596  uint8_t hw_version[HW_VERSION_MAX_SIZE];
597  enum tfm_plat_err_t res_plat;
598  uint32_t size = sizeof(hw_version);
599  struct q_useful_buf_c claim_value = {0};
600  uint16_t tlv_len;
601  uint8_t *tlv_ptr = NULL;
602  int32_t found = 0;
603 
604  /* First look up HW version in boot status, it might comes
605  * from bootloader
606  */
607  found = attest_get_tlv_by_id(HW_VERSION, &tlv_len, &tlv_ptr);
608  if (found == 1) {
609  claim_value.ptr = tlv_ptr + SHARED_DATA_ENTRY_HEADER_SIZE;
610  claim_value.len = tlv_len;
611  } else {
612  /* If not found in boot status then use callback function to get it
613  * from runtime SW
614  */
615  res_plat = tfm_plat_get_hw_version(&size, hw_version);
616  if (res_plat != TFM_PLAT_ERR_SUCCESS) {
618  }
619  claim_value.ptr = hw_version;
620  claim_value.len = size;
621  }
622 
625  &claim_value);
626 
627  return PSA_ATTEST_ERR_SUCCESS;
628 }
629 #endif /* INCLUDE_OPTIONAL_CLAIMS */
630 
641 static enum psa_attest_err_t attest_verify_challenge_size(size_t challenge_size)
642 {
643  switch (challenge_size) {
644  /* Intentional fall through */
648  return PSA_ATTEST_ERR_SUCCESS;
649  }
650 
652 }
653 
654 #ifdef INCLUDE_TEST_CODE /* Remove them from release build */
655 
670 static void attest_get_option_flags(struct q_useful_buf_c *challenge,
671  uint32_t *option_flags,
672  int32_t *key_select)
673 {
674  uint32_t found_option_flags = 1;
675  uint32_t option_flags_size = sizeof(uint32_t);
676  uint8_t *challenge_end;
677  uint8_t *challenge_data;
678 
679  /* Get option flags if there is encoded in the challenge object */
680  if ((challenge->len == PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64) &&
681  (challenge->ptr)) {
682  challenge_end = ((uint8_t *)challenge->ptr) + challenge->len;
683  challenge_data = ((uint8_t *)challenge->ptr) + option_flags_size;
684 
685  /* Compare bytes(4-63) with 0 */
686  while (challenge_data < challenge_end) {
687  if (*challenge_data++ != 0) {
688  found_option_flags = 0;
689  break;
690  }
691  }
692  } else {
693  found_option_flags = 0;
694  }
695 
696  if (found_option_flags) {
697  (void)tfm_memcpy(option_flags, challenge->ptr, option_flags_size);
698 
699  /* Lower three bits are the key select */
700  *key_select = *option_flags & 0x7;
701  } else {
702  *option_flags = 0;
703  *key_select = 0;
704  }
705 }
706 #endif /* INCLUDE_TEST_CODE */
707 
720 static enum psa_attest_err_t
721 attest_create_token(struct q_useful_buf_c *challenge,
722  struct q_useful_buf *token,
723  struct q_useful_buf_c *completed_token)
724 {
725  enum psa_attest_err_t attest_err = PSA_ATTEST_ERR_SUCCESS;
726  enum attest_token_err_t token_err;
727  struct attest_token_encode_ctx attest_token_ctx;
728  int32_t key_select = 0;
729  uint32_t option_flags = 0;
730 
732  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
733  goto error;
734  }
735 
736 #ifdef INCLUDE_TEST_CODE /* Remove them from release build */
737  attest_get_option_flags(challenge, &option_flags, &key_select);
738 #endif
739 
740  /* Get started creating the token. This sets up the CBOR and COSE contexts
741  * which causes the COSE headers to be constructed.
742  */
743  token_err = attest_token_encode_start(&attest_token_ctx,
744  option_flags, /* option_flags */
745  key_select, /* key_select */
746  T_COSE_ALGORITHM, /* alg_select */
747  token);
748 
749  if (token_err != ATTEST_TOKEN_ERR_SUCCESS) {
750  attest_err = error_mapping_to_psa_attest_err_t(token_err);
751  goto error;
752  }
753 
754  attest_err = attest_add_challenge_claim(&attest_token_ctx,
755  challenge);
756  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
757  goto error;
758  }
759 
760  if (!(option_flags & TOKEN_OPT_OMIT_CLAIMS)) {
761  /* Mandatory claims in IAT token */
762  attest_err = attest_add_boot_seed_claim(&attest_token_ctx);
763  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
764  goto error;
765  }
766 
767  attest_err = attest_add_instance_id_claim(&attest_token_ctx);
768  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
769  goto error;
770  }
771 
772  attest_err = attest_add_implementation_id_claim(&attest_token_ctx);
773  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
774  goto error;
775  }
776 
777  attest_err = attest_add_caller_id_claim(&attest_token_ctx);
778  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
779  goto error;
780  }
781 
782  attest_err = attest_add_security_lifecycle_claim(&attest_token_ctx);
783  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
784  goto error;
785  }
786 
787  attest_err = attest_add_all_sw_components(&attest_token_ctx);
788  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
789  goto error;
790  }
791 
792 #ifdef INCLUDE_OPTIONAL_CLAIMS
793  /* Optional claims in IAT token, remove them from release build */
794  attest_err = attest_add_verification_service(&attest_token_ctx);
795  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
796  goto error;
797  }
798 
799  attest_err = attest_add_profile_definition(&attest_token_ctx);
800  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
801  goto error;
802  }
803 
804  attest_err = attest_add_hw_version_claim(&attest_token_ctx);
805  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
806  goto error;
807  }
808 #endif /* INCLUDE_OPTIONAL_CLAIMS */
809  }
810 
811  /* Finish up creating the token. This is where the actual signature
812  * is generated. This finishes up the CBOR encoding too.
813  */
814  token_err = attest_token_encode_finish(&attest_token_ctx, completed_token);
815  if (token_err) {
816  attest_err = error_mapping_to_psa_attest_err_t(token_err);
817  goto error;
818  }
819 
820 error:
821  if (attest_err == PSA_ATTEST_ERR_SUCCESS) {
822  /* We got here normally and therefore care about error codes. */
824  }
825  else {
826  /* Error handler: just remove they key and preserve error. */
828  }
829  return attest_err;
830 }
831 
833 initial_attest_get_token(const psa_invec *in_vec, uint32_t num_invec,
834  psa_outvec *out_vec, uint32_t num_outvec)
835 {
836  enum psa_attest_err_t attest_err = PSA_ATTEST_ERR_SUCCESS;
837  struct q_useful_buf_c challenge;
838  struct q_useful_buf token;
839  struct q_useful_buf_c completed_token;
840 
841  challenge.ptr = in_vec[0].base;
842  challenge.len = in_vec[0].len;
843  token.ptr = out_vec[0].base;
844  token.len = out_vec[0].len;
845 
846  attest_err = attest_verify_challenge_size(challenge.len);
847  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
848  goto error;
849  }
850 
851  if (token.len == 0) {
852  attest_err = PSA_ATTEST_ERR_INVALID_INPUT;
853  goto error;
854  }
855 
856  attest_err = attest_create_token(&challenge, &token, &completed_token);
857  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
858  goto error;
859  }
860 
861  out_vec[0].base = (void *)completed_token.ptr;
862  out_vec[0].len = completed_token.len;
863 
864 error:
865  return error_mapping_to_psa_status_t(attest_err);
866 }
867 
869 initial_attest_get_token_size(const psa_invec *in_vec, uint32_t num_invec,
870  psa_outvec *out_vec, uint32_t num_outvec)
871 {
872  enum psa_attest_err_t attest_err = PSA_ATTEST_ERR_SUCCESS;
873  uint32_t challenge_size = *(uint32_t *)in_vec[0].base;
874  uint32_t *token_buf_size = (uint32_t *)out_vec[0].base;
875  struct q_useful_buf_c challenge;
876  struct q_useful_buf token;
877  struct q_useful_buf_c completed_token;
878 
879  /* Only the size of the challenge is needed */
880  challenge.ptr = NULL;
881  challenge.len = challenge_size;
882 
883  /* Special value to get the size of the token, but token is not created */
884  token.ptr = NULL;
885  token.len = INT32_MAX;
886 
887  if (out_vec[0].len < sizeof(uint32_t)) {
888  attest_err = PSA_ATTEST_ERR_INVALID_INPUT;
889  goto error;
890  }
891 
892  attest_err = attest_verify_challenge_size(challenge_size);
893  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
894  goto error;
895  }
896 
897  attest_err = attest_create_token(&challenge, &token, &completed_token);
898  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
899  goto error;
900  }
901 
902  *token_buf_size = completed_token.len;
903 
904 error:
905  return error_mapping_to_psa_status_t(attest_err);
906 }
907 
908 #ifdef SYMMETRIC_INITIAL_ATTESTATION
910 initial_attest_get_public_key(const psa_invec *in_vec, uint32_t num_invec,
911  psa_outvec *out_vec, uint32_t num_outvec)
912 {
913  (void)in_vec;
914  (void)num_invec;
915  (void)out_vec;
916  (void)num_outvec;
917 
919 }
920 #else /* SYMMETRIC_INITIAL_ATTESTATION */
922 initial_attest_get_public_key(const psa_invec *in_vec, uint32_t num_invec,
923  psa_outvec *out_vec, uint32_t num_outvec)
924 {
925  enum psa_attest_err_t attest_err = PSA_ATTEST_ERR_SUCCESS;
926  struct q_useful_buf key_buffer;
927  uint8_t *key_source;
928  size_t key_len;
929  psa_ecc_family_t curve_type;
930 
931  (void)in_vec;
932 
933  if (num_invec != 0 || num_outvec != 3) {
934  attest_err = PSA_ATTEST_ERR_INVALID_INPUT;
935  goto error;
936  }
937 
938  key_buffer.ptr = out_vec[0].base;
939  key_buffer.len = out_vec[0].len;
940 
941  if (out_vec[1].len != sizeof(curve_type) ||
942  out_vec[2].len != sizeof(key_len)) {
943  attest_err = PSA_ATTEST_ERR_INVALID_INPUT;
944  goto error;
945  }
946 
947  attest_err = attest_get_initial_attestation_public_key(&key_source,
948  &key_len,
949  &curve_type);
950  if (attest_err != PSA_ATTEST_ERR_SUCCESS) {
951  goto error;
952  }
953 
954  if (key_buffer.len < key_len) {
955  attest_err = PSA_ATTEST_ERR_BUFFER_OVERFLOW;
956  goto error;
957  }
958 
959  (void)tfm_memcpy(key_buffer.ptr, key_source, key_len);
960 
961  *(psa_ecc_family_t *)out_vec[1].base = curve_type;
962 
963  *(size_t *)out_vec[2].base = key_len;
964 
965 error:
966  return error_mapping_to_psa_status_t(attest_err);
967 }
968 #endif /* SYMMETRIC_INITIAL_ATTESTATION */
enum attest_token_err_t attest_token_encode_finish(struct attest_token_encode_ctx *me, struct q_useful_buf_c *completed_token)
Finish the token, complete the signing and get the result.
Contains the received boot status information from bootloader.
Definition: attest_core.c:46
enum psa_attest_err_t attest_register_initial_attestation_key()
Register the initial attestation private key to Crypto service. Loads the public key if the key has n...
void * base
Definition: client.h:75
#define EAT_CBOR_ARM_LABEL_SECURITY_LIFECYCLE
psa_status_t initial_attest_get_token_size(const psa_invec *in_vec, uint32_t num_invec, psa_outvec *out_vec, uint32_t num_outvec)
Get the size of the initial attestation token.
Definition: attest_core.c:869
Attestation Token Creation Interface.
#define TLV_MAJOR_IAS
#define PSA_SUCCESS
Definition: crypto_values.h:35
#define PSA_ERROR_BUFFER_TOO_SMALL
Definition: crypto_values.h:77
#define EAT_CBOR_ARM_LABEL_NO_SW_COMPONENTS
void attest_token_encode_add_bstr(struct attest_token_encode_ctx *me, int32_t label, const struct q_useful_buf_c *value)
Add a binary string claim.
size_t len
Definition: client.h:68
struct tfm_spm_service_t service[]
attest_token_err_t
Definition: attest_token.h:50
psa_attest_err_t
Initial attestation service error types.
Definition: attest.h:25
enum attest_token_err_t attest_token_encode_start(struct attest_token_encode_ctx *me, uint32_t opt_flags, int32_t key_select, int32_t cose_alg_id, const struct q_useful_buf *out_buffer)
Initialize a token creation context.
uint16_t tlv_len
enum psa_attest_err_t attest_unregister_initial_attestation_key()
Unregister the initial attestation private key from Crypto service to do not occupy key slot...
#define SHARED_DATA_ENTRY_HEADER_SIZE
void attest_token_encode_add_integer(struct attest_token_encode_ctx *me, int32_t label, int64_t value)
Add a 64-bit signed integer claim.
psa_status_t initial_attest_get_public_key(const psa_invec *in_vec, uint32_t num_invec, psa_outvec *out_vec, uint32_t num_outvec)
Get the initial attestation public key.
Definition: attest_core.c:922
#define NO_SW_COMPONENT_FIXED_VALUE
enum psa_attest_err_t attest_get_initial_attestation_public_key(uint8_t **public_key, size_t *public_key_len, psa_ecc_family_t *public_key_curve)
Get the public key derived from the initial attestation private key.
#define SHARED_DATA_TLV_INFO_MAGIC
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48
#define TOKEN_OPT_OMIT_CLAIMS
Definition: attest_token.h:107
#define SW_MAX
#define T_COSE_ALGORITHM
Definition: attest_core.c:35
#define EAT_CBOR_ARM_LABEL_UEID
enum psa_attest_err_t attest_get_boot_data(uint8_t major_type, struct tfm_boot_data *boot_data, uint32_t len)
Copy the boot data (coming from boot loader) from shared memory area to service memory area...
Definition: tfm_attest.c:38
struct shared_data_tlv_header header
Definition: attest_core.c:47
#define SW_GENERAL
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64
#define PSA_ERROR_GENERIC_ERROR
Definition: crypto_values.h:43
#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32
#define PSA_ERROR_INVALID_ARGUMENT
void attest_token_encode_add_tstr(struct attest_token_encode_ctx *me, int32_t label, const struct q_useful_buf_c *value)
Add a text string claim.
#define EAT_CBOR_ARM_LABEL_CLIENT_ID
#define GET_IAS_MODULE(tlv_type)
Store the data for the runtime SW.
#define EAT_CBOR_ARM_LABEL_ORIGINATION
#define EAT_CBOR_ARM_LABEL_SW_COMPONENTS
#define SECURITY_LIFECYCLE
#define EAT_CBOR_ARM_LABEL_IMPLEMENTATION_ID
enum psa_attest_err_t attest_get_caller_client_id(int32_t *caller_id)
Get the ID of the caller thread.
Definition: tfm_attest.c:20
#define MAX_BOOT_STATUS
Definition: attest_core.c:25
QCBOREncodeContext * attest_token_encode_borrow_cbor_cntxt(struct attest_token_encode_ctx *me)
Get a copy of the CBOR encoding context.
#define PSA_ERROR_NOT_SUPPORTED
Definition: crypto_values.h:52
size_t len
Definition: client.h:76
__STATIC_INLINE void * tfm_memcpy(void *dest, const void *src, size_t num)
uint8_t data[512]
Definition: attest_core.c:48
enum psa_attest_err_t attest_get_instance_id(struct q_useful_buf_c *id_buf)
Get the buffer of Instance ID data.
psa_status_t initial_attest_get_token(const psa_invec *in_vec, uint32_t num_invec, psa_outvec *out_vec, uint32_t num_outvec)
Get initial attestation token.
Definition: attest_core.c:833
psa_status_t attest_init(void)
Initialise the initial attestation service during the TF-M boot up process.
Definition: attest_core.c:99
uint8_t psa_ecc_family_t
Definition: crypto_types.h:69
const void * base
Definition: client.h:67
#define EAT_CBOR_ARM_LABEL_PROFILE_DEFINITION
#define HW_VERSION
int32_t psa_status_t
Function return status.
Definition: crypto_types.h:43
#define EAT_CBOR_ARM_LABEL_HW_VERSION
#define EAT_CBOR_ARM_LABEL_CHALLENGE
#define PSA_ERROR_SERVICE_FAILURE
Definition: error.h:47
#define GET_IAS_CLAIM(tlv_type)
#define BOOT_SEED
#define EAT_CBOR_ARM_LABEL_BOOT_SEED