xref: /optee_os/core/tee/tee_rpmb_fs.c (revision 3d3b05918ec9052ba13de82fbcaba204766eb636)
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_rpc_cmd.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 	struct mobj *phresp_mobj;
414 	size_t req_size;
415 	size_t resp_size;
416 };
417 
418 static void tee_rpmb_free(struct tee_rpmb_mem *mem)
419 {
420 	if (!mem)
421 		return;
422 
423 	if (mem->phreq_mobj) {
424 		thread_rpc_free_payload(mem->phreq_mobj);
425 		mem->phreq_mobj = NULL;
426 	}
427 	if (mem->phresp_mobj) {
428 		thread_rpc_free_payload(mem->phresp_mobj);
429 		mem->phresp_mobj = NULL;
430 	}
431 }
432 
433 
434 static TEE_Result tee_rpmb_alloc(size_t req_size, size_t resp_size,
435 		struct tee_rpmb_mem *mem, void **req, void **resp)
436 {
437 	TEE_Result res = TEE_SUCCESS;
438 	size_t req_s = ROUNDUP(req_size, sizeof(uint32_t));
439 	size_t resp_s = ROUNDUP(resp_size, sizeof(uint32_t));
440 
441 	if (!mem)
442 		return TEE_ERROR_BAD_PARAMETERS;
443 
444 	memset(mem, 0, sizeof(*mem));
445 
446 	mem->phreq_mobj = thread_rpc_alloc_payload(req_s);
447 	mem->phresp_mobj = thread_rpc_alloc_payload(resp_s);
448 
449 	if (!mem->phreq_mobj || !mem->phresp_mobj) {
450 		res = TEE_ERROR_OUT_OF_MEMORY;
451 		goto out;
452 	}
453 
454 	*req = mobj_get_va(mem->phreq_mobj, 0);
455 	*resp = mobj_get_va(mem->phresp_mobj, 0);
456 	if (!*req || !*resp) {
457 		res = TEE_ERROR_GENERIC;
458 		goto out;
459 	}
460 
461 	mem->req_size = req_size;
462 	mem->resp_size = resp_size;
463 
464 out:
465 	if (res != TEE_SUCCESS)
466 		tee_rpmb_free(mem);
467 	return res;
468 }
469 
470 static TEE_Result tee_rpmb_invoke(struct tee_rpmb_mem *mem)
471 {
472 	struct thread_param params[2] = {
473 		[0] = THREAD_PARAM_MEMREF(IN, mem->phreq_mobj, 0,
474 					  mem->req_size),
475 		[1] = THREAD_PARAM_MEMREF(OUT, mem->phresp_mobj, 0,
476 					  mem->resp_size),
477 	};
478 
479 	return thread_rpc_cmd(OPTEE_RPC_CMD_RPMB, 2, params);
480 }
481 
482 static bool is_zero(const uint8_t *buf, size_t size)
483 {
484 	size_t i;
485 
486 	for (i = 0; i < size; i++)
487 		if (buf[i])
488 			return false;
489 	return true;
490 }
491 
492 static TEE_Result encrypt_block(uint8_t *out, const uint8_t *in,
493 				uint16_t blk_idx, const uint8_t *fek,
494 				const TEE_UUID *uuid)
495 {
496 	return tee_fs_crypt_block(uuid, out, in, RPMB_DATA_SIZE,
497 				  blk_idx, fek, TEE_MODE_ENCRYPT);
498 }
499 
500 static TEE_Result decrypt_block(uint8_t *out, const uint8_t *in,
501 				uint16_t blk_idx, const uint8_t *fek,
502 				const TEE_UUID *uuid)
503 {
504 	return tee_fs_crypt_block(uuid, out, in, RPMB_DATA_SIZE,
505 				  blk_idx, fek, TEE_MODE_DECRYPT);
506 }
507 
508 /* Decrypt/copy at most one block of data */
509 static TEE_Result decrypt(uint8_t *out, const struct rpmb_data_frame *frm,
510 			  size_t size, size_t offset,
511 			  uint16_t blk_idx __maybe_unused, const uint8_t *fek,
512 			  const TEE_UUID *uuid)
513 {
514 	uint8_t *tmp __maybe_unused;
515 
516 
517 	if ((size + offset < size) || (size + offset > RPMB_DATA_SIZE))
518 		panic("invalid size or offset");
519 
520 	if (!fek) {
521 		/* Block is not encrypted (not a file data block) */
522 		memcpy(out, frm->data + offset, size);
523 	} else if (is_zero(fek, TEE_FS_KM_FEK_SIZE)) {
524 		/* The file was created with encryption disabled */
525 		return TEE_ERROR_SECURITY;
526 	} else {
527 		/* Block is encrypted */
528 		if (size < RPMB_DATA_SIZE) {
529 			/*
530 			 * Since output buffer is not large enough to hold one
531 			 * block we must allocate a temporary buffer.
532 			 */
533 			tmp = malloc(RPMB_DATA_SIZE);
534 			if (!tmp)
535 				return TEE_ERROR_OUT_OF_MEMORY;
536 			decrypt_block(tmp, frm->data, blk_idx, fek, uuid);
537 			memcpy(out, tmp + offset, size);
538 			free(tmp);
539 		} else {
540 			decrypt_block(out, frm->data, blk_idx, fek, uuid);
541 		}
542 	}
543 
544 	return TEE_SUCCESS;
545 }
546 
547 static TEE_Result tee_rpmb_req_pack(struct rpmb_req *req,
548 				    struct rpmb_raw_data *rawdata,
549 				    uint16_t nbr_frms, uint16_t dev_id,
550 				    const uint8_t *fek, const TEE_UUID *uuid)
551 {
552 	TEE_Result res = TEE_ERROR_GENERIC;
553 	int i;
554 	struct rpmb_data_frame *datafrm;
555 
556 	if (!req || !rawdata || !nbr_frms)
557 		return TEE_ERROR_BAD_PARAMETERS;
558 
559 	/*
560 	 * Check write blockcount is not bigger than reliable write
561 	 * blockcount.
562 	 */
563 	if ((rawdata->msg_type == RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE) &&
564 	    (nbr_frms > rpmb_ctx->rel_wr_blkcnt)) {
565 		DMSG("wr_blkcnt(%d) > rel_wr_blkcnt(%d)", nbr_frms,
566 		     rpmb_ctx->rel_wr_blkcnt);
567 		return TEE_ERROR_GENERIC;
568 	}
569 
570 	req->cmd = RPMB_CMD_DATA_REQ;
571 	req->dev_id = dev_id;
572 
573 	/* Allocate memory for construct all data packets and calculate MAC. */
574 	datafrm = calloc(nbr_frms, RPMB_DATA_FRAME_SIZE);
575 	if (!datafrm)
576 		return TEE_ERROR_OUT_OF_MEMORY;
577 
578 	for (i = 0; i < nbr_frms; i++) {
579 		u16_to_bytes(rawdata->msg_type, datafrm[i].msg_type);
580 
581 		if (rawdata->block_count)
582 			u16_to_bytes(*rawdata->block_count,
583 				     datafrm[i].block_count);
584 
585 		if (rawdata->blk_idx) {
586 			/* Check the block index is within range. */
587 			if ((*rawdata->blk_idx + nbr_frms) >
588 			    rpmb_ctx->max_blk_idx) {
589 				res = TEE_ERROR_GENERIC;
590 				goto func_exit;
591 			}
592 			u16_to_bytes(*rawdata->blk_idx, datafrm[i].address);
593 		}
594 
595 		if (rawdata->write_counter)
596 			u32_to_bytes(*rawdata->write_counter,
597 				     datafrm[i].write_counter);
598 
599 		if (rawdata->nonce)
600 			memcpy(datafrm[i].nonce, rawdata->nonce,
601 			       RPMB_NONCE_SIZE);
602 
603 		if (rawdata->data) {
604 			if (fek)
605 				encrypt_block(datafrm[i].data,
606 					rawdata->data + (i * RPMB_DATA_SIZE),
607 					*rawdata->blk_idx + i, fek, uuid);
608 			else
609 				memcpy(datafrm[i].data,
610 				       rawdata->data + (i * RPMB_DATA_SIZE),
611 				       RPMB_DATA_SIZE);
612 		}
613 	}
614 
615 	if (rawdata->key_mac) {
616 		if (rawdata->msg_type == RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE) {
617 			res =
618 			    tee_rpmb_mac_calc(rawdata->key_mac,
619 					      RPMB_KEY_MAC_SIZE, rpmb_ctx->key,
620 					      RPMB_KEY_MAC_SIZE, datafrm,
621 					      nbr_frms);
622 			if (res != TEE_SUCCESS)
623 				goto func_exit;
624 		}
625 		memcpy(datafrm[nbr_frms - 1].key_mac,
626 		       rawdata->key_mac, RPMB_KEY_MAC_SIZE);
627 	}
628 
629 	memcpy(TEE_RPMB_REQ_DATA(req), datafrm,
630 	       nbr_frms * RPMB_DATA_FRAME_SIZE);
631 
632 #ifdef CFG_RPMB_FS_DEBUG_DATA
633 	for (i = 0; i < nbr_frms; i++) {
634 		DMSG("Dumping data frame %d:", i);
635 		DHEXDUMP((uint8_t *)&datafrm[i] + RPMB_STUFF_DATA_SIZE,
636 			 512 - RPMB_STUFF_DATA_SIZE);
637 	}
638 #endif
639 
640 	res = TEE_SUCCESS;
641 func_exit:
642 	free(datafrm);
643 	return res;
644 }
645 
646 static TEE_Result data_cpy_mac_calc_1b(struct rpmb_raw_data *rawdata,
647 				       struct rpmb_data_frame *frm,
648 				       const uint8_t *fek, const TEE_UUID *uuid)
649 {
650 	TEE_Result res;
651 	uint8_t *data;
652 	uint16_t idx;
653 
654 	if (rawdata->len + rawdata->byte_offset > RPMB_DATA_SIZE)
655 		return TEE_ERROR_BAD_PARAMETERS;
656 
657 	res = tee_rpmb_mac_calc(rawdata->key_mac, RPMB_KEY_MAC_SIZE,
658 				rpmb_ctx->key, RPMB_KEY_MAC_SIZE, frm, 1);
659 	if (res != TEE_SUCCESS)
660 		return res;
661 
662 	data = rawdata->data;
663 	bytes_to_u16(frm->address, &idx);
664 
665 	res = decrypt(data, frm, rawdata->len, rawdata->byte_offset, idx, fek,
666 		      uuid);
667 	return res;
668 }
669 
670 static TEE_Result tee_rpmb_data_cpy_mac_calc(struct rpmb_data_frame *datafrm,
671 					     struct rpmb_raw_data *rawdata,
672 					     uint16_t nbr_frms,
673 					     struct rpmb_data_frame *lastfrm,
674 					     const uint8_t *fek,
675 					     const TEE_UUID *uuid)
676 {
677 	TEE_Result res = TEE_ERROR_GENERIC;
678 	int i;
679 	void *ctx = NULL;
680 	uint16_t offset;
681 	uint32_t size;
682 	uint8_t *data;
683 	uint16_t start_idx;
684 	struct rpmb_data_frame localfrm;
685 
686 	if (!datafrm || !rawdata || !nbr_frms || !lastfrm)
687 		return TEE_ERROR_BAD_PARAMETERS;
688 
689 	if (nbr_frms == 1)
690 		return data_cpy_mac_calc_1b(rawdata, lastfrm, fek, uuid);
691 
692 	/* nbr_frms > 1 */
693 
694 	data = rawdata->data;
695 
696 	res = crypto_mac_alloc_ctx(&ctx, TEE_ALG_HMAC_SHA256);
697 	if (res)
698 		goto func_exit;
699 
700 	res = crypto_mac_init(ctx, TEE_ALG_HMAC_SHA256, rpmb_ctx->key,
701 			      RPMB_KEY_MAC_SIZE);
702 	if (res != TEE_SUCCESS)
703 		goto func_exit;
704 
705 	/*
706 	 * Note: JEDEC JESD84-B51: "In every packet the address is the start
707 	 * address of the full access (not address of the individual half a
708 	 * sector)"
709 	 */
710 	bytes_to_u16(lastfrm->address, &start_idx);
711 
712 	for (i = 0; i < (nbr_frms - 1); i++) {
713 
714 		/*
715 		 * By working on a local copy of the RPMB frame, we ensure that
716 		 * the data can not be modified after the MAC is computed but
717 		 * before the payload is decrypted/copied to the output buffer.
718 		 */
719 		memcpy(&localfrm, &datafrm[i], RPMB_DATA_FRAME_SIZE);
720 
721 		res = crypto_mac_update(ctx, TEE_ALG_HMAC_SHA256, localfrm.data,
722 					RPMB_MAC_PROTECT_DATA_SIZE);
723 		if (res != TEE_SUCCESS)
724 			goto func_exit;
725 
726 		if (i == 0) {
727 			/* First block */
728 			offset = rawdata->byte_offset;
729 			size = RPMB_DATA_SIZE - offset;
730 		} else {
731 			/* Middle blocks */
732 			size = RPMB_DATA_SIZE;
733 			offset = 0;
734 		}
735 
736 		res = decrypt(data, &localfrm, size, offset, start_idx + i,
737 			      fek, uuid);
738 		if (res != TEE_SUCCESS)
739 			goto func_exit;
740 
741 		data += size;
742 	}
743 
744 	/* Last block */
745 	size = (rawdata->len + rawdata->byte_offset) % RPMB_DATA_SIZE;
746 	if (size == 0)
747 		size = RPMB_DATA_SIZE;
748 	res = decrypt(data, lastfrm, size, 0, start_idx + nbr_frms - 1, fek,
749 		      uuid);
750 	if (res != TEE_SUCCESS)
751 		goto func_exit;
752 
753 	/* Update MAC against the last block */
754 	res = crypto_mac_update(ctx, TEE_ALG_HMAC_SHA256, lastfrm->data,
755 				RPMB_MAC_PROTECT_DATA_SIZE);
756 	if (res != TEE_SUCCESS)
757 		goto func_exit;
758 
759 	res = crypto_mac_final(ctx, TEE_ALG_HMAC_SHA256, rawdata->key_mac,
760 			       RPMB_KEY_MAC_SIZE);
761 	if (res != TEE_SUCCESS)
762 		goto func_exit;
763 
764 	res = TEE_SUCCESS;
765 
766 func_exit:
767 	crypto_mac_free_ctx(ctx, TEE_ALG_HMAC_SHA256);
768 	return res;
769 }
770 
771 static TEE_Result tee_rpmb_resp_unpack_verify(struct rpmb_data_frame *datafrm,
772 					      struct rpmb_raw_data *rawdata,
773 					      uint16_t nbr_frms,
774 					      const uint8_t *fek,
775 					      const TEE_UUID *uuid)
776 {
777 	TEE_Result res = TEE_ERROR_GENERIC;
778 	uint16_t msg_type;
779 	uint32_t wr_cnt;
780 	uint16_t blk_idx;
781 	uint16_t op_result;
782 	struct rpmb_data_frame lastfrm;
783 
784 	if (!datafrm || !rawdata || !nbr_frms)
785 		return TEE_ERROR_BAD_PARAMETERS;
786 
787 #ifdef CFG_RPMB_FS_DEBUG_DATA
788 	for (uint32_t i = 0; i < nbr_frms; i++) {
789 		DMSG("Dumping data frame %d:", i);
790 		DHEXDUMP((uint8_t *)&datafrm[i] + RPMB_STUFF_DATA_SIZE,
791 			 512 - RPMB_STUFF_DATA_SIZE);
792 	}
793 #endif
794 
795 	/* Make sure the last data packet can't be modified once verified */
796 	memcpy(&lastfrm, &datafrm[nbr_frms - 1], RPMB_DATA_FRAME_SIZE);
797 
798 	/* Handle operation result and translate to TEEC error code. */
799 	bytes_to_u16(lastfrm.op_result, &op_result);
800 	if (rawdata->op_result)
801 		*rawdata->op_result = op_result;
802 	if (op_result != RPMB_RESULT_OK)
803 		return TEE_ERROR_GENERIC;
804 
805 	/* Check the response msg_type. */
806 	bytes_to_u16(lastfrm.msg_type, &msg_type);
807 	if (msg_type != rawdata->msg_type) {
808 		DMSG("Unexpected msg_type (0x%04x != 0x%04x)", msg_type,
809 		     rawdata->msg_type);
810 		return TEE_ERROR_GENERIC;
811 	}
812 
813 	if (rawdata->blk_idx) {
814 		bytes_to_u16(lastfrm.address, &blk_idx);
815 		if (blk_idx != *rawdata->blk_idx) {
816 			DMSG("Unexpected block index");
817 			return TEE_ERROR_GENERIC;
818 		}
819 	}
820 
821 	if (rawdata->write_counter) {
822 		wr_cnt = *rawdata->write_counter;
823 		bytes_to_u32(lastfrm.write_counter, rawdata->write_counter);
824 		if (msg_type == RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE) {
825 			/* Verify the write counter is incremented by 1 */
826 			if (*rawdata->write_counter != wr_cnt + 1) {
827 				DMSG("Counter mismatched (0x%04x/0x%04x)",
828 				     *rawdata->write_counter, wr_cnt + 1);
829 				return TEE_ERROR_SECURITY;
830 			}
831 			rpmb_ctx->wr_cnt++;
832 		}
833 	}
834 
835 	if (rawdata->nonce) {
836 		if (buf_compare_ct(rawdata->nonce, lastfrm.nonce,
837 				   RPMB_NONCE_SIZE) != 0) {
838 			DMSG("Nonce mismatched");
839 			return TEE_ERROR_SECURITY;
840 		}
841 	}
842 
843 	if (rawdata->key_mac) {
844 		if (msg_type == RPMB_MSG_TYPE_RESP_AUTH_DATA_READ) {
845 			if (!rawdata->data)
846 				return TEE_ERROR_GENERIC;
847 
848 			res = tee_rpmb_data_cpy_mac_calc(datafrm, rawdata,
849 							 nbr_frms, &lastfrm,
850 							 fek, uuid);
851 
852 			if (res != TEE_SUCCESS)
853 				return res;
854 		} else {
855 			/*
856 			 * There should be only one data frame for
857 			 * other msg types.
858 			 */
859 			if (nbr_frms != 1)
860 				return TEE_ERROR_GENERIC;
861 
862 			res = tee_rpmb_mac_calc(rawdata->key_mac,
863 						RPMB_KEY_MAC_SIZE,
864 						rpmb_ctx->key,
865 						RPMB_KEY_MAC_SIZE,
866 						&lastfrm, 1);
867 
868 			if (res != TEE_SUCCESS)
869 				return res;
870 		}
871 
872 #ifndef CFG_RPMB_FS_NO_MAC
873 		if (consttime_memcmp(rawdata->key_mac,
874 				     (datafrm + nbr_frms - 1)->key_mac,
875 				     RPMB_KEY_MAC_SIZE) != 0) {
876 			DMSG("MAC mismatched:");
877 #ifdef CFG_RPMB_FS_DEBUG_DATA
878 			DHEXDUMP((uint8_t *)rawdata->key_mac, 32);
879 #endif
880 			return TEE_ERROR_SECURITY;
881 		}
882 #endif /* !CFG_RPMB_FS_NO_MAC */
883 	}
884 
885 	return TEE_SUCCESS;
886 }
887 
888 static TEE_Result tee_rpmb_get_dev_info(uint16_t dev_id,
889 					struct rpmb_dev_info *dev_info)
890 {
891 	TEE_Result res = TEE_ERROR_GENERIC;
892 	struct tee_rpmb_mem mem;
893 	struct rpmb_dev_info *di;
894 	struct rpmb_req *req = NULL;
895 	uint8_t *resp = NULL;
896 	uint32_t req_size;
897 	uint32_t resp_size;
898 
899 	if (!dev_info)
900 		return TEE_ERROR_BAD_PARAMETERS;
901 
902 	req_size = sizeof(struct rpmb_req);
903 	resp_size = sizeof(struct rpmb_dev_info);
904 	res = tee_rpmb_alloc(req_size, resp_size, &mem,
905 			     (void *)&req, (void *)&resp);
906 	if (res != TEE_SUCCESS)
907 		goto func_exit;
908 
909 	req->cmd = RPMB_CMD_GET_DEV_INFO;
910 	req->dev_id = dev_id;
911 
912 	di = (struct rpmb_dev_info *)resp;
913 	di->ret_code = RPMB_CMD_GET_DEV_INFO_RET_ERROR;
914 
915 	res = tee_rpmb_invoke(&mem);
916 	if (res != TEE_SUCCESS)
917 		goto func_exit;
918 
919 	if (di->ret_code != RPMB_CMD_GET_DEV_INFO_RET_OK) {
920 		res = TEE_ERROR_GENERIC;
921 		goto func_exit;
922 	}
923 
924 	memcpy((uint8_t *)dev_info, resp, sizeof(struct rpmb_dev_info));
925 
926 #ifdef CFG_RPMB_FS_DEBUG_DATA
927 	DMSG("Dumping dev_info:");
928 	DHEXDUMP((uint8_t *)dev_info, sizeof(struct rpmb_dev_info));
929 #endif
930 
931 	res = TEE_SUCCESS;
932 
933 func_exit:
934 	tee_rpmb_free(&mem);
935 	return res;
936 }
937 
938 static TEE_Result tee_rpmb_init_read_wr_cnt(uint16_t dev_id,
939 					    uint32_t *wr_cnt,
940 					    uint16_t *op_result)
941 {
942 	TEE_Result res = TEE_ERROR_GENERIC;
943 	struct tee_rpmb_mem mem;
944 	uint16_t msg_type;
945 	uint8_t nonce[RPMB_NONCE_SIZE];
946 	uint8_t hmac[RPMB_KEY_MAC_SIZE];
947 	struct rpmb_req *req = NULL;
948 	struct rpmb_data_frame *resp = NULL;
949 	struct rpmb_raw_data rawdata;
950 	uint32_t req_size;
951 	uint32_t resp_size;
952 
953 	if (!wr_cnt)
954 		return TEE_ERROR_BAD_PARAMETERS;
955 
956 	req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE;
957 	resp_size = RPMB_DATA_FRAME_SIZE;
958 	res = tee_rpmb_alloc(req_size, resp_size, &mem,
959 			     (void *)&req, (void *)&resp);
960 	if (res != TEE_SUCCESS)
961 		goto func_exit;
962 
963 	res = crypto_rng_read(nonce, RPMB_NONCE_SIZE);
964 	if (res != TEE_SUCCESS)
965 		goto func_exit;
966 
967 	msg_type = RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ;
968 
969 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
970 	rawdata.msg_type = msg_type;
971 	rawdata.nonce = nonce;
972 
973 	res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL, NULL);
974 	if (res != TEE_SUCCESS)
975 		goto func_exit;
976 
977 	res = tee_rpmb_invoke(&mem);
978 	if (res != TEE_SUCCESS)
979 		goto func_exit;
980 
981 	msg_type = RPMB_MSG_TYPE_RESP_WRITE_COUNTER_VAL_READ;
982 
983 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
984 	rawdata.msg_type = msg_type;
985 	rawdata.op_result = op_result;
986 	rawdata.write_counter = wr_cnt;
987 	rawdata.nonce = nonce;
988 	rawdata.key_mac = hmac;
989 
990 	res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL, NULL);
991 	if (res != TEE_SUCCESS)
992 		goto func_exit;
993 
994 	res = TEE_SUCCESS;
995 
996 func_exit:
997 	tee_rpmb_free(&mem);
998 	return res;
999 }
1000 
1001 static TEE_Result tee_rpmb_verify_key_sync_counter(uint16_t dev_id)
1002 {
1003 	uint16_t op_result = 0;
1004 	TEE_Result res = TEE_ERROR_GENERIC;
1005 
1006 	res = tee_rpmb_init_read_wr_cnt(dev_id, &rpmb_ctx->wr_cnt,
1007 					&op_result);
1008 
1009 	if (res == TEE_SUCCESS) {
1010 		rpmb_ctx->key_verified = true;
1011 		rpmb_ctx->wr_cnt_synced = true;
1012 	}
1013 
1014 	DMSG("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 	DMSG("RPMB INIT: Writing Key");
1072 	res = tee_rpmb_write_key(dev_id);
1073 	if (res == TEE_SUCCESS) {
1074 		DMSG("RPMB INIT: Verifying Key");
1075 		res = tee_rpmb_verify_key_sync_counter(dev_id);
1076 	}
1077 	return res;
1078 }
1079 #else
1080 static TEE_Result tee_rpmb_write_and_verify_key(uint16_t dev_id __unused)
1081 {
1082 	return TEE_ERROR_BAD_STATE;
1083 }
1084 #endif
1085 
1086 /* This function must never return TEE_SUCCESS if rpmb_ctx == NULL */
1087 static TEE_Result tee_rpmb_init(uint16_t dev_id)
1088 {
1089 	TEE_Result res = TEE_SUCCESS;
1090 	struct rpmb_dev_info dev_info;
1091 
1092 	if (!rpmb_ctx) {
1093 		rpmb_ctx = calloc(1, sizeof(struct tee_rpmb_ctx));
1094 		if (!rpmb_ctx)
1095 			return TEE_ERROR_OUT_OF_MEMORY;
1096 	} else if (rpmb_ctx->dev_id != dev_id) {
1097 		memset(rpmb_ctx, 0x00, sizeof(struct tee_rpmb_ctx));
1098 	}
1099 
1100 	rpmb_ctx->dev_id = dev_id;
1101 
1102 	if (!rpmb_ctx->dev_info_synced) {
1103 		DMSG("RPMB: Syncing device information");
1104 
1105 		dev_info.rpmb_size_mult = 0;
1106 		dev_info.rel_wr_sec_c = 0;
1107 		res = tee_rpmb_get_dev_info(dev_id, &dev_info);
1108 		if (res != TEE_SUCCESS)
1109 			goto func_exit;
1110 
1111 		DMSG("RPMB: RPMB size is %d*128 KB", dev_info.rpmb_size_mult);
1112 		DMSG("RPMB: Reliable Write Sector Count is %d",
1113 		     dev_info.rel_wr_sec_c);
1114 
1115 		if (dev_info.rpmb_size_mult == 0) {
1116 			res = TEE_ERROR_GENERIC;
1117 			goto func_exit;
1118 		}
1119 
1120 		if (MUL_OVERFLOW(dev_info.rpmb_size_mult,
1121 				 RPMB_SIZE_SINGLE / RPMB_DATA_SIZE,
1122 				 &rpmb_ctx->max_blk_idx)) {
1123 			res = TEE_ERROR_BAD_PARAMETERS;
1124 			goto func_exit;
1125 		}
1126 		rpmb_ctx->max_blk_idx--;
1127 
1128 		memcpy(rpmb_ctx->cid, dev_info.cid, RPMB_EMMC_CID_SIZE);
1129 
1130 #ifdef RPMB_DRIVER_MULTIPLE_WRITE_FIXED
1131 		rpmb_ctx->rel_wr_blkcnt = dev_info.rel_wr_sec_c * 2;
1132 #else
1133 		rpmb_ctx->rel_wr_blkcnt = 1;
1134 #endif
1135 
1136 		rpmb_ctx->dev_info_synced = true;
1137 	}
1138 
1139 	if (!rpmb_ctx->key_derived) {
1140 		DMSG("RPMB INIT: Deriving key");
1141 
1142 		res = tee_rpmb_key_gen(dev_id, rpmb_ctx->key,
1143 				       RPMB_KEY_MAC_SIZE);
1144 		if (res != TEE_SUCCESS)
1145 			goto func_exit;
1146 
1147 		rpmb_ctx->key_derived = true;
1148 	}
1149 
1150 	/* Perform a write counter read to verify if the key is ok. */
1151 	if (!rpmb_ctx->wr_cnt_synced || !rpmb_ctx->key_verified) {
1152 		DMSG("RPMB INIT: Verifying Key");
1153 
1154 		res = tee_rpmb_verify_key_sync_counter(dev_id);
1155 		if (res != TEE_SUCCESS && !rpmb_ctx->key_verified) {
1156 			/*
1157 			 * Need to write the key here and verify it.
1158 			 */
1159 			res = tee_rpmb_write_and_verify_key(dev_id);
1160 		}
1161 	}
1162 
1163 func_exit:
1164 	return res;
1165 }
1166 
1167 /*
1168  * Read RPMB data in bytes.
1169  *
1170  * @dev_id     Device ID of the eMMC device.
1171  * @addr       Byte address of data.
1172  * @data       Pointer to the data.
1173  * @len        Size of data in bytes.
1174  * @fek        Encrypted File Encryption Key or NULL.
1175  */
1176 static TEE_Result tee_rpmb_read(uint16_t dev_id, uint32_t addr, uint8_t *data,
1177 				uint32_t len, const uint8_t *fek,
1178 				const TEE_UUID *uuid)
1179 {
1180 	TEE_Result res = TEE_ERROR_GENERIC;
1181 	struct tee_rpmb_mem mem = { 0 };
1182 	uint16_t msg_type;
1183 	uint8_t nonce[RPMB_NONCE_SIZE];
1184 	uint8_t hmac[RPMB_KEY_MAC_SIZE];
1185 	struct rpmb_req *req = NULL;
1186 	struct rpmb_data_frame *resp = NULL;
1187 	struct rpmb_raw_data rawdata;
1188 	uint32_t req_size;
1189 	uint32_t resp_size;
1190 	uint16_t blk_idx;
1191 	uint16_t blkcnt;
1192 	uint8_t byte_offset;
1193 
1194 	if (!data || !len)
1195 		return TEE_ERROR_BAD_PARAMETERS;
1196 
1197 	blk_idx = addr / RPMB_DATA_SIZE;
1198 	byte_offset = addr % RPMB_DATA_SIZE;
1199 
1200 	if (len + byte_offset + RPMB_DATA_SIZE < RPMB_DATA_SIZE) {
1201 		/* Overflow */
1202 		return TEE_ERROR_BAD_PARAMETERS;
1203 	}
1204 	blkcnt =
1205 	    ROUNDUP(len + byte_offset, RPMB_DATA_SIZE) / RPMB_DATA_SIZE;
1206 	res = tee_rpmb_init(dev_id);
1207 	if (res != TEE_SUCCESS)
1208 		goto func_exit;
1209 
1210 	req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE;
1211 	resp_size = RPMB_DATA_FRAME_SIZE * blkcnt;
1212 	res = tee_rpmb_alloc(req_size, resp_size, &mem,
1213 			     (void *)&req, (void *)&resp);
1214 	if (res != TEE_SUCCESS)
1215 		goto func_exit;
1216 
1217 	msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_READ;
1218 	res = crypto_rng_read(nonce, RPMB_NONCE_SIZE);
1219 	if (res != TEE_SUCCESS)
1220 		goto func_exit;
1221 
1222 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1223 	rawdata.msg_type = msg_type;
1224 	rawdata.nonce = nonce;
1225 	rawdata.blk_idx = &blk_idx;
1226 	res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL, NULL);
1227 	if (res != TEE_SUCCESS)
1228 		goto func_exit;
1229 
1230 	req->block_count = blkcnt;
1231 
1232 	DMSG("Read %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""),
1233 	     blk_idx);
1234 
1235 	res = tee_rpmb_invoke(&mem);
1236 	if (res != TEE_SUCCESS)
1237 		goto func_exit;
1238 
1239 	msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_READ;
1240 
1241 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1242 	rawdata.msg_type = msg_type;
1243 	rawdata.block_count = &blkcnt;
1244 	rawdata.blk_idx = &blk_idx;
1245 	rawdata.nonce = nonce;
1246 	rawdata.key_mac = hmac;
1247 	rawdata.data = data;
1248 
1249 	rawdata.len = len;
1250 	rawdata.byte_offset = byte_offset;
1251 
1252 	res = tee_rpmb_resp_unpack_verify(resp, &rawdata, blkcnt, fek, uuid);
1253 	if (res != TEE_SUCCESS)
1254 		goto func_exit;
1255 
1256 	res = TEE_SUCCESS;
1257 
1258 func_exit:
1259 	tee_rpmb_free(&mem);
1260 	return res;
1261 }
1262 
1263 static TEE_Result tee_rpmb_write_blk(uint16_t dev_id, uint16_t blk_idx,
1264 				     const uint8_t *data_blks, uint16_t blkcnt,
1265 				     const uint8_t *fek, const TEE_UUID *uuid)
1266 {
1267 	TEE_Result res;
1268 	struct tee_rpmb_mem mem;
1269 	uint16_t msg_type;
1270 	uint32_t wr_cnt;
1271 	uint8_t hmac[RPMB_KEY_MAC_SIZE];
1272 	struct rpmb_req *req = NULL;
1273 	struct rpmb_data_frame *resp = NULL;
1274 	struct rpmb_raw_data rawdata;
1275 	uint32_t req_size;
1276 	uint32_t resp_size;
1277 	uint32_t nbr_writes;
1278 	uint16_t tmp_blkcnt;
1279 	uint16_t tmp_blk_idx;
1280 	uint16_t i;
1281 
1282 	DMSG("Write %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""),
1283 	     blk_idx);
1284 
1285 	if (!data_blks || !blkcnt)
1286 		return TEE_ERROR_BAD_PARAMETERS;
1287 
1288 	res = tee_rpmb_init(dev_id);
1289 	if (res != TEE_SUCCESS)
1290 		return res;
1291 
1292 	/*
1293 	 * We need to split data when block count
1294 	 * is bigger than reliable block write count.
1295 	 */
1296 	if (blkcnt < rpmb_ctx->rel_wr_blkcnt)
1297 		req_size = sizeof(struct rpmb_req) +
1298 		    RPMB_DATA_FRAME_SIZE * blkcnt;
1299 	else
1300 		req_size = sizeof(struct rpmb_req) +
1301 		    RPMB_DATA_FRAME_SIZE * rpmb_ctx->rel_wr_blkcnt;
1302 
1303 	resp_size = RPMB_DATA_FRAME_SIZE;
1304 	res = tee_rpmb_alloc(req_size, resp_size, &mem,
1305 			     (void *)&req, (void *)&resp);
1306 	if (res != TEE_SUCCESS)
1307 		return res;
1308 
1309 	nbr_writes = blkcnt / rpmb_ctx->rel_wr_blkcnt;
1310 	if (blkcnt % rpmb_ctx->rel_wr_blkcnt > 0)
1311 		nbr_writes += 1;
1312 
1313 	tmp_blkcnt = rpmb_ctx->rel_wr_blkcnt;
1314 	tmp_blk_idx = blk_idx;
1315 	for (i = 0; i < nbr_writes; i++) {
1316 		/*
1317 		 * To handle the last write of block count which is
1318 		 * equal or smaller than reliable write block count.
1319 		 */
1320 		if (i == nbr_writes - 1)
1321 			tmp_blkcnt = blkcnt - rpmb_ctx->rel_wr_blkcnt *
1322 			    (nbr_writes - 1);
1323 
1324 		msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE;
1325 		wr_cnt = rpmb_ctx->wr_cnt;
1326 
1327 		memset(req, 0x00, req_size);
1328 		memset(resp, 0x00, resp_size);
1329 
1330 		memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1331 		rawdata.msg_type = msg_type;
1332 		rawdata.block_count = &tmp_blkcnt;
1333 		rawdata.blk_idx = &tmp_blk_idx;
1334 		rawdata.write_counter = &wr_cnt;
1335 		rawdata.key_mac = hmac;
1336 		rawdata.data = (uint8_t *)data_blks +
1337 				i * rpmb_ctx->rel_wr_blkcnt * RPMB_DATA_SIZE;
1338 
1339 		res = tee_rpmb_req_pack(req, &rawdata, tmp_blkcnt, dev_id,
1340 					fek, uuid);
1341 		if (res != TEE_SUCCESS)
1342 			goto out;
1343 
1344 		res = tee_rpmb_invoke(&mem);
1345 		if (res != TEE_SUCCESS) {
1346 			/*
1347 			 * To force wr_cnt sync next time, as it might get
1348 			 * out of sync due to inconsistent operation result!
1349 			 */
1350 			rpmb_ctx->wr_cnt_synced = false;
1351 			goto out;
1352 		}
1353 
1354 		msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE;
1355 
1356 		memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1357 		rawdata.msg_type = msg_type;
1358 		rawdata.block_count = &tmp_blkcnt;
1359 		rawdata.blk_idx = &tmp_blk_idx;
1360 		rawdata.write_counter = &wr_cnt;
1361 		rawdata.key_mac = hmac;
1362 
1363 		res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL,
1364 						  NULL);
1365 		if (res != TEE_SUCCESS) {
1366 			/*
1367 			 * To force wr_cnt sync next time, as it might get
1368 			 * out of sync due to inconsistent operation result!
1369 			 */
1370 			rpmb_ctx->wr_cnt_synced = false;
1371 			goto out;
1372 		}
1373 
1374 		tmp_blk_idx += tmp_blkcnt;
1375 	}
1376 
1377 out:
1378 	tee_rpmb_free(&mem);
1379 	return res;
1380 }
1381 
1382 static bool tee_rpmb_write_is_atomic(uint16_t dev_id __unused, uint32_t addr,
1383 				     uint32_t len)
1384 {
1385 	uint8_t byte_offset = addr % RPMB_DATA_SIZE;
1386 	uint16_t blkcnt = ROUNDUP(len + byte_offset,
1387 				  RPMB_DATA_SIZE) / RPMB_DATA_SIZE;
1388 
1389 	return (blkcnt <= rpmb_ctx->rel_wr_blkcnt);
1390 }
1391 
1392 /*
1393  * Write RPMB data in bytes.
1394  *
1395  * @dev_id     Device ID of the eMMC device.
1396  * @addr       Byte address of data.
1397  * @data       Pointer to the data.
1398  * @len        Size of data in bytes.
1399  * @fek        Encrypted File Encryption Key or NULL.
1400  */
1401 static TEE_Result tee_rpmb_write(uint16_t dev_id, uint32_t addr,
1402 				 const uint8_t *data, uint32_t len,
1403 				 const uint8_t *fek, const TEE_UUID *uuid)
1404 {
1405 	TEE_Result res = TEE_ERROR_GENERIC;
1406 	uint8_t *data_tmp = NULL;
1407 	uint16_t blk_idx;
1408 	uint16_t blkcnt;
1409 	uint8_t byte_offset;
1410 
1411 	blk_idx = addr / RPMB_DATA_SIZE;
1412 	byte_offset = addr % RPMB_DATA_SIZE;
1413 
1414 	blkcnt =
1415 	    ROUNDUP(len + byte_offset, RPMB_DATA_SIZE) / RPMB_DATA_SIZE;
1416 
1417 	if (byte_offset == 0 && (len % RPMB_DATA_SIZE) == 0) {
1418 		res = tee_rpmb_write_blk(dev_id, blk_idx, data, blkcnt, fek,
1419 					 uuid);
1420 		if (res != TEE_SUCCESS)
1421 			goto func_exit;
1422 	} else {
1423 		data_tmp = calloc(blkcnt, RPMB_DATA_SIZE);
1424 		if (!data_tmp) {
1425 			res = TEE_ERROR_OUT_OF_MEMORY;
1426 			goto func_exit;
1427 		}
1428 
1429 		/* Read the complete blocks */
1430 		res = tee_rpmb_read(dev_id, blk_idx * RPMB_DATA_SIZE, data_tmp,
1431 				    blkcnt * RPMB_DATA_SIZE, fek, uuid);
1432 		if (res != TEE_SUCCESS)
1433 			goto func_exit;
1434 
1435 		/* Partial update of the data blocks */
1436 		memcpy(data_tmp + byte_offset, data, len);
1437 
1438 		res = tee_rpmb_write_blk(dev_id, blk_idx, data_tmp, blkcnt,
1439 					 fek, uuid);
1440 		if (res != TEE_SUCCESS)
1441 			goto func_exit;
1442 	}
1443 
1444 	res = TEE_SUCCESS;
1445 
1446 func_exit:
1447 	free(data_tmp);
1448 	return res;
1449 }
1450 
1451 /*
1452  * Read the RPMB write counter.
1453  *
1454  * @dev_id     Device ID of the eMMC device.
1455  * @counter    Pointer to the counter.
1456  */
1457 static TEE_Result tee_rpmb_get_write_counter(uint16_t dev_id,
1458 					     uint32_t *counter)
1459 {
1460 	TEE_Result res = TEE_SUCCESS;
1461 
1462 	if (!counter)
1463 		return TEE_ERROR_BAD_PARAMETERS;
1464 
1465 	if (!rpmb_ctx || !rpmb_ctx->wr_cnt_synced) {
1466 		res = tee_rpmb_init(dev_id);
1467 		if (res != TEE_SUCCESS)
1468 			goto func_exit;
1469 	}
1470 
1471 	*counter = rpmb_ctx->wr_cnt;
1472 
1473 func_exit:
1474 	return res;
1475 }
1476 
1477 /*
1478  * Read the RPMB max block.
1479  *
1480  * @dev_id     Device ID of the eMMC device.
1481  * @counter    Pointer to receive the max block.
1482  */
1483 static TEE_Result tee_rpmb_get_max_block(uint16_t dev_id, uint32_t *max_block)
1484 {
1485 	TEE_Result res = TEE_SUCCESS;
1486 
1487 	if (!max_block)
1488 		return TEE_ERROR_BAD_PARAMETERS;
1489 
1490 	if (!rpmb_ctx || !rpmb_ctx->dev_info_synced) {
1491 		res = tee_rpmb_init(dev_id);
1492 		if (res != TEE_SUCCESS)
1493 			goto func_exit;
1494 	}
1495 
1496 	*max_block = rpmb_ctx->max_blk_idx;
1497 
1498 func_exit:
1499 	return res;
1500 }
1501 
1502 /*
1503  * End of lower interface to RPMB device
1504  */
1505 
1506 static TEE_Result get_fat_start_address(uint32_t *addr);
1507 
1508 static void dump_fat(void)
1509 {
1510 	TEE_Result res = TEE_ERROR_GENERIC;
1511 	struct rpmb_fat_entry *fat_entries = NULL;
1512 	uint32_t fat_address;
1513 	size_t size;
1514 	int i;
1515 	bool last_entry_found = false;
1516 
1517 	res = get_fat_start_address(&fat_address);
1518 	if (res != TEE_SUCCESS)
1519 		goto out;
1520 
1521 	size = N_ENTRIES * sizeof(struct rpmb_fat_entry);
1522 	fat_entries = malloc(size);
1523 	if (!fat_entries) {
1524 		res = TEE_ERROR_OUT_OF_MEMORY;
1525 		goto out;
1526 	}
1527 
1528 	while (!last_entry_found) {
1529 		res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address,
1530 				    (uint8_t *)fat_entries, size, NULL, NULL);
1531 		if (res != TEE_SUCCESS)
1532 			goto out;
1533 
1534 		for (i = 0; i < N_ENTRIES; i++) {
1535 
1536 			FMSG("flags 0x%x, size %d, address 0x%x, filename '%s'",
1537 				fat_entries[i].flags,
1538 				fat_entries[i].data_size,
1539 				fat_entries[i].start_address,
1540 				fat_entries[i].filename);
1541 
1542 			if ((fat_entries[i].flags & FILE_IS_LAST_ENTRY) != 0) {
1543 				last_entry_found = true;
1544 				break;
1545 			}
1546 
1547 			/* Move to next fat_entry. */
1548 			fat_address += sizeof(struct rpmb_fat_entry);
1549 		}
1550 	}
1551 
1552 out:
1553 	free(fat_entries);
1554 }
1555 
1556 #if (TRACE_LEVEL >= TRACE_DEBUG)
1557 static void dump_fh(struct rpmb_file_handle *fh)
1558 {
1559 	DMSG("fh->filename=%s", fh->filename);
1560 	DMSG("fh->rpmb_fat_address=%u", fh->rpmb_fat_address);
1561 	DMSG("fh->fat_entry.start_address=%u", fh->fat_entry.start_address);
1562 	DMSG("fh->fat_entry.data_size=%u", fh->fat_entry.data_size);
1563 }
1564 #else
1565 static void dump_fh(struct rpmb_file_handle *fh __unused)
1566 {
1567 }
1568 #endif
1569 
1570 static struct rpmb_file_handle *alloc_file_handle(struct tee_pobj *po,
1571 						  bool temporary)
1572 {
1573 	struct rpmb_file_handle *fh = NULL;
1574 
1575 	fh = calloc(1, sizeof(struct rpmb_file_handle));
1576 	if (!fh)
1577 		return NULL;
1578 
1579 	if (po)
1580 		tee_svc_storage_create_filename(fh->filename,
1581 						sizeof(fh->filename), po,
1582 						temporary);
1583 
1584 	return fh;
1585 }
1586 
1587 /**
1588  * write_fat_entry: Store info in a fat_entry to RPMB.
1589  */
1590 static TEE_Result write_fat_entry(struct rpmb_file_handle *fh,
1591 				  bool update_write_counter)
1592 {
1593 	TEE_Result res = TEE_ERROR_GENERIC;
1594 
1595 	/* Protect partition data. */
1596 	if (fh->rpmb_fat_address < sizeof(struct rpmb_fs_partition)) {
1597 		res = TEE_ERROR_ACCESS_CONFLICT;
1598 		goto out;
1599 	}
1600 
1601 	if (fh->rpmb_fat_address % sizeof(struct rpmb_fat_entry) != 0) {
1602 		res = TEE_ERROR_BAD_PARAMETERS;
1603 		goto out;
1604 	}
1605 
1606 	if (update_write_counter) {
1607 		res = tee_rpmb_get_write_counter(CFG_RPMB_FS_DEV_ID,
1608 						 &fh->fat_entry.write_counter);
1609 		if (res != TEE_SUCCESS)
1610 			goto out;
1611 	}
1612 
1613 	res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, fh->rpmb_fat_address,
1614 			     (uint8_t *)&fh->fat_entry,
1615 			     sizeof(struct rpmb_fat_entry), NULL, NULL);
1616 
1617 	dump_fat();
1618 
1619 out:
1620 	return res;
1621 }
1622 
1623 /**
1624  * rpmb_fs_setup: Setup rpmb fs.
1625  * Set initial partition and FS values and write to RPMB.
1626  * Store frequently used data in RAM.
1627  */
1628 static TEE_Result rpmb_fs_setup(void)
1629 {
1630 	TEE_Result res = TEE_ERROR_GENERIC;
1631 	struct rpmb_fs_partition *partition_data = NULL;
1632 	struct rpmb_file_handle *fh = NULL;
1633 	uint32_t max_rpmb_block = 0;
1634 
1635 	if (fs_par) {
1636 		res = TEE_SUCCESS;
1637 		goto out;
1638 	}
1639 
1640 	res = tee_rpmb_get_max_block(CFG_RPMB_FS_DEV_ID, &max_rpmb_block);
1641 	if (res != TEE_SUCCESS)
1642 		goto out;
1643 
1644 	partition_data = calloc(1, sizeof(struct rpmb_fs_partition));
1645 	if (!partition_data) {
1646 		res = TEE_ERROR_OUT_OF_MEMORY;
1647 		goto out;
1648 	}
1649 
1650 	res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS,
1651 			    (uint8_t *)partition_data,
1652 			    sizeof(struct rpmb_fs_partition), NULL, NULL);
1653 	if (res != TEE_SUCCESS)
1654 		goto out;
1655 
1656 #ifndef CFG_RPMB_RESET_FAT
1657 	if (partition_data->rpmb_fs_magic == RPMB_FS_MAGIC) {
1658 		if (partition_data->fs_version == FS_VERSION) {
1659 			res = TEE_SUCCESS;
1660 			goto store_fs_par;
1661 		} else {
1662 			/* Wrong software is in use. */
1663 			res = TEE_ERROR_ACCESS_DENIED;
1664 			goto out;
1665 		}
1666 	}
1667 #else
1668 	EMSG("**** Clearing Storage ****");
1669 #endif
1670 
1671 	/* Setup new partition data. */
1672 	partition_data->rpmb_fs_magic = RPMB_FS_MAGIC;
1673 	partition_data->fs_version = FS_VERSION;
1674 	partition_data->fat_start_address = RPMB_FS_FAT_START_ADDRESS;
1675 
1676 	/* Initial FAT entry with FILE_IS_LAST_ENTRY flag set. */
1677 	fh = alloc_file_handle(NULL, false);
1678 	if (!fh) {
1679 		res = TEE_ERROR_OUT_OF_MEMORY;
1680 		goto out;
1681 	}
1682 	fh->fat_entry.flags = FILE_IS_LAST_ENTRY;
1683 	fh->rpmb_fat_address = partition_data->fat_start_address;
1684 
1685 	/* Write init FAT entry and partition data to RPMB. */
1686 	res = write_fat_entry(fh, true);
1687 	if (res != TEE_SUCCESS)
1688 		goto out;
1689 
1690 	res =
1691 	    tee_rpmb_get_write_counter(CFG_RPMB_FS_DEV_ID,
1692 				       &partition_data->write_counter);
1693 	if (res != TEE_SUCCESS)
1694 		goto out;
1695 	res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS,
1696 			     (uint8_t *)partition_data,
1697 			     sizeof(struct rpmb_fs_partition), NULL, NULL);
1698 
1699 #ifndef CFG_RPMB_RESET_FAT
1700 store_fs_par:
1701 #endif
1702 
1703 	/* Store FAT start address. */
1704 	fs_par = calloc(1, sizeof(struct rpmb_fs_parameters));
1705 	if (!fs_par) {
1706 		res = TEE_ERROR_OUT_OF_MEMORY;
1707 		goto out;
1708 	}
1709 
1710 	fs_par->fat_start_address = partition_data->fat_start_address;
1711 	fs_par->max_rpmb_address = max_rpmb_block << RPMB_BLOCK_SIZE_SHIFT;
1712 
1713 	dump_fat();
1714 
1715 out:
1716 	free(fh);
1717 	free(partition_data);
1718 	return res;
1719 }
1720 
1721 /**
1722  * get_fat_start_address:
1723  * FAT start_address from fs_par.
1724  */
1725 static TEE_Result get_fat_start_address(uint32_t *addr)
1726 {
1727 	if (!fs_par)
1728 		return TEE_ERROR_NO_DATA;
1729 
1730 	*addr = fs_par->fat_start_address;
1731 
1732 	return TEE_SUCCESS;
1733 }
1734 
1735 /**
1736  * read_fat: Read FAT entries
1737  * Return matching FAT entry for read, rm rename and stat.
1738  * Build up memory pool and return matching entry for write operation.
1739  * "Last FAT entry" can be returned during write.
1740  */
1741 static TEE_Result read_fat(struct rpmb_file_handle *fh, tee_mm_pool_t *p)
1742 {
1743 	TEE_Result res = TEE_ERROR_GENERIC;
1744 	tee_mm_entry_t *mm = NULL;
1745 	struct rpmb_fat_entry *fat_entries = NULL;
1746 	uint32_t fat_address;
1747 	size_t size;
1748 	int i;
1749 	bool entry_found = false;
1750 	bool last_entry_found = false;
1751 	bool expand_fat = false;
1752 	struct rpmb_file_handle last_fh;
1753 
1754 	DMSG("fat_address %d", fh->rpmb_fat_address);
1755 
1756 	res = rpmb_fs_setup();
1757 	if (res != TEE_SUCCESS)
1758 		goto out;
1759 
1760 	res = get_fat_start_address(&fat_address);
1761 	if (res != TEE_SUCCESS)
1762 		goto out;
1763 
1764 	size = N_ENTRIES * sizeof(struct rpmb_fat_entry);
1765 	fat_entries = malloc(size);
1766 	if (!fat_entries) {
1767 		res = TEE_ERROR_OUT_OF_MEMORY;
1768 		goto out;
1769 	}
1770 
1771 	/*
1772 	 * The pool is used to represent the current RPMB layout. To find
1773 	 * a slot for the file tee_mm_alloc is called on the pool. Thus
1774 	 * if it is not NULL the entire FAT must be traversed to fill in
1775 	 * the pool.
1776 	 */
1777 	while (!last_entry_found && (!entry_found || p)) {
1778 		res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address,
1779 				    (uint8_t *)fat_entries, size, NULL, NULL);
1780 		if (res != TEE_SUCCESS)
1781 			goto out;
1782 
1783 		for (i = 0; i < N_ENTRIES; i++) {
1784 			/*
1785 			 * Look for an entry, matching filenames. (read, rm,
1786 			 * rename and stat.). Only store first filename match.
1787 			 */
1788 			if (fh->filename &&
1789 			    (strcmp(fh->filename,
1790 				    fat_entries[i].filename) == 0) &&
1791 			    (fat_entries[i].flags & FILE_IS_ACTIVE) &&
1792 			    (!entry_found)) {
1793 				entry_found = true;
1794 				fh->rpmb_fat_address = fat_address;
1795 				memcpy(&fh->fat_entry, &fat_entries[i],
1796 				       sizeof(struct rpmb_fat_entry));
1797 				if (!p)
1798 					break;
1799 			}
1800 
1801 			/* Add existing files to memory pool. (write) */
1802 			if (p) {
1803 				if ((fat_entries[i].flags & FILE_IS_ACTIVE) &&
1804 				    (fat_entries[i].data_size > 0)) {
1805 
1806 					mm = tee_mm_alloc2
1807 						(p,
1808 						 fat_entries[i].start_address,
1809 						 fat_entries[i].data_size);
1810 					if (!mm) {
1811 						res = TEE_ERROR_OUT_OF_MEMORY;
1812 						goto out;
1813 					}
1814 				}
1815 
1816 				/* Unused FAT entries can be reused (write) */
1817 				if (((fat_entries[i].flags & FILE_IS_ACTIVE) ==
1818 				     0) && (fh->rpmb_fat_address == 0)) {
1819 					fh->rpmb_fat_address = fat_address;
1820 					memcpy(&fh->fat_entry, &fat_entries[i],
1821 					       sizeof(struct rpmb_fat_entry));
1822 				}
1823 			}
1824 
1825 			if ((fat_entries[i].flags & FILE_IS_LAST_ENTRY) != 0) {
1826 				last_entry_found = true;
1827 
1828 				/*
1829 				 * If the last entry was reached and was chosen
1830 				 * by the previous check, then the FAT needs to
1831 				 * be expanded.
1832 				 * fh->rpmb_fat_address is the address chosen
1833 				 * to store the files FAT entry and fat_address
1834 				 * is the current FAT entry address being
1835 				 * compared.
1836 				 */
1837 				if (p && fh->rpmb_fat_address == fat_address)
1838 					expand_fat = true;
1839 				break;
1840 			}
1841 
1842 			/* Move to next fat_entry. */
1843 			fat_address += sizeof(struct rpmb_fat_entry);
1844 		}
1845 	}
1846 
1847 	/*
1848 	 * Represent the FAT table in the pool.
1849 	 */
1850 	if (p) {
1851 		/*
1852 		 * Since fat_address is the start of the last entry it needs to
1853 		 * be moved up by an entry.
1854 		 */
1855 		fat_address += sizeof(struct rpmb_fat_entry);
1856 
1857 		/* Make room for yet a FAT entry and add to memory pool. */
1858 		if (expand_fat)
1859 			fat_address += sizeof(struct rpmb_fat_entry);
1860 
1861 		mm = tee_mm_alloc2(p, RPMB_STORAGE_START_ADDRESS, fat_address);
1862 		if (!mm) {
1863 			res = TEE_ERROR_OUT_OF_MEMORY;
1864 			goto out;
1865 		}
1866 
1867 		if (expand_fat) {
1868 			/*
1869 			 * Point fat_address to the beginning of the new
1870 			 * entry.
1871 			 */
1872 			fat_address -= sizeof(struct rpmb_fat_entry);
1873 			memset(&last_fh, 0, sizeof(last_fh));
1874 			last_fh.fat_entry.flags = FILE_IS_LAST_ENTRY;
1875 			last_fh.rpmb_fat_address = fat_address;
1876 			res = write_fat_entry(&last_fh, true);
1877 			if (res != TEE_SUCCESS)
1878 				goto out;
1879 		}
1880 	}
1881 
1882 	if (fh->filename && !fh->rpmb_fat_address)
1883 		res = TEE_ERROR_ITEM_NOT_FOUND;
1884 
1885 out:
1886 	free(fat_entries);
1887 	return res;
1888 }
1889 
1890 static TEE_Result generate_fek(struct rpmb_fat_entry *fe, const TEE_UUID *uuid)
1891 {
1892 	TEE_Result res;
1893 
1894 again:
1895 	res = tee_fs_generate_fek(uuid, fe->fek, sizeof(fe->fek));
1896 	if (res != TEE_SUCCESS)
1897 		return res;
1898 
1899 	if (is_zero(fe->fek, sizeof(fe->fek)))
1900 		goto again;
1901 
1902 	return res;
1903 }
1904 
1905 static TEE_Result rpmb_fs_open_internal(struct rpmb_file_handle *fh,
1906 					const TEE_UUID *uuid, bool create)
1907 {
1908 	tee_mm_pool_t p;
1909 	bool pool_result;
1910 	TEE_Result res = TEE_ERROR_GENERIC;
1911 
1912 	/* We need to do setup in order to make sure fs_par is filled in */
1913 	res = rpmb_fs_setup();
1914 	if (res != TEE_SUCCESS)
1915 		goto out;
1916 
1917 	fh->uuid = uuid;
1918 	if (create) {
1919 		/* Upper memory allocation must be used for RPMB_FS. */
1920 		pool_result = tee_mm_init(&p,
1921 					  RPMB_STORAGE_START_ADDRESS,
1922 					  fs_par->max_rpmb_address,
1923 					  RPMB_BLOCK_SIZE_SHIFT,
1924 					  TEE_MM_POOL_HI_ALLOC);
1925 
1926 		if (!pool_result) {
1927 			res = TEE_ERROR_OUT_OF_MEMORY;
1928 			goto out;
1929 		}
1930 
1931 		res = read_fat(fh, &p);
1932 		tee_mm_final(&p);
1933 		if (res != TEE_SUCCESS)
1934 			goto out;
1935 	} else {
1936 		res = read_fat(fh, NULL);
1937 		if (res != TEE_SUCCESS)
1938 			goto out;
1939 	}
1940 
1941 	/*
1942 	 * If this is opened with create and the entry found was not active
1943 	 * then this is a new file and the FAT entry must be written
1944 	 */
1945 	if (create) {
1946 		if ((fh->fat_entry.flags & FILE_IS_ACTIVE) == 0) {
1947 			memset(&fh->fat_entry, 0,
1948 				sizeof(struct rpmb_fat_entry));
1949 			memcpy(fh->fat_entry.filename, fh->filename,
1950 				strlen(fh->filename));
1951 			/* Start address and size are 0 */
1952 			fh->fat_entry.flags = FILE_IS_ACTIVE;
1953 
1954 			res = generate_fek(&fh->fat_entry, uuid);
1955 			if (res != TEE_SUCCESS)
1956 				goto out;
1957 			DMSG("GENERATE FEK key: %p",
1958 			     (void *)fh->fat_entry.fek);
1959 			DHEXDUMP(fh->fat_entry.fek, sizeof(fh->fat_entry.fek));
1960 
1961 			res = write_fat_entry(fh, true);
1962 			if (res != TEE_SUCCESS)
1963 				goto out;
1964 		}
1965 	}
1966 
1967 	res = TEE_SUCCESS;
1968 
1969 out:
1970 	return res;
1971 }
1972 
1973 static void rpmb_fs_close(struct tee_file_handle **tfh)
1974 {
1975 	struct rpmb_file_handle *fh = (struct rpmb_file_handle *)*tfh;
1976 
1977 	free(fh);
1978 	*tfh = NULL;
1979 }
1980 
1981 static TEE_Result rpmb_fs_read(struct tee_file_handle *tfh, size_t pos,
1982 			       void *buf, size_t *len)
1983 {
1984 	TEE_Result res;
1985 	struct rpmb_file_handle *fh = (struct rpmb_file_handle *)tfh;
1986 	size_t size = *len;
1987 
1988 	if (!size)
1989 		return TEE_SUCCESS;
1990 
1991 	mutex_lock(&rpmb_mutex);
1992 
1993 	dump_fh(fh);
1994 
1995 	res = read_fat(fh, NULL);
1996 	if (res != TEE_SUCCESS)
1997 		goto out;
1998 
1999 	if (pos >= fh->fat_entry.data_size) {
2000 		*len = 0;
2001 		goto out;
2002 	}
2003 
2004 	size = MIN(size, fh->fat_entry.data_size - pos);
2005 	if (size) {
2006 		res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2007 				    fh->fat_entry.start_address + pos, buf,
2008 				    size, fh->fat_entry.fek, fh->uuid);
2009 		if (res != TEE_SUCCESS)
2010 			goto out;
2011 	}
2012 	*len = size;
2013 
2014 out:
2015 	mutex_unlock(&rpmb_mutex);
2016 	return res;
2017 }
2018 
2019 static TEE_Result rpmb_fs_write_primitive(struct rpmb_file_handle *fh,
2020 					  size_t pos, const void *buf,
2021 					  size_t size)
2022 {
2023 	TEE_Result res;
2024 	tee_mm_pool_t p;
2025 	bool pool_result = false;
2026 	tee_mm_entry_t *mm;
2027 	size_t end;
2028 	size_t newsize;
2029 	uint8_t *newbuf = NULL;
2030 	uintptr_t newaddr;
2031 	uint32_t start_addr;
2032 
2033 	if (!size)
2034 		return TEE_SUCCESS;
2035 
2036 	if (!fs_par) {
2037 		res = TEE_ERROR_GENERIC;
2038 		goto out;
2039 	}
2040 
2041 	dump_fh(fh);
2042 
2043 	/* Upper memory allocation must be used for RPMB_FS. */
2044 	pool_result = tee_mm_init(&p,
2045 				  RPMB_STORAGE_START_ADDRESS,
2046 				  fs_par->max_rpmb_address,
2047 				  RPMB_BLOCK_SIZE_SHIFT,
2048 				  TEE_MM_POOL_HI_ALLOC);
2049 	if (!pool_result) {
2050 		res = TEE_ERROR_OUT_OF_MEMORY;
2051 		goto out;
2052 	}
2053 
2054 	res = read_fat(fh, &p);
2055 	if (res != TEE_SUCCESS)
2056 		goto out;
2057 
2058 	if (fh->fat_entry.flags & FILE_IS_LAST_ENTRY)
2059 		panic("invalid last entry flag");
2060 
2061 	if (ADD_OVERFLOW(pos, size, &end)) {
2062 		res = TEE_ERROR_BAD_PARAMETERS;
2063 		goto out;
2064 	}
2065 	if (ADD_OVERFLOW(fh->fat_entry.start_address, pos, &start_addr)) {
2066 		res = TEE_ERROR_BAD_PARAMETERS;
2067 		goto out;
2068 	}
2069 
2070 	if (end <= fh->fat_entry.data_size &&
2071 	    tee_rpmb_write_is_atomic(CFG_RPMB_FS_DEV_ID, start_addr, size)) {
2072 
2073 		DMSG("Updating data in-place");
2074 		res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, start_addr, buf,
2075 				     size, fh->fat_entry.fek, fh->uuid);
2076 		if (res != TEE_SUCCESS)
2077 			goto out;
2078 	} else {
2079 		/*
2080 		 * File must be extended, or update cannot be atomic: allocate,
2081 		 * read, update, write.
2082 		 */
2083 
2084 		DMSG("Need to re-allocate");
2085 		newsize = MAX(end, fh->fat_entry.data_size);
2086 		mm = tee_mm_alloc(&p, newsize);
2087 		newbuf = calloc(1, newsize);
2088 		if (!mm || !newbuf) {
2089 			res = TEE_ERROR_OUT_OF_MEMORY;
2090 			goto out;
2091 		}
2092 
2093 		if (fh->fat_entry.data_size) {
2094 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2095 					    fh->fat_entry.start_address,
2096 					    newbuf, fh->fat_entry.data_size,
2097 					    fh->fat_entry.fek, fh->uuid);
2098 			if (res != TEE_SUCCESS)
2099 				goto out;
2100 		}
2101 
2102 		memcpy(newbuf + pos, buf, size);
2103 
2104 		newaddr = tee_mm_get_smem(mm);
2105 		res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf,
2106 				     newsize, fh->fat_entry.fek, fh->uuid);
2107 		if (res != TEE_SUCCESS)
2108 			goto out;
2109 
2110 		fh->fat_entry.data_size = newsize;
2111 		fh->fat_entry.start_address = newaddr;
2112 		res = write_fat_entry(fh, true);
2113 		if (res != TEE_SUCCESS)
2114 			goto out;
2115 	}
2116 
2117 out:
2118 	if (pool_result)
2119 		tee_mm_final(&p);
2120 	if (newbuf)
2121 		free(newbuf);
2122 
2123 	return res;
2124 }
2125 
2126 static TEE_Result rpmb_fs_write(struct tee_file_handle *tfh, size_t pos,
2127 				const void *buf, size_t size)
2128 {
2129 	TEE_Result res;
2130 
2131 	mutex_lock(&rpmb_mutex);
2132 	res = rpmb_fs_write_primitive((struct rpmb_file_handle *)tfh, pos,
2133 				      buf, size);
2134 	mutex_unlock(&rpmb_mutex);
2135 
2136 	return res;
2137 }
2138 
2139 static TEE_Result rpmb_fs_remove_internal(struct rpmb_file_handle *fh)
2140 {
2141 	TEE_Result res;
2142 
2143 	res = read_fat(fh, NULL);
2144 	if (res)
2145 		return res;
2146 
2147 	/* Clear this file entry. */
2148 	memset(&fh->fat_entry, 0, sizeof(struct rpmb_fat_entry));
2149 	return write_fat_entry(fh, false);
2150 }
2151 
2152 static TEE_Result rpmb_fs_remove(struct tee_pobj *po)
2153 {
2154 	TEE_Result res;
2155 	struct rpmb_file_handle *fh = alloc_file_handle(po, po->temporary);
2156 
2157 	if (!fh)
2158 		return TEE_ERROR_OUT_OF_MEMORY;
2159 
2160 	mutex_lock(&rpmb_mutex);
2161 
2162 	res = rpmb_fs_remove_internal(fh);
2163 
2164 	mutex_unlock(&rpmb_mutex);
2165 
2166 	free(fh);
2167 	return res;
2168 }
2169 
2170 static  TEE_Result rpmb_fs_rename_internal(struct tee_pobj *old,
2171 					   struct tee_pobj *new,
2172 					   bool overwrite)
2173 {
2174 	TEE_Result res = TEE_ERROR_GENERIC;
2175 	struct rpmb_file_handle *fh_old = NULL;
2176 	struct rpmb_file_handle *fh_new = NULL;
2177 
2178 	if (!old) {
2179 		res = TEE_ERROR_BAD_PARAMETERS;
2180 		goto out;
2181 	}
2182 
2183 	if (new)
2184 		fh_old = alloc_file_handle(old, old->temporary);
2185 	else
2186 		fh_old = alloc_file_handle(old, true);
2187 	if (!fh_old) {
2188 		res = TEE_ERROR_OUT_OF_MEMORY;
2189 		goto out;
2190 	}
2191 
2192 	if (new)
2193 		fh_new = alloc_file_handle(new, new->temporary);
2194 	else
2195 		fh_new = alloc_file_handle(old, false);
2196 	if (!fh_new) {
2197 		res = TEE_ERROR_OUT_OF_MEMORY;
2198 		goto out;
2199 	}
2200 
2201 	res = read_fat(fh_old, NULL);
2202 	if (res != TEE_SUCCESS)
2203 		goto out;
2204 
2205 	res = read_fat(fh_new, NULL);
2206 	if (res == TEE_SUCCESS) {
2207 		if (!overwrite) {
2208 			res = TEE_ERROR_ACCESS_CONFLICT;
2209 			goto out;
2210 		}
2211 
2212 		/* Clear this file entry. */
2213 		memset(&fh_new->fat_entry, 0, sizeof(struct rpmb_fat_entry));
2214 		res = write_fat_entry(fh_new, false);
2215 		if (res != TEE_SUCCESS)
2216 			goto out;
2217 	}
2218 
2219 	memset(fh_old->fat_entry.filename, 0, TEE_RPMB_FS_FILENAME_LENGTH);
2220 	memcpy(fh_old->fat_entry.filename, fh_new->filename,
2221 	       strlen(fh_new->filename));
2222 
2223 	res = write_fat_entry(fh_old, false);
2224 
2225 out:
2226 	free(fh_old);
2227 	free(fh_new);
2228 
2229 	return res;
2230 }
2231 
2232 static  TEE_Result rpmb_fs_rename(struct tee_pobj *old, struct tee_pobj *new,
2233 				  bool overwrite)
2234 {
2235 	TEE_Result res;
2236 
2237 	mutex_lock(&rpmb_mutex);
2238 	res = rpmb_fs_rename_internal(old, new, overwrite);
2239 	mutex_unlock(&rpmb_mutex);
2240 
2241 	return res;
2242 }
2243 
2244 static TEE_Result rpmb_fs_truncate(struct tee_file_handle *tfh, size_t length)
2245 {
2246 	struct rpmb_file_handle *fh = (struct rpmb_file_handle *)tfh;
2247 	tee_mm_pool_t p;
2248 	bool pool_result = false;
2249 	tee_mm_entry_t *mm;
2250 	uint32_t newsize;
2251 	uint8_t *newbuf = NULL;
2252 	uintptr_t newaddr;
2253 	TEE_Result res = TEE_ERROR_GENERIC;
2254 
2255 	mutex_lock(&rpmb_mutex);
2256 
2257 	if (length > INT32_MAX) {
2258 		res = TEE_ERROR_BAD_PARAMETERS;
2259 		goto out;
2260 	}
2261 	newsize = length;
2262 
2263 	res = read_fat(fh, NULL);
2264 	if (res != TEE_SUCCESS)
2265 		goto out;
2266 
2267 	if (newsize > fh->fat_entry.data_size) {
2268 		/* Extend file */
2269 
2270 		pool_result = tee_mm_init(&p,
2271 					  RPMB_STORAGE_START_ADDRESS,
2272 					  fs_par->max_rpmb_address,
2273 					  RPMB_BLOCK_SIZE_SHIFT,
2274 					  TEE_MM_POOL_HI_ALLOC);
2275 		if (!pool_result) {
2276 			res = TEE_ERROR_OUT_OF_MEMORY;
2277 			goto out;
2278 		}
2279 		res = read_fat(fh, &p);
2280 		if (res != TEE_SUCCESS)
2281 			goto out;
2282 
2283 		mm = tee_mm_alloc(&p, newsize);
2284 		newbuf = calloc(1, newsize);
2285 		if (!mm || !newbuf) {
2286 			res = TEE_ERROR_OUT_OF_MEMORY;
2287 			goto out;
2288 		}
2289 
2290 		if (fh->fat_entry.data_size) {
2291 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2292 					    fh->fat_entry.start_address,
2293 					    newbuf, fh->fat_entry.data_size,
2294 					    fh->fat_entry.fek, fh->uuid);
2295 			if (res != TEE_SUCCESS)
2296 				goto out;
2297 		}
2298 
2299 		newaddr = tee_mm_get_smem(mm);
2300 		res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf,
2301 				     newsize, fh->fat_entry.fek, fh->uuid);
2302 		if (res != TEE_SUCCESS)
2303 			goto out;
2304 
2305 	} else {
2306 		/* Don't change file location */
2307 		newaddr = fh->fat_entry.start_address;
2308 	}
2309 
2310 	/* fh->pos is unchanged */
2311 	fh->fat_entry.data_size = newsize;
2312 	fh->fat_entry.start_address = newaddr;
2313 	res = write_fat_entry(fh, true);
2314 
2315 out:
2316 	mutex_unlock(&rpmb_mutex);
2317 	if (pool_result)
2318 		tee_mm_final(&p);
2319 	if (newbuf)
2320 		free(newbuf);
2321 
2322 	return res;
2323 }
2324 
2325 static void rpmb_fs_dir_free(struct tee_fs_dir *dir)
2326 {
2327 	struct tee_rpmb_fs_dirent *e;
2328 
2329 	if (!dir)
2330 		return;
2331 
2332 	free(dir->current);
2333 
2334 	while ((e = SIMPLEQ_FIRST(&dir->next))) {
2335 		SIMPLEQ_REMOVE_HEAD(&dir->next, link);
2336 		free(e);
2337 	}
2338 }
2339 
2340 static TEE_Result rpmb_fs_dir_populate(const char *path,
2341 				       struct tee_fs_dir *dir)
2342 {
2343 	struct tee_rpmb_fs_dirent *current = NULL;
2344 	struct rpmb_fat_entry *fat_entries = NULL;
2345 	uint32_t fat_address;
2346 	uint32_t filelen;
2347 	char *filename;
2348 	int i;
2349 	bool last_entry_found = false;
2350 	bool matched;
2351 	struct tee_rpmb_fs_dirent *next = NULL;
2352 	uint32_t pathlen;
2353 	TEE_Result res = TEE_ERROR_GENERIC;
2354 	uint32_t size;
2355 	char temp;
2356 
2357 	mutex_lock(&rpmb_mutex);
2358 
2359 	res = rpmb_fs_setup();
2360 	if (res != TEE_SUCCESS)
2361 		goto out;
2362 
2363 	res = get_fat_start_address(&fat_address);
2364 	if (res != TEE_SUCCESS)
2365 		goto out;
2366 
2367 	size = N_ENTRIES * sizeof(struct rpmb_fat_entry);
2368 	fat_entries = malloc(size);
2369 	if (!fat_entries) {
2370 		res = TEE_ERROR_OUT_OF_MEMORY;
2371 		goto out;
2372 	}
2373 
2374 	pathlen = strlen(path);
2375 	while (!last_entry_found) {
2376 		res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address,
2377 				    (uint8_t *)fat_entries, size, NULL, NULL);
2378 		if (res != TEE_SUCCESS)
2379 			goto out;
2380 
2381 		for (i = 0; i < N_ENTRIES; i++) {
2382 			filename = fat_entries[i].filename;
2383 			if (fat_entries[i].flags & FILE_IS_ACTIVE) {
2384 				matched = false;
2385 				filelen = strlen(filename);
2386 				if (filelen > pathlen) {
2387 					temp = filename[pathlen];
2388 					filename[pathlen] = '\0';
2389 					if (strcmp(filename, path) == 0)
2390 						matched = true;
2391 
2392 					filename[pathlen] = temp;
2393 				}
2394 
2395 				if (matched) {
2396 					next = malloc(sizeof(*next));
2397 					if (!next) {
2398 						res = TEE_ERROR_OUT_OF_MEMORY;
2399 						goto out;
2400 					}
2401 
2402 					next->entry.oidlen = tee_hs2b(
2403 						(uint8_t *)&filename[pathlen],
2404 						next->entry.oid,
2405 						filelen - pathlen,
2406 						sizeof(next->entry.oid));
2407 					if (next->entry.oidlen) {
2408 						SIMPLEQ_INSERT_TAIL(&dir->next,
2409 								    next, link);
2410 						current = next;
2411 					} else {
2412 						free(next);
2413 						next = NULL;
2414 					}
2415 
2416 				}
2417 			}
2418 
2419 			if (fat_entries[i].flags & FILE_IS_LAST_ENTRY) {
2420 				last_entry_found = true;
2421 				break;
2422 			}
2423 
2424 			/* Move to next fat_entry. */
2425 			fat_address += sizeof(struct rpmb_fat_entry);
2426 		}
2427 	}
2428 
2429 	if (current)
2430 		res = TEE_SUCCESS;
2431 	else
2432 		res = TEE_ERROR_ITEM_NOT_FOUND; /* No directories were found. */
2433 
2434 out:
2435 	mutex_unlock(&rpmb_mutex);
2436 	if (res != TEE_SUCCESS)
2437 		rpmb_fs_dir_free(dir);
2438 	if (fat_entries)
2439 		free(fat_entries);
2440 
2441 	return res;
2442 }
2443 
2444 static TEE_Result rpmb_fs_opendir(const TEE_UUID *uuid, struct tee_fs_dir **dir)
2445 {
2446 	uint32_t len;
2447 	char path_local[TEE_RPMB_FS_FILENAME_LENGTH];
2448 	TEE_Result res = TEE_ERROR_GENERIC;
2449 	struct tee_fs_dir *rpmb_dir = NULL;
2450 
2451 	if (!uuid || !dir) {
2452 		res = TEE_ERROR_BAD_PARAMETERS;
2453 		goto out;
2454 	}
2455 
2456 	memset(path_local, 0, sizeof(path_local));
2457 	if (tee_svc_storage_create_dirname(path_local, sizeof(path_local) - 1,
2458 					   uuid) != TEE_SUCCESS) {
2459 		res = TEE_ERROR_BAD_PARAMETERS;
2460 		goto out;
2461 	}
2462 	len = strlen(path_local);
2463 
2464 	/* Add a slash to correctly match the full directory name. */
2465 	if (path_local[len - 1] != '/')
2466 		path_local[len] = '/';
2467 
2468 	rpmb_dir = calloc(1, sizeof(*rpmb_dir));
2469 	if (!rpmb_dir) {
2470 		res = TEE_ERROR_OUT_OF_MEMORY;
2471 		goto out;
2472 	}
2473 	SIMPLEQ_INIT(&rpmb_dir->next);
2474 
2475 	res = rpmb_fs_dir_populate(path_local, rpmb_dir);
2476 	if (res != TEE_SUCCESS) {
2477 		free(rpmb_dir);
2478 		rpmb_dir = NULL;
2479 		goto out;
2480 	}
2481 
2482 	*dir = rpmb_dir;
2483 
2484 out:
2485 	return res;
2486 }
2487 
2488 static TEE_Result rpmb_fs_readdir(struct tee_fs_dir *dir,
2489 				  struct tee_fs_dirent **ent)
2490 {
2491 	if (!dir)
2492 		return TEE_ERROR_GENERIC;
2493 
2494 	free(dir->current);
2495 
2496 	dir->current = SIMPLEQ_FIRST(&dir->next);
2497 	if (!dir->current)
2498 		return TEE_ERROR_ITEM_NOT_FOUND;
2499 
2500 	SIMPLEQ_REMOVE_HEAD(&dir->next, link);
2501 
2502 	*ent = &dir->current->entry;
2503 	return TEE_SUCCESS;
2504 }
2505 
2506 static void rpmb_fs_closedir(struct tee_fs_dir *dir)
2507 {
2508 	if (dir) {
2509 		rpmb_fs_dir_free(dir);
2510 		free(dir);
2511 	}
2512 }
2513 
2514 static TEE_Result rpmb_fs_open(struct tee_pobj *po, size_t *size,
2515 			       struct tee_file_handle **ret_fh)
2516 {
2517 	TEE_Result res;
2518 	struct rpmb_file_handle *fh = alloc_file_handle(po, po->temporary);
2519 
2520 	if (!fh)
2521 		return TEE_ERROR_OUT_OF_MEMORY;
2522 
2523 	mutex_lock(&rpmb_mutex);
2524 
2525 	res = rpmb_fs_open_internal(fh, &po->uuid, false);
2526 	if (!res && size)
2527 		*size = fh->fat_entry.data_size;
2528 
2529 	mutex_unlock(&rpmb_mutex);
2530 
2531 	if (res)
2532 		free(fh);
2533 	else
2534 		*ret_fh = (struct tee_file_handle *)fh;
2535 
2536 	return res;
2537 }
2538 
2539 static TEE_Result rpmb_fs_create(struct tee_pobj *po, bool overwrite,
2540 				 const void *head, size_t head_size,
2541 				 const void *attr, size_t attr_size,
2542 				 const void *data, size_t data_size,
2543 				 struct tee_file_handle **ret_fh)
2544 {
2545 	TEE_Result res;
2546 	size_t pos = 0;
2547 	struct rpmb_file_handle *fh = alloc_file_handle(po, po->temporary);
2548 
2549 	if (!fh)
2550 		return TEE_ERROR_OUT_OF_MEMORY;
2551 
2552 	mutex_lock(&rpmb_mutex);
2553 	res = rpmb_fs_open_internal(fh, &po->uuid, true);
2554 	if (res)
2555 		goto out;
2556 
2557 	if (head && head_size) {
2558 		res = rpmb_fs_write_primitive(fh, pos, head, head_size);
2559 		if (res)
2560 			goto out;
2561 		pos += head_size;
2562 	}
2563 
2564 	if (attr && attr_size) {
2565 		res = rpmb_fs_write_primitive(fh, pos, attr, attr_size);
2566 		if (res)
2567 			goto out;
2568 		pos += attr_size;
2569 	}
2570 
2571 	if (data && data_size) {
2572 		res = rpmb_fs_write_primitive(fh, pos, data, data_size);
2573 		if (res)
2574 			goto out;
2575 	}
2576 
2577 	if (po->temporary) {
2578 		/*
2579 		 * If it's a temporary filename (which it normally is)
2580 		 * rename into the final filename now that the file is
2581 		 * fully initialized.
2582 		 */
2583 		po->temporary = false;
2584 		res = rpmb_fs_rename_internal(po, NULL, overwrite);
2585 		if (res) {
2586 			po->temporary = true;
2587 			goto out;
2588 		}
2589 		/* Update file handle after rename. */
2590 		tee_svc_storage_create_filename(fh->filename,
2591 						sizeof(fh->filename),
2592 						po, false);
2593 	}
2594 
2595 out:
2596 	if (res) {
2597 		rpmb_fs_remove_internal(fh);
2598 		free(fh);
2599 	} else {
2600 		*ret_fh = (struct tee_file_handle *)fh;
2601 	}
2602 	mutex_unlock(&rpmb_mutex);
2603 
2604 	return res;
2605 }
2606 
2607 const struct tee_file_operations rpmb_fs_ops = {
2608 	.open = rpmb_fs_open,
2609 	.create = rpmb_fs_create,
2610 	.close = rpmb_fs_close,
2611 	.read = rpmb_fs_read,
2612 	.write = rpmb_fs_write,
2613 	.truncate = rpmb_fs_truncate,
2614 	.rename = rpmb_fs_rename,
2615 	.remove = rpmb_fs_remove,
2616 	.opendir = rpmb_fs_opendir,
2617 	.closedir = rpmb_fs_closedir,
2618 	.readdir = rpmb_fs_readdir,
2619 };
2620 
2621 TEE_Result tee_rpmb_fs_raw_open(const char *fname, bool create,
2622 				struct tee_file_handle **ret_fh)
2623 {
2624 	TEE_Result res;
2625 	struct rpmb_file_handle *fh = calloc(1, sizeof(*fh));
2626 	static const TEE_UUID uuid = { 0 };
2627 
2628 	if (!fh)
2629 		return TEE_ERROR_OUT_OF_MEMORY;
2630 
2631 	snprintf(fh->filename, sizeof(fh->filename), "/%s", fname);
2632 
2633 	mutex_lock(&rpmb_mutex);
2634 
2635 	res = rpmb_fs_open_internal(fh, &uuid, create);
2636 
2637 	mutex_unlock(&rpmb_mutex);
2638 
2639 	if (res) {
2640 		if (create)
2641 			rpmb_fs_remove_internal(fh);
2642 		free(fh);
2643 	} else {
2644 		*ret_fh = (struct tee_file_handle *)fh;
2645 	}
2646 
2647 	return res;
2648 }
2649