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 static struct tee_fs_ssk tee_fs_ssk; 59 static uint8_t string_for_ssk_gen[] = "ONLY_FOR_tee_fs_ssk"; 60 61 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) 65 { 66 TEE_Result res = TEE_ERROR_GENERIC; 67 uint8_t *ctx = NULL; 68 size_t hash_ctx_size = 0; 69 70 if (!out_key || !in_key || !message) 71 return TEE_ERROR_BAD_PARAMETERS; 72 73 res = crypto_ops.mac.get_ctx_size(TEE_FS_KM_HMAC_ALG, &hash_ctx_size); 74 if (res != TEE_SUCCESS) 75 return res; 76 77 ctx = malloc(hash_ctx_size); 78 if (!ctx) 79 return TEE_ERROR_OUT_OF_MEMORY; 80 81 res = crypto_ops.mac.init(ctx, TEE_FS_KM_HMAC_ALG, in_key, in_key_size); 82 if (res != TEE_SUCCESS) 83 goto exit; 84 85 res = crypto_ops.mac.update(ctx, TEE_FS_KM_HMAC_ALG, 86 message, message_size); 87 if (res != TEE_SUCCESS) 88 goto exit; 89 90 res = crypto_ops.mac.final(ctx, TEE_FS_KM_HMAC_ALG, out_key, 91 out_key_size); 92 if (res != TEE_SUCCESS) 93 goto exit; 94 95 res = TEE_SUCCESS; 96 97 exit: 98 free(ctx); 99 return res; 100 } 101 102 TEE_Result tee_fs_fek_crypt(TEE_OperationMode mode, const uint8_t *in_key, 103 size_t size, uint8_t *out_key) 104 { 105 TEE_Result res; 106 uint8_t *ctx = NULL; 107 size_t ctx_size; 108 uint8_t tsk[TEE_FS_KM_TSK_SIZE]; 109 uint8_t dst_key[size]; 110 struct tee_ta_session *sess; 111 112 if (!in_key || !out_key) 113 return TEE_ERROR_BAD_PARAMETERS; 114 115 if (size != TEE_FS_KM_FEK_SIZE) 116 return TEE_ERROR_BAD_PARAMETERS; 117 118 if (tee_fs_ssk.is_init == 0) 119 return TEE_ERROR_GENERIC; 120 121 res = tee_ta_get_current_session(&sess); 122 if (res != TEE_SUCCESS) 123 return res; 124 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) 128 return res; 129 130 res = crypto_ops.cipher.get_ctx_size(TEE_FS_KM_ENC_FEK_ALG, &ctx_size); 131 if (res != TEE_SUCCESS) 132 return res; 133 134 ctx = malloc(ctx_size); 135 if (!ctx) 136 return TEE_ERROR_OUT_OF_MEMORY; 137 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) 141 goto exit; 142 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) 146 goto exit; 147 148 crypto_ops.cipher.final(ctx, TEE_FS_KM_ENC_FEK_ALG); 149 150 memcpy(out_key, dst_key, sizeof(dst_key)); 151 152 exit: 153 free(ctx); 154 155 return res; 156 } 157 158 static TEE_Result generate_fek(uint8_t *key, uint8_t len) 159 { 160 return crypto_ops.prng.read(key, len); 161 } 162 163 static TEE_Result tee_fs_init_key_manager(void) 164 { 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)]; 169 170 /* Secure Storage Key Generation: 171 * 172 * SSK = HMAC(HUK, message) 173 * message := concatenate(chip_id, static string) 174 * */ 175 tee_otp_get_hw_unique_key(&huk); 176 tee_otp_get_die_id(chip_id, sizeof(chip_id)); 177 178 memcpy(message, chip_id, sizeof(chip_id)); 179 memcpy(message + sizeof(chip_id), string_for_ssk_gen, 180 sizeof(string_for_ssk_gen)); 181 182 res = do_hmac(tee_fs_ssk.key, sizeof(tee_fs_ssk.key), 183 huk.data, sizeof(huk.data), 184 message, sizeof(message)); 185 186 if (res == TEE_SUCCESS) 187 tee_fs_ssk.is_init = 1; 188 189 return res; 190 } 191 192 TEE_Result tee_fs_generate_fek(uint8_t *buf, int buf_size) 193 { 194 TEE_Result res; 195 196 if (buf_size != TEE_FS_KM_FEK_SIZE) 197 return TEE_ERROR_BAD_PARAMETERS; 198 199 res = generate_fek(buf, TEE_FS_KM_FEK_SIZE); 200 if (res != TEE_SUCCESS) 201 return res; 202 203 return tee_fs_fek_crypt(TEE_MODE_ENCRYPT, buf, TEE_FS_KM_FEK_SIZE, buf); 204 } 205 206 static TEE_Result sha256(uint8_t *out, size_t out_size, const uint8_t *in, 207 size_t in_size) 208 { 209 TEE_Result res; 210 uint8_t *ctx = NULL; 211 size_t ctx_size; 212 uint32_t algo = TEE_ALG_SHA256; 213 214 res = crypto_ops.hash.get_ctx_size(algo, &ctx_size); 215 if (res != TEE_SUCCESS) 216 return res; 217 218 ctx = malloc(ctx_size); 219 if (!ctx) 220 return TEE_ERROR_OUT_OF_MEMORY; 221 222 res = crypto_ops.hash.init(ctx, algo); 223 if (res != TEE_SUCCESS) 224 goto out; 225 226 res = crypto_ops.hash.update(ctx, algo, in, in_size); 227 if (res != TEE_SUCCESS) 228 goto out; 229 230 res = crypto_ops.hash.final(ctx, algo, out, out_size); 231 232 out: 233 free(ctx); 234 return res; 235 } 236 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) 240 { 241 TEE_Result res; 242 uint8_t *ctx = NULL; 243 size_t ctx_size; 244 uint32_t algo = TEE_ALG_AES_ECB_NOPAD; 245 246 res = crypto_ops.cipher.get_ctx_size(algo, &ctx_size); 247 if (res != TEE_SUCCESS) 248 return res; 249 250 ctx = malloc(ctx_size); 251 if (!ctx) 252 return TEE_ERROR_OUT_OF_MEMORY; 253 254 res = crypto_ops.cipher.init(ctx, algo, TEE_MODE_ENCRYPT, key, 255 key_size, NULL, 0, NULL, 0); 256 if (res != TEE_SUCCESS) 257 goto out; 258 259 res = crypto_ops.cipher.update(ctx, algo, TEE_MODE_ENCRYPT, true, in, 260 TEE_AES_BLOCK_SIZE, out); 261 if (res != TEE_SUCCESS) 262 goto out; 263 264 crypto_ops.cipher.final(ctx, algo); 265 res = TEE_SUCCESS; 266 267 out: 268 free(ctx); 269 return res; 270 } 271 272 static TEE_Result essiv(uint8_t iv[TEE_AES_BLOCK_SIZE], 273 const uint8_t fek[TEE_FS_KM_FEK_SIZE], 274 uint16_t blk_idx) 275 { 276 TEE_Result res; 277 uint8_t sha[TEE_SHA256_HASH_SIZE]; 278 uint8_t pad_blkid[TEE_AES_BLOCK_SIZE] = { 0, }; 279 280 res = sha256(sha, sizeof(sha), fek, TEE_FS_KM_FEK_SIZE); 281 if (res != TEE_SUCCESS) 282 return res; 283 284 pad_blkid[0] = (blk_idx & 0xFF); 285 pad_blkid[1] = (blk_idx & 0xFF00) >> 8; 286 287 return aes_ecb(iv, pad_blkid, sha, 16); 288 } 289 290 /* 291 * Encryption/decryption of RPMB FS file data. This is AES CBC with ESSIV. 292 */ 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) 296 { 297 TEE_Result res; 298 uint8_t fek[TEE_FS_KM_FEK_SIZE]; 299 uint8_t iv[TEE_AES_BLOCK_SIZE]; 300 uint8_t *ctx; 301 size_t ctx_size; 302 uint32_t algo = TEE_ALG_AES_CBC_NOPAD; 303 304 DMSG("%scrypt block #%u", (mode == TEE_MODE_ENCRYPT) ? "En" : "De", 305 blk_idx); 306 307 /* Decrypt FEK */ 308 res = tee_fs_fek_crypt(TEE_MODE_DECRYPT, encrypted_fek, 309 TEE_FS_KM_FEK_SIZE, fek); 310 if (res != TEE_SUCCESS) 311 return res; 312 313 /* Compute initialization vector for this block */ 314 res = essiv(iv, fek, blk_idx); 315 316 /* Run AES CBC */ 317 res = crypto_ops.cipher.get_ctx_size(algo, &ctx_size); 318 if (res != TEE_SUCCESS) 319 return res; 320 ctx = malloc(ctx_size); 321 if (!ctx) 322 return TEE_ERROR_OUT_OF_MEMORY; 323 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) 327 goto exit; 328 res = crypto_ops.cipher.update(ctx, algo, mode, true, in, size, out); 329 if (res != TEE_SUCCESS) 330 goto exit; 331 332 crypto_ops.cipher.final(ctx, algo); 333 334 exit: 335 free(ctx); 336 return res; 337 } 338 339 service_init_late(tee_fs_init_key_manager); 340