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