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