1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2014, STMicroelectronics International N.V. 4 */ 5 6 #include <assert.h> 7 #include <crypto/crypto.h> 8 #include <kernel/misc.h> 9 #include <kernel/msg_param.h> 10 #include <kernel/mutex.h> 11 #include <kernel/panic.h> 12 #include <kernel/tee_common.h> 13 #include <kernel/tee_common_otp.h> 14 #include <kernel/tee_misc.h> 15 #include <kernel/thread.h> 16 #include <mm/core_memprot.h> 17 #include <mm/mobj.h> 18 #include <mm/tee_mm.h> 19 #include <optee_rpc_cmd.h> 20 #include <stdlib.h> 21 #include <string_ext.h> 22 #include <string.h> 23 #include <sys/queue.h> 24 #include <tee/tee_fs.h> 25 #include <tee/tee_fs_key_manager.h> 26 #include <tee/tee_pobj.h> 27 #include <tee/tee_svc_storage.h> 28 #include <trace.h> 29 #include <util.h> 30 31 #define RPMB_STORAGE_START_ADDRESS 0 32 #define RPMB_FS_FAT_START_ADDRESS 512 33 #define RPMB_BLOCK_SIZE_SHIFT 8 34 #define RPMB_CID_PRV_OFFSET 9 35 #define RPMB_CID_CRC_OFFSET 15 36 37 #define RPMB_FS_MAGIC 0x52504D42 38 #define FS_VERSION 2 39 #define N_ENTRIES 8 40 41 #define FILE_IS_ACTIVE (1u << 0) 42 #define FILE_IS_LAST_ENTRY (1u << 1) 43 44 #define TEE_RPMB_FS_FILENAME_LENGTH 224 45 46 /** 47 * FS parameters: Information often used by internal functions. 48 * fat_start_address will be set by rpmb_fs_setup(). 49 * rpmb_fs_parameters can be read by any other function. 50 */ 51 struct rpmb_fs_parameters { 52 uint32_t fat_start_address; 53 uint32_t max_rpmb_address; 54 }; 55 56 /** 57 * File entry for a single file in a RPMB_FS partition. 58 */ 59 struct rpmb_fat_entry { 60 uint32_t start_address; 61 uint32_t data_size; 62 uint32_t flags; 63 uint32_t write_counter; 64 uint8_t fek[TEE_FS_KM_FEK_SIZE]; 65 char filename[TEE_RPMB_FS_FILENAME_LENGTH]; 66 }; 67 68 /** 69 * FAT entry context with reference to a FAT entry and its 70 * location in RPMB. 71 */ 72 struct rpmb_file_handle { 73 struct rpmb_fat_entry fat_entry; 74 const TEE_UUID *uuid; 75 char filename[TEE_RPMB_FS_FILENAME_LENGTH]; 76 /* Address for current entry in RPMB */ 77 uint32_t rpmb_fat_address; 78 }; 79 80 /** 81 * RPMB_FS partition data 82 */ 83 struct rpmb_fs_partition { 84 uint32_t rpmb_fs_magic; 85 uint32_t fs_version; 86 uint32_t write_counter; 87 uint32_t fat_start_address; 88 /* Do not use reserved[] for other purpose than partition data. */ 89 uint8_t reserved[112]; 90 }; 91 92 /** 93 * A node in a list of directory entries. 94 */ 95 struct tee_rpmb_fs_dirent { 96 struct tee_fs_dirent entry; 97 SIMPLEQ_ENTRY(tee_rpmb_fs_dirent) link; 98 }; 99 100 /** 101 * The RPMB directory representation. It contains a queue of 102 * RPMB directory entries: 'next'. 103 * The current pointer points to the last directory entry 104 * returned by readdir(). 105 */ 106 struct tee_fs_dir { 107 struct tee_rpmb_fs_dirent *current; 108 /* */ 109 SIMPLEQ_HEAD(next_head, tee_rpmb_fs_dirent) next; 110 }; 111 112 static struct rpmb_fs_parameters *fs_par; 113 114 /* 115 * Lower interface to RPMB device 116 */ 117 118 #define RPMB_DATA_OFFSET (RPMB_STUFF_DATA_SIZE + RPMB_KEY_MAC_SIZE) 119 #define RPMB_MAC_PROTECT_DATA_SIZE (RPMB_DATA_FRAME_SIZE - RPMB_DATA_OFFSET) 120 121 #define RPMB_MSG_TYPE_REQ_AUTH_KEY_PROGRAM 0x0001 122 #define RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ 0x0002 123 #define RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE 0x0003 124 #define RPMB_MSG_TYPE_REQ_AUTH_DATA_READ 0x0004 125 #define RPMB_MSG_TYPE_REQ_RESULT_READ 0x0005 126 #define RPMB_MSG_TYPE_RESP_AUTH_KEY_PROGRAM 0x0100 127 #define RPMB_MSG_TYPE_RESP_WRITE_COUNTER_VAL_READ 0x0200 128 #define RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE 0x0300 129 #define RPMB_MSG_TYPE_RESP_AUTH_DATA_READ 0x0400 130 131 #define RPMB_STUFF_DATA_SIZE 196 132 #define RPMB_KEY_MAC_SIZE 32 133 #define RPMB_DATA_SIZE 256 134 #define RPMB_NONCE_SIZE 16 135 #define RPMB_DATA_FRAME_SIZE 512 136 137 #define RPMB_RESULT_OK 0x00 138 #define RPMB_RESULT_GENERAL_FAILURE 0x01 139 #define RPMB_RESULT_AUTH_FAILURE 0x02 140 #define RPMB_RESULT_COUNTER_FAILURE 0x03 141 #define RPMB_RESULT_ADDRESS_FAILURE 0x04 142 #define RPMB_RESULT_WRITE_FAILURE 0x05 143 #define RPMB_RESULT_READ_FAILURE 0x06 144 #define RPMB_RESULT_AUTH_KEY_NOT_PROGRAMMED 0x07 145 #define RPMB_RESULT_MASK 0x3F 146 #define RPMB_RESULT_WR_CNT_EXPIRED 0x80 147 148 /* RPMB internal commands */ 149 #define RPMB_CMD_DATA_REQ 0x00 150 #define RPMB_CMD_GET_DEV_INFO 0x01 151 152 #define RPMB_SIZE_SINGLE (128 * 1024) 153 154 /* Error codes for get_dev_info request/response. */ 155 #define RPMB_CMD_GET_DEV_INFO_RET_OK 0x00 156 #define RPMB_CMD_GET_DEV_INFO_RET_ERROR 0x01 157 158 struct rpmb_data_frame { 159 uint8_t stuff_bytes[RPMB_STUFF_DATA_SIZE]; 160 uint8_t key_mac[RPMB_KEY_MAC_SIZE]; 161 uint8_t data[RPMB_DATA_SIZE]; 162 uint8_t nonce[RPMB_NONCE_SIZE]; 163 uint8_t write_counter[4]; 164 uint8_t address[2]; 165 uint8_t block_count[2]; 166 uint8_t op_result[2]; 167 uint8_t msg_type[2]; 168 }; 169 170 struct rpmb_req { 171 uint16_t cmd; 172 uint16_t dev_id; 173 uint16_t block_count; 174 /* variable length of data */ 175 /* uint8_t data[]; REMOVED! */ 176 }; 177 178 #define TEE_RPMB_REQ_DATA(req) \ 179 ((void *)((struct rpmb_req *)(req) + 1)) 180 181 struct rpmb_raw_data { 182 uint16_t msg_type; 183 uint16_t *op_result; 184 uint16_t *block_count; 185 uint16_t *blk_idx; 186 uint32_t *write_counter; 187 uint8_t *nonce; 188 uint8_t *key_mac; 189 uint8_t *data; 190 /* data length to read or write */ 191 uint32_t len; 192 /* Byte address offset in the first block involved */ 193 uint8_t byte_offset; 194 }; 195 196 #define RPMB_EMMC_CID_SIZE 16 197 struct rpmb_dev_info { 198 uint8_t cid[RPMB_EMMC_CID_SIZE]; 199 /* EXT CSD-slice 168 "RPMB Size" */ 200 uint8_t rpmb_size_mult; 201 /* EXT CSD-slice 222 "Reliable Write Sector Count" */ 202 uint8_t rel_wr_sec_c; 203 /* Check the ret code and accept the data only if it is OK. */ 204 uint8_t ret_code; 205 }; 206 207 /* 208 * Struct for rpmb context data. 209 * 210 * @key RPMB key. 211 * @cid eMMC card ID. 212 * @wr_cnt Current write counter. 213 * @max_blk_idx The highest block index supported by current device. 214 * @rel_wr_blkcnt Max number of data blocks for each reliable write. 215 * @dev_id Device ID of the eMMC device. 216 * @wr_cnt_synced Flag indicating if write counter is synced to RPMB. 217 * @key_derived Flag indicating if key has been generated. 218 * @key_verified Flag indicating the key generated is verified ok. 219 * @dev_info_synced Flag indicating if dev info has been retrieved from RPMB. 220 */ 221 struct tee_rpmb_ctx { 222 uint8_t key[RPMB_KEY_MAC_SIZE]; 223 uint8_t cid[RPMB_EMMC_CID_SIZE]; 224 uint32_t wr_cnt; 225 uint16_t max_blk_idx; 226 uint16_t rel_wr_blkcnt; 227 uint16_t dev_id; 228 bool wr_cnt_synced; 229 bool key_derived; 230 bool key_verified; 231 bool dev_info_synced; 232 }; 233 234 static struct tee_rpmb_ctx *rpmb_ctx; 235 236 /* 237 * Mutex to serialize the operations exported by this file. 238 * It protects rpmb_ctx and prevents overlapping operations on eMMC devices with 239 * different IDs. 240 */ 241 static struct mutex rpmb_mutex = MUTEX_INITIALIZER; 242 243 #ifdef CFG_RPMB_TESTKEY 244 245 static const uint8_t rpmb_test_key[RPMB_KEY_MAC_SIZE] = { 246 0xD3, 0xEB, 0x3E, 0xC3, 0x6E, 0x33, 0x4C, 0x9F, 247 0x98, 0x8C, 0xE2, 0xC0, 0xB8, 0x59, 0x54, 0x61, 248 0x0D, 0x2B, 0xCF, 0x86, 0x64, 0x84, 0x4D, 0xF2, 249 0xAB, 0x56, 0xE6, 0xC6, 0x1B, 0xB7, 0x01, 0xE4 250 }; 251 252 static TEE_Result tee_rpmb_key_gen(uint16_t dev_id __unused, 253 uint8_t *key, uint32_t len) 254 { 255 TEE_Result res = TEE_SUCCESS; 256 257 if (!key || RPMB_KEY_MAC_SIZE != len) { 258 res = TEE_ERROR_BAD_PARAMETERS; 259 goto out; 260 } 261 262 DMSG("RPMB: Using test key"); 263 memcpy(key, rpmb_test_key, RPMB_KEY_MAC_SIZE); 264 265 out: 266 return res; 267 } 268 269 #else /* !CFG_RPMB_TESTKEY */ 270 271 /* 272 * NOTE: We need a common API to get hw unique key and it 273 * should return error when the hw unique is not a valid 274 * one as stated below. 275 * We need to make sure the hw unique we get is valid by: 276 * 1. In case of HUK is used, checking if OTP is hidden (in 277 * which case only zeros will be returned) or not; 278 * 2. In case of SSK is used, checking if SSK in OTP is 279 * write_locked (which means a valid key is provisioned) 280 * or not. 281 * 282 * Maybe tee_get_hw_unique_key() should be exposed as 283 * generic API for getting hw unique key! 284 */ 285 static TEE_Result tee_get_hw_unique_key(struct tee_hw_unique_key *hwkey) 286 { 287 if (!hwkey) 288 return TEE_ERROR_BAD_PARAMETERS; 289 290 return tee_otp_get_hw_unique_key(hwkey); 291 } 292 293 static TEE_Result tee_rpmb_key_gen(uint16_t dev_id __unused, 294 uint8_t *key, uint32_t len) 295 { 296 TEE_Result res; 297 struct tee_hw_unique_key hwkey; 298 uint8_t message[RPMB_EMMC_CID_SIZE]; 299 void *ctx = NULL; 300 301 if (!key || RPMB_KEY_MAC_SIZE != len) { 302 res = TEE_ERROR_BAD_PARAMETERS; 303 goto out; 304 } 305 306 IMSG("RPMB: Using generated key"); 307 res = tee_get_hw_unique_key(&hwkey); 308 if (res != TEE_SUCCESS) 309 goto out; 310 311 res = crypto_mac_alloc_ctx(&ctx, TEE_ALG_HMAC_SHA256); 312 if (res) 313 goto out; 314 315 /* 316 * PRV/CRC would be changed when doing eMMC FFU 317 * The following fields should be masked off when deriving RPMB key 318 * 319 * CID [55: 48]: PRV (Product revision) 320 * CID [07: 01]: CRC (CRC7 checksum) 321 * CID [00]: not used 322 */ 323 memcpy(message, rpmb_ctx->cid, RPMB_EMMC_CID_SIZE); 324 memset(message + RPMB_CID_PRV_OFFSET, 0, 1); 325 memset(message + RPMB_CID_CRC_OFFSET, 0, 1); 326 res = crypto_mac_init(ctx, TEE_ALG_HMAC_SHA256, hwkey.data, 327 HW_UNIQUE_KEY_LENGTH); 328 if (res != TEE_SUCCESS) 329 goto out; 330 331 res = crypto_mac_update(ctx, TEE_ALG_HMAC_SHA256, 332 message, 333 RPMB_EMMC_CID_SIZE); 334 if (res != TEE_SUCCESS) 335 goto out; 336 337 res = crypto_mac_final(ctx, TEE_ALG_HMAC_SHA256, key, len); 338 339 out: 340 crypto_mac_free_ctx(ctx, TEE_ALG_HMAC_SHA256); 341 return res; 342 } 343 344 #endif /* !CFG_RPMB_TESTKEY */ 345 346 static void u32_to_bytes(uint32_t u32, uint8_t *bytes) 347 { 348 *bytes = (uint8_t) (u32 >> 24); 349 *(bytes + 1) = (uint8_t) (u32 >> 16); 350 *(bytes + 2) = (uint8_t) (u32 >> 8); 351 *(bytes + 3) = (uint8_t) u32; 352 } 353 354 static void bytes_to_u32(uint8_t *bytes, uint32_t *u32) 355 { 356 *u32 = (uint32_t) ((*(bytes) << 24) + 357 (*(bytes + 1) << 16) + 358 (*(bytes + 2) << 8) + (*(bytes + 3))); 359 } 360 361 static void u16_to_bytes(uint16_t u16, uint8_t *bytes) 362 { 363 *bytes = (uint8_t) (u16 >> 8); 364 *(bytes + 1) = (uint8_t) u16; 365 } 366 367 static void bytes_to_u16(uint8_t *bytes, uint16_t *u16) 368 { 369 *u16 = (uint16_t) ((*bytes << 8) + *(bytes + 1)); 370 } 371 372 static TEE_Result tee_rpmb_mac_calc(uint8_t *mac, uint32_t macsize, 373 uint8_t *key, uint32_t keysize, 374 struct rpmb_data_frame *datafrms, 375 uint16_t blkcnt) 376 { 377 TEE_Result res = TEE_ERROR_GENERIC; 378 int i; 379 void *ctx = NULL; 380 381 if (!mac || !key || !datafrms) 382 return TEE_ERROR_BAD_PARAMETERS; 383 384 res = crypto_mac_alloc_ctx(&ctx, TEE_ALG_HMAC_SHA256); 385 if (res) 386 return res; 387 388 res = crypto_mac_init(ctx, TEE_ALG_HMAC_SHA256, key, keysize); 389 if (res != TEE_SUCCESS) 390 goto func_exit; 391 392 for (i = 0; i < blkcnt; i++) { 393 res = crypto_mac_update(ctx, TEE_ALG_HMAC_SHA256, 394 datafrms[i].data, 395 RPMB_MAC_PROTECT_DATA_SIZE); 396 if (res != TEE_SUCCESS) 397 goto func_exit; 398 } 399 400 res = crypto_mac_final(ctx, TEE_ALG_HMAC_SHA256, mac, macsize); 401 if (res != TEE_SUCCESS) 402 goto func_exit; 403 404 res = TEE_SUCCESS; 405 406 func_exit: 407 crypto_mac_free_ctx(ctx, TEE_ALG_HMAC_SHA256); 408 return res; 409 } 410 411 struct tee_rpmb_mem { 412 struct mobj *phreq_mobj; 413 struct mobj *phresp_mobj; 414 size_t req_size; 415 size_t resp_size; 416 }; 417 418 static void tee_rpmb_free(struct tee_rpmb_mem *mem) 419 { 420 if (!mem) 421 return; 422 423 if (mem->phreq_mobj) { 424 thread_rpc_free_payload(mem->phreq_mobj); 425 mem->phreq_mobj = NULL; 426 } 427 if (mem->phresp_mobj) { 428 thread_rpc_free_payload(mem->phresp_mobj); 429 mem->phresp_mobj = NULL; 430 } 431 } 432 433 434 static TEE_Result tee_rpmb_alloc(size_t req_size, size_t resp_size, 435 struct tee_rpmb_mem *mem, void **req, void **resp) 436 { 437 TEE_Result res = TEE_SUCCESS; 438 size_t req_s = ROUNDUP(req_size, sizeof(uint32_t)); 439 size_t resp_s = ROUNDUP(resp_size, sizeof(uint32_t)); 440 441 if (!mem) 442 return TEE_ERROR_BAD_PARAMETERS; 443 444 memset(mem, 0, sizeof(*mem)); 445 446 mem->phreq_mobj = thread_rpc_alloc_payload(req_s); 447 mem->phresp_mobj = thread_rpc_alloc_payload(resp_s); 448 449 if (!mem->phreq_mobj || !mem->phresp_mobj) { 450 res = TEE_ERROR_OUT_OF_MEMORY; 451 goto out; 452 } 453 454 *req = mobj_get_va(mem->phreq_mobj, 0); 455 *resp = mobj_get_va(mem->phresp_mobj, 0); 456 if (!*req || !*resp) { 457 res = TEE_ERROR_GENERIC; 458 goto out; 459 } 460 461 mem->req_size = req_size; 462 mem->resp_size = resp_size; 463 464 out: 465 if (res != TEE_SUCCESS) 466 tee_rpmb_free(mem); 467 return res; 468 } 469 470 static TEE_Result tee_rpmb_invoke(struct tee_rpmb_mem *mem) 471 { 472 struct thread_param params[2] = { 473 [0] = THREAD_PARAM_MEMREF(IN, mem->phreq_mobj, 0, 474 mem->req_size), 475 [1] = THREAD_PARAM_MEMREF(OUT, mem->phresp_mobj, 0, 476 mem->resp_size), 477 }; 478 479 return thread_rpc_cmd(OPTEE_RPC_CMD_RPMB, 2, params); 480 } 481 482 static bool is_zero(const uint8_t *buf, size_t size) 483 { 484 size_t i; 485 486 for (i = 0; i < size; i++) 487 if (buf[i]) 488 return false; 489 return true; 490 } 491 492 static TEE_Result encrypt_block(uint8_t *out, const uint8_t *in, 493 uint16_t blk_idx, const uint8_t *fek, 494 const TEE_UUID *uuid) 495 { 496 return tee_fs_crypt_block(uuid, out, in, RPMB_DATA_SIZE, 497 blk_idx, fek, TEE_MODE_ENCRYPT); 498 } 499 500 static TEE_Result decrypt_block(uint8_t *out, const uint8_t *in, 501 uint16_t blk_idx, const uint8_t *fek, 502 const TEE_UUID *uuid) 503 { 504 return tee_fs_crypt_block(uuid, out, in, RPMB_DATA_SIZE, 505 blk_idx, fek, TEE_MODE_DECRYPT); 506 } 507 508 /* Decrypt/copy at most one block of data */ 509 static TEE_Result decrypt(uint8_t *out, const struct rpmb_data_frame *frm, 510 size_t size, size_t offset, 511 uint16_t blk_idx __maybe_unused, const uint8_t *fek, 512 const TEE_UUID *uuid) 513 { 514 uint8_t *tmp __maybe_unused; 515 516 517 if ((size + offset < size) || (size + offset > RPMB_DATA_SIZE)) 518 panic("invalid size or offset"); 519 520 if (!fek) { 521 /* Block is not encrypted (not a file data block) */ 522 memcpy(out, frm->data + offset, size); 523 } else if (is_zero(fek, TEE_FS_KM_FEK_SIZE)) { 524 /* The file was created with encryption disabled */ 525 return TEE_ERROR_SECURITY; 526 } else { 527 /* Block is encrypted */ 528 if (size < RPMB_DATA_SIZE) { 529 /* 530 * Since output buffer is not large enough to hold one 531 * block we must allocate a temporary buffer. 532 */ 533 tmp = malloc(RPMB_DATA_SIZE); 534 if (!tmp) 535 return TEE_ERROR_OUT_OF_MEMORY; 536 decrypt_block(tmp, frm->data, blk_idx, fek, uuid); 537 memcpy(out, tmp + offset, size); 538 free(tmp); 539 } else { 540 decrypt_block(out, frm->data, blk_idx, fek, uuid); 541 } 542 } 543 544 return TEE_SUCCESS; 545 } 546 547 static TEE_Result tee_rpmb_req_pack(struct rpmb_req *req, 548 struct rpmb_raw_data *rawdata, 549 uint16_t nbr_frms, uint16_t dev_id, 550 const uint8_t *fek, const TEE_UUID *uuid) 551 { 552 TEE_Result res = TEE_ERROR_GENERIC; 553 int i; 554 struct rpmb_data_frame *datafrm; 555 556 if (!req || !rawdata || !nbr_frms) 557 return TEE_ERROR_BAD_PARAMETERS; 558 559 /* 560 * Check write blockcount is not bigger than reliable write 561 * blockcount. 562 */ 563 if ((rawdata->msg_type == RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE) && 564 (nbr_frms > rpmb_ctx->rel_wr_blkcnt)) { 565 DMSG("wr_blkcnt(%d) > rel_wr_blkcnt(%d)", nbr_frms, 566 rpmb_ctx->rel_wr_blkcnt); 567 return TEE_ERROR_GENERIC; 568 } 569 570 req->cmd = RPMB_CMD_DATA_REQ; 571 req->dev_id = dev_id; 572 573 /* Allocate memory for construct all data packets and calculate MAC. */ 574 datafrm = calloc(nbr_frms, RPMB_DATA_FRAME_SIZE); 575 if (!datafrm) 576 return TEE_ERROR_OUT_OF_MEMORY; 577 578 for (i = 0; i < nbr_frms; i++) { 579 u16_to_bytes(rawdata->msg_type, datafrm[i].msg_type); 580 581 if (rawdata->block_count) 582 u16_to_bytes(*rawdata->block_count, 583 datafrm[i].block_count); 584 585 if (rawdata->blk_idx) { 586 /* Check the block index is within range. */ 587 if ((*rawdata->blk_idx + nbr_frms) > 588 rpmb_ctx->max_blk_idx) { 589 res = TEE_ERROR_GENERIC; 590 goto func_exit; 591 } 592 u16_to_bytes(*rawdata->blk_idx, datafrm[i].address); 593 } 594 595 if (rawdata->write_counter) 596 u32_to_bytes(*rawdata->write_counter, 597 datafrm[i].write_counter); 598 599 if (rawdata->nonce) 600 memcpy(datafrm[i].nonce, rawdata->nonce, 601 RPMB_NONCE_SIZE); 602 603 if (rawdata->data) { 604 if (fek) 605 encrypt_block(datafrm[i].data, 606 rawdata->data + (i * RPMB_DATA_SIZE), 607 *rawdata->blk_idx + i, fek, uuid); 608 else 609 memcpy(datafrm[i].data, 610 rawdata->data + (i * RPMB_DATA_SIZE), 611 RPMB_DATA_SIZE); 612 } 613 } 614 615 if (rawdata->key_mac) { 616 if (rawdata->msg_type == RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE) { 617 res = 618 tee_rpmb_mac_calc(rawdata->key_mac, 619 RPMB_KEY_MAC_SIZE, rpmb_ctx->key, 620 RPMB_KEY_MAC_SIZE, datafrm, 621 nbr_frms); 622 if (res != TEE_SUCCESS) 623 goto func_exit; 624 } 625 memcpy(datafrm[nbr_frms - 1].key_mac, 626 rawdata->key_mac, RPMB_KEY_MAC_SIZE); 627 } 628 629 memcpy(TEE_RPMB_REQ_DATA(req), datafrm, 630 nbr_frms * RPMB_DATA_FRAME_SIZE); 631 632 #ifdef CFG_RPMB_FS_DEBUG_DATA 633 for (i = 0; i < nbr_frms; i++) { 634 DMSG("Dumping data frame %d:", i); 635 DHEXDUMP((uint8_t *)&datafrm[i] + RPMB_STUFF_DATA_SIZE, 636 512 - RPMB_STUFF_DATA_SIZE); 637 } 638 #endif 639 640 res = TEE_SUCCESS; 641 func_exit: 642 free(datafrm); 643 return res; 644 } 645 646 static TEE_Result data_cpy_mac_calc_1b(struct rpmb_raw_data *rawdata, 647 struct rpmb_data_frame *frm, 648 const uint8_t *fek, const TEE_UUID *uuid) 649 { 650 TEE_Result res; 651 uint8_t *data; 652 uint16_t idx; 653 654 if (rawdata->len + rawdata->byte_offset > RPMB_DATA_SIZE) 655 return TEE_ERROR_BAD_PARAMETERS; 656 657 res = tee_rpmb_mac_calc(rawdata->key_mac, RPMB_KEY_MAC_SIZE, 658 rpmb_ctx->key, RPMB_KEY_MAC_SIZE, frm, 1); 659 if (res != TEE_SUCCESS) 660 return res; 661 662 data = rawdata->data; 663 bytes_to_u16(frm->address, &idx); 664 665 res = decrypt(data, frm, rawdata->len, rawdata->byte_offset, idx, fek, 666 uuid); 667 return res; 668 } 669 670 static TEE_Result tee_rpmb_data_cpy_mac_calc(struct rpmb_data_frame *datafrm, 671 struct rpmb_raw_data *rawdata, 672 uint16_t nbr_frms, 673 struct rpmb_data_frame *lastfrm, 674 const uint8_t *fek, 675 const TEE_UUID *uuid) 676 { 677 TEE_Result res = TEE_ERROR_GENERIC; 678 int i; 679 void *ctx = NULL; 680 uint16_t offset; 681 uint32_t size; 682 uint8_t *data; 683 uint16_t start_idx; 684 struct rpmb_data_frame localfrm; 685 686 if (!datafrm || !rawdata || !nbr_frms || !lastfrm) 687 return TEE_ERROR_BAD_PARAMETERS; 688 689 if (nbr_frms == 1) 690 return data_cpy_mac_calc_1b(rawdata, lastfrm, fek, uuid); 691 692 /* nbr_frms > 1 */ 693 694 data = rawdata->data; 695 696 res = crypto_mac_alloc_ctx(&ctx, TEE_ALG_HMAC_SHA256); 697 if (res) 698 goto func_exit; 699 700 res = crypto_mac_init(ctx, TEE_ALG_HMAC_SHA256, rpmb_ctx->key, 701 RPMB_KEY_MAC_SIZE); 702 if (res != TEE_SUCCESS) 703 goto func_exit; 704 705 /* 706 * Note: JEDEC JESD84-B51: "In every packet the address is the start 707 * address of the full access (not address of the individual half a 708 * sector)" 709 */ 710 bytes_to_u16(lastfrm->address, &start_idx); 711 712 for (i = 0; i < (nbr_frms - 1); i++) { 713 714 /* 715 * By working on a local copy of the RPMB frame, we ensure that 716 * the data can not be modified after the MAC is computed but 717 * before the payload is decrypted/copied to the output buffer. 718 */ 719 memcpy(&localfrm, &datafrm[i], RPMB_DATA_FRAME_SIZE); 720 721 res = crypto_mac_update(ctx, TEE_ALG_HMAC_SHA256, localfrm.data, 722 RPMB_MAC_PROTECT_DATA_SIZE); 723 if (res != TEE_SUCCESS) 724 goto func_exit; 725 726 if (i == 0) { 727 /* First block */ 728 offset = rawdata->byte_offset; 729 size = RPMB_DATA_SIZE - offset; 730 } else { 731 /* Middle blocks */ 732 size = RPMB_DATA_SIZE; 733 offset = 0; 734 } 735 736 res = decrypt(data, &localfrm, size, offset, start_idx + i, 737 fek, uuid); 738 if (res != TEE_SUCCESS) 739 goto func_exit; 740 741 data += size; 742 } 743 744 /* Last block */ 745 size = (rawdata->len + rawdata->byte_offset) % RPMB_DATA_SIZE; 746 if (size == 0) 747 size = RPMB_DATA_SIZE; 748 res = decrypt(data, lastfrm, size, 0, start_idx + nbr_frms - 1, fek, 749 uuid); 750 if (res != TEE_SUCCESS) 751 goto func_exit; 752 753 /* Update MAC against the last block */ 754 res = crypto_mac_update(ctx, TEE_ALG_HMAC_SHA256, lastfrm->data, 755 RPMB_MAC_PROTECT_DATA_SIZE); 756 if (res != TEE_SUCCESS) 757 goto func_exit; 758 759 res = crypto_mac_final(ctx, TEE_ALG_HMAC_SHA256, rawdata->key_mac, 760 RPMB_KEY_MAC_SIZE); 761 if (res != TEE_SUCCESS) 762 goto func_exit; 763 764 res = TEE_SUCCESS; 765 766 func_exit: 767 crypto_mac_free_ctx(ctx, TEE_ALG_HMAC_SHA256); 768 return res; 769 } 770 771 static TEE_Result tee_rpmb_resp_unpack_verify(struct rpmb_data_frame *datafrm, 772 struct rpmb_raw_data *rawdata, 773 uint16_t nbr_frms, 774 const uint8_t *fek, 775 const TEE_UUID *uuid) 776 { 777 TEE_Result res = TEE_ERROR_GENERIC; 778 uint16_t msg_type; 779 uint32_t wr_cnt; 780 uint16_t blk_idx; 781 uint16_t op_result; 782 struct rpmb_data_frame lastfrm; 783 784 if (!datafrm || !rawdata || !nbr_frms) 785 return TEE_ERROR_BAD_PARAMETERS; 786 787 #ifdef CFG_RPMB_FS_DEBUG_DATA 788 for (uint32_t i = 0; i < nbr_frms; i++) { 789 DMSG("Dumping data frame %d:", i); 790 DHEXDUMP((uint8_t *)&datafrm[i] + RPMB_STUFF_DATA_SIZE, 791 512 - RPMB_STUFF_DATA_SIZE); 792 } 793 #endif 794 795 /* Make sure the last data packet can't be modified once verified */ 796 memcpy(&lastfrm, &datafrm[nbr_frms - 1], RPMB_DATA_FRAME_SIZE); 797 798 /* Handle operation result and translate to TEEC error code. */ 799 bytes_to_u16(lastfrm.op_result, &op_result); 800 if (rawdata->op_result) 801 *rawdata->op_result = op_result; 802 if (op_result != RPMB_RESULT_OK) 803 return TEE_ERROR_GENERIC; 804 805 /* Check the response msg_type. */ 806 bytes_to_u16(lastfrm.msg_type, &msg_type); 807 if (msg_type != rawdata->msg_type) { 808 DMSG("Unexpected msg_type (0x%04x != 0x%04x)", msg_type, 809 rawdata->msg_type); 810 return TEE_ERROR_GENERIC; 811 } 812 813 if (rawdata->blk_idx) { 814 bytes_to_u16(lastfrm.address, &blk_idx); 815 if (blk_idx != *rawdata->blk_idx) { 816 DMSG("Unexpected block index"); 817 return TEE_ERROR_GENERIC; 818 } 819 } 820 821 if (rawdata->write_counter) { 822 wr_cnt = *rawdata->write_counter; 823 bytes_to_u32(lastfrm.write_counter, rawdata->write_counter); 824 if (msg_type == RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE) { 825 /* Verify the write counter is incremented by 1 */ 826 if (*rawdata->write_counter != wr_cnt + 1) { 827 DMSG("Counter mismatched (0x%04x/0x%04x)", 828 *rawdata->write_counter, wr_cnt + 1); 829 return TEE_ERROR_SECURITY; 830 } 831 rpmb_ctx->wr_cnt++; 832 } 833 } 834 835 if (rawdata->nonce) { 836 if (buf_compare_ct(rawdata->nonce, lastfrm.nonce, 837 RPMB_NONCE_SIZE) != 0) { 838 DMSG("Nonce mismatched"); 839 return TEE_ERROR_SECURITY; 840 } 841 } 842 843 if (rawdata->key_mac) { 844 if (msg_type == RPMB_MSG_TYPE_RESP_AUTH_DATA_READ) { 845 if (!rawdata->data) 846 return TEE_ERROR_GENERIC; 847 848 res = tee_rpmb_data_cpy_mac_calc(datafrm, rawdata, 849 nbr_frms, &lastfrm, 850 fek, uuid); 851 852 if (res != TEE_SUCCESS) 853 return res; 854 } else { 855 /* 856 * There should be only one data frame for 857 * other msg types. 858 */ 859 if (nbr_frms != 1) 860 return TEE_ERROR_GENERIC; 861 862 res = tee_rpmb_mac_calc(rawdata->key_mac, 863 RPMB_KEY_MAC_SIZE, 864 rpmb_ctx->key, 865 RPMB_KEY_MAC_SIZE, 866 &lastfrm, 1); 867 868 if (res != TEE_SUCCESS) 869 return res; 870 } 871 872 #ifndef CFG_RPMB_FS_NO_MAC 873 if (consttime_memcmp(rawdata->key_mac, 874 (datafrm + nbr_frms - 1)->key_mac, 875 RPMB_KEY_MAC_SIZE) != 0) { 876 DMSG("MAC mismatched:"); 877 #ifdef CFG_RPMB_FS_DEBUG_DATA 878 DHEXDUMP((uint8_t *)rawdata->key_mac, 32); 879 #endif 880 return TEE_ERROR_SECURITY; 881 } 882 #endif /* !CFG_RPMB_FS_NO_MAC */ 883 } 884 885 return TEE_SUCCESS; 886 } 887 888 static TEE_Result tee_rpmb_get_dev_info(uint16_t dev_id, 889 struct rpmb_dev_info *dev_info) 890 { 891 TEE_Result res = TEE_ERROR_GENERIC; 892 struct tee_rpmb_mem mem; 893 struct rpmb_dev_info *di; 894 struct rpmb_req *req = NULL; 895 uint8_t *resp = NULL; 896 uint32_t req_size; 897 uint32_t resp_size; 898 899 if (!dev_info) 900 return TEE_ERROR_BAD_PARAMETERS; 901 902 req_size = sizeof(struct rpmb_req); 903 resp_size = sizeof(struct rpmb_dev_info); 904 res = tee_rpmb_alloc(req_size, resp_size, &mem, 905 (void *)&req, (void *)&resp); 906 if (res != TEE_SUCCESS) 907 goto func_exit; 908 909 req->cmd = RPMB_CMD_GET_DEV_INFO; 910 req->dev_id = dev_id; 911 912 di = (struct rpmb_dev_info *)resp; 913 di->ret_code = RPMB_CMD_GET_DEV_INFO_RET_ERROR; 914 915 res = tee_rpmb_invoke(&mem); 916 if (res != TEE_SUCCESS) 917 goto func_exit; 918 919 if (di->ret_code != RPMB_CMD_GET_DEV_INFO_RET_OK) { 920 res = TEE_ERROR_GENERIC; 921 goto func_exit; 922 } 923 924 memcpy((uint8_t *)dev_info, resp, sizeof(struct rpmb_dev_info)); 925 926 #ifdef CFG_RPMB_FS_DEBUG_DATA 927 DMSG("Dumping dev_info:"); 928 DHEXDUMP((uint8_t *)dev_info, sizeof(struct rpmb_dev_info)); 929 #endif 930 931 res = TEE_SUCCESS; 932 933 func_exit: 934 tee_rpmb_free(&mem); 935 return res; 936 } 937 938 static TEE_Result tee_rpmb_init_read_wr_cnt(uint16_t dev_id, 939 uint32_t *wr_cnt, 940 uint16_t *op_result) 941 { 942 TEE_Result res = TEE_ERROR_GENERIC; 943 struct tee_rpmb_mem mem; 944 uint16_t msg_type; 945 uint8_t nonce[RPMB_NONCE_SIZE]; 946 uint8_t hmac[RPMB_KEY_MAC_SIZE]; 947 struct rpmb_req *req = NULL; 948 struct rpmb_data_frame *resp = NULL; 949 struct rpmb_raw_data rawdata; 950 uint32_t req_size; 951 uint32_t resp_size; 952 953 if (!wr_cnt) 954 return TEE_ERROR_BAD_PARAMETERS; 955 956 req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE; 957 resp_size = RPMB_DATA_FRAME_SIZE; 958 res = tee_rpmb_alloc(req_size, resp_size, &mem, 959 (void *)&req, (void *)&resp); 960 if (res != TEE_SUCCESS) 961 goto func_exit; 962 963 res = crypto_rng_read(nonce, RPMB_NONCE_SIZE); 964 if (res != TEE_SUCCESS) 965 goto func_exit; 966 967 msg_type = RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ; 968 969 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data)); 970 rawdata.msg_type = msg_type; 971 rawdata.nonce = nonce; 972 973 res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL, NULL); 974 if (res != TEE_SUCCESS) 975 goto func_exit; 976 977 res = tee_rpmb_invoke(&mem); 978 if (res != TEE_SUCCESS) 979 goto func_exit; 980 981 msg_type = RPMB_MSG_TYPE_RESP_WRITE_COUNTER_VAL_READ; 982 983 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data)); 984 rawdata.msg_type = msg_type; 985 rawdata.op_result = op_result; 986 rawdata.write_counter = wr_cnt; 987 rawdata.nonce = nonce; 988 rawdata.key_mac = hmac; 989 990 res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL, NULL); 991 if (res != TEE_SUCCESS) 992 goto func_exit; 993 994 res = TEE_SUCCESS; 995 996 func_exit: 997 tee_rpmb_free(&mem); 998 return res; 999 } 1000 1001 static TEE_Result tee_rpmb_verify_key_sync_counter(uint16_t dev_id) 1002 { 1003 uint16_t op_result = 0; 1004 TEE_Result res = TEE_ERROR_GENERIC; 1005 1006 res = tee_rpmb_init_read_wr_cnt(dev_id, &rpmb_ctx->wr_cnt, 1007 &op_result); 1008 1009 if (res == TEE_SUCCESS) { 1010 rpmb_ctx->key_verified = true; 1011 rpmb_ctx->wr_cnt_synced = true; 1012 } 1013 1014 DMSG("Verify key returning 0x%x", res); 1015 return res; 1016 } 1017 1018 #ifdef CFG_RPMB_WRITE_KEY 1019 static TEE_Result tee_rpmb_write_key(uint16_t dev_id) 1020 { 1021 TEE_Result res = TEE_ERROR_GENERIC; 1022 struct tee_rpmb_mem mem = { 0 }; 1023 uint16_t msg_type; 1024 struct rpmb_req *req = NULL; 1025 struct rpmb_data_frame *resp = NULL; 1026 struct rpmb_raw_data rawdata; 1027 uint32_t req_size; 1028 uint32_t resp_size; 1029 1030 req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE; 1031 resp_size = RPMB_DATA_FRAME_SIZE; 1032 res = tee_rpmb_alloc(req_size, resp_size, &mem, 1033 (void *)&req, (void *)&resp); 1034 if (res != TEE_SUCCESS) 1035 goto func_exit; 1036 1037 msg_type = RPMB_MSG_TYPE_REQ_AUTH_KEY_PROGRAM; 1038 1039 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data)); 1040 rawdata.msg_type = msg_type; 1041 rawdata.key_mac = rpmb_ctx->key; 1042 1043 res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL, NULL); 1044 if (res != TEE_SUCCESS) 1045 goto func_exit; 1046 1047 res = tee_rpmb_invoke(&mem); 1048 if (res != TEE_SUCCESS) 1049 goto func_exit; 1050 1051 msg_type = RPMB_MSG_TYPE_RESP_AUTH_KEY_PROGRAM; 1052 1053 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data)); 1054 rawdata.msg_type = msg_type; 1055 1056 res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL, NULL); 1057 if (res != TEE_SUCCESS) 1058 goto func_exit; 1059 1060 res = TEE_SUCCESS; 1061 1062 func_exit: 1063 tee_rpmb_free(&mem); 1064 return res; 1065 } 1066 1067 static TEE_Result tee_rpmb_write_and_verify_key(uint16_t dev_id) 1068 { 1069 TEE_Result res; 1070 1071 DMSG("RPMB INIT: Writing Key"); 1072 res = tee_rpmb_write_key(dev_id); 1073 if (res == TEE_SUCCESS) { 1074 DMSG("RPMB INIT: Verifying Key"); 1075 res = tee_rpmb_verify_key_sync_counter(dev_id); 1076 } 1077 return res; 1078 } 1079 #else 1080 static TEE_Result tee_rpmb_write_and_verify_key(uint16_t dev_id __unused) 1081 { 1082 return TEE_ERROR_BAD_STATE; 1083 } 1084 #endif 1085 1086 /* This function must never return TEE_SUCCESS if rpmb_ctx == NULL */ 1087 static TEE_Result tee_rpmb_init(uint16_t dev_id) 1088 { 1089 TEE_Result res = TEE_SUCCESS; 1090 struct rpmb_dev_info dev_info; 1091 1092 if (!rpmb_ctx) { 1093 rpmb_ctx = calloc(1, sizeof(struct tee_rpmb_ctx)); 1094 if (!rpmb_ctx) 1095 return TEE_ERROR_OUT_OF_MEMORY; 1096 } else if (rpmb_ctx->dev_id != dev_id) { 1097 memset(rpmb_ctx, 0x00, sizeof(struct tee_rpmb_ctx)); 1098 } 1099 1100 rpmb_ctx->dev_id = dev_id; 1101 1102 if (!rpmb_ctx->dev_info_synced) { 1103 DMSG("RPMB: Syncing device information"); 1104 1105 dev_info.rpmb_size_mult = 0; 1106 dev_info.rel_wr_sec_c = 0; 1107 res = tee_rpmb_get_dev_info(dev_id, &dev_info); 1108 if (res != TEE_SUCCESS) 1109 goto func_exit; 1110 1111 DMSG("RPMB: RPMB size is %d*128 KB", dev_info.rpmb_size_mult); 1112 DMSG("RPMB: Reliable Write Sector Count is %d", 1113 dev_info.rel_wr_sec_c); 1114 1115 if (dev_info.rpmb_size_mult == 0) { 1116 res = TEE_ERROR_GENERIC; 1117 goto func_exit; 1118 } 1119 1120 if (MUL_OVERFLOW(dev_info.rpmb_size_mult, 1121 RPMB_SIZE_SINGLE / RPMB_DATA_SIZE, 1122 &rpmb_ctx->max_blk_idx)) { 1123 res = TEE_ERROR_BAD_PARAMETERS; 1124 goto func_exit; 1125 } 1126 rpmb_ctx->max_blk_idx--; 1127 1128 memcpy(rpmb_ctx->cid, dev_info.cid, RPMB_EMMC_CID_SIZE); 1129 1130 #ifdef RPMB_DRIVER_MULTIPLE_WRITE_FIXED 1131 rpmb_ctx->rel_wr_blkcnt = dev_info.rel_wr_sec_c * 2; 1132 #else 1133 rpmb_ctx->rel_wr_blkcnt = 1; 1134 #endif 1135 1136 rpmb_ctx->dev_info_synced = true; 1137 } 1138 1139 if (!rpmb_ctx->key_derived) { 1140 DMSG("RPMB INIT: Deriving key"); 1141 1142 res = tee_rpmb_key_gen(dev_id, rpmb_ctx->key, 1143 RPMB_KEY_MAC_SIZE); 1144 if (res != TEE_SUCCESS) 1145 goto func_exit; 1146 1147 rpmb_ctx->key_derived = true; 1148 } 1149 1150 /* Perform a write counter read to verify if the key is ok. */ 1151 if (!rpmb_ctx->wr_cnt_synced || !rpmb_ctx->key_verified) { 1152 DMSG("RPMB INIT: Verifying Key"); 1153 1154 res = tee_rpmb_verify_key_sync_counter(dev_id); 1155 if (res != TEE_SUCCESS && !rpmb_ctx->key_verified) { 1156 /* 1157 * Need to write the key here and verify it. 1158 */ 1159 res = tee_rpmb_write_and_verify_key(dev_id); 1160 } 1161 } 1162 1163 func_exit: 1164 return res; 1165 } 1166 1167 /* 1168 * Read RPMB data in bytes. 1169 * 1170 * @dev_id Device ID of the eMMC device. 1171 * @addr Byte address of data. 1172 * @data Pointer to the data. 1173 * @len Size of data in bytes. 1174 * @fek Encrypted File Encryption Key or NULL. 1175 */ 1176 static TEE_Result tee_rpmb_read(uint16_t dev_id, uint32_t addr, uint8_t *data, 1177 uint32_t len, const uint8_t *fek, 1178 const TEE_UUID *uuid) 1179 { 1180 TEE_Result res = TEE_ERROR_GENERIC; 1181 struct tee_rpmb_mem mem = { 0 }; 1182 uint16_t msg_type; 1183 uint8_t nonce[RPMB_NONCE_SIZE]; 1184 uint8_t hmac[RPMB_KEY_MAC_SIZE]; 1185 struct rpmb_req *req = NULL; 1186 struct rpmb_data_frame *resp = NULL; 1187 struct rpmb_raw_data rawdata; 1188 uint32_t req_size; 1189 uint32_t resp_size; 1190 uint16_t blk_idx; 1191 uint16_t blkcnt; 1192 uint8_t byte_offset; 1193 1194 if (!data || !len) 1195 return TEE_ERROR_BAD_PARAMETERS; 1196 1197 blk_idx = addr / RPMB_DATA_SIZE; 1198 byte_offset = addr % RPMB_DATA_SIZE; 1199 1200 if (len + byte_offset + RPMB_DATA_SIZE < RPMB_DATA_SIZE) { 1201 /* Overflow */ 1202 return TEE_ERROR_BAD_PARAMETERS; 1203 } 1204 blkcnt = 1205 ROUNDUP(len + byte_offset, RPMB_DATA_SIZE) / RPMB_DATA_SIZE; 1206 res = tee_rpmb_init(dev_id); 1207 if (res != TEE_SUCCESS) 1208 goto func_exit; 1209 1210 req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE; 1211 resp_size = RPMB_DATA_FRAME_SIZE * blkcnt; 1212 res = tee_rpmb_alloc(req_size, resp_size, &mem, 1213 (void *)&req, (void *)&resp); 1214 if (res != TEE_SUCCESS) 1215 goto func_exit; 1216 1217 msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_READ; 1218 res = crypto_rng_read(nonce, RPMB_NONCE_SIZE); 1219 if (res != TEE_SUCCESS) 1220 goto func_exit; 1221 1222 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data)); 1223 rawdata.msg_type = msg_type; 1224 rawdata.nonce = nonce; 1225 rawdata.blk_idx = &blk_idx; 1226 res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL, NULL); 1227 if (res != TEE_SUCCESS) 1228 goto func_exit; 1229 1230 req->block_count = blkcnt; 1231 1232 DMSG("Read %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""), 1233 blk_idx); 1234 1235 res = tee_rpmb_invoke(&mem); 1236 if (res != TEE_SUCCESS) 1237 goto func_exit; 1238 1239 msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_READ; 1240 1241 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data)); 1242 rawdata.msg_type = msg_type; 1243 rawdata.block_count = &blkcnt; 1244 rawdata.blk_idx = &blk_idx; 1245 rawdata.nonce = nonce; 1246 rawdata.key_mac = hmac; 1247 rawdata.data = data; 1248 1249 rawdata.len = len; 1250 rawdata.byte_offset = byte_offset; 1251 1252 res = tee_rpmb_resp_unpack_verify(resp, &rawdata, blkcnt, fek, uuid); 1253 if (res != TEE_SUCCESS) 1254 goto func_exit; 1255 1256 res = TEE_SUCCESS; 1257 1258 func_exit: 1259 tee_rpmb_free(&mem); 1260 return res; 1261 } 1262 1263 static TEE_Result tee_rpmb_write_blk(uint16_t dev_id, uint16_t blk_idx, 1264 const uint8_t *data_blks, uint16_t blkcnt, 1265 const uint8_t *fek, const TEE_UUID *uuid) 1266 { 1267 TEE_Result res; 1268 struct tee_rpmb_mem mem; 1269 uint16_t msg_type; 1270 uint32_t wr_cnt; 1271 uint8_t hmac[RPMB_KEY_MAC_SIZE]; 1272 struct rpmb_req *req = NULL; 1273 struct rpmb_data_frame *resp = NULL; 1274 struct rpmb_raw_data rawdata; 1275 uint32_t req_size; 1276 uint32_t resp_size; 1277 uint32_t nbr_writes; 1278 uint16_t tmp_blkcnt; 1279 uint16_t tmp_blk_idx; 1280 uint16_t i; 1281 1282 DMSG("Write %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""), 1283 blk_idx); 1284 1285 if (!data_blks || !blkcnt) 1286 return TEE_ERROR_BAD_PARAMETERS; 1287 1288 res = tee_rpmb_init(dev_id); 1289 if (res != TEE_SUCCESS) 1290 return res; 1291 1292 /* 1293 * We need to split data when block count 1294 * is bigger than reliable block write count. 1295 */ 1296 if (blkcnt < rpmb_ctx->rel_wr_blkcnt) 1297 req_size = sizeof(struct rpmb_req) + 1298 RPMB_DATA_FRAME_SIZE * blkcnt; 1299 else 1300 req_size = sizeof(struct rpmb_req) + 1301 RPMB_DATA_FRAME_SIZE * rpmb_ctx->rel_wr_blkcnt; 1302 1303 resp_size = RPMB_DATA_FRAME_SIZE; 1304 res = tee_rpmb_alloc(req_size, resp_size, &mem, 1305 (void *)&req, (void *)&resp); 1306 if (res != TEE_SUCCESS) 1307 return res; 1308 1309 nbr_writes = blkcnt / rpmb_ctx->rel_wr_blkcnt; 1310 if (blkcnt % rpmb_ctx->rel_wr_blkcnt > 0) 1311 nbr_writes += 1; 1312 1313 tmp_blkcnt = rpmb_ctx->rel_wr_blkcnt; 1314 tmp_blk_idx = blk_idx; 1315 for (i = 0; i < nbr_writes; i++) { 1316 /* 1317 * To handle the last write of block count which is 1318 * equal or smaller than reliable write block count. 1319 */ 1320 if (i == nbr_writes - 1) 1321 tmp_blkcnt = blkcnt - rpmb_ctx->rel_wr_blkcnt * 1322 (nbr_writes - 1); 1323 1324 msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE; 1325 wr_cnt = rpmb_ctx->wr_cnt; 1326 1327 memset(req, 0x00, req_size); 1328 memset(resp, 0x00, resp_size); 1329 1330 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data)); 1331 rawdata.msg_type = msg_type; 1332 rawdata.block_count = &tmp_blkcnt; 1333 rawdata.blk_idx = &tmp_blk_idx; 1334 rawdata.write_counter = &wr_cnt; 1335 rawdata.key_mac = hmac; 1336 rawdata.data = (uint8_t *)data_blks + 1337 i * rpmb_ctx->rel_wr_blkcnt * RPMB_DATA_SIZE; 1338 1339 res = tee_rpmb_req_pack(req, &rawdata, tmp_blkcnt, dev_id, 1340 fek, uuid); 1341 if (res != TEE_SUCCESS) 1342 goto out; 1343 1344 res = tee_rpmb_invoke(&mem); 1345 if (res != TEE_SUCCESS) { 1346 /* 1347 * To force wr_cnt sync next time, as it might get 1348 * out of sync due to inconsistent operation result! 1349 */ 1350 rpmb_ctx->wr_cnt_synced = false; 1351 goto out; 1352 } 1353 1354 msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE; 1355 1356 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data)); 1357 rawdata.msg_type = msg_type; 1358 rawdata.block_count = &tmp_blkcnt; 1359 rawdata.blk_idx = &tmp_blk_idx; 1360 rawdata.write_counter = &wr_cnt; 1361 rawdata.key_mac = hmac; 1362 1363 res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL, 1364 NULL); 1365 if (res != TEE_SUCCESS) { 1366 /* 1367 * To force wr_cnt sync next time, as it might get 1368 * out of sync due to inconsistent operation result! 1369 */ 1370 rpmb_ctx->wr_cnt_synced = false; 1371 goto out; 1372 } 1373 1374 tmp_blk_idx += tmp_blkcnt; 1375 } 1376 1377 out: 1378 tee_rpmb_free(&mem); 1379 return res; 1380 } 1381 1382 static bool tee_rpmb_write_is_atomic(uint16_t dev_id __unused, uint32_t addr, 1383 uint32_t len) 1384 { 1385 uint8_t byte_offset = addr % RPMB_DATA_SIZE; 1386 uint16_t blkcnt = ROUNDUP(len + byte_offset, 1387 RPMB_DATA_SIZE) / RPMB_DATA_SIZE; 1388 1389 return (blkcnt <= rpmb_ctx->rel_wr_blkcnt); 1390 } 1391 1392 /* 1393 * Write RPMB data in bytes. 1394 * 1395 * @dev_id Device ID of the eMMC device. 1396 * @addr Byte address of data. 1397 * @data Pointer to the data. 1398 * @len Size of data in bytes. 1399 * @fek Encrypted File Encryption Key or NULL. 1400 */ 1401 static TEE_Result tee_rpmb_write(uint16_t dev_id, uint32_t addr, 1402 const uint8_t *data, uint32_t len, 1403 const uint8_t *fek, const TEE_UUID *uuid) 1404 { 1405 TEE_Result res = TEE_ERROR_GENERIC; 1406 uint8_t *data_tmp = NULL; 1407 uint16_t blk_idx; 1408 uint16_t blkcnt; 1409 uint8_t byte_offset; 1410 1411 blk_idx = addr / RPMB_DATA_SIZE; 1412 byte_offset = addr % RPMB_DATA_SIZE; 1413 1414 blkcnt = 1415 ROUNDUP(len + byte_offset, RPMB_DATA_SIZE) / RPMB_DATA_SIZE; 1416 1417 if (byte_offset == 0 && (len % RPMB_DATA_SIZE) == 0) { 1418 res = tee_rpmb_write_blk(dev_id, blk_idx, data, blkcnt, fek, 1419 uuid); 1420 if (res != TEE_SUCCESS) 1421 goto func_exit; 1422 } else { 1423 data_tmp = calloc(blkcnt, RPMB_DATA_SIZE); 1424 if (!data_tmp) { 1425 res = TEE_ERROR_OUT_OF_MEMORY; 1426 goto func_exit; 1427 } 1428 1429 /* Read the complete blocks */ 1430 res = tee_rpmb_read(dev_id, blk_idx * RPMB_DATA_SIZE, data_tmp, 1431 blkcnt * RPMB_DATA_SIZE, fek, uuid); 1432 if (res != TEE_SUCCESS) 1433 goto func_exit; 1434 1435 /* Partial update of the data blocks */ 1436 memcpy(data_tmp + byte_offset, data, len); 1437 1438 res = tee_rpmb_write_blk(dev_id, blk_idx, data_tmp, blkcnt, 1439 fek, uuid); 1440 if (res != TEE_SUCCESS) 1441 goto func_exit; 1442 } 1443 1444 res = TEE_SUCCESS; 1445 1446 func_exit: 1447 free(data_tmp); 1448 return res; 1449 } 1450 1451 /* 1452 * Read the RPMB write counter. 1453 * 1454 * @dev_id Device ID of the eMMC device. 1455 * @counter Pointer to the counter. 1456 */ 1457 static TEE_Result tee_rpmb_get_write_counter(uint16_t dev_id, 1458 uint32_t *counter) 1459 { 1460 TEE_Result res = TEE_SUCCESS; 1461 1462 if (!counter) 1463 return TEE_ERROR_BAD_PARAMETERS; 1464 1465 if (!rpmb_ctx || !rpmb_ctx->wr_cnt_synced) { 1466 res = tee_rpmb_init(dev_id); 1467 if (res != TEE_SUCCESS) 1468 goto func_exit; 1469 } 1470 1471 *counter = rpmb_ctx->wr_cnt; 1472 1473 func_exit: 1474 return res; 1475 } 1476 1477 /* 1478 * Read the RPMB max block. 1479 * 1480 * @dev_id Device ID of the eMMC device. 1481 * @counter Pointer to receive the max block. 1482 */ 1483 static TEE_Result tee_rpmb_get_max_block(uint16_t dev_id, uint32_t *max_block) 1484 { 1485 TEE_Result res = TEE_SUCCESS; 1486 1487 if (!max_block) 1488 return TEE_ERROR_BAD_PARAMETERS; 1489 1490 if (!rpmb_ctx || !rpmb_ctx->dev_info_synced) { 1491 res = tee_rpmb_init(dev_id); 1492 if (res != TEE_SUCCESS) 1493 goto func_exit; 1494 } 1495 1496 *max_block = rpmb_ctx->max_blk_idx; 1497 1498 func_exit: 1499 return res; 1500 } 1501 1502 /* 1503 * End of lower interface to RPMB device 1504 */ 1505 1506 static TEE_Result get_fat_start_address(uint32_t *addr); 1507 1508 static void dump_fat(void) 1509 { 1510 TEE_Result res = TEE_ERROR_GENERIC; 1511 struct rpmb_fat_entry *fat_entries = NULL; 1512 uint32_t fat_address; 1513 size_t size; 1514 int i; 1515 bool last_entry_found = false; 1516 1517 res = get_fat_start_address(&fat_address); 1518 if (res != TEE_SUCCESS) 1519 goto out; 1520 1521 size = N_ENTRIES * sizeof(struct rpmb_fat_entry); 1522 fat_entries = malloc(size); 1523 if (!fat_entries) { 1524 res = TEE_ERROR_OUT_OF_MEMORY; 1525 goto out; 1526 } 1527 1528 while (!last_entry_found) { 1529 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address, 1530 (uint8_t *)fat_entries, size, NULL, NULL); 1531 if (res != TEE_SUCCESS) 1532 goto out; 1533 1534 for (i = 0; i < N_ENTRIES; i++) { 1535 1536 FMSG("flags 0x%x, size %d, address 0x%x, filename '%s'", 1537 fat_entries[i].flags, 1538 fat_entries[i].data_size, 1539 fat_entries[i].start_address, 1540 fat_entries[i].filename); 1541 1542 if ((fat_entries[i].flags & FILE_IS_LAST_ENTRY) != 0) { 1543 last_entry_found = true; 1544 break; 1545 } 1546 1547 /* Move to next fat_entry. */ 1548 fat_address += sizeof(struct rpmb_fat_entry); 1549 } 1550 } 1551 1552 out: 1553 free(fat_entries); 1554 } 1555 1556 #if (TRACE_LEVEL >= TRACE_DEBUG) 1557 static void dump_fh(struct rpmb_file_handle *fh) 1558 { 1559 DMSG("fh->filename=%s", fh->filename); 1560 DMSG("fh->rpmb_fat_address=%u", fh->rpmb_fat_address); 1561 DMSG("fh->fat_entry.start_address=%u", fh->fat_entry.start_address); 1562 DMSG("fh->fat_entry.data_size=%u", fh->fat_entry.data_size); 1563 } 1564 #else 1565 static void dump_fh(struct rpmb_file_handle *fh __unused) 1566 { 1567 } 1568 #endif 1569 1570 static struct rpmb_file_handle *alloc_file_handle(struct tee_pobj *po, 1571 bool temporary) 1572 { 1573 struct rpmb_file_handle *fh = NULL; 1574 1575 fh = calloc(1, sizeof(struct rpmb_file_handle)); 1576 if (!fh) 1577 return NULL; 1578 1579 if (po) 1580 tee_svc_storage_create_filename(fh->filename, 1581 sizeof(fh->filename), po, 1582 temporary); 1583 1584 return fh; 1585 } 1586 1587 /** 1588 * write_fat_entry: Store info in a fat_entry to RPMB. 1589 */ 1590 static TEE_Result write_fat_entry(struct rpmb_file_handle *fh, 1591 bool update_write_counter) 1592 { 1593 TEE_Result res = TEE_ERROR_GENERIC; 1594 1595 /* Protect partition data. */ 1596 if (fh->rpmb_fat_address < sizeof(struct rpmb_fs_partition)) { 1597 res = TEE_ERROR_ACCESS_CONFLICT; 1598 goto out; 1599 } 1600 1601 if (fh->rpmb_fat_address % sizeof(struct rpmb_fat_entry) != 0) { 1602 res = TEE_ERROR_BAD_PARAMETERS; 1603 goto out; 1604 } 1605 1606 if (update_write_counter) { 1607 res = tee_rpmb_get_write_counter(CFG_RPMB_FS_DEV_ID, 1608 &fh->fat_entry.write_counter); 1609 if (res != TEE_SUCCESS) 1610 goto out; 1611 } 1612 1613 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, fh->rpmb_fat_address, 1614 (uint8_t *)&fh->fat_entry, 1615 sizeof(struct rpmb_fat_entry), NULL, NULL); 1616 1617 dump_fat(); 1618 1619 out: 1620 return res; 1621 } 1622 1623 /** 1624 * rpmb_fs_setup: Setup rpmb fs. 1625 * Set initial partition and FS values and write to RPMB. 1626 * Store frequently used data in RAM. 1627 */ 1628 static TEE_Result rpmb_fs_setup(void) 1629 { 1630 TEE_Result res = TEE_ERROR_GENERIC; 1631 struct rpmb_fs_partition *partition_data = NULL; 1632 struct rpmb_file_handle *fh = NULL; 1633 uint32_t max_rpmb_block = 0; 1634 1635 if (fs_par) { 1636 res = TEE_SUCCESS; 1637 goto out; 1638 } 1639 1640 res = tee_rpmb_get_max_block(CFG_RPMB_FS_DEV_ID, &max_rpmb_block); 1641 if (res != TEE_SUCCESS) 1642 goto out; 1643 1644 partition_data = calloc(1, sizeof(struct rpmb_fs_partition)); 1645 if (!partition_data) { 1646 res = TEE_ERROR_OUT_OF_MEMORY; 1647 goto out; 1648 } 1649 1650 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS, 1651 (uint8_t *)partition_data, 1652 sizeof(struct rpmb_fs_partition), NULL, NULL); 1653 if (res != TEE_SUCCESS) 1654 goto out; 1655 1656 #ifndef CFG_RPMB_RESET_FAT 1657 if (partition_data->rpmb_fs_magic == RPMB_FS_MAGIC) { 1658 if (partition_data->fs_version == FS_VERSION) { 1659 res = TEE_SUCCESS; 1660 goto store_fs_par; 1661 } else { 1662 /* Wrong software is in use. */ 1663 res = TEE_ERROR_ACCESS_DENIED; 1664 goto out; 1665 } 1666 } 1667 #else 1668 EMSG("**** Clearing Storage ****"); 1669 #endif 1670 1671 /* Setup new partition data. */ 1672 partition_data->rpmb_fs_magic = RPMB_FS_MAGIC; 1673 partition_data->fs_version = FS_VERSION; 1674 partition_data->fat_start_address = RPMB_FS_FAT_START_ADDRESS; 1675 1676 /* Initial FAT entry with FILE_IS_LAST_ENTRY flag set. */ 1677 fh = alloc_file_handle(NULL, false); 1678 if (!fh) { 1679 res = TEE_ERROR_OUT_OF_MEMORY; 1680 goto out; 1681 } 1682 fh->fat_entry.flags = FILE_IS_LAST_ENTRY; 1683 fh->rpmb_fat_address = partition_data->fat_start_address; 1684 1685 /* Write init FAT entry and partition data to RPMB. */ 1686 res = write_fat_entry(fh, true); 1687 if (res != TEE_SUCCESS) 1688 goto out; 1689 1690 res = 1691 tee_rpmb_get_write_counter(CFG_RPMB_FS_DEV_ID, 1692 &partition_data->write_counter); 1693 if (res != TEE_SUCCESS) 1694 goto out; 1695 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS, 1696 (uint8_t *)partition_data, 1697 sizeof(struct rpmb_fs_partition), NULL, NULL); 1698 1699 #ifndef CFG_RPMB_RESET_FAT 1700 store_fs_par: 1701 #endif 1702 1703 /* Store FAT start address. */ 1704 fs_par = calloc(1, sizeof(struct rpmb_fs_parameters)); 1705 if (!fs_par) { 1706 res = TEE_ERROR_OUT_OF_MEMORY; 1707 goto out; 1708 } 1709 1710 fs_par->fat_start_address = partition_data->fat_start_address; 1711 fs_par->max_rpmb_address = max_rpmb_block << RPMB_BLOCK_SIZE_SHIFT; 1712 1713 dump_fat(); 1714 1715 out: 1716 free(fh); 1717 free(partition_data); 1718 return res; 1719 } 1720 1721 /** 1722 * get_fat_start_address: 1723 * FAT start_address from fs_par. 1724 */ 1725 static TEE_Result get_fat_start_address(uint32_t *addr) 1726 { 1727 if (!fs_par) 1728 return TEE_ERROR_NO_DATA; 1729 1730 *addr = fs_par->fat_start_address; 1731 1732 return TEE_SUCCESS; 1733 } 1734 1735 /** 1736 * read_fat: Read FAT entries 1737 * Return matching FAT entry for read, rm rename and stat. 1738 * Build up memory pool and return matching entry for write operation. 1739 * "Last FAT entry" can be returned during write. 1740 */ 1741 static TEE_Result read_fat(struct rpmb_file_handle *fh, tee_mm_pool_t *p) 1742 { 1743 TEE_Result res = TEE_ERROR_GENERIC; 1744 tee_mm_entry_t *mm = NULL; 1745 struct rpmb_fat_entry *fat_entries = NULL; 1746 uint32_t fat_address; 1747 size_t size; 1748 int i; 1749 bool entry_found = false; 1750 bool last_entry_found = false; 1751 bool expand_fat = false; 1752 struct rpmb_file_handle last_fh; 1753 1754 DMSG("fat_address %d", fh->rpmb_fat_address); 1755 1756 res = rpmb_fs_setup(); 1757 if (res != TEE_SUCCESS) 1758 goto out; 1759 1760 res = get_fat_start_address(&fat_address); 1761 if (res != TEE_SUCCESS) 1762 goto out; 1763 1764 size = N_ENTRIES * sizeof(struct rpmb_fat_entry); 1765 fat_entries = malloc(size); 1766 if (!fat_entries) { 1767 res = TEE_ERROR_OUT_OF_MEMORY; 1768 goto out; 1769 } 1770 1771 /* 1772 * The pool is used to represent the current RPMB layout. To find 1773 * a slot for the file tee_mm_alloc is called on the pool. Thus 1774 * if it is not NULL the entire FAT must be traversed to fill in 1775 * the pool. 1776 */ 1777 while (!last_entry_found && (!entry_found || p)) { 1778 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address, 1779 (uint8_t *)fat_entries, size, NULL, NULL); 1780 if (res != TEE_SUCCESS) 1781 goto out; 1782 1783 for (i = 0; i < N_ENTRIES; i++) { 1784 /* 1785 * Look for an entry, matching filenames. (read, rm, 1786 * rename and stat.). Only store first filename match. 1787 */ 1788 if (fh->filename && 1789 (strcmp(fh->filename, 1790 fat_entries[i].filename) == 0) && 1791 (fat_entries[i].flags & FILE_IS_ACTIVE) && 1792 (!entry_found)) { 1793 entry_found = true; 1794 fh->rpmb_fat_address = fat_address; 1795 memcpy(&fh->fat_entry, &fat_entries[i], 1796 sizeof(struct rpmb_fat_entry)); 1797 if (!p) 1798 break; 1799 } 1800 1801 /* Add existing files to memory pool. (write) */ 1802 if (p) { 1803 if ((fat_entries[i].flags & FILE_IS_ACTIVE) && 1804 (fat_entries[i].data_size > 0)) { 1805 1806 mm = tee_mm_alloc2 1807 (p, 1808 fat_entries[i].start_address, 1809 fat_entries[i].data_size); 1810 if (!mm) { 1811 res = TEE_ERROR_OUT_OF_MEMORY; 1812 goto out; 1813 } 1814 } 1815 1816 /* Unused FAT entries can be reused (write) */ 1817 if (((fat_entries[i].flags & FILE_IS_ACTIVE) == 1818 0) && (fh->rpmb_fat_address == 0)) { 1819 fh->rpmb_fat_address = fat_address; 1820 memcpy(&fh->fat_entry, &fat_entries[i], 1821 sizeof(struct rpmb_fat_entry)); 1822 } 1823 } 1824 1825 if ((fat_entries[i].flags & FILE_IS_LAST_ENTRY) != 0) { 1826 last_entry_found = true; 1827 1828 /* 1829 * If the last entry was reached and was chosen 1830 * by the previous check, then the FAT needs to 1831 * be expanded. 1832 * fh->rpmb_fat_address is the address chosen 1833 * to store the files FAT entry and fat_address 1834 * is the current FAT entry address being 1835 * compared. 1836 */ 1837 if (p && fh->rpmb_fat_address == fat_address) 1838 expand_fat = true; 1839 break; 1840 } 1841 1842 /* Move to next fat_entry. */ 1843 fat_address += sizeof(struct rpmb_fat_entry); 1844 } 1845 } 1846 1847 /* 1848 * Represent the FAT table in the pool. 1849 */ 1850 if (p) { 1851 /* 1852 * Since fat_address is the start of the last entry it needs to 1853 * be moved up by an entry. 1854 */ 1855 fat_address += sizeof(struct rpmb_fat_entry); 1856 1857 /* Make room for yet a FAT entry and add to memory pool. */ 1858 if (expand_fat) 1859 fat_address += sizeof(struct rpmb_fat_entry); 1860 1861 mm = tee_mm_alloc2(p, RPMB_STORAGE_START_ADDRESS, fat_address); 1862 if (!mm) { 1863 res = TEE_ERROR_OUT_OF_MEMORY; 1864 goto out; 1865 } 1866 1867 if (expand_fat) { 1868 /* 1869 * Point fat_address to the beginning of the new 1870 * entry. 1871 */ 1872 fat_address -= sizeof(struct rpmb_fat_entry); 1873 memset(&last_fh, 0, sizeof(last_fh)); 1874 last_fh.fat_entry.flags = FILE_IS_LAST_ENTRY; 1875 last_fh.rpmb_fat_address = fat_address; 1876 res = write_fat_entry(&last_fh, true); 1877 if (res != TEE_SUCCESS) 1878 goto out; 1879 } 1880 } 1881 1882 if (fh->filename && !fh->rpmb_fat_address) 1883 res = TEE_ERROR_ITEM_NOT_FOUND; 1884 1885 out: 1886 free(fat_entries); 1887 return res; 1888 } 1889 1890 static TEE_Result generate_fek(struct rpmb_fat_entry *fe, const TEE_UUID *uuid) 1891 { 1892 TEE_Result res; 1893 1894 again: 1895 res = tee_fs_generate_fek(uuid, fe->fek, sizeof(fe->fek)); 1896 if (res != TEE_SUCCESS) 1897 return res; 1898 1899 if (is_zero(fe->fek, sizeof(fe->fek))) 1900 goto again; 1901 1902 return res; 1903 } 1904 1905 static TEE_Result rpmb_fs_open_internal(struct rpmb_file_handle *fh, 1906 const TEE_UUID *uuid, bool create) 1907 { 1908 tee_mm_pool_t p; 1909 bool pool_result; 1910 TEE_Result res = TEE_ERROR_GENERIC; 1911 1912 /* We need to do setup in order to make sure fs_par is filled in */ 1913 res = rpmb_fs_setup(); 1914 if (res != TEE_SUCCESS) 1915 goto out; 1916 1917 fh->uuid = uuid; 1918 if (create) { 1919 /* Upper memory allocation must be used for RPMB_FS. */ 1920 pool_result = tee_mm_init(&p, 1921 RPMB_STORAGE_START_ADDRESS, 1922 fs_par->max_rpmb_address, 1923 RPMB_BLOCK_SIZE_SHIFT, 1924 TEE_MM_POOL_HI_ALLOC); 1925 1926 if (!pool_result) { 1927 res = TEE_ERROR_OUT_OF_MEMORY; 1928 goto out; 1929 } 1930 1931 res = read_fat(fh, &p); 1932 tee_mm_final(&p); 1933 if (res != TEE_SUCCESS) 1934 goto out; 1935 } else { 1936 res = read_fat(fh, NULL); 1937 if (res != TEE_SUCCESS) 1938 goto out; 1939 } 1940 1941 /* 1942 * If this is opened with create and the entry found was not active 1943 * then this is a new file and the FAT entry must be written 1944 */ 1945 if (create) { 1946 if ((fh->fat_entry.flags & FILE_IS_ACTIVE) == 0) { 1947 memset(&fh->fat_entry, 0, 1948 sizeof(struct rpmb_fat_entry)); 1949 memcpy(fh->fat_entry.filename, fh->filename, 1950 strlen(fh->filename)); 1951 /* Start address and size are 0 */ 1952 fh->fat_entry.flags = FILE_IS_ACTIVE; 1953 1954 res = generate_fek(&fh->fat_entry, uuid); 1955 if (res != TEE_SUCCESS) 1956 goto out; 1957 DMSG("GENERATE FEK key: %p", 1958 (void *)fh->fat_entry.fek); 1959 DHEXDUMP(fh->fat_entry.fek, sizeof(fh->fat_entry.fek)); 1960 1961 res = write_fat_entry(fh, true); 1962 if (res != TEE_SUCCESS) 1963 goto out; 1964 } 1965 } 1966 1967 res = TEE_SUCCESS; 1968 1969 out: 1970 return res; 1971 } 1972 1973 static void rpmb_fs_close(struct tee_file_handle **tfh) 1974 { 1975 struct rpmb_file_handle *fh = (struct rpmb_file_handle *)*tfh; 1976 1977 free(fh); 1978 *tfh = NULL; 1979 } 1980 1981 static TEE_Result rpmb_fs_read(struct tee_file_handle *tfh, size_t pos, 1982 void *buf, size_t *len) 1983 { 1984 TEE_Result res; 1985 struct rpmb_file_handle *fh = (struct rpmb_file_handle *)tfh; 1986 size_t size = *len; 1987 1988 if (!size) 1989 return TEE_SUCCESS; 1990 1991 mutex_lock(&rpmb_mutex); 1992 1993 dump_fh(fh); 1994 1995 res = read_fat(fh, NULL); 1996 if (res != TEE_SUCCESS) 1997 goto out; 1998 1999 if (pos >= fh->fat_entry.data_size) { 2000 *len = 0; 2001 goto out; 2002 } 2003 2004 size = MIN(size, fh->fat_entry.data_size - pos); 2005 if (size) { 2006 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, 2007 fh->fat_entry.start_address + pos, buf, 2008 size, fh->fat_entry.fek, fh->uuid); 2009 if (res != TEE_SUCCESS) 2010 goto out; 2011 } 2012 *len = size; 2013 2014 out: 2015 mutex_unlock(&rpmb_mutex); 2016 return res; 2017 } 2018 2019 static TEE_Result rpmb_fs_write_primitive(struct rpmb_file_handle *fh, 2020 size_t pos, const void *buf, 2021 size_t size) 2022 { 2023 TEE_Result res; 2024 tee_mm_pool_t p; 2025 bool pool_result = false; 2026 tee_mm_entry_t *mm; 2027 size_t end; 2028 size_t newsize; 2029 uint8_t *newbuf = NULL; 2030 uintptr_t newaddr; 2031 uint32_t start_addr; 2032 2033 if (!size) 2034 return TEE_SUCCESS; 2035 2036 if (!fs_par) { 2037 res = TEE_ERROR_GENERIC; 2038 goto out; 2039 } 2040 2041 dump_fh(fh); 2042 2043 /* Upper memory allocation must be used for RPMB_FS. */ 2044 pool_result = tee_mm_init(&p, 2045 RPMB_STORAGE_START_ADDRESS, 2046 fs_par->max_rpmb_address, 2047 RPMB_BLOCK_SIZE_SHIFT, 2048 TEE_MM_POOL_HI_ALLOC); 2049 if (!pool_result) { 2050 res = TEE_ERROR_OUT_OF_MEMORY; 2051 goto out; 2052 } 2053 2054 res = read_fat(fh, &p); 2055 if (res != TEE_SUCCESS) 2056 goto out; 2057 2058 if (fh->fat_entry.flags & FILE_IS_LAST_ENTRY) 2059 panic("invalid last entry flag"); 2060 2061 if (ADD_OVERFLOW(pos, size, &end)) { 2062 res = TEE_ERROR_BAD_PARAMETERS; 2063 goto out; 2064 } 2065 if (ADD_OVERFLOW(fh->fat_entry.start_address, pos, &start_addr)) { 2066 res = TEE_ERROR_BAD_PARAMETERS; 2067 goto out; 2068 } 2069 2070 if (end <= fh->fat_entry.data_size && 2071 tee_rpmb_write_is_atomic(CFG_RPMB_FS_DEV_ID, start_addr, size)) { 2072 2073 DMSG("Updating data in-place"); 2074 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, start_addr, buf, 2075 size, fh->fat_entry.fek, fh->uuid); 2076 if (res != TEE_SUCCESS) 2077 goto out; 2078 } else { 2079 /* 2080 * File must be extended, or update cannot be atomic: allocate, 2081 * read, update, write. 2082 */ 2083 2084 DMSG("Need to re-allocate"); 2085 newsize = MAX(end, fh->fat_entry.data_size); 2086 mm = tee_mm_alloc(&p, newsize); 2087 newbuf = calloc(1, newsize); 2088 if (!mm || !newbuf) { 2089 res = TEE_ERROR_OUT_OF_MEMORY; 2090 goto out; 2091 } 2092 2093 if (fh->fat_entry.data_size) { 2094 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, 2095 fh->fat_entry.start_address, 2096 newbuf, fh->fat_entry.data_size, 2097 fh->fat_entry.fek, fh->uuid); 2098 if (res != TEE_SUCCESS) 2099 goto out; 2100 } 2101 2102 memcpy(newbuf + pos, buf, size); 2103 2104 newaddr = tee_mm_get_smem(mm); 2105 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf, 2106 newsize, fh->fat_entry.fek, fh->uuid); 2107 if (res != TEE_SUCCESS) 2108 goto out; 2109 2110 fh->fat_entry.data_size = newsize; 2111 fh->fat_entry.start_address = newaddr; 2112 res = write_fat_entry(fh, true); 2113 if (res != TEE_SUCCESS) 2114 goto out; 2115 } 2116 2117 out: 2118 if (pool_result) 2119 tee_mm_final(&p); 2120 if (newbuf) 2121 free(newbuf); 2122 2123 return res; 2124 } 2125 2126 static TEE_Result rpmb_fs_write(struct tee_file_handle *tfh, size_t pos, 2127 const void *buf, size_t size) 2128 { 2129 TEE_Result res; 2130 2131 mutex_lock(&rpmb_mutex); 2132 res = rpmb_fs_write_primitive((struct rpmb_file_handle *)tfh, pos, 2133 buf, size); 2134 mutex_unlock(&rpmb_mutex); 2135 2136 return res; 2137 } 2138 2139 static TEE_Result rpmb_fs_remove_internal(struct rpmb_file_handle *fh) 2140 { 2141 TEE_Result res; 2142 2143 res = read_fat(fh, NULL); 2144 if (res) 2145 return res; 2146 2147 /* Clear this file entry. */ 2148 memset(&fh->fat_entry, 0, sizeof(struct rpmb_fat_entry)); 2149 return write_fat_entry(fh, false); 2150 } 2151 2152 static TEE_Result rpmb_fs_remove(struct tee_pobj *po) 2153 { 2154 TEE_Result res; 2155 struct rpmb_file_handle *fh = alloc_file_handle(po, po->temporary); 2156 2157 if (!fh) 2158 return TEE_ERROR_OUT_OF_MEMORY; 2159 2160 mutex_lock(&rpmb_mutex); 2161 2162 res = rpmb_fs_remove_internal(fh); 2163 2164 mutex_unlock(&rpmb_mutex); 2165 2166 free(fh); 2167 return res; 2168 } 2169 2170 static TEE_Result rpmb_fs_rename_internal(struct tee_pobj *old, 2171 struct tee_pobj *new, 2172 bool overwrite) 2173 { 2174 TEE_Result res = TEE_ERROR_GENERIC; 2175 struct rpmb_file_handle *fh_old = NULL; 2176 struct rpmb_file_handle *fh_new = NULL; 2177 2178 if (!old) { 2179 res = TEE_ERROR_BAD_PARAMETERS; 2180 goto out; 2181 } 2182 2183 if (new) 2184 fh_old = alloc_file_handle(old, old->temporary); 2185 else 2186 fh_old = alloc_file_handle(old, true); 2187 if (!fh_old) { 2188 res = TEE_ERROR_OUT_OF_MEMORY; 2189 goto out; 2190 } 2191 2192 if (new) 2193 fh_new = alloc_file_handle(new, new->temporary); 2194 else 2195 fh_new = alloc_file_handle(old, false); 2196 if (!fh_new) { 2197 res = TEE_ERROR_OUT_OF_MEMORY; 2198 goto out; 2199 } 2200 2201 res = read_fat(fh_old, NULL); 2202 if (res != TEE_SUCCESS) 2203 goto out; 2204 2205 res = read_fat(fh_new, NULL); 2206 if (res == TEE_SUCCESS) { 2207 if (!overwrite) { 2208 res = TEE_ERROR_ACCESS_CONFLICT; 2209 goto out; 2210 } 2211 2212 /* Clear this file entry. */ 2213 memset(&fh_new->fat_entry, 0, sizeof(struct rpmb_fat_entry)); 2214 res = write_fat_entry(fh_new, false); 2215 if (res != TEE_SUCCESS) 2216 goto out; 2217 } 2218 2219 memset(fh_old->fat_entry.filename, 0, TEE_RPMB_FS_FILENAME_LENGTH); 2220 memcpy(fh_old->fat_entry.filename, fh_new->filename, 2221 strlen(fh_new->filename)); 2222 2223 res = write_fat_entry(fh_old, false); 2224 2225 out: 2226 free(fh_old); 2227 free(fh_new); 2228 2229 return res; 2230 } 2231 2232 static TEE_Result rpmb_fs_rename(struct tee_pobj *old, struct tee_pobj *new, 2233 bool overwrite) 2234 { 2235 TEE_Result res; 2236 2237 mutex_lock(&rpmb_mutex); 2238 res = rpmb_fs_rename_internal(old, new, overwrite); 2239 mutex_unlock(&rpmb_mutex); 2240 2241 return res; 2242 } 2243 2244 static TEE_Result rpmb_fs_truncate(struct tee_file_handle *tfh, size_t length) 2245 { 2246 struct rpmb_file_handle *fh = (struct rpmb_file_handle *)tfh; 2247 tee_mm_pool_t p; 2248 bool pool_result = false; 2249 tee_mm_entry_t *mm; 2250 uint32_t newsize; 2251 uint8_t *newbuf = NULL; 2252 uintptr_t newaddr; 2253 TEE_Result res = TEE_ERROR_GENERIC; 2254 2255 mutex_lock(&rpmb_mutex); 2256 2257 if (length > INT32_MAX) { 2258 res = TEE_ERROR_BAD_PARAMETERS; 2259 goto out; 2260 } 2261 newsize = length; 2262 2263 res = read_fat(fh, NULL); 2264 if (res != TEE_SUCCESS) 2265 goto out; 2266 2267 if (newsize > fh->fat_entry.data_size) { 2268 /* Extend file */ 2269 2270 pool_result = tee_mm_init(&p, 2271 RPMB_STORAGE_START_ADDRESS, 2272 fs_par->max_rpmb_address, 2273 RPMB_BLOCK_SIZE_SHIFT, 2274 TEE_MM_POOL_HI_ALLOC); 2275 if (!pool_result) { 2276 res = TEE_ERROR_OUT_OF_MEMORY; 2277 goto out; 2278 } 2279 res = read_fat(fh, &p); 2280 if (res != TEE_SUCCESS) 2281 goto out; 2282 2283 mm = tee_mm_alloc(&p, newsize); 2284 newbuf = calloc(1, newsize); 2285 if (!mm || !newbuf) { 2286 res = TEE_ERROR_OUT_OF_MEMORY; 2287 goto out; 2288 } 2289 2290 if (fh->fat_entry.data_size) { 2291 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, 2292 fh->fat_entry.start_address, 2293 newbuf, fh->fat_entry.data_size, 2294 fh->fat_entry.fek, fh->uuid); 2295 if (res != TEE_SUCCESS) 2296 goto out; 2297 } 2298 2299 newaddr = tee_mm_get_smem(mm); 2300 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf, 2301 newsize, fh->fat_entry.fek, fh->uuid); 2302 if (res != TEE_SUCCESS) 2303 goto out; 2304 2305 } else { 2306 /* Don't change file location */ 2307 newaddr = fh->fat_entry.start_address; 2308 } 2309 2310 /* fh->pos is unchanged */ 2311 fh->fat_entry.data_size = newsize; 2312 fh->fat_entry.start_address = newaddr; 2313 res = write_fat_entry(fh, true); 2314 2315 out: 2316 mutex_unlock(&rpmb_mutex); 2317 if (pool_result) 2318 tee_mm_final(&p); 2319 if (newbuf) 2320 free(newbuf); 2321 2322 return res; 2323 } 2324 2325 static void rpmb_fs_dir_free(struct tee_fs_dir *dir) 2326 { 2327 struct tee_rpmb_fs_dirent *e; 2328 2329 if (!dir) 2330 return; 2331 2332 free(dir->current); 2333 2334 while ((e = SIMPLEQ_FIRST(&dir->next))) { 2335 SIMPLEQ_REMOVE_HEAD(&dir->next, link); 2336 free(e); 2337 } 2338 } 2339 2340 static TEE_Result rpmb_fs_dir_populate(const char *path, 2341 struct tee_fs_dir *dir) 2342 { 2343 struct tee_rpmb_fs_dirent *current = NULL; 2344 struct rpmb_fat_entry *fat_entries = NULL; 2345 uint32_t fat_address; 2346 uint32_t filelen; 2347 char *filename; 2348 int i; 2349 bool last_entry_found = false; 2350 bool matched; 2351 struct tee_rpmb_fs_dirent *next = NULL; 2352 uint32_t pathlen; 2353 TEE_Result res = TEE_ERROR_GENERIC; 2354 uint32_t size; 2355 char temp; 2356 2357 mutex_lock(&rpmb_mutex); 2358 2359 res = rpmb_fs_setup(); 2360 if (res != TEE_SUCCESS) 2361 goto out; 2362 2363 res = get_fat_start_address(&fat_address); 2364 if (res != TEE_SUCCESS) 2365 goto out; 2366 2367 size = N_ENTRIES * sizeof(struct rpmb_fat_entry); 2368 fat_entries = malloc(size); 2369 if (!fat_entries) { 2370 res = TEE_ERROR_OUT_OF_MEMORY; 2371 goto out; 2372 } 2373 2374 pathlen = strlen(path); 2375 while (!last_entry_found) { 2376 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address, 2377 (uint8_t *)fat_entries, size, NULL, NULL); 2378 if (res != TEE_SUCCESS) 2379 goto out; 2380 2381 for (i = 0; i < N_ENTRIES; i++) { 2382 filename = fat_entries[i].filename; 2383 if (fat_entries[i].flags & FILE_IS_ACTIVE) { 2384 matched = false; 2385 filelen = strlen(filename); 2386 if (filelen > pathlen) { 2387 temp = filename[pathlen]; 2388 filename[pathlen] = '\0'; 2389 if (strcmp(filename, path) == 0) 2390 matched = true; 2391 2392 filename[pathlen] = temp; 2393 } 2394 2395 if (matched) { 2396 next = malloc(sizeof(*next)); 2397 if (!next) { 2398 res = TEE_ERROR_OUT_OF_MEMORY; 2399 goto out; 2400 } 2401 2402 next->entry.oidlen = tee_hs2b( 2403 (uint8_t *)&filename[pathlen], 2404 next->entry.oid, 2405 filelen - pathlen, 2406 sizeof(next->entry.oid)); 2407 if (next->entry.oidlen) { 2408 SIMPLEQ_INSERT_TAIL(&dir->next, 2409 next, link); 2410 current = next; 2411 } else { 2412 free(next); 2413 next = NULL; 2414 } 2415 2416 } 2417 } 2418 2419 if (fat_entries[i].flags & FILE_IS_LAST_ENTRY) { 2420 last_entry_found = true; 2421 break; 2422 } 2423 2424 /* Move to next fat_entry. */ 2425 fat_address += sizeof(struct rpmb_fat_entry); 2426 } 2427 } 2428 2429 if (current) 2430 res = TEE_SUCCESS; 2431 else 2432 res = TEE_ERROR_ITEM_NOT_FOUND; /* No directories were found. */ 2433 2434 out: 2435 mutex_unlock(&rpmb_mutex); 2436 if (res != TEE_SUCCESS) 2437 rpmb_fs_dir_free(dir); 2438 if (fat_entries) 2439 free(fat_entries); 2440 2441 return res; 2442 } 2443 2444 static TEE_Result rpmb_fs_opendir(const TEE_UUID *uuid, struct tee_fs_dir **dir) 2445 { 2446 uint32_t len; 2447 char path_local[TEE_RPMB_FS_FILENAME_LENGTH]; 2448 TEE_Result res = TEE_ERROR_GENERIC; 2449 struct tee_fs_dir *rpmb_dir = NULL; 2450 2451 if (!uuid || !dir) { 2452 res = TEE_ERROR_BAD_PARAMETERS; 2453 goto out; 2454 } 2455 2456 memset(path_local, 0, sizeof(path_local)); 2457 if (tee_svc_storage_create_dirname(path_local, sizeof(path_local) - 1, 2458 uuid) != TEE_SUCCESS) { 2459 res = TEE_ERROR_BAD_PARAMETERS; 2460 goto out; 2461 } 2462 len = strlen(path_local); 2463 2464 /* Add a slash to correctly match the full directory name. */ 2465 if (path_local[len - 1] != '/') 2466 path_local[len] = '/'; 2467 2468 rpmb_dir = calloc(1, sizeof(*rpmb_dir)); 2469 if (!rpmb_dir) { 2470 res = TEE_ERROR_OUT_OF_MEMORY; 2471 goto out; 2472 } 2473 SIMPLEQ_INIT(&rpmb_dir->next); 2474 2475 res = rpmb_fs_dir_populate(path_local, rpmb_dir); 2476 if (res != TEE_SUCCESS) { 2477 free(rpmb_dir); 2478 rpmb_dir = NULL; 2479 goto out; 2480 } 2481 2482 *dir = rpmb_dir; 2483 2484 out: 2485 return res; 2486 } 2487 2488 static TEE_Result rpmb_fs_readdir(struct tee_fs_dir *dir, 2489 struct tee_fs_dirent **ent) 2490 { 2491 if (!dir) 2492 return TEE_ERROR_GENERIC; 2493 2494 free(dir->current); 2495 2496 dir->current = SIMPLEQ_FIRST(&dir->next); 2497 if (!dir->current) 2498 return TEE_ERROR_ITEM_NOT_FOUND; 2499 2500 SIMPLEQ_REMOVE_HEAD(&dir->next, link); 2501 2502 *ent = &dir->current->entry; 2503 return TEE_SUCCESS; 2504 } 2505 2506 static void rpmb_fs_closedir(struct tee_fs_dir *dir) 2507 { 2508 if (dir) { 2509 rpmb_fs_dir_free(dir); 2510 free(dir); 2511 } 2512 } 2513 2514 static TEE_Result rpmb_fs_open(struct tee_pobj *po, size_t *size, 2515 struct tee_file_handle **ret_fh) 2516 { 2517 TEE_Result res; 2518 struct rpmb_file_handle *fh = alloc_file_handle(po, po->temporary); 2519 2520 if (!fh) 2521 return TEE_ERROR_OUT_OF_MEMORY; 2522 2523 mutex_lock(&rpmb_mutex); 2524 2525 res = rpmb_fs_open_internal(fh, &po->uuid, false); 2526 if (!res && size) 2527 *size = fh->fat_entry.data_size; 2528 2529 mutex_unlock(&rpmb_mutex); 2530 2531 if (res) 2532 free(fh); 2533 else 2534 *ret_fh = (struct tee_file_handle *)fh; 2535 2536 return res; 2537 } 2538 2539 static TEE_Result rpmb_fs_create(struct tee_pobj *po, bool overwrite, 2540 const void *head, size_t head_size, 2541 const void *attr, size_t attr_size, 2542 const void *data, size_t data_size, 2543 struct tee_file_handle **ret_fh) 2544 { 2545 TEE_Result res; 2546 size_t pos = 0; 2547 struct rpmb_file_handle *fh = alloc_file_handle(po, po->temporary); 2548 2549 if (!fh) 2550 return TEE_ERROR_OUT_OF_MEMORY; 2551 2552 mutex_lock(&rpmb_mutex); 2553 res = rpmb_fs_open_internal(fh, &po->uuid, true); 2554 if (res) 2555 goto out; 2556 2557 if (head && head_size) { 2558 res = rpmb_fs_write_primitive(fh, pos, head, head_size); 2559 if (res) 2560 goto out; 2561 pos += head_size; 2562 } 2563 2564 if (attr && attr_size) { 2565 res = rpmb_fs_write_primitive(fh, pos, attr, attr_size); 2566 if (res) 2567 goto out; 2568 pos += attr_size; 2569 } 2570 2571 if (data && data_size) { 2572 res = rpmb_fs_write_primitive(fh, pos, data, data_size); 2573 if (res) 2574 goto out; 2575 } 2576 2577 if (po->temporary) { 2578 /* 2579 * If it's a temporary filename (which it normally is) 2580 * rename into the final filename now that the file is 2581 * fully initialized. 2582 */ 2583 po->temporary = false; 2584 res = rpmb_fs_rename_internal(po, NULL, overwrite); 2585 if (res) { 2586 po->temporary = true; 2587 goto out; 2588 } 2589 /* Update file handle after rename. */ 2590 tee_svc_storage_create_filename(fh->filename, 2591 sizeof(fh->filename), 2592 po, false); 2593 } 2594 2595 out: 2596 if (res) { 2597 rpmb_fs_remove_internal(fh); 2598 free(fh); 2599 } else { 2600 *ret_fh = (struct tee_file_handle *)fh; 2601 } 2602 mutex_unlock(&rpmb_mutex); 2603 2604 return res; 2605 } 2606 2607 const struct tee_file_operations rpmb_fs_ops = { 2608 .open = rpmb_fs_open, 2609 .create = rpmb_fs_create, 2610 .close = rpmb_fs_close, 2611 .read = rpmb_fs_read, 2612 .write = rpmb_fs_write, 2613 .truncate = rpmb_fs_truncate, 2614 .rename = rpmb_fs_rename, 2615 .remove = rpmb_fs_remove, 2616 .opendir = rpmb_fs_opendir, 2617 .closedir = rpmb_fs_closedir, 2618 .readdir = rpmb_fs_readdir, 2619 }; 2620 2621 TEE_Result tee_rpmb_fs_raw_open(const char *fname, bool create, 2622 struct tee_file_handle **ret_fh) 2623 { 2624 TEE_Result res; 2625 struct rpmb_file_handle *fh = calloc(1, sizeof(*fh)); 2626 static const TEE_UUID uuid = { 0 }; 2627 2628 if (!fh) 2629 return TEE_ERROR_OUT_OF_MEMORY; 2630 2631 snprintf(fh->filename, sizeof(fh->filename), "/%s", fname); 2632 2633 mutex_lock(&rpmb_mutex); 2634 2635 res = rpmb_fs_open_internal(fh, &uuid, create); 2636 2637 mutex_unlock(&rpmb_mutex); 2638 2639 if (res) { 2640 if (create) 2641 rpmb_fs_remove_internal(fh); 2642 free(fh); 2643 } else { 2644 *ret_fh = (struct tee_file_handle *)fh; 2645 } 2646 2647 return res; 2648 } 2649