2 * Copyright (c) 2014, STMicroelectronics International N.V.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
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.
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.
29 #include <kernel/mutex.h>
30 #include <kernel/panic.h>
31 #include <kernel/tee_common.h>
32 #include <kernel/tee_common_otp.h>
33 #include <kernel/tee_misc.h>
34 #include <kernel/thread.h>
35 #include <mm/core_memprot.h>
36 #include <mm/tee_mm.h>
37 #include <optee_msg_supplicant.h>
39 #include <string_ext.h>
41 #include <sys/queue.h>
42 #include <tee/tee_cryp_provider.h>
43 #include <tee/tee_fs.h>
44 #include <tee/tee_fs_key_manager.h>
45 #include <tee/tee_pobj.h>
46 #include <tee/tee_svc_storage.h>
50 #define RPMB_STORAGE_START_ADDRESS 0
51 #define RPMB_FS_FAT_START_ADDRESS 512
52 #define RPMB_BLOCK_SIZE_SHIFT 8
54 #define RPMB_FS_MAGIC 0x52504D42
58 #define FILE_IS_ACTIVE (1u << 0)
59 #define FILE_IS_LAST_ENTRY (1u << 1)
61 #define TEE_RPMB_FS_FILENAME_LENGTH 224
64 * FS parameters: Information often used by internal functions.
65 * fat_start_address will be set by rpmb_fs_setup().
66 * rpmb_fs_parameters can be read by any other function.
68 struct rpmb_fs_parameters {
69 uint32_t fat_start_address;
70 uint32_t max_rpmb_address;
74 * File entry for a single file in a RPMB_FS partition.
76 struct rpmb_fat_entry {
77 uint32_t start_address;
80 uint32_t write_counter;
81 uint8_t fek[TEE_FS_KM_FEK_SIZE];
82 char filename[TEE_RPMB_FS_FILENAME_LENGTH];
86 * FAT entry context with reference to a FAT entry and its
89 struct rpmb_file_handle {
90 struct rpmb_fat_entry fat_entry;
91 char filename[TEE_RPMB_FS_FILENAME_LENGTH];
92 /* Address for current entry in RPMB */
93 uint32_t rpmb_fat_address;
97 * RPMB_FS partition data
99 struct rpmb_fs_partition {
100 uint32_t rpmb_fs_magic;
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];
109 * A node in a list of directory entries.
111 struct tee_rpmb_fs_dirent {
112 struct tee_fs_dirent entry;
113 SIMPLEQ_ENTRY(tee_rpmb_fs_dirent) link;
117 * The RPMB directory representation. It contains a queue of
118 * RPMB directory entries: 'next'.
119 * The current pointer points to the last directory entry
120 * returned by readdir().
123 struct tee_rpmb_fs_dirent *current;
125 SIMPLEQ_HEAD(next_head, tee_rpmb_fs_dirent) next;
128 static struct rpmb_fs_parameters *fs_par;
131 * Lower interface to RPMB device
134 #define RPMB_DATA_OFFSET (RPMB_STUFF_DATA_SIZE + RPMB_KEY_MAC_SIZE)
135 #define RPMB_MAC_PROTECT_DATA_SIZE (RPMB_DATA_FRAME_SIZE - RPMB_DATA_OFFSET)
137 #define RPMB_MSG_TYPE_REQ_AUTH_KEY_PROGRAM 0x0001
138 #define RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ 0x0002
139 #define RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE 0x0003
140 #define RPMB_MSG_TYPE_REQ_AUTH_DATA_READ 0x0004
141 #define RPMB_MSG_TYPE_REQ_RESULT_READ 0x0005
142 #define RPMB_MSG_TYPE_RESP_AUTH_KEY_PROGRAM 0x0100
143 #define RPMB_MSG_TYPE_RESP_WRITE_COUNTER_VAL_READ 0x0200
144 #define RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE 0x0300
145 #define RPMB_MSG_TYPE_RESP_AUTH_DATA_READ 0x0400
147 #define RPMB_STUFF_DATA_SIZE 196
148 #define RPMB_KEY_MAC_SIZE 32
149 #define RPMB_DATA_SIZE 256
150 #define RPMB_NONCE_SIZE 16
151 #define RPMB_DATA_FRAME_SIZE 512
153 #define RPMB_RESULT_OK 0x00
154 #define RPMB_RESULT_GENERAL_FAILURE 0x01
155 #define RPMB_RESULT_AUTH_FAILURE 0x02
156 #define RPMB_RESULT_COUNTER_FAILURE 0x03
157 #define RPMB_RESULT_ADDRESS_FAILURE 0x04
158 #define RPMB_RESULT_WRITE_FAILURE 0x05
159 #define RPMB_RESULT_READ_FAILURE 0x06
160 #define RPMB_RESULT_AUTH_KEY_NOT_PROGRAMMED 0x07
161 #define RPMB_RESULT_MASK 0x3F
162 #define RPMB_RESULT_WR_CNT_EXPIRED 0x80
164 /* RPMB internal commands */
165 #define RPMB_CMD_DATA_REQ 0x00
166 #define RPMB_CMD_GET_DEV_INFO 0x01
168 #define RPMB_SIZE_SINGLE (128 * 1024)
170 /* Error codes for get_dev_info request/response. */
171 #define RPMB_CMD_GET_DEV_INFO_RET_OK 0x00
172 #define RPMB_CMD_GET_DEV_INFO_RET_ERROR 0x01
174 struct rpmb_data_frame {
175 uint8_t stuff_bytes[RPMB_STUFF_DATA_SIZE];
176 uint8_t key_mac[RPMB_KEY_MAC_SIZE];
177 uint8_t data[RPMB_DATA_SIZE];
178 uint8_t nonce[RPMB_NONCE_SIZE];
179 uint8_t write_counter[4];
181 uint8_t block_count[2];
182 uint8_t op_result[2];
189 uint16_t block_count;
190 /* variable length of data */
191 /* uint8_t data[]; REMOVED! */
194 #define TEE_RPMB_REQ_DATA(req) \
195 ((void *)((struct rpmb_req *)(req) + 1))
197 struct rpmb_raw_data {
200 uint16_t *block_count;
202 uint32_t *write_counter;
206 /* data length to read or write */
208 /* Byte address offset in the first block involved */
212 #define RPMB_EMMC_CID_SIZE 16
213 struct rpmb_dev_info {
214 uint8_t cid[RPMB_EMMC_CID_SIZE];
215 /* EXT CSD-slice 168 "RPMB Size" */
216 uint8_t rpmb_size_mult;
217 /* EXT CSD-slice 222 "Reliable Write Sector Count" */
218 uint8_t rel_wr_sec_c;
219 /* Check the ret code and accept the data only if it is OK. */
224 * Struct for rpmb context data.
228 * @hash_ctx_size Hash context size
229 * @wr_cnt Current write counter.
230 * @max_blk_idx The highest block index supported by current device.
231 * @rel_wr_blkcnt Max number of data blocks for each reliable write.
232 * @dev_id Device ID of the eMMC device.
233 * @wr_cnt_synced Flag indicating if write counter is synced to RPMB.
234 * @key_derived Flag indicating if key has been generated.
235 * @key_verified Flag indicating the key generated is verified ok.
236 * @dev_info_synced Flag indicating if dev info has been retrieved from RPMB.
238 struct tee_rpmb_ctx {
239 uint8_t key[RPMB_KEY_MAC_SIZE];
240 uint8_t cid[RPMB_EMMC_CID_SIZE];
241 size_t hash_ctx_size;
243 uint16_t max_blk_idx;
244 uint16_t rel_wr_blkcnt;
249 bool dev_info_synced;
252 static struct tee_rpmb_ctx *rpmb_ctx;
255 * Mutex to serialize the operations exported by this file.
256 * It protects rpmb_ctx and prevents overlapping operations on eMMC devices with
259 static struct mutex rpmb_mutex = MUTEX_INITIALIZER;
261 #ifdef CFG_RPMB_TESTKEY
263 static const uint8_t rpmb_test_key[RPMB_KEY_MAC_SIZE] = {
264 0xD3, 0xEB, 0x3E, 0xC3, 0x6E, 0x33, 0x4C, 0x9F,
265 0x98, 0x8C, 0xE2, 0xC0, 0xB8, 0x59, 0x54, 0x61,
266 0x0D, 0x2B, 0xCF, 0x86, 0x64, 0x84, 0x4D, 0xF2,
267 0xAB, 0x56, 0xE6, 0xC6, 0x1B, 0xB7, 0x01, 0xE4
270 static TEE_Result tee_rpmb_key_gen(uint16_t dev_id __unused,
271 uint8_t *key, uint32_t len)
273 TEE_Result res = TEE_SUCCESS;
275 if (!key || RPMB_KEY_MAC_SIZE != len) {
276 res = TEE_ERROR_BAD_PARAMETERS;
280 DMSG("RPMB: Using test key");
281 memcpy(key, rpmb_test_key, RPMB_KEY_MAC_SIZE);
287 #else /* !CFG_RPMB_TESTKEY */
290 * NOTE: We need a common API to get hw unique key and it
291 * should return error when the hw unique is not a valid
292 * one as stated below.
293 * We need to make sure the hw unique we get is valid by:
294 * 1. In case of HUK is used, checking if OTP is hidden (in
295 * which case only zeros will be returned) or not;
296 * 2. In case of SSK is used, checking if SSK in OTP is
297 * write_locked (which means a valid key is provisioned)
300 * Maybe tee_get_hw_unique_key() should be exposed as
301 * generic API for getting hw unique key!
302 * We should change the API tee_otp_get_hw_unique_key()
303 * to return error code!
305 static TEE_Result tee_get_hw_unique_key(struct tee_hw_unique_key *hwkey)
308 return TEE_ERROR_BAD_PARAMETERS;
310 tee_otp_get_hw_unique_key(hwkey);
315 static TEE_Result tee_rpmb_key_gen(uint16_t dev_id __unused,
316 uint8_t *key, uint32_t len)
319 struct tee_hw_unique_key hwkey;
322 if (!key || RPMB_KEY_MAC_SIZE != len) {
323 res = TEE_ERROR_BAD_PARAMETERS;
327 IMSG("RPMB: Using generated key");
328 res = tee_get_hw_unique_key(&hwkey);
329 if (res != TEE_SUCCESS)
332 ctx = malloc(rpmb_ctx->hash_ctx_size);
334 res = TEE_ERROR_OUT_OF_MEMORY;
338 res = crypto_ops.mac.init(ctx, TEE_ALG_HMAC_SHA256, hwkey.data,
339 HW_UNIQUE_KEY_LENGTH);
340 if (res != TEE_SUCCESS)
343 res = crypto_ops.mac.update(ctx, TEE_ALG_HMAC_SHA256,
344 (uint8_t *)rpmb_ctx->cid,
346 if (res != TEE_SUCCESS)
349 res = crypto_ops.mac.final(ctx, TEE_ALG_HMAC_SHA256, key, len);
356 #endif /* !CFG_RPMB_TESTKEY */
358 static void u32_to_bytes(uint32_t u32, uint8_t *bytes)
360 *bytes = (uint8_t) (u32 >> 24);
361 *(bytes + 1) = (uint8_t) (u32 >> 16);
362 *(bytes + 2) = (uint8_t) (u32 >> 8);
363 *(bytes + 3) = (uint8_t) u32;
366 static void bytes_to_u32(uint8_t *bytes, uint32_t *u32)
368 *u32 = (uint32_t) ((*(bytes) << 24) +
369 (*(bytes + 1) << 16) +
370 (*(bytes + 2) << 8) + (*(bytes + 3)));
373 static void u16_to_bytes(uint16_t u16, uint8_t *bytes)
375 *bytes = (uint8_t) (u16 >> 8);
376 *(bytes + 1) = (uint8_t) u16;
379 static void bytes_to_u16(uint8_t *bytes, uint16_t *u16)
381 *u16 = (uint16_t) ((*bytes << 8) + *(bytes + 1));
384 static TEE_Result tee_rpmb_mac_calc(uint8_t *mac, uint32_t macsize,
385 uint8_t *key, uint32_t keysize,
386 struct rpmb_data_frame *datafrms,
389 TEE_Result res = TEE_ERROR_GENERIC;
393 if (!mac || !key || !datafrms)
394 return TEE_ERROR_BAD_PARAMETERS;
396 ctx = malloc(rpmb_ctx->hash_ctx_size);
398 return TEE_ERROR_OUT_OF_MEMORY;
400 res = crypto_ops.mac.init(ctx, TEE_ALG_HMAC_SHA256, key, keysize);
401 if (res != TEE_SUCCESS)
404 for (i = 0; i < blkcnt; i++) {
405 res = crypto_ops.mac.update(ctx, TEE_ALG_HMAC_SHA256,
407 RPMB_MAC_PROTECT_DATA_SIZE);
408 if (res != TEE_SUCCESS)
412 res = crypto_ops.mac.final(ctx, TEE_ALG_HMAC_SHA256, mac, macsize);
413 if (res != TEE_SUCCESS)
423 struct tee_rpmb_mem {
425 uint64_t phreq_cookie;
427 uint64_t phresp_cookie;
432 static void tee_rpmb_free(struct tee_rpmb_mem *mem)
438 thread_rpc_free_payload(mem->phreq_cookie);
439 mem->phreq_cookie = 0;
443 thread_rpc_free_payload(mem->phresp_cookie);
444 mem->phresp_cookie = 0;
450 static TEE_Result tee_rpmb_alloc(size_t req_size, size_t resp_size,
451 struct tee_rpmb_mem *mem, void **req, void **resp)
453 TEE_Result res = TEE_SUCCESS;
454 size_t req_s = ROUNDUP(req_size, sizeof(uint32_t));
455 size_t resp_s = ROUNDUP(resp_size, sizeof(uint32_t));
458 return TEE_ERROR_BAD_PARAMETERS;
460 memset(mem, 0, sizeof(*mem));
461 thread_rpc_alloc_payload(req_s, &mem->phreq, &mem->phreq_cookie);
462 thread_rpc_alloc_payload(resp_s, &mem->phresp, &mem->phresp_cookie);
463 if (!mem->phreq || !mem->phresp) {
464 res = TEE_ERROR_OUT_OF_MEMORY;
468 *req = phys_to_virt(mem->phreq, MEM_AREA_NSEC_SHM);
469 *resp = phys_to_virt(mem->phresp, MEM_AREA_NSEC_SHM);
470 if (!*req || !*resp) {
471 res = TEE_ERROR_GENERIC;
475 mem->req_size = req_size;
476 mem->resp_size = resp_size;
479 if (res != TEE_SUCCESS)
484 static TEE_Result tee_rpmb_invoke(struct tee_rpmb_mem *mem)
486 struct optee_msg_param params[2];
488 memset(params, 0, sizeof(params));
489 params[0].attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
490 params[1].attr = OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT;
491 params[0].u.tmem.buf_ptr = mem->phreq;
492 params[0].u.tmem.size = mem->req_size;
493 params[0].u.tmem.shm_ref = mem->phreq_cookie;
494 params[1].u.tmem.buf_ptr = mem->phresp;
495 params[1].u.tmem.size = mem->resp_size;
496 params[1].u.tmem.shm_ref = mem->phresp_cookie;
498 return thread_rpc_cmd(OPTEE_MSG_RPC_CMD_RPMB, 2, params);
501 static bool is_zero(const uint8_t *buf, size_t size)
505 for (i = 0; i < size; i++)
511 static TEE_Result encrypt_block(uint8_t *out, const uint8_t *in,
512 uint16_t blk_idx, const uint8_t *fek)
514 return tee_fs_crypt_block(out, in, RPMB_DATA_SIZE, blk_idx, fek,
518 static TEE_Result decrypt_block(uint8_t *out, const uint8_t *in,
519 uint16_t blk_idx, const uint8_t *fek)
521 return tee_fs_crypt_block(out, in, RPMB_DATA_SIZE, blk_idx, fek,
525 /* Decrypt/copy at most one block of data */
526 static TEE_Result decrypt(uint8_t *out, const struct rpmb_data_frame *frm,
527 size_t size, size_t offset,
528 uint16_t blk_idx __maybe_unused, const uint8_t *fek)
530 uint8_t *tmp __maybe_unused;
533 if ((size + offset < size) || (size + offset > RPMB_DATA_SIZE))
534 panic("invalid size or offset");
537 /* Block is not encrypted (not a file data block) */
538 memcpy(out, frm->data + offset, size);
539 } else if (is_zero(fek, TEE_FS_KM_FEK_SIZE)) {
540 /* The file was created with encryption disabled */
541 return TEE_ERROR_SECURITY;
543 /* Block is encrypted */
544 if (size < RPMB_DATA_SIZE) {
546 * Since output buffer is not large enough to hold one
547 * block we must allocate a temporary buffer.
549 tmp = malloc(RPMB_DATA_SIZE);
551 return TEE_ERROR_OUT_OF_MEMORY;
552 decrypt_block(tmp, frm->data, blk_idx, fek);
553 memcpy(out, tmp + offset, size);
556 decrypt_block(out, frm->data, blk_idx, fek);
563 static TEE_Result tee_rpmb_req_pack(struct rpmb_req *req,
564 struct rpmb_raw_data *rawdata,
565 uint16_t nbr_frms, uint16_t dev_id,
568 TEE_Result res = TEE_ERROR_GENERIC;
570 struct rpmb_data_frame *datafrm;
572 if (!req || !rawdata || !nbr_frms)
573 return TEE_ERROR_BAD_PARAMETERS;
576 * Check write blockcount is not bigger than reliable write
579 if ((rawdata->msg_type == RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE) &&
580 (nbr_frms > rpmb_ctx->rel_wr_blkcnt)) {
581 DMSG("wr_blkcnt(%d) > rel_wr_blkcnt(%d)", nbr_frms,
582 rpmb_ctx->rel_wr_blkcnt);
583 return TEE_ERROR_GENERIC;
586 req->cmd = RPMB_CMD_DATA_REQ;
587 req->dev_id = dev_id;
589 /* Allocate memory for construct all data packets and calculate MAC. */
590 datafrm = calloc(nbr_frms, RPMB_DATA_FRAME_SIZE);
592 return TEE_ERROR_OUT_OF_MEMORY;
594 for (i = 0; i < nbr_frms; i++) {
595 u16_to_bytes(rawdata->msg_type, datafrm[i].msg_type);
597 if (rawdata->block_count)
598 u16_to_bytes(*rawdata->block_count,
599 datafrm[i].block_count);
601 if (rawdata->blk_idx) {
602 /* Check the block index is within range. */
603 if ((*rawdata->blk_idx + nbr_frms) >
604 rpmb_ctx->max_blk_idx) {
605 res = TEE_ERROR_GENERIC;
608 u16_to_bytes(*rawdata->blk_idx, datafrm[i].address);
611 if (rawdata->write_counter)
612 u32_to_bytes(*rawdata->write_counter,
613 datafrm[i].write_counter);
616 memcpy(datafrm[i].nonce, rawdata->nonce,
621 encrypt_block(datafrm[i].data,
622 rawdata->data + (i * RPMB_DATA_SIZE),
623 *rawdata->blk_idx + i, fek);
625 memcpy(datafrm[i].data,
626 rawdata->data + (i * RPMB_DATA_SIZE),
631 if (rawdata->key_mac) {
632 if (rawdata->msg_type == RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE) {
634 tee_rpmb_mac_calc(rawdata->key_mac,
635 RPMB_KEY_MAC_SIZE, rpmb_ctx->key,
636 RPMB_KEY_MAC_SIZE, datafrm,
638 if (res != TEE_SUCCESS)
641 memcpy(datafrm[nbr_frms - 1].key_mac,
642 rawdata->key_mac, RPMB_KEY_MAC_SIZE);
645 memcpy(TEE_RPMB_REQ_DATA(req), datafrm,
646 nbr_frms * RPMB_DATA_FRAME_SIZE);
648 #ifdef CFG_RPMB_FS_DEBUG_DATA
649 for (i = 0; i < nbr_frms; i++) {
650 DMSG("Dumping data frame %d:", i);
651 DHEXDUMP((uint8_t *)&datafrm[i] + RPMB_STUFF_DATA_SIZE,
652 512 - RPMB_STUFF_DATA_SIZE);
662 static TEE_Result data_cpy_mac_calc_1b(struct rpmb_raw_data *rawdata,
663 struct rpmb_data_frame *frm,
670 if (rawdata->len + rawdata->byte_offset > RPMB_DATA_SIZE)
671 return TEE_ERROR_BAD_PARAMETERS;
673 res = tee_rpmb_mac_calc(rawdata->key_mac, RPMB_KEY_MAC_SIZE,
674 rpmb_ctx->key, RPMB_KEY_MAC_SIZE, frm, 1);
675 if (res != TEE_SUCCESS)
678 data = rawdata->data;
679 bytes_to_u16(frm->address, &idx);
681 res = decrypt(data, frm, rawdata->len, rawdata->byte_offset, idx, fek);
685 static TEE_Result tee_rpmb_data_cpy_mac_calc(struct rpmb_data_frame *datafrm,
686 struct rpmb_raw_data *rawdata,
688 struct rpmb_data_frame *lastfrm,
691 TEE_Result res = TEE_ERROR_GENERIC;
698 struct rpmb_data_frame localfrm;
700 if (!datafrm || !rawdata || !nbr_frms || !lastfrm)
701 return TEE_ERROR_BAD_PARAMETERS;
704 return data_cpy_mac_calc_1b(rawdata, lastfrm, fek);
708 data = rawdata->data;
710 ctx = malloc(rpmb_ctx->hash_ctx_size);
712 res = TEE_ERROR_OUT_OF_MEMORY;
716 res = crypto_ops.mac.init(ctx, TEE_ALG_HMAC_SHA256, rpmb_ctx->key,
718 if (res != TEE_SUCCESS)
722 * Note: JEDEC JESD84-B51: "In every packet the address is the start
723 * address of the full access (not address of the individual half a
726 bytes_to_u16(lastfrm->address, &start_idx);
728 for (i = 0; i < (nbr_frms - 1); i++) {
731 * By working on a local copy of the RPMB frame, we ensure that
732 * the data can not be modified after the MAC is computed but
733 * before the payload is decrypted/copied to the output buffer.
735 memcpy(&localfrm, &datafrm[i], RPMB_DATA_FRAME_SIZE);
737 res = crypto_ops.mac.update(ctx, TEE_ALG_HMAC_SHA256,
739 RPMB_MAC_PROTECT_DATA_SIZE);
740 if (res != TEE_SUCCESS)
745 offset = rawdata->byte_offset;
746 size = RPMB_DATA_SIZE - offset;
749 size = RPMB_DATA_SIZE;
753 res = decrypt(data, &localfrm, size, offset, start_idx + i,
755 if (res != TEE_SUCCESS)
762 size = (rawdata->len + rawdata->byte_offset) % RPMB_DATA_SIZE;
764 size = RPMB_DATA_SIZE;
765 res = decrypt(data, lastfrm, size, 0, start_idx + nbr_frms - 1, fek);
766 if (res != TEE_SUCCESS)
769 /* Update MAC against the last block */
770 res = crypto_ops.mac.update(ctx, TEE_ALG_HMAC_SHA256, lastfrm->data,
771 RPMB_MAC_PROTECT_DATA_SIZE);
772 if (res != TEE_SUCCESS)
775 res = crypto_ops.mac.final(ctx, TEE_ALG_HMAC_SHA256, rawdata->key_mac,
777 if (res != TEE_SUCCESS)
787 static TEE_Result tee_rpmb_resp_unpack_verify(struct rpmb_data_frame *datafrm,
788 struct rpmb_raw_data *rawdata,
789 uint16_t nbr_frms, uint8_t *fek)
791 TEE_Result res = TEE_ERROR_GENERIC;
796 struct rpmb_data_frame lastfrm;
798 if (!datafrm || !rawdata || !nbr_frms)
799 return TEE_ERROR_BAD_PARAMETERS;
801 #ifdef CFG_RPMB_FS_DEBUG_DATA
802 for (uint32_t i = 0; i < nbr_frms; i++) {
803 DMSG("Dumping data frame %d:", i);
804 DHEXDUMP((uint8_t *)&datafrm[i] + RPMB_STUFF_DATA_SIZE,
805 512 - RPMB_STUFF_DATA_SIZE);
809 /* Make sure the last data packet can't be modified once verified */
810 memcpy(&lastfrm, &datafrm[nbr_frms - 1], RPMB_DATA_FRAME_SIZE);
812 /* Handle operation result and translate to TEEC error code. */
813 bytes_to_u16(lastfrm.op_result, &op_result);
814 if (rawdata->op_result)
815 *rawdata->op_result = op_result;
816 if (op_result != RPMB_RESULT_OK)
817 return TEE_ERROR_GENERIC;
819 /* Check the response msg_type. */
820 bytes_to_u16(lastfrm.msg_type, &msg_type);
821 if (msg_type != rawdata->msg_type) {
822 DMSG("Unexpected msg_type (0x%04x != 0x%04x)", msg_type,
824 return TEE_ERROR_GENERIC;
827 if (rawdata->blk_idx) {
828 bytes_to_u16(lastfrm.address, &blk_idx);
829 if (blk_idx != *rawdata->blk_idx) {
830 DMSG("Unexpected block index");
831 return TEE_ERROR_GENERIC;
835 if (rawdata->write_counter) {
836 wr_cnt = *rawdata->write_counter;
837 bytes_to_u32(lastfrm.write_counter, rawdata->write_counter);
838 if (msg_type == RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE) {
839 /* Verify the write counter is incremented by 1 */
840 if (*rawdata->write_counter != wr_cnt + 1) {
841 DMSG("Counter mismatched (0x%04x/0x%04x)",
842 *rawdata->write_counter, wr_cnt + 1);
843 return TEE_ERROR_SECURITY;
849 if (rawdata->nonce) {
850 if (buf_compare_ct(rawdata->nonce, lastfrm.nonce,
851 RPMB_NONCE_SIZE) != 0) {
852 DMSG("Nonce mismatched");
853 return TEE_ERROR_SECURITY;
857 if (rawdata->key_mac) {
858 if (msg_type == RPMB_MSG_TYPE_RESP_AUTH_DATA_READ) {
860 return TEE_ERROR_GENERIC;
862 res = tee_rpmb_data_cpy_mac_calc(datafrm, rawdata,
866 if (res != TEE_SUCCESS)
870 * There should be only one data frame for
874 return TEE_ERROR_GENERIC;
876 res = tee_rpmb_mac_calc(rawdata->key_mac,
882 if (res != TEE_SUCCESS)
886 #ifndef CFG_RPMB_FS_NO_MAC
887 if (buf_compare_ct(rawdata->key_mac,
888 (datafrm + nbr_frms - 1)->key_mac,
889 RPMB_KEY_MAC_SIZE) != 0) {
890 DMSG("MAC mismatched:");
891 #ifdef CFG_RPMB_FS_DEBUG_DATA
892 DHEXDUMP((uint8_t *)rawdata->key_mac, 32);
894 return TEE_ERROR_SECURITY;
896 #endif /* !CFG_RPMB_FS_NO_MAC */
902 static TEE_Result tee_rpmb_get_dev_info(uint16_t dev_id,
903 struct rpmb_dev_info *dev_info)
905 TEE_Result res = TEE_ERROR_GENERIC;
906 struct tee_rpmb_mem mem;
907 struct rpmb_dev_info *di;
908 struct rpmb_req *req = NULL;
909 uint8_t *resp = NULL;
914 return TEE_ERROR_BAD_PARAMETERS;
916 req_size = sizeof(struct rpmb_req);
917 resp_size = sizeof(struct rpmb_dev_info);
918 res = tee_rpmb_alloc(req_size, resp_size, &mem,
919 (void *)&req, (void *)&resp);
920 if (res != TEE_SUCCESS)
923 req->cmd = RPMB_CMD_GET_DEV_INFO;
924 req->dev_id = dev_id;
926 di = (struct rpmb_dev_info *)resp;
927 di->ret_code = RPMB_CMD_GET_DEV_INFO_RET_ERROR;
929 res = tee_rpmb_invoke(&mem);
930 if (res != TEE_SUCCESS)
933 if (di->ret_code != RPMB_CMD_GET_DEV_INFO_RET_OK) {
934 res = TEE_ERROR_GENERIC;
938 memcpy((uint8_t *)dev_info, resp, sizeof(struct rpmb_dev_info));
940 #ifdef CFG_RPMB_FS_DEBUG_DATA
941 DMSG("Dumping dev_info:");
942 DHEXDUMP((uint8_t *)dev_info, sizeof(struct rpmb_dev_info));
952 static TEE_Result tee_rpmb_init_read_wr_cnt(uint16_t dev_id,
956 TEE_Result res = TEE_ERROR_GENERIC;
957 struct tee_rpmb_mem mem;
959 uint8_t nonce[RPMB_NONCE_SIZE];
960 uint8_t hmac[RPMB_KEY_MAC_SIZE];
961 struct rpmb_req *req = NULL;
962 struct rpmb_data_frame *resp = NULL;
963 struct rpmb_raw_data rawdata;
968 return TEE_ERROR_BAD_PARAMETERS;
970 req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE;
971 resp_size = RPMB_DATA_FRAME_SIZE;
972 res = tee_rpmb_alloc(req_size, resp_size, &mem,
973 (void *)&req, (void *)&resp);
974 if (res != TEE_SUCCESS)
977 res = crypto_ops.prng.read(nonce, RPMB_NONCE_SIZE);
978 if (res != TEE_SUCCESS)
981 msg_type = RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ;
983 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
984 rawdata.msg_type = msg_type;
985 rawdata.nonce = nonce;
987 res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL);
988 if (res != TEE_SUCCESS)
991 res = tee_rpmb_invoke(&mem);
992 if (res != TEE_SUCCESS)
995 msg_type = RPMB_MSG_TYPE_RESP_WRITE_COUNTER_VAL_READ;
997 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
998 rawdata.msg_type = msg_type;
999 rawdata.op_result = op_result;
1000 rawdata.write_counter = wr_cnt;
1001 rawdata.nonce = nonce;
1002 rawdata.key_mac = hmac;
1004 res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL);
1005 if (res != TEE_SUCCESS)
1011 tee_rpmb_free(&mem);
1015 static TEE_Result tee_rpmb_verify_key_sync_counter(uint16_t dev_id)
1017 uint16_t op_result = 0;
1018 TEE_Result res = TEE_ERROR_GENERIC;
1020 res = tee_rpmb_init_read_wr_cnt(dev_id, &rpmb_ctx->wr_cnt,
1023 if (res == TEE_SUCCESS) {
1024 rpmb_ctx->key_verified = true;
1025 rpmb_ctx->wr_cnt_synced = true;
1028 DMSG("Verify key returning 0x%x\n", res);
1032 #ifdef CFG_RPMB_WRITE_KEY
1033 static TEE_Result tee_rpmb_write_key(uint16_t dev_id)
1035 TEE_Result res = TEE_ERROR_GENERIC;
1036 struct tee_rpmb_mem mem = { 0 };
1038 struct rpmb_req *req = NULL;
1039 struct rpmb_data_frame *resp = NULL;
1040 struct rpmb_raw_data rawdata;
1044 req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE;
1045 resp_size = RPMB_DATA_FRAME_SIZE;
1046 res = tee_rpmb_alloc(req_size, resp_size, &mem,
1047 (void *)&req, (void *)&resp);
1048 if (res != TEE_SUCCESS)
1051 msg_type = RPMB_MSG_TYPE_REQ_AUTH_KEY_PROGRAM;
1053 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1054 rawdata.msg_type = msg_type;
1055 rawdata.key_mac = rpmb_ctx->key;
1057 res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL);
1058 if (res != TEE_SUCCESS)
1061 res = tee_rpmb_invoke(&mem);
1062 if (res != TEE_SUCCESS)
1065 msg_type = RPMB_MSG_TYPE_RESP_AUTH_KEY_PROGRAM;
1067 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1068 rawdata.msg_type = msg_type;
1070 res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL);
1071 if (res != TEE_SUCCESS)
1077 tee_rpmb_free(&mem);
1081 static TEE_Result tee_rpmb_write_and_verify_key(uint16_t dev_id)
1085 DMSG("RPMB INIT: Writing Key");
1086 res = tee_rpmb_write_key(dev_id);
1087 if (res == TEE_SUCCESS) {
1088 DMSG("RPMB INIT: Verifying Key");
1089 res = tee_rpmb_verify_key_sync_counter(dev_id);
1094 static TEE_Result tee_rpmb_write_and_verify_key(uint16_t dev_id __unused)
1096 return TEE_ERROR_BAD_STATE;
1100 /* True when all the required crypto functions are available */
1101 static bool have_crypto_ops(void)
1103 return (crypto_ops.mac.init && crypto_ops.mac.update &&
1104 crypto_ops.mac.final && crypto_ops.prng.read);
1107 /* This function must never return TEE_SUCCESS if rpmb_ctx == NULL */
1108 static TEE_Result tee_rpmb_init(uint16_t dev_id)
1110 TEE_Result res = TEE_SUCCESS;
1111 struct rpmb_dev_info dev_info;
1113 if (!have_crypto_ops())
1114 return TEE_ERROR_NOT_SUPPORTED;
1117 rpmb_ctx = calloc(1, sizeof(struct tee_rpmb_ctx));
1119 return TEE_ERROR_OUT_OF_MEMORY;
1120 } else if (rpmb_ctx->dev_id != dev_id) {
1121 memset(rpmb_ctx, 0x00, sizeof(struct tee_rpmb_ctx));
1124 rpmb_ctx->dev_id = dev_id;
1126 if (!rpmb_ctx->dev_info_synced) {
1127 DMSG("RPMB: Syncing device information");
1129 dev_info.rpmb_size_mult = 0;
1130 dev_info.rel_wr_sec_c = 0;
1131 res = tee_rpmb_get_dev_info(dev_id, &dev_info);
1132 if (res != TEE_SUCCESS)
1135 DMSG("RPMB: RPMB size is %d*128 KB", dev_info.rpmb_size_mult);
1136 DMSG("RPMB: Reliable Write Sector Count is %d",
1137 dev_info.rel_wr_sec_c);
1139 if (dev_info.rpmb_size_mult == 0) {
1140 res = TEE_ERROR_GENERIC;
1144 rpmb_ctx->max_blk_idx = (dev_info.rpmb_size_mult *
1145 RPMB_SIZE_SINGLE / RPMB_DATA_SIZE) - 1;
1147 memcpy(rpmb_ctx->cid, dev_info.cid, RPMB_EMMC_CID_SIZE);
1149 if ((rpmb_ctx->hash_ctx_size == 0) &&
1150 (crypto_ops.mac.get_ctx_size(
1151 TEE_ALG_HMAC_SHA256,
1152 &rpmb_ctx->hash_ctx_size))) {
1153 rpmb_ctx->hash_ctx_size = 0;
1154 res = TEE_ERROR_GENERIC;
1158 #ifdef RPMB_DRIVER_MULTIPLE_WRITE_FIXED
1159 rpmb_ctx->rel_wr_blkcnt = dev_info.rel_wr_sec_c * 2;
1161 rpmb_ctx->rel_wr_blkcnt = 1;
1164 rpmb_ctx->dev_info_synced = true;
1167 if (!rpmb_ctx->key_derived) {
1168 DMSG("RPMB INIT: Deriving key");
1170 res = tee_rpmb_key_gen(dev_id, rpmb_ctx->key,
1172 if (res != TEE_SUCCESS)
1175 rpmb_ctx->key_derived = true;
1178 /* Perform a write counter read to verify if the key is ok. */
1179 if (!rpmb_ctx->wr_cnt_synced || !rpmb_ctx->key_verified) {
1180 DMSG("RPMB INIT: Verifying Key");
1182 res = tee_rpmb_verify_key_sync_counter(dev_id);
1183 if (res != TEE_SUCCESS && !rpmb_ctx->key_verified) {
1185 * Need to write the key here and verify it.
1187 res = tee_rpmb_write_and_verify_key(dev_id);
1196 * Read RPMB data in bytes.
1198 * @dev_id Device ID of the eMMC device.
1199 * @addr Byte address of data.
1200 * @data Pointer to the data.
1201 * @len Size of data in bytes.
1202 * @fek Encrypted File Encryption Key or NULL.
1204 static TEE_Result tee_rpmb_read(uint16_t dev_id, uint32_t addr, uint8_t *data,
1205 uint32_t len, uint8_t *fek)
1207 TEE_Result res = TEE_ERROR_GENERIC;
1208 struct tee_rpmb_mem mem = { 0 };
1210 uint8_t nonce[RPMB_NONCE_SIZE];
1211 uint8_t hmac[RPMB_KEY_MAC_SIZE];
1212 struct rpmb_req *req = NULL;
1213 struct rpmb_data_frame *resp = NULL;
1214 struct rpmb_raw_data rawdata;
1219 uint8_t byte_offset;
1222 return TEE_ERROR_BAD_PARAMETERS;
1224 blk_idx = addr / RPMB_DATA_SIZE;
1225 byte_offset = addr % RPMB_DATA_SIZE;
1228 ROUNDUP(len + byte_offset, RPMB_DATA_SIZE) / RPMB_DATA_SIZE;
1229 res = tee_rpmb_init(dev_id);
1230 if (res != TEE_SUCCESS)
1233 req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE;
1234 resp_size = RPMB_DATA_FRAME_SIZE * blkcnt;
1235 res = tee_rpmb_alloc(req_size, resp_size, &mem,
1236 (void *)&req, (void *)&resp);
1237 if (res != TEE_SUCCESS)
1240 msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_READ;
1241 res = crypto_ops.prng.read(nonce, RPMB_NONCE_SIZE);
1242 if (res != TEE_SUCCESS)
1245 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1246 rawdata.msg_type = msg_type;
1247 rawdata.nonce = nonce;
1248 rawdata.blk_idx = &blk_idx;
1249 res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL);
1250 if (res != TEE_SUCCESS)
1253 req->block_count = blkcnt;
1255 DMSG("Read %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""),
1258 res = tee_rpmb_invoke(&mem);
1259 if (res != TEE_SUCCESS)
1262 msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_READ;
1264 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1265 rawdata.msg_type = msg_type;
1266 rawdata.block_count = &blkcnt;
1267 rawdata.blk_idx = &blk_idx;
1268 rawdata.nonce = nonce;
1269 rawdata.key_mac = hmac;
1270 rawdata.data = data;
1273 rawdata.byte_offset = byte_offset;
1275 res = tee_rpmb_resp_unpack_verify(resp, &rawdata, blkcnt, fek);
1276 if (res != TEE_SUCCESS)
1282 tee_rpmb_free(&mem);
1286 static TEE_Result tee_rpmb_write_blk(uint16_t dev_id, uint16_t blk_idx,
1287 const uint8_t *data_blks, uint16_t blkcnt,
1291 struct tee_rpmb_mem mem;
1294 uint8_t hmac[RPMB_KEY_MAC_SIZE];
1295 struct rpmb_req *req = NULL;
1296 struct rpmb_data_frame *resp = NULL;
1297 struct rpmb_raw_data rawdata;
1300 uint32_t nbr_writes;
1301 uint16_t tmp_blkcnt;
1302 uint16_t tmp_blk_idx;
1305 DMSG("Write %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""),
1308 if (!data_blks || !blkcnt)
1309 return TEE_ERROR_BAD_PARAMETERS;
1311 res = tee_rpmb_init(dev_id);
1312 if (res != TEE_SUCCESS)
1316 * We need to split data when block count
1317 * is bigger than reliable block write count.
1319 if (blkcnt < rpmb_ctx->rel_wr_blkcnt)
1320 req_size = sizeof(struct rpmb_req) +
1321 RPMB_DATA_FRAME_SIZE * blkcnt;
1323 req_size = sizeof(struct rpmb_req) +
1324 RPMB_DATA_FRAME_SIZE * rpmb_ctx->rel_wr_blkcnt;
1326 resp_size = RPMB_DATA_FRAME_SIZE;
1327 res = tee_rpmb_alloc(req_size, resp_size, &mem,
1328 (void *)&req, (void *)&resp);
1329 if (res != TEE_SUCCESS)
1332 nbr_writes = blkcnt / rpmb_ctx->rel_wr_blkcnt;
1333 if (blkcnt % rpmb_ctx->rel_wr_blkcnt > 0)
1336 tmp_blkcnt = rpmb_ctx->rel_wr_blkcnt;
1337 tmp_blk_idx = blk_idx;
1338 for (i = 0; i < nbr_writes; i++) {
1340 * To handle the last write of block count which is
1341 * equal or smaller than reliable write block count.
1343 if (i == nbr_writes - 1)
1344 tmp_blkcnt = blkcnt - rpmb_ctx->rel_wr_blkcnt *
1347 msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE;
1348 wr_cnt = rpmb_ctx->wr_cnt;
1350 memset(req, 0x00, req_size);
1351 memset(resp, 0x00, resp_size);
1353 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1354 rawdata.msg_type = msg_type;
1355 rawdata.block_count = &tmp_blkcnt;
1356 rawdata.blk_idx = &tmp_blk_idx;
1357 rawdata.write_counter = &wr_cnt;
1358 rawdata.key_mac = hmac;
1359 rawdata.data = (uint8_t *)data_blks +
1360 i * rpmb_ctx->rel_wr_blkcnt * RPMB_DATA_SIZE;
1362 res = tee_rpmb_req_pack(req, &rawdata, tmp_blkcnt, dev_id,
1364 if (res != TEE_SUCCESS)
1367 res = tee_rpmb_invoke(&mem);
1368 if (res != TEE_SUCCESS) {
1370 * To force wr_cnt sync next time, as it might get
1371 * out of sync due to inconsistent operation result!
1373 rpmb_ctx->wr_cnt_synced = false;
1377 msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE;
1379 memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1380 rawdata.msg_type = msg_type;
1381 rawdata.block_count = &tmp_blkcnt;
1382 rawdata.blk_idx = &tmp_blk_idx;
1383 rawdata.write_counter = &wr_cnt;
1384 rawdata.key_mac = hmac;
1386 res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL);
1387 if (res != TEE_SUCCESS) {
1389 * To force wr_cnt sync next time, as it might get
1390 * out of sync due to inconsistent operation result!
1392 rpmb_ctx->wr_cnt_synced = false;
1396 tmp_blk_idx += tmp_blkcnt;
1400 tee_rpmb_free(&mem);
1404 static bool tee_rpmb_write_is_atomic(uint16_t dev_id __unused, uint32_t addr,
1407 uint8_t byte_offset = addr % RPMB_DATA_SIZE;
1408 uint16_t blkcnt = ROUNDUP(len + byte_offset,
1409 RPMB_DATA_SIZE) / RPMB_DATA_SIZE;
1411 return (blkcnt <= rpmb_ctx->rel_wr_blkcnt);
1415 * Write RPMB data in bytes.
1417 * @dev_id Device ID of the eMMC device.
1418 * @addr Byte address of data.
1419 * @data Pointer to the data.
1420 * @len Size of data in bytes.
1421 * @fek Encrypted File Encryption Key or NULL.
1423 static TEE_Result tee_rpmb_write(uint16_t dev_id, uint32_t addr,
1424 const uint8_t *data, uint32_t len,
1427 TEE_Result res = TEE_ERROR_GENERIC;
1428 uint8_t *data_tmp = NULL;
1431 uint8_t byte_offset;
1433 blk_idx = addr / RPMB_DATA_SIZE;
1434 byte_offset = addr % RPMB_DATA_SIZE;
1437 ROUNDUP(len + byte_offset, RPMB_DATA_SIZE) / RPMB_DATA_SIZE;
1439 if (byte_offset == 0 && (len % RPMB_DATA_SIZE) == 0) {
1440 res = tee_rpmb_write_blk(dev_id, blk_idx, data, blkcnt, fek);
1441 if (res != TEE_SUCCESS)
1444 data_tmp = calloc(blkcnt, RPMB_DATA_SIZE);
1446 res = TEE_ERROR_OUT_OF_MEMORY;
1450 /* Read the complete blocks */
1451 res = tee_rpmb_read(dev_id, blk_idx * RPMB_DATA_SIZE, data_tmp,
1452 blkcnt * RPMB_DATA_SIZE, fek);
1453 if (res != TEE_SUCCESS)
1456 /* Partial update of the data blocks */
1457 memcpy(data_tmp + byte_offset, data, len);
1459 res = tee_rpmb_write_blk(dev_id, blk_idx, data_tmp, blkcnt,
1461 if (res != TEE_SUCCESS)
1473 * Read the RPMB write counter.
1475 * @dev_id Device ID of the eMMC device.
1476 * @counter Pointer to the counter.
1478 static TEE_Result tee_rpmb_get_write_counter(uint16_t dev_id,
1481 TEE_Result res = TEE_SUCCESS;
1484 return TEE_ERROR_BAD_PARAMETERS;
1486 if (!rpmb_ctx || !rpmb_ctx->wr_cnt_synced) {
1487 res = tee_rpmb_init(dev_id);
1488 if (res != TEE_SUCCESS)
1492 *counter = rpmb_ctx->wr_cnt;
1499 * Read the RPMB max block.
1501 * @dev_id Device ID of the eMMC device.
1502 * @counter Pointer to receive the max block.
1504 static TEE_Result tee_rpmb_get_max_block(uint16_t dev_id, uint32_t *max_block)
1506 TEE_Result res = TEE_SUCCESS;
1509 return TEE_ERROR_BAD_PARAMETERS;
1511 if (!rpmb_ctx || !rpmb_ctx->dev_info_synced) {
1512 res = tee_rpmb_init(dev_id);
1513 if (res != TEE_SUCCESS)
1517 *max_block = rpmb_ctx->max_blk_idx;
1524 * End of lower interface to RPMB device
1527 static TEE_Result get_fat_start_address(uint32_t *addr);
1529 static void dump_fat(void)
1531 TEE_Result res = TEE_ERROR_GENERIC;
1532 struct rpmb_fat_entry *fat_entries = NULL;
1533 uint32_t fat_address;
1536 bool last_entry_found = false;
1538 res = get_fat_start_address(&fat_address);
1539 if (res != TEE_SUCCESS)
1542 size = N_ENTRIES * sizeof(struct rpmb_fat_entry);
1543 fat_entries = malloc(size);
1545 res = TEE_ERROR_OUT_OF_MEMORY;
1549 while (!last_entry_found) {
1550 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address,
1551 (uint8_t *)fat_entries, size, NULL);
1552 if (res != TEE_SUCCESS)
1555 for (i = 0; i < N_ENTRIES; i++) {
1557 FMSG("flags 0x%x, size %d, address 0x%x, filename '%s'",
1558 fat_entries[i].flags,
1559 fat_entries[i].data_size,
1560 fat_entries[i].start_address,
1561 fat_entries[i].filename);
1563 if ((fat_entries[i].flags & FILE_IS_LAST_ENTRY) != 0) {
1564 last_entry_found = true;
1568 /* Move to next fat_entry. */
1569 fat_address += sizeof(struct rpmb_fat_entry);
1577 #if (TRACE_LEVEL >= TRACE_DEBUG)
1578 static void dump_fh(struct rpmb_file_handle *fh)
1580 DMSG("fh->filename=%s", fh->filename);
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);
1586 static void dump_fh(struct rpmb_file_handle *fh __unused)
1591 static struct rpmb_file_handle *alloc_file_handle(struct tee_pobj *po,
1594 struct rpmb_file_handle *fh = NULL;
1596 fh = calloc(1, sizeof(struct rpmb_file_handle));
1601 tee_svc_storage_create_filename(fh->filename,
1602 sizeof(fh->filename), po,
1609 * write_fat_entry: Store info in a fat_entry to RPMB.
1611 static TEE_Result write_fat_entry(struct rpmb_file_handle *fh,
1612 bool update_write_counter)
1614 TEE_Result res = TEE_ERROR_GENERIC;
1616 /* Protect partition data. */
1617 if (fh->rpmb_fat_address < sizeof(struct rpmb_fs_partition)) {
1618 res = TEE_ERROR_ACCESS_CONFLICT;
1622 if (fh->rpmb_fat_address % sizeof(struct rpmb_fat_entry) != 0) {
1623 res = TEE_ERROR_BAD_PARAMETERS;
1627 if (update_write_counter) {
1628 res = tee_rpmb_get_write_counter(CFG_RPMB_FS_DEV_ID,
1629 &fh->fat_entry.write_counter);
1630 if (res != TEE_SUCCESS)
1634 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, fh->rpmb_fat_address,
1635 (uint8_t *)&fh->fat_entry,
1636 sizeof(struct rpmb_fat_entry), NULL);
1645 * rpmb_fs_setup: Setup rpmb fs.
1646 * Set initial partition and FS values and write to RPMB.
1647 * Store frequently used data in RAM.
1649 static TEE_Result rpmb_fs_setup(void)
1651 TEE_Result res = TEE_ERROR_GENERIC;
1652 struct rpmb_fs_partition *partition_data = NULL;
1653 struct rpmb_file_handle *fh = NULL;
1654 uint32_t max_rpmb_block = 0;
1661 res = tee_rpmb_get_max_block(CFG_RPMB_FS_DEV_ID, &max_rpmb_block);
1662 if (res != TEE_SUCCESS)
1665 partition_data = calloc(1, sizeof(struct rpmb_fs_partition));
1666 if (!partition_data) {
1667 res = TEE_ERROR_OUT_OF_MEMORY;
1671 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS,
1672 (uint8_t *)partition_data,
1673 sizeof(struct rpmb_fs_partition), NULL);
1674 if (res != TEE_SUCCESS)
1677 #ifndef CFG_RPMB_RESET_FAT
1678 if (partition_data->rpmb_fs_magic == RPMB_FS_MAGIC) {
1679 if (partition_data->fs_version == FS_VERSION) {
1683 /* Wrong software is in use. */
1684 res = TEE_ERROR_ACCESS_DENIED;
1689 EMSG("**** Clearing Storage ****");
1692 /* Setup new partition data. */
1693 partition_data->rpmb_fs_magic = RPMB_FS_MAGIC;
1694 partition_data->fs_version = FS_VERSION;
1695 partition_data->fat_start_address = RPMB_FS_FAT_START_ADDRESS;
1697 /* Initial FAT entry with FILE_IS_LAST_ENTRY flag set. */
1698 fh = alloc_file_handle(NULL, false);
1700 res = TEE_ERROR_OUT_OF_MEMORY;
1703 fh->fat_entry.flags = FILE_IS_LAST_ENTRY;
1704 fh->rpmb_fat_address = partition_data->fat_start_address;
1706 /* Write init FAT entry and partition data to RPMB. */
1707 res = write_fat_entry(fh, true);
1708 if (res != TEE_SUCCESS)
1712 tee_rpmb_get_write_counter(CFG_RPMB_FS_DEV_ID,
1713 &partition_data->write_counter);
1714 if (res != TEE_SUCCESS)
1716 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS,
1717 (uint8_t *)partition_data,
1718 sizeof(struct rpmb_fs_partition), NULL);
1720 #ifndef CFG_RPMB_RESET_FAT
1724 /* Store FAT start address. */
1725 fs_par = calloc(1, sizeof(struct rpmb_fs_parameters));
1727 res = TEE_ERROR_OUT_OF_MEMORY;
1731 fs_par->fat_start_address = partition_data->fat_start_address;
1732 fs_par->max_rpmb_address = max_rpmb_block << RPMB_BLOCK_SIZE_SHIFT;
1738 free(partition_data);
1743 * get_fat_start_address:
1744 * FAT start_address from fs_par.
1746 static TEE_Result get_fat_start_address(uint32_t *addr)
1749 return TEE_ERROR_NO_DATA;
1751 *addr = fs_par->fat_start_address;
1757 * read_fat: Read FAT entries
1758 * Return matching FAT entry for read, rm rename and stat.
1759 * Build up memory pool and return matching entry for write operation.
1760 * "Last FAT entry" can be returned during write.
1762 static TEE_Result read_fat(struct rpmb_file_handle *fh, tee_mm_pool_t *p)
1764 TEE_Result res = TEE_ERROR_GENERIC;
1765 tee_mm_entry_t *mm = NULL;
1766 struct rpmb_fat_entry *fat_entries = NULL;
1767 uint32_t fat_address;
1770 bool entry_found = false;
1771 bool last_entry_found = false;
1772 bool expand_fat = false;
1773 struct rpmb_file_handle last_fh;
1775 DMSG("fat_address %d", fh->rpmb_fat_address);
1777 res = rpmb_fs_setup();
1778 if (res != TEE_SUCCESS)
1781 res = get_fat_start_address(&fat_address);
1782 if (res != TEE_SUCCESS)
1785 size = N_ENTRIES * sizeof(struct rpmb_fat_entry);
1786 fat_entries = malloc(size);
1788 res = TEE_ERROR_OUT_OF_MEMORY;
1793 * The pool is used to represent the current RPMB layout. To find
1794 * a slot for the file tee_mm_alloc is called on the pool. Thus
1795 * if it is not NULL the entire FAT must be traversed to fill in
1798 while (!last_entry_found && (!entry_found || p)) {
1799 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address,
1800 (uint8_t *)fat_entries, size, NULL);
1801 if (res != TEE_SUCCESS)
1804 for (i = 0; i < N_ENTRIES; i++) {
1806 * Look for an entry, matching filenames. (read, rm,
1807 * rename and stat.). Only store first filename match.
1810 (strcmp(fh->filename,
1811 fat_entries[i].filename) == 0) &&
1812 (fat_entries[i].flags & FILE_IS_ACTIVE) &&
1815 fh->rpmb_fat_address = fat_address;
1816 memcpy(&fh->fat_entry, &fat_entries[i],
1817 sizeof(struct rpmb_fat_entry));
1822 /* Add existing files to memory pool. (write) */
1824 if ((fat_entries[i].flags & FILE_IS_ACTIVE) &&
1825 (fat_entries[i].data_size > 0)) {
1829 fat_entries[i].start_address,
1830 fat_entries[i].data_size);
1832 res = TEE_ERROR_OUT_OF_MEMORY;
1837 /* Unused FAT entries can be reused (write) */
1838 if (((fat_entries[i].flags & FILE_IS_ACTIVE) ==
1839 0) && (fh->rpmb_fat_address == 0)) {
1840 fh->rpmb_fat_address = fat_address;
1841 memcpy(&fh->fat_entry, &fat_entries[i],
1842 sizeof(struct rpmb_fat_entry));
1846 if ((fat_entries[i].flags & FILE_IS_LAST_ENTRY) != 0) {
1847 last_entry_found = true;
1850 * If the last entry was reached and was chosen
1851 * by the previous check, then the FAT needs to
1853 * fh->rpmb_fat_address is the address chosen
1854 * to store the files FAT entry and fat_address
1855 * is the current FAT entry address being
1858 if (p && fh->rpmb_fat_address == fat_address)
1863 /* Move to next fat_entry. */
1864 fat_address += sizeof(struct rpmb_fat_entry);
1869 * Represent the FAT table in the pool.
1873 * Since fat_address is the start of the last entry it needs to
1874 * be moved up by an entry.
1876 fat_address += sizeof(struct rpmb_fat_entry);
1878 /* Make room for yet a FAT entry and add to memory pool. */
1880 fat_address += sizeof(struct rpmb_fat_entry);
1882 mm = tee_mm_alloc2(p, RPMB_STORAGE_START_ADDRESS, fat_address);
1884 res = TEE_ERROR_OUT_OF_MEMORY;
1890 * Point fat_address to the beginning of the new
1893 fat_address -= sizeof(struct rpmb_fat_entry);
1894 memset(&last_fh, 0, sizeof(last_fh));
1895 last_fh.fat_entry.flags = FILE_IS_LAST_ENTRY;
1896 last_fh.rpmb_fat_address = fat_address;
1897 res = write_fat_entry(&last_fh, true);
1898 if (res != TEE_SUCCESS)
1903 if (fh->filename && !fh->rpmb_fat_address)
1904 res = TEE_ERROR_ITEM_NOT_FOUND;
1911 static TEE_Result generate_fek(struct rpmb_fat_entry *fe)
1916 res = tee_fs_generate_fek(fe->fek, sizeof(fe->fek));
1917 if (res != TEE_SUCCESS)
1920 if (is_zero(fe->fek, sizeof(fe->fek)))
1926 static TEE_Result rpmb_fs_open_internal(struct tee_pobj *po, bool create,
1927 struct tee_file_handle **ret_fh)
1929 struct rpmb_file_handle *fh = NULL;
1932 TEE_Result res = TEE_ERROR_GENERIC;
1934 mutex_lock(&rpmb_mutex);
1936 fh = alloc_file_handle(po, po->temporary);
1938 res = TEE_ERROR_OUT_OF_MEMORY;
1942 /* We need to do setup in order to make sure fs_par is filled in */
1943 res = rpmb_fs_setup();
1944 if (res != TEE_SUCCESS)
1948 /* Upper memory allocation must be used for RPMB_FS. */
1949 pool_result = tee_mm_init(&p,
1950 RPMB_STORAGE_START_ADDRESS,
1951 fs_par->max_rpmb_address,
1952 RPMB_BLOCK_SIZE_SHIFT,
1953 TEE_MM_POOL_HI_ALLOC);
1956 res = TEE_ERROR_OUT_OF_MEMORY;
1960 res = read_fat(fh, &p);
1962 if (res != TEE_SUCCESS)
1965 res = read_fat(fh, NULL);
1966 if (res != TEE_SUCCESS)
1971 * If this is opened with create and the entry found was not active
1972 * then this is a new file and the FAT entry must be written
1975 if ((fh->fat_entry.flags & FILE_IS_ACTIVE) == 0) {
1976 memset(&fh->fat_entry, 0,
1977 sizeof(struct rpmb_fat_entry));
1978 memcpy(fh->fat_entry.filename, fh->filename,
1979 strlen(fh->filename));
1980 /* Start address and size are 0 */
1981 fh->fat_entry.flags = FILE_IS_ACTIVE;
1983 res = generate_fek(&fh->fat_entry);
1984 if (res != TEE_SUCCESS)
1986 DMSG("GENERATE FEK key: %p",
1987 (void *)fh->fat_entry.fek);
1988 DHEXDUMP(fh->fat_entry.fek, sizeof(fh->fat_entry.fek));
1990 res = write_fat_entry(fh, true);
1991 if (res != TEE_SUCCESS)
1999 if (res == TEE_SUCCESS)
2000 *ret_fh = (struct tee_file_handle *)fh;
2004 mutex_unlock(&rpmb_mutex);
2008 static void rpmb_fs_close(struct tee_file_handle **tfh)
2010 struct rpmb_file_handle *fh = (struct rpmb_file_handle *)*tfh;
2016 static TEE_Result rpmb_fs_read(struct tee_file_handle *tfh, size_t pos,
2017 void *buf, size_t *len)
2020 struct rpmb_file_handle *fh = (struct rpmb_file_handle *)tfh;
2026 mutex_lock(&rpmb_mutex);
2030 res = read_fat(fh, NULL);
2031 if (res != TEE_SUCCESS)
2034 if (pos >= fh->fat_entry.data_size) {
2039 size = MIN(size, fh->fat_entry.data_size - pos);
2041 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2042 fh->fat_entry.start_address + pos, buf,
2043 size, fh->fat_entry.fek);
2044 if (res != TEE_SUCCESS)
2050 mutex_unlock(&rpmb_mutex);
2054 static TEE_Result rpmb_fs_write(struct tee_file_handle *tfh, size_t pos,
2055 const void *buf, size_t size)
2058 struct rpmb_file_handle *fh = (struct rpmb_file_handle *)tfh;
2060 bool pool_result = false;
2064 uint8_t *newbuf = NULL;
2066 uint32_t start_addr;
2071 mutex_lock(&rpmb_mutex);
2074 res = TEE_ERROR_GENERIC;
2080 /* Upper memory allocation must be used for RPMB_FS. */
2081 pool_result = tee_mm_init(&p,
2082 RPMB_STORAGE_START_ADDRESS,
2083 fs_par->max_rpmb_address,
2084 RPMB_BLOCK_SIZE_SHIFT,
2085 TEE_MM_POOL_HI_ALLOC);
2087 res = TEE_ERROR_OUT_OF_MEMORY;
2091 res = read_fat(fh, &p);
2092 if (res != TEE_SUCCESS)
2095 if (fh->fat_entry.flags & FILE_IS_LAST_ENTRY)
2096 panic("invalid last entry flag");
2099 start_addr = fh->fat_entry.start_address + pos;
2101 if (end <= fh->fat_entry.data_size &&
2102 tee_rpmb_write_is_atomic(CFG_RPMB_FS_DEV_ID, start_addr, size)) {
2104 DMSG("Updating data in-place");
2105 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, start_addr, buf,
2106 size, fh->fat_entry.fek);
2107 if (res != TEE_SUCCESS)
2111 * File must be extended, or update cannot be atomic: allocate,
2112 * read, update, write.
2115 DMSG("Need to re-allocate");
2116 newsize = MAX(end, fh->fat_entry.data_size);
2117 mm = tee_mm_alloc(&p, newsize);
2118 newbuf = calloc(newsize, 1);
2119 if (!mm || !newbuf) {
2120 res = TEE_ERROR_OUT_OF_MEMORY;
2124 if (fh->fat_entry.data_size) {
2125 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2126 fh->fat_entry.start_address,
2127 newbuf, fh->fat_entry.data_size,
2129 if (res != TEE_SUCCESS)
2133 memcpy(newbuf + pos, buf, size);
2135 newaddr = tee_mm_get_smem(mm);
2136 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf,
2137 newsize, fh->fat_entry.fek);
2138 if (res != TEE_SUCCESS)
2141 fh->fat_entry.data_size = newsize;
2142 fh->fat_entry.start_address = newaddr;
2143 res = write_fat_entry(fh, true);
2144 if (res != TEE_SUCCESS)
2149 mutex_unlock(&rpmb_mutex);
2158 static TEE_Result rpmb_fs_remove(struct tee_pobj *po)
2160 TEE_Result res = TEE_ERROR_GENERIC;
2161 struct rpmb_file_handle *fh = NULL;
2163 mutex_lock(&rpmb_mutex);
2165 fh = alloc_file_handle(po, po->temporary);
2167 res = TEE_ERROR_OUT_OF_MEMORY;
2171 res = read_fat(fh, NULL);
2172 if (res != TEE_SUCCESS)
2175 /* Clear this file entry. */
2176 memset(&fh->fat_entry, 0, sizeof(struct rpmb_fat_entry));
2177 res = write_fat_entry(fh, false);
2180 mutex_unlock(&rpmb_mutex);
2185 static TEE_Result rpmb_fs_rename(struct tee_pobj *old, struct tee_pobj *new,
2188 TEE_Result res = TEE_ERROR_GENERIC;
2189 struct rpmb_file_handle *fh_old = NULL;
2190 struct rpmb_file_handle *fh_new = NULL;
2192 mutex_lock(&rpmb_mutex);
2195 res = TEE_ERROR_BAD_PARAMETERS;
2200 fh_old = alloc_file_handle(old, old->temporary);
2202 fh_old = alloc_file_handle(old, true);
2204 res = TEE_ERROR_OUT_OF_MEMORY;
2209 fh_new = alloc_file_handle(new, new->temporary);
2211 fh_new = alloc_file_handle(old, false);
2213 res = TEE_ERROR_OUT_OF_MEMORY;
2217 res = read_fat(fh_old, NULL);
2218 if (res != TEE_SUCCESS)
2221 res = read_fat(fh_new, NULL);
2222 if (res == TEE_SUCCESS) {
2224 res = TEE_ERROR_BAD_PARAMETERS;
2228 /* Clear this file entry. */
2229 memset(&fh_new->fat_entry, 0, sizeof(struct rpmb_fat_entry));
2230 res = write_fat_entry(fh_new, false);
2231 if (res != TEE_SUCCESS)
2235 memset(fh_old->fat_entry.filename, 0, TEE_RPMB_FS_FILENAME_LENGTH);
2236 memcpy(fh_old->fat_entry.filename, fh_new->filename,
2237 strlen(fh_new->filename));
2239 res = write_fat_entry(fh_old, false);
2242 mutex_unlock(&rpmb_mutex);
2249 static TEE_Result rpmb_fs_truncate(struct tee_file_handle *tfh, size_t length)
2251 struct rpmb_file_handle *fh = (struct rpmb_file_handle *)tfh;
2253 bool pool_result = false;
2256 uint8_t *newbuf = NULL;
2258 TEE_Result res = TEE_ERROR_GENERIC;
2260 mutex_lock(&rpmb_mutex);
2262 if (length > INT32_MAX) {
2263 res = TEE_ERROR_BAD_PARAMETERS;
2268 res = read_fat(fh, NULL);
2269 if (res != TEE_SUCCESS)
2272 if (newsize > fh->fat_entry.data_size) {
2275 pool_result = tee_mm_init(&p,
2276 RPMB_STORAGE_START_ADDRESS,
2277 fs_par->max_rpmb_address,
2278 RPMB_BLOCK_SIZE_SHIFT,
2279 TEE_MM_POOL_HI_ALLOC);
2281 res = TEE_ERROR_OUT_OF_MEMORY;
2284 res = read_fat(fh, &p);
2285 if (res != TEE_SUCCESS)
2288 mm = tee_mm_alloc(&p, newsize);
2289 newbuf = calloc(newsize, 1);
2290 if (!mm || !newbuf) {
2291 res = TEE_ERROR_OUT_OF_MEMORY;
2295 if (fh->fat_entry.data_size) {
2296 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2297 fh->fat_entry.start_address,
2298 newbuf, fh->fat_entry.data_size,
2300 if (res != TEE_SUCCESS)
2304 newaddr = tee_mm_get_smem(mm);
2305 res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf,
2306 newsize, fh->fat_entry.fek);
2307 if (res != TEE_SUCCESS)
2311 /* Don't change file location */
2312 newaddr = fh->fat_entry.start_address;
2315 /* fh->pos is unchanged */
2316 fh->fat_entry.data_size = newsize;
2317 fh->fat_entry.start_address = newaddr;
2318 res = write_fat_entry(fh, true);
2321 mutex_unlock(&rpmb_mutex);
2330 static void rpmb_fs_dir_free(struct tee_fs_dir *dir)
2332 struct tee_rpmb_fs_dirent *e;
2339 while ((e = SIMPLEQ_FIRST(&dir->next))) {
2340 SIMPLEQ_REMOVE_HEAD(&dir->next, link);
2345 static TEE_Result rpmb_fs_dir_populate(const char *path,
2346 struct tee_fs_dir *dir)
2348 struct tee_rpmb_fs_dirent *current = NULL;
2349 struct rpmb_fat_entry *fat_entries = NULL;
2350 uint32_t fat_address;
2354 bool last_entry_found = false;
2356 struct tee_rpmb_fs_dirent *next = NULL;
2358 TEE_Result res = TEE_ERROR_GENERIC;
2362 mutex_lock(&rpmb_mutex);
2364 res = rpmb_fs_setup();
2365 if (res != TEE_SUCCESS)
2368 res = get_fat_start_address(&fat_address);
2369 if (res != TEE_SUCCESS)
2372 size = N_ENTRIES * sizeof(struct rpmb_fat_entry);
2373 fat_entries = malloc(size);
2375 res = TEE_ERROR_OUT_OF_MEMORY;
2379 pathlen = strlen(path);
2380 while (!last_entry_found) {
2381 res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address,
2382 (uint8_t *)fat_entries, size, NULL);
2383 if (res != TEE_SUCCESS)
2386 for (i = 0; i < N_ENTRIES; i++) {
2387 filename = fat_entries[i].filename;
2388 if (fat_entries[i].flags & FILE_IS_ACTIVE) {
2390 filelen = strlen(filename);
2391 if (filelen > pathlen) {
2392 temp = filename[pathlen];
2393 filename[pathlen] = '\0';
2394 if (strcmp(filename, path) == 0)
2397 filename[pathlen] = temp;
2401 next = malloc(sizeof(*next));
2403 res = TEE_ERROR_OUT_OF_MEMORY;
2407 next->entry.oidlen = tee_hs2b(
2408 (uint8_t *)&filename[pathlen],
2411 sizeof(next->entry.oid));
2412 if (next->entry.oidlen) {
2413 SIMPLEQ_INSERT_TAIL(&dir->next,
2424 if (fat_entries[i].flags & FILE_IS_LAST_ENTRY) {
2425 last_entry_found = true;
2429 /* Move to next fat_entry. */
2430 fat_address += sizeof(struct rpmb_fat_entry);
2437 res = TEE_ERROR_ITEM_NOT_FOUND; /* No directories were found. */
2440 mutex_unlock(&rpmb_mutex);
2441 if (res != TEE_SUCCESS)
2442 rpmb_fs_dir_free(dir);
2449 static TEE_Result rpmb_fs_opendir(const TEE_UUID *uuid, struct tee_fs_dir **dir)
2452 char path_local[TEE_RPMB_FS_FILENAME_LENGTH];
2453 TEE_Result res = TEE_ERROR_GENERIC;
2454 struct tee_fs_dir *rpmb_dir = NULL;
2456 if (!uuid || !dir) {
2457 res = TEE_ERROR_BAD_PARAMETERS;
2461 memset(path_local, 0, sizeof(path_local));
2462 if (tee_svc_storage_create_dirname(path_local, sizeof(path_local) - 1,
2463 uuid) != TEE_SUCCESS) {
2464 res = TEE_ERROR_BAD_PARAMETERS;
2467 len = strlen(path_local);
2469 /* Add a slash to correctly match the full directory name. */
2470 if (path_local[len - 1] != '/')
2471 path_local[len] = '/';
2473 rpmb_dir = calloc(1, sizeof(*rpmb_dir));
2475 res = TEE_ERROR_OUT_OF_MEMORY;
2478 SIMPLEQ_INIT(&rpmb_dir->next);
2480 res = rpmb_fs_dir_populate(path_local, rpmb_dir);
2481 if (res != TEE_SUCCESS) {
2493 static TEE_Result rpmb_fs_readdir(struct tee_fs_dir *dir,
2494 struct tee_fs_dirent **ent)
2497 return TEE_ERROR_GENERIC;
2501 dir->current = SIMPLEQ_FIRST(&dir->next);
2503 return TEE_ERROR_ITEM_NOT_FOUND;
2505 SIMPLEQ_REMOVE_HEAD(&dir->next, link);
2507 *ent = &dir->current->entry;
2511 static void rpmb_fs_closedir(struct tee_fs_dir *dir)
2514 rpmb_fs_dir_free(dir);
2519 static TEE_Result rpmb_fs_open(struct tee_pobj *po, struct tee_file_handle **fh)
2521 return rpmb_fs_open_internal(po, false, fh);
2524 static TEE_Result rpmb_fs_create(struct tee_pobj *po,
2525 struct tee_file_handle **fh)
2527 return rpmb_fs_open_internal(po, true, fh);
2530 const struct tee_file_operations rpmb_fs_ops = {
2531 .open = rpmb_fs_open,
2532 .create = rpmb_fs_create,
2533 .close = rpmb_fs_close,
2534 .read = rpmb_fs_read,
2535 .write = rpmb_fs_write,
2536 .truncate = rpmb_fs_truncate,
2537 .rename = rpmb_fs_rename,
2538 .remove = rpmb_fs_remove,
2539 .opendir = rpmb_fs_opendir,
2540 .closedir = rpmb_fs_closedir,
2541 .readdir = rpmb_fs_readdir,