xref: /optee_os/core/tee/tee_rpmb_fs.c (revision 51ac0e23b5c2b3c84469a0de79c9f027a46d5747)
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 static TEE_Result tee_rpmb_read_unlocked(uint16_t dev_id, uint32_t addr,
1204 					 uint8_t *data, uint32_t len,
1205 					 uint8_t *fek)
1206 {
1207 	TEE_Result res = TEE_ERROR_GENERIC;
1208 	struct tee_rpmb_mem mem = { 0 };
1209 	uint16_t msg_type;
1210 	uint8_t nonce[RPMB_NONCE_SIZE];
1211 	uint8_t hmac[RPMB_KEY_MAC_SIZE];
1212 	struct rpmb_req *req = NULL;
1213 	struct rpmb_data_frame *resp = NULL;
1214 	struct rpmb_raw_data rawdata;
1215 	uint32_t req_size;
1216 	uint32_t resp_size;
1217 	uint16_t blk_idx;
1218 	uint16_t blkcnt;
1219 	uint8_t byte_offset;
1220 
1221 	if (!data || !len)
1222 		return TEE_ERROR_BAD_PARAMETERS;
1223 
1224 	blk_idx = addr / RPMB_DATA_SIZE;
1225 	byte_offset = addr % RPMB_DATA_SIZE;
1226 
1227 	blkcnt =
1228 	    ROUNDUP(len + byte_offset, RPMB_DATA_SIZE) / RPMB_DATA_SIZE;
1229 	res = tee_rpmb_init(dev_id);
1230 	if (res != TEE_SUCCESS)
1231 		goto func_exit;
1232 
1233 	req_size = sizeof(struct rpmb_req) + RPMB_DATA_FRAME_SIZE;
1234 	resp_size = RPMB_DATA_FRAME_SIZE * blkcnt;
1235 	res = tee_rpmb_alloc(req_size, resp_size, &mem,
1236 			     (void *)&req, (void *)&resp);
1237 	if (res != TEE_SUCCESS)
1238 		goto func_exit;
1239 
1240 	msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_READ;
1241 	res = crypto_ops.prng.read(nonce, RPMB_NONCE_SIZE);
1242 	if (res != TEE_SUCCESS)
1243 		goto func_exit;
1244 
1245 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1246 	rawdata.msg_type = msg_type;
1247 	rawdata.nonce = nonce;
1248 	rawdata.blk_idx = &blk_idx;
1249 	res = tee_rpmb_req_pack(req, &rawdata, 1, dev_id, NULL);
1250 	if (res != TEE_SUCCESS)
1251 		goto func_exit;
1252 
1253 	req->block_count = blkcnt;
1254 
1255 	DMSG("Read %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""),
1256 	     blk_idx);
1257 
1258 	res = tee_rpmb_invoke(&mem);
1259 	if (res != TEE_SUCCESS)
1260 		goto func_exit;
1261 
1262 	msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_READ;
1263 
1264 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1265 	rawdata.msg_type = msg_type;
1266 	rawdata.block_count = &blkcnt;
1267 	rawdata.blk_idx = &blk_idx;
1268 	rawdata.nonce = nonce;
1269 	rawdata.key_mac = hmac;
1270 	rawdata.data = data;
1271 
1272 	rawdata.len = len;
1273 	rawdata.byte_offset = byte_offset;
1274 
1275 	res = tee_rpmb_resp_unpack_verify(resp, &rawdata, blkcnt, fek);
1276 	if (res != TEE_SUCCESS)
1277 		goto func_exit;
1278 
1279 	res = TEE_SUCCESS;
1280 
1281 func_exit:
1282 	tee_rpmb_free(&mem);
1283 	return res;
1284 }
1285 
1286 static TEE_Result tee_rpmb_write_blk(uint16_t dev_id, uint16_t blk_idx,
1287 				     const uint8_t *data_blks, uint16_t blkcnt,
1288 				     const uint8_t *fek)
1289 {
1290 	TEE_Result res;
1291 	struct tee_rpmb_mem mem;
1292 	uint16_t msg_type;
1293 	uint32_t wr_cnt;
1294 	uint8_t hmac[RPMB_KEY_MAC_SIZE];
1295 	struct rpmb_req *req = NULL;
1296 	struct rpmb_data_frame *resp = NULL;
1297 	struct rpmb_raw_data rawdata;
1298 	uint32_t req_size;
1299 	uint32_t resp_size;
1300 	uint32_t nbr_writes;
1301 	uint16_t tmp_blkcnt;
1302 	uint16_t tmp_blk_idx;
1303 	uint16_t i;
1304 
1305 	DMSG("Write %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""),
1306 	     blk_idx);
1307 
1308 	if (!data_blks || !blkcnt)
1309 		return TEE_ERROR_BAD_PARAMETERS;
1310 
1311 	res = tee_rpmb_init(dev_id);
1312 	if (res != TEE_SUCCESS)
1313 		return res;
1314 
1315 	/*
1316 	 * We need to split data when block count
1317 	 * is bigger than reliable block write count.
1318 	 */
1319 	if (blkcnt < rpmb_ctx->rel_wr_blkcnt)
1320 		req_size = sizeof(struct rpmb_req) +
1321 		    RPMB_DATA_FRAME_SIZE * blkcnt;
1322 	else
1323 		req_size = sizeof(struct rpmb_req) +
1324 		    RPMB_DATA_FRAME_SIZE * rpmb_ctx->rel_wr_blkcnt;
1325 
1326 	resp_size = RPMB_DATA_FRAME_SIZE;
1327 	res = tee_rpmb_alloc(req_size, resp_size, &mem,
1328 			     (void *)&req, (void *)&resp);
1329 	if (res != TEE_SUCCESS)
1330 		return res;
1331 
1332 	nbr_writes = blkcnt / rpmb_ctx->rel_wr_blkcnt;
1333 	if (blkcnt % rpmb_ctx->rel_wr_blkcnt > 0)
1334 		nbr_writes += 1;
1335 
1336 	tmp_blkcnt = rpmb_ctx->rel_wr_blkcnt;
1337 	tmp_blk_idx = blk_idx;
1338 	for (i = 0; i < nbr_writes; i++) {
1339 		/*
1340 		 * To handle the last write of block count which is
1341 		 * equal or smaller than reliable write block count.
1342 		 */
1343 		if (i == nbr_writes - 1)
1344 			tmp_blkcnt = blkcnt - rpmb_ctx->rel_wr_blkcnt *
1345 			    (nbr_writes - 1);
1346 
1347 		msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE;
1348 		wr_cnt = rpmb_ctx->wr_cnt;
1349 
1350 		memset(req, 0x00, req_size);
1351 		memset(resp, 0x00, resp_size);
1352 
1353 		memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1354 		rawdata.msg_type = msg_type;
1355 		rawdata.block_count = &tmp_blkcnt;
1356 		rawdata.blk_idx = &tmp_blk_idx;
1357 		rawdata.write_counter = &wr_cnt;
1358 		rawdata.key_mac = hmac;
1359 		rawdata.data = (uint8_t *)data_blks +
1360 				i * rpmb_ctx->rel_wr_blkcnt * RPMB_DATA_SIZE;
1361 
1362 		res = tee_rpmb_req_pack(req, &rawdata, tmp_blkcnt, dev_id,
1363 					fek);
1364 		if (res != TEE_SUCCESS)
1365 			goto out;
1366 
1367 		res = tee_rpmb_invoke(&mem);
1368 		if (res != TEE_SUCCESS) {
1369 			/*
1370 			 * To force wr_cnt sync next time, as it might get
1371 			 * out of sync due to inconsistent operation result!
1372 			 */
1373 			rpmb_ctx->wr_cnt_synced = false;
1374 			goto out;
1375 		}
1376 
1377 		msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE;
1378 
1379 		memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1380 		rawdata.msg_type = msg_type;
1381 		rawdata.block_count = &tmp_blkcnt;
1382 		rawdata.blk_idx = &tmp_blk_idx;
1383 		rawdata.write_counter = &wr_cnt;
1384 		rawdata.key_mac = hmac;
1385 
1386 		res = tee_rpmb_resp_unpack_verify(resp, &rawdata, 1, NULL);
1387 		if (res != TEE_SUCCESS) {
1388 			/*
1389 			 * To force wr_cnt sync next time, as it might get
1390 			 * out of sync due to inconsistent operation result!
1391 			 */
1392 			rpmb_ctx->wr_cnt_synced = false;
1393 			goto out;
1394 		}
1395 
1396 		tmp_blk_idx += tmp_blkcnt;
1397 	}
1398 
1399 out:
1400 	tee_rpmb_free(&mem);
1401 	return res;
1402 }
1403 
1404 /*
1405  * Read RPMB data in bytes.
1406  *
1407  * @dev_id     Device ID of the eMMC device.
1408  * @addr       Byte address of data.
1409  * @data       Pointer to the data.
1410  * @len        Size of data in bytes.
1411  * @fek        Encrypted File Encryption Key or NULL.
1412  */
1413 static TEE_Result tee_rpmb_read(uint16_t dev_id, uint32_t addr, uint8_t *data,
1414 				uint32_t len, uint8_t *fek)
1415 {
1416 	TEE_Result res;
1417 
1418 	mutex_lock(&rpmb_mutex);
1419 	res = tee_rpmb_read_unlocked(dev_id, addr, data, len, fek);
1420 	mutex_unlock(&rpmb_mutex);
1421 
1422 	return res;
1423 }
1424 
1425 static bool tee_rpmb_write_is_atomic(uint16_t dev_id __unused, uint32_t addr,
1426 				     uint32_t len)
1427 {
1428 	uint8_t byte_offset = addr % RPMB_DATA_SIZE;
1429 	uint16_t blkcnt = ROUNDUP(len + byte_offset,
1430 				  RPMB_DATA_SIZE) / RPMB_DATA_SIZE;
1431 
1432 	return (blkcnt <= rpmb_ctx->rel_wr_blkcnt);
1433 }
1434 
1435 /*
1436  * Write RPMB data in bytes.
1437  *
1438  * @dev_id     Device ID of the eMMC device.
1439  * @addr       Byte address of data.
1440  * @data       Pointer to the data.
1441  * @len        Size of data in bytes.
1442  * @fek        Encrypted File Encryption Key or NULL.
1443  */
1444 static TEE_Result tee_rpmb_write(uint16_t dev_id, uint32_t addr,
1445 				 const uint8_t *data, uint32_t len,
1446 				 uint8_t *fek)
1447 {
1448 	TEE_Result res = TEE_ERROR_GENERIC;
1449 	uint8_t *data_tmp = NULL;
1450 	uint16_t blk_idx;
1451 	uint16_t blkcnt;
1452 	uint8_t byte_offset;
1453 
1454 	mutex_lock(&rpmb_mutex);
1455 
1456 	blk_idx = addr / RPMB_DATA_SIZE;
1457 	byte_offset = addr % RPMB_DATA_SIZE;
1458 
1459 	blkcnt =
1460 	    ROUNDUP(len + byte_offset, RPMB_DATA_SIZE) / RPMB_DATA_SIZE;
1461 
1462 	if (byte_offset == 0 && (len % RPMB_DATA_SIZE) == 0) {
1463 		res = tee_rpmb_write_blk(dev_id, blk_idx, data, blkcnt, fek);
1464 		if (res != TEE_SUCCESS)
1465 			goto func_exit;
1466 	} else {
1467 		data_tmp = calloc(blkcnt, RPMB_DATA_SIZE);
1468 		if (!data_tmp) {
1469 			res = TEE_ERROR_OUT_OF_MEMORY;
1470 			goto func_exit;
1471 		}
1472 
1473 		/* Read the complete blocks */
1474 		res = tee_rpmb_read_unlocked(dev_id, blk_idx * RPMB_DATA_SIZE,
1475 					     data_tmp,
1476 					     blkcnt * RPMB_DATA_SIZE, fek);
1477 		if (res != TEE_SUCCESS)
1478 			goto func_exit;
1479 
1480 		/* Partial update of the data blocks */
1481 		memcpy(data_tmp + byte_offset, data, len);
1482 
1483 		res = tee_rpmb_write_blk(dev_id, blk_idx, data_tmp, blkcnt,
1484 					 fek);
1485 		if (res != TEE_SUCCESS)
1486 			goto func_exit;
1487 	}
1488 
1489 	res = TEE_SUCCESS;
1490 
1491 func_exit:
1492 	mutex_unlock(&rpmb_mutex);
1493 	free(data_tmp);
1494 	return res;
1495 }
1496 
1497 /*
1498  * Read the RPMB write counter.
1499  *
1500  * @dev_id     Device ID of the eMMC device.
1501  * @counter    Pointer to the counter.
1502  */
1503 static TEE_Result tee_rpmb_get_write_counter(uint16_t dev_id,
1504 					     uint32_t *counter)
1505 {
1506 	TEE_Result res = TEE_SUCCESS;
1507 
1508 	if (!counter)
1509 		return TEE_ERROR_BAD_PARAMETERS;
1510 
1511 	mutex_lock(&rpmb_mutex);
1512 
1513 	if (!rpmb_ctx || !rpmb_ctx->wr_cnt_synced) {
1514 		res = tee_rpmb_init(dev_id);
1515 		if (res != TEE_SUCCESS)
1516 			goto func_exit;
1517 	}
1518 
1519 	*counter = rpmb_ctx->wr_cnt;
1520 
1521 func_exit:
1522 	mutex_unlock(&rpmb_mutex);
1523 	return res;
1524 }
1525 
1526 /*
1527  * Read the RPMB max block.
1528  *
1529  * @dev_id     Device ID of the eMMC device.
1530  * @counter    Pointer to receive the max block.
1531  */
1532 static TEE_Result tee_rpmb_get_max_block(uint16_t dev_id, uint32_t *max_block)
1533 {
1534 	TEE_Result res = TEE_SUCCESS;
1535 
1536 	if (!max_block)
1537 		return TEE_ERROR_BAD_PARAMETERS;
1538 
1539 	mutex_lock(&rpmb_mutex);
1540 
1541 	if (!rpmb_ctx || !rpmb_ctx->dev_info_synced) {
1542 		res = tee_rpmb_init(dev_id);
1543 		if (res != TEE_SUCCESS)
1544 			goto func_exit;
1545 	}
1546 
1547 	*max_block = rpmb_ctx->max_blk_idx;
1548 
1549 func_exit:
1550 	mutex_unlock(&rpmb_mutex);
1551 	return res;
1552 }
1553 
1554 /*
1555  * End of lower interface to RPMB device
1556  */
1557 
1558 static TEE_Result get_fat_start_address(uint32_t *addr);
1559 
1560 static void dump_fat(void)
1561 {
1562 	TEE_Result res = TEE_ERROR_GENERIC;
1563 	struct rpmb_fat_entry *fat_entries = NULL;
1564 	uint32_t fat_address;
1565 	size_t size;
1566 	int i;
1567 	bool last_entry_found = false;
1568 
1569 	res = get_fat_start_address(&fat_address);
1570 	if (res != TEE_SUCCESS)
1571 		goto out;
1572 
1573 	size = N_ENTRIES * sizeof(struct rpmb_fat_entry);
1574 	fat_entries = malloc(size);
1575 	if (!fat_entries) {
1576 		res = TEE_ERROR_OUT_OF_MEMORY;
1577 		goto out;
1578 	}
1579 
1580 	while (!last_entry_found) {
1581 		res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address,
1582 				    (uint8_t *)fat_entries, size, NULL);
1583 		if (res != TEE_SUCCESS)
1584 			goto out;
1585 
1586 		for (i = 0; i < N_ENTRIES; i++) {
1587 
1588 			FMSG("flags 0x%x, size %d, address 0x%x, filename '%s'",
1589 				fat_entries[i].flags,
1590 				fat_entries[i].data_size,
1591 				fat_entries[i].start_address,
1592 				fat_entries[i].filename);
1593 
1594 			if ((fat_entries[i].flags & FILE_IS_LAST_ENTRY) != 0) {
1595 				last_entry_found = true;
1596 				break;
1597 			}
1598 
1599 			/* Move to next fat_entry. */
1600 			fat_address += sizeof(struct rpmb_fat_entry);
1601 		}
1602 	}
1603 
1604 out:
1605 	free(fat_entries);
1606 }
1607 
1608 #if (TRACE_LEVEL >= TRACE_DEBUG)
1609 static void dump_fh(struct rpmb_file_handle *fh)
1610 {
1611 	DMSG("fh->filename=%s", fh->filename);
1612 	DMSG("fh->pos=%u", fh->pos);
1613 	DMSG("fh->rpmb_fat_address=%u", fh->rpmb_fat_address);
1614 	DMSG("fh->fat_entry.start_address=%u", fh->fat_entry.start_address);
1615 	DMSG("fh->fat_entry.data_size=%u", fh->fat_entry.data_size);
1616 }
1617 #else
1618 static void dump_fh(struct rpmb_file_handle *fh __unused)
1619 {
1620 }
1621 #endif
1622 
1623 static struct rpmb_file_handle *alloc_file_handle(const char *filename)
1624 {
1625 	struct rpmb_file_handle *fh = NULL;
1626 
1627 	fh = calloc(1, sizeof(struct rpmb_file_handle));
1628 	if (!fh)
1629 		return NULL;
1630 
1631 	if (filename)
1632 		strlcpy(fh->filename, filename, sizeof(fh->filename));
1633 
1634 	return fh;
1635 }
1636 
1637 /**
1638  * write_fat_entry: Store info in a fat_entry to RPMB.
1639  */
1640 static TEE_Result write_fat_entry(struct rpmb_file_handle *fh,
1641 				  bool update_write_counter)
1642 {
1643 	TEE_Result res = TEE_ERROR_GENERIC;
1644 
1645 	/* Protect partition data. */
1646 	if (fh->rpmb_fat_address < sizeof(struct rpmb_fs_partition)) {
1647 		res = TEE_ERROR_ACCESS_CONFLICT;
1648 		goto out;
1649 	}
1650 
1651 	if (fh->rpmb_fat_address % sizeof(struct rpmb_fat_entry) != 0) {
1652 		res = TEE_ERROR_BAD_PARAMETERS;
1653 		goto out;
1654 	}
1655 
1656 	if (update_write_counter) {
1657 		res = tee_rpmb_get_write_counter(CFG_RPMB_FS_DEV_ID,
1658 						 &fh->fat_entry.write_counter);
1659 		if (res != TEE_SUCCESS)
1660 			goto out;
1661 	}
1662 
1663 	res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, fh->rpmb_fat_address,
1664 			     (uint8_t *)&fh->fat_entry,
1665 			     sizeof(struct rpmb_fat_entry), NULL);
1666 
1667 	dump_fat();
1668 
1669 out:
1670 	return res;
1671 }
1672 
1673 /**
1674  * rpmb_fs_setup: Setup rpmb fs.
1675  * Set initial partition and FS values and write to RPMB.
1676  * Store frequently used data in RAM.
1677  */
1678 static TEE_Result rpmb_fs_setup(void)
1679 {
1680 	TEE_Result res = TEE_ERROR_GENERIC;
1681 	struct rpmb_fs_partition *partition_data = NULL;
1682 	struct rpmb_file_handle *fh = NULL;
1683 	uint32_t max_rpmb_block = 0;
1684 
1685 	if (fs_par) {
1686 		res = TEE_SUCCESS;
1687 		goto out;
1688 	}
1689 
1690 	res = tee_rpmb_get_max_block(CFG_RPMB_FS_DEV_ID, &max_rpmb_block);
1691 	if (res != TEE_SUCCESS)
1692 		goto out;
1693 
1694 	partition_data = calloc(1, sizeof(struct rpmb_fs_partition));
1695 	if (!partition_data) {
1696 		res = TEE_ERROR_OUT_OF_MEMORY;
1697 		goto out;
1698 	}
1699 
1700 	res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS,
1701 			    (uint8_t *)partition_data,
1702 			    sizeof(struct rpmb_fs_partition), NULL);
1703 	if (res != TEE_SUCCESS)
1704 		goto out;
1705 
1706 #ifndef CFG_RPMB_RESET_FAT
1707 	if (partition_data->rpmb_fs_magic == RPMB_FS_MAGIC) {
1708 		if (partition_data->fs_version == FS_VERSION) {
1709 			res = TEE_SUCCESS;
1710 			goto store_fs_par;
1711 		} else {
1712 			/* Wrong software is in use. */
1713 			res = TEE_ERROR_ACCESS_DENIED;
1714 			goto out;
1715 		}
1716 	}
1717 #else
1718 	EMSG("**** Clearing Storage ****");
1719 #endif
1720 
1721 	/* Setup new partition data. */
1722 	partition_data->rpmb_fs_magic = RPMB_FS_MAGIC;
1723 	partition_data->fs_version = FS_VERSION;
1724 	partition_data->fat_start_address = RPMB_FS_FAT_START_ADDRESS;
1725 
1726 	/* Initial FAT entry with FILE_IS_LAST_ENTRY flag set. */
1727 	fh = alloc_file_handle(NULL);
1728 	if (!fh) {
1729 		res = TEE_ERROR_OUT_OF_MEMORY;
1730 		goto out;
1731 	}
1732 	fh->fat_entry.flags = FILE_IS_LAST_ENTRY;
1733 	fh->rpmb_fat_address = partition_data->fat_start_address;
1734 
1735 	/* Write init FAT entry and partition data to RPMB. */
1736 	res = write_fat_entry(fh, true);
1737 	if (res != TEE_SUCCESS)
1738 		goto out;
1739 
1740 	res =
1741 	    tee_rpmb_get_write_counter(CFG_RPMB_FS_DEV_ID,
1742 				       &partition_data->write_counter);
1743 	if (res != TEE_SUCCESS)
1744 		goto out;
1745 	res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, RPMB_STORAGE_START_ADDRESS,
1746 			     (uint8_t *)partition_data,
1747 			     sizeof(struct rpmb_fs_partition), NULL);
1748 
1749 #ifndef CFG_RPMB_RESET_FAT
1750 store_fs_par:
1751 #endif
1752 
1753 	/* Store FAT start address. */
1754 	fs_par = calloc(1, sizeof(struct rpmb_fs_parameters));
1755 	if (!fs_par) {
1756 		res = TEE_ERROR_OUT_OF_MEMORY;
1757 		goto out;
1758 	}
1759 
1760 	fs_par->fat_start_address = partition_data->fat_start_address;
1761 	fs_par->max_rpmb_address = max_rpmb_block << RPMB_BLOCK_SIZE_SHIFT;
1762 
1763 	dump_fat();
1764 
1765 out:
1766 	free(fh);
1767 	free(partition_data);
1768 	return res;
1769 }
1770 
1771 /**
1772  * get_fat_start_address:
1773  * FAT start_address from fs_par.
1774  */
1775 static TEE_Result get_fat_start_address(uint32_t *addr)
1776 {
1777 	if (!fs_par)
1778 		return TEE_ERROR_NO_DATA;
1779 
1780 	*addr = fs_par->fat_start_address;
1781 
1782 	return TEE_SUCCESS;
1783 }
1784 
1785 /**
1786  * read_fat: Read FAT entries
1787  * Return matching FAT entry for read, rm rename and stat.
1788  * Build up memory pool and return matching entry for write operation.
1789  * "Last FAT entry" can be returned during write.
1790  */
1791 static TEE_Result read_fat(struct rpmb_file_handle *fh, tee_mm_pool_t *p)
1792 {
1793 	TEE_Result res = TEE_ERROR_GENERIC;
1794 	tee_mm_entry_t *mm = NULL;
1795 	struct rpmb_fat_entry *fat_entries = NULL;
1796 	uint32_t fat_address;
1797 	size_t size;
1798 	int i;
1799 	bool entry_found = false;
1800 	bool last_entry_found = false;
1801 	bool expand_fat = false;
1802 	struct rpmb_file_handle last_fh;
1803 
1804 	DMSG("fat_address %d", fh->rpmb_fat_address);
1805 
1806 	res = rpmb_fs_setup();
1807 	if (res != TEE_SUCCESS)
1808 		goto out;
1809 
1810 	res = get_fat_start_address(&fat_address);
1811 	if (res != TEE_SUCCESS)
1812 		goto out;
1813 
1814 	size = N_ENTRIES * sizeof(struct rpmb_fat_entry);
1815 	fat_entries = malloc(size);
1816 	if (!fat_entries) {
1817 		res = TEE_ERROR_OUT_OF_MEMORY;
1818 		goto out;
1819 	}
1820 
1821 	/*
1822 	 * The pool is used to represent the current RPMB layout. To find
1823 	 * a slot for the file tee_mm_alloc is called on the pool. Thus
1824 	 * if it is not NULL the entire FAT must be traversed to fill in
1825 	 * the pool.
1826 	 */
1827 	while (!last_entry_found && (!entry_found || p)) {
1828 		res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address,
1829 				    (uint8_t *)fat_entries, size, NULL);
1830 		if (res != TEE_SUCCESS)
1831 			goto out;
1832 
1833 		for (i = 0; i < N_ENTRIES; i++) {
1834 			/*
1835 			 * Look for an entry, matching filenames. (read, rm,
1836 			 * rename and stat.). Only store first filename match.
1837 			 */
1838 			if (fh->filename &&
1839 			    (strcmp(fh->filename,
1840 				    fat_entries[i].filename) == 0) &&
1841 			    (fat_entries[i].flags & FILE_IS_ACTIVE) &&
1842 			    (!entry_found)) {
1843 				entry_found = true;
1844 				fh->rpmb_fat_address = fat_address;
1845 				memcpy(&fh->fat_entry, &fat_entries[i],
1846 				       sizeof(struct rpmb_fat_entry));
1847 				if (!p)
1848 					break;
1849 			}
1850 
1851 			/* Add existing files to memory pool. (write) */
1852 			if (p) {
1853 				if ((fat_entries[i].flags & FILE_IS_ACTIVE) &&
1854 				    (fat_entries[i].data_size > 0)) {
1855 
1856 					mm = tee_mm_alloc2
1857 						(p,
1858 						 fat_entries[i].start_address,
1859 						 fat_entries[i].data_size);
1860 					if (!mm) {
1861 						res = TEE_ERROR_OUT_OF_MEMORY;
1862 						goto out;
1863 					}
1864 				}
1865 
1866 				/* Unused FAT entries can be reused (write) */
1867 				if (((fat_entries[i].flags & FILE_IS_ACTIVE) ==
1868 				     0) && (fh->rpmb_fat_address == 0)) {
1869 					fh->rpmb_fat_address = fat_address;
1870 					memcpy(&fh->fat_entry, &fat_entries[i],
1871 					       sizeof(struct rpmb_fat_entry));
1872 				}
1873 			}
1874 
1875 			if ((fat_entries[i].flags & FILE_IS_LAST_ENTRY) != 0) {
1876 				last_entry_found = true;
1877 
1878 				/*
1879 				 * If the last entry was reached and was chosen
1880 				 * by the previous check, then the FAT needs to
1881 				 * be expanded.
1882 				 * fh->rpmb_fat_address is the address chosen
1883 				 * to store the files FAT entry and fat_address
1884 				 * is the current FAT entry address being
1885 				 * compared.
1886 				 */
1887 				if (p && fh->rpmb_fat_address == fat_address)
1888 					expand_fat = true;
1889 				break;
1890 			}
1891 
1892 			/* Move to next fat_entry. */
1893 			fat_address += sizeof(struct rpmb_fat_entry);
1894 		}
1895 	}
1896 
1897 	/*
1898 	 * Represent the FAT table in the pool.
1899 	 */
1900 	if (p) {
1901 		/*
1902 		 * Since fat_address is the start of the last entry it needs to
1903 		 * be moved up by an entry.
1904 		 */
1905 		fat_address += sizeof(struct rpmb_fat_entry);
1906 
1907 		/* Make room for yet a FAT entry and add to memory pool. */
1908 		if (expand_fat)
1909 			fat_address += sizeof(struct rpmb_fat_entry);
1910 
1911 		mm = tee_mm_alloc2(p, RPMB_STORAGE_START_ADDRESS, fat_address);
1912 		if (!mm) {
1913 			res = TEE_ERROR_OUT_OF_MEMORY;
1914 			goto out;
1915 		}
1916 
1917 		if (expand_fat) {
1918 			/*
1919 			 * Point fat_address to the beginning of the new
1920 			 * entry.
1921 			 */
1922 			fat_address -= sizeof(struct rpmb_fat_entry);
1923 			memset(&last_fh, 0, sizeof(last_fh));
1924 			last_fh.fat_entry.flags = FILE_IS_LAST_ENTRY;
1925 			last_fh.rpmb_fat_address = fat_address;
1926 			res = write_fat_entry(&last_fh, true);
1927 			if (res != TEE_SUCCESS)
1928 				goto out;
1929 		}
1930 	}
1931 
1932 	if (fh->filename && !fh->rpmb_fat_address)
1933 		res = TEE_ERROR_FILE_NOT_FOUND;
1934 
1935 out:
1936 	free(fat_entries);
1937 	return res;
1938 }
1939 
1940 #ifdef CFG_ENC_FS
1941 static TEE_Result generate_fek(struct rpmb_fat_entry *fe)
1942 {
1943 	TEE_Result res;
1944 
1945 again:
1946 	res = tee_fs_generate_fek(fe->fek, sizeof(fe->fek));
1947 	if (res != TEE_SUCCESS)
1948 		return res;
1949 
1950 	if (is_zero(fe->fek, sizeof(fe->fek)))
1951 		goto again;
1952 
1953 	return res;
1954 }
1955 #else
1956 static TEE_Result generate_fek(struct rpmb_fat_entry *fe)
1957 {
1958 	memset(fe->fek, 0, sizeof(fe->fek));
1959 	return TEE_SUCCESS;
1960 }
1961 #endif
1962 
1963 static int rpmb_fs_open_internal(const char *file, int flags, ...)
1964 {
1965 	int fd = -1;
1966 	struct rpmb_file_handle *fh = NULL;
1967 	size_t filelen;
1968 	tee_mm_pool_t p;
1969 	bool pool_result;
1970 	TEE_Result res = TEE_ERROR_GENERIC;
1971 
1972 	if (!file) {
1973 		res = TEE_ERROR_BAD_PARAMETERS;
1974 		goto out;
1975 	}
1976 
1977 	filelen = strlen(file);
1978 	if (filelen >= TEE_RPMB_FS_FILENAME_LENGTH - 1 || filelen == 0) {
1979 		res = TEE_ERROR_BAD_PARAMETERS;
1980 		goto out;
1981 	}
1982 
1983 	if (file[filelen - 1] == '/') {
1984 		res = TEE_ERROR_BAD_PARAMETERS;
1985 		goto out;
1986 	}
1987 
1988 	fh = alloc_file_handle(file);
1989 	if (!fh) {
1990 		res = TEE_ERROR_OUT_OF_MEMORY;
1991 		goto out;
1992 	}
1993 
1994 	/* We need to do setup in order to make sure fs_par is filled in */
1995 	res = rpmb_fs_setup();
1996 	if (res != TEE_SUCCESS)
1997 		goto out;
1998 
1999 	if (flags & TEE_FS_O_CREATE) {
2000 		/* Upper memory allocation must be used for RPMB_FS. */
2001 		pool_result = tee_mm_init(&p,
2002 					  RPMB_STORAGE_START_ADDRESS,
2003 					  fs_par->max_rpmb_address,
2004 					  RPMB_BLOCK_SIZE_SHIFT,
2005 					  TEE_MM_POOL_HI_ALLOC);
2006 
2007 		if (!pool_result) {
2008 			res = TEE_ERROR_OUT_OF_MEMORY;
2009 			goto out;
2010 		}
2011 
2012 		res = read_fat(fh, &p);
2013 		tee_mm_final(&p);
2014 		if (res != TEE_SUCCESS)
2015 			goto out;
2016 	} else {
2017 		res = read_fat(fh, NULL);
2018 		if (res != TEE_SUCCESS)
2019 			goto out;
2020 	}
2021 
2022 	/* Add the handle to the db */
2023 	fd = handle_get(&fs_handle_db, fh);
2024 	if (fd == -1) {
2025 		res = TEE_ERROR_OUT_OF_MEMORY;
2026 		goto out;
2027 	}
2028 
2029 	/*
2030 	 * If this is opened with create and the entry found was not active
2031 	 * then this is a new file and the FAT entry must be written
2032 	 */
2033 	if (flags & TEE_FS_O_CREATE) {
2034 		if ((fh->fat_entry.flags & FILE_IS_ACTIVE) == 0) {
2035 			memset(&fh->fat_entry, 0,
2036 				sizeof(struct rpmb_fat_entry));
2037 			memcpy(fh->fat_entry.filename, file, strlen(file));
2038 			/* Start address and size are 0 */
2039 			fh->fat_entry.flags = FILE_IS_ACTIVE;
2040 
2041 			res = generate_fek(&fh->fat_entry);
2042 			if (res != TEE_SUCCESS) {
2043 				handle_put(&fs_handle_db, fd);
2044 				fd = -1;
2045 				goto out;
2046 			}
2047 			DMSG("GENERATE FEK key: %p",
2048 			     (void *)fh->fat_entry.fek);
2049 			DHEXDUMP(fh->fat_entry.fek, sizeof(fh->fat_entry.fek));
2050 
2051 			res = write_fat_entry(fh, true);
2052 			if (res != TEE_SUCCESS) {
2053 				handle_put(&fs_handle_db, fd);
2054 				fd = -1;
2055 				goto out;
2056 			}
2057 		}
2058 	}
2059 
2060 	res = TEE_SUCCESS;
2061 	fh->flags = flags;
2062 
2063 out:
2064 	if (res != TEE_SUCCESS) {
2065 		if (fh)
2066 			free(fh);
2067 
2068 		fd = -1;
2069 	}
2070 
2071 	return fd;
2072 }
2073 
2074 static int rpmb_fs_close(int fd)
2075 {
2076 	struct rpmb_file_handle *fh;
2077 
2078 	fh = handle_put(&fs_handle_db, fd);
2079 	if (fh) {
2080 		free(fh);
2081 		return 0;
2082 	}
2083 
2084 	return -1;
2085 }
2086 
2087 static int rpmb_fs_read(TEE_Result *errno, int fd, void *buf, size_t size)
2088 {
2089 	TEE_Result res;
2090 	struct rpmb_file_handle *fh;
2091 	int read_size = -1;
2092 
2093 	if (!size)
2094 		return 0;
2095 
2096 	if (!buf) {
2097 		*errno = TEE_ERROR_BAD_PARAMETERS;
2098 		goto out;
2099 	}
2100 
2101 	fh = handle_lookup(&fs_handle_db, fd);
2102 	if (!fh) {
2103 		*errno = TEE_ERROR_BAD_PARAMETERS;
2104 		goto out;
2105 	}
2106 	dump_fh(fh);
2107 
2108 	res = read_fat(fh, NULL);
2109 	if (res != TEE_SUCCESS) {
2110 		*errno = res;
2111 		goto out;
2112 	}
2113 
2114 	if (fh->pos >= fh->fat_entry.data_size) {
2115 		read_size = 0;
2116 		goto out;
2117 	}
2118 
2119 	size = MIN(size, fh->fat_entry.data_size - fh->pos);
2120 	if (size) {
2121 		res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2122 				    fh->fat_entry.start_address + fh->pos, buf,
2123 				    size, fh->fat_entry.fek);
2124 		if (res != TEE_SUCCESS) {
2125 			*errno = res;
2126 			goto out;
2127 		}
2128 	}
2129 	read_size = size;
2130 	fh->pos += size;
2131 
2132 out:
2133 	return read_size;
2134 }
2135 
2136 static int rpmb_fs_write(TEE_Result *errno, int fd, const void *buf,
2137 			size_t size)
2138 {
2139 	TEE_Result res;
2140 	struct rpmb_file_handle *fh;
2141 	tee_mm_pool_t p;
2142 	bool pool_result = false;
2143 	tee_mm_entry_t *mm;
2144 	size_t end;
2145 	size_t newsize;
2146 	uint8_t *newbuf = NULL;
2147 	uintptr_t newaddr;
2148 	uint32_t start_addr;
2149 
2150 	if (!size)
2151 		return 0;
2152 
2153 	if (!buf) {
2154 		res = TEE_ERROR_BAD_PARAMETERS;
2155 		goto out;
2156 	}
2157 
2158 	if (!fs_par) {
2159 		res = TEE_ERROR_GENERIC;
2160 		goto out;
2161 	}
2162 
2163 	fh = handle_lookup(&fs_handle_db, fd);
2164 	if (!fh) {
2165 		res = TEE_ERROR_BAD_PARAMETERS;
2166 		goto out;
2167 	}
2168 	dump_fh(fh);
2169 
2170 	/* Upper memory allocation must be used for RPMB_FS. */
2171 	pool_result = tee_mm_init(&p,
2172 				  RPMB_STORAGE_START_ADDRESS,
2173 				  fs_par->max_rpmb_address,
2174 				  RPMB_BLOCK_SIZE_SHIFT,
2175 				  TEE_MM_POOL_HI_ALLOC);
2176 	if (!pool_result) {
2177 		res = TEE_ERROR_OUT_OF_MEMORY;
2178 		goto out;
2179 	}
2180 
2181 	res = read_fat(fh, &p);
2182 	if (res != TEE_SUCCESS)
2183 		goto out;
2184 
2185 	if (fh->fat_entry.flags & FILE_IS_LAST_ENTRY)
2186 		panic("invalid last entry flag");
2187 
2188 	end = fh->pos + size;
2189 	start_addr = fh->fat_entry.start_address + fh->pos;
2190 
2191 	if (end <= fh->fat_entry.data_size &&
2192 	    tee_rpmb_write_is_atomic(CFG_RPMB_FS_DEV_ID, start_addr, size)) {
2193 
2194 		DMSG("Updating data in-place");
2195 		res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, start_addr, buf,
2196 				     size, fh->fat_entry.fek);
2197 		if (res != TEE_SUCCESS)
2198 			goto out;
2199 	} else {
2200 		/*
2201 		 * File must be extended, or update cannot be atomic: allocate,
2202 		 * read, update, write.
2203 		 */
2204 
2205 		DMSG("Need to re-allocate");
2206 		newsize = MAX(end, fh->fat_entry.data_size);
2207 		mm = tee_mm_alloc(&p, newsize);
2208 		newbuf = calloc(newsize, 1);
2209 		if (!mm || !newbuf) {
2210 			res = TEE_ERROR_OUT_OF_MEMORY;
2211 			goto out;
2212 		}
2213 
2214 		if (fh->fat_entry.data_size) {
2215 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2216 					    fh->fat_entry.start_address,
2217 					    newbuf, fh->fat_entry.data_size,
2218 					    fh->fat_entry.fek);
2219 			if (res != TEE_SUCCESS)
2220 				goto out;
2221 		}
2222 
2223 		memcpy(newbuf + fh->pos, buf, size);
2224 
2225 		newaddr = tee_mm_get_smem(mm);
2226 		res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf,
2227 				     newsize, fh->fat_entry.fek);
2228 		if (res != TEE_SUCCESS)
2229 			goto out;
2230 
2231 		fh->fat_entry.data_size = newsize;
2232 		fh->fat_entry.start_address = newaddr;
2233 		res = write_fat_entry(fh, true);
2234 		if (res != TEE_SUCCESS)
2235 			goto out;
2236 	}
2237 
2238 	fh->pos += size;
2239 out:
2240 	if (pool_result)
2241 		tee_mm_final(&p);
2242 	if (newbuf)
2243 		free(newbuf);
2244 
2245 	if (res == TEE_SUCCESS)
2246 		return size;
2247 
2248 	*errno = res;
2249 	return -1;
2250 }
2251 
2252 static tee_fs_off_t rpmb_fs_lseek(TEE_Result *errno, int fd,
2253 				  tee_fs_off_t offset, int whence)
2254 {
2255 	struct rpmb_file_handle *fh;
2256 	TEE_Result res;
2257 	tee_fs_off_t ret = -1;
2258 	tee_fs_off_t new_pos;
2259 
2260 	fh = handle_lookup(&fs_handle_db, fd);
2261 	if (!fh)
2262 		return TEE_ERROR_BAD_PARAMETERS;
2263 
2264 	res = read_fat(fh, NULL);
2265 	if (res != TEE_SUCCESS) {
2266 		*errno = res;
2267 		goto out;
2268 	}
2269 
2270 	switch (whence) {
2271 	case TEE_FS_SEEK_SET:
2272 		new_pos = offset;
2273 		break;
2274 
2275 	case TEE_FS_SEEK_CUR:
2276 		new_pos = fh->pos + offset;
2277 		break;
2278 
2279 	case TEE_FS_SEEK_END:
2280 		new_pos = fh->fat_entry.data_size + offset;
2281 		break;
2282 
2283 	default:
2284 		*errno = TEE_ERROR_BAD_PARAMETERS;
2285 		goto out;
2286 	}
2287 
2288 	if (new_pos < 0)
2289 		new_pos = 0;
2290 
2291 	if (new_pos > TEE_DATA_MAX_POSITION) {
2292 		EMSG("Position is beyond TEE_DATA_MAX_POSITION");
2293 		*errno = TEE_ERROR_BAD_PARAMETERS;
2294 		goto out;
2295 	}
2296 
2297 	ret = fh->pos = new_pos;
2298 out:
2299 	return ret;
2300 }
2301 
2302 static int rpmb_fs_unlink(const char *filename)
2303 {
2304 	TEE_Result res = TEE_ERROR_GENERIC;
2305 	struct rpmb_file_handle *fh = NULL;
2306 
2307 	if (!filename || strlen(filename) >= TEE_RPMB_FS_FILENAME_LENGTH - 1) {
2308 		res = TEE_ERROR_BAD_PARAMETERS;
2309 		goto out;
2310 	}
2311 
2312 	fh = alloc_file_handle(filename);
2313 	if (!fh) {
2314 		res = TEE_ERROR_OUT_OF_MEMORY;
2315 		goto out;
2316 	}
2317 
2318 	res = read_fat(fh, NULL);
2319 	if (res != TEE_SUCCESS)
2320 		goto out;
2321 
2322 	/* Clear this file entry. */
2323 	memset(&fh->fat_entry, 0, sizeof(struct rpmb_fat_entry));
2324 	res = write_fat_entry(fh, false);
2325 
2326 out:
2327 	free(fh);
2328 	return (res == TEE_SUCCESS ? 0 : -1);
2329 }
2330 
2331 static  int rpmb_fs_rename(const char *old_name, const char *new_name)
2332 {
2333 	TEE_Result res = TEE_ERROR_GENERIC;
2334 	struct rpmb_file_handle *fh_old = NULL;
2335 	struct rpmb_file_handle *fh_new = NULL;
2336 	uint32_t old_len;
2337 	uint32_t new_len;
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 	free(fh_old);
2383 	free(fh_new);
2384 
2385 	return (res == TEE_SUCCESS ? 0 : -1);
2386 }
2387 
2388 static int rpmb_fs_mkdir(const char *path __unused,
2389 			 tee_fs_mode_t mode __unused)
2390 {
2391 	/*
2392 	 * FIXME: mkdir() should really create some entry in the FAT so that
2393 	 * access() would return success when the directory exists but is
2394 	 * empty. This does not matter for the current use cases.
2395 	 */
2396 	return 0;
2397 }
2398 
2399 static int rpmb_fs_ftruncate(TEE_Result *errno, int fd, tee_fs_off_t length)
2400 {
2401 	struct rpmb_file_handle *fh;
2402 	tee_mm_pool_t p;
2403 	bool pool_result = false;
2404 	tee_mm_entry_t *mm;
2405 	uint32_t newsize;
2406 	uint8_t *newbuf = NULL;
2407 	uintptr_t newaddr;
2408 	TEE_Result res = TEE_ERROR_GENERIC;
2409 
2410 	if (length < 0 || length > INT32_MAX) {
2411 		res = TEE_ERROR_BAD_PARAMETERS;
2412 		goto out;
2413 	}
2414 	newsize = length;
2415 
2416 	fh = handle_lookup(&fs_handle_db, fd);
2417 	if (!fh) {
2418 		res = TEE_ERROR_BAD_PARAMETERS;
2419 		goto out;
2420 	}
2421 
2422 	res = read_fat(fh, NULL);
2423 	if (res != TEE_SUCCESS)
2424 		goto out;
2425 
2426 	if (newsize > fh->fat_entry.data_size) {
2427 		/* Extend file */
2428 
2429 		pool_result = tee_mm_init(&p,
2430 					  RPMB_STORAGE_START_ADDRESS,
2431 					  fs_par->max_rpmb_address,
2432 					  RPMB_BLOCK_SIZE_SHIFT,
2433 					  TEE_MM_POOL_HI_ALLOC);
2434 		if (!pool_result) {
2435 			res = TEE_ERROR_OUT_OF_MEMORY;
2436 			goto out;
2437 		}
2438 		res = read_fat(fh, &p);
2439 		if (res != TEE_SUCCESS)
2440 			goto out;
2441 
2442 		mm = tee_mm_alloc(&p, newsize);
2443 		newbuf = calloc(newsize, 1);
2444 		if (!mm || !newbuf) {
2445 			res = TEE_ERROR_OUT_OF_MEMORY;
2446 			goto out;
2447 		}
2448 
2449 		if (fh->fat_entry.data_size) {
2450 			res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID,
2451 					    fh->fat_entry.start_address,
2452 					    newbuf, fh->fat_entry.data_size,
2453 					    fh->fat_entry.fek);
2454 			if (res != TEE_SUCCESS)
2455 				goto out;
2456 		}
2457 
2458 		newaddr = tee_mm_get_smem(mm);
2459 		res = tee_rpmb_write(CFG_RPMB_FS_DEV_ID, newaddr, newbuf,
2460 				     newsize, fh->fat_entry.fek);
2461 		if (res != TEE_SUCCESS)
2462 			goto out;
2463 
2464 	} else {
2465 		/* Don't change file location */
2466 		newaddr = fh->fat_entry.start_address;
2467 	}
2468 
2469 	/* fh->pos is unchanged */
2470 	fh->fat_entry.data_size = newsize;
2471 	fh->fat_entry.start_address = newaddr;
2472 	res = write_fat_entry(fh, true);
2473 
2474 out:
2475 	if (pool_result)
2476 		tee_mm_final(&p);
2477 	if (newbuf)
2478 		free(newbuf);
2479 
2480 	if (res == TEE_SUCCESS)
2481 		return 0;
2482 
2483 	*errno = res;
2484 	return -1;
2485 }
2486 
2487 static void rpmb_fs_dir_free(struct tee_fs_dir *dir)
2488 {
2489 	struct tee_rpmb_fs_dirent *e;
2490 
2491 	if (!dir)
2492 		return;
2493 
2494 	free(dir->current);
2495 
2496 	while ((e = SIMPLEQ_FIRST(&dir->next))) {
2497 		SIMPLEQ_REMOVE_HEAD(&dir->next, link);
2498 		free(e);
2499 	}
2500 }
2501 
2502 static TEE_Result rpmb_fs_dir_populate(const char *path,
2503 				       struct tee_fs_dir *dir)
2504 {
2505 	struct tee_rpmb_fs_dirent *current = NULL;
2506 	struct rpmb_fat_entry *fat_entries = NULL;
2507 	uint32_t fat_address;
2508 	uint32_t filelen;
2509 	char *filename;
2510 	int i;
2511 	bool last_entry_found = false;
2512 	bool matched;
2513 	struct tee_rpmb_fs_dirent *next = NULL;
2514 	uint32_t pathlen;
2515 	TEE_Result res = TEE_ERROR_GENERIC;
2516 	uint32_t size;
2517 	char temp;
2518 
2519 	res = rpmb_fs_setup();
2520 	if (res != TEE_SUCCESS)
2521 		goto out;
2522 
2523 	res = get_fat_start_address(&fat_address);
2524 	if (res != TEE_SUCCESS)
2525 		goto out;
2526 
2527 	size = N_ENTRIES * sizeof(struct rpmb_fat_entry);
2528 	fat_entries = malloc(size);
2529 	if (!fat_entries) {
2530 		res = TEE_ERROR_OUT_OF_MEMORY;
2531 		goto out;
2532 	}
2533 
2534 	pathlen = strlen(path);
2535 	while (!last_entry_found) {
2536 		res = tee_rpmb_read(CFG_RPMB_FS_DEV_ID, fat_address,
2537 				    (uint8_t *)fat_entries, size, NULL);
2538 		if (res != TEE_SUCCESS)
2539 			goto out;
2540 
2541 		for (i = 0; i < N_ENTRIES; i++) {
2542 			filename = fat_entries[i].filename;
2543 			if (fat_entries[i].flags & FILE_IS_ACTIVE) {
2544 				matched = false;
2545 				filelen = strlen(filename);
2546 				if (filelen > pathlen) {
2547 					temp = filename[pathlen];
2548 					filename[pathlen] = '\0';
2549 					if (strcmp(filename, path) == 0)
2550 						matched = true;
2551 
2552 					filename[pathlen] = temp;
2553 				}
2554 
2555 				if (matched) {
2556 					next = malloc(sizeof(*next));
2557 					if (!next) {
2558 						res = TEE_ERROR_OUT_OF_MEMORY;
2559 						goto out;
2560 					}
2561 
2562 					memset(next, 0, sizeof(*next));
2563 					next->entry.d_name = next->name;
2564 					memcpy(next->name,
2565 						&filename[pathlen],
2566 						filelen - pathlen);
2567 
2568 					SIMPLEQ_INSERT_TAIL(&dir->next, next,
2569 							    link);
2570 					current = next;
2571 				}
2572 			}
2573 
2574 			if (fat_entries[i].flags & FILE_IS_LAST_ENTRY) {
2575 				last_entry_found = true;
2576 				break;
2577 			}
2578 
2579 			/* Move to next fat_entry. */
2580 			fat_address += sizeof(struct rpmb_fat_entry);
2581 		}
2582 	}
2583 
2584 	/* No directories were found. */
2585 	if (!current) {
2586 		res = TEE_ERROR_NO_DATA;
2587 		goto out;
2588 	}
2589 
2590 	res = TEE_SUCCESS;
2591 
2592 out:
2593 	if (res != TEE_SUCCESS)
2594 		rpmb_fs_dir_free(dir);
2595 	if (fat_entries)
2596 		free(fat_entries);
2597 
2598 	return res;
2599 }
2600 
2601 static TEE_Result rpmb_fs_opendir_internal(const char *path,
2602 					   struct tee_fs_dir **dir)
2603 {
2604 	uint32_t len;
2605 	uint32_t max_size;
2606 	char path_local[TEE_RPMB_FS_FILENAME_LENGTH];
2607 	TEE_Result res = TEE_ERROR_GENERIC;
2608 	struct tee_fs_dir *rpmb_dir = NULL;
2609 
2610 	if (!path || !dir) {
2611 		res = TEE_ERROR_BAD_PARAMETERS;
2612 		goto out;
2613 	}
2614 
2615 	/*
2616 	 * There must be room for at least the NULL char and a char for the
2617 	 * filename after the path.
2618 	 */
2619 	max_size = TEE_RPMB_FS_FILENAME_LENGTH - 2;
2620 	len = strlen(path);
2621 	if (len > max_size || len == 0) {
2622 		res = TEE_ERROR_BAD_PARAMETERS;
2623 		goto out;
2624 	}
2625 
2626 	memset(path_local, 0, sizeof(path_local));
2627 	memcpy(path_local, path, len);
2628 
2629 	/* Add a slash to correctly match the full directory name. */
2630 	if (path_local[len - 1] != '/')
2631 		path_local[len] = '/';
2632 
2633 	rpmb_dir = calloc(1, sizeof(*rpmb_dir));
2634 	if (!rpmb_dir) {
2635 		res = TEE_ERROR_OUT_OF_MEMORY;
2636 		goto out;
2637 	}
2638 	SIMPLEQ_INIT(&rpmb_dir->next);
2639 
2640 	res = rpmb_fs_dir_populate(path_local, rpmb_dir);
2641 	if (res != TEE_SUCCESS) {
2642 		free(rpmb_dir);
2643 		rpmb_dir = NULL;
2644 		goto out;
2645 	}
2646 
2647 	*dir = rpmb_dir;
2648 
2649 out:
2650 	return res;
2651 }
2652 
2653 static struct tee_fs_dir *rpmb_fs_opendir(const char *path)
2654 {
2655 	struct tee_fs_dir *dir = NULL;
2656 	TEE_Result res = TEE_ERROR_GENERIC;
2657 
2658 	res = rpmb_fs_opendir_internal(path, &dir);
2659 	if (res != TEE_SUCCESS)
2660 		dir = NULL;
2661 
2662 	return dir;
2663 }
2664 
2665 
2666 static struct tee_fs_dirent *rpmb_fs_readdir(struct tee_fs_dir *dir)
2667 {
2668 	if (!dir)
2669 		return NULL;
2670 
2671 	free(dir->current);
2672 
2673 	dir->current = SIMPLEQ_FIRST(&dir->next);
2674 	if (!dir->current)
2675 		return NULL;
2676 
2677 	SIMPLEQ_REMOVE_HEAD(&dir->next, link);
2678 
2679 	return &dir->current->entry;
2680 }
2681 
2682 static int rpmb_fs_closedir(struct tee_fs_dir *dir)
2683 {
2684 	TEE_Result res = TEE_ERROR_GENERIC;
2685 
2686 	if (!dir) {
2687 		res = TEE_SUCCESS;
2688 		goto out;
2689 	}
2690 
2691 	rpmb_fs_dir_free(dir);
2692 	free(dir);
2693 	res = TEE_SUCCESS;
2694 out:
2695 	if (res == TEE_SUCCESS)
2696 		return 0;
2697 
2698 	return -1;
2699 }
2700 
2701 static int rpmb_fs_rmdir(const char *path)
2702 {
2703 	struct tee_fs_dir *dir = NULL;
2704 	TEE_Result res = TEE_ERROR_GENERIC;
2705 	int ret = -1;
2706 
2707 	/* Open the directory anyting other than NO_DATA is a failure */
2708 	res = rpmb_fs_opendir_internal(path, &dir);
2709 	if (res == TEE_SUCCESS) {
2710 		rpmb_fs_closedir(dir);
2711 		ret = -1;
2712 
2713 	} else if (res == TEE_ERROR_NO_DATA) {
2714 		ret = 0;
2715 
2716 	} else {
2717 		/* The case any other failure is returned */
2718 		ret = -1;
2719 	}
2720 
2721 
2722 	return ret;
2723 }
2724 
2725 static int rpmb_fs_stat(const char *filename, struct tee_rpmb_fs_stat *stat)
2726 {
2727 	TEE_Result res = TEE_ERROR_GENERIC;
2728 	struct rpmb_file_handle *fh = NULL;
2729 
2730 	if (!stat || !filename) {
2731 		res = TEE_ERROR_BAD_PARAMETERS;
2732 		goto out;
2733 	}
2734 
2735 	fh = alloc_file_handle(filename);
2736 	if (!fh) {
2737 		res = TEE_ERROR_OUT_OF_MEMORY;
2738 		goto out;
2739 	}
2740 
2741 	res = read_fat(fh, NULL);
2742 	if (res != TEE_SUCCESS)
2743 		goto out;
2744 
2745 	stat->size = (size_t)fh->fat_entry.data_size;
2746 	stat->reserved = 0;
2747 
2748 out:
2749 	free(fh);
2750 	return (res == TEE_SUCCESS ? 0 : -1);
2751 }
2752 
2753 static int rpmb_fs_access(const char *filename, int mode)
2754 {
2755 	struct tee_rpmb_fs_stat stat;
2756 	TEE_Result res;
2757 
2758 	/* Mode is currently ignored, this only checks for existence */
2759 	(void)mode;
2760 
2761 	res = rpmb_fs_stat(filename, &stat);
2762 
2763 	if (res == TEE_SUCCESS)
2764 		return 0;
2765 
2766 	return -1;
2767 }
2768 
2769 static int rpmb_fs_open(TEE_Result *errno, const char *file, int flags, ...)
2770 {
2771 	int fd = -1;
2772 	size_t len;
2773 
2774 	assert(errno);
2775 	*errno = TEE_SUCCESS;
2776 
2777 	len = strlen(file) + 1;
2778 	if (len > TEE_FS_NAME_MAX) {
2779 		*errno = TEE_ERROR_BAD_PARAMETERS;
2780 		goto exit;
2781 	}
2782 
2783 	/*
2784 	 * try to open file without O_CREATE flag, if failed try again with
2785 	 * O_CREATE flag (to distinguish whether it's a new file or not)
2786 	 */
2787 	fd = rpmb_fs_open_internal(file, flags & (~TEE_FS_O_CREATE));
2788 	if (fd < 0) {
2789 		if (!(flags & TEE_FS_O_CREATE)) {
2790 			*errno = TEE_ERROR_ITEM_NOT_FOUND;
2791 			goto exit;
2792 		}
2793 
2794 		fd = rpmb_fs_open_internal(file, flags);
2795 		/* File has been created */
2796 	} else {
2797 		/* File already exists */
2798 		if ((flags & TEE_FS_O_CREATE) && (flags & TEE_FS_O_EXCL)) {
2799 			*errno = TEE_ERROR_ACCESS_CONFLICT;
2800 			rpmb_fs_close(fd);
2801 		}
2802 	}
2803 
2804 exit:
2805 	return fd;
2806 }
2807 
2808 const struct tee_file_operations rpmb_fs_ops = {
2809 	.open = rpmb_fs_open,
2810 	.close = rpmb_fs_close,
2811 	.read = rpmb_fs_read,
2812 	.write = rpmb_fs_write,
2813 	.lseek = rpmb_fs_lseek,
2814 	.ftruncate = rpmb_fs_ftruncate,
2815 	.rename = rpmb_fs_rename,
2816 	.unlink = rpmb_fs_unlink,
2817 	.mkdir = rpmb_fs_mkdir,
2818 	.opendir = rpmb_fs_opendir,
2819 	.closedir = rpmb_fs_closedir,
2820 	.readdir = rpmb_fs_readdir,
2821 	.rmdir = rpmb_fs_rmdir,
2822 	.access = rpmb_fs_access
2823 };
2824