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