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