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