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