Raef Coles | aefbe08 | 2021-06-18 08:53:43 +0100 | [diff] [blame] | 1 | /* |
Tamas Ban | fc318d7 | 2022-06-22 14:23:52 +0200 | [diff] [blame] | 2 | * Copyright (c) 2021-2022, Arm Limited. All rights reserved. |
Raef Coles | aefbe08 | 2021-06-18 08:53:43 +0100 | [diff] [blame] | 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 "tfm_spm_log.h" |
Raef Coles | aefbe08 | 2021-06-18 08:53:43 +0100 | [diff] [blame] | 15 | |
| 16 | #include <string.h> |
| 17 | |
| 18 | #define ASSEMBLY_AND_TEST_PROV_DATA_MAGIC 0xC0DEFEED |
| 19 | #define PSA_ROT_PROV_DATA_MAGIC 0xBEEFFEED |
| 20 | |
| 21 | __PACKED_STRUCT tfm_assembly_and_test_provisioning_data_t { |
| 22 | uint32_t magic; |
| 23 | uint8_t huk[32]; |
| 24 | }; |
| 25 | |
| 26 | __PACKED_STRUCT tfm_psa_rot_provisioning_data_t { |
| 27 | uint32_t magic; |
| 28 | uint8_t iak[32]; |
| 29 | uint32_t iak_len; |
| 30 | uint32_t iak_type; |
| 31 | uint8_t iak_id[32]; |
| 32 | |
| 33 | uint8_t boot_seed[32]; |
| 34 | uint8_t implementation_id[32]; |
Tamas Ban | fc318d7 | 2022-06-22 14:23:52 +0200 | [diff] [blame] | 35 | uint8_t cert_ref[32]; |
Raef Coles | aefbe08 | 2021-06-18 08:53:43 +0100 | [diff] [blame] | 36 | uint8_t verification_service_url[32]; |
| 37 | uint8_t profile_definition[32]; |
| 38 | |
| 39 | uint8_t entropy_seed[64]; |
| 40 | }; |
| 41 | |
| 42 | #ifdef TFM_DUMMY_PROVISIONING |
| 43 | static const struct tfm_assembly_and_test_provisioning_data_t assembly_and_test_prov_data = { |
| 44 | ASSEMBLY_AND_TEST_PROV_DATA_MAGIC, |
| 45 | /* HUK */ |
| 46 | { |
| 47 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 48 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
| 49 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 50 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
| 51 | }, |
| 52 | }; |
| 53 | |
| 54 | static const struct tfm_psa_rot_provisioning_data_t psa_rot_prov_data = { |
| 55 | PSA_ROT_PROV_DATA_MAGIC, |
| 56 | /* IAK */ |
| 57 | { |
| 58 | 0xA9, 0xB4, 0x54, 0xB2, 0x6D, 0x6F, 0x90, 0xA4, |
| 59 | 0xEA, 0x31, 0x19, 0x35, 0x64, 0xCB, 0xA9, 0x1F, |
| 60 | 0xEC, 0x6F, 0x9A, 0x00, 0x2A, 0x7D, 0xC0, 0x50, |
| 61 | 0x4B, 0x92, 0xA1, 0x93, 0x71, 0x34, 0x58, 0x5F |
| 62 | }, |
| 63 | /* IAK len */ |
| 64 | 32, |
| 65 | #ifdef SYMMETRIC_INITIAL_ATTESTATION |
| 66 | /* IAK type */ |
| 67 | PSA_ALG_HMAC(PSA_ALG_SHA_256), |
| 68 | #else |
| 69 | /* IAK type */ |
| 70 | PSA_ECC_FAMILY_SECP_R1, |
| 71 | #endif /* SYMMETRIC_INITIAL_ATTESTATION */ |
| 72 | /* IAK id */ |
| 73 | "kid@trustedfirmware.example", |
| 74 | /* boot seed */ |
| 75 | { |
| 76 | 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, |
| 77 | 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, |
| 78 | 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, |
| 79 | 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, |
| 80 | }, |
| 81 | /* implementation id */ |
| 82 | { |
| 83 | 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, |
| 84 | 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, |
| 85 | 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, |
| 86 | 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, |
| 87 | }, |
Tamas Ban | fc318d7 | 2022-06-22 14:23:52 +0200 | [diff] [blame] | 88 | /* certification reference */ |
Tamas Ban | fbdbf66 | 2022-06-28 15:28:38 +0200 | [diff] [blame] | 89 | "0604565272829-10010", |
Raef Coles | aefbe08 | 2021-06-18 08:53:43 +0100 | [diff] [blame] | 90 | /* verification_service_url */ |
| 91 | "www.trustedfirmware.org", |
| 92 | /* attestation_profile_definition */ |
Tamas Ban | a7ef16b | 2022-06-28 15:03:10 +0200 | [diff] [blame] | 93 | #if defined(ATTEST_TOKEN_PROFILE_PSA_IOT_1) |
Raef Coles | aefbe08 | 2021-06-18 08:53:43 +0100 | [diff] [blame] | 94 | "PSA_IOT_PROFILE_1", |
Tamas Ban | a7ef16b | 2022-06-28 15:03:10 +0200 | [diff] [blame] | 95 | #elif defined(ATTEST_TOKEN_PROFILE_PSA_2_0_0) |
| 96 | "http://arm.com/psa/2.0.0", |
Tamas Ban | 7a32d9c | 2022-06-28 15:45:10 +0200 | [diff] [blame] | 97 | #elif defined(ATTEST_TOKEN_PROFILE_ARM_CCA) |
| 98 | "http://arm.com/CCA-SSD/1.0.0", |
Tamas Ban | a7ef16b | 2022-06-28 15:03:10 +0200 | [diff] [blame] | 99 | #else |
Raef Coles | 6e8dfd2 | 2022-07-29 12:57:47 +0100 | [diff] [blame] | 100 | #ifdef TFM_PARTITION_INITIAL_ATTESTATION |
Tamas Ban | a7ef16b | 2022-06-28 15:03:10 +0200 | [diff] [blame] | 101 | #error "Attestation token profile is incorrect" |
Raef Coles | 6e8dfd2 | 2022-07-29 12:57:47 +0100 | [diff] [blame] | 102 | #else |
| 103 | "UNDEFINED", |
| 104 | #endif /* TFM_PARTITION_INITIAL_ATTESTATION */ |
Tamas Ban | a7ef16b | 2022-06-28 15:03:10 +0200 | [diff] [blame] | 105 | #endif |
Raef Coles | aefbe08 | 2021-06-18 08:53:43 +0100 | [diff] [blame] | 106 | /* Entropy seed */ |
| 107 | { |
| 108 | 0x12, 0x13, 0x23, 0x34, 0x0a, 0x05, 0x89, 0x78, |
| 109 | 0xa3, 0x66, 0x8c, 0x0d, 0x97, 0x55, 0x53, 0xca, |
| 110 | 0xb5, 0x76, 0x18, 0x62, 0x29, 0xc6, 0xb6, 0x79, |
| 111 | 0x75, 0xc8, 0x5a, 0x8d, 0x9e, 0x11, 0x8f, 0x85, |
| 112 | 0xde, 0xc4, 0x5f, 0x66, 0x21, 0x52, 0xf9, 0x39, |
| 113 | 0xd9, 0x77, 0x93, 0x28, 0xb0, 0x5e, 0x02, 0xfa, |
| 114 | 0x58, 0xb4, 0x16, 0xc8, 0x0f, 0x38, 0x91, 0xbb, |
| 115 | 0x28, 0x17, 0xcd, 0x8a, 0xc9, 0x53, 0x72, 0x66, |
| 116 | }, |
| 117 | }; |
| 118 | #else |
| 119 | static struct tfm_assembly_and_test_provisioning_data_t assembly_and_test_prov_data; |
| 120 | static struct tfm_psa_rot_provisioning_data_t psa_rot_prov_data; |
| 121 | #endif /* TFM_DUMMY_PROVISIONING */ |
| 122 | |
| 123 | void tfm_plat_provisioning_check_for_dummy_keys(void) |
| 124 | { |
| 125 | uint64_t iak_start; |
| 126 | |
| 127 | tfm_plat_otp_read(PLAT_OTP_ID_IAK, sizeof(iak_start), (uint8_t*)&iak_start); |
| 128 | |
| 129 | if(iak_start == 0xA4906F6DB254B4A9) { |
| 130 | SPMLOG_ERRMSG("[WRN]\033[1;31m "); |
| 131 | SPMLOG_ERRMSG("This device was provisioned with dummy keys. "); |
| 132 | SPMLOG_ERRMSG("This device is \033[1;1mNOT SECURE"); |
| 133 | SPMLOG_ERRMSG("\033[0m\r\n"); |
| 134 | } |
| 135 | |
Ken Liu | b671d68 | 2022-05-12 20:39:29 +0800 | [diff] [blame] | 136 | memset(&iak_start, 0, sizeof(iak_start)); |
Raef Coles | aefbe08 | 2021-06-18 08:53:43 +0100 | [diff] [blame] | 137 | } |
| 138 | |
| 139 | int tfm_plat_provisioning_is_required(void) |
| 140 | { |
| 141 | enum tfm_plat_err_t err; |
| 142 | enum plat_otp_lcs_t lcs; |
| 143 | |
| 144 | err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs); |
| 145 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 146 | return err; |
| 147 | } |
| 148 | |
| 149 | return lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST |
| 150 | || lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING; |
| 151 | } |
| 152 | |
| 153 | enum tfm_plat_err_t provision_assembly_and_test(void) |
| 154 | { |
| 155 | enum tfm_plat_err_t err; |
| 156 | uint32_t new_lcs; |
| 157 | |
| 158 | err = tfm_plat_otp_write(PLAT_OTP_ID_HUK, sizeof(assembly_and_test_prov_data.huk), |
| 159 | assembly_and_test_prov_data.huk); |
| 160 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 161 | return err; |
| 162 | } |
| 163 | |
| 164 | new_lcs = PLAT_OTP_LCS_PSA_ROT_PROVISIONING; |
| 165 | err = tfm_plat_otp_write(PLAT_OTP_ID_LCS, sizeof(new_lcs), |
| 166 | (uint8_t*)&new_lcs); |
| 167 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 168 | return err; |
| 169 | } |
| 170 | |
| 171 | return err; |
| 172 | } |
| 173 | |
| 174 | enum tfm_plat_err_t provision_psa_rot(void) |
| 175 | { |
| 176 | enum tfm_plat_err_t err; |
| 177 | uint32_t new_lcs; |
| 178 | |
| 179 | err = tfm_plat_otp_write(PLAT_OTP_ID_IAK, |
| 180 | sizeof(psa_rot_prov_data.iak), |
| 181 | psa_rot_prov_data.iak); |
| 182 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 183 | return err; |
| 184 | } |
| 185 | err = tfm_plat_otp_write(PLAT_OTP_ID_IAK_LEN, |
| 186 | sizeof(psa_rot_prov_data.iak_len), |
| 187 | (uint8_t*)&psa_rot_prov_data.iak_len); |
| 188 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 189 | return err; |
| 190 | } |
| 191 | err = tfm_plat_otp_write(PLAT_OTP_ID_IAK_TYPE, |
| 192 | sizeof(psa_rot_prov_data.iak_type), |
| 193 | (uint8_t*)&psa_rot_prov_data.iak_type); |
| 194 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 195 | return err; |
| 196 | } |
| 197 | |
| 198 | #ifdef ATTEST_INCLUDE_COSE_KEY_ID |
| 199 | err = tfm_plat_otp_write(PLAT_OTP_ID_IAK_ID, |
| 200 | sizeof(psa_rot_prov_data.iak_id), |
| 201 | psa_rot_prov_data.iak_id); |
| 202 | if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) { |
| 203 | return err; |
| 204 | } |
| 205 | #endif /* ATTEST_INCLUDE_COSE_KEY_ID */ |
| 206 | |
| 207 | err = tfm_plat_otp_write(PLAT_OTP_ID_BOOT_SEED, |
| 208 | sizeof(psa_rot_prov_data.boot_seed), |
| 209 | psa_rot_prov_data.boot_seed); |
| 210 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 211 | return err; |
| 212 | } |
| 213 | err = tfm_plat_otp_write(PLAT_OTP_ID_IMPLEMENTATION_ID, |
| 214 | sizeof(psa_rot_prov_data.implementation_id), |
| 215 | psa_rot_prov_data.implementation_id); |
| 216 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 217 | return err; |
| 218 | } |
Tamas Ban | fc318d7 | 2022-06-22 14:23:52 +0200 | [diff] [blame] | 219 | err = tfm_plat_otp_write(PLAT_OTP_ID_CERT_REF, |
| 220 | sizeof(psa_rot_prov_data.cert_ref), |
| 221 | psa_rot_prov_data.cert_ref); |
Raef Coles | aefbe08 | 2021-06-18 08:53:43 +0100 | [diff] [blame] | 222 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 223 | return err; |
| 224 | } |
| 225 | err = tfm_plat_otp_write(PLAT_OTP_ID_VERIFICATION_SERVICE_URL, |
| 226 | sizeof(psa_rot_prov_data.verification_service_url), |
| 227 | psa_rot_prov_data.verification_service_url); |
| 228 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 229 | return err; |
| 230 | } |
| 231 | err = tfm_plat_otp_write(PLAT_OTP_ID_PROFILE_DEFINITION, |
| 232 | sizeof(psa_rot_prov_data.profile_definition), |
| 233 | psa_rot_prov_data.profile_definition); |
| 234 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 235 | return err; |
| 236 | } |
| 237 | |
| 238 | err = tfm_plat_otp_write(PLAT_OTP_ID_ENTROPY_SEED, |
| 239 | sizeof(psa_rot_prov_data.entropy_seed), |
| 240 | psa_rot_prov_data.entropy_seed); |
| 241 | if (err != TFM_PLAT_ERR_SUCCESS && err != TFM_PLAT_ERR_UNSUPPORTED) { |
| 242 | return err; |
| 243 | } |
| 244 | |
| 245 | new_lcs = PLAT_OTP_LCS_SECURED; |
| 246 | err = tfm_plat_otp_write(PLAT_OTP_ID_LCS, |
| 247 | sizeof(new_lcs), |
| 248 | (uint8_t*)&new_lcs); |
| 249 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 250 | return err; |
| 251 | } |
| 252 | |
| 253 | return err; |
| 254 | } |
| 255 | |
| 256 | enum tfm_plat_err_t tfm_plat_provisioning_perform(void) |
| 257 | { |
| 258 | enum tfm_plat_err_t err; |
| 259 | enum plat_otp_lcs_t lcs; |
| 260 | |
| 261 | err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs); |
| 262 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 263 | return err; |
| 264 | } |
| 265 | |
| 266 | SPMLOG_INFMSG("[INF] Beginning TF-M provisioning\r\n"); |
| 267 | |
| 268 | #ifdef TFM_DUMMY_PROVISIONING |
| 269 | SPMLOG_ERRMSG("[WRN]\033[1;31m "); |
| 270 | SPMLOG_ERRMSG("TFM_DUMMY_PROVISIONING is not suitable for production! "); |
| 271 | SPMLOG_ERRMSG("This device is \033[1;1mNOT SECURE"); |
| 272 | SPMLOG_ERRMSG("\033[0m\r\n"); |
| 273 | #endif /* TFM_DUMMY_PROVISIONING */ |
| 274 | |
| 275 | if (lcs == PLAT_OTP_LCS_ASSEMBLY_AND_TEST) { |
| 276 | if (assembly_and_test_prov_data.magic != ASSEMBLY_AND_TEST_PROV_DATA_MAGIC) { |
| 277 | SPMLOG_ERRMSG("No valid ASSEMBLY_AND_TEST provisioning data found\r\n"); |
| 278 | return TFM_PLAT_ERR_INVALID_INPUT; |
| 279 | } |
| 280 | |
| 281 | err = provision_assembly_and_test(); |
| 282 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 283 | return err; |
| 284 | } |
| 285 | } |
| 286 | |
| 287 | err = tfm_plat_otp_read(PLAT_OTP_ID_LCS, sizeof(lcs), (uint8_t*)&lcs); |
| 288 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 289 | return err; |
| 290 | } |
| 291 | if (lcs == PLAT_OTP_LCS_PSA_ROT_PROVISIONING) { |
| 292 | if (psa_rot_prov_data.magic != PSA_ROT_PROV_DATA_MAGIC) { |
| 293 | SPMLOG_ERRMSG("No valid PSA_ROT provisioning data found\r\n"); |
| 294 | return TFM_PLAT_ERR_INVALID_INPUT; |
| 295 | } |
| 296 | |
| 297 | err = provision_psa_rot(); |
| 298 | if (err != TFM_PLAT_ERR_SUCCESS) { |
| 299 | return err; |
| 300 | } |
| 301 | } |
| 302 | |
| 303 | return TFM_PLAT_ERR_SUCCESS; |
| 304 | } |