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