c827cef6e9f33e3f49c1f86ea524ab96d608ecda
[platform/core/security/tef-optee_os.git] / core / tee / tee_fs_key_manager.c
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 /*
30  * Acronyms:
31  *
32  * FEK - File Encryption Key
33  * SSK - Secure Storage Key
34  * TSK - Trusted app Storage Key
35  * IV  - Initial vector
36  * HUK - Hardware Unique Key
37  * RNG - Random Number Generator
38  */
39
40 #include <initcall.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <kernel/panic.h>
44 #include <kernel/tee_common_otp.h>
45 #include <kernel/tee_ta_manager.h>
46 #include <tee/tee_cryp_utl.h>
47 #include <tee/tee_cryp_provider.h>
48 #include <tee/tee_fs_key_manager.h>
49 #include <compiler.h>
50 #include <trace.h>
51 #include <util.h>
52
53 struct tee_fs_ssk {
54         bool is_init;
55         uint8_t key[TEE_FS_KM_SSK_SIZE];
56 };
57
58 struct aad {
59         const uint8_t *encrypted_key;
60         const uint8_t *iv;
61 };
62
63 struct km_header {
64         struct aad aad;
65         uint8_t *tag;
66 };
67
68 static struct tee_fs_ssk tee_fs_ssk;
69 static uint8_t string_for_ssk_gen[] = "ONLY_FOR_tee_fs_ssk";
70
71
72 static TEE_Result do_hmac(uint8_t *out_key, uint32_t out_key_size,
73                           const uint8_t *in_key, uint32_t in_key_size,
74                           const uint8_t *message, uint32_t message_size)
75 {
76         TEE_Result res = TEE_ERROR_GENERIC;
77         uint8_t *ctx = NULL;
78         size_t hash_ctx_size = 0;
79
80         if (!out_key || !in_key || !message)
81                 return TEE_ERROR_BAD_PARAMETERS;
82
83         res = crypto_ops.mac.get_ctx_size(TEE_FS_KM_HMAC_ALG, &hash_ctx_size);
84         if (res != TEE_SUCCESS)
85                 return res;
86
87         ctx = malloc(hash_ctx_size);
88         if (!ctx)
89                 return TEE_ERROR_OUT_OF_MEMORY;
90
91         res = crypto_ops.mac.init(ctx, TEE_FS_KM_HMAC_ALG, in_key, in_key_size);
92         if (res != TEE_SUCCESS)
93                 goto exit;
94
95         res = crypto_ops.mac.update(ctx, TEE_FS_KM_HMAC_ALG,
96                         message, message_size);
97         if (res != TEE_SUCCESS)
98                 goto exit;
99
100         res = crypto_ops.mac.final(ctx, TEE_FS_KM_HMAC_ALG, out_key,
101                                    out_key_size);
102         if (res != TEE_SUCCESS)
103                 goto exit;
104
105         res = TEE_SUCCESS;
106
107 exit:
108         free(ctx);
109         return res;
110 }
111
112 static TEE_Result fek_crypt(TEE_OperationMode mode,
113                 uint8_t *key, int size)
114 {
115         TEE_Result res;
116         uint8_t *ctx = NULL;
117         size_t ctx_size;
118         uint8_t tsk[TEE_FS_KM_TSK_SIZE];
119         uint8_t dst_key[TEE_FS_KM_FEK_SIZE];
120         struct tee_ta_session *sess;
121
122         if (!key)
123                 return TEE_ERROR_BAD_PARAMETERS;
124
125         if (size != TEE_FS_KM_FEK_SIZE)
126                 return TEE_ERROR_BAD_PARAMETERS;
127
128         if (tee_fs_ssk.is_init == 0)
129                 return TEE_ERROR_GENERIC;
130
131         res = tee_ta_get_current_session(&sess);
132         if (res != TEE_SUCCESS)
133                 return res;
134
135         res = do_hmac(tsk, sizeof(tsk), tee_fs_ssk.key, TEE_FS_KM_SSK_SIZE,
136                       (uint8_t *)&sess->ctx->uuid, sizeof(TEE_UUID));
137         if (res != TEE_SUCCESS)
138                 return res;
139
140         res = crypto_ops.cipher.get_ctx_size(TEE_FS_KM_ENC_FEK_ALG, &ctx_size);
141         if (res != TEE_SUCCESS)
142                 return res;
143
144         ctx = malloc(ctx_size);
145         if (!ctx)
146                 return TEE_ERROR_OUT_OF_MEMORY;
147
148         res = crypto_ops.cipher.init(ctx, TEE_FS_KM_ENC_FEK_ALG, mode, tsk,
149                                      sizeof(tsk), NULL, 0, NULL, 0);
150         if (res != TEE_SUCCESS)
151                 goto exit;
152
153         res = crypto_ops.cipher.update(ctx, TEE_FS_KM_ENC_FEK_ALG,
154                         mode, true, key, size, dst_key);
155         if (res != TEE_SUCCESS)
156                 goto exit;
157
158         crypto_ops.cipher.final(ctx, TEE_FS_KM_ENC_FEK_ALG);
159
160         memcpy(key, dst_key, sizeof(dst_key));
161
162 exit:
163         free(ctx);
164
165         return res;
166 }
167
168 static TEE_Result generate_fek(uint8_t *key, uint8_t len)
169 {
170         return crypto_ops.prng.read(key, len);
171 }
172
173 static TEE_Result generate_iv(uint8_t *iv, uint8_t len)
174 {
175         return crypto_ops.prng.read(iv, len);
176 }
177
178 static TEE_Result tee_fs_init_key_manager(void)
179 {
180         int res = TEE_SUCCESS;
181         struct tee_hw_unique_key huk;
182         uint8_t chip_id[TEE_FS_KM_CHIP_ID_LENGTH];
183         uint8_t message[sizeof(chip_id) + sizeof(string_for_ssk_gen)];
184
185         /* Secure Storage Key Generation:
186          *
187          *     SSK = HMAC(HUK, message)
188          *     message := concatenate(chip_id, static string)
189          * */
190         tee_otp_get_hw_unique_key(&huk);
191         tee_otp_get_die_id(chip_id, sizeof(chip_id));
192
193         memcpy(message, chip_id, sizeof(chip_id));
194         memcpy(message + sizeof(chip_id), string_for_ssk_gen,
195                         sizeof(string_for_ssk_gen));
196
197         res = do_hmac(tee_fs_ssk.key, sizeof(tee_fs_ssk.key),
198                         huk.data, sizeof(huk.data),
199                         message, sizeof(message));
200
201         if (res == TEE_SUCCESS)
202                 tee_fs_ssk.is_init = 1;
203
204         return res;
205 }
206
207 static TEE_Result do_auth_enc(TEE_OperationMode mode,
208                 struct km_header *hdr,
209                 uint8_t *fek, int fek_len,
210                 const uint8_t *data_in, size_t in_size,
211                 uint8_t *data_out, size_t *out_size)
212 {
213         TEE_Result res = TEE_SUCCESS;
214         uint8_t *ctx = NULL;
215         size_t ctx_size;
216         size_t tag_len = TEE_FS_KM_MAX_TAG_LEN;
217
218         if ((mode != TEE_MODE_ENCRYPT) && (mode != TEE_MODE_DECRYPT))
219                 return TEE_ERROR_BAD_PARAMETERS;
220
221         if (*out_size < in_size) {
222                 EMSG("output buffer(%zd) < input buffer(%zd)",
223                                 *out_size, in_size);
224                 return TEE_ERROR_SHORT_BUFFER;
225         }
226
227         res = crypto_ops.authenc.get_ctx_size(TEE_FS_KM_AUTH_ENC_ALG,
228                         &ctx_size);
229         if (res != TEE_SUCCESS)
230                 return res;
231
232         ctx = malloc(ctx_size);
233         if (!ctx) {
234                 EMSG("request memory size %zu failed", ctx_size);
235                 return TEE_ERROR_OUT_OF_MEMORY;
236         }
237
238         res = crypto_ops.authenc.init(ctx, TEE_FS_KM_AUTH_ENC_ALG,
239                         mode, fek, fek_len, hdr->aad.iv,
240                         TEE_FS_KM_IV_LEN, TEE_FS_KM_MAX_TAG_LEN,
241                         sizeof(struct aad), in_size);
242         if (res != TEE_SUCCESS)
243                 goto exit;
244
245         res = crypto_ops.authenc.update_aad(ctx, TEE_FS_KM_AUTH_ENC_ALG,
246                         mode, (uint8_t *)hdr->aad.encrypted_key,
247                         TEE_FS_KM_FEK_SIZE);
248         if (res != TEE_SUCCESS)
249                 goto exit;
250
251         res = crypto_ops.authenc.update_aad(ctx, TEE_FS_KM_AUTH_ENC_ALG,
252                         mode, (uint8_t *)hdr->aad.iv,
253                         TEE_FS_KM_IV_LEN);
254         if (res != TEE_SUCCESS)
255                 goto exit;
256
257         if (mode == TEE_MODE_ENCRYPT) {
258                 res = crypto_ops.authenc.enc_final(ctx, TEE_FS_KM_AUTH_ENC_ALG,
259                                 data_in, in_size, data_out, out_size,
260                                 hdr->tag, &tag_len);
261         } else {
262                 res = crypto_ops.authenc.dec_final(ctx, TEE_FS_KM_AUTH_ENC_ALG,
263                                 data_in, in_size, data_out, out_size,
264                                 hdr->tag, tag_len);
265         }
266
267         if (res != TEE_SUCCESS)
268                 goto exit;
269
270         crypto_ops.authenc.final(ctx, TEE_FS_KM_AUTH_ENC_ALG);
271
272 exit:
273         free(ctx);
274         return res;
275 }
276
277 size_t tee_fs_get_header_size(enum tee_fs_file_type type)
278 {
279         size_t header_size = 0;
280
281         switch (type) {
282         case META_FILE:
283                 header_size = sizeof(struct meta_header);
284                 break;
285         case BLOCK_FILE:
286                 header_size = sizeof(struct block_header);
287                 break;
288         default:
289                 panic("Unknown file type");
290         }
291
292         return header_size;
293 }
294
295 TEE_Result tee_fs_generate_fek(uint8_t *buf, int buf_size)
296 {
297         TEE_Result res;
298
299         if (buf_size != TEE_FS_KM_FEK_SIZE)
300                 return TEE_ERROR_BAD_PARAMETERS;
301
302         res = generate_fek(buf, TEE_FS_KM_FEK_SIZE);
303         if (res != TEE_SUCCESS)
304                 return res;
305
306         return fek_crypt(TEE_MODE_ENCRYPT, buf,
307                         TEE_FS_KM_FEK_SIZE);
308 }
309
310 TEE_Result tee_fs_encrypt_file(enum tee_fs_file_type file_type,
311                 const uint8_t *data_in, size_t data_in_size,
312                 uint8_t *data_out, size_t *data_out_size,
313                 const uint8_t *encrypted_fek)
314 {
315         TEE_Result res = TEE_SUCCESS;
316         struct km_header hdr;
317         uint8_t iv[TEE_FS_KM_IV_LEN];
318         uint8_t tag[TEE_FS_KM_MAX_TAG_LEN];
319         uint8_t fek[TEE_FS_KM_FEK_SIZE];
320         uint8_t *ciphertext;
321         size_t cipher_size;
322         size_t header_size = tee_fs_get_header_size(file_type);
323
324         /*
325          * Meta File Format: |Header|Chipertext|
326          * Header Format:    |AAD|Tag|
327          * AAD Format:       |Encrypted_FEK|IV|
328          *
329          * Block File Format: |Header|Ciphertext|
330          * Header Format:     |IV|Tag|
331          *
332          * TSK = HMAC(SSK, TA_UUID)
333          * FEK = AES_DECRYPT(TSK, Encrypted_FEK)
334          * Chipertext = AES_GCM_ENCRYPT(FEK, IV, Meta_Info, AAD)
335          */
336
337         if (*data_out_size != (header_size + data_in_size))
338                 return TEE_ERROR_SHORT_BUFFER;
339
340         res = generate_iv(iv, TEE_FS_KM_IV_LEN);
341         if (res != TEE_SUCCESS)
342                 goto fail;
343
344         memcpy(fek, encrypted_fek, TEE_FS_KM_FEK_SIZE);
345         res = fek_crypt(TEE_MODE_DECRYPT, fek, TEE_FS_KM_FEK_SIZE);
346         if (res != TEE_SUCCESS)
347                 goto fail;
348
349         ciphertext = data_out + header_size;
350         cipher_size = data_in_size;
351
352         hdr.aad.iv = iv;
353         hdr.aad.encrypted_key = encrypted_fek;
354         hdr.tag = tag;
355
356         res = do_auth_enc(TEE_MODE_ENCRYPT, &hdr,
357                         fek, TEE_FS_KM_FEK_SIZE,
358                         data_in, data_in_size,
359                         ciphertext, &cipher_size);
360
361         if (res == TEE_SUCCESS) {
362                 if (file_type == META_FILE) {
363                         memcpy(data_out, encrypted_fek, TEE_FS_KM_FEK_SIZE);
364                         data_out += TEE_FS_KM_FEK_SIZE;
365                 }
366
367                 memcpy(data_out, iv, TEE_FS_KM_IV_LEN);
368                 data_out += TEE_FS_KM_IV_LEN;
369                 memcpy(data_out, tag, TEE_FS_KM_MAX_TAG_LEN);
370
371                 *data_out_size = header_size + cipher_size;
372         }
373
374 fail:
375         return res;
376 }
377
378 TEE_Result tee_fs_decrypt_file(enum tee_fs_file_type file_type,
379                 const uint8_t *data_in, size_t data_in_size,
380                 uint8_t *plaintext, size_t *plaintext_size,
381                 uint8_t *encrypted_fek)
382 {
383         TEE_Result res = TEE_SUCCESS;
384         struct km_header km_hdr;
385         size_t file_hdr_size = tee_fs_get_header_size(file_type);
386         const uint8_t *cipher = data_in + file_hdr_size;
387         int cipher_size = data_in_size - file_hdr_size;
388         uint8_t fek[TEE_FS_KM_FEK_SIZE];
389
390         if (file_type == META_FILE) {
391                 struct meta_header *hdr = (struct meta_header *)data_in;
392
393                 km_hdr.aad.encrypted_key = hdr->encrypted_key;
394                 km_hdr.aad.iv = hdr->common.iv;
395                 km_hdr.tag = hdr->common.tag;
396
397                 /* return encrypted FEK to tee_fs which is used for block
398                  * encryption/decryption */
399                 memcpy(encrypted_fek, hdr->encrypted_key, TEE_FS_KM_FEK_SIZE);
400         } else {
401                 struct block_header *hdr = (struct block_header *)data_in;
402
403                 km_hdr.aad.encrypted_key = encrypted_fek;
404                 km_hdr.aad.iv = hdr->common.iv;
405                 km_hdr.tag = hdr->common.tag;
406         }
407
408         memcpy(fek, km_hdr.aad.encrypted_key, TEE_FS_KM_FEK_SIZE);
409         res = fek_crypt(TEE_MODE_DECRYPT, fek, TEE_FS_KM_FEK_SIZE);
410         if (res != TEE_SUCCESS) {
411                 EMSG("Failed to decrypt FEK, res=0x%x", res);
412                 return res;
413         }
414
415         return do_auth_enc(TEE_MODE_DECRYPT, &km_hdr, fek, TEE_FS_KM_FEK_SIZE,
416                         cipher, cipher_size, plaintext, plaintext_size);
417 }
418
419 static TEE_Result sha256(uint8_t *out, size_t out_size, const uint8_t *in,
420                          size_t in_size)
421 {
422         TEE_Result res;
423         uint8_t *ctx = NULL;
424         size_t ctx_size;
425         uint32_t algo = TEE_ALG_SHA256;
426
427         res = crypto_ops.hash.get_ctx_size(algo, &ctx_size);
428         if (res != TEE_SUCCESS)
429                 return res;
430
431         ctx = malloc(ctx_size);
432         if (!ctx)
433                 return TEE_ERROR_OUT_OF_MEMORY;
434
435         res = crypto_ops.hash.init(ctx, algo);
436         if (res != TEE_SUCCESS)
437                 goto out;
438
439         res = crypto_ops.hash.update(ctx, algo, in, in_size);
440         if (res != TEE_SUCCESS)
441                 goto out;
442
443         res = crypto_ops.hash.final(ctx, algo, out, out_size);
444
445 out:
446         free(ctx);
447         return res;
448 }
449
450 static TEE_Result aes_ecb(uint8_t out[TEE_AES_BLOCK_SIZE],
451                           const uint8_t in[TEE_AES_BLOCK_SIZE],
452                           const uint8_t *key, size_t key_size)
453 {
454         TEE_Result res;
455         uint8_t *ctx = NULL;
456         size_t ctx_size;
457         uint32_t algo = TEE_ALG_AES_ECB_NOPAD;
458
459         res = crypto_ops.cipher.get_ctx_size(algo, &ctx_size);
460         if (res != TEE_SUCCESS)
461                 return res;
462
463         ctx = malloc(ctx_size);
464         if (!ctx)
465                 return TEE_ERROR_OUT_OF_MEMORY;
466
467         res = crypto_ops.cipher.init(ctx, algo, TEE_MODE_ENCRYPT, key,
468                                      key_size, NULL, 0, NULL, 0);
469         if (res != TEE_SUCCESS)
470                 goto out;
471
472         res = crypto_ops.cipher.update(ctx, algo, TEE_MODE_ENCRYPT, true, in,
473                                        TEE_AES_BLOCK_SIZE, out);
474         if (res != TEE_SUCCESS)
475                 goto out;
476
477         crypto_ops.cipher.final(ctx, algo);
478         res = TEE_SUCCESS;
479
480 out:
481         free(ctx);
482         return res;
483 }
484
485 static TEE_Result essiv(uint8_t iv[TEE_AES_BLOCK_SIZE],
486                         const uint8_t fek[TEE_FS_KM_FEK_SIZE],
487                         uint16_t blk_idx)
488 {
489         TEE_Result res;
490         uint8_t sha[TEE_SHA256_HASH_SIZE];
491         uint8_t pad_blkid[TEE_AES_BLOCK_SIZE] = { 0, };
492
493         res = sha256(sha, sizeof(sha), fek, TEE_FS_KM_FEK_SIZE);
494         if (res != TEE_SUCCESS)
495                 return res;
496
497         pad_blkid[0] = (blk_idx & 0xFF);
498         pad_blkid[1] = (blk_idx & 0xFF00) >> 8;
499
500         return aes_ecb(iv, pad_blkid, sha, 16);
501 }
502
503 /*
504  * Encryption/decryption of RPMB FS file data. This is AES CBC with ESSIV.
505  */
506 TEE_Result tee_fs_crypt_block(uint8_t *out, const uint8_t *in, size_t size,
507                               uint16_t blk_idx, const uint8_t *encrypted_fek,
508                               TEE_OperationMode mode)
509 {
510         TEE_Result res;
511         uint8_t fek[TEE_FS_KM_FEK_SIZE];
512         uint8_t iv[TEE_AES_BLOCK_SIZE];
513         uint8_t *ctx;
514         size_t ctx_size;
515         uint32_t algo = TEE_ALG_AES_CBC_NOPAD;
516
517         DMSG("%scrypt block #%u", (mode == TEE_MODE_ENCRYPT) ? "En" : "De",
518              blk_idx);
519
520         /* Decrypt FEK */
521         memcpy(fek, encrypted_fek, TEE_FS_KM_FEK_SIZE);
522         res = fek_crypt(TEE_MODE_DECRYPT, fek, TEE_FS_KM_FEK_SIZE);
523         if (res != TEE_SUCCESS)
524                 return res;
525
526         /* Compute initialization vector for this block */
527         res = essiv(iv, fek, blk_idx);
528
529         /* Run AES CBC */
530         res = crypto_ops.cipher.get_ctx_size(algo, &ctx_size);
531         if (res != TEE_SUCCESS)
532                 return res;
533         ctx = malloc(ctx_size);
534         if (!ctx)
535                 return TEE_ERROR_OUT_OF_MEMORY;
536
537         res = crypto_ops.cipher.init(ctx, algo, mode, fek, sizeof(fek), NULL,
538                                      0, iv, TEE_AES_BLOCK_SIZE);
539         if (res != TEE_SUCCESS)
540                 goto exit;
541         res = crypto_ops.cipher.update(ctx, algo, mode, true, in, size, out);
542         if (res != TEE_SUCCESS)
543                 goto exit;
544
545         crypto_ops.cipher.final(ctx, algo);
546
547 exit:
548         free(ctx);
549         return res;
550 }
551
552 service_init_late(tee_fs_init_key_manager);
553