1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2022, Linaro Limited 4 * Copyright (c) 2022, Foundries.io Limited 5 */ 6 7 #include <assert.h> 8 #include <config.h> 9 #include <crypto/crypto.h> 10 #include <drivers/stm32_bsec.h> 11 #include <kernel/tee_common_otp.h> 12 #include <mempool.h> 13 #include <platform_config.h> 14 #include <stm32_util.h> 15 #include <string.h> 16 #include <string_ext.h> 17 18 #define HUK_NB_OTP (HW_UNIQUE_KEY_LENGTH / sizeof(uint32_t)) 19 20 static bool stm32mp15_huk_init; 21 22 static TEE_Result stm32mp15_read_uid(uint32_t *uid) 23 { 24 TEE_Result ret = TEE_ERROR_GENERIC; 25 uint32_t *q = uid; 26 uint32_t otp_idx = 0; 27 size_t __maybe_unused sz = 0; 28 29 ret = stm32_bsec_find_otp_in_nvmem_layout("uid_otp", &otp_idx, &sz); 30 if (ret) 31 return ret; 32 assert(sz == 3 * 32); 33 34 /* 35 * Shadow memory for UID words might not be locked: to guarante that 36 * the final values are read we must lock them. 37 */ 38 if (stm32_bsec_set_sw_lock(otp_idx) || 39 stm32_bsec_shadow_read_otp(q++, otp_idx)) 40 return TEE_ERROR_GENERIC; 41 42 if (stm32_bsec_set_sw_lock(otp_idx + 1) || 43 stm32_bsec_shadow_read_otp(q++, otp_idx + 1)) 44 return TEE_ERROR_GENERIC; 45 46 if (stm32_bsec_set_sw_lock(otp_idx + 2) || 47 stm32_bsec_shadow_read_otp(q++, otp_idx + 2)) 48 return TEE_ERROR_GENERIC; 49 50 return TEE_SUCCESS; 51 } 52 53 static TEE_Result stm32mp15_read_otp(uint32_t otp, uint32_t *key, bool *locked) 54 { 55 bool tmp = true; 56 uint32_t state = 0; 57 58 if (stm32_bsec_get_state(&state)) 59 panic(); 60 61 if (state != BSEC_STATE_SEC_CLOSED) { 62 /* 63 * When the device is not closed, the shadow memory for these 64 * words might not be locked: check and report them 65 */ 66 if (stm32_bsec_read_permanent_lock(otp, &tmp)) 67 return TEE_ERROR_GENERIC; 68 69 if (tmp && stm32_bsec_read_sw_lock(otp, &tmp)) 70 return TEE_ERROR_GENERIC; 71 } 72 73 if (stm32_bsec_shadow_read_otp(key, otp)) 74 return TEE_ERROR_GENERIC; 75 76 *locked = *locked && tmp; 77 78 return TEE_SUCCESS; 79 } 80 81 /* 82 * AES-GCM: nonce must be unique per message and key. 83 * 84 * This function always uses the same key - once its locked - with the same 85 * unique message hence the nonce can be any constant. 86 */ 87 static TEE_Result aes_gcm_encrypt_uid(uint8_t *key, size_t key_len, 88 uint8_t *out, size_t *out_len) 89 { 90 TEE_Result ret = TEE_ERROR_GENERIC; 91 const uint8_t nonce[12] = { 0x55 }; 92 uint32_t uid[4] = { 0 }; 93 uint8_t tag[16] = { 0 }; 94 size_t nonce_len = sizeof(nonce); 95 size_t tag_len = sizeof(tag); 96 size_t uid_len = sizeof(uid); 97 void *ctx = NULL; 98 99 ret = stm32mp15_read_uid(uid); 100 if (ret) 101 goto out; 102 103 ret = crypto_authenc_alloc_ctx(&ctx, TEE_ALG_AES_GCM); 104 if (ret) 105 goto out; 106 107 ret = crypto_authenc_init(ctx, TEE_MODE_ENCRYPT, key, key_len, nonce, 108 nonce_len, TEE_AES_BLOCK_SIZE, 0, uid_len); 109 if (ret) 110 goto out_free_ctx; 111 112 ret = crypto_authenc_enc_final(ctx, (uint8_t *)uid, sizeof(uid), 113 out, out_len, tag, &tag_len); 114 if (ret) 115 goto out_free_ctx; 116 117 crypto_authenc_final(ctx); 118 out_free_ctx: 119 crypto_authenc_free_ctx(ctx); 120 out: 121 if (ret) 122 memzero_explicit(out, *out_len); 123 124 return ret; 125 } 126 127 static __maybe_unused TEE_Result pos_from_dt(uint32_t otp_id[HUK_NB_OTP]) 128 { 129 TEE_Result ret = TEE_SUCCESS; 130 uint32_t otp_start = 0; 131 size_t tmp = 0; 132 size_t i = 0; 133 134 ret = stm32_bsec_find_otp_in_nvmem_layout("huk-otp", &otp_start, &tmp); 135 if (ret) 136 return ret; 137 138 if (tmp != (HW_UNIQUE_KEY_LENGTH * CHAR_BIT)) 139 return TEE_ERROR_SECURITY; 140 141 for (i = 0; i < HUK_NB_OTP; i++) 142 otp_id[i] = otp_start + i; 143 144 return TEE_SUCCESS; 145 } 146 147 static TEE_Result get_otp_pos(uint32_t otp_id[HUK_NB_OTP]) 148 { 149 #ifdef CFG_STM32_HUK_FROM_DT 150 return pos_from_dt(otp_id); 151 #else /* CFG_STM32_HUK_FROM_DT */ 152 153 static_assert(CFG_STM32MP15_HUK_BSEC_KEY_0 < STM32MP1_OTP_MAX_ID); 154 static_assert(CFG_STM32MP15_HUK_BSEC_KEY_1 < STM32MP1_OTP_MAX_ID); 155 static_assert(CFG_STM32MP15_HUK_BSEC_KEY_2 < STM32MP1_OTP_MAX_ID); 156 static_assert(CFG_STM32MP15_HUK_BSEC_KEY_3 < STM32MP1_OTP_MAX_ID); 157 158 otp_id[0] = CFG_STM32MP15_HUK_BSEC_KEY_0; 159 otp_id[1] = CFG_STM32MP15_HUK_BSEC_KEY_1; 160 otp_id[2] = CFG_STM32MP15_HUK_BSEC_KEY_2; 161 otp_id[3] = CFG_STM32MP15_HUK_BSEC_KEY_3; 162 163 return TEE_SUCCESS; 164 #endif /* CFG_STM32_HUK_FROM_DT */ 165 } 166 167 TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey) 168 { 169 uint32_t otp_key[HUK_NB_OTP] = { }; 170 uint32_t otp_id[HUK_NB_OTP] = { }; 171 size_t len = HW_UNIQUE_KEY_LENGTH; 172 TEE_Result ret = TEE_SUCCESS; 173 uint32_t *key = otp_key; 174 bool lock = true; 175 size_t i = 0; 176 177 ret = get_otp_pos(otp_id); 178 if (ret) 179 return ret; 180 181 for (i = 0; i < HUK_NB_OTP; i++) { 182 ret = stm32mp15_read_otp(otp_id[i], key++, &lock); 183 if (ret) 184 goto out; 185 } 186 187 if (IS_ENABLED(CFG_STM32MP15_HUK_BSEC_KEY)) { 188 static_assert(sizeof(otp_key) == HW_UNIQUE_KEY_LENGTH); 189 memcpy(hwkey->data, otp_key, HW_UNIQUE_KEY_LENGTH); 190 ret = TEE_SUCCESS; 191 goto out; 192 } 193 194 if (IS_ENABLED(CFG_STM32MP15_HUK_BSEC_DERIVE_UID)) { 195 ret = aes_gcm_encrypt_uid((uint8_t *)otp_key, len, hwkey->data, 196 &len); 197 if (len != HW_UNIQUE_KEY_LENGTH) 198 ret = TEE_ERROR_GENERIC; 199 goto out; 200 } 201 202 panic(); 203 204 out: 205 memzero_explicit(otp_key, HW_UNIQUE_KEY_LENGTH); 206 207 if (!ret && !stm32mp15_huk_init) { 208 stm32mp15_huk_init = true; 209 IMSG("HUK %slocked", lock ? "" : "un"); 210 DHEXDUMP(hwkey->data, HW_UNIQUE_KEY_LENGTH); 211 } 212 213 return ret; 214 } 215 216