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 /* 1204 * Read RPMB data in bytes. 1205 * 1206 * @dev_id Device ID of the eMMC device. 1207 * @addr Byte address of data. 1208 * @data Pointer to the data. 1209 * @len Size of data in bytes. 1210 * @fek Encrypted File Encryption Key or NULL. 1211 */ 1212 static TEE_Result tee_rpmb_read(uint16_t dev_id, uint32_t addr, uint8_t *data, 1213 uint32_t len, uint8_t *fek) 1214 { 1215 TEE_Result res = TEE_ERROR_GENERIC; 1216 struct tee_rpmb_mem mem = { 0 }; 1217 uint16_t msg_type; 1218 uint8_t nonce[RPMB_NONCE_SIZE]; 1219 uint8_t hmac[RPMB_KEY_MAC_SIZE]; 1220 struct rpmb_req *req = NULL; 1221 struct rpmb_data_frame *resp = NULL; 1222 struct rpmb_raw_data rawdata; 1223 uint32_t req_size; 1224 uint32_t resp_size; 1225 uint16_t blk_idx; 1226 uint16_t blkcnt; 1227 uint8_t byte_offset; 1228 1229 if (!data || !len) 1230 return TEE_ERROR_BAD_PARAMETERS; 1231 1232 blk_idx = addr / RPMB_DATA_SIZE; 1233 byte_offset = addr % RPMB_DATA_SIZE; 1234 1235 blkcnt = 1236 ROUNDUP(len + byte_offset, RPMB_DATA_SIZE) / RPMB_DATA_SIZE; 1237 res = tee_rpmb_init(dev_id); 1238 if (res != TEE_SUCCESS) 1239 goto func_exit; 1240 1241 req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE; 1242 resp_size = RPMB_DATA_FRAME_SIZE * blkcnt; 1243 res = tee_rpmb_alloc(req_size, resp_size, &mem, 1244 (void *)&req, (void *)&resp); 1245 if (res != TEE_SUCCESS) 1246 goto func_exit; 1247 1248 msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_READ; 1249 res = crypto_ops.prng.read(nonce, RPMB_NONCE_SIZE); 1250 if (res != TEE_SUCCESS) 1251 goto func_exit; 1252 1253 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data)); 1254 rawdata.msg_type = msg_type; 1255 rawdata.nonce = nonce; 1256 rawdata.blk_idx = &blk_idx; 1257 res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL); 1258 if (res != TEE_SUCCESS) 1259 goto func_exit; 1260 1261 req->block_count = blkcnt; 1262 1263 DMSG("Read %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""), 1264 blk_idx); 1265 1266 res = tee_rpmb_invoke(&mem); 1267 if (res != TEE_SUCCESS) 1268 goto func_exit; 1269 1270 msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_READ; 1271 1272 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data)); 1273 rawdata.msg_type = msg_type; 1274 rawdata.block_count = &blkcnt; 1275 rawdata.blk_idx = &blk_idx; 1276 rawdata.nonce = nonce; 1277 rawdata.key_mac = hmac; 1278 rawdata.data = data; 1279 1280 rawdata.len = len; 1281 rawdata.byte_offset = byte_offset; 1282 1283 res = tee_rpmb_resp_unpack_verify(resp, &rawdata, blkcnt, fek); 1284 if (res != TEE_SUCCESS) 1285 goto func_exit; 1286 1287 res = TEE_SUCCESS; 1288 1289 func_exit: 1290 tee_rpmb_free(&mem); 1291 return res; 1292 } 1293 1294 static TEE_Result tee_rpmb_write_blk(uint16_t dev_id, uint16_t blk_idx, 1295 const uint8_t *data_blks, uint16_t blkcnt, 1296 const uint8_t *fek) 1297 { 1298 TEE_Result res; 1299 struct tee_rpmb_mem mem; 1300 uint16_t msg_type; 1301 uint32_t wr_cnt; 1302 uint8_t hmac[RPMB_KEY_MAC_SIZE]; 1303 struct rpmb_req *req = NULL; 1304 struct rpmb_data_frame *resp = NULL; 1305 struct rpmb_raw_data rawdata; 1306 uint32_t req_size; 1307 uint32_t resp_size; 1308 uint32_t nbr_writes; 1309 uint16_t tmp_blkcnt; 1310 uint16_t tmp_blk_idx; 1311 uint16_t i; 1312 1313 DMSG("Write %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""), 1314 blk_idx); 1315 1316 if (!data_blks || !blkcnt) 1317 return TEE_ERROR_BAD_PARAMETERS; 1318 1319 res = tee_rpmb_init(dev_id); 1320 if (res != TEE_SUCCESS) 1321 return res; 1322 1323 /* 1324 * We need to split data when block count 1325 * is bigger than reliable block write count. 1326 */ 1327 if (blkcnt < rpmb_ctx->rel_wr_blkcnt) 1328 req_size = sizeof(struct rpmb_req) + 1329 RPMB_DATA_FRAME_SIZE * blkcnt; 1330 else 1331 req_size = sizeof(struct rpmb_req) + 1332 RPMB_DATA_FRAME_SIZE * rpmb_ctx->rel_wr_blkcnt; 1333 1334 resp_size = RPMB_DATA_FRAME_SIZE; 1335 res = tee_rpmb_alloc(req_size, resp_size, &mem, 1336 (void *)&req, (void *)&resp); 1337 if (res != TEE_SUCCESS) 1338 return res; 1339 1340 nbr_writes = blkcnt / rpmb_ctx->rel_wr_blkcnt; 1341 if (blkcnt % rpmb_ctx->rel_wr_blkcnt > 0) 1342 nbr_writes += 1; 1343 1344 tmp_blkcnt = rpmb_ctx->rel_wr_blkcnt; 1345 tmp_blk_idx = blk_idx; 1346 for (i = 0; i < nbr_writes; i++) { 1347 /* 1348 * To handle the last write of block count which is 1349 * equal or smaller than reliable write block count. 1350 */ 1351 if (i == nbr_writes - 1) 1352 tmp_blkcnt = blkcnt - rpmb_ctx->rel_wr_blkcnt * 1353 (nbr_writes - 1); 1354 1355 msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE; 1356 wr_cnt = rpmb_ctx->wr_cnt; 1357 1358 memset(req, 0x00, req_size); 1359 memset(resp, 0x00, resp_size); 1360 1361 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data)); 1362 rawdata.msg_type = msg_type; 1363 rawdata.block_count = &tmp_blkcnt; 1364 rawdata.blk_idx = &tmp_blk_idx; 1365 rawdata.write_counter = &wr_cnt; 1366 rawdata.key_mac = hmac; 1367 rawdata.data = (uint8_t *)data_blks + 1368 i * rpmb_ctx->rel_wr_blkcnt * RPMB_DATA_SIZE; 1369 1370 res = tee_rpmb_req_pack(req, &rawdata, tmp_blkcnt, dev_id, 1371 fek); 1372 if (res != TEE_SUCCESS) 1373 goto out; 1374 1375 res = tee_rpmb_invoke(&mem); 1376 if (res != TEE_SUCCESS) { 1377 /* 1378 * To force wr_cnt sync next time, as it might get 1379 * out of sync due to inconsistent operation result! 1380 */ 1381 rpmb_ctx->wr_cnt_synced = false; 1382 goto out; 1383 } 1384 1385 msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE; 1386 1387 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data)); 1388 rawdata.msg_type = msg_type; 1389 rawdata.block_count = &tmp_blkcnt; 1390 rawdata.blk_idx = &tmp_blk_idx; 1391 rawdata.write_counter = &wr_cnt; 1392 rawdata.key_mac = hmac; 1393 1394 res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL); 1395 if (res != TEE_SUCCESS) { 1396 /* 1397 * To force wr_cnt sync next time, as it might get 1398 * out of sync due to inconsistent operation result! 1399 */ 1400 rpmb_ctx->wr_cnt_synced = false; 1401 goto out; 1402 } 1403 1404 tmp_blk_idx += tmp_blkcnt; 1405 } 1406 1407 out: 1408 tee_rpmb_free(&mem); 1409 return res; 1410 } 1411 1412 static bool tee_rpmb_write_is_atomic(uint16_t dev_id __unused, uint32_t addr, 1413 uint32_t len) 1414 { 1415 uint8_t byte_offset = addr % RPMB_DATA_SIZE; 1416 uint16_t blkcnt = ROUNDUP(len + byte_offset, 1417 RPMB_DATA_SIZE) / RPMB_DATA_SIZE; 1418 1419 return (blkcnt <= rpmb_ctx->rel_wr_blkcnt); 1420 } 1421 1422 /* 1423 * Write RPMB data in bytes. 1424 * 1425 * @dev_id Device ID of the eMMC device. 1426 * @addr Byte address of data. 1427 * @data Pointer to the data. 1428 * @len Size of data in bytes. 1429 * @fek Encrypted File Encryption Key or NULL. 1430 */ 1431 static TEE_Result tee_rpmb_write(uint16_t dev_id, uint32_t addr, 1432 const uint8_t *data, uint32_t len, 1433 uint8_t *fek) 1434 { 1435 TEE_Result res = TEE_ERROR_GENERIC; 1436 uint8_t *data_tmp = NULL; 1437 uint16_t blk_idx; 1438 uint16_t blkcnt; 1439 uint8_t byte_offset; 1440 1441 blk_idx = addr / RPMB_DATA_SIZE; 1442 byte_offset = addr % RPMB_DATA_SIZE; 1443 1444 blkcnt = 1445 ROUNDUP(len + byte_offset, RPMB_DATA_SIZE) / RPMB_DATA_SIZE; 1446 1447 if (byte_offset == 0 && (len % RPMB_DATA_SIZE) == 0) { 1448 res = tee_rpmb_write_blk(dev_id, blk_idx, data, blkcnt, fek); 1449 if (res != TEE_SUCCESS) 1450 goto func_exit; 1451 } else { 1452 data_tmp = calloc(blkcnt, RPMB_DATA_SIZE); 1453 if (!data_tmp) { 1454 res = TEE_ERROR_OUT_OF_MEMORY; 1455 goto func_exit; 1456 } 1457 1458 /* Read the complete blocks */ 1459 res = tee_rpmb_read(dev_id, blk_idx * RPMB_DATA_SIZE, data_tmp, 1460 blkcnt * RPMB_DATA_SIZE, fek); 1461 if (res != TEE_SUCCESS) 1462 goto func_exit; 1463 1464 /* Partial update of the data blocks */ 1465 memcpy(data_tmp + byte_offset, data, len); 1466 1467 res = tee_rpmb_write_blk(dev_id, blk_idx, data_tmp, blkcnt, 1468 fek); 1469 if (res != TEE_SUCCESS) 1470 goto func_exit; 1471 } 1472 1473 res = TEE_SUCCESS; 1474 1475 func_exit: 1476 free(data_tmp); 1477 return res; 1478 } 1479 1480 /* 1481 * Read the RPMB write counter. 1482 * 1483 * @dev_id Device ID of the eMMC device. 1484 * @counter Pointer to the counter. 1485 */ 1486 static TEE_Result tee_rpmb_get_write_counter(uint16_t dev_id, 1487 uint32_t *counter) 1488 { 1489 TEE_Result res = TEE_SUCCESS; 1490 1491 if (!counter) 1492 return TEE_ERROR_BAD_PARAMETERS; 1493 1494 if (!rpmb_ctx || !rpmb_ctx->wr_cnt_synced) { 1495 res = tee_rpmb_init(dev_id); 1496 if (res != TEE_SUCCESS) 1497 goto func_exit; 1498 } 1499 1500 *counter = rpmb_ctx->wr_cnt; 1501 1502 func_exit: 1503 return res; 1504 } 1505 1506 /* 1507 * Read the RPMB max block. 1508 * 1509 * @dev_id Device ID of the eMMC device. 1510 * @counter Pointer to receive the max block. 1511 */ 1512 static TEE_Result tee_rpmb_get_max_block(uint16_t dev_id, uint32_t *max_block) 1513 { 1514 TEE_Result res = TEE_SUCCESS; 1515 1516 if (!max_block) 1517 return TEE_ERROR_BAD_PARAMETERS; 1518 1519 if (!rpmb_ctx || !rpmb_ctx->dev_info_synced) { 1520 res = tee_rpmb_init(dev_id); 1521 if (res != TEE_SUCCESS) 1522 goto func_exit; 1523 } 1524 1525 *max_block = rpmb_ctx->max_blk_idx; 1526 1527 func_exit: 1528 return res; 1529 } 1530 1531 /* 1532 * End of lower interface to RPMB device 1533 */ 1534 1535 static TEE_Result get_fat_start_address(uint32_t *addr); 1536 1537 static void dump_fat(void) 1538 { 1539 TEE_Result res = TEE_ERROR_GENERIC; 1540 struct rpmb_fat_entry *fat_entries = NULL; 1541 uint32_t fat_address; 1542 size_t size; 1543 int i; 1544 bool last_entry_found = false; 1545 1546 res = get_fat_start_address(&fat_address); 1547 if (res != TEE_SUCCESS) 1548 goto out; 1549 1550 size = N_ENTRIES * sizeof(struct rpmb_fat_entry); 1551 fat_entries = malloc(size); 1552 if (!fat_entries) { 1553 res = TEE_ERROR_OUT_OF_MEMORY; 1554 goto out; 1555 } 1556 1557 while (!last_entry_found) { 1558 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address, 1559 (uint8_t *)fat_entries, size, NULL); 1560 if (res != TEE_SUCCESS) 1561 goto out; 1562 1563 for (i = 0; i < N_ENTRIES; i++) { 1564 1565 FMSG("flags 0x%x, size %d, address 0x%x, filename '%s'", 1566 fat_entries[i].flags, 1567 fat_entries[i].data_size, 1568 fat_entries[i].start_address, 1569 fat_entries[i].filename); 1570 1571 if ((fat_entries[i].flags & FILE_IS_LAST_ENTRY) != 0) { 1572 last_entry_found = true; 1573 break; 1574 } 1575 1576 /* Move to next fat_entry. */ 1577 fat_address += sizeof(struct rpmb_fat_entry); 1578 } 1579 } 1580 1581 out: 1582 free(fat_entries); 1583 } 1584 1585 #if (TRACE_LEVEL >= TRACE_DEBUG) 1586 static void dump_fh(struct rpmb_file_handle *fh) 1587 { 1588 DMSG("fh->filename=%s", fh->filename); 1589 DMSG("fh->pos=%u", fh->pos); 1590 DMSG("fh->rpmb_fat_address=%u", fh->rpmb_fat_address); 1591 DMSG("fh->fat_entry.start_address=%u", fh->fat_entry.start_address); 1592 DMSG("fh->fat_entry.data_size=%u", fh->fat_entry.data_size); 1593 } 1594 #else 1595 static void dump_fh(struct rpmb_file_handle *fh __unused) 1596 { 1597 } 1598 #endif 1599 1600 static struct rpmb_file_handle *alloc_file_handle(const char *filename) 1601 { 1602 struct rpmb_file_handle *fh = NULL; 1603 1604 fh = calloc(1, sizeof(struct rpmb_file_handle)); 1605 if (!fh) 1606 return NULL; 1607 1608 if (filename) 1609 strlcpy(fh->filename, filename, sizeof(fh->filename)); 1610 1611 return fh; 1612 } 1613 1614 /** 1615 * write_fat_entry: Store info in a fat_entry to RPMB. 1616 */ 1617 static TEE_Result write_fat_entry(struct rpmb_file_handle *fh, 1618 bool update_write_counter) 1619 { 1620 TEE_Result res = TEE_ERROR_GENERIC; 1621 1622 /* Protect partition data. */ 1623 if (fh->rpmb_fat_address < sizeof(struct rpmb_fs_partition)) { 1624 res = TEE_ERROR_ACCESS_CONFLICT; 1625 goto out; 1626 } 1627 1628 if (fh->rpmb_fat_address % sizeof(struct rpmb_fat_entry) != 0) { 1629 res = TEE_ERROR_BAD_PARAMETERS; 1630 goto out; 1631 } 1632 1633 if (update_write_counter) { 1634 res = tee_rpmb_get_write_counter(CFG_RPMB_FS_DEV_ID, 1635 &fh->fat_entry.write_counter); 1636 if (res != TEE_SUCCESS) 1637 goto out; 1638 } 1639 1640 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, fh->rpmb_fat_address, 1641 (uint8_t *)&fh->fat_entry, 1642 sizeof(struct rpmb_fat_entry), NULL); 1643 1644 dump_fat(); 1645 1646 out: 1647 return res; 1648 } 1649 1650 /** 1651 * rpmb_fs_setup: Setup rpmb fs. 1652 * Set initial partition and FS values and write to RPMB. 1653 * Store frequently used data in RAM. 1654 */ 1655 static TEE_Result rpmb_fs_setup(void) 1656 { 1657 TEE_Result res = TEE_ERROR_GENERIC; 1658 struct rpmb_fs_partition *partition_data = NULL; 1659 struct rpmb_file_handle *fh = NULL; 1660 uint32_t max_rpmb_block = 0; 1661 1662 if (fs_par) { 1663 res = TEE_SUCCESS; 1664 goto out; 1665 } 1666 1667 res = tee_rpmb_get_max_block(CFG_RPMB_FS_DEV_ID, &max_rpmb_block); 1668 if (res != TEE_SUCCESS) 1669 goto out; 1670 1671 partition_data = calloc(1, sizeof(struct rpmb_fs_partition)); 1672 if (!partition_data) { 1673 res = TEE_ERROR_OUT_OF_MEMORY; 1674 goto out; 1675 } 1676 1677 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS, 1678 (uint8_t *)partition_data, 1679 sizeof(struct rpmb_fs_partition), NULL); 1680 if (res != TEE_SUCCESS) 1681 goto out; 1682 1683 #ifndef CFG_RPMB_RESET_FAT 1684 if (partition_data->rpmb_fs_magic == RPMB_FS_MAGIC) { 1685 if (partition_data->fs_version == FS_VERSION) { 1686 res = TEE_SUCCESS; 1687 goto store_fs_par; 1688 } else { 1689 /* Wrong software is in use. */ 1690 res = TEE_ERROR_ACCESS_DENIED; 1691 goto out; 1692 } 1693 } 1694 #else 1695 EMSG("**** Clearing Storage ****"); 1696 #endif 1697 1698 /* Setup new partition data. */ 1699 partition_data->rpmb_fs_magic = RPMB_FS_MAGIC; 1700 partition_data->fs_version = FS_VERSION; 1701 partition_data->fat_start_address = RPMB_FS_FAT_START_ADDRESS; 1702 1703 /* Initial FAT entry with FILE_IS_LAST_ENTRY flag set. */ 1704 fh = alloc_file_handle(NULL); 1705 if (!fh) { 1706 res = TEE_ERROR_OUT_OF_MEMORY; 1707 goto out; 1708 } 1709 fh->fat_entry.flags = FILE_IS_LAST_ENTRY; 1710 fh->rpmb_fat_address = partition_data->fat_start_address; 1711 1712 /* Write init FAT entry and partition data to RPMB. */ 1713 res = write_fat_entry(fh, true); 1714 if (res != TEE_SUCCESS) 1715 goto out; 1716 1717 res = 1718 tee_rpmb_get_write_counter(CFG_RPMB_FS_DEV_ID, 1719 &partition_data->write_counter); 1720 if (res != TEE_SUCCESS) 1721 goto out; 1722 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS, 1723 (uint8_t *)partition_data, 1724 sizeof(struct rpmb_fs_partition), NULL); 1725 1726 #ifndef CFG_RPMB_RESET_FAT 1727 store_fs_par: 1728 #endif 1729 1730 /* Store FAT start address. */ 1731 fs_par = calloc(1, sizeof(struct rpmb_fs_parameters)); 1732 if (!fs_par) { 1733 res = TEE_ERROR_OUT_OF_MEMORY; 1734 goto out; 1735 } 1736 1737 fs_par->fat_start_address = partition_data->fat_start_address; 1738 fs_par->max_rpmb_address = max_rpmb_block << RPMB_BLOCK_SIZE_SHIFT; 1739 1740 dump_fat(); 1741 1742 out: 1743 free(fh); 1744 free(partition_data); 1745 return res; 1746 } 1747 1748 /** 1749 * get_fat_start_address: 1750 * FAT start_address from fs_par. 1751 */ 1752 static TEE_Result get_fat_start_address(uint32_t *addr) 1753 { 1754 if (!fs_par) 1755 return TEE_ERROR_NO_DATA; 1756 1757 *addr = fs_par->fat_start_address; 1758 1759 return TEE_SUCCESS; 1760 } 1761 1762 /** 1763 * read_fat: Read FAT entries 1764 * Return matching FAT entry for read, rm rename and stat. 1765 * Build up memory pool and return matching entry for write operation. 1766 * "Last FAT entry" can be returned during write. 1767 */ 1768 static TEE_Result read_fat(struct rpmb_file_handle *fh, tee_mm_pool_t *p) 1769 { 1770 TEE_Result res = TEE_ERROR_GENERIC; 1771 tee_mm_entry_t *mm = NULL; 1772 struct rpmb_fat_entry *fat_entries = NULL; 1773 uint32_t fat_address; 1774 size_t size; 1775 int i; 1776 bool entry_found = false; 1777 bool last_entry_found = false; 1778 bool expand_fat = false; 1779 struct rpmb_file_handle last_fh; 1780 1781 DMSG("fat_address %d", fh->rpmb_fat_address); 1782 1783 res = rpmb_fs_setup(); 1784 if (res != TEE_SUCCESS) 1785 goto out; 1786 1787 res = get_fat_start_address(&fat_address); 1788 if (res != TEE_SUCCESS) 1789 goto out; 1790 1791 size = N_ENTRIES * sizeof(struct rpmb_fat_entry); 1792 fat_entries = malloc(size); 1793 if (!fat_entries) { 1794 res = TEE_ERROR_OUT_OF_MEMORY; 1795 goto out; 1796 } 1797 1798 /* 1799 * The pool is used to represent the current RPMB layout. To find 1800 * a slot for the file tee_mm_alloc is called on the pool. Thus 1801 * if it is not NULL the entire FAT must be traversed to fill in 1802 * the pool. 1803 */ 1804 while (!last_entry_found && (!entry_found || p)) { 1805 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address, 1806 (uint8_t *)fat_entries, size, NULL); 1807 if (res != TEE_SUCCESS) 1808 goto out; 1809 1810 for (i = 0; i < N_ENTRIES; i++) { 1811 /* 1812 * Look for an entry, matching filenames. (read, rm, 1813 * rename and stat.). Only store first filename match. 1814 */ 1815 if (fh->filename && 1816 (strcmp(fh->filename, 1817 fat_entries[i].filename) == 0) && 1818 (fat_entries[i].flags & FILE_IS_ACTIVE) && 1819 (!entry_found)) { 1820 entry_found = true; 1821 fh->rpmb_fat_address = fat_address; 1822 memcpy(&fh->fat_entry, &fat_entries[i], 1823 sizeof(struct rpmb_fat_entry)); 1824 if (!p) 1825 break; 1826 } 1827 1828 /* Add existing files to memory pool. (write) */ 1829 if (p) { 1830 if ((fat_entries[i].flags & FILE_IS_ACTIVE) && 1831 (fat_entries[i].data_size > 0)) { 1832 1833 mm = tee_mm_alloc2 1834 (p, 1835 fat_entries[i].start_address, 1836 fat_entries[i].data_size); 1837 if (!mm) { 1838 res = TEE_ERROR_OUT_OF_MEMORY; 1839 goto out; 1840 } 1841 } 1842 1843 /* Unused FAT entries can be reused (write) */ 1844 if (((fat_entries[i].flags & FILE_IS_ACTIVE) == 1845 0) && (fh->rpmb_fat_address == 0)) { 1846 fh->rpmb_fat_address = fat_address; 1847 memcpy(&fh->fat_entry, &fat_entries[i], 1848 sizeof(struct rpmb_fat_entry)); 1849 } 1850 } 1851 1852 if ((fat_entries[i].flags & FILE_IS_LAST_ENTRY) != 0) { 1853 last_entry_found = true; 1854 1855 /* 1856 * If the last entry was reached and was chosen 1857 * by the previous check, then the FAT needs to 1858 * be expanded. 1859 * fh->rpmb_fat_address is the address chosen 1860 * to store the files FAT entry and fat_address 1861 * is the current FAT entry address being 1862 * compared. 1863 */ 1864 if (p && fh->rpmb_fat_address == fat_address) 1865 expand_fat = true; 1866 break; 1867 } 1868 1869 /* Move to next fat_entry. */ 1870 fat_address += sizeof(struct rpmb_fat_entry); 1871 } 1872 } 1873 1874 /* 1875 * Represent the FAT table in the pool. 1876 */ 1877 if (p) { 1878 /* 1879 * Since fat_address is the start of the last entry it needs to 1880 * be moved up by an entry. 1881 */ 1882 fat_address += sizeof(struct rpmb_fat_entry); 1883 1884 /* Make room for yet a FAT entry and add to memory pool. */ 1885 if (expand_fat) 1886 fat_address += sizeof(struct rpmb_fat_entry); 1887 1888 mm = tee_mm_alloc2(p, RPMB_STORAGE_START_ADDRESS, fat_address); 1889 if (!mm) { 1890 res = TEE_ERROR_OUT_OF_MEMORY; 1891 goto out; 1892 } 1893 1894 if (expand_fat) { 1895 /* 1896 * Point fat_address to the beginning of the new 1897 * entry. 1898 */ 1899 fat_address -= sizeof(struct rpmb_fat_entry); 1900 memset(&last_fh, 0, sizeof(last_fh)); 1901 last_fh.fat_entry.flags = FILE_IS_LAST_ENTRY; 1902 last_fh.rpmb_fat_address = fat_address; 1903 res = write_fat_entry(&last_fh, true); 1904 if (res != TEE_SUCCESS) 1905 goto out; 1906 } 1907 } 1908 1909 if (fh->filename && !fh->rpmb_fat_address) 1910 res = TEE_ERROR_FILE_NOT_FOUND; 1911 1912 out: 1913 free(fat_entries); 1914 return res; 1915 } 1916 1917 #ifdef CFG_ENC_FS 1918 static TEE_Result generate_fek(struct rpmb_fat_entry *fe) 1919 { 1920 TEE_Result res; 1921 1922 again: 1923 res = tee_fs_generate_fek(fe->fek, sizeof(fe->fek)); 1924 if (res != TEE_SUCCESS) 1925 return res; 1926 1927 if (is_zero(fe->fek, sizeof(fe->fek))) 1928 goto again; 1929 1930 return res; 1931 } 1932 #else 1933 static TEE_Result generate_fek(struct rpmb_fat_entry *fe) 1934 { 1935 memset(fe->fek, 0, sizeof(fe->fek)); 1936 return TEE_SUCCESS; 1937 } 1938 #endif 1939 1940 static int rpmb_fs_open_internal(const char *file, int flags, ...) 1941 { 1942 int fd = -1; 1943 struct rpmb_file_handle *fh = NULL; 1944 size_t filelen; 1945 tee_mm_pool_t p; 1946 bool pool_result; 1947 TEE_Result res = TEE_ERROR_GENERIC; 1948 1949 mutex_lock(&rpmb_mutex); 1950 1951 if (!file) { 1952 res = TEE_ERROR_BAD_PARAMETERS; 1953 goto out; 1954 } 1955 1956 filelen = strlen(file); 1957 if (filelen >= TEE_RPMB_FS_FILENAME_LENGTH - 1 || filelen == 0) { 1958 res = TEE_ERROR_BAD_PARAMETERS; 1959 goto out; 1960 } 1961 1962 if (file[filelen - 1] == '/') { 1963 res = TEE_ERROR_BAD_PARAMETERS; 1964 goto out; 1965 } 1966 1967 fh = alloc_file_handle(file); 1968 if (!fh) { 1969 res = TEE_ERROR_OUT_OF_MEMORY; 1970 goto out; 1971 } 1972 1973 /* We need to do setup in order to make sure fs_par is filled in */ 1974 res = rpmb_fs_setup(); 1975 if (res != TEE_SUCCESS) 1976 goto out; 1977 1978 if (flags & TEE_FS_O_CREATE) { 1979 /* Upper memory allocation must be used for RPMB_FS. */ 1980 pool_result = tee_mm_init(&p, 1981 RPMB_STORAGE_START_ADDRESS, 1982 fs_par->max_rpmb_address, 1983 RPMB_BLOCK_SIZE_SHIFT, 1984 TEE_MM_POOL_HI_ALLOC); 1985 1986 if (!pool_result) { 1987 res = TEE_ERROR_OUT_OF_MEMORY; 1988 goto out; 1989 } 1990 1991 res = read_fat(fh, &p); 1992 tee_mm_final(&p); 1993 if (res != TEE_SUCCESS) 1994 goto out; 1995 } else { 1996 res = read_fat(fh, NULL); 1997 if (res != TEE_SUCCESS) 1998 goto out; 1999 } 2000 2001 /* Add the handle to the db */ 2002 fd = handle_get(&fs_handle_db, fh); 2003 if (fd == -1) { 2004 res = TEE_ERROR_OUT_OF_MEMORY; 2005 goto out; 2006 } 2007 2008 /* 2009 * If this is opened with create and the entry found was not active 2010 * then this is a new file and the FAT entry must be written 2011 */ 2012 if (flags & TEE_FS_O_CREATE) { 2013 if ((fh->fat_entry.flags & FILE_IS_ACTIVE) == 0) { 2014 memset(&fh->fat_entry, 0, 2015 sizeof(struct rpmb_fat_entry)); 2016 memcpy(fh->fat_entry.filename, file, strlen(file)); 2017 /* Start address and size are 0 */ 2018 fh->fat_entry.flags = FILE_IS_ACTIVE; 2019 2020 res = generate_fek(&fh->fat_entry); 2021 if (res != TEE_SUCCESS) { 2022 handle_put(&fs_handle_db, fd); 2023 fd = -1; 2024 goto out; 2025 } 2026 DMSG("GENERATE FEK key: %p", 2027 (void *)fh->fat_entry.fek); 2028 DHEXDUMP(fh->fat_entry.fek, sizeof(fh->fat_entry.fek)); 2029 2030 res = write_fat_entry(fh, true); 2031 if (res != TEE_SUCCESS) { 2032 handle_put(&fs_handle_db, fd); 2033 fd = -1; 2034 goto out; 2035 } 2036 } 2037 } 2038 2039 res = TEE_SUCCESS; 2040 fh->flags = flags; 2041 2042 out: 2043 if (res != TEE_SUCCESS) { 2044 if (fh) 2045 free(fh); 2046 2047 fd = -1; 2048 } 2049 2050 mutex_unlock(&rpmb_mutex); 2051 return fd; 2052 } 2053 2054 static int rpmb_fs_close(int fd) 2055 { 2056 struct rpmb_file_handle *fh; 2057 2058 mutex_lock(&rpmb_mutex); 2059 fh = handle_put(&fs_handle_db, fd); 2060 mutex_unlock(&rpmb_mutex); 2061 2062 if (fh) { 2063 free(fh); 2064 return 0; 2065 } 2066 2067 return -1; 2068 } 2069 2070 static int rpmb_fs_read(TEE_Result *errno, int fd, void *buf, size_t size) 2071 { 2072 TEE_Result res; 2073 struct rpmb_file_handle *fh; 2074 int read_size = -1; 2075 2076 if (!size) 2077 return 0; 2078 2079 mutex_lock(&rpmb_mutex); 2080 2081 if (!buf) { 2082 *errno = TEE_ERROR_BAD_PARAMETERS; 2083 goto out; 2084 } 2085 2086 fh = handle_lookup(&fs_handle_db, fd); 2087 if (!fh) { 2088 *errno = TEE_ERROR_BAD_PARAMETERS; 2089 goto out; 2090 } 2091 dump_fh(fh); 2092 2093 res = read_fat(fh, NULL); 2094 if (res != TEE_SUCCESS) { 2095 *errno = res; 2096 goto out; 2097 } 2098 2099 if (fh->pos >= fh->fat_entry.data_size) { 2100 read_size = 0; 2101 goto out; 2102 } 2103 2104 size = MIN(size, fh->fat_entry.data_size - fh->pos); 2105 if (size) { 2106 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, 2107 fh->fat_entry.start_address + fh->pos, buf, 2108 size, fh->fat_entry.fek); 2109 if (res != TEE_SUCCESS) { 2110 *errno = res; 2111 goto out; 2112 } 2113 } 2114 read_size = size; 2115 fh->pos += size; 2116 2117 out: 2118 mutex_unlock(&rpmb_mutex); 2119 return read_size; 2120 } 2121 2122 static int rpmb_fs_write(TEE_Result *errno, int fd, const void *buf, 2123 size_t size) 2124 { 2125 TEE_Result res; 2126 struct rpmb_file_handle *fh; 2127 tee_mm_pool_t p; 2128 bool pool_result = false; 2129 tee_mm_entry_t *mm; 2130 size_t end; 2131 size_t newsize; 2132 uint8_t *newbuf = NULL; 2133 uintptr_t newaddr; 2134 uint32_t start_addr; 2135 2136 if (!size) 2137 return 0; 2138 2139 mutex_lock(&rpmb_mutex); 2140 2141 if (!buf) { 2142 res = TEE_ERROR_BAD_PARAMETERS; 2143 goto out; 2144 } 2145 2146 if (!fs_par) { 2147 res = TEE_ERROR_GENERIC; 2148 goto out; 2149 } 2150 2151 fh = handle_lookup(&fs_handle_db, fd); 2152 if (!fh) { 2153 res = TEE_ERROR_BAD_PARAMETERS; 2154 goto out; 2155 } 2156 dump_fh(fh); 2157 2158 /* Upper memory allocation must be used for RPMB_FS. */ 2159 pool_result = tee_mm_init(&p, 2160 RPMB_STORAGE_START_ADDRESS, 2161 fs_par->max_rpmb_address, 2162 RPMB_BLOCK_SIZE_SHIFT, 2163 TEE_MM_POOL_HI_ALLOC); 2164 if (!pool_result) { 2165 res = TEE_ERROR_OUT_OF_MEMORY; 2166 goto out; 2167 } 2168 2169 res = read_fat(fh, &p); 2170 if (res != TEE_SUCCESS) 2171 goto out; 2172 2173 if (fh->fat_entry.flags & FILE_IS_LAST_ENTRY) 2174 panic("invalid last entry flag"); 2175 2176 end = fh->pos + size; 2177 start_addr = fh->fat_entry.start_address + fh->pos; 2178 2179 if (end <= fh->fat_entry.data_size && 2180 tee_rpmb_write_is_atomic(CFG_RPMB_FS_DEV_ID, start_addr, size)) { 2181 2182 DMSG("Updating data in-place"); 2183 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, start_addr, buf, 2184 size, fh->fat_entry.fek); 2185 if (res != TEE_SUCCESS) 2186 goto out; 2187 } else { 2188 /* 2189 * File must be extended, or update cannot be atomic: allocate, 2190 * read, update, write. 2191 */ 2192 2193 DMSG("Need to re-allocate"); 2194 newsize = MAX(end, fh->fat_entry.data_size); 2195 mm = tee_mm_alloc(&p, newsize); 2196 newbuf = calloc(newsize, 1); 2197 if (!mm || !newbuf) { 2198 res = TEE_ERROR_OUT_OF_MEMORY; 2199 goto out; 2200 } 2201 2202 if (fh->fat_entry.data_size) { 2203 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, 2204 fh->fat_entry.start_address, 2205 newbuf, fh->fat_entry.data_size, 2206 fh->fat_entry.fek); 2207 if (res != TEE_SUCCESS) 2208 goto out; 2209 } 2210 2211 memcpy(newbuf + fh->pos, buf, size); 2212 2213 newaddr = tee_mm_get_smem(mm); 2214 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf, 2215 newsize, fh->fat_entry.fek); 2216 if (res != TEE_SUCCESS) 2217 goto out; 2218 2219 fh->fat_entry.data_size = newsize; 2220 fh->fat_entry.start_address = newaddr; 2221 res = write_fat_entry(fh, true); 2222 if (res != TEE_SUCCESS) 2223 goto out; 2224 } 2225 2226 fh->pos += size; 2227 out: 2228 mutex_unlock(&rpmb_mutex); 2229 if (pool_result) 2230 tee_mm_final(&p); 2231 if (newbuf) 2232 free(newbuf); 2233 2234 if (res == TEE_SUCCESS) 2235 return size; 2236 2237 *errno = res; 2238 return -1; 2239 } 2240 2241 static tee_fs_off_t rpmb_fs_lseek(TEE_Result *errno, int fd, 2242 tee_fs_off_t offset, int whence) 2243 { 2244 struct rpmb_file_handle *fh; 2245 TEE_Result res; 2246 tee_fs_off_t ret = -1; 2247 tee_fs_off_t new_pos; 2248 2249 mutex_lock(&rpmb_mutex); 2250 2251 fh = handle_lookup(&fs_handle_db, fd); 2252 if (!fh) { 2253 res = TEE_ERROR_BAD_PARAMETERS; 2254 goto out; 2255 } 2256 2257 2258 res = read_fat(fh, NULL); 2259 if (res != TEE_SUCCESS) { 2260 *errno = res; 2261 goto out; 2262 } 2263 2264 switch (whence) { 2265 case TEE_FS_SEEK_SET: 2266 new_pos = offset; 2267 break; 2268 2269 case TEE_FS_SEEK_CUR: 2270 new_pos = fh->pos + offset; 2271 break; 2272 2273 case TEE_FS_SEEK_END: 2274 new_pos = fh->fat_entry.data_size + offset; 2275 break; 2276 2277 default: 2278 *errno = TEE_ERROR_BAD_PARAMETERS; 2279 goto out; 2280 } 2281 2282 if (new_pos < 0) 2283 new_pos = 0; 2284 2285 if (new_pos > TEE_DATA_MAX_POSITION) { 2286 EMSG("Position is beyond TEE_DATA_MAX_POSITION"); 2287 *errno = TEE_ERROR_BAD_PARAMETERS; 2288 goto out; 2289 } 2290 2291 ret = fh->pos = new_pos; 2292 out: 2293 mutex_unlock(&rpmb_mutex); 2294 return ret; 2295 } 2296 2297 static int rpmb_fs_unlink(const char *filename) 2298 { 2299 TEE_Result res = TEE_ERROR_GENERIC; 2300 struct rpmb_file_handle *fh = NULL; 2301 2302 mutex_lock(&rpmb_mutex); 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 mutex_unlock(&rpmb_mutex); 2325 free(fh); 2326 return (res == TEE_SUCCESS ? 0 : -1); 2327 } 2328 2329 static int rpmb_fs_rename(const char *old_name, const char *new_name) 2330 { 2331 TEE_Result res = TEE_ERROR_GENERIC; 2332 struct rpmb_file_handle *fh_old = NULL; 2333 struct rpmb_file_handle *fh_new = NULL; 2334 uint32_t old_len; 2335 uint32_t new_len; 2336 2337 mutex_lock(&rpmb_mutex); 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 mutex_unlock(&rpmb_mutex); 2383 free(fh_old); 2384 free(fh_new); 2385 2386 return (res == TEE_SUCCESS ? 0 : -1); 2387 } 2388 2389 static int rpmb_fs_mkdir(const char *path __unused, 2390 tee_fs_mode_t mode __unused) 2391 { 2392 /* 2393 * FIXME: mkdir() should really create some entry in the FAT so that 2394 * access() would return success when the directory exists but is 2395 * empty. This does not matter for the current use cases. 2396 */ 2397 return 0; 2398 } 2399 2400 static int rpmb_fs_ftruncate(TEE_Result *errno, int fd, tee_fs_off_t length) 2401 { 2402 struct rpmb_file_handle *fh; 2403 tee_mm_pool_t p; 2404 bool pool_result = false; 2405 tee_mm_entry_t *mm; 2406 uint32_t newsize; 2407 uint8_t *newbuf = NULL; 2408 uintptr_t newaddr; 2409 TEE_Result res = TEE_ERROR_GENERIC; 2410 2411 mutex_lock(&rpmb_mutex); 2412 2413 if (length < 0 || length > INT32_MAX) { 2414 res = TEE_ERROR_BAD_PARAMETERS; 2415 goto out; 2416 } 2417 newsize = length; 2418 2419 fh = handle_lookup(&fs_handle_db, fd); 2420 if (!fh) { 2421 res = TEE_ERROR_BAD_PARAMETERS; 2422 goto out; 2423 } 2424 2425 res = read_fat(fh, NULL); 2426 if (res != TEE_SUCCESS) 2427 goto out; 2428 2429 if (newsize > fh->fat_entry.data_size) { 2430 /* Extend file */ 2431 2432 pool_result = tee_mm_init(&p, 2433 RPMB_STORAGE_START_ADDRESS, 2434 fs_par->max_rpmb_address, 2435 RPMB_BLOCK_SIZE_SHIFT, 2436 TEE_MM_POOL_HI_ALLOC); 2437 if (!pool_result) { 2438 res = TEE_ERROR_OUT_OF_MEMORY; 2439 goto out; 2440 } 2441 res = read_fat(fh, &p); 2442 if (res != TEE_SUCCESS) 2443 goto out; 2444 2445 mm = tee_mm_alloc(&p, newsize); 2446 newbuf = calloc(newsize, 1); 2447 if (!mm || !newbuf) { 2448 res = TEE_ERROR_OUT_OF_MEMORY; 2449 goto out; 2450 } 2451 2452 if (fh->fat_entry.data_size) { 2453 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, 2454 fh->fat_entry.start_address, 2455 newbuf, fh->fat_entry.data_size, 2456 fh->fat_entry.fek); 2457 if (res != TEE_SUCCESS) 2458 goto out; 2459 } 2460 2461 newaddr = tee_mm_get_smem(mm); 2462 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf, 2463 newsize, fh->fat_entry.fek); 2464 if (res != TEE_SUCCESS) 2465 goto out; 2466 2467 } else { 2468 /* Don't change file location */ 2469 newaddr = fh->fat_entry.start_address; 2470 } 2471 2472 /* fh->pos is unchanged */ 2473 fh->fat_entry.data_size = newsize; 2474 fh->fat_entry.start_address = newaddr; 2475 res = write_fat_entry(fh, true); 2476 2477 out: 2478 mutex_unlock(&rpmb_mutex); 2479 if (pool_result) 2480 tee_mm_final(&p); 2481 if (newbuf) 2482 free(newbuf); 2483 2484 if (res == TEE_SUCCESS) 2485 return 0; 2486 2487 *errno = res; 2488 return -1; 2489 } 2490 2491 static void rpmb_fs_dir_free(struct tee_fs_dir *dir) 2492 { 2493 struct tee_rpmb_fs_dirent *e; 2494 2495 if (!dir) 2496 return; 2497 2498 free(dir->current); 2499 2500 while ((e = SIMPLEQ_FIRST(&dir->next))) { 2501 SIMPLEQ_REMOVE_HEAD(&dir->next, link); 2502 free(e); 2503 } 2504 } 2505 2506 static TEE_Result rpmb_fs_dir_populate(const char *path, 2507 struct tee_fs_dir *dir) 2508 { 2509 struct tee_rpmb_fs_dirent *current = NULL; 2510 struct rpmb_fat_entry *fat_entries = NULL; 2511 uint32_t fat_address; 2512 uint32_t filelen; 2513 char *filename; 2514 int i; 2515 bool last_entry_found = false; 2516 bool matched; 2517 struct tee_rpmb_fs_dirent *next = NULL; 2518 uint32_t pathlen; 2519 TEE_Result res = TEE_ERROR_GENERIC; 2520 uint32_t size; 2521 char temp; 2522 2523 mutex_lock(&rpmb_mutex); 2524 2525 res = rpmb_fs_setup(); 2526 if (res != TEE_SUCCESS) 2527 goto out; 2528 2529 res = get_fat_start_address(&fat_address); 2530 if (res != TEE_SUCCESS) 2531 goto out; 2532 2533 size = N_ENTRIES * sizeof(struct rpmb_fat_entry); 2534 fat_entries = malloc(size); 2535 if (!fat_entries) { 2536 res = TEE_ERROR_OUT_OF_MEMORY; 2537 goto out; 2538 } 2539 2540 pathlen = strlen(path); 2541 while (!last_entry_found) { 2542 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address, 2543 (uint8_t *)fat_entries, size, NULL); 2544 if (res != TEE_SUCCESS) 2545 goto out; 2546 2547 for (i = 0; i < N_ENTRIES; i++) { 2548 filename = fat_entries[i].filename; 2549 if (fat_entries[i].flags & FILE_IS_ACTIVE) { 2550 matched = false; 2551 filelen = strlen(filename); 2552 if (filelen > pathlen) { 2553 temp = filename[pathlen]; 2554 filename[pathlen] = '\0'; 2555 if (strcmp(filename, path) == 0) 2556 matched = true; 2557 2558 filename[pathlen] = temp; 2559 } 2560 2561 if (matched) { 2562 next = malloc(sizeof(*next)); 2563 if (!next) { 2564 res = TEE_ERROR_OUT_OF_MEMORY; 2565 goto out; 2566 } 2567 2568 memset(next, 0, sizeof(*next)); 2569 next->entry.d_name = next->name; 2570 memcpy(next->name, 2571 &filename[pathlen], 2572 filelen - pathlen); 2573 2574 SIMPLEQ_INSERT_TAIL(&dir->next, next, 2575 link); 2576 current = next; 2577 } 2578 } 2579 2580 if (fat_entries[i].flags & FILE_IS_LAST_ENTRY) { 2581 last_entry_found = true; 2582 break; 2583 } 2584 2585 /* Move to next fat_entry. */ 2586 fat_address += sizeof(struct rpmb_fat_entry); 2587 } 2588 } 2589 2590 /* No directories were found. */ 2591 if (!current) { 2592 res = TEE_ERROR_NO_DATA; 2593 goto out; 2594 } 2595 2596 res = TEE_SUCCESS; 2597 2598 out: 2599 mutex_unlock(&rpmb_mutex); 2600 if (res != TEE_SUCCESS) 2601 rpmb_fs_dir_free(dir); 2602 if (fat_entries) 2603 free(fat_entries); 2604 2605 return res; 2606 } 2607 2608 static TEE_Result rpmb_fs_opendir_internal(const char *path, 2609 struct tee_fs_dir **dir) 2610 { 2611 uint32_t len; 2612 uint32_t max_size; 2613 char path_local[TEE_RPMB_FS_FILENAME_LENGTH]; 2614 TEE_Result res = TEE_ERROR_GENERIC; 2615 struct tee_fs_dir *rpmb_dir = NULL; 2616 2617 if (!path || !dir) { 2618 res = TEE_ERROR_BAD_PARAMETERS; 2619 goto out; 2620 } 2621 2622 /* 2623 * There must be room for at least the NULL char and a char for the 2624 * filename after the path. 2625 */ 2626 max_size = TEE_RPMB_FS_FILENAME_LENGTH - 2; 2627 len = strlen(path); 2628 if (len > max_size || len == 0) { 2629 res = TEE_ERROR_BAD_PARAMETERS; 2630 goto out; 2631 } 2632 2633 memset(path_local, 0, sizeof(path_local)); 2634 memcpy(path_local, path, len); 2635 2636 /* Add a slash to correctly match the full directory name. */ 2637 if (path_local[len - 1] != '/') 2638 path_local[len] = '/'; 2639 2640 rpmb_dir = calloc(1, sizeof(*rpmb_dir)); 2641 if (!rpmb_dir) { 2642 res = TEE_ERROR_OUT_OF_MEMORY; 2643 goto out; 2644 } 2645 SIMPLEQ_INIT(&rpmb_dir->next); 2646 2647 res = rpmb_fs_dir_populate(path_local, rpmb_dir); 2648 if (res != TEE_SUCCESS) { 2649 free(rpmb_dir); 2650 rpmb_dir = NULL; 2651 goto out; 2652 } 2653 2654 *dir = rpmb_dir; 2655 2656 out: 2657 return res; 2658 } 2659 2660 static struct tee_fs_dir *rpmb_fs_opendir(const char *path) 2661 { 2662 struct tee_fs_dir *dir = NULL; 2663 TEE_Result res = TEE_ERROR_GENERIC; 2664 2665 res = rpmb_fs_opendir_internal(path, &dir); 2666 if (res != TEE_SUCCESS) 2667 dir = NULL; 2668 2669 return dir; 2670 } 2671 2672 2673 static struct tee_fs_dirent *rpmb_fs_readdir(struct tee_fs_dir *dir) 2674 { 2675 if (!dir) 2676 return NULL; 2677 2678 free(dir->current); 2679 2680 dir->current = SIMPLEQ_FIRST(&dir->next); 2681 if (!dir->current) 2682 return NULL; 2683 2684 SIMPLEQ_REMOVE_HEAD(&dir->next, link); 2685 2686 return &dir->current->entry; 2687 } 2688 2689 static int rpmb_fs_closedir(struct tee_fs_dir *dir) 2690 { 2691 TEE_Result res = TEE_ERROR_GENERIC; 2692 2693 if (!dir) { 2694 res = TEE_SUCCESS; 2695 goto out; 2696 } 2697 2698 rpmb_fs_dir_free(dir); 2699 free(dir); 2700 res = TEE_SUCCESS; 2701 out: 2702 if (res == TEE_SUCCESS) 2703 return 0; 2704 2705 return -1; 2706 } 2707 2708 static int rpmb_fs_rmdir(const char *path) 2709 { 2710 struct tee_fs_dir *dir = NULL; 2711 TEE_Result res = TEE_ERROR_GENERIC; 2712 int ret = -1; 2713 2714 /* Open the directory anyting other than NO_DATA is a failure */ 2715 res = rpmb_fs_opendir_internal(path, &dir); 2716 if (res == TEE_SUCCESS) { 2717 rpmb_fs_closedir(dir); 2718 ret = -1; 2719 2720 } else if (res == TEE_ERROR_NO_DATA) { 2721 ret = 0; 2722 2723 } else { 2724 /* The case any other failure is returned */ 2725 ret = -1; 2726 } 2727 2728 2729 return ret; 2730 } 2731 2732 static int rpmb_fs_stat(const char *filename, struct tee_rpmb_fs_stat *stat) 2733 { 2734 TEE_Result res = TEE_ERROR_GENERIC; 2735 struct rpmb_file_handle *fh = NULL; 2736 2737 mutex_lock(&rpmb_mutex); 2738 2739 if (!stat || !filename) { 2740 res = TEE_ERROR_BAD_PARAMETERS; 2741 goto out; 2742 } 2743 2744 fh = alloc_file_handle(filename); 2745 if (!fh) { 2746 res = TEE_ERROR_OUT_OF_MEMORY; 2747 goto out; 2748 } 2749 2750 res = read_fat(fh, NULL); 2751 if (res != TEE_SUCCESS) 2752 goto out; 2753 2754 stat->size = (size_t)fh->fat_entry.data_size; 2755 stat->reserved = 0; 2756 2757 out: 2758 mutex_unlock(&rpmb_mutex); 2759 free(fh); 2760 return (res == TEE_SUCCESS ? 0 : -1); 2761 } 2762 2763 static int rpmb_fs_access(const char *filename, int mode) 2764 { 2765 struct tee_rpmb_fs_stat stat; 2766 TEE_Result res; 2767 2768 /* Mode is currently ignored, this only checks for existence */ 2769 (void)mode; 2770 2771 res = rpmb_fs_stat(filename, &stat); 2772 2773 if (res == TEE_SUCCESS) 2774 return 0; 2775 2776 return -1; 2777 } 2778 2779 static int rpmb_fs_open(TEE_Result *errno, const char *file, int flags, ...) 2780 { 2781 int fd = -1; 2782 size_t len; 2783 2784 assert(errno); 2785 *errno = TEE_SUCCESS; 2786 2787 len = strlen(file) + 1; 2788 if (len > TEE_FS_NAME_MAX) { 2789 *errno = TEE_ERROR_BAD_PARAMETERS; 2790 goto exit; 2791 } 2792 2793 /* 2794 * try to open file without O_CREATE flag, if failed try again with 2795 * O_CREATE flag (to distinguish whether it's a new file or not) 2796 */ 2797 fd = rpmb_fs_open_internal(file, flags & (~TEE_FS_O_CREATE)); 2798 if (fd < 0) { 2799 if (!(flags & TEE_FS_O_CREATE)) { 2800 *errno = TEE_ERROR_ITEM_NOT_FOUND; 2801 goto exit; 2802 } 2803 2804 fd = rpmb_fs_open_internal(file, flags); 2805 /* File has been created */ 2806 } else { 2807 /* File already exists */ 2808 if ((flags & TEE_FS_O_CREATE) && (flags & TEE_FS_O_EXCL)) { 2809 *errno = TEE_ERROR_ACCESS_CONFLICT; 2810 rpmb_fs_close(fd); 2811 } 2812 } 2813 2814 exit: 2815 return fd; 2816 } 2817 2818 const struct tee_file_operations rpmb_fs_ops = { 2819 .open = rpmb_fs_open, 2820 .close = rpmb_fs_close, 2821 .read = rpmb_fs_read, 2822 .write = rpmb_fs_write, 2823 .lseek = rpmb_fs_lseek, 2824 .ftruncate = rpmb_fs_ftruncate, 2825 .rename = rpmb_fs_rename, 2826 .unlink = rpmb_fs_unlink, 2827 .mkdir = rpmb_fs_mkdir, 2828 .opendir = rpmb_fs_opendir, 2829 .closedir = rpmb_fs_closedir, 2830 .readdir = rpmb_fs_readdir, 2831 .rmdir = rpmb_fs_rmdir, 2832 .access = rpmb_fs_access 2833 }; 2834