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