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