1 /*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright The TrustedFirmware-M Contributors
4 */
5
6 #include <stddef.h>
7 #include <stdint.h>
8 #include <string.h>
9 #include "tfm_attest_hal.h"
10 #include "tfm_plat_boot_seed.h"
11 #include "tfm_plat_device_id.h"
12 #include "tfm_plat_otp.h"
13 #include "tfm_strnlen.h"
14 #include "pico/bootrom.h"
15 #include "pico/sha256.h"
16
map_otp_lcs_to_tfm_slc(enum plat_otp_lcs_t lcs)17 static enum tfm_security_lifecycle_t map_otp_lcs_to_tfm_slc(enum plat_otp_lcs_t lcs) {
18 switch (lcs) {
19 case PLAT_OTP_LCS_ASSEMBLY_AND_TEST:
20 return TFM_SLC_ASSEMBLY_AND_TEST;
21 case PLAT_OTP_LCS_PSA_ROT_PROVISIONING:
22 return TFM_SLC_PSA_ROT_PROVISIONING;
23 case PLAT_OTP_LCS_SECURED:
24 return TFM_SLC_SECURED;
25 case PLAT_OTP_LCS_DECOMMISSIONED:
26 return TFM_SLC_DECOMMISSIONED;
27 case PLAT_OTP_LCS_UNKNOWN:
28 default:
29 return TFM_SLC_UNKNOWN;
30 }
31 }
32
tfm_attest_hal_get_security_lifecycle(void)33 enum tfm_security_lifecycle_t tfm_attest_hal_get_security_lifecycle(void)
34 {
35 enum plat_otp_lcs_t otp_lcs;
36 enum tfm_plat_err_t err;
37
38 err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(otp_lcs), (uint8_t*)&otp_lcs);
39 if (err != TFM_PLAT_ERR_SUCCESS) {
40 return TFM_SLC_UNKNOWN;
41 }
42
43 return map_otp_lcs_to_tfm_slc(otp_lcs);
44 }
45
46 enum tfm_plat_err_t
tfm_attest_hal_get_verification_service(uint32_t * size,uint8_t * buf)47 tfm_attest_hal_get_verification_service(uint32_t *size, uint8_t *buf)
48 {
49 enum tfm_plat_err_t err;
50 size_t otp_size;
51 size_t copy_size;
52
53 err = tfm_plat_otp_read(PLAT_OTP_ID_VERIFICATION_SERVICE_URL, *size, buf);
54 if(err != TFM_PLAT_ERR_SUCCESS) {
55 return err;
56 }
57
58 err = tfm_plat_otp_get_size(PLAT_OTP_ID_VERIFICATION_SERVICE_URL, &otp_size);
59 if(err != TFM_PLAT_ERR_SUCCESS) {
60 return err;
61 }
62
63 /* Actually copied data is always the smaller */
64 copy_size = (*size < otp_size) ? *size : otp_size;
65 /* String content */
66 *size = tfm_strnlen((char*)buf, copy_size);
67
68 return TFM_PLAT_ERR_SUCCESS;
69 }
70
71 enum tfm_plat_err_t
tfm_attest_hal_get_profile_definition(uint32_t * size,uint8_t * buf)72 tfm_attest_hal_get_profile_definition(uint32_t *size, uint8_t *buf)
73 {
74 enum tfm_plat_err_t err;
75 size_t otp_size;
76 size_t copy_size;
77
78 err = tfm_plat_otp_read(PLAT_OTP_ID_PROFILE_DEFINITION, *size, buf);
79 if(err != TFM_PLAT_ERR_SUCCESS) {
80 return err;
81 }
82
83 err = tfm_plat_otp_get_size(PLAT_OTP_ID_PROFILE_DEFINITION, &otp_size);
84 if(err != TFM_PLAT_ERR_SUCCESS) {
85 return err;
86 }
87
88 /* Actually copied data is always the smaller */
89 copy_size = (*size < otp_size) ? *size : otp_size;
90 /* String content */
91 *size = tfm_strnlen((char*)buf, copy_size);
92
93 return TFM_PLAT_ERR_SUCCESS;
94 }
95
96 #if BOOT_SEED_SIZE != SHA256_RESULT_BYTES
97 #error "boot seed size not equal to SHA256_RESULT_BYTES"
98 #endif
99
tfm_plat_get_boot_seed(uint32_t size,uint8_t * buf)100 enum tfm_plat_err_t tfm_plat_get_boot_seed(uint32_t size, uint8_t *buf)
101 {
102 uint32_t out[4];
103 if (!rom_get_boot_random(out)) {
104 return TFM_PLAT_ERR_SYSTEM_ERR;
105 }
106 pico_sha256_state_t state;
107 if (pico_sha256_start_blocking(&state, SHA256_BIG_ENDIAN, false) != PICO_OK) {
108 return TFM_PLAT_ERR_SYSTEM_ERR;
109 }
110 pico_sha256_update_blocking(&state, (const uint8_t*)out, sizeof(out));
111 sha256_result_t result;
112 pico_sha256_finish(&state, &result);
113
114 memcpy(buf, result.bytes, size);
115
116 return TFM_PLAT_ERR_SUCCESS;
117 }
118
tfm_plat_get_implementation_id(uint32_t * size,uint8_t * buf)119 enum tfm_plat_err_t tfm_plat_get_implementation_id(uint32_t *size,
120 uint8_t *buf)
121 {
122 enum tfm_plat_err_t err;
123 size_t otp_size;
124 size_t copy_size;
125
126 err = tfm_plat_otp_read(PLAT_OTP_ID_IMPLEMENTATION_ID, *size, buf);
127 if(err != TFM_PLAT_ERR_SUCCESS) {
128 return err;
129 }
130
131 err = tfm_plat_otp_get_size(PLAT_OTP_ID_IMPLEMENTATION_ID, &otp_size);
132 if(err != TFM_PLAT_ERR_SUCCESS) {
133 return err;
134 }
135
136 /* Actually copied data is always the smaller */
137 copy_size = (*size < otp_size) ? *size : otp_size;
138 /* Binary data */
139 *size = copy_size;
140
141 return TFM_PLAT_ERR_SUCCESS;
142 }
143
tfm_plat_get_cert_ref(uint32_t * size,uint8_t * buf)144 enum tfm_plat_err_t tfm_plat_get_cert_ref(uint32_t *size, uint8_t *buf)
145 {
146 enum tfm_plat_err_t err;
147 size_t otp_size;
148 size_t copy_size;
149
150 err = tfm_plat_otp_read(PLAT_OTP_ID_CERT_REF, *size, buf);
151 if(err != TFM_PLAT_ERR_SUCCESS) {
152 return err;
153 }
154
155 err = tfm_plat_otp_get_size(PLAT_OTP_ID_CERT_REF, &otp_size);
156 if(err != TFM_PLAT_ERR_SUCCESS) {
157 return err;
158 }
159
160 /* Actually copied data is always the smaller */
161 copy_size = (*size < otp_size) ? *size : otp_size;
162 /* String content */
163 *size = tfm_strnlen((char*)buf, copy_size);
164
165 return TFM_PLAT_ERR_SUCCESS;
166 }
167
tfm_attest_hal_get_platform_config(uint32_t * size,uint8_t * buf)168 enum tfm_plat_err_t tfm_attest_hal_get_platform_config(uint32_t *size,
169 uint8_t *buf)
170 {
171 uint32_t dummy_plat_config = 0xDEADBEEF;
172
173 if (*size < sizeof(dummy_plat_config)) {
174 return TFM_PLAT_ERR_SYSTEM_ERR;
175 }
176
177 memcpy(buf, &dummy_plat_config, sizeof(dummy_plat_config));
178 *size = sizeof(dummy_plat_config);
179
180 return TFM_PLAT_ERR_SUCCESS;
181 }
182
tfm_attest_hal_get_platform_hash_algo(uint32_t * size,const char ** buf)183 enum tfm_plat_err_t tfm_attest_hal_get_platform_hash_algo(uint32_t *size,
184 const char **buf)
185 {
186 #ifdef MEASUREMENT_HASH_ALGO_NAME
187 static const char hash_algo[] = MEASUREMENT_HASH_ALGO_NAME;
188 #else
189 static const char hash_algo[] = "not-hash-extended";
190 #endif
191
192 /* Not including the null-terminator. */
193 *size = (uint32_t)sizeof(hash_algo) - 1;
194 *buf = hash_algo;
195
196 return TFM_PLAT_ERR_SUCCESS;
197 }
198