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