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