2 * Copyright (c) 2015, Linaro Limited
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
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.
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.
32 * FEK - File Encryption Key
33 * SSK - Secure Storage Key
34 * TSK - Trusted app Storage Key
36 * HUK - Hardware Unique Key
37 * RNG - Random Number Generator
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>
55 uint8_t key[TEE_FS_KM_SSK_SIZE];
58 static struct tee_fs_ssk tee_fs_ssk;
59 static uint8_t string_for_ssk_gen[] = "ONLY_FOR_tee_fs_ssk";
62 static TEE_Result do_hmac(uint8_t *out_key, uint32_t out_key_size,
63 const uint8_t *in_key, uint32_t in_key_size,
64 const uint8_t *message, uint32_t message_size)
66 TEE_Result res = TEE_ERROR_GENERIC;
68 size_t hash_ctx_size = 0;
70 if (!out_key || !in_key || !message)
71 return TEE_ERROR_BAD_PARAMETERS;
73 res = crypto_ops.mac.get_ctx_size(TEE_FS_KM_HMAC_ALG, &hash_ctx_size);
74 if (res != TEE_SUCCESS)
77 ctx = malloc(hash_ctx_size);
79 return TEE_ERROR_OUT_OF_MEMORY;
81 res = crypto_ops.mac.init(ctx, TEE_FS_KM_HMAC_ALG, in_key, in_key_size);
82 if (res != TEE_SUCCESS)
85 res = crypto_ops.mac.update(ctx, TEE_FS_KM_HMAC_ALG,
86 message, message_size);
87 if (res != TEE_SUCCESS)
90 res = crypto_ops.mac.final(ctx, TEE_FS_KM_HMAC_ALG, out_key,
92 if (res != TEE_SUCCESS)
102 TEE_Result tee_fs_fek_crypt(TEE_OperationMode mode, const uint8_t *in_key,
103 size_t size, uint8_t *out_key)
108 uint8_t tsk[TEE_FS_KM_TSK_SIZE];
109 uint8_t dst_key[size];
110 struct tee_ta_session *sess;
112 if (!in_key || !out_key)
113 return TEE_ERROR_BAD_PARAMETERS;
115 if (size != TEE_FS_KM_FEK_SIZE)
116 return TEE_ERROR_BAD_PARAMETERS;
118 if (tee_fs_ssk.is_init == 0)
119 return TEE_ERROR_GENERIC;
121 res = tee_ta_get_current_session(&sess);
122 if (res != TEE_SUCCESS)
125 res = do_hmac(tsk, sizeof(tsk), tee_fs_ssk.key, TEE_FS_KM_SSK_SIZE,
126 (uint8_t *)&sess->ctx->uuid, sizeof(TEE_UUID));
127 if (res != TEE_SUCCESS)
130 res = crypto_ops.cipher.get_ctx_size(TEE_FS_KM_ENC_FEK_ALG, &ctx_size);
131 if (res != TEE_SUCCESS)
134 ctx = malloc(ctx_size);
136 return TEE_ERROR_OUT_OF_MEMORY;
138 res = crypto_ops.cipher.init(ctx, TEE_FS_KM_ENC_FEK_ALG, mode, tsk,
139 sizeof(tsk), NULL, 0, NULL, 0);
140 if (res != TEE_SUCCESS)
143 res = crypto_ops.cipher.update(ctx, TEE_FS_KM_ENC_FEK_ALG,
144 mode, true, in_key, size, dst_key);
145 if (res != TEE_SUCCESS)
148 crypto_ops.cipher.final(ctx, TEE_FS_KM_ENC_FEK_ALG);
150 memcpy(out_key, dst_key, sizeof(dst_key));
158 static TEE_Result generate_fek(uint8_t *key, uint8_t len)
160 return crypto_ops.prng.read(key, len);
163 static TEE_Result tee_fs_init_key_manager(void)
165 int res = TEE_SUCCESS;
166 struct tee_hw_unique_key huk;
167 uint8_t chip_id[TEE_FS_KM_CHIP_ID_LENGTH];
168 uint8_t message[sizeof(chip_id) + sizeof(string_for_ssk_gen)];
170 /* Secure Storage Key Generation:
172 * SSK = HMAC(HUK, message)
173 * message := concatenate(chip_id, static string)
175 tee_otp_get_hw_unique_key(&huk);
176 tee_otp_get_die_id(chip_id, sizeof(chip_id));
178 memcpy(message, chip_id, sizeof(chip_id));
179 memcpy(message + sizeof(chip_id), string_for_ssk_gen,
180 sizeof(string_for_ssk_gen));
182 res = do_hmac(tee_fs_ssk.key, sizeof(tee_fs_ssk.key),
183 huk.data, sizeof(huk.data),
184 message, sizeof(message));
186 if (res == TEE_SUCCESS)
187 tee_fs_ssk.is_init = 1;
192 TEE_Result tee_fs_generate_fek(uint8_t *buf, int buf_size)
196 if (buf_size != TEE_FS_KM_FEK_SIZE)
197 return TEE_ERROR_BAD_PARAMETERS;
199 res = generate_fek(buf, TEE_FS_KM_FEK_SIZE);
200 if (res != TEE_SUCCESS)
203 return tee_fs_fek_crypt(TEE_MODE_ENCRYPT, buf, TEE_FS_KM_FEK_SIZE, buf);
206 static TEE_Result sha256(uint8_t *out, size_t out_size, const uint8_t *in,
212 uint32_t algo = TEE_ALG_SHA256;
214 res = crypto_ops.hash.get_ctx_size(algo, &ctx_size);
215 if (res != TEE_SUCCESS)
218 ctx = malloc(ctx_size);
220 return TEE_ERROR_OUT_OF_MEMORY;
222 res = crypto_ops.hash.init(ctx, algo);
223 if (res != TEE_SUCCESS)
226 res = crypto_ops.hash.update(ctx, algo, in, in_size);
227 if (res != TEE_SUCCESS)
230 res = crypto_ops.hash.final(ctx, algo, out, out_size);
237 static TEE_Result aes_ecb(uint8_t out[TEE_AES_BLOCK_SIZE],
238 const uint8_t in[TEE_AES_BLOCK_SIZE],
239 const uint8_t *key, size_t key_size)
244 uint32_t algo = TEE_ALG_AES_ECB_NOPAD;
246 res = crypto_ops.cipher.get_ctx_size(algo, &ctx_size);
247 if (res != TEE_SUCCESS)
250 ctx = malloc(ctx_size);
252 return TEE_ERROR_OUT_OF_MEMORY;
254 res = crypto_ops.cipher.init(ctx, algo, TEE_MODE_ENCRYPT, key,
255 key_size, NULL, 0, NULL, 0);
256 if (res != TEE_SUCCESS)
259 res = crypto_ops.cipher.update(ctx, algo, TEE_MODE_ENCRYPT, true, in,
260 TEE_AES_BLOCK_SIZE, out);
261 if (res != TEE_SUCCESS)
264 crypto_ops.cipher.final(ctx, algo);
272 static TEE_Result essiv(uint8_t iv[TEE_AES_BLOCK_SIZE],
273 const uint8_t fek[TEE_FS_KM_FEK_SIZE],
277 uint8_t sha[TEE_SHA256_HASH_SIZE];
278 uint8_t pad_blkid[TEE_AES_BLOCK_SIZE] = { 0, };
280 res = sha256(sha, sizeof(sha), fek, TEE_FS_KM_FEK_SIZE);
281 if (res != TEE_SUCCESS)
284 pad_blkid[0] = (blk_idx & 0xFF);
285 pad_blkid[1] = (blk_idx & 0xFF00) >> 8;
287 return aes_ecb(iv, pad_blkid, sha, 16);
291 * Encryption/decryption of RPMB FS file data. This is AES CBC with ESSIV.
293 TEE_Result tee_fs_crypt_block(uint8_t *out, const uint8_t *in, size_t size,
294 uint16_t blk_idx, const uint8_t *encrypted_fek,
295 TEE_OperationMode mode)
298 uint8_t fek[TEE_FS_KM_FEK_SIZE];
299 uint8_t iv[TEE_AES_BLOCK_SIZE];
302 uint32_t algo = TEE_ALG_AES_CBC_NOPAD;
304 DMSG("%scrypt block #%u", (mode == TEE_MODE_ENCRYPT) ? "En" : "De",
308 res = tee_fs_fek_crypt(TEE_MODE_DECRYPT, encrypted_fek,
309 TEE_FS_KM_FEK_SIZE, fek);
310 if (res != TEE_SUCCESS)
313 /* Compute initialization vector for this block */
314 res = essiv(iv, fek, blk_idx);
317 res = crypto_ops.cipher.get_ctx_size(algo, &ctx_size);
318 if (res != TEE_SUCCESS)
320 ctx = malloc(ctx_size);
322 return TEE_ERROR_OUT_OF_MEMORY;
324 res = crypto_ops.cipher.init(ctx, algo, mode, fek, sizeof(fek), NULL,
325 0, iv, TEE_AES_BLOCK_SIZE);
326 if (res != TEE_SUCCESS)
328 res = crypto_ops.cipher.update(ctx, algo, mode, true, in, size, out);
329 if (res != TEE_SUCCESS)
332 crypto_ops.cipher.final(ctx, algo);
339 service_init_late(tee_fs_init_key_manager);