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