1 /*
2 * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "tfm_plat_provisioning.h"
9 #include "tfm_plat_otp.h"
10 #include "tfm_attest_hal.h"
11 #include "region_defs.h"
12 #include "bootutil/bootutil_log.h"
13 #include "string.h"
14 #include "provisioning_bundle.h"
15
16 static const volatile struct provisioning_bundle *bundle =
17 (const struct provisioning_bundle *)PROVISIONING_BUNDLE_START;
18
19 static enum tfm_plat_err_t provision_assembly_and_test(void);
20
tfm_plat_provisioning_check_for_dummy_keys(void)21 void tfm_plat_provisioning_check_for_dummy_keys(void)
22 {
23 uint64_t iak_start;
24
25 tfm_plat_otp_read(PLAT_OTP_ID_IAK, sizeof(iak_start), (uint8_t*)&iak_start);
26
27 if(iak_start == 0xA4906F6DB254B4A9) {
28 BOOT_LOG_WRN("%s%s%s%s",
29 "\033[1;31m",
30 "This device was provisioned with dummy keys. ",
31 "This device is \033[1;1mNOT SECURE",
32 "\033[0m");
33 }
34
35 memset(&iak_start, 0, sizeof(iak_start));
36
37 }
38
tfm_plat_provisioning_is_required(void)39 int tfm_plat_provisioning_is_required(void)
40 {
41 enum tfm_plat_err_t err;
42 enum plat_otp_lcs_t lcs;
43
44 err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
45 if (err != TFM_PLAT_ERR_SUCCESS) {
46 return err;
47 }
48
49 return lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST
50 || lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
51 }
52
tfm_plat_provisioning_perform(void)53 enum tfm_plat_err_t tfm_plat_provisioning_perform(void)
54 {
55 enum tfm_plat_err_t err;
56 enum plat_otp_lcs_t lcs;
57
58 err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs);
59 if (err != TFM_PLAT_ERR_SUCCESS) {
60 return err;
61 }
62
63 BOOT_LOG_INF("Beginning provisioning");
64 #ifdef TFM_DUMMY_PROVISIONING
65 BOOT_LOG_WRN("%s%s%s%s",
66 "\033[1;31m",
67 "TFM_DUMMY_PROVISIONING is not suitable for production! ",
68 "This device is \033[1;1mNOT SECURE",
69 "\033[0m");
70 #endif /* TFM_DUMMY_PROVISIONING */
71
72 if (lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST) {
73
74 BOOT_LOG_INF("Waiting for provisioning bundle");
75 while (bundle->magic != BUNDLE_MAGIC ||
76 bundle->magic2 != BUNDLE_MAGIC) {
77 }
78
79 err = provision_assembly_and_test();
80 if (err != TFM_PLAT_ERR_SUCCESS) {
81 return err;
82 }
83 }
84
85 return TFM_PLAT_ERR_SUCCESS;
86 }
87
provision_assembly_and_test(void)88 static enum tfm_plat_err_t provision_assembly_and_test(void)
89 {
90 enum tfm_plat_err_t err;
91
92 /* TODO replace this with decrypt and auth */
93 memcpy((void*)PROVISIONING_BUNDLE_CODE_START,
94 (void *)bundle->code,
95 PROVISIONING_BUNDLE_CODE_SIZE);
96 memcpy((void*)PROVISIONING_BUNDLE_DATA_START,
97 (void *)&bundle->data,
98 PROVISIONING_BUNDLE_DATA_SIZE);
99 memcpy((void*)PROVISIONING_BUNDLE_VALUES_START,
100 (void *)&bundle->values,
101 PROVISIONING_BUNDLE_VALUES_SIZE);
102
103 BOOT_LOG_INF("Running provisioning bundle");
104 err = ((enum tfm_plat_err_t (*)(void))(PROVISIONING_BUNDLE_CODE_START | 0b1))();
105
106 memset((void *)PROVISIONING_BUNDLE_CODE_START, 0,
107 PROVISIONING_BUNDLE_CODE_SIZE);
108 memset((void *)PROVISIONING_BUNDLE_DATA_START, 0,
109 PROVISIONING_BUNDLE_DATA_SIZE);
110 memset((void *)PROVISIONING_BUNDLE_VALUES_START, 0,
111 PROVISIONING_BUNDLE_VALUES_SIZE);
112
113 return err;
114 }
115