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