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