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