xref: /optee_os/core/tee/tee_fs_key_manager.c (revision 9403c583381528e7fb391e3769644cc9653cfbb6)
1 /*
2  * Copyright (c) 2015, Linaro Limited
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 
29 /* Acronyms:
30  *
31  * FEK - File Encryption Key
32  * SST - Secure Storage
33  * SSK - Secure Storage Key
34  * IV  - Initial vector
35  * HUK - Hardware Unique Key
36  * RNG - Random Number Generator
37  *
38  * */
39 
40 #include <initcall.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <kernel/tee_common_otp.h>
44 #include <kernel/tee_common_unpg.h>
45 #include <tee/tee_cryp_utl.h>
46 #include <tee/tee_cryp_provider.h>
47 #include <tee/tee_fs_key_manager.h>
48 #include <compiler.h>
49 #include <trace.h>
50 
51 struct tee_fs_ssk {
52 	bool is_init;
53 	uint8_t key[TEE_FS_KM_SSK_SIZE];
54 };
55 
56 struct aad {
57 	const uint8_t *encrypted_key;
58 	const uint8_t *iv;
59 };
60 
61 struct km_header {
62 	struct aad aad;
63 	uint8_t *tag;
64 };
65 
66 static struct tee_fs_ssk tee_fs_ssk;
67 static uint8_t string_for_ssk_gen[] = "ONLY_FOR_tee_fs_ssk";
68 
69 
70 static TEE_Result fek_crypt(TEE_OperationMode mode,
71 		uint8_t *key, int size)
72 {
73 	TEE_Result res;
74 	uint8_t *ctx = NULL;
75 	size_t ctx_size;
76 	uint8_t dst_key[TEE_FS_KM_FEK_SIZE];
77 
78 	if (!key)
79 		return TEE_ERROR_BAD_PARAMETERS;
80 
81 	if (size != TEE_FS_KM_FEK_SIZE)
82 		return TEE_ERROR_BAD_PARAMETERS;
83 
84 	if (tee_fs_ssk.is_init == 0)
85 		return TEE_ERROR_GENERIC;
86 
87 	res = crypto_ops.cipher.get_ctx_size(TEE_FS_KM_ENC_FEK_ALG, &ctx_size);
88 	if (res != TEE_SUCCESS)
89 		return res;
90 
91 	ctx = malloc(ctx_size);
92 	if (!ctx)
93 		return TEE_ERROR_OUT_OF_MEMORY;
94 
95 	res = crypto_ops.cipher.init(ctx, TEE_FS_KM_ENC_FEK_ALG,
96 			mode, tee_fs_ssk.key, TEE_FS_KM_SSK_SIZE,
97 			NULL, 0, NULL, 0);
98 	if (res != TEE_SUCCESS)
99 		goto exit;
100 
101 	res = crypto_ops.cipher.update(ctx, TEE_FS_KM_ENC_FEK_ALG,
102 			mode, true, key, size, dst_key);
103 	if (res != TEE_SUCCESS)
104 		goto exit;
105 
106 	crypto_ops.cipher.final(ctx, TEE_FS_KM_ENC_FEK_ALG);
107 
108 	memcpy(key, dst_key, sizeof(dst_key));
109 
110 exit:
111 	free(ctx);
112 
113 	return res;
114 }
115 
116 static TEE_Result generate_fek(uint8_t *key, uint8_t len)
117 {
118 	return crypto_ops.prng.read(key, len);
119 }
120 
121 static TEE_Result generate_iv(uint8_t *iv, uint8_t len)
122 {
123 	return crypto_ops.prng.read(iv, len);
124 }
125 
126 static TEE_Result generate_ssk(uint8_t *ssk, uint32_t ssk_size,
127 			uint8_t *huk, uint32_t huk_size,
128 			uint8_t *message, uint32_t message_size)
129 {
130 	TEE_Result res = TEE_ERROR_GENERIC;
131 	uint8_t *ctx = NULL;
132 	size_t hash_ctx_size = 0;
133 
134 	if (!ssk || !huk || !message)
135 		return TEE_ERROR_BAD_PARAMETERS;
136 
137 	res = crypto_ops.mac.get_ctx_size(TEE_FS_KM_HMAC_ALG, &hash_ctx_size);
138 	if (res != TEE_SUCCESS)
139 		return res;
140 
141 	ctx = malloc(hash_ctx_size);
142 	if (!ctx)
143 		return TEE_ERROR_OUT_OF_MEMORY;
144 
145 	res = crypto_ops.mac.init(ctx, TEE_FS_KM_HMAC_ALG, huk, huk_size);
146 	if (res != TEE_SUCCESS)
147 		goto exit;
148 
149 	res = crypto_ops.mac.update(ctx, TEE_FS_KM_HMAC_ALG,
150 			message, message_size);
151 	if (res != TEE_SUCCESS)
152 		goto exit;
153 
154 	res = crypto_ops.hash.final(ctx, TEE_FS_KM_HMAC_ALG, ssk, ssk_size);
155 	if (res != TEE_SUCCESS)
156 		goto exit;
157 
158 	res = TEE_SUCCESS;
159 
160 exit:
161 	free(ctx);
162 	return res;
163 }
164 
165 static TEE_Result tee_fs_init_key_manager(void)
166 {
167 	int res = TEE_SUCCESS;
168 	struct tee_hw_unique_key huk;
169 	uint8_t chip_id[TEE_FS_KM_CHIP_ID_LENGTH];
170 	uint8_t message[sizeof(chip_id) + sizeof(string_for_ssk_gen)];
171 
172 	/* Secure Storage Key Generation:
173 	 *
174 	 *     SSK = HMAC(HUK, message)
175 	 *     message := concatenate(chip_id, static string)
176 	 * */
177 	tee_otp_get_hw_unique_key(&huk);
178 	tee_otp_get_die_id(chip_id, sizeof(chip_id));
179 
180 	memcpy(message, chip_id, sizeof(chip_id));
181 	memcpy(message + sizeof(chip_id), string_for_ssk_gen,
182 			sizeof(string_for_ssk_gen));
183 
184 	res = generate_ssk(tee_fs_ssk.key, sizeof(tee_fs_ssk.key),
185 			huk.data, sizeof(huk.data),
186 			message, sizeof(message));
187 
188 	if (res == TEE_SUCCESS)
189 		tee_fs_ssk.is_init = 1;
190 
191 	return res;
192 }
193 
194 static TEE_Result do_auth_enc(TEE_OperationMode mode,
195 		struct km_header *hdr,
196 		uint8_t *fek, int fek_len,
197 		const uint8_t *data_in, size_t in_size,
198 		uint8_t *data_out, size_t *out_size)
199 {
200 	TEE_Result res = TEE_SUCCESS;
201 	uint8_t *ctx = NULL;
202 	size_t ctx_size;
203 	size_t tag_len = TEE_FS_KM_MAX_TAG_LEN;
204 
205 	if ((mode != TEE_MODE_ENCRYPT) && (mode != TEE_MODE_DECRYPT))
206 		return TEE_ERROR_BAD_PARAMETERS;
207 
208 	if (*out_size < in_size) {
209 		EMSG("output buffer(%zd) < input buffer(%zd)",
210 				*out_size, in_size);
211 		return TEE_ERROR_SHORT_BUFFER;
212 	}
213 
214 	res = crypto_ops.authenc.get_ctx_size(TEE_FS_KM_AUTH_ENC_ALG,
215 			&ctx_size);
216 	if (res != TEE_SUCCESS)
217 		return res;
218 
219 	ctx = malloc(ctx_size);
220 	if (!ctx) {
221 		EMSG("request memory size %zu failed", ctx_size);
222 		return TEE_ERROR_OUT_OF_MEMORY;
223 	}
224 
225 	res = crypto_ops.authenc.init(ctx, TEE_FS_KM_AUTH_ENC_ALG,
226 			mode, fek, fek_len, hdr->aad.iv,
227 			TEE_FS_KM_IV_LEN, TEE_FS_KM_MAX_TAG_LEN,
228 			sizeof(struct aad), in_size);
229 	if (res != TEE_SUCCESS)
230 		goto exit;
231 
232 	res = crypto_ops.authenc.update_aad(ctx, TEE_FS_KM_AUTH_ENC_ALG,
233 			mode, (uint8_t *)hdr->aad.encrypted_key,
234 			TEE_FS_KM_FEK_SIZE);
235 	if (res != TEE_SUCCESS)
236 		goto exit;
237 
238 	res = crypto_ops.authenc.update_aad(ctx, TEE_FS_KM_AUTH_ENC_ALG,
239 			mode, (uint8_t *)hdr->aad.iv,
240 			TEE_FS_KM_IV_LEN);
241 	if (res != TEE_SUCCESS)
242 		goto exit;
243 
244 	if (mode == TEE_MODE_ENCRYPT) {
245 		res = crypto_ops.authenc.enc_final(ctx, TEE_FS_KM_AUTH_ENC_ALG,
246 				data_in, in_size, data_out, out_size,
247 				hdr->tag, &tag_len);
248 	} else {
249 		res = crypto_ops.authenc.dec_final(ctx, TEE_FS_KM_AUTH_ENC_ALG,
250 				data_in, in_size, data_out, out_size,
251 				hdr->tag, tag_len);
252 	}
253 
254 	if (res != TEE_SUCCESS)
255 		goto exit;
256 
257 	crypto_ops.authenc.final(ctx, TEE_FS_KM_AUTH_ENC_ALG);
258 
259 exit:
260 	free(ctx);
261 	return res;
262 }
263 
264 size_t tee_fs_get_header_size(enum tee_fs_file_type type)
265 {
266 	size_t header_size = 0;
267 
268 	switch (type) {
269 	case META_FILE:
270 		header_size = sizeof(struct meta_header);
271 		break;
272 	case BLOCK_FILE:
273 		header_size = sizeof(struct block_header);
274 		break;
275 	default:
276 		EMSG("Unknown file type, type=%d", type);
277 		TEE_ASSERT(0);
278 	}
279 
280 	return header_size;
281 }
282 
283 TEE_Result tee_fs_generate_fek(uint8_t *buf, int buf_size)
284 {
285 	TEE_Result res;
286 
287 	if (buf_size != TEE_FS_KM_FEK_SIZE)
288 		return TEE_ERROR_SHORT_BUFFER;
289 
290 	res = generate_fek(buf, TEE_FS_KM_FEK_SIZE);
291 	if (res != TEE_SUCCESS)
292 		return res;
293 
294 	return fek_crypt(TEE_MODE_ENCRYPT, buf,
295 			TEE_FS_KM_FEK_SIZE);
296 }
297 
298 TEE_Result tee_fs_encrypt_file(enum tee_fs_file_type file_type,
299 		const uint8_t *data_in, size_t data_in_size,
300 		uint8_t *data_out, size_t *data_out_size,
301 		const uint8_t *encrypted_fek)
302 {
303 	TEE_Result res = TEE_SUCCESS;
304 	struct km_header hdr;
305 	uint8_t iv[TEE_FS_KM_IV_LEN];
306 	uint8_t tag[TEE_FS_KM_MAX_TAG_LEN];
307 	uint8_t fek[TEE_FS_KM_FEK_SIZE];
308 	uint8_t *ciphertext;
309 	size_t cipher_size;
310 	size_t header_size = tee_fs_get_header_size(file_type);
311 
312 	/*
313 	 * Meta File Format: |Header|Chipertext|
314 	 * Header Format:    |AAD|Tag|
315 	 * AAD Format:       |Encrypted_FEK|IV|
316 	 *
317 	 * Block File Format: |Header|Ciphertext|
318 	 * Header Format:     |IV|Tag|
319 	 *
320 	 * FEK = AES_DECRYPT(SSK, Encrypted_FEK)
321 	 * Chipertext = AES_GCM_ENCRYPT(FEK, IV, Meta_Info, AAD)
322 	 */
323 
324 	if (*data_out_size != (header_size + data_in_size))
325 		return TEE_ERROR_SHORT_BUFFER;
326 
327 	res = generate_iv(iv, TEE_FS_KM_IV_LEN);
328 	if (res != TEE_SUCCESS)
329 		goto fail;
330 
331 	memcpy(fek, encrypted_fek, TEE_FS_KM_FEK_SIZE);
332 	res = fek_crypt(TEE_MODE_DECRYPT, fek, TEE_FS_KM_FEK_SIZE);
333 	if (res != TEE_SUCCESS)
334 		goto fail;
335 
336 	ciphertext = data_out + header_size;
337 	cipher_size = data_in_size;
338 
339 	hdr.aad.iv = iv;
340 	hdr.aad.encrypted_key = encrypted_fek;
341 	hdr.tag = tag;
342 
343 	res = do_auth_enc(TEE_MODE_ENCRYPT, &hdr,
344 			fek, TEE_FS_KM_FEK_SIZE,
345 			data_in, data_in_size,
346 			ciphertext, &cipher_size);
347 
348 	if (res == TEE_SUCCESS) {
349 		if (file_type == META_FILE) {
350 			memcpy(data_out, encrypted_fek, TEE_FS_KM_FEK_SIZE);
351 			data_out += TEE_FS_KM_FEK_SIZE;
352 		}
353 
354 		memcpy(data_out, iv, TEE_FS_KM_IV_LEN);
355 		data_out += TEE_FS_KM_IV_LEN;
356 		memcpy(data_out, tag, TEE_FS_KM_MAX_TAG_LEN);
357 
358 		*data_out_size = header_size + cipher_size;
359 	}
360 
361 fail:
362 	return res;
363 }
364 
365 TEE_Result tee_fs_decrypt_file(enum tee_fs_file_type file_type,
366 		const uint8_t *data_in, size_t data_in_size,
367 		uint8_t *plaintext, size_t *plaintext_size,
368 		uint8_t *encrypted_fek)
369 {
370 	TEE_Result res = TEE_SUCCESS;
371 	struct km_header km_hdr;
372 	size_t file_hdr_size = tee_fs_get_header_size(file_type);
373 	const uint8_t *cipher = data_in + file_hdr_size;
374 	int cipher_size = data_in_size - file_hdr_size;
375 	uint8_t fek[TEE_FS_KM_FEK_SIZE];
376 
377 	if (file_type == META_FILE) {
378 		struct meta_header *hdr = (struct meta_header *)data_in;
379 
380 		km_hdr.aad.encrypted_key = hdr->encrypted_key;
381 		km_hdr.aad.iv = hdr->common.iv;
382 		km_hdr.tag = hdr->common.tag;
383 
384 		/* return encrypted FEK to tee_fs which is used for block
385 		 * encryption/decryption */
386 		memcpy(encrypted_fek, hdr->encrypted_key, TEE_FS_KM_FEK_SIZE);
387 	} else {
388 		struct block_header *hdr = (struct block_header *)data_in;
389 
390 		km_hdr.aad.encrypted_key = encrypted_fek;
391 		km_hdr.aad.iv = hdr->common.iv;
392 		km_hdr.tag = hdr->common.tag;
393 	}
394 
395 	memcpy(fek, km_hdr.aad.encrypted_key, TEE_FS_KM_FEK_SIZE);
396 	res = fek_crypt(TEE_MODE_DECRYPT, fek, TEE_FS_KM_FEK_SIZE);
397 	if (res != TEE_SUCCESS) {
398 		EMSG("Failed to decrypt FEK, res=0x%x", res);
399 		return res;
400 	}
401 
402 	return do_auth_enc(TEE_MODE_DECRYPT, &km_hdr, fek, TEE_FS_KM_FEK_SIZE,
403 			cipher, cipher_size, plaintext, plaintext_size);
404 }
405 
406 service_init(tee_fs_init_key_manager);
407 
408