1 /*
2  * Copyright (c) 2021-2023, 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 *encrypted_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 (encrypted_bundle->magic != BUNDLE_MAGIC ||
76                encrypted_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 *)encrypted_bundle->code,
95            PROVISIONING_BUNDLE_CODE_SIZE);
96     memcpy((void*)PROVISIONING_BUNDLE_DATA_START,
97            (void *)&encrypted_bundle->data,
98            PROVISIONING_BUNDLE_DATA_SIZE);
99     memcpy((void*)PROVISIONING_BUNDLE_VALUES_START,
100            (void *)&encrypted_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