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