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