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