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