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