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