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