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