1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2015, Linaro Limited 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 30 /* 31 * Acronyms: 32 * 33 * FEK - File Encryption Key 34 * SSK - Secure Storage Key 35 * TSK - Trusted app Storage Key 36 * IV - Initial vector 37 * HUK - Hardware Unique Key 38 * RNG - Random Number Generator 39 */ 40 41 #include <compiler.h> 42 #include <crypto/crypto.h> 43 #include <initcall.h> 44 #include <kernel/panic.h> 45 #include <kernel/tee_common_otp.h> 46 #include <kernel/tee_ta_manager.h> 47 #include <stdlib.h> 48 #include <string.h> 49 #include <tee/tee_cryp_utl.h> 50 #include <tee/tee_fs_key_manager.h> 51 #include <trace.h> 52 #include <util.h> 53 54 struct tee_fs_ssk { 55 bool is_init; 56 uint8_t key[TEE_FS_KM_SSK_SIZE]; 57 }; 58 59 static struct tee_fs_ssk tee_fs_ssk; 60 static uint8_t string_for_ssk_gen[] = "ONLY_FOR_tee_fs_ssk"; 61 62 63 static TEE_Result do_hmac(void *out_key, size_t out_key_size, 64 const void *in_key, size_t in_key_size, 65 const void *message, size_t message_size) 66 { 67 TEE_Result res = TEE_ERROR_GENERIC; 68 uint8_t *ctx = NULL; 69 size_t hash_ctx_size = 0; 70 71 if (!out_key || !in_key || !message) 72 return TEE_ERROR_BAD_PARAMETERS; 73 74 res = crypto_mac_get_ctx_size(TEE_FS_KM_HMAC_ALG, &hash_ctx_size); 75 if (res != TEE_SUCCESS) 76 return res; 77 78 ctx = malloc(hash_ctx_size); 79 if (!ctx) 80 return TEE_ERROR_OUT_OF_MEMORY; 81 82 res = crypto_mac_init(ctx, TEE_FS_KM_HMAC_ALG, in_key, in_key_size); 83 if (res != TEE_SUCCESS) 84 goto exit; 85 86 res = crypto_mac_update(ctx, TEE_FS_KM_HMAC_ALG, message, message_size); 87 if (res != TEE_SUCCESS) 88 goto exit; 89 90 res = crypto_mac_final(ctx, TEE_FS_KM_HMAC_ALG, out_key, out_key_size); 91 if (res != TEE_SUCCESS) 92 goto exit; 93 94 res = TEE_SUCCESS; 95 96 exit: 97 free(ctx); 98 return res; 99 } 100 101 TEE_Result tee_fs_fek_crypt(const TEE_UUID *uuid, TEE_OperationMode mode, 102 const uint8_t *in_key, size_t size, 103 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 111 if (!in_key || !out_key) 112 return TEE_ERROR_BAD_PARAMETERS; 113 114 if (size != TEE_FS_KM_FEK_SIZE) 115 return TEE_ERROR_BAD_PARAMETERS; 116 117 if (tee_fs_ssk.is_init == 0) 118 return TEE_ERROR_GENERIC; 119 120 if (uuid) { 121 res = do_hmac(tsk, sizeof(tsk), tee_fs_ssk.key, 122 TEE_FS_KM_SSK_SIZE, uuid, sizeof(*uuid)); 123 if (res != TEE_SUCCESS) 124 return res; 125 } else { 126 /* 127 * Pick something of a different size than TEE_UUID to 128 * guarantee that there's never a conflict. 129 */ 130 uint8_t dummy[1] = { 0 }; 131 132 res = do_hmac(tsk, sizeof(tsk), tee_fs_ssk.key, 133 TEE_FS_KM_SSK_SIZE, dummy, sizeof(dummy)); 134 if (res != TEE_SUCCESS) 135 return res; 136 } 137 138 res = crypto_cipher_get_ctx_size(TEE_FS_KM_ENC_FEK_ALG, &ctx_size); 139 if (res != TEE_SUCCESS) 140 return res; 141 142 ctx = malloc(ctx_size); 143 if (!ctx) 144 return TEE_ERROR_OUT_OF_MEMORY; 145 146 res = crypto_cipher_init(ctx, TEE_FS_KM_ENC_FEK_ALG, mode, tsk, 147 sizeof(tsk), NULL, 0, NULL, 0); 148 if (res != TEE_SUCCESS) 149 goto exit; 150 151 res = crypto_cipher_update(ctx, TEE_FS_KM_ENC_FEK_ALG, 152 mode, true, in_key, size, dst_key); 153 if (res != TEE_SUCCESS) 154 goto exit; 155 156 crypto_cipher_final(ctx, TEE_FS_KM_ENC_FEK_ALG); 157 158 memcpy(out_key, dst_key, sizeof(dst_key)); 159 160 exit: 161 free(ctx); 162 163 return res; 164 } 165 166 static TEE_Result generate_fek(uint8_t *key, uint8_t len) 167 { 168 return crypto_rng_read(key, len); 169 } 170 171 static TEE_Result tee_fs_init_key_manager(void) 172 { 173 int res = TEE_SUCCESS; 174 struct tee_hw_unique_key huk; 175 uint8_t chip_id[TEE_FS_KM_CHIP_ID_LENGTH]; 176 uint8_t message[sizeof(chip_id) + sizeof(string_for_ssk_gen)]; 177 178 /* Secure Storage Key Generation: 179 * 180 * SSK = HMAC(HUK, message) 181 * message := concatenate(chip_id, static string) 182 * */ 183 tee_otp_get_hw_unique_key(&huk); 184 tee_otp_get_die_id(chip_id, sizeof(chip_id)); 185 186 memcpy(message, chip_id, sizeof(chip_id)); 187 memcpy(message + sizeof(chip_id), string_for_ssk_gen, 188 sizeof(string_for_ssk_gen)); 189 190 res = do_hmac(tee_fs_ssk.key, sizeof(tee_fs_ssk.key), 191 huk.data, sizeof(huk.data), 192 message, sizeof(message)); 193 194 if (res == TEE_SUCCESS) 195 tee_fs_ssk.is_init = 1; 196 197 return res; 198 } 199 200 TEE_Result tee_fs_generate_fek(const TEE_UUID *uuid, void *buf, size_t buf_size) 201 { 202 TEE_Result res; 203 204 if (buf_size != TEE_FS_KM_FEK_SIZE) 205 return TEE_ERROR_BAD_PARAMETERS; 206 207 res = generate_fek(buf, TEE_FS_KM_FEK_SIZE); 208 if (res != TEE_SUCCESS) 209 return res; 210 211 return tee_fs_fek_crypt(uuid, TEE_MODE_ENCRYPT, buf, 212 TEE_FS_KM_FEK_SIZE, buf); 213 } 214 215 static TEE_Result sha256(uint8_t *out, size_t out_size, const uint8_t *in, 216 size_t in_size) 217 { 218 TEE_Result res; 219 uint8_t *ctx = NULL; 220 size_t ctx_size; 221 uint32_t algo = TEE_ALG_SHA256; 222 223 res = crypto_hash_get_ctx_size(algo, &ctx_size); 224 if (res != TEE_SUCCESS) 225 return res; 226 227 ctx = malloc(ctx_size); 228 if (!ctx) 229 return TEE_ERROR_OUT_OF_MEMORY; 230 231 res = crypto_hash_init(ctx, algo); 232 if (res != TEE_SUCCESS) 233 goto out; 234 235 res = crypto_hash_update(ctx, algo, in, in_size); 236 if (res != TEE_SUCCESS) 237 goto out; 238 239 res = crypto_hash_final(ctx, algo, out, out_size); 240 241 out: 242 free(ctx); 243 return res; 244 } 245 246 static TEE_Result aes_ecb(uint8_t out[TEE_AES_BLOCK_SIZE], 247 const uint8_t in[TEE_AES_BLOCK_SIZE], 248 const uint8_t *key, size_t key_size) 249 { 250 TEE_Result res; 251 uint8_t *ctx = NULL; 252 size_t ctx_size; 253 uint32_t algo = TEE_ALG_AES_ECB_NOPAD; 254 255 res = crypto_cipher_get_ctx_size(algo, &ctx_size); 256 if (res != TEE_SUCCESS) 257 return res; 258 259 ctx = malloc(ctx_size); 260 if (!ctx) 261 return TEE_ERROR_OUT_OF_MEMORY; 262 263 res = crypto_cipher_init(ctx, algo, TEE_MODE_ENCRYPT, key, 264 key_size, NULL, 0, NULL, 0); 265 if (res != TEE_SUCCESS) 266 goto out; 267 268 res = crypto_cipher_update(ctx, algo, TEE_MODE_ENCRYPT, true, in, 269 TEE_AES_BLOCK_SIZE, out); 270 if (res != TEE_SUCCESS) 271 goto out; 272 273 crypto_cipher_final(ctx, algo); 274 res = TEE_SUCCESS; 275 276 out: 277 free(ctx); 278 return res; 279 } 280 281 static TEE_Result essiv(uint8_t iv[TEE_AES_BLOCK_SIZE], 282 const uint8_t fek[TEE_FS_KM_FEK_SIZE], 283 uint16_t blk_idx) 284 { 285 TEE_Result res; 286 uint8_t sha[TEE_SHA256_HASH_SIZE]; 287 uint8_t pad_blkid[TEE_AES_BLOCK_SIZE] = { 0, }; 288 289 res = sha256(sha, sizeof(sha), fek, TEE_FS_KM_FEK_SIZE); 290 if (res != TEE_SUCCESS) 291 return res; 292 293 pad_blkid[0] = (blk_idx & 0xFF); 294 pad_blkid[1] = (blk_idx & 0xFF00) >> 8; 295 296 return aes_ecb(iv, pad_blkid, sha, 16); 297 } 298 299 /* 300 * Encryption/decryption of RPMB FS file data. This is AES CBC with ESSIV. 301 */ 302 TEE_Result tee_fs_crypt_block(const TEE_UUID *uuid, uint8_t *out, 303 const uint8_t *in, size_t size, 304 uint16_t blk_idx, const uint8_t *encrypted_fek, 305 TEE_OperationMode mode) 306 { 307 TEE_Result res; 308 uint8_t fek[TEE_FS_KM_FEK_SIZE]; 309 uint8_t iv[TEE_AES_BLOCK_SIZE]; 310 uint8_t *ctx; 311 size_t ctx_size; 312 uint32_t algo = TEE_ALG_AES_CBC_NOPAD; 313 314 DMSG("%scrypt block #%u", (mode == TEE_MODE_ENCRYPT) ? "En" : "De", 315 blk_idx); 316 317 /* Decrypt FEK */ 318 res = tee_fs_fek_crypt(uuid, TEE_MODE_DECRYPT, encrypted_fek, 319 TEE_FS_KM_FEK_SIZE, fek); 320 if (res != TEE_SUCCESS) 321 return res; 322 323 /* Compute initialization vector for this block */ 324 res = essiv(iv, fek, blk_idx); 325 326 /* Run AES CBC */ 327 res = crypto_cipher_get_ctx_size(algo, &ctx_size); 328 if (res != TEE_SUCCESS) 329 return res; 330 ctx = malloc(ctx_size); 331 if (!ctx) 332 return TEE_ERROR_OUT_OF_MEMORY; 333 334 res = crypto_cipher_init(ctx, algo, mode, fek, sizeof(fek), NULL, 335 0, iv, TEE_AES_BLOCK_SIZE); 336 if (res != TEE_SUCCESS) 337 goto exit; 338 res = crypto_cipher_update(ctx, algo, mode, true, in, size, out); 339 if (res != TEE_SUCCESS) 340 goto exit; 341 342 crypto_cipher_final(ctx, algo); 343 344 exit: 345 free(ctx); 346 return res; 347 } 348 349 service_init_late(tee_fs_init_key_manager); 350