xref: /optee_os/core/tee/tee_rpmb_fs.c (revision c2f5808039471d8cb9ac43385b63fb8dc6aa8ac4)
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 	if (fh->pos >= fh->fat_entry.data_size) {
2113 		read_size = 0;
2114 		goto out;
2115 	}
2116 
2117 	size = MIN(size, fh->fat_entry.data_size - fh->pos);
2118 	if (size) {
2119 		res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2120 				    fh->fat_entry.start_address + fh->pos, buf,
2121 				    size, fh->fat_entry.fek);
2122 		if (res != TEE_SUCCESS) {
2123 			*errno = res;
2124 			goto out;
2125 		}
2126 	}
2127 	read_size = size;
2128 	fh->pos += size;
2129 
2130 out:
2131 	return read_size;
2132 }
2133 
2134 static int rpmb_fs_write(TEE_Result *errno, int fd, const void *buf,
2135 			size_t size)
2136 {
2137 	TEE_Result res;
2138 	struct rpmb_file_handle *fh;
2139 	tee_mm_pool_t p;
2140 	bool pool_result = false;
2141 	tee_mm_entry_t *mm;
2142 	size_t end;
2143 	size_t newsize;
2144 	uint8_t *newbuf = NULL;
2145 	uintptr_t newaddr;
2146 	uint32_t start_addr;
2147 
2148 	if (!size)
2149 		return 0;
2150 
2151 	if (!buf) {
2152 		res = TEE_ERROR_BAD_PARAMETERS;
2153 		goto out;
2154 	}
2155 
2156 	if (!fs_par) {
2157 		res = TEE_ERROR_GENERIC;
2158 		goto out;
2159 	}
2160 
2161 	fh = handle_lookup(&fs_handle_db, fd);
2162 	if (!fh) {
2163 		res = TEE_ERROR_BAD_PARAMETERS;
2164 		goto out;
2165 	}
2166 	dump_fh(fh);
2167 
2168 	/* Upper memory allocation must be used for RPMB_FS. */
2169 	pool_result = tee_mm_init(&p,
2170 				  RPMB_STORAGE_START_ADDRESS,
2171 				  fs_par->max_rpmb_address,
2172 				  RPMB_BLOCK_SIZE_SHIFT,
2173 				  TEE_MM_POOL_HI_ALLOC);
2174 	if (!pool_result) {
2175 		res = TEE_ERROR_OUT_OF_MEMORY;
2176 		goto out;
2177 	}
2178 
2179 	res = read_fat(fh, &p);
2180 	if (res != TEE_SUCCESS)
2181 		goto out;
2182 
2183 	TEE_ASSERT(!(fh->fat_entry.flags & FILE_IS_LAST_ENTRY));
2184 
2185 	end = fh->pos + size;
2186 	start_addr = fh->fat_entry.start_address + fh->pos;
2187 
2188 	if (end <= fh->fat_entry.data_size &&
2189 	    tee_rpmb_write_is_atomic(CFG_RPMB_FS_DEV_ID, start_addr, size)) {
2190 
2191 		DMSG("Updating data in-place");
2192 		res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, start_addr, buf,
2193 				     size, fh->fat_entry.fek);
2194 		if (res != TEE_SUCCESS)
2195 			goto out;
2196 	} else {
2197 		/*
2198 		 * File must be extended, or update cannot be atomic: allocate,
2199 		 * read, update, write.
2200 		 */
2201 
2202 		DMSG("Need to re-allocate");
2203 		newsize = MAX(end, fh->fat_entry.data_size);
2204 		mm = tee_mm_alloc(&p, newsize);
2205 		newbuf = calloc(newsize, 1);
2206 		if (!mm || !newbuf) {
2207 			res = TEE_ERROR_OUT_OF_MEMORY;
2208 			goto out;
2209 		}
2210 
2211 		if (fh->fat_entry.data_size) {
2212 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2213 					    fh->fat_entry.start_address,
2214 					    newbuf, fh->fat_entry.data_size,
2215 					    fh->fat_entry.fek);
2216 			if (res != TEE_SUCCESS)
2217 				goto out;
2218 		}
2219 
2220 		memcpy(newbuf + fh->pos, buf, size);
2221 
2222 		newaddr = tee_mm_get_smem(mm);
2223 		res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf,
2224 				     newsize, fh->fat_entry.fek);
2225 		if (res != TEE_SUCCESS)
2226 			goto out;
2227 
2228 		fh->fat_entry.data_size = newsize;
2229 		fh->fat_entry.start_address = newaddr;
2230 		res = write_fat_entry(fh, true);
2231 		if (res != TEE_SUCCESS)
2232 			goto out;
2233 	}
2234 
2235 	fh->pos += size;
2236 out:
2237 	if (pool_result)
2238 		tee_mm_final(&p);
2239 	if (newbuf)
2240 		free(newbuf);
2241 
2242 	if (res == TEE_SUCCESS)
2243 		return size;
2244 
2245 	*errno = res;
2246 	return -1;
2247 }
2248 
2249 static tee_fs_off_t rpmb_fs_lseek(TEE_Result *errno, int fd,
2250 				  tee_fs_off_t offset, int whence)
2251 {
2252 	struct rpmb_file_handle *fh;
2253 	TEE_Result res;
2254 	tee_fs_off_t ret = -1;
2255 	tee_fs_off_t new_pos;
2256 
2257 	fh = handle_lookup(&fs_handle_db, fd);
2258 	if (!fh)
2259 		return TEE_ERROR_BAD_PARAMETERS;
2260 
2261 	res = read_fat(fh, NULL);
2262 	if (res != TEE_SUCCESS) {
2263 		*errno = res;
2264 		goto out;
2265 	}
2266 
2267 	switch (whence) {
2268 	case TEE_FS_SEEK_SET:
2269 		new_pos = offset;
2270 		break;
2271 
2272 	case TEE_FS_SEEK_CUR:
2273 		new_pos = fh->pos + offset;
2274 		break;
2275 
2276 	case TEE_FS_SEEK_END:
2277 		new_pos = fh->fat_entry.data_size + offset;
2278 		break;
2279 
2280 	default:
2281 		*errno = TEE_ERROR_BAD_PARAMETERS;
2282 		goto out;
2283 	}
2284 
2285 	if (new_pos < 0)
2286 		new_pos = 0;
2287 
2288 	if (new_pos > TEE_DATA_MAX_POSITION) {
2289 		EMSG("Position is beyond TEE_DATA_MAX_POSITION");
2290 		*errno = TEE_ERROR_BAD_PARAMETERS;
2291 		goto out;
2292 	}
2293 
2294 	ret = fh->pos = new_pos;
2295 out:
2296 	return ret;
2297 }
2298 
2299 static int rpmb_fs_unlink(const char *filename)
2300 {
2301 	TEE_Result res = TEE_ERROR_GENERIC;
2302 	struct rpmb_file_handle *fh = NULL;
2303 
2304 	if (!filename || strlen(filename) >= TEE_RPMB_FS_FILENAME_LENGTH - 1) {
2305 		res = TEE_ERROR_BAD_PARAMETERS;
2306 		goto out;
2307 	}
2308 
2309 	fh = alloc_file_handle(filename);
2310 	if (!fh) {
2311 		res = TEE_ERROR_OUT_OF_MEMORY;
2312 		goto out;
2313 	}
2314 
2315 	res = read_fat(fh, NULL);
2316 	if (res != TEE_SUCCESS)
2317 		goto out;
2318 
2319 	/* Clear this file entry. */
2320 	memset(&fh->fat_entry, 0, sizeof(struct rpmb_fat_entry));
2321 	res = write_fat_entry(fh, false);
2322 
2323 out:
2324 	free(fh);
2325 	return (res == TEE_SUCCESS ? 0 : -1);
2326 }
2327 
2328 static  int rpmb_fs_rename(const char *old_name, const char *new_name)
2329 {
2330 	TEE_Result res = TEE_ERROR_GENERIC;
2331 	struct rpmb_file_handle *fh_old = NULL;
2332 	struct rpmb_file_handle *fh_new = NULL;
2333 	uint32_t old_len;
2334 	uint32_t new_len;
2335 
2336 	if (!old_name || !new_name) {
2337 		res = TEE_ERROR_BAD_PARAMETERS;
2338 		goto out;
2339 	}
2340 
2341 	old_len = strlen(old_name);
2342 	new_len = strlen(new_name);
2343 
2344 	if ((old_len >= TEE_RPMB_FS_FILENAME_LENGTH - 1) ||
2345 	    (new_len >= TEE_RPMB_FS_FILENAME_LENGTH - 1) || (new_len == 0)) {
2346 
2347 		res = TEE_ERROR_BAD_PARAMETERS;
2348 		goto out;
2349 	}
2350 
2351 	fh_old = alloc_file_handle(old_name);
2352 	if (!fh_old) {
2353 		res = TEE_ERROR_OUT_OF_MEMORY;
2354 		goto out;
2355 	}
2356 
2357 	fh_new = alloc_file_handle(new_name);
2358 	if (!fh_new) {
2359 		res = TEE_ERROR_OUT_OF_MEMORY;
2360 		goto out;
2361 	}
2362 
2363 	res = read_fat(fh_old, NULL);
2364 	if (res != TEE_SUCCESS)
2365 		goto out;
2366 
2367 	res = read_fat(fh_new, NULL);
2368 	if (res == TEE_SUCCESS) {
2369 		res = TEE_ERROR_BAD_PARAMETERS;
2370 		goto out;
2371 	}
2372 
2373 	memset(fh_old->fat_entry.filename, 0, TEE_RPMB_FS_FILENAME_LENGTH);
2374 	memcpy(fh_old->fat_entry.filename, new_name, new_len);
2375 
2376 	res = write_fat_entry(fh_old, false);
2377 
2378 out:
2379 	free(fh_old);
2380 	free(fh_new);
2381 
2382 	return (res == TEE_SUCCESS ? 0 : -1);
2383 }
2384 
2385 static int rpmb_fs_mkdir(const char *path __unused,
2386 			 tee_fs_mode_t mode __unused)
2387 {
2388 	/*
2389 	 * FIXME: mkdir() should really create some entry in the FAT so that
2390 	 * access() would return success when the directory exists but is
2391 	 * empty. This does not matter for the current use cases.
2392 	 */
2393 	return 0;
2394 }
2395 
2396 static int rpmb_fs_ftruncate(TEE_Result *errno, int fd, tee_fs_off_t length)
2397 {
2398 	struct rpmb_file_handle *fh;
2399 	tee_mm_pool_t p;
2400 	bool pool_result = false;
2401 	tee_mm_entry_t *mm;
2402 	uint32_t newsize;
2403 	uint8_t *newbuf = NULL;
2404 	uintptr_t newaddr;
2405 	TEE_Result res = TEE_ERROR_GENERIC;
2406 
2407 	if (length < 0 || length > INT32_MAX) {
2408 		res = TEE_ERROR_BAD_PARAMETERS;
2409 		goto out;
2410 	}
2411 	newsize = length;
2412 
2413 	fh = handle_lookup(&fs_handle_db, fd);
2414 	if (!fh) {
2415 		res = TEE_ERROR_BAD_PARAMETERS;
2416 		goto out;
2417 	}
2418 
2419 	res = read_fat(fh, NULL);
2420 	if (res != TEE_SUCCESS)
2421 		goto out;
2422 
2423 	if (newsize > fh->fat_entry.data_size) {
2424 		/* Extend file */
2425 
2426 		pool_result = tee_mm_init(&p,
2427 					  RPMB_STORAGE_START_ADDRESS,
2428 					  fs_par->max_rpmb_address,
2429 					  RPMB_BLOCK_SIZE_SHIFT,
2430 					  TEE_MM_POOL_HI_ALLOC);
2431 		if (!pool_result) {
2432 			res = TEE_ERROR_OUT_OF_MEMORY;
2433 			goto out;
2434 		}
2435 		res = read_fat(fh, &p);
2436 		if (res != TEE_SUCCESS)
2437 			goto out;
2438 
2439 		mm = tee_mm_alloc(&p, newsize);
2440 		newbuf = calloc(newsize, 1);
2441 		if (!mm || !newbuf) {
2442 			res = TEE_ERROR_OUT_OF_MEMORY;
2443 			goto out;
2444 		}
2445 
2446 		if (fh->fat_entry.data_size) {
2447 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2448 					    fh->fat_entry.start_address,
2449 					    newbuf, fh->fat_entry.data_size,
2450 					    fh->fat_entry.fek);
2451 			if (res != TEE_SUCCESS)
2452 				goto out;
2453 		}
2454 
2455 		newaddr = tee_mm_get_smem(mm);
2456 		res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf,
2457 				     newsize, fh->fat_entry.fek);
2458 		if (res != TEE_SUCCESS)
2459 			goto out;
2460 
2461 	} else {
2462 		/* Don't change file location */
2463 		newaddr = fh->fat_entry.start_address;
2464 	}
2465 
2466 	/* fh->pos is unchanged */
2467 	fh->fat_entry.data_size = newsize;
2468 	fh->fat_entry.start_address = newaddr;
2469 	res = write_fat_entry(fh, true);
2470 
2471 out:
2472 	if (pool_result)
2473 		tee_mm_final(&p);
2474 	if (newbuf)
2475 		free(newbuf);
2476 
2477 	if (res == TEE_SUCCESS)
2478 		return 0;
2479 
2480 	*errno = res;
2481 	return -1;
2482 }
2483 
2484 static void rpmb_fs_dir_free(struct tee_fs_dir *dir)
2485 {
2486 	struct tee_rpmb_fs_dirent *e;
2487 
2488 	if (!dir)
2489 		return;
2490 
2491 	free(dir->current);
2492 
2493 	while ((e = SIMPLEQ_FIRST(&dir->next))) {
2494 		SIMPLEQ_REMOVE_HEAD(&dir->next, link);
2495 		free(e);
2496 	}
2497 }
2498 
2499 static TEE_Result rpmb_fs_dir_populate(const char *path,
2500 				       struct tee_fs_dir *dir)
2501 {
2502 	struct tee_rpmb_fs_dirent *current = NULL;
2503 	struct rpmb_fat_entry *fat_entries = NULL;
2504 	uint32_t fat_address;
2505 	uint32_t filelen;
2506 	char *filename;
2507 	int i;
2508 	bool last_entry_found = false;
2509 	bool matched;
2510 	struct tee_rpmb_fs_dirent *next = NULL;
2511 	uint32_t pathlen;
2512 	TEE_Result res = TEE_ERROR_GENERIC;
2513 	uint32_t size;
2514 	char temp;
2515 
2516 	res = rpmb_fs_setup();
2517 	if (res != TEE_SUCCESS)
2518 		goto out;
2519 
2520 	res = get_fat_start_address(&fat_address);
2521 	if (res != TEE_SUCCESS)
2522 		goto out;
2523 
2524 	size = N_ENTRIES * sizeof(struct rpmb_fat_entry);
2525 	fat_entries = malloc(size);
2526 	if (!fat_entries) {
2527 		res = TEE_ERROR_OUT_OF_MEMORY;
2528 		goto out;
2529 	}
2530 
2531 	pathlen = strlen(path);
2532 	while (!last_entry_found) {
2533 		res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address,
2534 				    (uint8_t *)fat_entries, size, NULL);
2535 		if (res != TEE_SUCCESS)
2536 			goto out;
2537 
2538 		for (i = 0; i < N_ENTRIES; i++) {
2539 			filename = fat_entries[i].filename;
2540 			if (fat_entries[i].flags & FILE_IS_ACTIVE) {
2541 				matched = false;
2542 				filelen = strlen(filename);
2543 				if (filelen > pathlen) {
2544 					temp = filename[pathlen];
2545 					filename[pathlen] = '\0';
2546 					if (strcmp(filename, path) == 0)
2547 						matched = true;
2548 
2549 					filename[pathlen] = temp;
2550 				}
2551 
2552 				if (matched) {
2553 					next = malloc(sizeof(*next));
2554 					if (!next) {
2555 						res = TEE_ERROR_OUT_OF_MEMORY;
2556 						goto out;
2557 					}
2558 
2559 					memset(next, 0, sizeof(*next));
2560 					next->entry.d_name = next->name;
2561 					memcpy(next->name,
2562 						&filename[pathlen],
2563 						filelen - pathlen);
2564 
2565 					SIMPLEQ_INSERT_TAIL(&dir->next, next,
2566 							    link);
2567 					current = next;
2568 				}
2569 			}
2570 
2571 			if (fat_entries[i].flags & FILE_IS_LAST_ENTRY) {
2572 				last_entry_found = true;
2573 				break;
2574 			}
2575 
2576 			/* Move to next fat_entry. */
2577 			fat_address += sizeof(struct rpmb_fat_entry);
2578 		}
2579 	}
2580 
2581 	/* No directories were found. */
2582 	if (!current) {
2583 		res = TEE_ERROR_NO_DATA;
2584 		goto out;
2585 	}
2586 
2587 	res = TEE_SUCCESS;
2588 
2589 out:
2590 	if (res != TEE_SUCCESS)
2591 		rpmb_fs_dir_free(dir);
2592 	if (fat_entries)
2593 		free(fat_entries);
2594 
2595 	return res;
2596 }
2597 
2598 static TEE_Result rpmb_fs_opendir_internal(const char *path,
2599 					   struct tee_fs_dir **dir)
2600 {
2601 	uint32_t len;
2602 	uint32_t max_size;
2603 	char path_local[TEE_RPMB_FS_FILENAME_LENGTH];
2604 	TEE_Result res = TEE_ERROR_GENERIC;
2605 	struct tee_fs_dir *rpmb_dir = NULL;
2606 
2607 	if (!path || !dir) {
2608 		res = TEE_ERROR_BAD_PARAMETERS;
2609 		goto out;
2610 	}
2611 
2612 	/*
2613 	 * There must be room for at least the NULL char and a char for the
2614 	 * filename after the path.
2615 	 */
2616 	max_size = TEE_RPMB_FS_FILENAME_LENGTH - 2;
2617 	len = strlen(path);
2618 	if (len > max_size || len == 0) {
2619 		res = TEE_ERROR_BAD_PARAMETERS;
2620 		goto out;
2621 	}
2622 
2623 	memset(path_local, 0, sizeof(path_local));
2624 	memcpy(path_local, path, len);
2625 
2626 	/* Add a slash to correctly match the full directory name. */
2627 	if (path_local[len - 1] != '/')
2628 		path_local[len] = '/';
2629 
2630 	rpmb_dir = calloc(1, sizeof(*rpmb_dir));
2631 	if (!rpmb_dir) {
2632 		res = TEE_ERROR_OUT_OF_MEMORY;
2633 		goto out;
2634 	}
2635 	SIMPLEQ_INIT(&rpmb_dir->next);
2636 
2637 	res = rpmb_fs_dir_populate(path_local, rpmb_dir);
2638 	if (res != TEE_SUCCESS) {
2639 		free(rpmb_dir);
2640 		rpmb_dir = NULL;
2641 		goto out;
2642 	}
2643 
2644 	*dir = rpmb_dir;
2645 
2646 out:
2647 	return res;
2648 }
2649 
2650 static struct tee_fs_dir *rpmb_fs_opendir(const char *path)
2651 {
2652 	struct tee_fs_dir *dir = NULL;
2653 	TEE_Result res = TEE_ERROR_GENERIC;
2654 
2655 	res = rpmb_fs_opendir_internal(path, &dir);
2656 	if (res != TEE_SUCCESS)
2657 		dir = NULL;
2658 
2659 	return dir;
2660 }
2661 
2662 
2663 static struct tee_fs_dirent *rpmb_fs_readdir(struct tee_fs_dir *dir)
2664 {
2665 	if (!dir)
2666 		return NULL;
2667 
2668 	free(dir->current);
2669 
2670 	dir->current = SIMPLEQ_FIRST(&dir->next);
2671 	if (!dir->current)
2672 		return NULL;
2673 
2674 	SIMPLEQ_REMOVE_HEAD(&dir->next, link);
2675 
2676 	return &dir->current->entry;
2677 }
2678 
2679 static int rpmb_fs_closedir(struct tee_fs_dir *dir)
2680 {
2681 	TEE_Result res = TEE_ERROR_GENERIC;
2682 
2683 	if (!dir) {
2684 		res = TEE_SUCCESS;
2685 		goto out;
2686 	}
2687 
2688 	rpmb_fs_dir_free(dir);
2689 	free(dir);
2690 	res = TEE_SUCCESS;
2691 out:
2692 	if (res == TEE_SUCCESS)
2693 		return 0;
2694 
2695 	return -1;
2696 }
2697 
2698 static int rpmb_fs_rmdir(const char *path)
2699 {
2700 	struct tee_fs_dir *dir = NULL;
2701 	TEE_Result res = TEE_ERROR_GENERIC;
2702 	int ret = -1;
2703 
2704 	/* Open the directory anyting other than NO_DATA is a failure */
2705 	res = rpmb_fs_opendir_internal(path, &dir);
2706 	if (res == TEE_SUCCESS) {
2707 		rpmb_fs_closedir(dir);
2708 		ret = -1;
2709 
2710 	} else if (res == TEE_ERROR_NO_DATA) {
2711 		ret = 0;
2712 
2713 	} else {
2714 		/* The case any other failure is returned */
2715 		ret = -1;
2716 	}
2717 
2718 
2719 	return ret;
2720 }
2721 
2722 static int rpmb_fs_stat(const char *filename, struct tee_rpmb_fs_stat *stat)
2723 {
2724 	TEE_Result res = TEE_ERROR_GENERIC;
2725 	struct rpmb_file_handle *fh = NULL;
2726 
2727 	if (!stat || !filename) {
2728 		res = TEE_ERROR_BAD_PARAMETERS;
2729 		goto out;
2730 	}
2731 
2732 	fh = alloc_file_handle(filename);
2733 	if (!fh) {
2734 		res = TEE_ERROR_OUT_OF_MEMORY;
2735 		goto out;
2736 	}
2737 
2738 	res = read_fat(fh, NULL);
2739 	if (res != TEE_SUCCESS)
2740 		goto out;
2741 
2742 	stat->size = (size_t)fh->fat_entry.data_size;
2743 	stat->reserved = 0;
2744 
2745 out:
2746 	free(fh);
2747 	return (res == TEE_SUCCESS ? 0 : -1);
2748 }
2749 
2750 static int rpmb_fs_access(const char *filename, int mode)
2751 {
2752 	struct tee_rpmb_fs_stat stat;
2753 	TEE_Result res;
2754 
2755 	/* Mode is currently ignored, this only checks for existence */
2756 	(void)mode;
2757 
2758 	res = rpmb_fs_stat(filename, &stat);
2759 
2760 	if (res == TEE_SUCCESS)
2761 		return 0;
2762 
2763 	return -1;
2764 }
2765 
2766 static int rpmb_fs_open(TEE_Result *errno, const char *file, int flags, ...)
2767 {
2768 	int fd = -1;
2769 	size_t len;
2770 
2771 	assert(errno);
2772 	*errno = TEE_SUCCESS;
2773 
2774 	len = strlen(file) + 1;
2775 	if (len > TEE_FS_NAME_MAX) {
2776 		*errno = TEE_ERROR_BAD_PARAMETERS;
2777 		goto exit;
2778 	}
2779 
2780 	/*
2781 	 * try to open file without O_CREATE flag, if failed try again with
2782 	 * O_CREATE flag (to distinguish whether it's a new file or not)
2783 	 */
2784 	fd = rpmb_fs_open_internal(file, flags & (~TEE_FS_O_CREATE));
2785 	if (fd < 0) {
2786 		if (!(flags & TEE_FS_O_CREATE)) {
2787 			*errno = TEE_ERROR_ITEM_NOT_FOUND;
2788 			goto exit;
2789 		}
2790 
2791 		fd = rpmb_fs_open_internal(file, flags);
2792 		/* File has been created */
2793 	} else {
2794 		/* File already exists */
2795 		if ((flags & TEE_FS_O_CREATE) && (flags & TEE_FS_O_EXCL)) {
2796 			*errno = TEE_ERROR_ACCESS_CONFLICT;
2797 			rpmb_fs_close(fd);
2798 		}
2799 	}
2800 
2801 exit:
2802 	return fd;
2803 }
2804 
2805 const struct tee_file_operations rpmb_fs_ops = {
2806 	.open = rpmb_fs_open,
2807 	.close = rpmb_fs_close,
2808 	.read = rpmb_fs_read,
2809 	.write = rpmb_fs_write,
2810 	.lseek = rpmb_fs_lseek,
2811 	.ftruncate = rpmb_fs_ftruncate,
2812 	.rename = rpmb_fs_rename,
2813 	.unlink = rpmb_fs_unlink,
2814 	.mkdir = rpmb_fs_mkdir,
2815 	.opendir = rpmb_fs_opendir,
2816 	.closedir = rpmb_fs_closedir,
2817 	.readdir = rpmb_fs_readdir,
2818 	.rmdir = rpmb_fs_rmdir,
2819 	.access = rpmb_fs_access
2820 };
2821