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