1 /*
2 * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "tfm_plat_provisioning.h"
9
10 #include "cmsis_compiler.h"
11 #include "tfm_plat_otp.h"
12 #include "tfm_attest_hal.h"
13 #include "psa/crypto.h"
14 #include "region_defs.h"
15 #include "log.h"
16
17 #include <string.h>
18
19 #define ASSEMBLY_AND_TEST_PROV_DATA_MAGIC 0xC0DEFEED
20
21 __PACKED_STRUCT bl1_assembly_and_test_provisioning_data_t {
22 uint32_t magic;
23 uint8_t bl2_encryption_key[32];
24 uint8_t guk[32];
25 uint8_t bl1_2_image_hash[32];
26 uint8_t bl2_image_hash[32];
27 uint8_t bl1_2_image[BL1_2_CODE_SIZE];
28 uint8_t bl1_rotpk_0[56];
29 };
30
31 static const struct bl1_assembly_and_test_provisioning_data_t *bl1_assembly_and_test_prov_data =
32 (struct bl1_assembly_and_test_provisioning_data_t *)PROVISIONING_DATA_START;
33
tfm_plat_provisioning_check_for_dummy_keys(void)34 void tfm_plat_provisioning_check_for_dummy_keys(void)
35 {
36 uint64_t guk_start;
37
38 tfm_plat_otp_read(PLAT_OTP_ID_GUK, sizeof(guk_start), (uint8_t *)&guk_start);
39
40 if (guk_start == 0x0706050403020100) {
41 BL1_LOG("\033[1;31m[WRN] ");
42 BL1_LOG("This device was provisioned with dummy keys. ");
43 BL1_LOG("This device is \033[1;1mNOT SECURE");
44 BL1_LOG("\033[0m\r\n");
45 }
46
47 memset(&guk_start, 0, sizeof(guk_start));
48 }
49
tfm_plat_provisioning_is_required(void)50 int tfm_plat_provisioning_is_required(void)
51 {
52 enum tfm_plat_err_t err;
53 enum plat_otp_lcs_t lcs;
54
55 err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t *)&lcs);
56 if (err != TFM_PLAT_ERR_SUCCESS) {
57 return err;
58 }
59
60 return lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST
61 || lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING;
62 }
63
provision_assembly_and_test(void)64 enum tfm_plat_err_t provision_assembly_and_test(void)
65 {
66 enum tfm_plat_err_t err;
67
68 err = tfm_plat_otp_write(PLAT_OTP_ID_KEY_BL2_ENCRYPTION,
69 sizeof(bl1_assembly_and_test_prov_data->bl2_encryption_key),
70 bl1_assembly_and_test_prov_data->bl2_encryption_key);
71 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
72 return err;
73 }
74
75 err = tfm_plat_otp_write(PLAT_OTP_ID_GUK,
76 sizeof(bl1_assembly_and_test_prov_data->guk),
77 bl1_assembly_and_test_prov_data->guk);
78 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
79 return err;
80 }
81
82 err = tfm_plat_otp_write(PLAT_OTP_ID_BL1_2_IMAGE_HASH,
83 sizeof(bl1_assembly_and_test_prov_data->bl1_2_image_hash),
84 bl1_assembly_and_test_prov_data->bl1_2_image_hash);
85 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
86 return err;
87 }
88
89 err = tfm_plat_otp_write(PLAT_OTP_ID_BL2_IMAGE_HASH,
90 sizeof(bl1_assembly_and_test_prov_data->bl2_image_hash),
91 bl1_assembly_and_test_prov_data->bl2_image_hash);
92 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
93 return err;
94 }
95
96 err = tfm_plat_otp_write(PLAT_OTP_ID_BL1_2_IMAGE,
97 sizeof(bl1_assembly_and_test_prov_data->bl1_2_image),
98 bl1_assembly_and_test_prov_data->bl1_2_image);
99 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
100 return err;
101 }
102
103 err = tfm_plat_otp_write(PLAT_OTP_ID_BL1_ROTPK_0,
104 sizeof(bl1_assembly_and_test_prov_data->bl1_rotpk_0),
105 bl1_assembly_and_test_prov_data->bl1_rotpk_0);
106 if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) {
107 return err;
108 }
109
110 return err;
111 }
112
tfm_plat_provisioning_perform(void)113 enum tfm_plat_err_t tfm_plat_provisioning_perform(void)
114 {
115 enum tfm_plat_err_t err;
116 enum plat_otp_lcs_t lcs;
117
118 err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t *)&lcs);
119 if (err != TFM_PLAT_ERR_SUCCESS) {
120 return err;
121 }
122
123 BL1_LOG("[INF] Beginning BL1 provisioning\r\n");
124
125 #ifdef TFM_DUMMY_PROVISIONING
126 BL1_LOG("\033[1;31m[WRN] ");
127 BL1_LOG("TFM_DUMMY_PROVISIONING is not suitable for production! ");
128 BL1_LOG("This device is \033[1;1mNOT SECURE");
129 BL1_LOG("\033[0m\r\n");
130 #endif /* TFM_DUMMY_PROVISIONING */
131
132 if (lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST) {
133 if (bl1_assembly_and_test_prov_data->magic != ASSEMBLY_AND_TEST_PROV_DATA_MAGIC) {
134 BL1_LOG("[ERR] No valid ASSEMBLY_AND_TEST provisioning data found\r\n");
135 return TFM_PLAT_ERR_INVALID_INPUT;
136 }
137
138 err = tfm_plat_otp_secure_provisioning_start();
139 if (err != TFM_PLAT_ERR_SUCCESS) {
140 return err;
141 }
142
143 err = provision_assembly_and_test();
144 if (err != TFM_PLAT_ERR_SUCCESS) {
145 return err;
146 }
147
148 err = tfm_plat_otp_secure_provisioning_finish();
149 if (err != TFM_PLAT_ERR_SUCCESS) {
150 return err;
151 }
152 }
153
154 return TFM_PLAT_ERR_SUCCESS;
155 }
156