xref: /optee_os/core/tee/tee_rpmb_fs.c (revision 19a31ec40245ae01a9adcd206eec2a4bb4479fc9)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  */
5 
6 #include <assert.h>
7 #include <config.h>
8 #include <crypto/crypto.h>
9 #include <kernel/huk_subkey.h>
10 #include <kernel/misc.h>
11 #include <kernel/msg_param.h>
12 #include <kernel/mutex.h>
13 #include <kernel/panic.h>
14 #include <kernel/tee_common.h>
15 #include <kernel/tee_common_otp.h>
16 #include <kernel/tee_misc.h>
17 #include <kernel/thread.h>
18 #include <kernel/user_access.h>
19 #include <mempool.h>
20 #include <mm/core_memprot.h>
21 #include <mm/mobj.h>
22 #include <mm/tee_mm.h>
23 #include <optee_rpc_cmd.h>
24 #include <stdlib.h>
25 #include <string_ext.h>
26 #include <string.h>
27 #include <sys/queue.h>
28 #include <tee/tee_fs.h>
29 #include <tee/tee_fs_key_manager.h>
30 #include <tee/tee_pobj.h>
31 #include <tee/tee_svc_storage.h>
32 #include <trace.h>
33 #include <util.h>
34 
35 #define RPMB_STORAGE_START_ADDRESS      0
36 #define RPMB_FS_FAT_START_ADDRESS       512
37 #define RPMB_BLOCK_SIZE_SHIFT           8
38 #define RPMB_CID_PRV_OFFSET             9
39 #define RPMB_CID_CRC_OFFSET             15
40 
41 #define RPMB_FS_MAGIC                   0x52504D42
42 #define FS_VERSION                      2
43 
44 #define FILE_IS_ACTIVE                  (1u << 0)
45 #define FILE_IS_LAST_ENTRY              (1u << 1)
46 
47 #define TEE_RPMB_FS_FILENAME_LENGTH 224
48 
49 #define TMP_BLOCK_SIZE			4096U
50 
51 #define RPMB_MAX_RETRIES		10
52 
53 /**
54  * Utilized when caching is enabled, i.e., when CFG_RPMB_FS_CACHE_ENTRIES > 0.
55  * Cache size + the number of entries that are repeatedly read in and buffered
56  * once the cache is full.
57  */
58 #define RPMB_BUF_MAX_ENTRIES (CFG_RPMB_FS_CACHE_ENTRIES + \
59 			      CFG_RPMB_FS_RD_ENTRIES)
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 unused;
79 	uint8_t fek[TEE_FS_KM_FEK_SIZE];
80 	char filename[TEE_RPMB_FS_FILENAME_LENGTH];
81 };
82 
83 /**
84  * Structure that describes buffered/cached FAT FS entries in RPMB storage.
85  * This structure is used in functions traversing the FAT FS.
86  */
87 struct rpmb_fat_entry_dir {
88 	/*
89 	 * Buffer storing the FAT FS entries read in from RPMB storage. It
90 	 * includes the optional cache entries (CFG_RPMB_FS_CACHE_ENTRIES)
91 	 * and entries temporary read for current FAT FS traversal
92 	 * (CFG_RPMB_FS_RD_ENTRIES) when not found from cached entries.
93 	 */
94 	struct rpmb_fat_entry *rpmb_fat_entry_buf;
95 	/* Current index of FAT FS entry to read from buffer. */
96 	uint32_t idx_curr;
97 	/* Total number of FAT FS entries in buffer. */
98 	uint32_t num_buffered;
99 	/* Total number of FAT FS entries read during traversal. */
100 	uint32_t num_total_read;
101 	/* Indicates that last FAT FS entry was read. */
102 	bool last_reached;
103 };
104 
105 /**
106  * FAT entry context with reference to a FAT entry and its
107  * location in RPMB.
108  */
109 struct rpmb_file_handle {
110 	struct rpmb_fat_entry fat_entry;
111 	const TEE_UUID *uuid;
112 	char filename[TEE_RPMB_FS_FILENAME_LENGTH];
113 	/* Address for current entry in RPMB */
114 	uint32_t rpmb_fat_address;
115 };
116 
117 /**
118  * RPMB_FS partition data
119  */
120 struct rpmb_fs_partition {
121 	uint32_t rpmb_fs_magic;
122 	uint32_t fs_version;
123 	uint32_t write_counter;
124 	uint32_t fat_start_address;
125 	/* Do not use reserved[] for other purpose than partition data. */
126 	uint8_t reserved[112];
127 };
128 
129 /**
130  * A node in a list of directory entries.
131  */
132 struct tee_rpmb_fs_dirent {
133 	struct tee_fs_dirent entry;
134 	SIMPLEQ_ENTRY(tee_rpmb_fs_dirent) link;
135 };
136 
137 /**
138  * The RPMB directory representation. It contains a queue of
139  * RPMB directory entries: 'next'.
140  * The current pointer points to the last directory entry
141  * returned by readdir().
142  */
143 struct tee_fs_dir {
144 	struct tee_rpmb_fs_dirent *current;
145 	/* */
146 	SIMPLEQ_HEAD(next_head, tee_rpmb_fs_dirent) next;
147 };
148 
149 static struct rpmb_fs_parameters *fs_par;
150 static struct rpmb_fat_entry_dir *fat_entry_dir;
151 
152 /*
153  * Lower interface to RPMB device
154  */
155 
156 #define RPMB_DATA_OFFSET            (RPMB_STUFF_DATA_SIZE + RPMB_KEY_MAC_SIZE)
157 #define RPMB_MAC_PROTECT_DATA_SIZE  (RPMB_DATA_FRAME_SIZE - RPMB_DATA_OFFSET)
158 
159 #define RPMB_MSG_TYPE_REQ_AUTH_KEY_PROGRAM          0x0001
160 #define RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ    0x0002
161 #define RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE           0x0003
162 #define RPMB_MSG_TYPE_REQ_AUTH_DATA_READ            0x0004
163 #define RPMB_MSG_TYPE_REQ_RESULT_READ               0x0005
164 #define RPMB_MSG_TYPE_RESP_AUTH_KEY_PROGRAM         0x0100
165 #define RPMB_MSG_TYPE_RESP_WRITE_COUNTER_VAL_READ   0x0200
166 #define RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE          0x0300
167 #define RPMB_MSG_TYPE_RESP_AUTH_DATA_READ           0x0400
168 
169 #define RPMB_STUFF_DATA_SIZE                        196
170 #define RPMB_KEY_MAC_SIZE                           32
171 #define RPMB_DATA_SIZE                              256
172 #define RPMB_NONCE_SIZE                             16
173 #define RPMB_DATA_FRAME_SIZE                        512
174 
175 #define RPMB_RESULT_OK                              0x00
176 #define RPMB_RESULT_GENERAL_FAILURE                 0x01
177 #define RPMB_RESULT_AUTH_FAILURE                    0x02
178 #define RPMB_RESULT_COUNTER_FAILURE                 0x03
179 #define RPMB_RESULT_ADDRESS_FAILURE                 0x04
180 #define RPMB_RESULT_WRITE_FAILURE                   0x05
181 #define RPMB_RESULT_READ_FAILURE                    0x06
182 #define RPMB_RESULT_AUTH_KEY_NOT_PROGRAMMED         0x07
183 #define RPMB_RESULT_MASK                            0x3F
184 #define RPMB_RESULT_WR_CNT_EXPIRED                  0x80
185 
186 /* RPMB internal commands */
187 #define RPMB_CMD_DATA_REQ      0x00
188 #define RPMB_CMD_GET_DEV_INFO  0x01
189 
190 #define RPMB_SIZE_SINGLE (128 * 1024)
191 
192 /* Error codes for get_dev_info request/response. */
193 #define RPMB_CMD_GET_DEV_INFO_RET_OK     0x00
194 #define RPMB_CMD_GET_DEV_INFO_RET_ERROR  0x01
195 
196 struct rpmb_data_frame {
197 	uint8_t stuff_bytes[RPMB_STUFF_DATA_SIZE];
198 	uint8_t key_mac[RPMB_KEY_MAC_SIZE];
199 	uint8_t data[RPMB_DATA_SIZE];
200 	uint8_t nonce[RPMB_NONCE_SIZE];
201 	uint8_t write_counter[4];
202 	uint8_t address[2];
203 	uint8_t block_count[2];
204 	uint8_t op_result[2];
205 	uint8_t msg_type[2];
206 };
207 
208 struct rpmb_req {
209 	uint16_t cmd;
210 	uint16_t dev_id;
211 	uint16_t block_count;
212 	/* variable length of data */
213 	/* uint8_t data[]; REMOVED! */
214 };
215 
216 #define TEE_RPMB_REQ_DATA(req) \
217 		((void *)((struct rpmb_req *)(req) + 1))
218 
219 struct rpmb_raw_data {
220 	uint16_t msg_type;
221 	uint16_t *op_result;
222 	uint16_t *block_count;
223 	uint16_t *blk_idx;
224 	uint32_t *write_counter;
225 	uint8_t *nonce;
226 	uint8_t *key_mac;
227 	uint8_t *data;
228 	/* data length to read or write */
229 	uint32_t len;
230 	/* Byte address offset in the first block involved */
231 	uint8_t byte_offset;
232 };
233 
234 #define RPMB_EMMC_CID_SIZE 16
235 struct rpmb_dev_info {
236 	uint8_t cid[RPMB_EMMC_CID_SIZE];
237 	/* EXT CSD-slice 168 "RPMB Size" */
238 	uint8_t rpmb_size_mult;
239 	/* EXT CSD-slice 222 "Reliable Write Sector Count" */
240 	uint8_t rel_wr_sec_c;
241 	/* Check the ret code and accept the data only if it is OK. */
242 	uint8_t ret_code;
243 };
244 
245 /*
246  * Struct for rpmb context data.
247  *
248  * @key              RPMB key.
249  * @cid              eMMC card ID.
250  * @wr_cnt           Current write counter.
251  * @max_blk_idx      The highest block index supported by current device.
252  * @rel_wr_blkcnt    Max number of data blocks for each reliable write.
253  * @dev_id           Device ID of the eMMC device.
254  * @wr_cnt_synced    Flag indicating if write counter is synced to RPMB.
255  * @key_derived      Flag indicating if key has been generated.
256  * @key_verified     Flag indicating the key generated is verified ok.
257  * @dev_info_synced  Flag indicating if dev info has been retrieved from RPMB.
258  */
259 struct tee_rpmb_ctx {
260 	uint8_t key[RPMB_KEY_MAC_SIZE];
261 	uint8_t cid[RPMB_EMMC_CID_SIZE];
262 	uint32_t wr_cnt;
263 	uint16_t max_blk_idx;
264 	uint16_t rel_wr_blkcnt;
265 	uint16_t dev_id;
266 	bool wr_cnt_synced;
267 	bool key_derived;
268 	bool key_verified;
269 	bool dev_info_synced;
270 };
271 
272 static struct tee_rpmb_ctx *rpmb_ctx;
273 
274 /* If set to true, don't try to access RPMB until rebooted */
275 static bool rpmb_dead;
276 
277 /*
278  * Mutex to serialize the operations exported by this file.
279  * It protects rpmb_ctx and prevents overlapping operations on eMMC devices with
280  * different IDs.
281  */
282 static struct mutex rpmb_mutex = MUTEX_INITIALIZER;
283 
284 #ifdef CFG_RPMB_TESTKEY
285 
286 static const uint8_t rpmb_test_key[RPMB_KEY_MAC_SIZE] = {
287 	0xD3, 0xEB, 0x3E, 0xC3, 0x6E, 0x33, 0x4C, 0x9F,
288 	0x98, 0x8C, 0xE2, 0xC0, 0xB8, 0x59, 0x54, 0x61,
289 	0x0D, 0x2B, 0xCF, 0x86, 0x64, 0x84, 0x4D, 0xF2,
290 	0xAB, 0x56, 0xE6, 0xC6, 0x1B, 0xB7, 0x01, 0xE4
291 };
292 
293 static TEE_Result tee_rpmb_key_gen(uint16_t dev_id __unused,
294 				   uint8_t *key, uint32_t len)
295 {
296 	TEE_Result res = TEE_SUCCESS;
297 
298 	if (!key || RPMB_KEY_MAC_SIZE != len) {
299 		res = TEE_ERROR_BAD_PARAMETERS;
300 		goto out;
301 	}
302 
303 	DMSG("RPMB: Using test key");
304 	memcpy(key, rpmb_test_key, RPMB_KEY_MAC_SIZE);
305 
306 out:
307 	return res;
308 }
309 
310 #else /* !CFG_RPMB_TESTKEY */
311 
312 static TEE_Result tee_rpmb_key_gen(uint16_t dev_id __unused,
313 				   uint8_t *key, uint32_t len)
314 {
315 	uint8_t message[RPMB_EMMC_CID_SIZE];
316 
317 	if (!key || RPMB_KEY_MAC_SIZE != len)
318 		return TEE_ERROR_BAD_PARAMETERS;
319 
320 	IMSG("RPMB: Using generated key");
321 
322 	/*
323 	 * PRV/CRC would be changed when doing eMMC FFU
324 	 * The following fields should be masked off when deriving RPMB key
325 	 *
326 	 * CID [55: 48]: PRV (Product revision)
327 	 * CID [07: 01]: CRC (CRC7 checksum)
328 	 * CID [00]: not used
329 	 */
330 	memcpy(message, rpmb_ctx->cid, RPMB_EMMC_CID_SIZE);
331 	memset(message + RPMB_CID_PRV_OFFSET, 0, 1);
332 	memset(message + RPMB_CID_CRC_OFFSET, 0, 1);
333 	return huk_subkey_derive(HUK_SUBKEY_RPMB, message, sizeof(message),
334 				 key, len);
335 }
336 
337 #endif /* !CFG_RPMB_TESTKEY */
338 
339 static void u32_to_bytes(uint32_t u32, uint8_t *bytes)
340 {
341 	*bytes = (uint8_t) (u32 >> 24);
342 	*(bytes + 1) = (uint8_t) (u32 >> 16);
343 	*(bytes + 2) = (uint8_t) (u32 >> 8);
344 	*(bytes + 3) = (uint8_t) u32;
345 }
346 
347 static void bytes_to_u32(uint8_t *bytes, uint32_t *u32)
348 {
349 	*u32 = (uint32_t) ((*(bytes) << 24) +
350 			   (*(bytes + 1) << 16) +
351 			   (*(bytes + 2) << 8) + (*(bytes + 3)));
352 }
353 
354 static void u16_to_bytes(uint16_t u16, uint8_t *bytes)
355 {
356 	*bytes = (uint8_t) (u16 >> 8);
357 	*(bytes + 1) = (uint8_t) u16;
358 }
359 
360 static void bytes_to_u16(uint8_t *bytes, uint16_t *u16)
361 {
362 	*u16 = (uint16_t) ((*bytes << 8) + *(bytes + 1));
363 }
364 
365 static void get_op_result_bits(uint8_t *bytes, uint8_t *res)
366 {
367 	*res = *(bytes + 1) & RPMB_RESULT_MASK;
368 }
369 
370 static TEE_Result tee_rpmb_mac_calc(uint8_t *mac, uint32_t macsize,
371 				    uint8_t *key, uint32_t keysize,
372 				    struct rpmb_data_frame *datafrms,
373 				    uint16_t blkcnt)
374 {
375 	TEE_Result res = TEE_ERROR_GENERIC;
376 	int i;
377 	void *ctx = NULL;
378 
379 	if (!mac || !key || !datafrms)
380 		return TEE_ERROR_BAD_PARAMETERS;
381 
382 	res = crypto_mac_alloc_ctx(&ctx, TEE_ALG_HMAC_SHA256);
383 	if (res)
384 		return res;
385 
386 	res = crypto_mac_init(ctx, key, keysize);
387 	if (res != TEE_SUCCESS)
388 		goto func_exit;
389 
390 	for (i = 0; i < blkcnt; i++) {
391 		res = crypto_mac_update(ctx, datafrms[i].data,
392 					RPMB_MAC_PROTECT_DATA_SIZE);
393 		if (res != TEE_SUCCESS)
394 			goto func_exit;
395 	}
396 
397 	res = crypto_mac_final(ctx, mac, macsize);
398 	if (res != TEE_SUCCESS)
399 		goto func_exit;
400 
401 	res = TEE_SUCCESS;
402 
403 func_exit:
404 	crypto_mac_free_ctx(ctx);
405 	return res;
406 }
407 
408 struct tee_rpmb_mem {
409 	struct mobj *phreq_mobj;
410 	struct mobj *phresp_mobj;
411 	size_t req_size;
412 	size_t resp_size;
413 };
414 
415 static void tee_rpmb_free(struct tee_rpmb_mem *mem)
416 {
417 	if (!mem)
418 		return;
419 
420 	if (mem->phreq_mobj) {
421 		thread_rpc_free_payload(mem->phreq_mobj);
422 		mem->phreq_mobj = NULL;
423 	}
424 	if (mem->phresp_mobj) {
425 		thread_rpc_free_payload(mem->phresp_mobj);
426 		mem->phresp_mobj = NULL;
427 	}
428 }
429 
430 
431 static TEE_Result tee_rpmb_alloc(size_t req_size, size_t resp_size,
432 		struct tee_rpmb_mem *mem, void **req, void **resp)
433 {
434 	TEE_Result res = TEE_SUCCESS;
435 	size_t req_s = ROUNDUP(req_size, sizeof(uint32_t));
436 	size_t resp_s = ROUNDUP(resp_size, sizeof(uint32_t));
437 
438 	if (!mem)
439 		return TEE_ERROR_BAD_PARAMETERS;
440 
441 	memset(mem, 0, sizeof(*mem));
442 
443 	mem->phreq_mobj = thread_rpc_alloc_payload(req_s);
444 	mem->phresp_mobj = thread_rpc_alloc_payload(resp_s);
445 
446 	if (!mem->phreq_mobj || !mem->phresp_mobj) {
447 		res = TEE_ERROR_OUT_OF_MEMORY;
448 		goto out;
449 	}
450 
451 	*req = mobj_get_va(mem->phreq_mobj, 0, req_s);
452 	*resp = mobj_get_va(mem->phresp_mobj, 0, resp_s);
453 	if (!*req || !*resp) {
454 		res = TEE_ERROR_GENERIC;
455 		goto out;
456 	}
457 
458 	mem->req_size = req_size;
459 	mem->resp_size = resp_size;
460 
461 out:
462 	if (res != TEE_SUCCESS)
463 		tee_rpmb_free(mem);
464 	return res;
465 }
466 
467 static TEE_Result tee_rpmb_invoke(struct tee_rpmb_mem *mem)
468 {
469 	struct thread_param params[2] = {
470 		[0] = THREAD_PARAM_MEMREF(IN, mem->phreq_mobj, 0,
471 					  mem->req_size),
472 		[1] = THREAD_PARAM_MEMREF(OUT, mem->phresp_mobj, 0,
473 					  mem->resp_size),
474 	};
475 
476 	return thread_rpc_cmd(OPTEE_RPC_CMD_RPMB, 2, params);
477 }
478 
479 static bool is_zero(const uint8_t *buf, size_t size)
480 {
481 	size_t i;
482 
483 	for (i = 0; i < size; i++)
484 		if (buf[i])
485 			return false;
486 	return true;
487 }
488 
489 static TEE_Result encrypt_block(uint8_t *out, const uint8_t *in,
490 				uint16_t blk_idx, const uint8_t *fek,
491 				const TEE_UUID *uuid)
492 {
493 	return tee_fs_crypt_block(uuid, out, in, RPMB_DATA_SIZE,
494 				  blk_idx, fek, TEE_MODE_ENCRYPT);
495 }
496 
497 static TEE_Result decrypt_block(uint8_t *out, const uint8_t *in,
498 				uint16_t blk_idx, const uint8_t *fek,
499 				const TEE_UUID *uuid)
500 {
501 	return tee_fs_crypt_block(uuid, out, in, RPMB_DATA_SIZE,
502 				  blk_idx, fek, TEE_MODE_DECRYPT);
503 }
504 
505 /* Decrypt/copy at most one block of data */
506 static TEE_Result decrypt(uint8_t *out, const struct rpmb_data_frame *frm,
507 			  size_t size, size_t offset,
508 			  uint16_t blk_idx __maybe_unused, const uint8_t *fek,
509 			  const TEE_UUID *uuid)
510 {
511 	uint8_t *tmp __maybe_unused;
512 	TEE_Result res = TEE_SUCCESS;
513 
514 
515 	if ((size + offset < size) || (size + offset > RPMB_DATA_SIZE))
516 		panic("invalid size or offset");
517 
518 	if (!fek) {
519 		/* Block is not encrypted (not a file data block) */
520 		memcpy(out, frm->data + offset, size);
521 	} else if (is_zero(fek, TEE_FS_KM_FEK_SIZE)) {
522 		/* The file was created with encryption disabled */
523 		return TEE_ERROR_SECURITY;
524 	} else {
525 		/* Block is encrypted */
526 		if (size < RPMB_DATA_SIZE) {
527 			/*
528 			 * Since output buffer is not large enough to hold one
529 			 * block we must allocate a temporary buffer.
530 			 */
531 			tmp = malloc(RPMB_DATA_SIZE);
532 			if (!tmp)
533 				return TEE_ERROR_OUT_OF_MEMORY;
534 			res = decrypt_block(tmp, frm->data, blk_idx, fek, uuid);
535 			if (res == TEE_SUCCESS)
536 				memcpy(out, tmp + offset, size);
537 			free(tmp);
538 		} else {
539 			res = decrypt_block(out, frm->data, blk_idx, fek, uuid);
540 		}
541 	}
542 
543 	return res;
544 }
545 
546 static TEE_Result tee_rpmb_req_pack(struct rpmb_req *req,
547 				    struct rpmb_raw_data *rawdata,
548 				    uint16_t nbr_frms, uint16_t dev_id,
549 				    const uint8_t *fek, const TEE_UUID *uuid)
550 {
551 	TEE_Result res = TEE_ERROR_GENERIC;
552 	int i;
553 	struct rpmb_data_frame *datafrm;
554 
555 	if (!req || !rawdata || !nbr_frms)
556 		return TEE_ERROR_BAD_PARAMETERS;
557 
558 	/*
559 	 * Check write blockcount is not bigger than reliable write
560 	 * blockcount.
561 	 */
562 	if ((rawdata->msg_type == RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE) &&
563 	    (nbr_frms > rpmb_ctx->rel_wr_blkcnt)) {
564 		DMSG("wr_blkcnt(%d) > rel_wr_blkcnt(%d)", nbr_frms,
565 		     rpmb_ctx->rel_wr_blkcnt);
566 		return TEE_ERROR_GENERIC;
567 	}
568 
569 	req->cmd = RPMB_CMD_DATA_REQ;
570 	req->dev_id = dev_id;
571 
572 	/* Allocate memory for construct all data packets and calculate MAC. */
573 	datafrm = calloc(nbr_frms, RPMB_DATA_FRAME_SIZE);
574 	if (!datafrm)
575 		return TEE_ERROR_OUT_OF_MEMORY;
576 
577 	for (i = 0; i < nbr_frms; i++) {
578 		u16_to_bytes(rawdata->msg_type, datafrm[i].msg_type);
579 
580 		if (rawdata->block_count)
581 			u16_to_bytes(*rawdata->block_count,
582 				     datafrm[i].block_count);
583 
584 		if (rawdata->blk_idx) {
585 			/* Check the block index is within range. */
586 			if ((*rawdata->blk_idx + nbr_frms - 1) >
587 			    rpmb_ctx->max_blk_idx) {
588 				res = TEE_ERROR_GENERIC;
589 				goto func_exit;
590 			}
591 			u16_to_bytes(*rawdata->blk_idx, datafrm[i].address);
592 		}
593 
594 		if (rawdata->write_counter)
595 			u32_to_bytes(*rawdata->write_counter,
596 				     datafrm[i].write_counter);
597 
598 		if (rawdata->nonce)
599 			memcpy(datafrm[i].nonce, rawdata->nonce,
600 			       RPMB_NONCE_SIZE);
601 
602 		if (rawdata->data) {
603 			if (fek) {
604 				res = encrypt_block(datafrm[i].data,
605 						    rawdata->data +
606 						    (i * RPMB_DATA_SIZE),
607 						    *rawdata->blk_idx + i,
608 						    fek, uuid);
609 				if (res != TEE_SUCCESS)
610 					goto func_exit;
611 			} else {
612 				memcpy(datafrm[i].data,
613 				       rawdata->data + (i * RPMB_DATA_SIZE),
614 				       RPMB_DATA_SIZE);
615 			}
616 		}
617 	}
618 
619 	if (rawdata->key_mac) {
620 		if (rawdata->msg_type == RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE) {
621 			res =
622 			    tee_rpmb_mac_calc(rawdata->key_mac,
623 					      RPMB_KEY_MAC_SIZE, rpmb_ctx->key,
624 					      RPMB_KEY_MAC_SIZE, datafrm,
625 					      nbr_frms);
626 			if (res != TEE_SUCCESS)
627 				goto func_exit;
628 		}
629 		memcpy(datafrm[nbr_frms - 1].key_mac,
630 		       rawdata->key_mac, RPMB_KEY_MAC_SIZE);
631 	}
632 
633 	memcpy(TEE_RPMB_REQ_DATA(req), datafrm,
634 	       nbr_frms * RPMB_DATA_FRAME_SIZE);
635 
636 	if (IS_ENABLED(CFG_RPMB_FS_DEBUG_DATA)) {
637 		for (i = 0; i < nbr_frms; i++) {
638 			DMSG("Dumping data frame %d:", i);
639 			DHEXDUMP((uint8_t *)&datafrm[i] + RPMB_STUFF_DATA_SIZE,
640 				 512 - RPMB_STUFF_DATA_SIZE);
641 		}
642 	}
643 
644 	res = TEE_SUCCESS;
645 func_exit:
646 	free(datafrm);
647 	return res;
648 }
649 
650 static TEE_Result data_cpy_mac_calc_1b(struct rpmb_raw_data *rawdata,
651 				       struct rpmb_data_frame *frm,
652 				       const uint8_t *fek, const TEE_UUID *uuid)
653 {
654 	TEE_Result res;
655 	uint8_t *data;
656 	uint16_t idx;
657 
658 	if (rawdata->len + rawdata->byte_offset > RPMB_DATA_SIZE)
659 		return TEE_ERROR_BAD_PARAMETERS;
660 
661 	res = tee_rpmb_mac_calc(rawdata->key_mac, RPMB_KEY_MAC_SIZE,
662 				rpmb_ctx->key, RPMB_KEY_MAC_SIZE, frm, 1);
663 	if (res != TEE_SUCCESS)
664 		return res;
665 
666 	data = rawdata->data;
667 	bytes_to_u16(frm->address, &idx);
668 
669 	res = decrypt(data, frm, rawdata->len, rawdata->byte_offset, idx, fek,
670 		      uuid);
671 	return res;
672 }
673 
674 static TEE_Result tee_rpmb_data_cpy_mac_calc(struct rpmb_data_frame *datafrm,
675 					     struct rpmb_raw_data *rawdata,
676 					     uint16_t nbr_frms,
677 					     struct rpmb_data_frame *lastfrm,
678 					     const uint8_t *fek,
679 					     const TEE_UUID *uuid)
680 {
681 	TEE_Result res = TEE_ERROR_GENERIC;
682 	int i;
683 	void *ctx = NULL;
684 	uint16_t offset;
685 	uint32_t size;
686 	uint8_t *data;
687 	uint16_t start_idx;
688 	struct rpmb_data_frame localfrm;
689 
690 	if (!datafrm || !rawdata || !nbr_frms || !lastfrm)
691 		return TEE_ERROR_BAD_PARAMETERS;
692 
693 	if (nbr_frms == 1)
694 		return data_cpy_mac_calc_1b(rawdata, lastfrm, fek, uuid);
695 
696 	/* nbr_frms > 1 */
697 
698 	data = rawdata->data;
699 
700 	res = crypto_mac_alloc_ctx(&ctx, TEE_ALG_HMAC_SHA256);
701 	if (res)
702 		goto func_exit;
703 
704 	res = crypto_mac_init(ctx, rpmb_ctx->key, RPMB_KEY_MAC_SIZE);
705 	if (res != TEE_SUCCESS)
706 		goto func_exit;
707 
708 	/*
709 	 * Note: JEDEC JESD84-B51: "In every packet the address is the start
710 	 * address of the full access (not address of the individual half a
711 	 * sector)"
712 	 */
713 	bytes_to_u16(lastfrm->address, &start_idx);
714 
715 	for (i = 0; i < (nbr_frms - 1); i++) {
716 
717 		/*
718 		 * By working on a local copy of the RPMB frame, we ensure that
719 		 * the data can not be modified after the MAC is computed but
720 		 * before the payload is decrypted/copied to the output buffer.
721 		 */
722 		memcpy(&localfrm, &datafrm[i], RPMB_DATA_FRAME_SIZE);
723 
724 		res = crypto_mac_update(ctx, localfrm.data,
725 					RPMB_MAC_PROTECT_DATA_SIZE);
726 		if (res != TEE_SUCCESS)
727 			goto func_exit;
728 
729 		if (i == 0) {
730 			/* First block */
731 			offset = rawdata->byte_offset;
732 			size = RPMB_DATA_SIZE - offset;
733 		} else {
734 			/* Middle blocks */
735 			size = RPMB_DATA_SIZE;
736 			offset = 0;
737 		}
738 
739 		res = decrypt(data, &localfrm, size, offset, start_idx + i,
740 			      fek, uuid);
741 		if (res != TEE_SUCCESS)
742 			goto func_exit;
743 
744 		data += size;
745 	}
746 
747 	/* Last block */
748 	size = (rawdata->len + rawdata->byte_offset) % RPMB_DATA_SIZE;
749 	if (size == 0)
750 		size = RPMB_DATA_SIZE;
751 	res = decrypt(data, lastfrm, size, 0, start_idx + nbr_frms - 1, fek,
752 		      uuid);
753 	if (res != TEE_SUCCESS)
754 		goto func_exit;
755 
756 	/* Update MAC against the last block */
757 	res = crypto_mac_update(ctx, lastfrm->data, RPMB_MAC_PROTECT_DATA_SIZE);
758 	if (res != TEE_SUCCESS)
759 		goto func_exit;
760 
761 	res = crypto_mac_final(ctx, rawdata->key_mac, RPMB_KEY_MAC_SIZE);
762 	if (res != TEE_SUCCESS)
763 		goto func_exit;
764 
765 	res = TEE_SUCCESS;
766 
767 func_exit:
768 	crypto_mac_free_ctx(ctx);
769 	return res;
770 }
771 
772 static TEE_Result tee_rpmb_resp_unpack_verify(struct rpmb_data_frame *datafrm,
773 					      struct rpmb_raw_data *rawdata,
774 					      uint16_t nbr_frms,
775 					      const uint8_t *fek,
776 					      const TEE_UUID *uuid)
777 {
778 	TEE_Result res = TEE_ERROR_GENERIC;
779 	uint16_t msg_type;
780 	uint32_t wr_cnt;
781 	uint16_t blk_idx;
782 	uint8_t op_result;
783 	struct rpmb_data_frame lastfrm;
784 
785 	if (!datafrm || !rawdata || !nbr_frms)
786 		return TEE_ERROR_BAD_PARAMETERS;
787 
788 	if (IS_ENABLED(CFG_RPMB_FS_DEBUG_DATA)) {
789 		size_t i = 0;
790 
791 		for (i = 0; i < nbr_frms; i++) {
792 			DMSG("Dumping data frame %zu:", i);
793 			DHEXDUMP((uint8_t *)&datafrm[i] + RPMB_STUFF_DATA_SIZE,
794 				 512 - RPMB_STUFF_DATA_SIZE);
795 		}
796 	}
797 
798 	/* Make sure the last data packet can't be modified once verified */
799 	memcpy(&lastfrm, &datafrm[nbr_frms - 1], RPMB_DATA_FRAME_SIZE);
800 
801 	/* Handle operation result and translate to TEEC error code. */
802 	get_op_result_bits(lastfrm.op_result, &op_result);
803 	if (op_result == RPMB_RESULT_AUTH_KEY_NOT_PROGRAMMED)
804 		return TEE_ERROR_ITEM_NOT_FOUND;
805 	if (op_result != RPMB_RESULT_OK)
806 		return TEE_ERROR_GENERIC;
807 
808 	/* Check the response msg_type. */
809 	bytes_to_u16(lastfrm.msg_type, &msg_type);
810 	if (msg_type != rawdata->msg_type) {
811 		DMSG("Unexpected msg_type (0x%04x != 0x%04x)", msg_type,
812 		     rawdata->msg_type);
813 		return TEE_ERROR_GENERIC;
814 	}
815 
816 	if (rawdata->blk_idx) {
817 		bytes_to_u16(lastfrm.address, &blk_idx);
818 		if (blk_idx != *rawdata->blk_idx) {
819 			DMSG("Unexpected block index");
820 			return TEE_ERROR_GENERIC;
821 		}
822 	}
823 
824 	if (rawdata->write_counter) {
825 		wr_cnt = *rawdata->write_counter;
826 		bytes_to_u32(lastfrm.write_counter, rawdata->write_counter);
827 		if (msg_type == RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE) {
828 			/* Verify the write counter is incremented by 1 */
829 			if (*rawdata->write_counter != wr_cnt + 1) {
830 				DMSG("Counter mismatched (0x%04x/0x%04x)",
831 				     *rawdata->write_counter, wr_cnt + 1);
832 				return TEE_ERROR_SECURITY;
833 			}
834 			rpmb_ctx->wr_cnt++;
835 		}
836 	}
837 
838 	if (rawdata->nonce) {
839 		if (buf_compare_ct(rawdata->nonce, lastfrm.nonce,
840 				   RPMB_NONCE_SIZE) != 0) {
841 			DMSG("Nonce mismatched");
842 			return TEE_ERROR_SECURITY;
843 		}
844 	}
845 
846 	if (rawdata->key_mac) {
847 		if (msg_type == RPMB_MSG_TYPE_RESP_AUTH_DATA_READ) {
848 			if (!rawdata->data)
849 				return TEE_ERROR_GENERIC;
850 
851 			res = tee_rpmb_data_cpy_mac_calc(datafrm, rawdata,
852 							 nbr_frms, &lastfrm,
853 							 fek, uuid);
854 
855 			if (res != TEE_SUCCESS)
856 				return res;
857 		} else {
858 			/*
859 			 * There should be only one data frame for
860 			 * other msg types.
861 			 */
862 			if (nbr_frms != 1)
863 				return TEE_ERROR_GENERIC;
864 
865 			res = tee_rpmb_mac_calc(rawdata->key_mac,
866 						RPMB_KEY_MAC_SIZE,
867 						rpmb_ctx->key,
868 						RPMB_KEY_MAC_SIZE,
869 						&lastfrm, 1);
870 
871 			if (res != TEE_SUCCESS)
872 				return res;
873 		}
874 
875 		if (consttime_memcmp(rawdata->key_mac,
876 				     (datafrm + nbr_frms - 1)->key_mac,
877 				     RPMB_KEY_MAC_SIZE) != 0) {
878 			DMSG("MAC mismatched:");
879 			if (IS_ENABLED(CFG_RPMB_FS_DEBUG_DATA))
880 				DHEXDUMP(rawdata->key_mac, RPMB_KEY_MAC_SIZE);
881 
882 			return TEE_ERROR_SECURITY;
883 		}
884 	}
885 
886 	return TEE_SUCCESS;
887 }
888 
889 static TEE_Result tee_rpmb_get_dev_info(uint16_t dev_id,
890 					struct rpmb_dev_info *dev_info)
891 {
892 	TEE_Result res = TEE_ERROR_GENERIC;
893 	struct tee_rpmb_mem mem;
894 	struct rpmb_dev_info *di;
895 	struct rpmb_req *req = NULL;
896 	uint8_t *resp = NULL;
897 	uint32_t req_size;
898 	uint32_t resp_size;
899 
900 	if (!dev_info)
901 		return TEE_ERROR_BAD_PARAMETERS;
902 
903 	req_size = sizeof(struct rpmb_req);
904 	resp_size = sizeof(struct rpmb_dev_info);
905 	res = tee_rpmb_alloc(req_size, resp_size, &mem,
906 			     (void *)&req, (void *)&resp);
907 	if (res != TEE_SUCCESS)
908 		goto func_exit;
909 
910 	req->cmd = RPMB_CMD_GET_DEV_INFO;
911 	req->dev_id = dev_id;
912 
913 	di = (struct rpmb_dev_info *)resp;
914 	di->ret_code = RPMB_CMD_GET_DEV_INFO_RET_ERROR;
915 
916 	res = tee_rpmb_invoke(&mem);
917 	if (res != TEE_SUCCESS)
918 		goto func_exit;
919 
920 	if (di->ret_code != RPMB_CMD_GET_DEV_INFO_RET_OK) {
921 		res = TEE_ERROR_GENERIC;
922 		goto func_exit;
923 	}
924 
925 	memcpy((uint8_t *)dev_info, resp, sizeof(struct rpmb_dev_info));
926 
927 	if (IS_ENABLED(CFG_RPMB_FS_DEBUG_DATA)) {
928 		DMSG("Dumping dev_info:");
929 		DHEXDUMP((uint8_t *)dev_info, sizeof(struct rpmb_dev_info));
930 	}
931 
932 	res = TEE_SUCCESS;
933 
934 func_exit:
935 	tee_rpmb_free(&mem);
936 	return res;
937 }
938 
939 static TEE_Result tee_rpmb_init_read_wr_cnt(uint16_t dev_id,
940 					    uint32_t *wr_cnt,
941 					    uint16_t *op_result)
942 {
943 	TEE_Result res = TEE_ERROR_GENERIC;
944 	struct tee_rpmb_mem mem;
945 	uint16_t msg_type;
946 	uint8_t nonce[RPMB_NONCE_SIZE];
947 	uint8_t hmac[RPMB_KEY_MAC_SIZE];
948 	struct rpmb_req *req = NULL;
949 	struct rpmb_data_frame *resp = NULL;
950 	struct rpmb_raw_data rawdata;
951 	uint32_t req_size;
952 	uint32_t resp_size;
953 
954 	if (!wr_cnt)
955 		return TEE_ERROR_BAD_PARAMETERS;
956 
957 	req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE;
958 	resp_size = RPMB_DATA_FRAME_SIZE;
959 	res = tee_rpmb_alloc(req_size, resp_size, &mem,
960 			     (void *)&req, (void *)&resp);
961 	if (res != TEE_SUCCESS)
962 		goto func_exit;
963 
964 	res = crypto_rng_read(nonce, RPMB_NONCE_SIZE);
965 	if (res != TEE_SUCCESS)
966 		goto func_exit;
967 
968 	msg_type = RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ;
969 
970 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
971 	rawdata.msg_type = msg_type;
972 	rawdata.nonce = nonce;
973 
974 	res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL, NULL);
975 	if (res != TEE_SUCCESS)
976 		goto func_exit;
977 
978 	res = tee_rpmb_invoke(&mem);
979 	if (res != TEE_SUCCESS)
980 		goto func_exit;
981 
982 	msg_type = RPMB_MSG_TYPE_RESP_WRITE_COUNTER_VAL_READ;
983 
984 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
985 	rawdata.msg_type = msg_type;
986 	rawdata.op_result = op_result;
987 	rawdata.write_counter = wr_cnt;
988 	rawdata.nonce = nonce;
989 	rawdata.key_mac = hmac;
990 
991 	res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL, NULL);
992 	if (res != TEE_SUCCESS)
993 		goto func_exit;
994 
995 	res = TEE_SUCCESS;
996 
997 func_exit:
998 	tee_rpmb_free(&mem);
999 	return res;
1000 }
1001 
1002 static TEE_Result tee_rpmb_verify_key_sync_counter(uint16_t dev_id)
1003 {
1004 	uint16_t op_result = 0;
1005 	TEE_Result res = TEE_ERROR_GENERIC;
1006 
1007 	res = tee_rpmb_init_read_wr_cnt(dev_id, &rpmb_ctx->wr_cnt,
1008 					&op_result);
1009 
1010 	if (res == TEE_SUCCESS) {
1011 		rpmb_ctx->key_verified = true;
1012 		rpmb_ctx->wr_cnt_synced = true;
1013 	} else
1014 		EMSG("Verify key returning 0x%x", res);
1015 	return res;
1016 }
1017 
1018 #ifdef CFG_RPMB_WRITE_KEY
1019 static TEE_Result tee_rpmb_write_key(uint16_t dev_id)
1020 {
1021 	TEE_Result res = TEE_ERROR_GENERIC;
1022 	struct tee_rpmb_mem mem = { 0 };
1023 	uint16_t msg_type;
1024 	struct rpmb_req *req = NULL;
1025 	struct rpmb_data_frame *resp = NULL;
1026 	struct rpmb_raw_data rawdata;
1027 	uint32_t req_size;
1028 	uint32_t resp_size;
1029 
1030 	req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE;
1031 	resp_size = RPMB_DATA_FRAME_SIZE;
1032 	res = tee_rpmb_alloc(req_size, resp_size, &mem,
1033 			     (void *)&req, (void *)&resp);
1034 	if (res != TEE_SUCCESS)
1035 		goto func_exit;
1036 
1037 	msg_type = RPMB_MSG_TYPE_REQ_AUTH_KEY_PROGRAM;
1038 
1039 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1040 	rawdata.msg_type = msg_type;
1041 	rawdata.key_mac = rpmb_ctx->key;
1042 
1043 	res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL, NULL);
1044 	if (res != TEE_SUCCESS)
1045 		goto func_exit;
1046 
1047 	res = tee_rpmb_invoke(&mem);
1048 	if (res != TEE_SUCCESS)
1049 		goto func_exit;
1050 
1051 	msg_type = RPMB_MSG_TYPE_RESP_AUTH_KEY_PROGRAM;
1052 
1053 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1054 	rawdata.msg_type = msg_type;
1055 
1056 	res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL, NULL);
1057 	if (res != TEE_SUCCESS)
1058 		goto func_exit;
1059 
1060 	res = TEE_SUCCESS;
1061 
1062 func_exit:
1063 	tee_rpmb_free(&mem);
1064 	return res;
1065 }
1066 
1067 static TEE_Result tee_rpmb_write_and_verify_key(uint16_t dev_id)
1068 {
1069 	TEE_Result res;
1070 
1071 	if (!plat_rpmb_key_is_ready()) {
1072 		DMSG("RPMB INIT: platform indicates RPMB key is not ready");
1073 		return TEE_ERROR_BAD_STATE;
1074 	}
1075 
1076 	DMSG("RPMB INIT: Writing Key value:");
1077 	DHEXDUMP(rpmb_ctx->key, RPMB_KEY_MAC_SIZE);
1078 
1079 	res = tee_rpmb_write_key(dev_id);
1080 	if (res == TEE_SUCCESS) {
1081 		DMSG("RPMB INIT: Verifying Key");
1082 		res = tee_rpmb_verify_key_sync_counter(dev_id);
1083 	}
1084 	return res;
1085 }
1086 #else
1087 static TEE_Result tee_rpmb_write_and_verify_key(uint16_t dev_id __unused)
1088 {
1089 	DMSG("RPMB INIT: CFG_RPMB_WRITE_KEY is not set");
1090 	return TEE_ERROR_STORAGE_NOT_AVAILABLE;
1091 }
1092 #endif
1093 
1094 /* This function must never return TEE_SUCCESS if rpmb_ctx == NULL */
1095 static TEE_Result tee_rpmb_init(uint16_t dev_id)
1096 {
1097 	TEE_Result res = TEE_SUCCESS;
1098 	struct rpmb_dev_info dev_info = { };
1099 	uint32_t nblocks = 0;
1100 
1101 	if (rpmb_dead)
1102 		return TEE_ERROR_COMMUNICATION;
1103 
1104 	if (!rpmb_ctx) {
1105 		rpmb_ctx = calloc(1, sizeof(struct tee_rpmb_ctx));
1106 		if (!rpmb_ctx)
1107 			return TEE_ERROR_OUT_OF_MEMORY;
1108 	} else if (rpmb_ctx->dev_id != dev_id) {
1109 		memset(rpmb_ctx, 0x00, sizeof(struct tee_rpmb_ctx));
1110 	}
1111 
1112 	rpmb_ctx->dev_id = dev_id;
1113 
1114 	if (!rpmb_ctx->dev_info_synced) {
1115 		DMSG("RPMB: Syncing device information");
1116 
1117 		dev_info.rpmb_size_mult = 0;
1118 		dev_info.rel_wr_sec_c = 0;
1119 		res = tee_rpmb_get_dev_info(dev_id, &dev_info);
1120 		if (res != TEE_SUCCESS)
1121 			goto func_exit;
1122 
1123 		DMSG("RPMB: RPMB size is %d*128 KB", dev_info.rpmb_size_mult);
1124 		DMSG("RPMB: Reliable Write Sector Count is %d",
1125 		     dev_info.rel_wr_sec_c);
1126 
1127 		if (dev_info.rpmb_size_mult == 0) {
1128 			res = TEE_ERROR_GENERIC;
1129 			goto func_exit;
1130 		}
1131 
1132 		if (MUL_OVERFLOW(dev_info.rpmb_size_mult,
1133 				 RPMB_SIZE_SINGLE / RPMB_DATA_SIZE, &nblocks) ||
1134 		    SUB_OVERFLOW(nblocks, 1, &rpmb_ctx->max_blk_idx)) {
1135 			res = TEE_ERROR_BAD_PARAMETERS;
1136 			goto func_exit;
1137 		}
1138 
1139 		memcpy(rpmb_ctx->cid, dev_info.cid, RPMB_EMMC_CID_SIZE);
1140 
1141 #ifdef RPMB_DRIVER_MULTIPLE_WRITE_FIXED
1142 		rpmb_ctx->rel_wr_blkcnt = dev_info.rel_wr_sec_c * 2;
1143 #else
1144 		rpmb_ctx->rel_wr_blkcnt = 1;
1145 #endif
1146 
1147 		rpmb_ctx->dev_info_synced = true;
1148 	}
1149 
1150 	if (!rpmb_ctx->key_derived) {
1151 		DMSG("RPMB INIT: Deriving key");
1152 
1153 		res = tee_rpmb_key_gen(dev_id, rpmb_ctx->key,
1154 				       RPMB_KEY_MAC_SIZE);
1155 		if (res != TEE_SUCCESS) {
1156 			EMSG("RPMB INIT: Deriving key failed with error 0x%x",
1157 				res);
1158 			goto func_exit;
1159 		}
1160 
1161 		rpmb_ctx->key_derived = true;
1162 	}
1163 
1164 	/* Perform a write counter read to verify if the key is ok. */
1165 	if (!rpmb_ctx->wr_cnt_synced || !rpmb_ctx->key_verified) {
1166 		DMSG("RPMB INIT: Verifying Key");
1167 
1168 		res = tee_rpmb_verify_key_sync_counter(dev_id);
1169 		if (res == TEE_ERROR_ITEM_NOT_FOUND &&
1170 			!rpmb_ctx->key_verified) {
1171 			/*
1172 			 * Need to write the key here and verify it.
1173 			 */
1174 			DMSG("RPMB INIT: Auth key not yet written");
1175 			res = tee_rpmb_write_and_verify_key(dev_id);
1176 		} else if (res != TEE_SUCCESS) {
1177 			EMSG("Verify key failed!");
1178 			EMSG("Make sure key here matches device key");
1179 		}
1180 	}
1181 
1182 func_exit:
1183 	return res;
1184 }
1185 
1186 /*
1187  * Read RPMB data in bytes.
1188  *
1189  * @dev_id     Device ID of the eMMC device.
1190  * @addr       Byte address of data.
1191  * @data       Pointer to the data.
1192  * @len        Size of data in bytes.
1193  * @fek        Encrypted File Encryption Key or NULL.
1194  */
1195 static TEE_Result tee_rpmb_read(uint16_t dev_id, uint32_t addr, uint8_t *data,
1196 				uint32_t len, const uint8_t *fek,
1197 				const TEE_UUID *uuid)
1198 {
1199 	TEE_Result res = TEE_ERROR_GENERIC;
1200 	struct tee_rpmb_mem mem = { 0 };
1201 	uint16_t msg_type;
1202 	uint8_t nonce[RPMB_NONCE_SIZE];
1203 	uint8_t hmac[RPMB_KEY_MAC_SIZE];
1204 	struct rpmb_req *req = NULL;
1205 	struct rpmb_data_frame *resp = NULL;
1206 	struct rpmb_raw_data rawdata;
1207 	uint32_t req_size;
1208 	uint32_t resp_size;
1209 	uint16_t blk_idx;
1210 	uint16_t blkcnt;
1211 	uint8_t byte_offset;
1212 
1213 	if (!data || !len)
1214 		return TEE_ERROR_BAD_PARAMETERS;
1215 
1216 	blk_idx = addr / RPMB_DATA_SIZE;
1217 	byte_offset = addr % RPMB_DATA_SIZE;
1218 
1219 	if (len + byte_offset + RPMB_DATA_SIZE < RPMB_DATA_SIZE) {
1220 		/* Overflow */
1221 		return TEE_ERROR_BAD_PARAMETERS;
1222 	}
1223 	blkcnt =
1224 	    ROUNDUP(len + byte_offset, RPMB_DATA_SIZE) / RPMB_DATA_SIZE;
1225 	res = tee_rpmb_init(dev_id);
1226 	if (res != TEE_SUCCESS)
1227 		goto func_exit;
1228 
1229 	req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE;
1230 	resp_size = RPMB_DATA_FRAME_SIZE * blkcnt;
1231 	res = tee_rpmb_alloc(req_size, resp_size, &mem,
1232 			     (void *)&req, (void *)&resp);
1233 	if (res != TEE_SUCCESS)
1234 		goto func_exit;
1235 
1236 	msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_READ;
1237 	res = crypto_rng_read(nonce, RPMB_NONCE_SIZE);
1238 	if (res != TEE_SUCCESS)
1239 		goto func_exit;
1240 
1241 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1242 	rawdata.msg_type = msg_type;
1243 	rawdata.nonce = nonce;
1244 	rawdata.blk_idx = &blk_idx;
1245 	res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL, NULL);
1246 	if (res != TEE_SUCCESS)
1247 		goto func_exit;
1248 
1249 	req->block_count = blkcnt;
1250 
1251 	DMSG("Read %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""),
1252 	     blk_idx);
1253 
1254 	res = tee_rpmb_invoke(&mem);
1255 	if (res != TEE_SUCCESS)
1256 		goto func_exit;
1257 
1258 	msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_READ;
1259 
1260 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1261 	rawdata.msg_type = msg_type;
1262 	rawdata.block_count = &blkcnt;
1263 	rawdata.blk_idx = &blk_idx;
1264 	rawdata.nonce = nonce;
1265 	rawdata.key_mac = hmac;
1266 	rawdata.data = data;
1267 
1268 	rawdata.len = len;
1269 	rawdata.byte_offset = byte_offset;
1270 
1271 	res = tee_rpmb_resp_unpack_verify(resp, &rawdata, blkcnt, fek, uuid);
1272 	if (res != TEE_SUCCESS)
1273 		goto func_exit;
1274 
1275 	res = TEE_SUCCESS;
1276 
1277 func_exit:
1278 	tee_rpmb_free(&mem);
1279 	return res;
1280 }
1281 
1282 static TEE_Result write_req(uint16_t dev_id, uint16_t blk_idx,
1283 			    const void *data_blks, uint16_t blkcnt,
1284 			    const uint8_t *fek, const TEE_UUID *uuid,
1285 			    struct tee_rpmb_mem *mem, void  *req, void *resp)
1286 {
1287 	TEE_Result res = TEE_SUCCESS;
1288 	uint8_t hmac[RPMB_KEY_MAC_SIZE] = { };
1289 	uint32_t wr_cnt = rpmb_ctx->wr_cnt;
1290 	struct rpmb_raw_data rawdata = { };
1291 	size_t retry_count = 0;
1292 
1293 	assert(mem->req_size <=
1294 	       sizeof(struct rpmb_req) + blkcnt * RPMB_DATA_FRAME_SIZE);
1295 	assert(mem->resp_size <= RPMB_DATA_FRAME_SIZE);
1296 
1297 	while (true) {
1298 		memset(req, 0, mem->req_size);
1299 		memset(resp, 0, mem->resp_size);
1300 
1301 		memset(&rawdata, 0, sizeof(struct rpmb_raw_data));
1302 		rawdata.msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE;
1303 		rawdata.block_count = &blkcnt;
1304 		rawdata.blk_idx = &blk_idx;
1305 		rawdata.write_counter = &wr_cnt;
1306 		rawdata.key_mac = hmac;
1307 		rawdata.data = (uint8_t *)data_blks;
1308 
1309 		res = tee_rpmb_req_pack(req, &rawdata, blkcnt, dev_id, fek,
1310 					uuid);
1311 		if (res) {
1312 			/*
1313 			 * If we haven't tried to send a request yet we can
1314 			 * allow a failure here since there's no chance of
1315 			 * an intercepted request with a valid write
1316 			 * counter.
1317 			 */
1318 			if (!retry_count)
1319 				return res;
1320 
1321 			retry_count++;
1322 			if (retry_count >= RPMB_MAX_RETRIES)
1323 				goto out_of_retries;
1324 
1325 			DMSG("Request pack failed, retrying %zu", retry_count);
1326 			continue;
1327 		}
1328 
1329 		res = tee_rpmb_invoke(mem);
1330 		if (res != TEE_SUCCESS) {
1331 			retry_count++;
1332 			if (retry_count >= RPMB_MAX_RETRIES)
1333 				goto out_of_retries;
1334 			/*
1335 			 * To force wr_cnt sync next time, as it might get
1336 			 * out of sync due to inconsistent operation result!
1337 			 */
1338 			rpmb_ctx->wr_cnt_synced = false;
1339 			DMSG("Write invoke failed, retrying %zu", retry_count);
1340 			continue;
1341 		}
1342 
1343 		memset(&rawdata, 0, sizeof(struct rpmb_raw_data));
1344 		rawdata.msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE;
1345 		rawdata.block_count = &blkcnt;
1346 		rawdata.blk_idx = &blk_idx;
1347 		rawdata.write_counter = &wr_cnt;
1348 		rawdata.key_mac = hmac;
1349 
1350 		res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL,
1351 						  NULL);
1352 		if (res != TEE_SUCCESS) {
1353 			retry_count++;
1354 			if (retry_count >= RPMB_MAX_RETRIES)
1355 				goto out_of_retries;
1356 			/*
1357 			 * To force wr_cnt sync next time, as it might get
1358 			 * out of sync due to inconsistent operation result!
1359 			 */
1360 			rpmb_ctx->wr_cnt_synced = false;
1361 			DMSG("Write resp unpack verify failed, retrying %zu",
1362 			     retry_count);
1363 			continue;
1364 		}
1365 
1366 		return TEE_SUCCESS;
1367 	}
1368 
1369 out_of_retries:
1370 	rpmb_dead = true;
1371 	/*
1372 	 * We're using this error code to cause an eventuall calling TA to
1373 	 * panic since we don't know if the data to be written has been
1374 	 * committed to storage or not.
1375 	 */
1376 	return TEE_ERROR_COMMUNICATION;
1377 }
1378 
1379 static TEE_Result tee_rpmb_write_blk(uint16_t dev_id, uint16_t blk_idx,
1380 				     const uint8_t *data_blks, uint16_t blkcnt,
1381 				     const uint8_t *fek, const TEE_UUID *uuid)
1382 {
1383 	TEE_Result res;
1384 	struct tee_rpmb_mem mem;
1385 	struct rpmb_req *req = NULL;
1386 	struct rpmb_data_frame *resp = NULL;
1387 	uint32_t req_size;
1388 	uint32_t resp_size;
1389 	uint32_t nbr_writes;
1390 	uint16_t tmp_blkcnt;
1391 	uint16_t tmp_blk_idx;
1392 	uint16_t i;
1393 
1394 	DMSG("Write %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""),
1395 	     blk_idx);
1396 
1397 	if (!data_blks || !blkcnt)
1398 		return TEE_ERROR_BAD_PARAMETERS;
1399 
1400 	res = tee_rpmb_init(dev_id);
1401 	if (res != TEE_SUCCESS)
1402 		return res;
1403 
1404 	/*
1405 	 * We need to split data when block count
1406 	 * is bigger than reliable block write count.
1407 	 */
1408 	if (blkcnt < rpmb_ctx->rel_wr_blkcnt)
1409 		req_size = sizeof(struct rpmb_req) +
1410 		    RPMB_DATA_FRAME_SIZE * blkcnt;
1411 	else
1412 		req_size = sizeof(struct rpmb_req) +
1413 		    RPMB_DATA_FRAME_SIZE * rpmb_ctx->rel_wr_blkcnt;
1414 
1415 	resp_size = RPMB_DATA_FRAME_SIZE;
1416 	res = tee_rpmb_alloc(req_size, resp_size, &mem,
1417 			     (void *)&req, (void *)&resp);
1418 	if (res != TEE_SUCCESS)
1419 		return res;
1420 
1421 	nbr_writes = blkcnt / rpmb_ctx->rel_wr_blkcnt;
1422 	if (blkcnt % rpmb_ctx->rel_wr_blkcnt > 0)
1423 		nbr_writes += 1;
1424 
1425 	tmp_blkcnt = rpmb_ctx->rel_wr_blkcnt;
1426 	tmp_blk_idx = blk_idx;
1427 	for (i = 0; i < nbr_writes; i++) {
1428 		size_t offs = i * rpmb_ctx->rel_wr_blkcnt * RPMB_DATA_SIZE;
1429 
1430 		/*
1431 		 * To handle the last write of block count which is
1432 		 * equal or smaller than reliable write block count.
1433 		 */
1434 		if (i == nbr_writes - 1)
1435 			tmp_blkcnt = blkcnt - rpmb_ctx->rel_wr_blkcnt *
1436 			    (nbr_writes - 1);
1437 
1438 		res = write_req(dev_id, tmp_blk_idx, data_blks + offs,
1439 				tmp_blkcnt, fek, uuid, &mem, req, resp);
1440 		if (res)
1441 			goto out;
1442 
1443 
1444 		tmp_blk_idx += tmp_blkcnt;
1445 	}
1446 
1447 out:
1448 	tee_rpmb_free(&mem);
1449 	return res;
1450 }
1451 
1452 static bool tee_rpmb_write_is_atomic(uint16_t dev_id __unused, uint32_t addr,
1453 				     uint32_t len)
1454 {
1455 	uint8_t byte_offset = addr % RPMB_DATA_SIZE;
1456 	uint16_t blkcnt = ROUNDUP(len + byte_offset,
1457 				  RPMB_DATA_SIZE) / RPMB_DATA_SIZE;
1458 
1459 	return (blkcnt <= rpmb_ctx->rel_wr_blkcnt);
1460 }
1461 
1462 /*
1463  * Write RPMB data in bytes.
1464  *
1465  * @dev_id     Device ID of the eMMC device.
1466  * @addr       Byte address of data.
1467  * @data       Pointer to the data.
1468  * @len        Size of data in bytes.
1469  * @fek        Encrypted File Encryption Key or NULL.
1470  */
1471 static TEE_Result tee_rpmb_write(uint16_t dev_id, uint32_t addr,
1472 				 const uint8_t *data, uint32_t len,
1473 				 const uint8_t *fek, const TEE_UUID *uuid)
1474 {
1475 	TEE_Result res = TEE_ERROR_GENERIC;
1476 	uint8_t *data_tmp = NULL;
1477 	uint16_t blk_idx;
1478 	uint16_t blkcnt;
1479 	uint8_t byte_offset;
1480 
1481 	blk_idx = addr / RPMB_DATA_SIZE;
1482 	byte_offset = addr % RPMB_DATA_SIZE;
1483 
1484 	blkcnt =
1485 	    ROUNDUP(len + byte_offset, RPMB_DATA_SIZE) / RPMB_DATA_SIZE;
1486 
1487 	if (byte_offset == 0 && (len % RPMB_DATA_SIZE) == 0) {
1488 		res = tee_rpmb_write_blk(dev_id, blk_idx, data, blkcnt, fek,
1489 					 uuid);
1490 		if (res != TEE_SUCCESS)
1491 			goto func_exit;
1492 	} else {
1493 		data_tmp = calloc(blkcnt, RPMB_DATA_SIZE);
1494 		if (!data_tmp) {
1495 			res = TEE_ERROR_OUT_OF_MEMORY;
1496 			goto func_exit;
1497 		}
1498 
1499 		/* Read the complete blocks */
1500 		res = tee_rpmb_read(dev_id, blk_idx * RPMB_DATA_SIZE, data_tmp,
1501 				    blkcnt * RPMB_DATA_SIZE, fek, uuid);
1502 		if (res != TEE_SUCCESS)
1503 			goto func_exit;
1504 
1505 		/* Partial update of the data blocks */
1506 		memcpy(data_tmp + byte_offset, data, len);
1507 
1508 		res = tee_rpmb_write_blk(dev_id, blk_idx, data_tmp, blkcnt,
1509 					 fek, uuid);
1510 		if (res != TEE_SUCCESS)
1511 			goto func_exit;
1512 	}
1513 
1514 	res = TEE_SUCCESS;
1515 
1516 func_exit:
1517 	free(data_tmp);
1518 	return res;
1519 }
1520 
1521 /*
1522  * Read the RPMB max block.
1523  *
1524  * @dev_id     Device ID of the eMMC device.
1525  * @counter    Pointer to receive the max block.
1526  */
1527 static TEE_Result tee_rpmb_get_max_block(uint16_t dev_id, uint32_t *max_block)
1528 {
1529 	TEE_Result res = TEE_SUCCESS;
1530 
1531 	if (!max_block)
1532 		return TEE_ERROR_BAD_PARAMETERS;
1533 
1534 	if (rpmb_dead)
1535 		return TEE_ERROR_COMMUNICATION;
1536 
1537 	if (!rpmb_ctx || !rpmb_ctx->dev_info_synced) {
1538 		res = tee_rpmb_init(dev_id);
1539 		if (res != TEE_SUCCESS)
1540 			goto func_exit;
1541 	}
1542 
1543 	*max_block = rpmb_ctx->max_blk_idx;
1544 
1545 func_exit:
1546 	return res;
1547 }
1548 
1549 /*
1550  * End of lower interface to RPMB device
1551  */
1552 
1553 static TEE_Result get_fat_start_address(uint32_t *addr);
1554 static TEE_Result rpmb_fs_setup(void);
1555 
1556 /**
1557  * fat_entry_dir_free: Free the FAT entry dir.
1558  */
1559 static void fat_entry_dir_free(void)
1560 {
1561 	if (fat_entry_dir) {
1562 		free(fat_entry_dir->rpmb_fat_entry_buf);
1563 		free(fat_entry_dir);
1564 		fat_entry_dir = NULL;
1565 	}
1566 }
1567 
1568 /**
1569  * fat_entry_dir_init: Initialize the FAT FS entry buffer/cache
1570  * This function must be called before reading FAT FS entries using the
1571  * function fat_entry_dir_get_next. This initializes the buffer/cache with the
1572  * first FAT FS entries.
1573  */
1574 static TEE_Result fat_entry_dir_init(void)
1575 {
1576 	TEE_Result res = TEE_ERROR_GENERIC;
1577 	struct rpmb_fat_entry *fe = NULL;
1578 	uint32_t fat_address = 0;
1579 	uint32_t num_elems_read = 0;
1580 
1581 	if (fat_entry_dir)
1582 		return TEE_SUCCESS;
1583 
1584 	res = rpmb_fs_setup();
1585 	if (res)
1586 		return res;
1587 
1588 	res = get_fat_start_address(&fat_address);
1589 	if (res)
1590 		return res;
1591 
1592 	fat_entry_dir = calloc(1, sizeof(struct rpmb_fat_entry_dir));
1593 	if (!fat_entry_dir)
1594 		return TEE_ERROR_OUT_OF_MEMORY;
1595 
1596 	/*
1597 	 * If caching is enabled, read in up to the maximum cache size, but
1598 	 * never more than the single read in size. Otherwise, read in as many
1599 	 * entries fit into the temporary buffer.
1600 	 */
1601 	if (CFG_RPMB_FS_CACHE_ENTRIES)
1602 		num_elems_read = MIN(CFG_RPMB_FS_CACHE_ENTRIES,
1603 				     CFG_RPMB_FS_RD_ENTRIES);
1604 	else
1605 		num_elems_read = CFG_RPMB_FS_RD_ENTRIES;
1606 
1607 	/*
1608 	 * Allocate memory for the FAT FS entries to read in.
1609 	 */
1610 	fe = calloc(num_elems_read, sizeof(struct rpmb_fat_entry));
1611 	if (!fe) {
1612 		res = TEE_ERROR_OUT_OF_MEMORY;
1613 		goto out;
1614 	}
1615 
1616 	res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address, (uint8_t *)fe,
1617 			    num_elems_read * sizeof(*fe), NULL, NULL);
1618 	if (res)
1619 		goto out;
1620 
1621 	fat_entry_dir->rpmb_fat_entry_buf = fe;
1622 
1623 	/*
1624 	 * We use this variable when getting next entries from the buffer/cache
1625 	 * to see whether we have to read in more entries from storage.
1626 	 */
1627 	fat_entry_dir->num_buffered = num_elems_read;
1628 
1629 	return TEE_SUCCESS;
1630 out:
1631 	fat_entry_dir_free();
1632 	free(fe);
1633 	return res;
1634 }
1635 
1636 /**
1637  * fat_entry_dir_deinit: If caching is enabled, free the temporary buffer for
1638  * FAT FS entries in case the cache was too small. Keep the elements in the
1639  * cache. Reset the counter variables to start the next traversal from fresh
1640  * from the first cached entry. If caching is disabled, just free the
1641  * temporary buffer by calling fat_entry_dir_free and return.
1642  */
1643 static void fat_entry_dir_deinit(void)
1644 {
1645 	struct rpmb_fat_entry *fe = NULL;
1646 
1647 	if (!fat_entry_dir)
1648 		return;
1649 
1650 	if (!CFG_RPMB_FS_CACHE_ENTRIES) {
1651 		fat_entry_dir_free();
1652 		return;
1653 	}
1654 
1655 	fe = fat_entry_dir->rpmb_fat_entry_buf;
1656 	fat_entry_dir->idx_curr = 0;
1657 	fat_entry_dir->num_total_read = 0;
1658 	fat_entry_dir->last_reached = false;
1659 
1660 	if (fat_entry_dir->num_buffered > CFG_RPMB_FS_CACHE_ENTRIES) {
1661 		fat_entry_dir->num_buffered = CFG_RPMB_FS_CACHE_ENTRIES;
1662 
1663 		fe = realloc(fe, fat_entry_dir->num_buffered * sizeof(*fe));
1664 
1665 		/*
1666 		 * In case realloc fails, we are on the safe side if we destroy
1667 		 * the whole structure. Upon the next init, the cache has to be
1668 		 * re-established, but this case should not happen in practice.
1669 		 */
1670 		if (!fe)
1671 			fat_entry_dir_free();
1672 		else
1673 			fat_entry_dir->rpmb_fat_entry_buf = fe;
1674 	}
1675 }
1676 
1677 /**
1678  * fat_entry_dir_update: Updates a persisted FAT FS entry in the cache.
1679  * This function updates the FAT entry fat_entry that was written to address
1680  * fat_address onto RPMB storage in the cache.
1681  */
1682 static TEE_Result __maybe_unused fat_entry_dir_update
1683 					(struct rpmb_fat_entry *fat_entry,
1684 					 uint32_t fat_address)
1685 {
1686 	uint32_t fat_entry_buf_idx = 0;
1687 	/* Use a temp var to avoid compiler warning if caching disabled. */
1688 	uint32_t max_cache_entries = CFG_RPMB_FS_CACHE_ENTRIES;
1689 
1690 	assert(!((fat_address - RPMB_FS_FAT_START_ADDRESS) %
1691 	       sizeof(struct rpmb_fat_entry)));
1692 
1693 	/* Nothing to update if the cache is not initialized. */
1694 	if (!fat_entry_dir)
1695 		return TEE_SUCCESS;
1696 
1697 	fat_entry_buf_idx = (fat_address - RPMB_FS_FAT_START_ADDRESS) /
1698 			     sizeof(struct rpmb_fat_entry);
1699 
1700 	/* Only need to write if index points to an entry in cache. */
1701 	if (fat_entry_buf_idx < fat_entry_dir->num_buffered &&
1702 	    fat_entry_buf_idx < max_cache_entries) {
1703 		memcpy(fat_entry_dir->rpmb_fat_entry_buf + fat_entry_buf_idx,
1704 		       fat_entry, sizeof(struct rpmb_fat_entry));
1705 	}
1706 
1707 	return TEE_SUCCESS;
1708 }
1709 
1710 /**
1711  * fat_entry_dir_get_next: Get next FAT FS entry.
1712  * Read either from cache/buffer, or by reading from RPMB storage if the
1713  * elements in the buffer/cache are fully read. When reading in from RPMB
1714  * storage, the buffer is overwritten in case caching is disabled.
1715  * In case caching is enabled, the cache is either further filled, or a
1716  * temporary buffer populated if the cache is already full.
1717  * The FAT FS entry is written to fat_entry. The respective address in RPMB
1718  * storage is written to fat_address, if not NULL. When the last FAT FS entry
1719  * was previously read, the function indicates this case by writing a NULL
1720  * pointer to fat_entry.
1721  * Returns a value different TEE_SUCCESS if the next FAT FS entry could not be
1722  * retrieved.
1723  */
1724 static TEE_Result fat_entry_dir_get_next(struct rpmb_fat_entry **fat_entry,
1725 					 uint32_t *fat_address)
1726 {
1727 	TEE_Result res = TEE_ERROR_GENERIC;
1728 	struct rpmb_fat_entry *fe = NULL;
1729 	uint32_t num_elems_read = 0;
1730 	uint32_t fat_address_local = 0;
1731 
1732 	assert(fat_entry_dir && fat_entry);
1733 
1734 	/* Don't read further if we previously read the last FAT FS entry. */
1735 	if (fat_entry_dir->last_reached) {
1736 		*fat_entry = NULL;
1737 		return TEE_SUCCESS;
1738 	}
1739 
1740 	fe = fat_entry_dir->rpmb_fat_entry_buf;
1741 
1742 	/* Determine address of FAT FS entry in RPMB storage. */
1743 	fat_address_local = RPMB_FS_FAT_START_ADDRESS +
1744 			(fat_entry_dir->num_total_read *
1745 			sizeof(struct rpmb_fat_entry));
1746 
1747 	/*
1748 	 * We've read all so-far buffered elements, so we need to
1749 	 * read in more entries from RPMB storage.
1750 	 */
1751 	if (fat_entry_dir->idx_curr >= fat_entry_dir->num_buffered) {
1752 		/*
1753 		 * This is the case where we do not cache entries, so just read
1754 		 * in next set of FAT FS entries into the buffer.
1755 		 * Goto the end of the when statement if that is done.
1756 		 */
1757 		if (!CFG_RPMB_FS_CACHE_ENTRIES) {
1758 			num_elems_read = CFG_RPMB_FS_RD_ENTRIES;
1759 			fat_entry_dir->idx_curr = 0;
1760 
1761 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
1762 					    fat_address_local, (uint8_t *)fe,
1763 					    num_elems_read * sizeof(*fe), NULL,
1764 					    NULL);
1765 			if (res)
1766 				return res;
1767 			goto post_read_in;
1768 		}
1769 
1770 		/*
1771 		 * We cache FAT FS entries, and the buffer is not completely
1772 		 * filled. Further keep on extending the buffer up to its max
1773 		 * size by reading in from RPMB.
1774 		 */
1775 		if (fat_entry_dir->num_total_read < RPMB_BUF_MAX_ENTRIES) {
1776 			/*
1777 			 * Read at most as many elements as fit in the buffer
1778 			 * and no more than the defined number of entries to
1779 			 * read in at once.
1780 			 */
1781 			num_elems_read = MIN(RPMB_BUF_MAX_ENTRIES -
1782 					     fat_entry_dir->num_total_read,
1783 					     (uint32_t)CFG_RPMB_FS_RD_ENTRIES);
1784 
1785 			/*
1786 			 * Expand the buffer to fit in the additional entries.
1787 			 */
1788 			fe = realloc(fe,
1789 				     (fat_entry_dir->num_buffered +
1790 				      num_elems_read) * sizeof(*fe));
1791 			if (!fe)
1792 				return TEE_ERROR_OUT_OF_MEMORY;
1793 
1794 			fat_entry_dir->rpmb_fat_entry_buf = fe;
1795 
1796 			/* Read in to the next free slot in the buffer/cache. */
1797 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
1798 					    fat_address_local,
1799 					    (uint8_t *)(fe +
1800 					    fat_entry_dir->num_total_read),
1801 					    num_elems_read * sizeof(*fe),
1802 					    NULL, NULL);
1803 			if (res)
1804 				return res;
1805 
1806 			fat_entry_dir->num_buffered += num_elems_read;
1807 		} else {
1808 			/*
1809 			 * This happens when we have read as many elements as
1810 			 * can possibly fit into the buffer.
1811 			 * As the first part of the buffer serves as our cache,
1812 			 * we only overwrite the last part that serves as our
1813 			 * temporary buffer used to iteratively read in entries
1814 			 * when the cache is full. Read in the temporary buffer
1815 			 * maximum size.
1816 			 */
1817 			num_elems_read = CFG_RPMB_FS_RD_ENTRIES;
1818 			/* Reset index to beginning of the temporary buffer. */
1819 			fat_entry_dir->idx_curr = CFG_RPMB_FS_CACHE_ENTRIES;
1820 
1821 			/* Read in elements after the end of the cache. */
1822 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
1823 					    fat_address_local,
1824 					    (uint8_t *)(fe +
1825 					    fat_entry_dir->idx_curr),
1826 					    num_elems_read * sizeof(*fe),
1827 					    NULL, NULL);
1828 			if (res)
1829 				return res;
1830 		}
1831 	}
1832 
1833 post_read_in:
1834 	if (fat_address)
1835 		*fat_address = fat_address_local;
1836 
1837 	*fat_entry = fe + fat_entry_dir->idx_curr;
1838 
1839 	fat_entry_dir->idx_curr++;
1840 	fat_entry_dir->num_total_read++;
1841 
1842 	/*
1843 	 * Indicate last entry was read.
1844 	 * Ensures we return a zero value for fat_entry on next invocation.
1845 	 */
1846 	if ((*fat_entry)->flags & FILE_IS_LAST_ENTRY)
1847 		fat_entry_dir->last_reached = true;
1848 
1849 	return TEE_SUCCESS;
1850 }
1851 
1852 #if (TRACE_LEVEL >= TRACE_FLOW)
1853 static void dump_fat(void)
1854 {
1855 	TEE_Result res = TEE_ERROR_SECURITY;
1856 	struct rpmb_fat_entry *fe = NULL;
1857 
1858 	if (!fs_par)
1859 		return;
1860 
1861 	if (fat_entry_dir_init())
1862 		return;
1863 
1864 	while (true) {
1865 		res = fat_entry_dir_get_next(&fe, NULL);
1866 		if (res || !fe)
1867 			break;
1868 
1869 		FMSG("flags %#"PRIx32", size %"PRIu32", address %#"PRIx32
1870 		     ", filename '%s'",
1871 		     fe->flags, fe->data_size, fe->start_address, fe->filename);
1872 	}
1873 
1874 	fat_entry_dir_deinit();
1875 }
1876 #else
1877 static void dump_fat(void)
1878 {
1879 }
1880 #endif
1881 
1882 #if (TRACE_LEVEL >= TRACE_DEBUG)
1883 static void dump_fh(struct rpmb_file_handle *fh)
1884 {
1885 	DMSG("fh->filename=%s", fh->filename);
1886 	DMSG("fh->rpmb_fat_address=%u", fh->rpmb_fat_address);
1887 	DMSG("fh->fat_entry.start_address=%u", fh->fat_entry.start_address);
1888 	DMSG("fh->fat_entry.data_size=%u", fh->fat_entry.data_size);
1889 }
1890 #else
1891 static void dump_fh(struct rpmb_file_handle *fh __unused)
1892 {
1893 }
1894 #endif
1895 
1896 /* "/TA_uuid/object_id" or "/TA_uuid/.object_id" */
1897 static TEE_Result create_filename(void *buf, size_t blen, struct tee_pobj *po,
1898 				  bool transient)
1899 {
1900 	uint8_t *file = buf;
1901 	uint32_t pos = 0;
1902 	uint32_t hslen = 1 /* Leading slash */
1903 			+ TEE_B2HS_HSBUF_SIZE(sizeof(TEE_UUID) + po->obj_id_len)
1904 			+ 1; /* Intermediate slash */
1905 
1906 	/* +1 for the '.' (temporary persistent object) */
1907 	if (transient)
1908 		hslen++;
1909 
1910 	if (blen < hslen)
1911 		return TEE_ERROR_SHORT_BUFFER;
1912 
1913 	file[pos++] = '/';
1914 	pos += tee_b2hs((uint8_t *)&po->uuid, &file[pos],
1915 			sizeof(TEE_UUID), hslen);
1916 	file[pos++] = '/';
1917 
1918 	if (transient)
1919 		file[pos++] = '.';
1920 
1921 	tee_b2hs(po->obj_id, file + pos, po->obj_id_len, hslen - pos);
1922 
1923 	return TEE_SUCCESS;
1924 }
1925 
1926 /* "/TA_uuid" */
1927 static TEE_Result create_dirname(void *buf, size_t blen, const TEE_UUID *uuid)
1928 {
1929 	uint8_t *dir = buf;
1930 	uint32_t hslen = TEE_B2HS_HSBUF_SIZE(sizeof(TEE_UUID)) + 1;
1931 
1932 	if (blen < hslen)
1933 		return TEE_ERROR_SHORT_BUFFER;
1934 
1935 	dir[0] = '/';
1936 	tee_b2hs((uint8_t *)uuid, dir + 1, sizeof(TEE_UUID), hslen);
1937 
1938 	return TEE_SUCCESS;
1939 }
1940 
1941 static struct rpmb_file_handle *alloc_file_handle(struct tee_pobj *po,
1942 						  bool temporary)
1943 {
1944 	struct rpmb_file_handle *fh = NULL;
1945 
1946 	fh = calloc(1, sizeof(struct rpmb_file_handle));
1947 	if (!fh)
1948 		return NULL;
1949 
1950 	if (po)
1951 		create_filename(fh->filename, sizeof(fh->filename), po,
1952 				temporary);
1953 
1954 	return fh;
1955 }
1956 
1957 /**
1958  * write_fat_entry: Store info in a fat_entry to RPMB.
1959  */
1960 static TEE_Result write_fat_entry(struct rpmb_file_handle *fh)
1961 {
1962 	TEE_Result res = TEE_ERROR_GENERIC;
1963 
1964 	/* Protect partition data. */
1965 	if (fh->rpmb_fat_address < sizeof(struct rpmb_fs_partition)) {
1966 		res = TEE_ERROR_ACCESS_CONFLICT;
1967 		goto out;
1968 	}
1969 
1970 	if (fh->rpmb_fat_address % sizeof(struct rpmb_fat_entry) != 0) {
1971 		res = TEE_ERROR_BAD_PARAMETERS;
1972 		goto out;
1973 	}
1974 
1975 	res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, fh->rpmb_fat_address,
1976 			     (uint8_t *)&fh->fat_entry,
1977 			     sizeof(struct rpmb_fat_entry), NULL, NULL);
1978 
1979 	dump_fat();
1980 
1981 	/* If caching enabled, update a successfully written entry in cache. */
1982 	if (CFG_RPMB_FS_CACHE_ENTRIES && !res)
1983 		res = fat_entry_dir_update(&fh->fat_entry,
1984 					   fh->rpmb_fat_address);
1985 
1986 out:
1987 	return res;
1988 }
1989 
1990 /**
1991  * rpmb_fs_setup: Setup RPMB FS.
1992  * Set initial partition and FS values and write to RPMB.
1993  * Store frequently used data in RAM.
1994  */
1995 static TEE_Result rpmb_fs_setup(void)
1996 {
1997 	TEE_Result res = TEE_ERROR_GENERIC;
1998 	struct rpmb_fs_partition *partition_data = NULL;
1999 	struct rpmb_file_handle *fh = NULL;
2000 	uint32_t max_rpmb_block = 0;
2001 
2002 	if (fs_par) {
2003 		res = TEE_SUCCESS;
2004 		goto out;
2005 	}
2006 
2007 	res = tee_rpmb_get_max_block(CFG_RPMB_FS_DEV_ID, &max_rpmb_block);
2008 	if (res != TEE_SUCCESS)
2009 		goto out;
2010 
2011 	/*
2012 	 * We're going to read a full block in order to have a full block
2013 	 * for the dummy write below.
2014 	 */
2015 	COMPILE_TIME_ASSERT(sizeof(struct rpmb_fs_partition) <=
2016 			    RPMB_DATA_SIZE);
2017 	partition_data = calloc(1, RPMB_DATA_SIZE);
2018 	if (!partition_data) {
2019 		res = TEE_ERROR_OUT_OF_MEMORY;
2020 		goto out;
2021 	}
2022 
2023 	res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS,
2024 			    (uint8_t *)partition_data, RPMB_DATA_SIZE,
2025 			    NULL, NULL);
2026 	if (res != TEE_SUCCESS)
2027 		goto out;
2028 	/*
2029 	 * Perform a write in order to increase the write counter. This
2030 	 * prevents late usage (replay attack) of a previously blocked
2031 	 * request with a valid write counter value.
2032 	 */
2033 	res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS,
2034 			     (uint8_t *)partition_data, RPMB_DATA_SIZE,
2035 			     NULL, NULL);
2036 	if (res != TEE_SUCCESS)
2037 		goto out;
2038 	/*
2039 	 * We're reading again in case a stale request was committed
2040 	 * instead of the one issued above. If this succeeds we're in sync
2041 	 * with the RPMB block since there are no other possible stale
2042 	 * blocks with valid write counters available.
2043 	 */
2044 	res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS,
2045 			    (uint8_t *)partition_data,
2046 			    sizeof(struct rpmb_fs_partition), NULL, NULL);
2047 	if (res != TEE_SUCCESS)
2048 		goto out;
2049 
2050 #ifndef CFG_RPMB_RESET_FAT
2051 	if (partition_data->rpmb_fs_magic == RPMB_FS_MAGIC) {
2052 		if (partition_data->fs_version == FS_VERSION) {
2053 			res = TEE_SUCCESS;
2054 			goto store_fs_par;
2055 		} else {
2056 			EMSG("Wrong software is in use.");
2057 			res = TEE_ERROR_ACCESS_DENIED;
2058 			goto out;
2059 		}
2060 	}
2061 #else
2062 	EMSG("**** Clearing Storage ****");
2063 #endif
2064 
2065 	/* Setup new partition data. */
2066 	partition_data->rpmb_fs_magic = RPMB_FS_MAGIC;
2067 	partition_data->fs_version = FS_VERSION;
2068 	partition_data->fat_start_address = RPMB_FS_FAT_START_ADDRESS;
2069 
2070 	/* Initial FAT entry with FILE_IS_LAST_ENTRY flag set. */
2071 	fh = alloc_file_handle(NULL, false);
2072 	if (!fh) {
2073 		res = TEE_ERROR_OUT_OF_MEMORY;
2074 		goto out;
2075 	}
2076 	fh->fat_entry.flags = FILE_IS_LAST_ENTRY;
2077 	fh->rpmb_fat_address = partition_data->fat_start_address;
2078 
2079 	/* Write init FAT entry and partition data to RPMB. */
2080 	res = write_fat_entry(fh);
2081 	if (res != TEE_SUCCESS)
2082 		goto out;
2083 
2084 	res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS,
2085 			     (uint8_t *)partition_data,
2086 			     sizeof(struct rpmb_fs_partition), NULL, NULL);
2087 
2088 #ifndef CFG_RPMB_RESET_FAT
2089 store_fs_par:
2090 #endif
2091 
2092 	/* Store FAT start address. */
2093 	fs_par = calloc(1, sizeof(struct rpmb_fs_parameters));
2094 	if (!fs_par) {
2095 		res = TEE_ERROR_OUT_OF_MEMORY;
2096 		goto out;
2097 	}
2098 
2099 	fs_par->fat_start_address = partition_data->fat_start_address;
2100 	fs_par->max_rpmb_address = max_rpmb_block << RPMB_BLOCK_SIZE_SHIFT;
2101 
2102 	dump_fat();
2103 
2104 out:
2105 	free(fh);
2106 	free(partition_data);
2107 	return res;
2108 }
2109 
2110 /**
2111  * get_fat_start_address:
2112  * FAT start_address from fs_par.
2113  */
2114 static TEE_Result get_fat_start_address(uint32_t *addr)
2115 {
2116 	if (!fs_par)
2117 		return TEE_ERROR_NO_DATA;
2118 
2119 	*addr = fs_par->fat_start_address;
2120 
2121 	return TEE_SUCCESS;
2122 }
2123 
2124 /**
2125  * read_fat: Read FAT entries
2126  * Return matching FAT entry for read, rm rename and stat.
2127  * Build up memory pool and return matching entry for write operation.
2128  * "Last FAT entry" can be returned during write.
2129  */
2130 static TEE_Result read_fat(struct rpmb_file_handle *fh, tee_mm_pool_t *p)
2131 {
2132 	TEE_Result res = TEE_ERROR_GENERIC;
2133 	tee_mm_entry_t *mm = NULL;
2134 	struct rpmb_fat_entry *fe = NULL;
2135 	uint32_t fat_address;
2136 	bool entry_found = false;
2137 	bool expand_fat = false;
2138 	struct rpmb_file_handle last_fh;
2139 
2140 	DMSG("fat_address %d", fh->rpmb_fat_address);
2141 
2142 	res = fat_entry_dir_init();
2143 	if (res)
2144 		goto out;
2145 
2146 	/*
2147 	 * The pool is used to represent the current RPMB layout. To find
2148 	 * a slot for the file tee_mm_alloc is called on the pool. Thus
2149 	 * if it is not NULL the entire FAT must be traversed to fill in
2150 	 * the pool.
2151 	 */
2152 	while (true) {
2153 		res = fat_entry_dir_get_next(&fe, &fat_address);
2154 		if (res || !fe)
2155 			break;
2156 
2157 		/*
2158 		 * Look for an entry, matching filenames. (read, rm,
2159 		 * rename and stat.). Only store first filename match.
2160 		 */
2161 		if ((!strcmp(fh->filename, fe->filename)) &&
2162 		    (fe->flags & FILE_IS_ACTIVE) && !entry_found) {
2163 			entry_found = true;
2164 			fh->rpmb_fat_address = fat_address;
2165 			memcpy(&fh->fat_entry, fe, sizeof(*fe));
2166 			if (!p)
2167 				break;
2168 		}
2169 
2170 		/* Add existing files to memory pool. (write) */
2171 		if (p) {
2172 			if ((fe->flags & FILE_IS_ACTIVE) && fe->data_size > 0) {
2173 
2174 				mm = tee_mm_alloc2(p, fe->start_address,
2175 						   fe->data_size);
2176 				if (!mm) {
2177 					res = TEE_ERROR_OUT_OF_MEMORY;
2178 					goto out;
2179 				}
2180 			}
2181 
2182 			/* Unused FAT entries can be reused (write) */
2183 			if (((fe->flags & FILE_IS_ACTIVE) == 0) &&
2184 			    fh->rpmb_fat_address == 0) {
2185 				fh->rpmb_fat_address = fat_address;
2186 				memcpy(&fh->fat_entry, fe,
2187 				       sizeof(struct rpmb_fat_entry));
2188 			}
2189 
2190 			if (((fe->flags & FILE_IS_LAST_ENTRY) != 0) &&
2191 			    fh->rpmb_fat_address == fat_address) {
2192 
2193 				/*
2194 				 * If the last entry was reached and was chosen
2195 				 * by the previous check, then the FAT needs to
2196 				 * be expanded.
2197 				 * fh->rpmb_fat_address is the address chosen
2198 				 * to store the files FAT entry and fat_address
2199 				 * is the current FAT entry address being
2200 				 * compared.
2201 				 */
2202 				expand_fat = true;
2203 			}
2204 		}
2205 	}
2206 
2207 	if (res)
2208 		goto out;
2209 	/*
2210 	 * Represent the FAT table in the pool.
2211 	 */
2212 	if (p) {
2213 		/*
2214 		 * Since fat_address is the start of the last entry it needs to
2215 		 * be moved up by an entry.
2216 		 */
2217 		fat_address += sizeof(struct rpmb_fat_entry);
2218 
2219 		/* Make room for yet a FAT entry and add to memory pool. */
2220 		if (expand_fat)
2221 			fat_address += sizeof(struct rpmb_fat_entry);
2222 
2223 		mm = tee_mm_alloc2(p, RPMB_STORAGE_START_ADDRESS, fat_address);
2224 		if (!mm) {
2225 			res = TEE_ERROR_OUT_OF_MEMORY;
2226 			goto out;
2227 		}
2228 
2229 		if (expand_fat) {
2230 			/*
2231 			 * Point fat_address to the beginning of the new
2232 			 * entry.
2233 			 */
2234 			fat_address -= sizeof(struct rpmb_fat_entry);
2235 			memset(&last_fh, 0, sizeof(last_fh));
2236 			last_fh.fat_entry.flags = FILE_IS_LAST_ENTRY;
2237 			last_fh.rpmb_fat_address = fat_address;
2238 			res = write_fat_entry(&last_fh);
2239 			if (res != TEE_SUCCESS)
2240 				goto out;
2241 		}
2242 	}
2243 
2244 	if (!fh->rpmb_fat_address)
2245 		res = TEE_ERROR_ITEM_NOT_FOUND;
2246 
2247 out:
2248 	fat_entry_dir_deinit();
2249 	return res;
2250 }
2251 
2252 static TEE_Result generate_fek(struct rpmb_fat_entry *fe, const TEE_UUID *uuid)
2253 {
2254 	TEE_Result res;
2255 
2256 again:
2257 	res = tee_fs_generate_fek(uuid, fe->fek, sizeof(fe->fek));
2258 	if (res != TEE_SUCCESS)
2259 		return res;
2260 
2261 	if (is_zero(fe->fek, sizeof(fe->fek)))
2262 		goto again;
2263 
2264 	return res;
2265 }
2266 
2267 static TEE_Result rpmb_fs_open_internal(struct rpmb_file_handle *fh,
2268 					const TEE_UUID *uuid, bool create)
2269 {
2270 	tee_mm_pool_t p;
2271 	bool pool_result;
2272 	paddr_size_t pool_sz = 0;
2273 	TEE_Result res = TEE_ERROR_GENERIC;
2274 
2275 	/* We need to do setup in order to make sure fs_par is filled in */
2276 	res = rpmb_fs_setup();
2277 	if (res != TEE_SUCCESS)
2278 		goto out;
2279 
2280 	fh->uuid = uuid;
2281 	if (create) {
2282 		/* Upper memory allocation must be used for RPMB_FS. */
2283 		pool_sz = fs_par->max_rpmb_address - RPMB_STORAGE_START_ADDRESS;
2284 		pool_result = tee_mm_init(&p,
2285 					  RPMB_STORAGE_START_ADDRESS,
2286 					  pool_sz,
2287 					  RPMB_BLOCK_SIZE_SHIFT,
2288 					  TEE_MM_POOL_HI_ALLOC);
2289 
2290 		if (!pool_result) {
2291 			res = TEE_ERROR_OUT_OF_MEMORY;
2292 			goto out;
2293 		}
2294 
2295 		res = read_fat(fh, &p);
2296 		tee_mm_final(&p);
2297 		if (res != TEE_SUCCESS)
2298 			goto out;
2299 	} else {
2300 		res = read_fat(fh, NULL);
2301 		if (res != TEE_SUCCESS)
2302 			goto out;
2303 	}
2304 
2305 	/*
2306 	 * If this is opened with create and the entry found was not active
2307 	 * then this is a new file and the FAT entry must be written
2308 	 */
2309 	if (create) {
2310 		if ((fh->fat_entry.flags & FILE_IS_ACTIVE) == 0) {
2311 			memset(&fh->fat_entry, 0,
2312 				sizeof(struct rpmb_fat_entry));
2313 			memcpy(fh->fat_entry.filename, fh->filename,
2314 				strlen(fh->filename));
2315 			/* Start address and size are 0 */
2316 			fh->fat_entry.flags = FILE_IS_ACTIVE;
2317 
2318 			res = generate_fek(&fh->fat_entry, uuid);
2319 			if (res != TEE_SUCCESS)
2320 				goto out;
2321 			DMSG("GENERATE FEK key: %p",
2322 			     (void *)fh->fat_entry.fek);
2323 			DHEXDUMP(fh->fat_entry.fek, sizeof(fh->fat_entry.fek));
2324 
2325 			res = write_fat_entry(fh);
2326 			if (res != TEE_SUCCESS)
2327 				goto out;
2328 		}
2329 	}
2330 
2331 	res = TEE_SUCCESS;
2332 
2333 out:
2334 	return res;
2335 }
2336 
2337 static void rpmb_fs_close(struct tee_file_handle **tfh)
2338 {
2339 	struct rpmb_file_handle *fh = (struct rpmb_file_handle *)*tfh;
2340 
2341 	free(fh);
2342 	*tfh = NULL;
2343 }
2344 
2345 static TEE_Result rpmb_fs_read(struct tee_file_handle *tfh, size_t pos,
2346 			       void *buf_core, void *buf_user, size_t *len)
2347 {
2348 	TEE_Result res;
2349 	struct rpmb_file_handle *fh = (struct rpmb_file_handle *)tfh;
2350 	size_t size = *len;
2351 
2352 	/* One of buf_core and buf_user must be NULL */
2353 	assert(!buf_core || !buf_user);
2354 
2355 	if (!size)
2356 		return TEE_SUCCESS;
2357 
2358 	mutex_lock(&rpmb_mutex);
2359 
2360 	dump_fh(fh);
2361 
2362 	res = read_fat(fh, NULL);
2363 	if (res != TEE_SUCCESS)
2364 		goto out;
2365 
2366 	if (pos >= fh->fat_entry.data_size) {
2367 		*len = 0;
2368 		goto out;
2369 	}
2370 
2371 	size = MIN(size, fh->fat_entry.data_size - pos);
2372 	if (size) {
2373 		if (buf_core) {
2374 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2375 					    fh->fat_entry.start_address + pos,
2376 					    buf_core, size, fh->fat_entry.fek,
2377 					    fh->uuid);
2378 			if (res != TEE_SUCCESS)
2379 				goto out;
2380 		} else if (buf_user) {
2381 			uint32_t f = TEE_MEMORY_ACCESS_WRITE;
2382 
2383 			res = check_user_access(f, buf_user, size);
2384 			if (res)
2385 				goto out;
2386 			enter_user_access();
2387 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2388 					    fh->fat_entry.start_address + pos,
2389 					    buf_user, size, fh->fat_entry.fek,
2390 					    fh->uuid);
2391 			exit_user_access();
2392 			if (res)
2393 				goto out;
2394 		}
2395 	}
2396 	*len = size;
2397 
2398 out:
2399 	mutex_unlock(&rpmb_mutex);
2400 	return res;
2401 }
2402 
2403 static TEE_Result update_write_helper(struct rpmb_file_handle *fh,
2404 				      size_t pos, const void *buf,
2405 				      size_t size, uintptr_t new_fat,
2406 				      size_t new_size)
2407 {
2408 	uintptr_t old_fat = fh->fat_entry.start_address;
2409 	size_t old_size = fh->fat_entry.data_size;
2410 	const uint8_t *rem_buf = buf;
2411 	size_t rem_size = size;
2412 	uint8_t *blk_buf = NULL;
2413 	size_t blk_offset = 0;
2414 	size_t blk_size = 0;
2415 	TEE_Result res = TEE_SUCCESS;
2416 
2417 	blk_buf = mempool_alloc(mempool_default, TMP_BLOCK_SIZE);
2418 	if (!blk_buf)
2419 		return TEE_ERROR_OUT_OF_MEMORY;
2420 
2421 	while (blk_offset < new_size) {
2422 		uint8_t *copy_dst = blk_buf;
2423 		size_t copy_size = 0;
2424 		size_t rd_size = 0;
2425 
2426 		blk_size = MIN(TMP_BLOCK_SIZE, new_size - blk_offset);
2427 		memset(blk_buf, 0, blk_size);
2428 
2429 		/* Possibly read old RPMB data in temporary buffer */
2430 		if (blk_offset < pos && blk_offset < old_size) {
2431 			rd_size = MIN(blk_size, old_size - blk_offset);
2432 
2433 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2434 					    old_fat + blk_offset, blk_buf,
2435 					    rd_size, fh->fat_entry.fek,
2436 					    fh->uuid);
2437 			if (res != TEE_SUCCESS)
2438 				break;
2439 		}
2440 
2441 		/* Possibly update data in temporary buffer */
2442 		if ((blk_offset + TMP_BLOCK_SIZE > pos) &&
2443 		    (blk_offset < pos + size)) {
2444 			size_t offset = 0;
2445 
2446 			copy_dst = blk_buf;
2447 			copy_size = TMP_BLOCK_SIZE;
2448 
2449 			if (blk_offset < pos) {
2450 				offset = pos - blk_offset;
2451 
2452 				copy_dst += offset;
2453 				copy_size -= offset;
2454 			}
2455 			copy_size = MIN(copy_size, rem_size);
2456 
2457 			memcpy(copy_dst, rem_buf, copy_size);
2458 			rem_buf += copy_size;
2459 			rem_size -= copy_size;
2460 		}
2461 
2462 		/* Write temporary buffer to new RPMB destination */
2463 		res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, new_fat + blk_offset,
2464 				     blk_buf, blk_size,
2465 				     fh->fat_entry.fek, fh->uuid);
2466 		if (res != TEE_SUCCESS)
2467 			break;
2468 
2469 		blk_offset += blk_size;
2470 	}
2471 
2472 	mempool_free(mempool_default, blk_buf);
2473 
2474 	return res;
2475 }
2476 
2477 static TEE_Result rpmb_fs_write_primitive(struct rpmb_file_handle *fh,
2478 					  size_t pos, const void *buf,
2479 					  size_t size)
2480 {
2481 	TEE_Result res = TEE_ERROR_GENERIC;
2482 	tee_mm_pool_t p = { };
2483 	bool pool_result = false;
2484 	size_t end = 0;
2485 	uint32_t start_addr = 0;
2486 	paddr_size_t pool_sz = 0;
2487 
2488 	if (!size)
2489 		return TEE_SUCCESS;
2490 
2491 	if (!fs_par) {
2492 		res = TEE_ERROR_GENERIC;
2493 		goto out;
2494 	}
2495 
2496 	dump_fh(fh);
2497 
2498 	/* Upper memory allocation must be used for RPMB_FS. */
2499 	pool_sz = fs_par->max_rpmb_address - RPMB_STORAGE_START_ADDRESS;
2500 	pool_result = tee_mm_init(&p,
2501 				  RPMB_STORAGE_START_ADDRESS,
2502 				  pool_sz,
2503 				  RPMB_BLOCK_SIZE_SHIFT,
2504 				  TEE_MM_POOL_HI_ALLOC);
2505 	if (!pool_result) {
2506 		res = TEE_ERROR_OUT_OF_MEMORY;
2507 		goto out;
2508 	}
2509 
2510 	res = read_fat(fh, &p);
2511 	if (res != TEE_SUCCESS)
2512 		goto out;
2513 
2514 	if (fh->fat_entry.flags & FILE_IS_LAST_ENTRY)
2515 		panic("invalid last entry flag");
2516 
2517 	if (ADD_OVERFLOW(pos, size, &end)) {
2518 		res = TEE_ERROR_BAD_PARAMETERS;
2519 		goto out;
2520 	}
2521 	if (ADD_OVERFLOW(fh->fat_entry.start_address, pos, &start_addr)) {
2522 		res = TEE_ERROR_BAD_PARAMETERS;
2523 		goto out;
2524 	}
2525 
2526 	if (end <= fh->fat_entry.data_size &&
2527 	    tee_rpmb_write_is_atomic(CFG_RPMB_FS_DEV_ID, start_addr, size)) {
2528 
2529 		DMSG("Updating data in-place");
2530 		res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, start_addr, buf,
2531 				     size, fh->fat_entry.fek, fh->uuid);
2532 	} else {
2533 		/*
2534 		 * File must be extended, or update cannot be atomic: allocate,
2535 		 * read, update, write.
2536 		 */
2537 		size_t new_size = MAX(end, fh->fat_entry.data_size);
2538 		tee_mm_entry_t *mm = tee_mm_alloc(&p, new_size);
2539 		uintptr_t new_fat_entry = 0;
2540 
2541 		DMSG("Need to re-allocate");
2542 		if (!mm) {
2543 			DMSG("RPMB: No space left");
2544 			res = TEE_ERROR_STORAGE_NO_SPACE;
2545 			goto out;
2546 		}
2547 
2548 		new_fat_entry = tee_mm_get_smem(mm);
2549 
2550 		res = update_write_helper(fh, pos, buf, size,
2551 					  new_fat_entry, new_size);
2552 		if (res == TEE_SUCCESS) {
2553 			fh->fat_entry.data_size = new_size;
2554 			fh->fat_entry.start_address = new_fat_entry;
2555 
2556 			res = write_fat_entry(fh);
2557 		}
2558 	}
2559 
2560 out:
2561 	if (pool_result)
2562 		tee_mm_final(&p);
2563 
2564 	return res;
2565 }
2566 
2567 static TEE_Result rpmb_fs_write(struct tee_file_handle *tfh, size_t pos,
2568 				const void *buf_core, const void *buf_user,
2569 				size_t size)
2570 {
2571 	TEE_Result res = TEE_SUCCESS;
2572 
2573 	/* One of buf_core and buf_user must be NULL */
2574 	assert(!buf_core || !buf_user);
2575 
2576 	if (!size)
2577 		return TEE_SUCCESS;
2578 
2579 	mutex_lock(&rpmb_mutex);
2580 	if (buf_core) {
2581 		res = rpmb_fs_write_primitive((struct rpmb_file_handle *)tfh,
2582 					      pos, buf_core, size);
2583 	} else if (buf_user) {
2584 		uint32_t f = TEE_MEMORY_ACCESS_READ;
2585 
2586 		res = check_user_access(f, buf_user, size);
2587 		if (res)
2588 			goto out;
2589 		enter_user_access();
2590 		res = rpmb_fs_write_primitive((struct rpmb_file_handle *)tfh,
2591 					      pos, buf_user, size);
2592 		exit_user_access();
2593 	}
2594 out:
2595 	mutex_unlock(&rpmb_mutex);
2596 
2597 	return res;
2598 }
2599 
2600 static TEE_Result rpmb_fs_remove_internal(struct rpmb_file_handle *fh)
2601 {
2602 	TEE_Result res;
2603 
2604 	res = read_fat(fh, NULL);
2605 	if (res)
2606 		return res;
2607 
2608 	/* Clear this file entry. */
2609 	memset(&fh->fat_entry, 0, sizeof(struct rpmb_fat_entry));
2610 	return write_fat_entry(fh);
2611 }
2612 
2613 static TEE_Result rpmb_fs_remove(struct tee_pobj *po)
2614 {
2615 	TEE_Result res;
2616 	struct rpmb_file_handle *fh = alloc_file_handle(po, po->temporary);
2617 
2618 	if (!fh)
2619 		return TEE_ERROR_OUT_OF_MEMORY;
2620 
2621 	mutex_lock(&rpmb_mutex);
2622 
2623 	res = rpmb_fs_remove_internal(fh);
2624 
2625 	mutex_unlock(&rpmb_mutex);
2626 
2627 	free(fh);
2628 	return res;
2629 }
2630 
2631 static  TEE_Result rpmb_fs_rename_internal(struct tee_pobj *old,
2632 					   struct tee_pobj *new,
2633 					   bool overwrite)
2634 {
2635 	TEE_Result res = TEE_ERROR_GENERIC;
2636 	struct rpmb_file_handle *fh_old = NULL;
2637 	struct rpmb_file_handle *fh_new = NULL;
2638 
2639 	if (!old) {
2640 		res = TEE_ERROR_BAD_PARAMETERS;
2641 		goto out;
2642 	}
2643 
2644 	if (new)
2645 		fh_old = alloc_file_handle(old, old->temporary);
2646 	else
2647 		fh_old = alloc_file_handle(old, true);
2648 	if (!fh_old) {
2649 		res = TEE_ERROR_OUT_OF_MEMORY;
2650 		goto out;
2651 	}
2652 
2653 	if (new)
2654 		fh_new = alloc_file_handle(new, new->temporary);
2655 	else
2656 		fh_new = alloc_file_handle(old, false);
2657 	if (!fh_new) {
2658 		res = TEE_ERROR_OUT_OF_MEMORY;
2659 		goto out;
2660 	}
2661 
2662 	res = read_fat(fh_old, NULL);
2663 	if (res != TEE_SUCCESS)
2664 		goto out;
2665 
2666 	res = read_fat(fh_new, NULL);
2667 	if (res == TEE_SUCCESS) {
2668 		if (!overwrite) {
2669 			res = TEE_ERROR_ACCESS_CONFLICT;
2670 			goto out;
2671 		}
2672 
2673 		/* Clear this file entry. */
2674 		memset(&fh_new->fat_entry, 0, sizeof(struct rpmb_fat_entry));
2675 		res = write_fat_entry(fh_new);
2676 		if (res != TEE_SUCCESS)
2677 			goto out;
2678 	}
2679 
2680 	memset(fh_old->fat_entry.filename, 0, TEE_RPMB_FS_FILENAME_LENGTH);
2681 	memcpy(fh_old->fat_entry.filename, fh_new->filename,
2682 	       strlen(fh_new->filename));
2683 
2684 	res = write_fat_entry(fh_old);
2685 
2686 out:
2687 	free(fh_old);
2688 	free(fh_new);
2689 
2690 	return res;
2691 }
2692 
2693 static  TEE_Result rpmb_fs_rename(struct tee_pobj *old, struct tee_pobj *new,
2694 				  bool overwrite)
2695 {
2696 	TEE_Result res;
2697 
2698 	mutex_lock(&rpmb_mutex);
2699 	res = rpmb_fs_rename_internal(old, new, overwrite);
2700 	mutex_unlock(&rpmb_mutex);
2701 
2702 	return res;
2703 }
2704 
2705 static TEE_Result rpmb_fs_truncate(struct tee_file_handle *tfh, size_t length)
2706 {
2707 	struct rpmb_file_handle *fh = (struct rpmb_file_handle *)tfh;
2708 	tee_mm_pool_t p;
2709 	bool pool_result = false;
2710 	tee_mm_entry_t *mm;
2711 	uint32_t newsize;
2712 	uint8_t *newbuf = NULL;
2713 	uintptr_t newaddr;
2714 	TEE_Result res = TEE_ERROR_GENERIC;
2715 	paddr_size_t pool_sz = 0;
2716 
2717 	mutex_lock(&rpmb_mutex);
2718 
2719 	if (length > INT32_MAX) {
2720 		res = TEE_ERROR_BAD_PARAMETERS;
2721 		goto out;
2722 	}
2723 	newsize = length;
2724 
2725 	res = read_fat(fh, NULL);
2726 	if (res != TEE_SUCCESS)
2727 		goto out;
2728 
2729 	if (newsize > fh->fat_entry.data_size) {
2730 		/* Extend file */
2731 
2732 		pool_sz = fs_par->max_rpmb_address - RPMB_STORAGE_START_ADDRESS;
2733 		pool_result = tee_mm_init(&p,
2734 					  RPMB_STORAGE_START_ADDRESS,
2735 					  pool_sz,
2736 					  RPMB_BLOCK_SIZE_SHIFT,
2737 					  TEE_MM_POOL_HI_ALLOC);
2738 		if (!pool_result) {
2739 			res = TEE_ERROR_OUT_OF_MEMORY;
2740 			goto out;
2741 		}
2742 		res = read_fat(fh, &p);
2743 		if (res != TEE_SUCCESS)
2744 			goto out;
2745 
2746 		mm = tee_mm_alloc(&p, newsize);
2747 		newbuf = calloc(1, newsize);
2748 		if (!mm || !newbuf) {
2749 			res = TEE_ERROR_OUT_OF_MEMORY;
2750 			goto out;
2751 		}
2752 
2753 		if (fh->fat_entry.data_size) {
2754 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2755 					    fh->fat_entry.start_address,
2756 					    newbuf, fh->fat_entry.data_size,
2757 					    fh->fat_entry.fek, fh->uuid);
2758 			if (res != TEE_SUCCESS)
2759 				goto out;
2760 		}
2761 
2762 		newaddr = tee_mm_get_smem(mm);
2763 		res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf,
2764 				     newsize, fh->fat_entry.fek, fh->uuid);
2765 		if (res != TEE_SUCCESS)
2766 			goto out;
2767 
2768 	} else {
2769 		/* Don't change file location */
2770 		newaddr = fh->fat_entry.start_address;
2771 	}
2772 
2773 	/* fh->pos is unchanged */
2774 	fh->fat_entry.data_size = newsize;
2775 	fh->fat_entry.start_address = newaddr;
2776 	res = write_fat_entry(fh);
2777 
2778 out:
2779 	mutex_unlock(&rpmb_mutex);
2780 	if (pool_result)
2781 		tee_mm_final(&p);
2782 	if (newbuf)
2783 		free(newbuf);
2784 
2785 	return res;
2786 }
2787 
2788 static void rpmb_fs_dir_free(struct tee_fs_dir *dir)
2789 {
2790 	struct tee_rpmb_fs_dirent *e;
2791 
2792 	if (!dir)
2793 		return;
2794 
2795 	free(dir->current);
2796 
2797 	while ((e = SIMPLEQ_FIRST(&dir->next))) {
2798 		SIMPLEQ_REMOVE_HEAD(&dir->next, link);
2799 		free(e);
2800 	}
2801 }
2802 
2803 static TEE_Result rpmb_fs_dir_populate(const char *path,
2804 				       struct tee_fs_dir *dir)
2805 {
2806 	struct tee_rpmb_fs_dirent *current = NULL;
2807 	struct rpmb_fat_entry *fe = NULL;
2808 	uint32_t fat_address;
2809 	uint32_t filelen;
2810 	char *filename;
2811 	bool matched;
2812 	struct tee_rpmb_fs_dirent *next = NULL;
2813 	uint32_t pathlen;
2814 	TEE_Result res = TEE_ERROR_GENERIC;
2815 	char temp;
2816 
2817 	mutex_lock(&rpmb_mutex);
2818 
2819 	res = fat_entry_dir_init();
2820 	if (res)
2821 		goto out;
2822 
2823 	pathlen = strlen(path);
2824 
2825 	while (true) {
2826 		res = fat_entry_dir_get_next(&fe, &fat_address);
2827 		if (res || !fe)
2828 			break;
2829 
2830 		filename = fe->filename;
2831 		if (fe->flags & FILE_IS_ACTIVE) {
2832 			matched = false;
2833 			filelen = strlen(filename);
2834 			if (filelen > pathlen) {
2835 				temp = filename[pathlen];
2836 				filename[pathlen] = '\0';
2837 				if (strcmp(filename, path) == 0)
2838 					matched = true;
2839 
2840 				filename[pathlen] = temp;
2841 			}
2842 
2843 			if (matched) {
2844 				next = malloc(sizeof(*next));
2845 				if (!next) {
2846 					res = TEE_ERROR_OUT_OF_MEMORY;
2847 					goto out;
2848 				}
2849 
2850 				next->entry.oidlen = tee_hs2b((uint8_t *)
2851 						&filename[pathlen],
2852 						next->entry.oid,
2853 						filelen - pathlen,
2854 						sizeof(next->entry.oid));
2855 				if (next->entry.oidlen) {
2856 					SIMPLEQ_INSERT_TAIL(&dir->next,
2857 							    next, link);
2858 					current = next;
2859 				} else {
2860 					free(next);
2861 					next = NULL;
2862 				}
2863 			}
2864 		}
2865 	}
2866 
2867 	if (res)
2868 		goto out;
2869 
2870 	if (current)
2871 		res = TEE_SUCCESS;
2872 	else
2873 		res = TEE_ERROR_ITEM_NOT_FOUND; /* No directories were found. */
2874 
2875 out:
2876 	mutex_unlock(&rpmb_mutex);
2877 	fat_entry_dir_deinit();
2878 	if (res)
2879 		rpmb_fs_dir_free(dir);
2880 
2881 	return res;
2882 }
2883 
2884 static TEE_Result rpmb_fs_opendir(const TEE_UUID *uuid, struct tee_fs_dir **dir)
2885 {
2886 	uint32_t len;
2887 	char path_local[TEE_RPMB_FS_FILENAME_LENGTH];
2888 	TEE_Result res = TEE_ERROR_GENERIC;
2889 	struct tee_fs_dir *rpmb_dir = NULL;
2890 
2891 	if (!uuid || !dir) {
2892 		res = TEE_ERROR_BAD_PARAMETERS;
2893 		goto out;
2894 	}
2895 
2896 	memset(path_local, 0, sizeof(path_local));
2897 	if (create_dirname(path_local, sizeof(path_local) - 1, uuid)) {
2898 		res = TEE_ERROR_BAD_PARAMETERS;
2899 		goto out;
2900 	}
2901 	len = strlen(path_local);
2902 
2903 	/* Add a slash to correctly match the full directory name. */
2904 	if (path_local[len - 1] != '/')
2905 		path_local[len] = '/';
2906 
2907 	rpmb_dir = calloc(1, sizeof(*rpmb_dir));
2908 	if (!rpmb_dir) {
2909 		res = TEE_ERROR_OUT_OF_MEMORY;
2910 		goto out;
2911 	}
2912 	SIMPLEQ_INIT(&rpmb_dir->next);
2913 
2914 	res = rpmb_fs_dir_populate(path_local, rpmb_dir);
2915 	if (res != TEE_SUCCESS) {
2916 		free(rpmb_dir);
2917 		rpmb_dir = NULL;
2918 		goto out;
2919 	}
2920 
2921 	*dir = rpmb_dir;
2922 
2923 out:
2924 	return res;
2925 }
2926 
2927 static TEE_Result rpmb_fs_readdir(struct tee_fs_dir *dir,
2928 				  struct tee_fs_dirent **ent)
2929 {
2930 	if (!dir)
2931 		return TEE_ERROR_GENERIC;
2932 
2933 	free(dir->current);
2934 
2935 	dir->current = SIMPLEQ_FIRST(&dir->next);
2936 	if (!dir->current)
2937 		return TEE_ERROR_ITEM_NOT_FOUND;
2938 
2939 	SIMPLEQ_REMOVE_HEAD(&dir->next, link);
2940 
2941 	*ent = &dir->current->entry;
2942 	return TEE_SUCCESS;
2943 }
2944 
2945 static void rpmb_fs_closedir(struct tee_fs_dir *dir)
2946 {
2947 	if (dir) {
2948 		rpmb_fs_dir_free(dir);
2949 		free(dir);
2950 	}
2951 }
2952 
2953 static TEE_Result rpmb_fs_open(struct tee_pobj *po, size_t *size,
2954 			       struct tee_file_handle **ret_fh)
2955 {
2956 	TEE_Result res;
2957 	struct rpmb_file_handle *fh = alloc_file_handle(po, po->temporary);
2958 
2959 	if (!fh)
2960 		return TEE_ERROR_OUT_OF_MEMORY;
2961 
2962 	mutex_lock(&rpmb_mutex);
2963 
2964 	res = rpmb_fs_open_internal(fh, &po->uuid, false);
2965 	if (!res && size)
2966 		*size = fh->fat_entry.data_size;
2967 
2968 	mutex_unlock(&rpmb_mutex);
2969 
2970 	if (res)
2971 		free(fh);
2972 	else
2973 		*ret_fh = (struct tee_file_handle *)fh;
2974 
2975 	return res;
2976 }
2977 
2978 static TEE_Result rpmb_fs_create(struct tee_pobj *po, bool overwrite,
2979 				 const void *head, size_t head_size,
2980 				 const void *attr, size_t attr_size,
2981 				 const void *data_core, const void *data_user,
2982 				 size_t data_size,
2983 				 struct tee_file_handle **ret_fh)
2984 {
2985 	TEE_Result res;
2986 	size_t pos = 0;
2987 	struct rpmb_file_handle *fh = alloc_file_handle(po, po->temporary);
2988 
2989 	/* One of data_core and data_user must be NULL */
2990 	assert(!data_core || !data_user);
2991 
2992 	if (!fh)
2993 		return TEE_ERROR_OUT_OF_MEMORY;
2994 
2995 	mutex_lock(&rpmb_mutex);
2996 	res = rpmb_fs_open_internal(fh, &po->uuid, true);
2997 	if (res)
2998 		goto out;
2999 
3000 	if (head && head_size) {
3001 		res = rpmb_fs_write_primitive(fh, pos, head, head_size);
3002 		if (res)
3003 			goto out;
3004 		pos += head_size;
3005 	}
3006 
3007 	if (attr && attr_size) {
3008 		res = rpmb_fs_write_primitive(fh, pos, attr, attr_size);
3009 		if (res)
3010 			goto out;
3011 		pos += attr_size;
3012 	}
3013 
3014 	if (data_size) {
3015 		if (data_core) {
3016 			res = rpmb_fs_write_primitive(fh, pos, data_core,
3017 						      data_size);
3018 			if (res)
3019 				goto out;
3020 		} else if (data_user) {
3021 			uint32_t f = TEE_MEMORY_ACCESS_READ |
3022 				     TEE_MEMORY_ACCESS_ANY_OWNER;
3023 
3024 			res = check_user_access(f, data_user, data_size);
3025 			if (res)
3026 				goto out;
3027 			enter_user_access();
3028 			res = rpmb_fs_write_primitive(fh, pos, data_user,
3029 						      data_size);
3030 			exit_user_access();
3031 			if (res)
3032 				goto out;
3033 		}
3034 	}
3035 
3036 	if (po->temporary) {
3037 		/*
3038 		 * If it's a temporary filename (which it normally is)
3039 		 * rename into the final filename now that the file is
3040 		 * fully initialized.
3041 		 */
3042 		po->temporary = false;
3043 		res = rpmb_fs_rename_internal(po, NULL, overwrite);
3044 		if (res) {
3045 			po->temporary = true;
3046 			goto out;
3047 		}
3048 		/* Update file handle after rename. */
3049 		create_filename(fh->filename, sizeof(fh->filename), po, false);
3050 	}
3051 
3052 out:
3053 	if (res) {
3054 		rpmb_fs_remove_internal(fh);
3055 		free(fh);
3056 	} else {
3057 		*ret_fh = (struct tee_file_handle *)fh;
3058 	}
3059 	mutex_unlock(&rpmb_mutex);
3060 
3061 	return res;
3062 }
3063 
3064 const struct tee_file_operations rpmb_fs_ops = {
3065 	.open = rpmb_fs_open,
3066 	.create = rpmb_fs_create,
3067 	.close = rpmb_fs_close,
3068 	.read = rpmb_fs_read,
3069 	.write = rpmb_fs_write,
3070 	.truncate = rpmb_fs_truncate,
3071 	.rename = rpmb_fs_rename,
3072 	.remove = rpmb_fs_remove,
3073 	.opendir = rpmb_fs_opendir,
3074 	.closedir = rpmb_fs_closedir,
3075 	.readdir = rpmb_fs_readdir,
3076 };
3077 
3078 TEE_Result tee_rpmb_fs_raw_open(const char *fname, bool create,
3079 				struct tee_file_handle **ret_fh)
3080 {
3081 	TEE_Result res;
3082 	struct rpmb_file_handle *fh = calloc(1, sizeof(*fh));
3083 	static const TEE_UUID uuid = { 0 };
3084 
3085 	if (!fh)
3086 		return TEE_ERROR_OUT_OF_MEMORY;
3087 
3088 	snprintf(fh->filename, sizeof(fh->filename), "/%s", fname);
3089 
3090 	mutex_lock(&rpmb_mutex);
3091 
3092 	res = rpmb_fs_open_internal(fh, &uuid, create);
3093 
3094 	mutex_unlock(&rpmb_mutex);
3095 
3096 	if (res) {
3097 		if (create)
3098 			rpmb_fs_remove_internal(fh);
3099 		free(fh);
3100 	} else {
3101 		*ret_fh = (struct tee_file_handle *)fh;
3102 	}
3103 
3104 	return res;
3105 }
3106 
3107 bool __weak plat_rpmb_key_is_ready(void)
3108 {
3109 	return true;
3110 }
3111