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