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