xref: /optee_os/core/drivers/stm32mp15_huk.c (revision 12fc37711783247b0d05fdc271ef007f4930767b)
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