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 static bool stm32mp15_huk_init; 19 20 static TEE_Result stm32mp15_read_uid(uint32_t *uid) 21 { 22 TEE_Result ret = TEE_ERROR_GENERIC; 23 uint32_t *q = uid; 24 uint32_t otp_idx = 0; 25 size_t __maybe_unused sz = 0; 26 27 ret = stm32_bsec_find_otp_in_nvmem_layout("uid_otp", &otp_idx, &sz); 28 if (ret) 29 return ret; 30 assert(sz == 3 * 32); 31 32 /* 33 * Shadow memory for UID words might not be locked: to guarante that 34 * the final values are read we must lock them. 35 */ 36 if (stm32_bsec_set_sw_lock(otp_idx) || 37 stm32_bsec_shadow_read_otp(q++, otp_idx)) 38 return TEE_ERROR_GENERIC; 39 40 if (stm32_bsec_set_sw_lock(otp_idx + 1) || 41 stm32_bsec_shadow_read_otp(q++, otp_idx + 1)) 42 return TEE_ERROR_GENERIC; 43 44 if (stm32_bsec_set_sw_lock(otp_idx + 2) || 45 stm32_bsec_shadow_read_otp(q++, otp_idx + 2)) 46 return TEE_ERROR_GENERIC; 47 48 return TEE_SUCCESS; 49 } 50 51 static TEE_Result stm32mp15_read_otp(uint32_t otp, uint32_t *key, bool *locked) 52 { 53 bool tmp = true; 54 uint32_t state = 0; 55 56 if (stm32_bsec_get_state(&state)) 57 panic(); 58 59 if (state != BSEC_STATE_SEC_CLOSED) { 60 /* 61 * When the device is not closed, the shadow memory for these 62 * words might not be locked: check and report them 63 */ 64 if (stm32_bsec_read_permanent_lock(otp, &tmp)) 65 return TEE_ERROR_GENERIC; 66 67 if (tmp && stm32_bsec_read_sw_lock(otp, &tmp)) 68 return TEE_ERROR_GENERIC; 69 } 70 71 if (stm32_bsec_shadow_read_otp(key, otp)) 72 return TEE_ERROR_GENERIC; 73 74 *locked = *locked && tmp; 75 76 return TEE_SUCCESS; 77 } 78 79 /* 80 * AES-GCM: nonce must be unique per message and key. 81 * 82 * This function always uses the same key - once its locked - with the same 83 * unique message hence the nonce can be any constant. 84 */ 85 static TEE_Result aes_gcm_encrypt_uid(uint8_t *key, size_t key_len, 86 uint8_t *out, size_t *out_len) 87 { 88 TEE_Result ret = TEE_ERROR_GENERIC; 89 const uint8_t nonce[12] = { 0x55 }; 90 uint32_t uid[4] = { 0 }; 91 uint8_t tag[16] = { 0 }; 92 size_t nonce_len = sizeof(nonce); 93 size_t tag_len = sizeof(tag); 94 size_t uid_len = sizeof(uid); 95 void *ctx = NULL; 96 97 ret = stm32mp15_read_uid(uid); 98 if (ret) 99 goto out; 100 101 ret = crypto_authenc_alloc_ctx(&ctx, TEE_ALG_AES_GCM); 102 if (ret) 103 goto out; 104 105 ret = crypto_authenc_init(ctx, TEE_MODE_ENCRYPT, key, key_len, nonce, 106 nonce_len, TEE_AES_BLOCK_SIZE, 0, uid_len); 107 if (ret) 108 goto out_free_ctx; 109 110 ret = crypto_authenc_enc_final(ctx, (uint8_t *)uid, sizeof(uid), 111 out, out_len, tag, &tag_len); 112 if (ret) 113 goto out_free_ctx; 114 115 crypto_authenc_final(ctx); 116 out_free_ctx: 117 crypto_authenc_free_ctx(ctx); 118 out: 119 if (ret) 120 memzero_explicit(out, *out_len); 121 122 return ret; 123 } 124 125 TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey) 126 { 127 uint32_t otp_key[4] = { 0 }; 128 size_t len = sizeof(otp_key); 129 TEE_Result ret = TEE_SUCCESS; 130 uint32_t *key = otp_key; 131 bool lock = true; 132 133 static_assert(CFG_STM32MP15_HUK_BSEC_KEY_0 < STM32MP1_OTP_MAX_ID); 134 static_assert(CFG_STM32MP15_HUK_BSEC_KEY_1 < STM32MP1_OTP_MAX_ID); 135 static_assert(CFG_STM32MP15_HUK_BSEC_KEY_2 < STM32MP1_OTP_MAX_ID); 136 static_assert(CFG_STM32MP15_HUK_BSEC_KEY_3 < STM32MP1_OTP_MAX_ID); 137 138 ret = stm32mp15_read_otp(CFG_STM32MP15_HUK_BSEC_KEY_0, key++, &lock); 139 if (ret) 140 goto out; 141 142 ret = stm32mp15_read_otp(CFG_STM32MP15_HUK_BSEC_KEY_1, key++, &lock); 143 if (ret) 144 goto out; 145 146 ret = stm32mp15_read_otp(CFG_STM32MP15_HUK_BSEC_KEY_2, key++, &lock); 147 if (ret) 148 goto out; 149 150 ret = stm32mp15_read_otp(CFG_STM32MP15_HUK_BSEC_KEY_3, key++, &lock); 151 if (ret) 152 goto out; 153 154 if (IS_ENABLED(CFG_STM32MP15_HUK_BSEC_KEY)) { 155 static_assert(sizeof(otp_key) == HW_UNIQUE_KEY_LENGTH); 156 memcpy(hwkey->data, otp_key, HW_UNIQUE_KEY_LENGTH); 157 ret = TEE_SUCCESS; 158 goto out; 159 } 160 161 if (IS_ENABLED(CFG_STM32MP15_HUK_BSEC_DERIVE_UID)) { 162 ret = aes_gcm_encrypt_uid((uint8_t *)otp_key, len, hwkey->data, 163 &len); 164 if (len != HW_UNIQUE_KEY_LENGTH) 165 ret = TEE_ERROR_GENERIC; 166 goto out; 167 } 168 169 panic(); 170 171 out: 172 memzero_explicit(otp_key, HW_UNIQUE_KEY_LENGTH); 173 174 if (!ret && !stm32mp15_huk_init) { 175 stm32mp15_huk_init = true; 176 IMSG("HUK %slocked", lock ? "" : "un"); 177 DHEXDUMP(hwkey->data, HW_UNIQUE_KEY_LENGTH); 178 } 179 180 return ret; 181 } 182 183