xref: /optee_os/core/tee/tee_fs_key_manager.c (revision 82ef73bc2be676a5bd5c1590acca8540869d1d4f)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2015, Linaro Limited
4  */
5 
6 
7 /*
8  * Acronyms:
9  *
10  * FEK - File Encryption Key
11  * SSK - Secure Storage Key
12  * TSK - Trusted app Storage Key
13  * IV  - Initial vector
14  * HUK - Hardware Unique Key
15  * RNG - Random Number Generator
16  */
17 
18 #include <compiler.h>
19 #include <crypto/crypto.h>
20 #include <initcall.h>
21 #include <kernel/panic.h>
22 #include <kernel/tee_common_otp.h>
23 #include <kernel/tee_ta_manager.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <tee/tee_cryp_utl.h>
27 #include <tee/tee_fs_key_manager.h>
28 #include <trace.h>
29 #include <util.h>
30 
31 struct tee_fs_ssk {
32 	bool is_init;
33 	uint8_t key[TEE_FS_KM_SSK_SIZE];
34 };
35 
36 static struct tee_fs_ssk tee_fs_ssk;
37 static uint8_t string_for_ssk_gen[] = "ONLY_FOR_tee_fs_ssk";
38 
39 
40 static TEE_Result do_hmac(void *out_key, size_t out_key_size,
41 			  const void *in_key, size_t in_key_size,
42 			  const void *message, size_t message_size)
43 {
44 	TEE_Result res;
45 	void *ctx = NULL;
46 
47 	if (!out_key || !in_key || !message)
48 		return TEE_ERROR_BAD_PARAMETERS;
49 
50 	res = crypto_mac_alloc_ctx(&ctx, TEE_FS_KM_HMAC_ALG);
51 	if (res != TEE_SUCCESS)
52 		return res;
53 
54 	res = crypto_mac_init(ctx, TEE_FS_KM_HMAC_ALG, in_key, in_key_size);
55 	if (res != TEE_SUCCESS)
56 		goto exit;
57 
58 	res = crypto_mac_update(ctx, TEE_FS_KM_HMAC_ALG, message, message_size);
59 	if (res != TEE_SUCCESS)
60 		goto exit;
61 
62 	res = crypto_mac_final(ctx, TEE_FS_KM_HMAC_ALG, out_key, out_key_size);
63 	if (res != TEE_SUCCESS)
64 		goto exit;
65 
66 	res = TEE_SUCCESS;
67 
68 exit:
69 	crypto_mac_free_ctx(ctx, TEE_FS_KM_HMAC_ALG);
70 	return res;
71 }
72 
73 TEE_Result tee_fs_fek_crypt(const TEE_UUID *uuid, TEE_OperationMode mode,
74 			    const uint8_t *in_key, size_t size,
75 			    uint8_t *out_key)
76 {
77 	TEE_Result res;
78 	uint8_t *ctx = NULL;
79 	size_t ctx_size;
80 	uint8_t tsk[TEE_FS_KM_TSK_SIZE];
81 	uint8_t dst_key[size];
82 
83 	if (!in_key || !out_key)
84 		return TEE_ERROR_BAD_PARAMETERS;
85 
86 	if (size != TEE_FS_KM_FEK_SIZE)
87 		return TEE_ERROR_BAD_PARAMETERS;
88 
89 	if (tee_fs_ssk.is_init == 0)
90 		return TEE_ERROR_GENERIC;
91 
92 	if (uuid) {
93 		res = do_hmac(tsk, sizeof(tsk), tee_fs_ssk.key,
94 			      TEE_FS_KM_SSK_SIZE, uuid, sizeof(*uuid));
95 		if (res != TEE_SUCCESS)
96 			return res;
97 	} else {
98 		/*
99 		 * Pick something of a different size than TEE_UUID to
100 		 * guarantee that there's never a conflict.
101 		 */
102 		uint8_t dummy[1] = { 0 };
103 
104 		res = do_hmac(tsk, sizeof(tsk), tee_fs_ssk.key,
105 			      TEE_FS_KM_SSK_SIZE, dummy, sizeof(dummy));
106 		if (res != TEE_SUCCESS)
107 			return res;
108 	}
109 
110 	res = crypto_cipher_get_ctx_size(TEE_FS_KM_ENC_FEK_ALG, &ctx_size);
111 	if (res != TEE_SUCCESS)
112 		return res;
113 
114 	ctx = malloc(ctx_size);
115 	if (!ctx)
116 		return TEE_ERROR_OUT_OF_MEMORY;
117 
118 	res = crypto_cipher_init(ctx, TEE_FS_KM_ENC_FEK_ALG, mode, tsk,
119 				 sizeof(tsk), NULL, 0, NULL, 0);
120 	if (res != TEE_SUCCESS)
121 		goto exit;
122 
123 	res = crypto_cipher_update(ctx, TEE_FS_KM_ENC_FEK_ALG,
124 				   mode, true, in_key, size, dst_key);
125 	if (res != TEE_SUCCESS)
126 		goto exit;
127 
128 	crypto_cipher_final(ctx, TEE_FS_KM_ENC_FEK_ALG);
129 
130 	memcpy(out_key, dst_key, sizeof(dst_key));
131 
132 exit:
133 	free(ctx);
134 
135 	return res;
136 }
137 
138 static TEE_Result generate_fek(uint8_t *key, uint8_t len)
139 {
140 	return crypto_rng_read(key, len);
141 }
142 
143 static TEE_Result tee_fs_init_key_manager(void)
144 {
145 	int res = TEE_SUCCESS;
146 	struct tee_hw_unique_key huk;
147 	uint8_t chip_id[TEE_FS_KM_CHIP_ID_LENGTH];
148 	uint8_t message[sizeof(chip_id) + sizeof(string_for_ssk_gen)];
149 
150 	/* Secure Storage Key Generation:
151 	 *
152 	 *     SSK = HMAC(HUK, message)
153 	 *     message := concatenate(chip_id, static string)
154 	 * */
155 	tee_otp_get_hw_unique_key(&huk);
156 	tee_otp_get_die_id(chip_id, sizeof(chip_id));
157 
158 	memcpy(message, chip_id, sizeof(chip_id));
159 	memcpy(message + sizeof(chip_id), string_for_ssk_gen,
160 			sizeof(string_for_ssk_gen));
161 
162 	res = do_hmac(tee_fs_ssk.key, sizeof(tee_fs_ssk.key),
163 			huk.data, sizeof(huk.data),
164 			message, sizeof(message));
165 
166 	if (res == TEE_SUCCESS)
167 		tee_fs_ssk.is_init = 1;
168 
169 	return res;
170 }
171 
172 TEE_Result tee_fs_generate_fek(const TEE_UUID *uuid, void *buf, size_t buf_size)
173 {
174 	TEE_Result res;
175 
176 	if (buf_size != TEE_FS_KM_FEK_SIZE)
177 		return TEE_ERROR_BAD_PARAMETERS;
178 
179 	res = generate_fek(buf, TEE_FS_KM_FEK_SIZE);
180 	if (res != TEE_SUCCESS)
181 		return res;
182 
183 	return tee_fs_fek_crypt(uuid, TEE_MODE_ENCRYPT, buf,
184 				TEE_FS_KM_FEK_SIZE, buf);
185 }
186 
187 static TEE_Result sha256(uint8_t *out, size_t out_size, const uint8_t *in,
188 			 size_t in_size)
189 {
190 	return tee_hash_createdigest(TEE_ALG_SHA256, in, in_size,
191 				     out, out_size);
192 }
193 
194 static TEE_Result aes_ecb(uint8_t out[TEE_AES_BLOCK_SIZE],
195 			  const uint8_t in[TEE_AES_BLOCK_SIZE],
196 			  const uint8_t *key, size_t key_size)
197 {
198 	TEE_Result res;
199 	uint8_t *ctx = NULL;
200 	size_t ctx_size;
201 	uint32_t algo = TEE_ALG_AES_ECB_NOPAD;
202 
203 	res = crypto_cipher_get_ctx_size(algo, &ctx_size);
204 	if (res != TEE_SUCCESS)
205 		return res;
206 
207 	ctx = malloc(ctx_size);
208 	if (!ctx)
209 		return TEE_ERROR_OUT_OF_MEMORY;
210 
211 	res = crypto_cipher_init(ctx, algo, TEE_MODE_ENCRYPT, key,
212 				 key_size, NULL, 0, NULL, 0);
213 	if (res != TEE_SUCCESS)
214 		goto out;
215 
216 	res = crypto_cipher_update(ctx, algo, TEE_MODE_ENCRYPT, true, in,
217 				   TEE_AES_BLOCK_SIZE, out);
218 	if (res != TEE_SUCCESS)
219 		goto out;
220 
221 	crypto_cipher_final(ctx, algo);
222 	res = TEE_SUCCESS;
223 
224 out:
225 	free(ctx);
226 	return res;
227 }
228 
229 static TEE_Result essiv(uint8_t iv[TEE_AES_BLOCK_SIZE],
230 			const uint8_t fek[TEE_FS_KM_FEK_SIZE],
231 			uint16_t blk_idx)
232 {
233 	TEE_Result res;
234 	uint8_t sha[TEE_SHA256_HASH_SIZE];
235 	uint8_t pad_blkid[TEE_AES_BLOCK_SIZE] = { 0, };
236 
237 	res = sha256(sha, sizeof(sha), fek, TEE_FS_KM_FEK_SIZE);
238 	if (res != TEE_SUCCESS)
239 		return res;
240 
241 	pad_blkid[0] = (blk_idx & 0xFF);
242 	pad_blkid[1] = (blk_idx & 0xFF00) >> 8;
243 
244 	return aes_ecb(iv, pad_blkid, sha, 16);
245 }
246 
247 /*
248  * Encryption/decryption of RPMB FS file data. This is AES CBC with ESSIV.
249  */
250 TEE_Result tee_fs_crypt_block(const TEE_UUID *uuid, uint8_t *out,
251 			      const uint8_t *in, size_t size,
252 			      uint16_t blk_idx, const uint8_t *encrypted_fek,
253 			      TEE_OperationMode mode)
254 {
255 	TEE_Result res;
256 	uint8_t fek[TEE_FS_KM_FEK_SIZE];
257 	uint8_t iv[TEE_AES_BLOCK_SIZE];
258 	uint8_t *ctx;
259 	size_t ctx_size;
260 	uint32_t algo = TEE_ALG_AES_CBC_NOPAD;
261 
262 	DMSG("%scrypt block #%u", (mode == TEE_MODE_ENCRYPT) ? "En" : "De",
263 	     blk_idx);
264 
265 	/* Decrypt FEK */
266 	res = tee_fs_fek_crypt(uuid, TEE_MODE_DECRYPT, encrypted_fek,
267 			       TEE_FS_KM_FEK_SIZE, fek);
268 	if (res != TEE_SUCCESS)
269 		return res;
270 
271 	/* Compute initialization vector for this block */
272 	res = essiv(iv, fek, blk_idx);
273 
274 	/* Run AES CBC */
275 	res = crypto_cipher_get_ctx_size(algo, &ctx_size);
276 	if (res != TEE_SUCCESS)
277 		return res;
278 	ctx = malloc(ctx_size);
279 	if (!ctx)
280 		return TEE_ERROR_OUT_OF_MEMORY;
281 
282 	res = crypto_cipher_init(ctx, algo, mode, fek, sizeof(fek), NULL,
283 				 0, iv, TEE_AES_BLOCK_SIZE);
284 	if (res != TEE_SUCCESS)
285 		goto exit;
286 	res = crypto_cipher_update(ctx, algo, mode, true, in, size, out);
287 	if (res != TEE_SUCCESS)
288 		goto exit;
289 
290 	crypto_cipher_final(ctx, algo);
291 
292 exit:
293 	free(ctx);
294 	return res;
295 }
296 
297 service_init_late(tee_fs_init_key_manager);
298