xref: /optee_os/core/tee/tee_rpmb_fs.c (revision 04e46975d8f02e25209af552aaea4acb4d70c7f9)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014, STMicroelectronics International N.V.
4  */
5 
6 #include <assert.h>
7 #include <config.h>
8 #include <crypto/crypto.h>
9 #include <kernel/huk_subkey.h>
10 #include <kernel/misc.h>
11 #include <kernel/msg_param.h>
12 #include <kernel/mutex.h>
13 #include <kernel/panic.h>
14 #include <kernel/tee_common.h>
15 #include <kernel/tee_common_otp.h>
16 #include <kernel/tee_misc.h>
17 #include <kernel/thread.h>
18 #include <kernel/user_access.h>
19 #include <mempool.h>
20 #include <mm/core_memprot.h>
21 #include <mm/mobj.h>
22 #include <mm/tee_mm.h>
23 #include <optee_rpc_cmd.h>
24 #include <stdlib.h>
25 #include <string_ext.h>
26 #include <string.h>
27 #include <sys/queue.h>
28 #include <tee/tee_fs.h>
29 #include <tee/tee_fs_key_manager.h>
30 #include <tee/tee_pobj.h>
31 #include <tee/tee_svc_storage.h>
32 #include <trace.h>
33 #include <util.h>
34 
35 #define RPMB_STORAGE_START_ADDRESS      0
36 #define RPMB_FS_FAT_START_ADDRESS       512
37 #define RPMB_BLOCK_SIZE_SHIFT           8
38 #define RPMB_CID_PRV_OFFSET             9
39 #define RPMB_CID_CRC_OFFSET             15
40 
41 #define RPMB_FS_MAGIC                   0x52504D42
42 #define FS_VERSION                      2
43 
44 #define FILE_IS_ACTIVE                  (1u << 0)
45 #define FILE_IS_LAST_ENTRY              (1u << 1)
46 
47 #define TEE_RPMB_FS_FILENAME_LENGTH 224
48 
49 #define TMP_BLOCK_SIZE			4096U
50 
51 #define RPMB_MAX_RETRIES		10
52 
53 /**
54  * Utilized when caching is enabled, i.e., when CFG_RPMB_FS_CACHE_ENTRIES > 0.
55  * Cache size + the number of entries that are repeatedly read in and buffered
56  * once the cache is full.
57  */
58 #define RPMB_BUF_MAX_ENTRIES (CFG_RPMB_FS_CACHE_ENTRIES + \
59 			      CFG_RPMB_FS_RD_ENTRIES)
60 
61 /**
62  * FS parameters: Information often used by internal functions.
63  * fat_start_address will be set by rpmb_fs_setup().
64  * rpmb_fs_parameters can be read by any other function.
65  */
66 struct rpmb_fs_parameters {
67 	uint32_t fat_start_address;
68 	uint32_t max_rpmb_address;
69 };
70 
71 /**
72  * File entry for a single file in a RPMB_FS partition.
73  */
74 struct rpmb_fat_entry {
75 	uint32_t start_address;
76 	uint32_t data_size;
77 	uint32_t flags;
78 	uint32_t unused;
79 	uint8_t fek[TEE_FS_KM_FEK_SIZE];
80 	char filename[TEE_RPMB_FS_FILENAME_LENGTH];
81 };
82 
83 /**
84  * Structure that describes buffered/cached FAT FS entries in RPMB storage.
85  * This structure is used in functions traversing the FAT FS.
86  */
87 struct rpmb_fat_entry_dir {
88 	/*
89 	 * Buffer storing the FAT FS entries read in from RPMB storage. It
90 	 * includes the optional cache entries (CFG_RPMB_FS_CACHE_ENTRIES)
91 	 * and entries temporary read for current FAT FS traversal
92 	 * (CFG_RPMB_FS_RD_ENTRIES) when not found from cached entries.
93 	 */
94 	struct rpmb_fat_entry *rpmb_fat_entry_buf;
95 	/* Current index of FAT FS entry to read from buffer. */
96 	uint32_t idx_curr;
97 	/* Total number of FAT FS entries in buffer. */
98 	uint32_t num_buffered;
99 	/* Total number of FAT FS entries read during traversal. */
100 	uint32_t num_total_read;
101 	/* Indicates that last FAT FS entry was read. */
102 	bool last_reached;
103 };
104 
105 /**
106  * FAT entry context with reference to a FAT entry and its
107  * location in RPMB.
108  */
109 struct rpmb_file_handle {
110 	struct rpmb_fat_entry fat_entry;
111 	const TEE_UUID *uuid;
112 	char filename[TEE_RPMB_FS_FILENAME_LENGTH];
113 	/* Address for current entry in RPMB */
114 	uint32_t rpmb_fat_address;
115 };
116 
117 /**
118  * RPMB_FS partition data
119  */
120 struct rpmb_fs_partition {
121 	uint32_t rpmb_fs_magic;
122 	uint32_t fs_version;
123 	uint32_t write_counter;
124 	uint32_t fat_start_address;
125 	/* Do not use reserved[] for other purpose than partition data. */
126 	uint8_t reserved[112];
127 };
128 
129 /**
130  * A node in a list of directory entries.
131  */
132 struct tee_rpmb_fs_dirent {
133 	struct tee_fs_dirent entry;
134 	SIMPLEQ_ENTRY(tee_rpmb_fs_dirent) link;
135 };
136 
137 /**
138  * The RPMB directory representation. It contains a queue of
139  * RPMB directory entries: 'next'.
140  * The current pointer points to the last directory entry
141  * returned by readdir().
142  */
143 struct tee_fs_dir {
144 	struct tee_rpmb_fs_dirent *current;
145 	/* */
146 	SIMPLEQ_HEAD(next_head, tee_rpmb_fs_dirent) next;
147 };
148 
149 static struct rpmb_fs_parameters *fs_par;
150 static struct rpmb_fat_entry_dir *fat_entry_dir;
151 
152 /*
153  * Lower interface to RPMB device
154  */
155 
156 #define RPMB_DATA_OFFSET            (RPMB_STUFF_DATA_SIZE + RPMB_KEY_MAC_SIZE)
157 #define RPMB_MAC_PROTECT_DATA_SIZE  (RPMB_DATA_FRAME_SIZE - RPMB_DATA_OFFSET)
158 
159 #define RPMB_MSG_TYPE_REQ_AUTH_KEY_PROGRAM          0x0001
160 #define RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ    0x0002
161 #define RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE           0x0003
162 #define RPMB_MSG_TYPE_REQ_AUTH_DATA_READ            0x0004
163 #define RPMB_MSG_TYPE_REQ_RESULT_READ               0x0005
164 #define RPMB_MSG_TYPE_RESP_AUTH_KEY_PROGRAM         0x0100
165 #define RPMB_MSG_TYPE_RESP_WRITE_COUNTER_VAL_READ   0x0200
166 #define RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE          0x0300
167 #define RPMB_MSG_TYPE_RESP_AUTH_DATA_READ           0x0400
168 
169 #define RPMB_STUFF_DATA_SIZE                        196
170 #define RPMB_KEY_MAC_SIZE                           32
171 #define RPMB_DATA_SIZE                              256
172 #define RPMB_NONCE_SIZE                             16
173 #define RPMB_DATA_FRAME_SIZE                        512
174 
175 #define RPMB_RESULT_OK                              0x00
176 #define RPMB_RESULT_GENERAL_FAILURE                 0x01
177 #define RPMB_RESULT_AUTH_FAILURE                    0x02
178 #define RPMB_RESULT_COUNTER_FAILURE                 0x03
179 #define RPMB_RESULT_ADDRESS_FAILURE                 0x04
180 #define RPMB_RESULT_WRITE_FAILURE                   0x05
181 #define RPMB_RESULT_READ_FAILURE                    0x06
182 #define RPMB_RESULT_AUTH_KEY_NOT_PROGRAMMED         0x07
183 #define RPMB_RESULT_MASK                            0x3F
184 #define RPMB_RESULT_WR_CNT_EXPIRED                  0x80
185 
186 /* RPMB internal commands */
187 #define RPMB_CMD_DATA_REQ      0x00
188 #define RPMB_CMD_GET_DEV_INFO  0x01
189 
190 #define RPMB_SIZE_SINGLE (128 * 1024)
191 
192 /* Error codes for get_dev_info request/response. */
193 #define RPMB_CMD_GET_DEV_INFO_RET_OK     0x00
194 #define RPMB_CMD_GET_DEV_INFO_RET_ERROR  0x01
195 
196 struct rpmb_data_frame {
197 	uint8_t stuff_bytes[RPMB_STUFF_DATA_SIZE];
198 	uint8_t key_mac[RPMB_KEY_MAC_SIZE];
199 	uint8_t data[RPMB_DATA_SIZE];
200 	uint8_t nonce[RPMB_NONCE_SIZE];
201 	uint8_t write_counter[4];
202 	uint8_t address[2];
203 	uint8_t block_count[2];
204 	uint8_t op_result[2];
205 	uint8_t msg_type[2];
206 };
207 
208 struct rpmb_req {
209 	uint16_t cmd;
210 	uint16_t dev_id;
211 	uint16_t block_count;
212 	/* variable length of data */
213 	/* uint8_t data[]; REMOVED! */
214 };
215 
216 #define TEE_RPMB_REQ_DATA(req) \
217 		((void *)((struct rpmb_req *)(req) + 1))
218 
219 struct rpmb_raw_data {
220 	uint16_t msg_type;
221 	uint16_t *op_result;
222 	uint16_t *block_count;
223 	uint16_t *blk_idx;
224 	uint32_t *write_counter;
225 	uint8_t *nonce;
226 	uint8_t *key_mac;
227 	uint8_t *data;
228 	/* data length to read or write */
229 	uint32_t len;
230 	/* Byte address offset in the first block involved */
231 	uint8_t byte_offset;
232 };
233 
234 #define RPMB_EMMC_CID_SIZE 16
235 struct rpmb_dev_info {
236 	uint8_t cid[RPMB_EMMC_CID_SIZE];
237 	/* EXT CSD-slice 168 "RPMB Size" */
238 	uint8_t rpmb_size_mult;
239 	/* EXT CSD-slice 222 "Reliable Write Sector Count" */
240 	uint8_t rel_wr_sec_c;
241 	/* Check the ret code and accept the data only if it is OK. */
242 	uint8_t ret_code;
243 };
244 
245 /*
246  * Struct for rpmb context data.
247  *
248  * @key              RPMB key.
249  * @cid              eMMC card ID.
250  * @wr_cnt           Current write counter.
251  * @max_blk_idx      The highest block index supported by current device.
252  * @rel_wr_blkcnt    Max number of data blocks for each reliable write.
253  * @dev_id           Device ID of the eMMC device.
254  * @wr_cnt_synced    Flag indicating if write counter is synced to RPMB.
255  * @key_derived      Flag indicating if key has been generated.
256  * @key_verified     Flag indicating the key generated is verified ok.
257  * @dev_info_synced  Flag indicating if dev info has been retrieved from RPMB.
258  * @legacy_operation Flag indicating if the legacy interface is used.
259  * @reinit           Flag indicating if the device needs to be found again
260  * @shm_type         Indicates type of shared memory to allocate
261  */
262 struct tee_rpmb_ctx {
263 	uint8_t key[RPMB_KEY_MAC_SIZE];
264 	uint8_t cid[RPMB_EMMC_CID_SIZE];
265 	uint32_t wr_cnt;
266 	uint16_t max_blk_idx;
267 	uint16_t rel_wr_blkcnt;
268 	uint16_t dev_id;
269 	bool wr_cnt_synced;
270 	bool key_derived;
271 	bool key_verified;
272 	bool dev_info_synced;
273 	bool legacy_operation;
274 	bool reinit;
275 	enum thread_shm_type shm_type;
276 };
277 
278 static struct tee_rpmb_ctx *rpmb_ctx;
279 
280 /* If set to true, don't try to access RPMB until rebooted */
281 static bool rpmb_dead;
282 
283 /*
284  * Mutex to serialize the operations exported by this file.
285  * It protects rpmb_ctx and prevents overlapping operations on eMMC devices with
286  * different IDs.
287  */
288 static struct mutex rpmb_mutex = MUTEX_INITIALIZER;
289 
290 #ifdef CFG_RPMB_TESTKEY
291 
292 static const uint8_t rpmb_test_key[RPMB_KEY_MAC_SIZE] = {
293 	0xD3, 0xEB, 0x3E, 0xC3, 0x6E, 0x33, 0x4C, 0x9F,
294 	0x98, 0x8C, 0xE2, 0xC0, 0xB8, 0x59, 0x54, 0x61,
295 	0x0D, 0x2B, 0xCF, 0x86, 0x64, 0x84, 0x4D, 0xF2,
296 	0xAB, 0x56, 0xE6, 0xC6, 0x1B, 0xB7, 0x01, 0xE4
297 };
298 
299 static TEE_Result tee_rpmb_key_gen(uint8_t *key, uint32_t len)
300 {
301 	TEE_Result res = TEE_SUCCESS;
302 
303 	if (!key || RPMB_KEY_MAC_SIZE != len) {
304 		res = TEE_ERROR_BAD_PARAMETERS;
305 		goto out;
306 	}
307 
308 	DMSG("RPMB: Using test key");
309 	memcpy(key, rpmb_test_key, RPMB_KEY_MAC_SIZE);
310 
311 out:
312 	return res;
313 }
314 
315 #else /* !CFG_RPMB_TESTKEY */
316 
317 static TEE_Result tee_rpmb_key_gen(uint8_t *key, uint32_t len)
318 {
319 	uint8_t message[RPMB_EMMC_CID_SIZE];
320 
321 	if (!key || RPMB_KEY_MAC_SIZE != len)
322 		return TEE_ERROR_BAD_PARAMETERS;
323 
324 	IMSG("RPMB: Using generated key");
325 
326 	/*
327 	 * PRV/CRC would be changed when doing eMMC FFU
328 	 * The following fields should be masked off when deriving RPMB key
329 	 *
330 	 * CID [55: 48]: PRV (Product revision)
331 	 * CID [07: 01]: CRC (CRC7 checksum)
332 	 * CID [00]: not used
333 	 */
334 	memcpy(message, rpmb_ctx->cid, RPMB_EMMC_CID_SIZE);
335 	memset(message + RPMB_CID_PRV_OFFSET, 0, 1);
336 	memset(message + RPMB_CID_CRC_OFFSET, 0, 1);
337 	return huk_subkey_derive(HUK_SUBKEY_RPMB, message, sizeof(message),
338 				 key, len);
339 }
340 
341 #endif /* !CFG_RPMB_TESTKEY */
342 
343 static void u32_to_bytes(uint32_t u32, uint8_t *bytes)
344 {
345 	*bytes = (uint8_t) (u32 >> 24);
346 	*(bytes + 1) = (uint8_t) (u32 >> 16);
347 	*(bytes + 2) = (uint8_t) (u32 >> 8);
348 	*(bytes + 3) = (uint8_t) u32;
349 }
350 
351 static void bytes_to_u32(uint8_t *bytes, uint32_t *u32)
352 {
353 	*u32 = (uint32_t) ((*(bytes) << 24) +
354 			   (*(bytes + 1) << 16) +
355 			   (*(bytes + 2) << 8) + (*(bytes + 3)));
356 }
357 
358 static void u16_to_bytes(uint16_t u16, uint8_t *bytes)
359 {
360 	*bytes = (uint8_t) (u16 >> 8);
361 	*(bytes + 1) = (uint8_t) u16;
362 }
363 
364 static void bytes_to_u16(uint8_t *bytes, uint16_t *u16)
365 {
366 	*u16 = (uint16_t) ((*bytes << 8) + *(bytes + 1));
367 }
368 
369 static void get_op_result_bits(uint8_t *bytes, uint8_t *res)
370 {
371 	*res = *(bytes + 1) & RPMB_RESULT_MASK;
372 }
373 
374 static TEE_Result tee_rpmb_mac_calc(uint8_t *mac, uint32_t macsize,
375 				    uint8_t *key, uint32_t keysize,
376 				    struct rpmb_data_frame *datafrms,
377 				    uint16_t blkcnt)
378 {
379 	TEE_Result res = TEE_ERROR_GENERIC;
380 	int i;
381 	void *ctx = NULL;
382 
383 	if (!mac || !key || !datafrms)
384 		return TEE_ERROR_BAD_PARAMETERS;
385 
386 	res = crypto_mac_alloc_ctx(&ctx, TEE_ALG_HMAC_SHA256);
387 	if (res)
388 		return res;
389 
390 	res = crypto_mac_init(ctx, key, keysize);
391 	if (res != TEE_SUCCESS)
392 		goto func_exit;
393 
394 	for (i = 0; i < blkcnt; i++) {
395 		res = crypto_mac_update(ctx, datafrms[i].data,
396 					RPMB_MAC_PROTECT_DATA_SIZE);
397 		if (res != TEE_SUCCESS)
398 			goto func_exit;
399 	}
400 
401 	res = crypto_mac_final(ctx, mac, macsize);
402 	if (res != TEE_SUCCESS)
403 		goto func_exit;
404 
405 	res = TEE_SUCCESS;
406 
407 func_exit:
408 	crypto_mac_free_ctx(ctx);
409 	return res;
410 }
411 
412 struct tee_rpmb_mem {
413 	struct mobj *mobj;
414 	size_t req_size;
415 	size_t resp_offs;
416 	size_t resp_size;
417 	struct rpmb_req *req_hdr;
418 	struct rpmb_data_frame *req_data;
419 	struct rpmb_data_frame *resp_data;
420 };
421 
422 static TEE_Result tee_rpmb_alloc(size_t req_size, size_t resp_size,
423 				 struct tee_rpmb_mem *mem)
424 {
425 	size_t req_s = 0;
426 	size_t resp_s = 0;
427 	struct mobj *mobj = NULL;
428 	void *va = NULL;
429 
430 	if (!mem)
431 		return TEE_ERROR_BAD_PARAMETERS;
432 
433 	if (rpmb_ctx->legacy_operation)
434 		req_size += sizeof(struct rpmb_req);
435 	req_s = ROUNDUP(req_size, SMALL_PAGE_SIZE);
436 	resp_s = ROUNDUP(resp_size, SMALL_PAGE_SIZE);
437 	va = thread_rpc_shm_cache_alloc(THREAD_SHM_CACHE_USER_RPMB,
438 					rpmb_ctx->shm_type, req_s + resp_s,
439 					&mobj);
440 	if (!va)
441 		return TEE_ERROR_OUT_OF_MEMORY;
442 
443 	*mem = (struct tee_rpmb_mem){
444 		.mobj = mobj,
445 		.req_size = req_size,
446 		.resp_offs = req_s,
447 		.resp_size = resp_size,
448 	};
449 
450 	if (rpmb_ctx->legacy_operation) {
451 		mem->req_hdr = mobj_get_va(mem->mobj, 0, req_s);
452 		if (!mem->req_hdr)
453 			return TEE_ERROR_GENERIC;
454 		mem->req_data = (void *)(mem->req_hdr + 1);
455 	} else {
456 		mem->req_data = mobj_get_va(mem->mobj, 0, req_s);
457 		if (!mem->req_data)
458 			return TEE_ERROR_GENERIC;
459 	}
460 	mem->resp_data = mobj_get_va(mem->mobj, req_s, resp_s);
461 	if (!mem->resp_data)
462 		return TEE_ERROR_GENERIC;
463 
464 	return TEE_SUCCESS;
465 }
466 
467 static TEE_Result tee_rpmb_invoke(struct tee_rpmb_mem *mem)
468 {
469 	struct thread_param params[2] = {
470 		[0] = THREAD_PARAM_MEMREF(IN, mem->mobj, 0, mem->req_size),
471 		[1] = THREAD_PARAM_MEMREF(OUT, mem->mobj, mem->resp_offs,
472 					  mem->resp_size),
473 	};
474 	uint32_t cmd = OPTEE_RPC_CMD_RPMB_FRAMES;
475 
476 	if (rpmb_ctx->legacy_operation)
477 		cmd = OPTEE_RPC_CMD_RPMB;
478 
479 	return thread_rpc_cmd(cmd, 2, params);
480 }
481 
482 static TEE_Result rpmb_probe_reset(void)
483 {
484 	struct thread_param params[1] = {
485 		[0] = THREAD_PARAM_VALUE(OUT, 0, 0, 0),
486 	};
487 	TEE_Result res = TEE_SUCCESS;
488 
489 	res = thread_rpc_cmd(OPTEE_RPC_CMD_RPMB_PROBE_RESET, 1, params);
490 	if (res)
491 		return res;
492 
493 	rpmb_ctx->legacy_operation = false;
494 	rpmb_ctx->dev_id = 0;
495 
496 	switch (params[0].u.value.a) {
497 	case OPTEE_RPC_SHM_TYPE_APPL:
498 		rpmb_ctx->shm_type = THREAD_SHM_TYPE_APPLICATION;
499 		return TEE_SUCCESS;
500 	case OPTEE_RPC_SHM_TYPE_KERNEL:
501 		rpmb_ctx->shm_type = THREAD_SHM_TYPE_KERNEL_PRIVATE;
502 		return TEE_SUCCESS;
503 	default:
504 		return TEE_ERROR_GENERIC;
505 	}
506 }
507 
508 static TEE_Result rpmb_probe_next(struct rpmb_dev_info *dev_info)
509 {
510 	struct thread_param params[2] = { };
511 	TEE_Result res = TEE_SUCCESS;
512 	struct mobj *mobj = NULL;
513 	void *va = NULL;
514 
515 	va = thread_rpc_shm_cache_alloc(THREAD_SHM_CACHE_USER_RPMB,
516 					THREAD_SHM_TYPE_KERNEL_PRIVATE,
517 					sizeof(dev_info->cid), &mobj);
518 	if (!va)
519 		return TEE_ERROR_OUT_OF_MEMORY;
520 
521 	do {
522 		params[0] = THREAD_PARAM_VALUE(OUT, 0, 0, 0);
523 		params[1] = THREAD_PARAM_MEMREF(OUT, mobj, 0,
524 						sizeof(dev_info->cid));
525 		res = thread_rpc_cmd(OPTEE_RPC_CMD_RPMB_PROBE_NEXT, 2, params);
526 		/*
527 		 * If the ID buffer is too small, perhaps it's a new kind
528 		 * of RPMB device that we don't know how to communicate
529 		 * with, let's ignore it for now.
530 		 */
531 	} while (res == TEE_ERROR_SHORT_BUFFER);
532 	if (res)
533 		return res;
534 
535 	if (params[0].u.value.a != OPTEE_RPC_RPMB_EMMC)
536 		return TEE_ERROR_NOT_SUPPORTED;
537 
538 	*dev_info = (struct rpmb_dev_info){
539 		.rpmb_size_mult = params[0].u.value.b,
540 		.rel_wr_sec_c = params[0].u.value.c,
541 		.ret_code = RPMB_CMD_GET_DEV_INFO_RET_OK,
542 	};
543 	memcpy(dev_info->cid, va, sizeof(dev_info->cid));
544 
545 	return TEE_SUCCESS;
546 }
547 
548 static bool is_zero(const uint8_t *buf, size_t size)
549 {
550 	size_t i;
551 
552 	for (i = 0; i < size; i++)
553 		if (buf[i])
554 			return false;
555 	return true;
556 }
557 
558 static TEE_Result encrypt_block(uint8_t *out, const uint8_t *in,
559 				uint16_t blk_idx, const uint8_t *fek,
560 				const TEE_UUID *uuid)
561 {
562 	return tee_fs_crypt_block(uuid, out, in, RPMB_DATA_SIZE,
563 				  blk_idx, fek, TEE_MODE_ENCRYPT);
564 }
565 
566 static TEE_Result decrypt_block(uint8_t *out, const uint8_t *in,
567 				uint16_t blk_idx, const uint8_t *fek,
568 				const TEE_UUID *uuid)
569 {
570 	return tee_fs_crypt_block(uuid, out, in, RPMB_DATA_SIZE,
571 				  blk_idx, fek, TEE_MODE_DECRYPT);
572 }
573 
574 /* Decrypt/copy at most one block of data */
575 static TEE_Result decrypt(uint8_t *out, const struct rpmb_data_frame *frm,
576 			  size_t size, size_t offset,
577 			  uint16_t blk_idx __maybe_unused, const uint8_t *fek,
578 			  const TEE_UUID *uuid)
579 {
580 	uint8_t *tmp __maybe_unused;
581 	TEE_Result res = TEE_SUCCESS;
582 
583 
584 	if ((size + offset < size) || (size + offset > RPMB_DATA_SIZE))
585 		panic("invalid size or offset");
586 
587 	if (!fek) {
588 		/* Block is not encrypted (not a file data block) */
589 		memcpy(out, frm->data + offset, size);
590 	} else if (is_zero(fek, TEE_FS_KM_FEK_SIZE)) {
591 		/* The file was created with encryption disabled */
592 		return TEE_ERROR_SECURITY;
593 	} else {
594 		/* Block is encrypted */
595 		if (size < RPMB_DATA_SIZE) {
596 			/*
597 			 * Since output buffer is not large enough to hold one
598 			 * block we must allocate a temporary buffer.
599 			 */
600 			tmp = malloc(RPMB_DATA_SIZE);
601 			if (!tmp)
602 				return TEE_ERROR_OUT_OF_MEMORY;
603 			res = decrypt_block(tmp, frm->data, blk_idx, fek, uuid);
604 			if (res == TEE_SUCCESS)
605 				memcpy(out, tmp + offset, size);
606 			free(tmp);
607 		} else {
608 			res = decrypt_block(out, frm->data, blk_idx, fek, uuid);
609 		}
610 	}
611 
612 	return res;
613 }
614 
615 static TEE_Result tee_rpmb_req_pack(struct rpmb_req *req_hdr,
616 				    struct rpmb_data_frame *req_data,
617 				    struct rpmb_raw_data *rawdata,
618 				    uint16_t nbr_frms,
619 				    const uint8_t *fek, const TEE_UUID *uuid)
620 {
621 	TEE_Result res = TEE_ERROR_GENERIC;
622 	int i;
623 	struct rpmb_data_frame *datafrm;
624 
625 	if (!req_data || !rawdata || !nbr_frms)
626 		return TEE_ERROR_BAD_PARAMETERS;
627 
628 	/*
629 	 * Check write blockcount is not bigger than reliable write
630 	 * blockcount.
631 	 */
632 	if ((rawdata->msg_type == RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE) &&
633 	    (nbr_frms > rpmb_ctx->rel_wr_blkcnt)) {
634 		DMSG("wr_blkcnt(%d) > rel_wr_blkcnt(%d)", nbr_frms,
635 		     rpmb_ctx->rel_wr_blkcnt);
636 		return TEE_ERROR_GENERIC;
637 	}
638 
639 	if (req_hdr) {
640 		req_hdr->cmd = RPMB_CMD_DATA_REQ;
641 		req_hdr->dev_id = rpmb_ctx->dev_id;
642 	}
643 
644 	/* Allocate memory for construct all data packets and calculate MAC. */
645 	datafrm = calloc(nbr_frms, RPMB_DATA_FRAME_SIZE);
646 	if (!datafrm)
647 		return TEE_ERROR_OUT_OF_MEMORY;
648 
649 	for (i = 0; i < nbr_frms; i++) {
650 		u16_to_bytes(rawdata->msg_type, datafrm[i].msg_type);
651 
652 		if (rawdata->block_count)
653 			u16_to_bytes(*rawdata->block_count,
654 				     datafrm[i].block_count);
655 
656 		if (rawdata->blk_idx) {
657 			/* Check the block index is within range. */
658 			if ((*rawdata->blk_idx + nbr_frms - 1) >
659 			    rpmb_ctx->max_blk_idx) {
660 				res = TEE_ERROR_GENERIC;
661 				goto func_exit;
662 			}
663 			u16_to_bytes(*rawdata->blk_idx, datafrm[i].address);
664 		}
665 
666 		if (rawdata->write_counter)
667 			u32_to_bytes(*rawdata->write_counter,
668 				     datafrm[i].write_counter);
669 
670 		if (rawdata->nonce)
671 			memcpy(datafrm[i].nonce, rawdata->nonce,
672 			       RPMB_NONCE_SIZE);
673 
674 		if (rawdata->data) {
675 			if (fek) {
676 				res = encrypt_block(datafrm[i].data,
677 						    rawdata->data +
678 						    (i * RPMB_DATA_SIZE),
679 						    *rawdata->blk_idx + i,
680 						    fek, uuid);
681 				if (res != TEE_SUCCESS)
682 					goto func_exit;
683 			} else {
684 				memcpy(datafrm[i].data,
685 				       rawdata->data + (i * RPMB_DATA_SIZE),
686 				       RPMB_DATA_SIZE);
687 			}
688 		}
689 	}
690 
691 	if (rawdata->key_mac) {
692 		if (rawdata->msg_type == RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE) {
693 			res =
694 			    tee_rpmb_mac_calc(rawdata->key_mac,
695 					      RPMB_KEY_MAC_SIZE, rpmb_ctx->key,
696 					      RPMB_KEY_MAC_SIZE, datafrm,
697 					      nbr_frms);
698 			if (res != TEE_SUCCESS)
699 				goto func_exit;
700 		}
701 		memcpy(datafrm[nbr_frms - 1].key_mac,
702 		       rawdata->key_mac, RPMB_KEY_MAC_SIZE);
703 	}
704 
705 	memcpy(req_data, datafrm, nbr_frms * RPMB_DATA_FRAME_SIZE);
706 
707 	if (IS_ENABLED(CFG_RPMB_FS_DEBUG_DATA)) {
708 		for (i = 0; i < nbr_frms; i++) {
709 			DMSG("Dumping data frame %d:", i);
710 			DHEXDUMP((uint8_t *)&datafrm[i] + RPMB_STUFF_DATA_SIZE,
711 				 512 - RPMB_STUFF_DATA_SIZE);
712 		}
713 	}
714 
715 	res = TEE_SUCCESS;
716 func_exit:
717 	free(datafrm);
718 	return res;
719 }
720 
721 static TEE_Result data_cpy_mac_calc_1b(struct rpmb_raw_data *rawdata,
722 				       struct rpmb_data_frame *frm,
723 				       const uint8_t *fek, const TEE_UUID *uuid)
724 {
725 	TEE_Result res;
726 	uint8_t *data;
727 	uint16_t idx;
728 
729 	if (rawdata->len + rawdata->byte_offset > RPMB_DATA_SIZE)
730 		return TEE_ERROR_BAD_PARAMETERS;
731 
732 	res = tee_rpmb_mac_calc(rawdata->key_mac, RPMB_KEY_MAC_SIZE,
733 				rpmb_ctx->key, RPMB_KEY_MAC_SIZE, frm, 1);
734 	if (res != TEE_SUCCESS)
735 		return res;
736 
737 	data = rawdata->data;
738 	bytes_to_u16(frm->address, &idx);
739 
740 	res = decrypt(data, frm, rawdata->len, rawdata->byte_offset, idx, fek,
741 		      uuid);
742 	return res;
743 }
744 
745 static TEE_Result tee_rpmb_data_cpy_mac_calc(struct rpmb_data_frame *datafrm,
746 					     struct rpmb_raw_data *rawdata,
747 					     uint16_t nbr_frms,
748 					     struct rpmb_data_frame *lastfrm,
749 					     const uint8_t *fek,
750 					     const TEE_UUID *uuid)
751 {
752 	TEE_Result res = TEE_ERROR_GENERIC;
753 	int i;
754 	void *ctx = NULL;
755 	uint16_t offset;
756 	uint32_t size;
757 	uint8_t *data;
758 	uint16_t start_idx;
759 	struct rpmb_data_frame localfrm;
760 
761 	if (!datafrm || !rawdata || !nbr_frms || !lastfrm)
762 		return TEE_ERROR_BAD_PARAMETERS;
763 
764 	if (nbr_frms == 1)
765 		return data_cpy_mac_calc_1b(rawdata, lastfrm, fek, uuid);
766 
767 	/* nbr_frms > 1 */
768 
769 	data = rawdata->data;
770 
771 	res = crypto_mac_alloc_ctx(&ctx, TEE_ALG_HMAC_SHA256);
772 	if (res)
773 		goto func_exit;
774 
775 	res = crypto_mac_init(ctx, rpmb_ctx->key, RPMB_KEY_MAC_SIZE);
776 	if (res != TEE_SUCCESS)
777 		goto func_exit;
778 
779 	/*
780 	 * Note: JEDEC JESD84-B51: "In every packet the address is the start
781 	 * address of the full access (not address of the individual half a
782 	 * sector)"
783 	 */
784 	bytes_to_u16(lastfrm->address, &start_idx);
785 
786 	for (i = 0; i < (nbr_frms - 1); i++) {
787 
788 		/*
789 		 * By working on a local copy of the RPMB frame, we ensure that
790 		 * the data can not be modified after the MAC is computed but
791 		 * before the payload is decrypted/copied to the output buffer.
792 		 */
793 		memcpy(&localfrm, &datafrm[i], RPMB_DATA_FRAME_SIZE);
794 
795 		res = crypto_mac_update(ctx, localfrm.data,
796 					RPMB_MAC_PROTECT_DATA_SIZE);
797 		if (res != TEE_SUCCESS)
798 			goto func_exit;
799 
800 		if (i == 0) {
801 			/* First block */
802 			offset = rawdata->byte_offset;
803 			size = RPMB_DATA_SIZE - offset;
804 		} else {
805 			/* Middle blocks */
806 			size = RPMB_DATA_SIZE;
807 			offset = 0;
808 		}
809 
810 		res = decrypt(data, &localfrm, size, offset, start_idx + i,
811 			      fek, uuid);
812 		if (res != TEE_SUCCESS)
813 			goto func_exit;
814 
815 		data += size;
816 	}
817 
818 	/* Last block */
819 	size = (rawdata->len + rawdata->byte_offset) % RPMB_DATA_SIZE;
820 	if (size == 0)
821 		size = RPMB_DATA_SIZE;
822 	res = decrypt(data, lastfrm, size, 0, start_idx + nbr_frms - 1, fek,
823 		      uuid);
824 	if (res != TEE_SUCCESS)
825 		goto func_exit;
826 
827 	/* Update MAC against the last block */
828 	res = crypto_mac_update(ctx, lastfrm->data, RPMB_MAC_PROTECT_DATA_SIZE);
829 	if (res != TEE_SUCCESS)
830 		goto func_exit;
831 
832 	res = crypto_mac_final(ctx, rawdata->key_mac, RPMB_KEY_MAC_SIZE);
833 	if (res != TEE_SUCCESS)
834 		goto func_exit;
835 
836 	res = TEE_SUCCESS;
837 
838 func_exit:
839 	crypto_mac_free_ctx(ctx);
840 	return res;
841 }
842 
843 static TEE_Result tee_rpmb_resp_unpack_verify(struct rpmb_data_frame *datafrm,
844 					      struct rpmb_raw_data *rawdata,
845 					      uint16_t nbr_frms,
846 					      const uint8_t *fek,
847 					      const TEE_UUID *uuid)
848 {
849 	TEE_Result res = TEE_ERROR_GENERIC;
850 	uint16_t msg_type;
851 	uint32_t wr_cnt;
852 	uint16_t blk_idx;
853 	uint8_t op_result;
854 	struct rpmb_data_frame lastfrm;
855 
856 	if (!datafrm || !rawdata || !nbr_frms)
857 		return TEE_ERROR_BAD_PARAMETERS;
858 
859 	if (IS_ENABLED(CFG_RPMB_FS_DEBUG_DATA)) {
860 		size_t i = 0;
861 
862 		for (i = 0; i < nbr_frms; i++) {
863 			DMSG("Dumping data frame %zu:", i);
864 			DHEXDUMP((uint8_t *)&datafrm[i] + RPMB_STUFF_DATA_SIZE,
865 				 512 - RPMB_STUFF_DATA_SIZE);
866 		}
867 	}
868 
869 	/* Make sure the last data packet can't be modified once verified */
870 	memcpy(&lastfrm, &datafrm[nbr_frms - 1], RPMB_DATA_FRAME_SIZE);
871 
872 	/* Handle operation result and translate to TEEC error code. */
873 	get_op_result_bits(lastfrm.op_result, &op_result);
874 	if (op_result == RPMB_RESULT_AUTH_KEY_NOT_PROGRAMMED)
875 		return TEE_ERROR_ITEM_NOT_FOUND;
876 	if (op_result != RPMB_RESULT_OK)
877 		return TEE_ERROR_GENERIC;
878 
879 	/* Check the response msg_type. */
880 	bytes_to_u16(lastfrm.msg_type, &msg_type);
881 	if (msg_type != rawdata->msg_type) {
882 		DMSG("Unexpected msg_type (0x%04x != 0x%04x)", msg_type,
883 		     rawdata->msg_type);
884 		return TEE_ERROR_GENERIC;
885 	}
886 
887 	if (rawdata->blk_idx) {
888 		bytes_to_u16(lastfrm.address, &blk_idx);
889 		if (blk_idx != *rawdata->blk_idx) {
890 			DMSG("Unexpected block index");
891 			return TEE_ERROR_GENERIC;
892 		}
893 	}
894 
895 	if (rawdata->write_counter) {
896 		wr_cnt = *rawdata->write_counter;
897 		bytes_to_u32(lastfrm.write_counter, rawdata->write_counter);
898 		if (msg_type == RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE) {
899 			/* Verify the write counter is incremented by 1 */
900 			if (*rawdata->write_counter != wr_cnt + 1) {
901 				DMSG("Counter mismatched (0x%04x/0x%04x)",
902 				     *rawdata->write_counter, wr_cnt + 1);
903 				return TEE_ERROR_SECURITY;
904 			}
905 			rpmb_ctx->wr_cnt++;
906 		}
907 	}
908 
909 	if (rawdata->nonce) {
910 		if (buf_compare_ct(rawdata->nonce, lastfrm.nonce,
911 				   RPMB_NONCE_SIZE) != 0) {
912 			DMSG("Nonce mismatched");
913 			return TEE_ERROR_SECURITY;
914 		}
915 	}
916 
917 	if (rawdata->key_mac) {
918 		if (msg_type == RPMB_MSG_TYPE_RESP_AUTH_DATA_READ) {
919 			if (!rawdata->data)
920 				return TEE_ERROR_GENERIC;
921 
922 			res = tee_rpmb_data_cpy_mac_calc(datafrm, rawdata,
923 							 nbr_frms, &lastfrm,
924 							 fek, uuid);
925 
926 			if (res != TEE_SUCCESS)
927 				return res;
928 		} else {
929 			/*
930 			 * There should be only one data frame for
931 			 * other msg types.
932 			 */
933 			if (nbr_frms != 1)
934 				return TEE_ERROR_GENERIC;
935 
936 			res = tee_rpmb_mac_calc(rawdata->key_mac,
937 						RPMB_KEY_MAC_SIZE,
938 						rpmb_ctx->key,
939 						RPMB_KEY_MAC_SIZE,
940 						&lastfrm, 1);
941 
942 			if (res != TEE_SUCCESS)
943 				return res;
944 		}
945 
946 		if (consttime_memcmp(rawdata->key_mac,
947 				     (datafrm + nbr_frms - 1)->key_mac,
948 				     RPMB_KEY_MAC_SIZE) != 0) {
949 			DMSG("MAC mismatched:");
950 			if (IS_ENABLED(CFG_RPMB_FS_DEBUG_DATA))
951 				DHEXDUMP(rawdata->key_mac, RPMB_KEY_MAC_SIZE);
952 
953 			return TEE_ERROR_SECURITY;
954 		}
955 	}
956 
957 	return TEE_SUCCESS;
958 }
959 
960 static TEE_Result tee_rpmb_get_dev_info(struct rpmb_dev_info *dev_info)
961 {
962 	TEE_Result res = TEE_ERROR_GENERIC;
963 	struct tee_rpmb_mem mem;
964 	struct rpmb_dev_info *di;
965 
966 	if (!dev_info || !rpmb_ctx->legacy_operation)
967 		return TEE_ERROR_BAD_PARAMETERS;
968 
969 	res = tee_rpmb_alloc(0, sizeof(struct rpmb_dev_info), &mem);
970 	if (res != TEE_SUCCESS)
971 		return res;
972 
973 	mem.req_hdr->cmd = RPMB_CMD_GET_DEV_INFO;
974 	mem.req_hdr->dev_id = rpmb_ctx->dev_id;
975 
976 	di = (struct rpmb_dev_info *)mem.resp_data;
977 	di->ret_code = RPMB_CMD_GET_DEV_INFO_RET_ERROR;
978 
979 	res = tee_rpmb_invoke(&mem);
980 	if (res != TEE_SUCCESS)
981 		return res;
982 
983 	*dev_info = *di;
984 	if (dev_info->ret_code != RPMB_CMD_GET_DEV_INFO_RET_OK)
985 		return TEE_ERROR_GENERIC;
986 
987 	if (IS_ENABLED(CFG_RPMB_FS_DEBUG_DATA)) {
988 		DMSG("Dumping dev_info:");
989 		DHEXDUMP((uint8_t *)dev_info, sizeof(struct rpmb_dev_info));
990 	}
991 
992 	return TEE_SUCCESS;
993 }
994 
995 static TEE_Result tee_rpmb_init_read_wr_cnt(uint32_t *wr_cnt)
996 {
997 	TEE_Result res = TEE_ERROR_GENERIC;
998 	struct tee_rpmb_mem mem;
999 	uint16_t msg_type;
1000 	uint8_t nonce[RPMB_NONCE_SIZE];
1001 	uint8_t hmac[RPMB_KEY_MAC_SIZE];
1002 	struct rpmb_raw_data rawdata;
1003 	uint16_t op_result = 0;
1004 
1005 	if (!wr_cnt)
1006 		return TEE_ERROR_BAD_PARAMETERS;
1007 
1008 	res = tee_rpmb_alloc(RPMB_DATA_FRAME_SIZE, RPMB_DATA_FRAME_SIZE, &mem);
1009 	if (res != TEE_SUCCESS)
1010 		return res;
1011 
1012 	res = crypto_rng_read(nonce, RPMB_NONCE_SIZE);
1013 	if (res != TEE_SUCCESS)
1014 		return res;
1015 
1016 	msg_type = RPMB_MSG_TYPE_REQ_WRITE_COUNTER_VAL_READ;
1017 
1018 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1019 	rawdata.msg_type = msg_type;
1020 	rawdata.nonce = nonce;
1021 
1022 	res = tee_rpmb_req_pack(mem.req_hdr, mem.req_data, &rawdata, 1, NULL,
1023 				NULL);
1024 	if (res != TEE_SUCCESS)
1025 		return res;
1026 
1027 	res = tee_rpmb_invoke(&mem);
1028 	if (res != TEE_SUCCESS)
1029 		return res;
1030 
1031 	msg_type = RPMB_MSG_TYPE_RESP_WRITE_COUNTER_VAL_READ;
1032 
1033 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1034 	rawdata.msg_type = msg_type;
1035 	rawdata.op_result = &op_result;
1036 	rawdata.write_counter = wr_cnt;
1037 	rawdata.nonce = nonce;
1038 	rawdata.key_mac = hmac;
1039 
1040 	return tee_rpmb_resp_unpack_verify(mem.resp_data, &rawdata, 1, NULL,
1041 					   NULL);
1042 }
1043 
1044 #ifdef CFG_RPMB_WRITE_KEY
1045 static TEE_Result tee_rpmb_write_key(void)
1046 {
1047 	TEE_Result res = TEE_ERROR_GENERIC;
1048 	struct tee_rpmb_mem mem = { 0 };
1049 	uint16_t msg_type;
1050 	struct rpmb_raw_data rawdata;
1051 
1052 	res = tee_rpmb_alloc(RPMB_DATA_FRAME_SIZE, RPMB_DATA_FRAME_SIZE, &mem);
1053 	if (res != TEE_SUCCESS)
1054 		return res;
1055 
1056 	msg_type = RPMB_MSG_TYPE_REQ_AUTH_KEY_PROGRAM;
1057 
1058 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1059 	rawdata.msg_type = msg_type;
1060 	rawdata.key_mac = rpmb_ctx->key;
1061 
1062 	res = tee_rpmb_req_pack(mem.req_hdr, mem.req_data, &rawdata, 1, NULL,
1063 				NULL);
1064 	if (res != TEE_SUCCESS)
1065 		return res;
1066 
1067 	res = tee_rpmb_invoke(&mem);
1068 	if (res != TEE_SUCCESS)
1069 		return res;
1070 
1071 	msg_type = RPMB_MSG_TYPE_RESP_AUTH_KEY_PROGRAM;
1072 
1073 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1074 	rawdata.msg_type = msg_type;
1075 
1076 	return tee_rpmb_resp_unpack_verify(mem.resp_data, &rawdata, 1, NULL,
1077 					   NULL);
1078 }
1079 
1080 static TEE_Result tee_rpmb_write_and_verify_key(void)
1081 {
1082 	TEE_Result res;
1083 
1084 	if (!plat_rpmb_key_is_ready()) {
1085 		DMSG("RPMB INIT: platform indicates RPMB key is not ready");
1086 		return TEE_ERROR_BAD_STATE;
1087 	}
1088 
1089 	DMSG("RPMB INIT: Writing Key value:");
1090 	DHEXDUMP(rpmb_ctx->key, RPMB_KEY_MAC_SIZE);
1091 
1092 	res = tee_rpmb_write_key();
1093 	if (res == TEE_SUCCESS) {
1094 		DMSG("RPMB INIT: Verifying Key");
1095 		res = tee_rpmb_init_read_wr_cnt(&rpmb_ctx->wr_cnt);
1096 	}
1097 	return res;
1098 }
1099 #else
1100 static TEE_Result tee_rpmb_write_and_verify_key(void)
1101 {
1102 	DMSG("RPMB INIT: CFG_RPMB_WRITE_KEY is not set");
1103 	return TEE_ERROR_STORAGE_NOT_AVAILABLE;
1104 }
1105 #endif
1106 
1107 static TEE_Result rpmb_set_dev_info(const struct rpmb_dev_info *dev_info)
1108 {
1109 	uint32_t nblocks = 0;
1110 
1111 	DMSG("RPMB: Syncing device information");
1112 
1113 	DMSG("RPMB: RPMB size is %"PRIu8"*128 KB", dev_info->rpmb_size_mult);
1114 	DMSG("RPMB: Reliable Write Sector Count is %"PRIu8,
1115 	     dev_info->rel_wr_sec_c);
1116 	DMSG("RPMB: CID");
1117 	DHEXDUMP(dev_info->cid, sizeof(dev_info->cid));
1118 
1119 	if (!dev_info->rpmb_size_mult)
1120 		return TEE_ERROR_GENERIC;
1121 
1122 	if (MUL_OVERFLOW(dev_info->rpmb_size_mult,
1123 			 RPMB_SIZE_SINGLE / RPMB_DATA_SIZE, &nblocks) ||
1124 	    SUB_OVERFLOW(nblocks, 1, &rpmb_ctx->max_blk_idx))
1125 		return TEE_ERROR_BAD_PARAMETERS;
1126 
1127 	memcpy(rpmb_ctx->cid, dev_info->cid, RPMB_EMMC_CID_SIZE);
1128 
1129 	if (IS_ENABLED(RPMB_DRIVER_MULTIPLE_WRITE_FIXED))
1130 		rpmb_ctx->rel_wr_blkcnt = dev_info->rel_wr_sec_c * 2;
1131 	else
1132 		rpmb_ctx->rel_wr_blkcnt = 1;
1133 
1134 	return TEE_SUCCESS;
1135 }
1136 
1137 static TEE_Result legacy_rpmb_init(void)
1138 {
1139 	TEE_Result res = TEE_SUCCESS;
1140 	struct rpmb_dev_info dev_info = { };
1141 
1142 	DMSG("Trying legacy RPMB init");
1143 	rpmb_ctx->legacy_operation = true;
1144 	rpmb_ctx->dev_id = CFG_RPMB_FS_DEV_ID;
1145 	rpmb_ctx->shm_type = THREAD_SHM_TYPE_APPLICATION;
1146 
1147 	if (!rpmb_ctx->dev_info_synced) {
1148 		dev_info.rpmb_size_mult = 0;
1149 		dev_info.rel_wr_sec_c = 0;
1150 		res = tee_rpmb_get_dev_info(&dev_info);
1151 		if (res != TEE_SUCCESS)
1152 			return res;
1153 
1154 		res = rpmb_set_dev_info(&dev_info);
1155 		if (res)
1156 			return res;
1157 
1158 		rpmb_ctx->dev_info_synced = true;
1159 	}
1160 
1161 	if (!rpmb_ctx->key_derived) {
1162 		DMSG("RPMB INIT: Deriving key");
1163 
1164 		res = tee_rpmb_key_gen(rpmb_ctx->key, RPMB_KEY_MAC_SIZE);
1165 		if (res != TEE_SUCCESS) {
1166 			EMSG("RPMB INIT: Deriving key failed with error 0x%x",
1167 				res);
1168 			return res;
1169 		}
1170 
1171 		rpmb_ctx->key_derived = true;
1172 	}
1173 
1174 	/* Perform a write counter read to verify if the key is ok. */
1175 	if (!rpmb_ctx->wr_cnt_synced || !rpmb_ctx->key_verified) {
1176 		DMSG("RPMB INIT: Verifying Key");
1177 
1178 		res = tee_rpmb_init_read_wr_cnt(&rpmb_ctx->wr_cnt);
1179 		if (res == TEE_SUCCESS) {
1180 			DMSG("Found working RPMB device");
1181 			rpmb_ctx->key_verified = true;
1182 			rpmb_ctx->wr_cnt_synced = true;
1183 		} else if (res == TEE_ERROR_ITEM_NOT_FOUND &&
1184 			   !rpmb_ctx->key_verified) {
1185 			/*
1186 			 * Need to write the key here and verify it.
1187 			 */
1188 			DMSG("RPMB INIT: Auth key not yet written");
1189 			res = tee_rpmb_write_and_verify_key();
1190 		} else {
1191 			EMSG("Verify key failed! %#"PRIx32, res);
1192 			EMSG("Make sure key here matches device key");
1193 		}
1194 	}
1195 
1196 	return res;
1197 }
1198 
1199 /* This function must never return TEE_SUCCESS if rpmb_ctx == NULL */
1200 static TEE_Result tee_rpmb_init(void)
1201 {
1202 	TEE_Result res = TEE_SUCCESS;
1203 	struct rpmb_dev_info dev_info = { };
1204 
1205 	if (rpmb_dead)
1206 		return TEE_ERROR_COMMUNICATION;
1207 
1208 	if (!rpmb_ctx) {
1209 		rpmb_ctx = calloc(1, sizeof(struct tee_rpmb_ctx));
1210 		if (!rpmb_ctx)
1211 			return TEE_ERROR_OUT_OF_MEMORY;
1212 	}
1213 
1214 	if (rpmb_ctx->reinit) {
1215 		if (!rpmb_ctx->key_verified) {
1216 			rpmb_ctx->wr_cnt_synced = false;
1217 			rpmb_ctx->key_derived = false;
1218 			rpmb_ctx->dev_info_synced = false;
1219 			rpmb_ctx->reinit = false;
1220 			goto next;
1221 		}
1222 		res = rpmb_probe_reset();
1223 		if (res) {
1224 			if (res != TEE_ERROR_NOT_SUPPORTED)
1225 				return res;
1226 			return legacy_rpmb_init();
1227 		}
1228 		while (true) {
1229 			res = rpmb_probe_next(&dev_info);
1230 			if (res) {
1231 				DMSG("rpmb_probe_next error %#"PRIx32, res);
1232 				return res;
1233 			}
1234 			if (!memcmp(rpmb_ctx->cid, dev_info.cid,
1235 				    RPMB_EMMC_CID_SIZE)) {
1236 				rpmb_ctx->reinit = false;
1237 				return TEE_SUCCESS;
1238 			}
1239 		}
1240 	}
1241 
1242 	if (rpmb_ctx->key_verified)
1243 		return TEE_SUCCESS;
1244 
1245 next:
1246 	if (IS_ENABLED(CFG_RPMB_WRITE_KEY))
1247 		return legacy_rpmb_init();
1248 
1249 	res = rpmb_probe_reset();
1250 	if (res) {
1251 		if (res != TEE_ERROR_NOT_SUPPORTED)
1252 			return res;
1253 		return legacy_rpmb_init();
1254 	}
1255 
1256 	while (true) {
1257 		res = rpmb_probe_next(&dev_info);
1258 		if (res) {
1259 			DMSG("rpmb_probe_next error %#"PRIx32, res);
1260 			return res;
1261 		}
1262 		res = rpmb_set_dev_info(&dev_info);
1263 		if (res) {
1264 			DMSG("Invalid device info, looking for another device");
1265 			continue;
1266 		}
1267 
1268 		res = tee_rpmb_key_gen(rpmb_ctx->key, RPMB_KEY_MAC_SIZE);
1269 		if (res)
1270 			return res;
1271 
1272 		res = tee_rpmb_init_read_wr_cnt(&rpmb_ctx->wr_cnt);
1273 		if (res)
1274 			continue;
1275 		break;
1276 	}
1277 
1278 	DMSG("Found working RPMB device");
1279 	rpmb_ctx->key_verified = true;
1280 	rpmb_ctx->wr_cnt_synced = true;
1281 
1282 	return TEE_SUCCESS;
1283 }
1284 
1285 TEE_Result tee_rpmb_reinit(void)
1286 {
1287 	if (rpmb_ctx)
1288 		rpmb_ctx->reinit = true;
1289 	return tee_rpmb_init();
1290 }
1291 
1292 /*
1293  * Read RPMB data in bytes.
1294  *
1295  * @addr       Byte address of data.
1296  * @data       Pointer to the data.
1297  * @len        Size of data in bytes.
1298  * @fek        Encrypted File Encryption Key or NULL.
1299  */
1300 static TEE_Result tee_rpmb_read(uint32_t addr, uint8_t *data,
1301 				uint32_t len, const uint8_t *fek,
1302 				const TEE_UUID *uuid)
1303 {
1304 	TEE_Result res = TEE_ERROR_GENERIC;
1305 	struct tee_rpmb_mem mem = { 0 };
1306 	uint16_t msg_type;
1307 	uint8_t nonce[RPMB_NONCE_SIZE];
1308 	uint8_t hmac[RPMB_KEY_MAC_SIZE];
1309 	struct rpmb_raw_data rawdata;
1310 	uint16_t blk_idx;
1311 	uint16_t blkcnt;
1312 	uint8_t byte_offset;
1313 
1314 	if (!data || !len)
1315 		return TEE_ERROR_BAD_PARAMETERS;
1316 
1317 	blk_idx = addr / RPMB_DATA_SIZE;
1318 	byte_offset = addr % RPMB_DATA_SIZE;
1319 
1320 	if (len + byte_offset + RPMB_DATA_SIZE < RPMB_DATA_SIZE) {
1321 		/* Overflow */
1322 		return TEE_ERROR_BAD_PARAMETERS;
1323 	}
1324 	blkcnt = ROUNDUP_DIV(len + byte_offset, RPMB_DATA_SIZE);
1325 	res = tee_rpmb_init();
1326 	if (res != TEE_SUCCESS)
1327 		return res;
1328 
1329 	res = tee_rpmb_alloc(RPMB_DATA_FRAME_SIZE,
1330 			     RPMB_DATA_FRAME_SIZE * blkcnt, &mem);
1331 	if (res != TEE_SUCCESS)
1332 		return res;
1333 
1334 	msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_READ;
1335 	res = crypto_rng_read(nonce, RPMB_NONCE_SIZE);
1336 	if (res != TEE_SUCCESS)
1337 		return res;
1338 
1339 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1340 	rawdata.msg_type = msg_type;
1341 	rawdata.nonce = nonce;
1342 	rawdata.blk_idx = &blk_idx;
1343 	res = tee_rpmb_req_pack(mem.req_hdr, mem.req_data, &rawdata, 1, NULL,
1344 				NULL);
1345 	if (res != TEE_SUCCESS)
1346 		return res;
1347 
1348 	if (mem.req_hdr)
1349 		mem.req_hdr->block_count = blkcnt;
1350 
1351 	DMSG("Read %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""),
1352 	     blk_idx);
1353 
1354 	res = tee_rpmb_invoke(&mem);
1355 	if (res != TEE_SUCCESS)
1356 		return res;
1357 
1358 	msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_READ;
1359 
1360 	memset(&rawdata, 0x00, sizeof(struct rpmb_raw_data));
1361 	rawdata.msg_type = msg_type;
1362 	rawdata.block_count = &blkcnt;
1363 	rawdata.blk_idx = &blk_idx;
1364 	rawdata.nonce = nonce;
1365 	rawdata.key_mac = hmac;
1366 	rawdata.data = data;
1367 
1368 	rawdata.len = len;
1369 	rawdata.byte_offset = byte_offset;
1370 
1371 	return tee_rpmb_resp_unpack_verify(mem.resp_data, &rawdata, blkcnt,
1372 					   fek, uuid);
1373 }
1374 
1375 static TEE_Result write_req(uint16_t blk_idx,
1376 			    const void *data_blks, uint16_t blkcnt,
1377 			    const uint8_t *fek, const TEE_UUID *uuid,
1378 			    struct tee_rpmb_mem *mem)
1379 {
1380 	TEE_Result res = TEE_SUCCESS;
1381 	uint8_t hmac[RPMB_KEY_MAC_SIZE] = { };
1382 	uint32_t wr_cnt = rpmb_ctx->wr_cnt;
1383 	struct rpmb_raw_data rawdata = { };
1384 	size_t retry_count = 0;
1385 
1386 	while (true) {
1387 		if (mem->req_hdr)
1388 			memset(mem->req_hdr, 0, mem->req_size);
1389 		else
1390 			memset(mem->req_data, 0, mem->req_size);
1391 		memset(mem->resp_data, 0, mem->resp_size);
1392 
1393 		memset(&rawdata, 0, sizeof(struct rpmb_raw_data));
1394 		rawdata.msg_type = RPMB_MSG_TYPE_REQ_AUTH_DATA_WRITE;
1395 		rawdata.block_count = &blkcnt;
1396 		rawdata.blk_idx = &blk_idx;
1397 		rawdata.write_counter = &wr_cnt;
1398 		rawdata.key_mac = hmac;
1399 		rawdata.data = (uint8_t *)data_blks;
1400 
1401 		res = tee_rpmb_req_pack(mem->req_hdr, mem->req_data, &rawdata,
1402 					blkcnt, fek, uuid);
1403 		if (res) {
1404 			/*
1405 			 * If we haven't tried to send a request yet we can
1406 			 * allow a failure here since there's no chance of
1407 			 * an intercepted request with a valid write
1408 			 * counter.
1409 			 */
1410 			if (!retry_count)
1411 				return res;
1412 
1413 			retry_count++;
1414 			if (retry_count >= RPMB_MAX_RETRIES)
1415 				goto out_of_retries;
1416 
1417 			DMSG("Request pack failed, retrying %zu", retry_count);
1418 			continue;
1419 		}
1420 
1421 		res = tee_rpmb_invoke(mem);
1422 		if (res != TEE_SUCCESS) {
1423 			retry_count++;
1424 			if (retry_count >= RPMB_MAX_RETRIES)
1425 				goto out_of_retries;
1426 			/*
1427 			 * To force wr_cnt sync next time, as it might get
1428 			 * out of sync due to inconsistent operation result!
1429 			 */
1430 			rpmb_ctx->wr_cnt_synced = false;
1431 			DMSG("Write invoke failed, retrying %zu", retry_count);
1432 			continue;
1433 		}
1434 
1435 		memset(&rawdata, 0, sizeof(struct rpmb_raw_data));
1436 		rawdata.msg_type = RPMB_MSG_TYPE_RESP_AUTH_DATA_WRITE;
1437 		rawdata.block_count = &blkcnt;
1438 		rawdata.blk_idx = &blk_idx;
1439 		rawdata.write_counter = &wr_cnt;
1440 		rawdata.key_mac = hmac;
1441 
1442 		res = tee_rpmb_resp_unpack_verify(mem->resp_data, &rawdata, 1,
1443 						  NULL, NULL);
1444 		if (res != TEE_SUCCESS) {
1445 			retry_count++;
1446 			if (retry_count >= RPMB_MAX_RETRIES)
1447 				goto out_of_retries;
1448 			/*
1449 			 * To force wr_cnt sync next time, as it might get
1450 			 * out of sync due to inconsistent operation result!
1451 			 */
1452 			rpmb_ctx->wr_cnt_synced = false;
1453 			DMSG("Write resp unpack verify failed, retrying %zu",
1454 			     retry_count);
1455 			continue;
1456 		}
1457 
1458 		return TEE_SUCCESS;
1459 	}
1460 
1461 out_of_retries:
1462 	rpmb_dead = true;
1463 	/*
1464 	 * We're using this error code to cause an eventuall calling TA to
1465 	 * panic since we don't know if the data to be written has been
1466 	 * committed to storage or not.
1467 	 */
1468 	return TEE_ERROR_COMMUNICATION;
1469 }
1470 
1471 static TEE_Result tee_rpmb_write_blk(uint16_t blk_idx,
1472 				     const uint8_t *data_blks, uint16_t blkcnt,
1473 				     const uint8_t *fek, const TEE_UUID *uuid)
1474 {
1475 	TEE_Result res;
1476 	struct tee_rpmb_mem mem;
1477 	uint32_t req_size;
1478 	uint32_t nbr_writes;
1479 	uint16_t tmp_blkcnt;
1480 	uint16_t tmp_blk_idx;
1481 	uint16_t i;
1482 
1483 	DMSG("Write %u block%s at index %u", blkcnt, ((blkcnt > 1) ? "s" : ""),
1484 	     blk_idx);
1485 
1486 	if (!data_blks || !blkcnt)
1487 		return TEE_ERROR_BAD_PARAMETERS;
1488 
1489 	res = tee_rpmb_init();
1490 	if (res != TEE_SUCCESS)
1491 		return res;
1492 
1493 	/*
1494 	 * We need to split data when block count
1495 	 * is bigger than reliable block write count.
1496 	 */
1497 	req_size = RPMB_DATA_FRAME_SIZE * MIN(blkcnt, rpmb_ctx->rel_wr_blkcnt);
1498 	res = tee_rpmb_alloc(req_size, RPMB_DATA_FRAME_SIZE, &mem);
1499 	if (res != TEE_SUCCESS)
1500 		return res;
1501 
1502 	nbr_writes = blkcnt / rpmb_ctx->rel_wr_blkcnt;
1503 	if (blkcnt % rpmb_ctx->rel_wr_blkcnt > 0)
1504 		nbr_writes += 1;
1505 
1506 	tmp_blkcnt = rpmb_ctx->rel_wr_blkcnt;
1507 	tmp_blk_idx = blk_idx;
1508 	for (i = 0; i < nbr_writes; i++) {
1509 		size_t offs = i * rpmb_ctx->rel_wr_blkcnt * RPMB_DATA_SIZE;
1510 
1511 		/*
1512 		 * To handle the last write of block count which is
1513 		 * equal or smaller than reliable write block count.
1514 		 */
1515 		if (i == nbr_writes - 1)
1516 			tmp_blkcnt = blkcnt - rpmb_ctx->rel_wr_blkcnt *
1517 			    (nbr_writes - 1);
1518 
1519 		res = write_req(tmp_blk_idx, data_blks + offs,
1520 				tmp_blkcnt, fek, uuid, &mem);
1521 		if (res)
1522 			return res;
1523 
1524 
1525 		tmp_blk_idx += tmp_blkcnt;
1526 	}
1527 
1528 	return TEE_SUCCESS;
1529 }
1530 
1531 static bool tee_rpmb_write_is_atomic(uint32_t addr, uint32_t len)
1532 {
1533 	uint8_t byte_offset = addr % RPMB_DATA_SIZE;
1534 	uint16_t blkcnt = ROUNDUP_DIV(len + byte_offset, RPMB_DATA_SIZE);
1535 
1536 	return (blkcnt <= rpmb_ctx->rel_wr_blkcnt);
1537 }
1538 
1539 /*
1540  * Write RPMB data in bytes.
1541  *
1542  * @addr       Byte address of data.
1543  * @data       Pointer to the data.
1544  * @len        Size of data in bytes.
1545  * @fek        Encrypted File Encryption Key or NULL.
1546  */
1547 static TEE_Result tee_rpmb_write(uint32_t addr,
1548 				 const uint8_t *data, uint32_t len,
1549 				 const uint8_t *fek, const TEE_UUID *uuid)
1550 {
1551 	TEE_Result res = TEE_ERROR_GENERIC;
1552 	uint8_t *data_tmp = NULL;
1553 	uint16_t blk_idx;
1554 	uint16_t blkcnt;
1555 	uint8_t byte_offset;
1556 
1557 	blk_idx = addr / RPMB_DATA_SIZE;
1558 	byte_offset = addr % RPMB_DATA_SIZE;
1559 
1560 	blkcnt = ROUNDUP_DIV(len + byte_offset, RPMB_DATA_SIZE);
1561 
1562 	if (byte_offset == 0 && (len % RPMB_DATA_SIZE) == 0) {
1563 		res = tee_rpmb_write_blk(blk_idx, data, blkcnt, fek, uuid);
1564 		if (res != TEE_SUCCESS)
1565 			goto func_exit;
1566 	} else {
1567 		data_tmp = calloc(blkcnt, RPMB_DATA_SIZE);
1568 		if (!data_tmp) {
1569 			res = TEE_ERROR_OUT_OF_MEMORY;
1570 			goto func_exit;
1571 		}
1572 
1573 		/* Read the complete blocks */
1574 		res = tee_rpmb_read(blk_idx * RPMB_DATA_SIZE, data_tmp,
1575 				    blkcnt * RPMB_DATA_SIZE, fek, uuid);
1576 		if (res != TEE_SUCCESS)
1577 			goto func_exit;
1578 
1579 		/* Partial update of the data blocks */
1580 		memcpy(data_tmp + byte_offset, data, len);
1581 
1582 		res = tee_rpmb_write_blk(blk_idx, data_tmp, blkcnt, fek, uuid);
1583 		if (res != TEE_SUCCESS)
1584 			goto func_exit;
1585 	}
1586 
1587 	res = TEE_SUCCESS;
1588 
1589 func_exit:
1590 	free(data_tmp);
1591 	return res;
1592 }
1593 
1594 /*
1595  * Read the RPMB max block.
1596  *
1597  * @counter    Pointer to receive the max block.
1598  */
1599 static TEE_Result tee_rpmb_get_max_block(uint32_t *max_block)
1600 {
1601 	TEE_Result res = TEE_SUCCESS;
1602 
1603 	if (!max_block)
1604 		return TEE_ERROR_BAD_PARAMETERS;
1605 
1606 	if (rpmb_dead)
1607 		return TEE_ERROR_COMMUNICATION;
1608 
1609 	if (!rpmb_ctx || !rpmb_ctx->dev_info_synced) {
1610 		res = tee_rpmb_init();
1611 		if (res != TEE_SUCCESS)
1612 			goto func_exit;
1613 	}
1614 
1615 	*max_block = rpmb_ctx->max_blk_idx;
1616 
1617 func_exit:
1618 	return res;
1619 }
1620 
1621 /*
1622  * End of lower interface to RPMB device
1623  */
1624 
1625 static TEE_Result get_fat_start_address(uint32_t *addr);
1626 static TEE_Result rpmb_fs_setup(void);
1627 
1628 /**
1629  * fat_entry_dir_free: Free the FAT entry dir.
1630  */
1631 static void fat_entry_dir_free(void)
1632 {
1633 	if (fat_entry_dir) {
1634 		free(fat_entry_dir->rpmb_fat_entry_buf);
1635 		free(fat_entry_dir);
1636 		fat_entry_dir = NULL;
1637 	}
1638 }
1639 
1640 /**
1641  * fat_entry_dir_init: Initialize the FAT FS entry buffer/cache
1642  * This function must be called before reading FAT FS entries using the
1643  * function fat_entry_dir_get_next. This initializes the buffer/cache with the
1644  * first FAT FS entries.
1645  */
1646 static TEE_Result fat_entry_dir_init(void)
1647 {
1648 	TEE_Result res = TEE_ERROR_GENERIC;
1649 	struct rpmb_fat_entry *fe = NULL;
1650 	uint32_t fat_address = 0;
1651 	uint32_t num_elems_read = 0;
1652 
1653 	if (fat_entry_dir)
1654 		return TEE_SUCCESS;
1655 
1656 	res = rpmb_fs_setup();
1657 	if (res)
1658 		return res;
1659 
1660 	res = get_fat_start_address(&fat_address);
1661 	if (res)
1662 		return res;
1663 
1664 	fat_entry_dir = calloc(1, sizeof(struct rpmb_fat_entry_dir));
1665 	if (!fat_entry_dir)
1666 		return TEE_ERROR_OUT_OF_MEMORY;
1667 
1668 	/*
1669 	 * If caching is enabled, read in up to the maximum cache size, but
1670 	 * never more than the single read in size. Otherwise, read in as many
1671 	 * entries fit into the temporary buffer.
1672 	 */
1673 	if (CFG_RPMB_FS_CACHE_ENTRIES)
1674 		num_elems_read = MIN(CFG_RPMB_FS_CACHE_ENTRIES,
1675 				     CFG_RPMB_FS_RD_ENTRIES);
1676 	else
1677 		num_elems_read = CFG_RPMB_FS_RD_ENTRIES;
1678 
1679 	/*
1680 	 * Allocate memory for the FAT FS entries to read in.
1681 	 */
1682 	fe = calloc(num_elems_read, sizeof(struct rpmb_fat_entry));
1683 	if (!fe) {
1684 		res = TEE_ERROR_OUT_OF_MEMORY;
1685 		goto out;
1686 	}
1687 
1688 	res = tee_rpmb_read(fat_address, (uint8_t *)fe,
1689 			    num_elems_read * sizeof(*fe), NULL, NULL);
1690 	if (res)
1691 		goto out;
1692 
1693 	fat_entry_dir->rpmb_fat_entry_buf = fe;
1694 
1695 	/*
1696 	 * We use this variable when getting next entries from the buffer/cache
1697 	 * to see whether we have to read in more entries from storage.
1698 	 */
1699 	fat_entry_dir->num_buffered = num_elems_read;
1700 
1701 	return TEE_SUCCESS;
1702 out:
1703 	fat_entry_dir_free();
1704 	free(fe);
1705 	return res;
1706 }
1707 
1708 /**
1709  * fat_entry_dir_deinit: If caching is enabled, free the temporary buffer for
1710  * FAT FS entries in case the cache was too small. Keep the elements in the
1711  * cache. Reset the counter variables to start the next traversal from fresh
1712  * from the first cached entry. If caching is disabled, just free the
1713  * temporary buffer by calling fat_entry_dir_free and return.
1714  */
1715 static void fat_entry_dir_deinit(void)
1716 {
1717 	struct rpmb_fat_entry *fe = NULL;
1718 
1719 	if (!fat_entry_dir)
1720 		return;
1721 
1722 	if (!CFG_RPMB_FS_CACHE_ENTRIES) {
1723 		fat_entry_dir_free();
1724 		return;
1725 	}
1726 
1727 	fe = fat_entry_dir->rpmb_fat_entry_buf;
1728 	fat_entry_dir->idx_curr = 0;
1729 	fat_entry_dir->num_total_read = 0;
1730 	fat_entry_dir->last_reached = false;
1731 
1732 	if (fat_entry_dir->num_buffered > CFG_RPMB_FS_CACHE_ENTRIES) {
1733 		fat_entry_dir->num_buffered = CFG_RPMB_FS_CACHE_ENTRIES;
1734 
1735 		fe = realloc(fe, fat_entry_dir->num_buffered * sizeof(*fe));
1736 
1737 		/*
1738 		 * In case realloc fails, we are on the safe side if we destroy
1739 		 * the whole structure. Upon the next init, the cache has to be
1740 		 * re-established, but this case should not happen in practice.
1741 		 */
1742 		if (!fe)
1743 			fat_entry_dir_free();
1744 		else
1745 			fat_entry_dir->rpmb_fat_entry_buf = fe;
1746 	}
1747 }
1748 
1749 /**
1750  * fat_entry_dir_update: Updates a persisted FAT FS entry in the cache.
1751  * This function updates the FAT entry fat_entry that was written to address
1752  * fat_address onto RPMB storage in the cache.
1753  */
1754 static TEE_Result __maybe_unused fat_entry_dir_update
1755 					(struct rpmb_fat_entry *fat_entry,
1756 					 uint32_t fat_address)
1757 {
1758 	uint32_t fat_entry_buf_idx = 0;
1759 	/* Use a temp var to avoid compiler warning if caching disabled. */
1760 	uint32_t max_cache_entries = CFG_RPMB_FS_CACHE_ENTRIES;
1761 
1762 	assert(!((fat_address - RPMB_FS_FAT_START_ADDRESS) %
1763 	       sizeof(struct rpmb_fat_entry)));
1764 
1765 	/* Nothing to update if the cache is not initialized. */
1766 	if (!fat_entry_dir)
1767 		return TEE_SUCCESS;
1768 
1769 	fat_entry_buf_idx = (fat_address - RPMB_FS_FAT_START_ADDRESS) /
1770 			     sizeof(struct rpmb_fat_entry);
1771 
1772 	/* Only need to write if index points to an entry in cache. */
1773 	if (fat_entry_buf_idx < fat_entry_dir->num_buffered &&
1774 	    fat_entry_buf_idx < max_cache_entries) {
1775 		memcpy(fat_entry_dir->rpmb_fat_entry_buf + fat_entry_buf_idx,
1776 		       fat_entry, sizeof(struct rpmb_fat_entry));
1777 	}
1778 
1779 	return TEE_SUCCESS;
1780 }
1781 
1782 /**
1783  * fat_entry_dir_get_next: Get next FAT FS entry.
1784  * Read either from cache/buffer, or by reading from RPMB storage if the
1785  * elements in the buffer/cache are fully read. When reading in from RPMB
1786  * storage, the buffer is overwritten in case caching is disabled.
1787  * In case caching is enabled, the cache is either further filled, or a
1788  * temporary buffer populated if the cache is already full.
1789  * The FAT FS entry is written to fat_entry. The respective address in RPMB
1790  * storage is written to fat_address, if not NULL. When the last FAT FS entry
1791  * was previously read, the function indicates this case by writing a NULL
1792  * pointer to fat_entry.
1793  * Returns a value different TEE_SUCCESS if the next FAT FS entry could not be
1794  * retrieved.
1795  */
1796 static TEE_Result fat_entry_dir_get_next(struct rpmb_fat_entry **fat_entry,
1797 					 uint32_t *fat_address)
1798 {
1799 	TEE_Result res = TEE_ERROR_GENERIC;
1800 	struct rpmb_fat_entry *fe = NULL;
1801 	uint32_t num_elems_read = 0;
1802 	uint32_t fat_address_local = 0;
1803 
1804 	assert(fat_entry_dir && fat_entry);
1805 
1806 	/* Don't read further if we previously read the last FAT FS entry. */
1807 	if (fat_entry_dir->last_reached) {
1808 		*fat_entry = NULL;
1809 		return TEE_SUCCESS;
1810 	}
1811 
1812 	fe = fat_entry_dir->rpmb_fat_entry_buf;
1813 
1814 	/* Determine address of FAT FS entry in RPMB storage. */
1815 	fat_address_local = RPMB_FS_FAT_START_ADDRESS +
1816 			(fat_entry_dir->num_total_read *
1817 			sizeof(struct rpmb_fat_entry));
1818 
1819 	/*
1820 	 * We've read all so-far buffered elements, so we need to
1821 	 * read in more entries from RPMB storage.
1822 	 */
1823 	if (fat_entry_dir->idx_curr >= fat_entry_dir->num_buffered) {
1824 		/*
1825 		 * This is the case where we do not cache entries, so just read
1826 		 * in next set of FAT FS entries into the buffer.
1827 		 * Goto the end of the when statement if that is done.
1828 		 */
1829 		if (!CFG_RPMB_FS_CACHE_ENTRIES) {
1830 			num_elems_read = CFG_RPMB_FS_RD_ENTRIES;
1831 			fat_entry_dir->idx_curr = 0;
1832 
1833 			res = tee_rpmb_read(fat_address_local, (uint8_t *)fe,
1834 					    num_elems_read * sizeof(*fe), NULL,
1835 					    NULL);
1836 			if (res)
1837 				return res;
1838 			goto post_read_in;
1839 		}
1840 
1841 		/*
1842 		 * We cache FAT FS entries, and the buffer is not completely
1843 		 * filled. Further keep on extending the buffer up to its max
1844 		 * size by reading in from RPMB.
1845 		 */
1846 		if (fat_entry_dir->num_total_read < RPMB_BUF_MAX_ENTRIES) {
1847 			/*
1848 			 * Read at most as many elements as fit in the buffer
1849 			 * and no more than the defined number of entries to
1850 			 * read in at once.
1851 			 */
1852 			num_elems_read = MIN(RPMB_BUF_MAX_ENTRIES -
1853 					     fat_entry_dir->num_total_read,
1854 					     (uint32_t)CFG_RPMB_FS_RD_ENTRIES);
1855 
1856 			/*
1857 			 * Expand the buffer to fit in the additional entries.
1858 			 */
1859 			fe = realloc(fe,
1860 				     (fat_entry_dir->num_buffered +
1861 				      num_elems_read) * sizeof(*fe));
1862 			if (!fe)
1863 				return TEE_ERROR_OUT_OF_MEMORY;
1864 
1865 			fat_entry_dir->rpmb_fat_entry_buf = fe;
1866 
1867 			/* Read in to the next free slot in the buffer/cache. */
1868 			res = tee_rpmb_read(fat_address_local,
1869 					    (uint8_t *)(fe +
1870 					    fat_entry_dir->num_total_read),
1871 					    num_elems_read * sizeof(*fe),
1872 					    NULL, NULL);
1873 			if (res)
1874 				return res;
1875 
1876 			fat_entry_dir->num_buffered += num_elems_read;
1877 		} else {
1878 			/*
1879 			 * This happens when we have read as many elements as
1880 			 * can possibly fit into the buffer.
1881 			 * As the first part of the buffer serves as our cache,
1882 			 * we only overwrite the last part that serves as our
1883 			 * temporary buffer used to iteratively read in entries
1884 			 * when the cache is full. Read in the temporary buffer
1885 			 * maximum size.
1886 			 */
1887 			num_elems_read = CFG_RPMB_FS_RD_ENTRIES;
1888 			/* Reset index to beginning of the temporary buffer. */
1889 			fat_entry_dir->idx_curr = CFG_RPMB_FS_CACHE_ENTRIES;
1890 
1891 			/* Read in elements after the end of the cache. */
1892 			res = tee_rpmb_read(fat_address_local,
1893 					    (uint8_t *)(fe +
1894 					    fat_entry_dir->idx_curr),
1895 					    num_elems_read * sizeof(*fe),
1896 					    NULL, NULL);
1897 			if (res)
1898 				return res;
1899 		}
1900 	}
1901 
1902 post_read_in:
1903 	if (fat_address)
1904 		*fat_address = fat_address_local;
1905 
1906 	*fat_entry = fe + fat_entry_dir->idx_curr;
1907 
1908 	fat_entry_dir->idx_curr++;
1909 	fat_entry_dir->num_total_read++;
1910 
1911 	/*
1912 	 * Indicate last entry was read.
1913 	 * Ensures we return a zero value for fat_entry on next invocation.
1914 	 */
1915 	if ((*fat_entry)->flags & FILE_IS_LAST_ENTRY)
1916 		fat_entry_dir->last_reached = true;
1917 
1918 	return TEE_SUCCESS;
1919 }
1920 
1921 #if (TRACE_LEVEL >= TRACE_FLOW)
1922 static void dump_fat(void)
1923 {
1924 	TEE_Result res = TEE_ERROR_SECURITY;
1925 	struct rpmb_fat_entry *fe = NULL;
1926 
1927 	if (!fs_par)
1928 		return;
1929 
1930 	if (fat_entry_dir_init())
1931 		return;
1932 
1933 	while (true) {
1934 		res = fat_entry_dir_get_next(&fe, NULL);
1935 		if (res || !fe)
1936 			break;
1937 
1938 		FMSG("flags %#"PRIx32", size %"PRIu32", address %#"PRIx32
1939 		     ", filename '%s'",
1940 		     fe->flags, fe->data_size, fe->start_address, fe->filename);
1941 	}
1942 
1943 	fat_entry_dir_deinit();
1944 }
1945 #else
1946 static void dump_fat(void)
1947 {
1948 }
1949 #endif
1950 
1951 #if (TRACE_LEVEL >= TRACE_DEBUG)
1952 static void dump_fh(struct rpmb_file_handle *fh)
1953 {
1954 	DMSG("fh->filename=%s", fh->filename);
1955 	DMSG("fh->rpmb_fat_address=%u", fh->rpmb_fat_address);
1956 	DMSG("fh->fat_entry.start_address=%u", fh->fat_entry.start_address);
1957 	DMSG("fh->fat_entry.data_size=%u", fh->fat_entry.data_size);
1958 }
1959 #else
1960 static void dump_fh(struct rpmb_file_handle *fh __unused)
1961 {
1962 }
1963 #endif
1964 
1965 /* "/TA_uuid/object_id" or "/TA_uuid/.object_id" */
1966 static TEE_Result create_filename(void *buf, size_t blen, struct tee_pobj *po,
1967 				  bool transient)
1968 {
1969 	uint8_t *file = buf;
1970 	uint32_t pos = 0;
1971 	uint32_t hslen = 1 /* Leading slash */
1972 			+ TEE_B2HS_HSBUF_SIZE(sizeof(TEE_UUID) + po->obj_id_len)
1973 			+ 1; /* Intermediate slash */
1974 
1975 	/* +1 for the '.' (temporary persistent object) */
1976 	if (transient)
1977 		hslen++;
1978 
1979 	if (blen < hslen)
1980 		return TEE_ERROR_SHORT_BUFFER;
1981 
1982 	file[pos++] = '/';
1983 	pos += tee_b2hs((uint8_t *)&po->uuid, &file[pos],
1984 			sizeof(TEE_UUID), hslen);
1985 	file[pos++] = '/';
1986 
1987 	if (transient)
1988 		file[pos++] = '.';
1989 
1990 	tee_b2hs(po->obj_id, file + pos, po->obj_id_len, hslen - pos);
1991 
1992 	return TEE_SUCCESS;
1993 }
1994 
1995 /* "/TA_uuid" */
1996 static TEE_Result create_dirname(void *buf, size_t blen, const TEE_UUID *uuid)
1997 {
1998 	uint8_t *dir = buf;
1999 	uint32_t hslen = TEE_B2HS_HSBUF_SIZE(sizeof(TEE_UUID)) + 1;
2000 
2001 	if (blen < hslen)
2002 		return TEE_ERROR_SHORT_BUFFER;
2003 
2004 	dir[0] = '/';
2005 	tee_b2hs((uint8_t *)uuid, dir + 1, sizeof(TEE_UUID), hslen);
2006 
2007 	return TEE_SUCCESS;
2008 }
2009 
2010 static struct rpmb_file_handle *alloc_file_handle(struct tee_pobj *po,
2011 						  bool temporary)
2012 {
2013 	struct rpmb_file_handle *fh = NULL;
2014 
2015 	fh = calloc(1, sizeof(struct rpmb_file_handle));
2016 	if (!fh)
2017 		return NULL;
2018 
2019 	if (po)
2020 		create_filename(fh->filename, sizeof(fh->filename), po,
2021 				temporary);
2022 
2023 	return fh;
2024 }
2025 
2026 /**
2027  * write_fat_entry: Store info in a fat_entry to RPMB.
2028  */
2029 static TEE_Result write_fat_entry(struct rpmb_file_handle *fh)
2030 {
2031 	TEE_Result res = TEE_ERROR_GENERIC;
2032 
2033 	/* Protect partition data. */
2034 	if (fh->rpmb_fat_address < sizeof(struct rpmb_fs_partition)) {
2035 		res = TEE_ERROR_ACCESS_CONFLICT;
2036 		goto out;
2037 	}
2038 
2039 	if (fh->rpmb_fat_address % sizeof(struct rpmb_fat_entry) != 0) {
2040 		res = TEE_ERROR_BAD_PARAMETERS;
2041 		goto out;
2042 	}
2043 
2044 	res = tee_rpmb_write(fh->rpmb_fat_address, (uint8_t *)&fh->fat_entry,
2045 			     sizeof(struct rpmb_fat_entry), NULL, NULL);
2046 
2047 	dump_fat();
2048 
2049 	/* If caching enabled, update a successfully written entry in cache. */
2050 	if (CFG_RPMB_FS_CACHE_ENTRIES && !res)
2051 		res = fat_entry_dir_update(&fh->fat_entry,
2052 					   fh->rpmb_fat_address);
2053 
2054 out:
2055 	return res;
2056 }
2057 
2058 /**
2059  * rpmb_fs_setup: Setup RPMB FS.
2060  * Set initial partition and FS values and write to RPMB.
2061  * Store frequently used data in RAM.
2062  */
2063 static TEE_Result rpmb_fs_setup(void)
2064 {
2065 	TEE_Result res = TEE_ERROR_GENERIC;
2066 	struct rpmb_fs_partition *partition_data = NULL;
2067 	struct rpmb_file_handle *fh = NULL;
2068 	uint32_t max_rpmb_block = 0;
2069 
2070 	if (fs_par) {
2071 		res = TEE_SUCCESS;
2072 		goto out;
2073 	}
2074 
2075 	res = tee_rpmb_get_max_block(&max_rpmb_block);
2076 	if (res != TEE_SUCCESS)
2077 		goto out;
2078 
2079 	/*
2080 	 * We're going to read a full block in order to have a full block
2081 	 * for the dummy write below.
2082 	 */
2083 	COMPILE_TIME_ASSERT(sizeof(struct rpmb_fs_partition) <=
2084 			    RPMB_DATA_SIZE);
2085 	partition_data = calloc(1, RPMB_DATA_SIZE);
2086 	if (!partition_data) {
2087 		res = TEE_ERROR_OUT_OF_MEMORY;
2088 		goto out;
2089 	}
2090 
2091 	res = tee_rpmb_read(RPMB_STORAGE_START_ADDRESS,
2092 			    (uint8_t *)partition_data, RPMB_DATA_SIZE,
2093 			    NULL, NULL);
2094 	if (res != TEE_SUCCESS)
2095 		goto out;
2096 	/*
2097 	 * Perform a write in order to increase the write counter. This
2098 	 * prevents late usage (replay attack) of a previously blocked
2099 	 * request with a valid write counter value.
2100 	 */
2101 	res = tee_rpmb_write(RPMB_STORAGE_START_ADDRESS,
2102 			     (uint8_t *)partition_data, RPMB_DATA_SIZE,
2103 			     NULL, NULL);
2104 	if (res != TEE_SUCCESS)
2105 		goto out;
2106 	/*
2107 	 * We're reading again in case a stale request was committed
2108 	 * instead of the one issued above. If this succeeds we're in sync
2109 	 * with the RPMB block since there are no other possible stale
2110 	 * blocks with valid write counters available.
2111 	 */
2112 	res = tee_rpmb_read(RPMB_STORAGE_START_ADDRESS,
2113 			    (uint8_t *)partition_data,
2114 			    sizeof(struct rpmb_fs_partition), NULL, NULL);
2115 	if (res != TEE_SUCCESS)
2116 		goto out;
2117 
2118 #ifndef CFG_RPMB_RESET_FAT
2119 	if (partition_data->rpmb_fs_magic == RPMB_FS_MAGIC) {
2120 		if (partition_data->fs_version == FS_VERSION) {
2121 			res = TEE_SUCCESS;
2122 			goto store_fs_par;
2123 		} else {
2124 			EMSG("Wrong software is in use.");
2125 			res = TEE_ERROR_ACCESS_DENIED;
2126 			goto out;
2127 		}
2128 	}
2129 #else
2130 	EMSG("**** Clearing Storage ****");
2131 #endif
2132 
2133 	/* Setup new partition data. */
2134 	partition_data->rpmb_fs_magic = RPMB_FS_MAGIC;
2135 	partition_data->fs_version = FS_VERSION;
2136 	partition_data->fat_start_address = RPMB_FS_FAT_START_ADDRESS;
2137 
2138 	/* Initial FAT entry with FILE_IS_LAST_ENTRY flag set. */
2139 	fh = alloc_file_handle(NULL, false);
2140 	if (!fh) {
2141 		res = TEE_ERROR_OUT_OF_MEMORY;
2142 		goto out;
2143 	}
2144 	fh->fat_entry.flags = FILE_IS_LAST_ENTRY;
2145 	fh->rpmb_fat_address = partition_data->fat_start_address;
2146 
2147 	/* Write init FAT entry and partition data to RPMB. */
2148 	res = write_fat_entry(fh);
2149 	if (res != TEE_SUCCESS)
2150 		goto out;
2151 
2152 	res = tee_rpmb_write(RPMB_STORAGE_START_ADDRESS,
2153 			     (uint8_t *)partition_data,
2154 			     sizeof(struct rpmb_fs_partition), NULL, NULL);
2155 
2156 #ifndef CFG_RPMB_RESET_FAT
2157 store_fs_par:
2158 #endif
2159 
2160 	/* Store FAT start address. */
2161 	fs_par = calloc(1, sizeof(struct rpmb_fs_parameters));
2162 	if (!fs_par) {
2163 		res = TEE_ERROR_OUT_OF_MEMORY;
2164 		goto out;
2165 	}
2166 
2167 	fs_par->fat_start_address = partition_data->fat_start_address;
2168 	fs_par->max_rpmb_address = max_rpmb_block << RPMB_BLOCK_SIZE_SHIFT;
2169 
2170 	dump_fat();
2171 
2172 out:
2173 	free(fh);
2174 	free(partition_data);
2175 	return res;
2176 }
2177 
2178 /**
2179  * get_fat_start_address:
2180  * FAT start_address from fs_par.
2181  */
2182 static TEE_Result get_fat_start_address(uint32_t *addr)
2183 {
2184 	if (!fs_par)
2185 		return TEE_ERROR_NO_DATA;
2186 
2187 	*addr = fs_par->fat_start_address;
2188 
2189 	return TEE_SUCCESS;
2190 }
2191 
2192 /**
2193  * read_fat: Read FAT entries
2194  * Return matching FAT entry for read, rm rename and stat.
2195  * Build up memory pool and return matching entry for write operation.
2196  * "Last FAT entry" can be returned during write.
2197  */
2198 static TEE_Result read_fat(struct rpmb_file_handle *fh, tee_mm_pool_t *p)
2199 {
2200 	TEE_Result res = TEE_ERROR_GENERIC;
2201 	tee_mm_entry_t *mm = NULL;
2202 	struct rpmb_fat_entry *fe = NULL;
2203 	uint32_t fat_address;
2204 	bool entry_found = false;
2205 	bool expand_fat = false;
2206 	struct rpmb_file_handle last_fh;
2207 
2208 	DMSG("fat_address %d", fh->rpmb_fat_address);
2209 
2210 	res = fat_entry_dir_init();
2211 	if (res)
2212 		goto out;
2213 
2214 	/*
2215 	 * The pool is used to represent the current RPMB layout. To find
2216 	 * a slot for the file tee_mm_alloc is called on the pool. Thus
2217 	 * if it is not NULL the entire FAT must be traversed to fill in
2218 	 * the pool.
2219 	 */
2220 	while (true) {
2221 		res = fat_entry_dir_get_next(&fe, &fat_address);
2222 		if (res || !fe)
2223 			break;
2224 
2225 		/*
2226 		 * Look for an entry, matching filenames. (read, rm,
2227 		 * rename and stat.). Only store first filename match.
2228 		 */
2229 		if ((!strcmp(fh->filename, fe->filename)) &&
2230 		    (fe->flags & FILE_IS_ACTIVE) && !entry_found) {
2231 			entry_found = true;
2232 			fh->rpmb_fat_address = fat_address;
2233 			memcpy(&fh->fat_entry, fe, sizeof(*fe));
2234 			if (!p)
2235 				break;
2236 		}
2237 
2238 		/* Add existing files to memory pool. (write) */
2239 		if (p) {
2240 			if ((fe->flags & FILE_IS_ACTIVE) && fe->data_size > 0) {
2241 
2242 				mm = tee_mm_alloc2(p, fe->start_address,
2243 						   fe->data_size);
2244 				if (!mm) {
2245 					res = TEE_ERROR_OUT_OF_MEMORY;
2246 					goto out;
2247 				}
2248 			}
2249 
2250 			/* Unused FAT entries can be reused (write) */
2251 			if (((fe->flags & FILE_IS_ACTIVE) == 0) &&
2252 			    fh->rpmb_fat_address == 0) {
2253 				fh->rpmb_fat_address = fat_address;
2254 				memcpy(&fh->fat_entry, fe,
2255 				       sizeof(struct rpmb_fat_entry));
2256 			}
2257 
2258 			if (((fe->flags & FILE_IS_LAST_ENTRY) != 0) &&
2259 			    fh->rpmb_fat_address == fat_address) {
2260 
2261 				/*
2262 				 * If the last entry was reached and was chosen
2263 				 * by the previous check, then the FAT needs to
2264 				 * be expanded.
2265 				 * fh->rpmb_fat_address is the address chosen
2266 				 * to store the files FAT entry and fat_address
2267 				 * is the current FAT entry address being
2268 				 * compared.
2269 				 */
2270 				expand_fat = true;
2271 			}
2272 		}
2273 	}
2274 
2275 	if (res)
2276 		goto out;
2277 	/*
2278 	 * Represent the FAT table in the pool.
2279 	 */
2280 	if (p) {
2281 		/*
2282 		 * Since fat_address is the start of the last entry it needs to
2283 		 * be moved up by an entry.
2284 		 */
2285 		fat_address += sizeof(struct rpmb_fat_entry);
2286 
2287 		/* Make room for yet a FAT entry and add to memory pool. */
2288 		if (expand_fat)
2289 			fat_address += sizeof(struct rpmb_fat_entry);
2290 
2291 		mm = tee_mm_alloc2(p, RPMB_STORAGE_START_ADDRESS, fat_address);
2292 		if (!mm) {
2293 			res = TEE_ERROR_OUT_OF_MEMORY;
2294 			goto out;
2295 		}
2296 
2297 		if (expand_fat) {
2298 			/*
2299 			 * Point fat_address to the beginning of the new
2300 			 * entry.
2301 			 */
2302 			fat_address -= sizeof(struct rpmb_fat_entry);
2303 			memset(&last_fh, 0, sizeof(last_fh));
2304 			last_fh.fat_entry.flags = FILE_IS_LAST_ENTRY;
2305 			last_fh.rpmb_fat_address = fat_address;
2306 			res = write_fat_entry(&last_fh);
2307 			if (res != TEE_SUCCESS)
2308 				goto out;
2309 		}
2310 	}
2311 
2312 	if (!fh->rpmb_fat_address)
2313 		res = TEE_ERROR_ITEM_NOT_FOUND;
2314 
2315 out:
2316 	fat_entry_dir_deinit();
2317 	return res;
2318 }
2319 
2320 static TEE_Result generate_fek(struct rpmb_fat_entry *fe, const TEE_UUID *uuid)
2321 {
2322 	TEE_Result res;
2323 
2324 again:
2325 	res = tee_fs_generate_fek(uuid, fe->fek, sizeof(fe->fek));
2326 	if (res != TEE_SUCCESS)
2327 		return res;
2328 
2329 	if (is_zero(fe->fek, sizeof(fe->fek)))
2330 		goto again;
2331 
2332 	return res;
2333 }
2334 
2335 static TEE_Result rpmb_fs_open_internal(struct rpmb_file_handle *fh,
2336 					const TEE_UUID *uuid, bool create)
2337 {
2338 	tee_mm_pool_t p;
2339 	bool pool_result;
2340 	paddr_size_t pool_sz = 0;
2341 	TEE_Result res = TEE_ERROR_GENERIC;
2342 
2343 	/* We need to do setup in order to make sure fs_par is filled in */
2344 	res = rpmb_fs_setup();
2345 	if (res != TEE_SUCCESS)
2346 		goto out;
2347 
2348 	fh->uuid = uuid;
2349 	if (create) {
2350 		/* Upper memory allocation must be used for RPMB_FS. */
2351 		pool_sz = fs_par->max_rpmb_address - RPMB_STORAGE_START_ADDRESS;
2352 		pool_result = tee_mm_init(&p,
2353 					  RPMB_STORAGE_START_ADDRESS,
2354 					  pool_sz,
2355 					  RPMB_BLOCK_SIZE_SHIFT,
2356 					  TEE_MM_POOL_HI_ALLOC);
2357 
2358 		if (!pool_result) {
2359 			res = TEE_ERROR_OUT_OF_MEMORY;
2360 			goto out;
2361 		}
2362 
2363 		res = read_fat(fh, &p);
2364 		tee_mm_final(&p);
2365 		if (res != TEE_SUCCESS)
2366 			goto out;
2367 	} else {
2368 		res = read_fat(fh, NULL);
2369 		if (res != TEE_SUCCESS)
2370 			goto out;
2371 	}
2372 
2373 	/*
2374 	 * If this is opened with create and the entry found was not active
2375 	 * then this is a new file and the FAT entry must be written
2376 	 */
2377 	if (create) {
2378 		if ((fh->fat_entry.flags & FILE_IS_ACTIVE) == 0) {
2379 			memset(&fh->fat_entry, 0,
2380 				sizeof(struct rpmb_fat_entry));
2381 			memcpy(fh->fat_entry.filename, fh->filename,
2382 				strlen(fh->filename));
2383 			/* Start address and size are 0 */
2384 			fh->fat_entry.flags = FILE_IS_ACTIVE;
2385 
2386 			res = generate_fek(&fh->fat_entry, uuid);
2387 			if (res != TEE_SUCCESS)
2388 				goto out;
2389 			DMSG("GENERATE FEK key: %p",
2390 			     (void *)fh->fat_entry.fek);
2391 			DHEXDUMP(fh->fat_entry.fek, sizeof(fh->fat_entry.fek));
2392 
2393 			res = write_fat_entry(fh);
2394 			if (res != TEE_SUCCESS)
2395 				goto out;
2396 		}
2397 	}
2398 
2399 	res = TEE_SUCCESS;
2400 
2401 out:
2402 	return res;
2403 }
2404 
2405 static void rpmb_fs_close(struct tee_file_handle **tfh)
2406 {
2407 	struct rpmb_file_handle *fh = (struct rpmb_file_handle *)*tfh;
2408 
2409 	free(fh);
2410 	*tfh = NULL;
2411 }
2412 
2413 static TEE_Result rpmb_fs_read(struct tee_file_handle *tfh, size_t pos,
2414 			       void *buf_core, void *buf_user, size_t *len)
2415 {
2416 	TEE_Result res;
2417 	struct rpmb_file_handle *fh = (struct rpmb_file_handle *)tfh;
2418 	size_t size = *len;
2419 
2420 	/* One of buf_core and buf_user must be NULL */
2421 	assert(!buf_core || !buf_user);
2422 
2423 	if (!size)
2424 		return TEE_SUCCESS;
2425 
2426 	mutex_lock(&rpmb_mutex);
2427 
2428 	dump_fh(fh);
2429 
2430 	res = read_fat(fh, NULL);
2431 	if (res != TEE_SUCCESS)
2432 		goto out;
2433 
2434 	if (pos >= fh->fat_entry.data_size) {
2435 		*len = 0;
2436 		goto out;
2437 	}
2438 
2439 	size = MIN(size, fh->fat_entry.data_size - pos);
2440 	if (size) {
2441 		if (buf_core) {
2442 			res = tee_rpmb_read(fh->fat_entry.start_address + pos,
2443 					    buf_core, size, fh->fat_entry.fek,
2444 					    fh->uuid);
2445 			if (res != TEE_SUCCESS)
2446 				goto out;
2447 		} else if (buf_user) {
2448 			uint32_t f = TEE_MEMORY_ACCESS_WRITE;
2449 
2450 			res = check_user_access(f, buf_user, size);
2451 			if (res)
2452 				goto out;
2453 			enter_user_access();
2454 			res = tee_rpmb_read(fh->fat_entry.start_address + pos,
2455 					    buf_user, size, fh->fat_entry.fek,
2456 					    fh->uuid);
2457 			exit_user_access();
2458 			if (res)
2459 				goto out;
2460 		}
2461 	}
2462 	*len = size;
2463 
2464 out:
2465 	mutex_unlock(&rpmb_mutex);
2466 	return res;
2467 }
2468 
2469 static TEE_Result update_write_helper(struct rpmb_file_handle *fh,
2470 				      size_t pos, const void *buf,
2471 				      size_t size, uintptr_t new_fat,
2472 				      size_t new_size)
2473 {
2474 	uintptr_t old_fat = fh->fat_entry.start_address;
2475 	size_t old_size = fh->fat_entry.data_size;
2476 	const uint8_t *rem_buf = buf;
2477 	size_t rem_size = size;
2478 	uint8_t *blk_buf = NULL;
2479 	size_t blk_offset = 0;
2480 	size_t blk_size = 0;
2481 	TEE_Result res = TEE_SUCCESS;
2482 
2483 	blk_buf = mempool_alloc(mempool_default, TMP_BLOCK_SIZE);
2484 	if (!blk_buf)
2485 		return TEE_ERROR_OUT_OF_MEMORY;
2486 
2487 	while (blk_offset < new_size) {
2488 		uint8_t *copy_dst = blk_buf;
2489 		size_t copy_size = 0;
2490 		size_t rd_size = 0;
2491 
2492 		blk_size = MIN(TMP_BLOCK_SIZE, new_size - blk_offset);
2493 		memset(blk_buf, 0, blk_size);
2494 
2495 		/* Possibly read old RPMB data in temporary buffer */
2496 		if (blk_offset < pos && blk_offset < old_size) {
2497 			rd_size = MIN(blk_size, old_size - blk_offset);
2498 
2499 			res = tee_rpmb_read(old_fat + blk_offset, blk_buf,
2500 					    rd_size, fh->fat_entry.fek,
2501 					    fh->uuid);
2502 			if (res != TEE_SUCCESS)
2503 				break;
2504 		}
2505 
2506 		/* Possibly update data in temporary buffer */
2507 		if ((blk_offset + TMP_BLOCK_SIZE > pos) &&
2508 		    (blk_offset < pos + size)) {
2509 			size_t offset = 0;
2510 
2511 			copy_dst = blk_buf;
2512 			copy_size = TMP_BLOCK_SIZE;
2513 
2514 			if (blk_offset < pos) {
2515 				offset = pos - blk_offset;
2516 
2517 				copy_dst += offset;
2518 				copy_size -= offset;
2519 			}
2520 			copy_size = MIN(copy_size, rem_size);
2521 
2522 			memcpy(copy_dst, rem_buf, copy_size);
2523 			rem_buf += copy_size;
2524 			rem_size -= copy_size;
2525 		}
2526 
2527 		/* Write temporary buffer to new RPMB destination */
2528 		res = tee_rpmb_write(new_fat + blk_offset, blk_buf, blk_size,
2529 				     fh->fat_entry.fek, fh->uuid);
2530 		if (res != TEE_SUCCESS)
2531 			break;
2532 
2533 		blk_offset += blk_size;
2534 	}
2535 
2536 	mempool_free(mempool_default, blk_buf);
2537 
2538 	return res;
2539 }
2540 
2541 static TEE_Result rpmb_fs_write_primitive(struct rpmb_file_handle *fh,
2542 					  size_t pos, const void *buf,
2543 					  size_t size)
2544 {
2545 	TEE_Result res = TEE_ERROR_GENERIC;
2546 	tee_mm_pool_t p = { };
2547 	bool pool_result = false;
2548 	size_t end = 0;
2549 	uint32_t start_addr = 0;
2550 	paddr_size_t pool_sz = 0;
2551 
2552 	if (!size)
2553 		return TEE_SUCCESS;
2554 
2555 	if (!fs_par) {
2556 		res = TEE_ERROR_GENERIC;
2557 		goto out;
2558 	}
2559 
2560 	dump_fh(fh);
2561 
2562 	/* Upper memory allocation must be used for RPMB_FS. */
2563 	pool_sz = fs_par->max_rpmb_address - RPMB_STORAGE_START_ADDRESS;
2564 	pool_result = tee_mm_init(&p,
2565 				  RPMB_STORAGE_START_ADDRESS,
2566 				  pool_sz,
2567 				  RPMB_BLOCK_SIZE_SHIFT,
2568 				  TEE_MM_POOL_HI_ALLOC);
2569 	if (!pool_result) {
2570 		res = TEE_ERROR_OUT_OF_MEMORY;
2571 		goto out;
2572 	}
2573 
2574 	res = read_fat(fh, &p);
2575 	if (res != TEE_SUCCESS)
2576 		goto out;
2577 
2578 	if (fh->fat_entry.flags & FILE_IS_LAST_ENTRY)
2579 		panic("invalid last entry flag");
2580 
2581 	if (ADD_OVERFLOW(pos, size, &end)) {
2582 		res = TEE_ERROR_BAD_PARAMETERS;
2583 		goto out;
2584 	}
2585 	if (ADD_OVERFLOW(fh->fat_entry.start_address, pos, &start_addr)) {
2586 		res = TEE_ERROR_BAD_PARAMETERS;
2587 		goto out;
2588 	}
2589 
2590 	if (end <= fh->fat_entry.data_size &&
2591 	    tee_rpmb_write_is_atomic(start_addr, size)) {
2592 
2593 		DMSG("Updating data in-place");
2594 		res = tee_rpmb_write(start_addr, buf,
2595 				     size, fh->fat_entry.fek, fh->uuid);
2596 	} else {
2597 		/*
2598 		 * File must be extended, or update cannot be atomic: allocate,
2599 		 * read, update, write.
2600 		 */
2601 		size_t new_size = MAX(end, fh->fat_entry.data_size);
2602 		tee_mm_entry_t *mm = tee_mm_alloc(&p, new_size);
2603 		uintptr_t new_fat_entry = 0;
2604 
2605 		DMSG("Need to re-allocate");
2606 		if (!mm) {
2607 			DMSG("RPMB: No space left");
2608 			res = TEE_ERROR_STORAGE_NO_SPACE;
2609 			goto out;
2610 		}
2611 
2612 		new_fat_entry = tee_mm_get_smem(mm);
2613 
2614 		res = update_write_helper(fh, pos, buf, size,
2615 					  new_fat_entry, new_size);
2616 		if (res == TEE_SUCCESS) {
2617 			fh->fat_entry.data_size = new_size;
2618 			fh->fat_entry.start_address = new_fat_entry;
2619 
2620 			res = write_fat_entry(fh);
2621 		}
2622 	}
2623 
2624 out:
2625 	if (pool_result)
2626 		tee_mm_final(&p);
2627 
2628 	return res;
2629 }
2630 
2631 static TEE_Result rpmb_fs_write(struct tee_file_handle *tfh, size_t pos,
2632 				const void *buf_core, const void *buf_user,
2633 				size_t size)
2634 {
2635 	TEE_Result res = TEE_SUCCESS;
2636 
2637 	/* One of buf_core and buf_user must be NULL */
2638 	assert(!buf_core || !buf_user);
2639 
2640 	if (!size)
2641 		return TEE_SUCCESS;
2642 
2643 	mutex_lock(&rpmb_mutex);
2644 	if (buf_core) {
2645 		res = rpmb_fs_write_primitive((struct rpmb_file_handle *)tfh,
2646 					      pos, buf_core, size);
2647 	} else if (buf_user) {
2648 		uint32_t f = TEE_MEMORY_ACCESS_READ;
2649 
2650 		res = check_user_access(f, buf_user, size);
2651 		if (res)
2652 			goto out;
2653 		enter_user_access();
2654 		res = rpmb_fs_write_primitive((struct rpmb_file_handle *)tfh,
2655 					      pos, buf_user, size);
2656 		exit_user_access();
2657 	}
2658 out:
2659 	mutex_unlock(&rpmb_mutex);
2660 
2661 	return res;
2662 }
2663 
2664 static TEE_Result rpmb_fs_remove_internal(struct rpmb_file_handle *fh)
2665 {
2666 	TEE_Result res;
2667 
2668 	res = read_fat(fh, NULL);
2669 	if (res)
2670 		return res;
2671 
2672 	/* Clear this file entry. */
2673 	memset(&fh->fat_entry, 0, sizeof(struct rpmb_fat_entry));
2674 	return write_fat_entry(fh);
2675 }
2676 
2677 static TEE_Result rpmb_fs_remove(struct tee_pobj *po)
2678 {
2679 	TEE_Result res;
2680 	struct rpmb_file_handle *fh = alloc_file_handle(po, po->temporary);
2681 
2682 	if (!fh)
2683 		return TEE_ERROR_OUT_OF_MEMORY;
2684 
2685 	mutex_lock(&rpmb_mutex);
2686 
2687 	res = rpmb_fs_remove_internal(fh);
2688 
2689 	mutex_unlock(&rpmb_mutex);
2690 
2691 	free(fh);
2692 	return res;
2693 }
2694 
2695 static  TEE_Result rpmb_fs_rename_internal(struct tee_pobj *old,
2696 					   struct tee_pobj *new,
2697 					   bool overwrite)
2698 {
2699 	TEE_Result res = TEE_ERROR_GENERIC;
2700 	struct rpmb_file_handle *fh_old = NULL;
2701 	struct rpmb_file_handle *fh_new = NULL;
2702 
2703 	if (!old) {
2704 		res = TEE_ERROR_BAD_PARAMETERS;
2705 		goto out;
2706 	}
2707 
2708 	if (new)
2709 		fh_old = alloc_file_handle(old, old->temporary);
2710 	else
2711 		fh_old = alloc_file_handle(old, true);
2712 	if (!fh_old) {
2713 		res = TEE_ERROR_OUT_OF_MEMORY;
2714 		goto out;
2715 	}
2716 
2717 	if (new)
2718 		fh_new = alloc_file_handle(new, new->temporary);
2719 	else
2720 		fh_new = alloc_file_handle(old, false);
2721 	if (!fh_new) {
2722 		res = TEE_ERROR_OUT_OF_MEMORY;
2723 		goto out;
2724 	}
2725 
2726 	res = read_fat(fh_old, NULL);
2727 	if (res != TEE_SUCCESS)
2728 		goto out;
2729 
2730 	res = read_fat(fh_new, NULL);
2731 	if (res == TEE_SUCCESS) {
2732 		if (!overwrite) {
2733 			res = TEE_ERROR_ACCESS_CONFLICT;
2734 			goto out;
2735 		}
2736 
2737 		/* Clear this file entry. */
2738 		memset(&fh_new->fat_entry, 0, sizeof(struct rpmb_fat_entry));
2739 		res = write_fat_entry(fh_new);
2740 		if (res != TEE_SUCCESS)
2741 			goto out;
2742 	}
2743 
2744 	memset(fh_old->fat_entry.filename, 0, TEE_RPMB_FS_FILENAME_LENGTH);
2745 	memcpy(fh_old->fat_entry.filename, fh_new->filename,
2746 	       strlen(fh_new->filename));
2747 
2748 	res = write_fat_entry(fh_old);
2749 
2750 out:
2751 	free(fh_old);
2752 	free(fh_new);
2753 
2754 	return res;
2755 }
2756 
2757 static  TEE_Result rpmb_fs_rename(struct tee_pobj *old, struct tee_pobj *new,
2758 				  bool overwrite)
2759 {
2760 	TEE_Result res;
2761 
2762 	mutex_lock(&rpmb_mutex);
2763 	res = rpmb_fs_rename_internal(old, new, overwrite);
2764 	mutex_unlock(&rpmb_mutex);
2765 
2766 	return res;
2767 }
2768 
2769 static TEE_Result rpmb_fs_truncate(struct tee_file_handle *tfh, size_t length)
2770 {
2771 	struct rpmb_file_handle *fh = (struct rpmb_file_handle *)tfh;
2772 	tee_mm_pool_t p;
2773 	bool pool_result = false;
2774 	tee_mm_entry_t *mm;
2775 	uint32_t newsize;
2776 	uint8_t *newbuf = NULL;
2777 	uintptr_t newaddr;
2778 	TEE_Result res = TEE_ERROR_GENERIC;
2779 	paddr_size_t pool_sz = 0;
2780 
2781 	mutex_lock(&rpmb_mutex);
2782 
2783 	if (length > INT32_MAX) {
2784 		res = TEE_ERROR_BAD_PARAMETERS;
2785 		goto out;
2786 	}
2787 	newsize = length;
2788 
2789 	res = read_fat(fh, NULL);
2790 	if (res != TEE_SUCCESS)
2791 		goto out;
2792 
2793 	if (newsize > fh->fat_entry.data_size) {
2794 		/* Extend file */
2795 
2796 		pool_sz = fs_par->max_rpmb_address - RPMB_STORAGE_START_ADDRESS;
2797 		pool_result = tee_mm_init(&p,
2798 					  RPMB_STORAGE_START_ADDRESS,
2799 					  pool_sz,
2800 					  RPMB_BLOCK_SIZE_SHIFT,
2801 					  TEE_MM_POOL_HI_ALLOC);
2802 		if (!pool_result) {
2803 			res = TEE_ERROR_OUT_OF_MEMORY;
2804 			goto out;
2805 		}
2806 		res = read_fat(fh, &p);
2807 		if (res != TEE_SUCCESS)
2808 			goto out;
2809 
2810 		mm = tee_mm_alloc(&p, newsize);
2811 		newbuf = calloc(1, newsize);
2812 		if (!mm || !newbuf) {
2813 			res = TEE_ERROR_OUT_OF_MEMORY;
2814 			goto out;
2815 		}
2816 
2817 		if (fh->fat_entry.data_size) {
2818 			res = tee_rpmb_read(fh->fat_entry.start_address,
2819 					    newbuf, fh->fat_entry.data_size,
2820 					    fh->fat_entry.fek, fh->uuid);
2821 			if (res != TEE_SUCCESS)
2822 				goto out;
2823 		}
2824 
2825 		newaddr = tee_mm_get_smem(mm);
2826 		res = tee_rpmb_write(newaddr, newbuf,
2827 				     newsize, fh->fat_entry.fek, fh->uuid);
2828 		if (res != TEE_SUCCESS)
2829 			goto out;
2830 
2831 	} else {
2832 		/* Don't change file location */
2833 		newaddr = fh->fat_entry.start_address;
2834 	}
2835 
2836 	/* fh->pos is unchanged */
2837 	fh->fat_entry.data_size = newsize;
2838 	fh->fat_entry.start_address = newaddr;
2839 	res = write_fat_entry(fh);
2840 
2841 out:
2842 	mutex_unlock(&rpmb_mutex);
2843 	if (pool_result)
2844 		tee_mm_final(&p);
2845 	if (newbuf)
2846 		free(newbuf);
2847 
2848 	return res;
2849 }
2850 
2851 static void rpmb_fs_dir_free(struct tee_fs_dir *dir)
2852 {
2853 	struct tee_rpmb_fs_dirent *e;
2854 
2855 	if (!dir)
2856 		return;
2857 
2858 	free(dir->current);
2859 
2860 	while ((e = SIMPLEQ_FIRST(&dir->next))) {
2861 		SIMPLEQ_REMOVE_HEAD(&dir->next, link);
2862 		free(e);
2863 	}
2864 }
2865 
2866 static TEE_Result rpmb_fs_dir_populate(const char *path,
2867 				       struct tee_fs_dir *dir)
2868 {
2869 	struct tee_rpmb_fs_dirent *current = NULL;
2870 	struct rpmb_fat_entry *fe = NULL;
2871 	uint32_t fat_address;
2872 	uint32_t filelen;
2873 	char *filename;
2874 	bool matched;
2875 	struct tee_rpmb_fs_dirent *next = NULL;
2876 	uint32_t pathlen;
2877 	TEE_Result res = TEE_ERROR_GENERIC;
2878 	char temp;
2879 
2880 	mutex_lock(&rpmb_mutex);
2881 
2882 	res = fat_entry_dir_init();
2883 	if (res)
2884 		goto out;
2885 
2886 	pathlen = strlen(path);
2887 
2888 	while (true) {
2889 		res = fat_entry_dir_get_next(&fe, &fat_address);
2890 		if (res || !fe)
2891 			break;
2892 
2893 		filename = fe->filename;
2894 		if (fe->flags & FILE_IS_ACTIVE) {
2895 			matched = false;
2896 			filelen = strlen(filename);
2897 			if (filelen > pathlen) {
2898 				temp = filename[pathlen];
2899 				filename[pathlen] = '\0';
2900 				if (strcmp(filename, path) == 0)
2901 					matched = true;
2902 
2903 				filename[pathlen] = temp;
2904 			}
2905 
2906 			if (matched) {
2907 				next = malloc(sizeof(*next));
2908 				if (!next) {
2909 					res = TEE_ERROR_OUT_OF_MEMORY;
2910 					goto out;
2911 				}
2912 
2913 				next->entry.oidlen = tee_hs2b((uint8_t *)
2914 						&filename[pathlen],
2915 						next->entry.oid,
2916 						filelen - pathlen,
2917 						sizeof(next->entry.oid));
2918 				if (next->entry.oidlen) {
2919 					SIMPLEQ_INSERT_TAIL(&dir->next,
2920 							    next, link);
2921 					current = next;
2922 				} else {
2923 					free(next);
2924 					next = NULL;
2925 				}
2926 			}
2927 		}
2928 	}
2929 
2930 	if (res)
2931 		goto out;
2932 
2933 	if (current)
2934 		res = TEE_SUCCESS;
2935 	else
2936 		res = TEE_ERROR_ITEM_NOT_FOUND; /* No directories were found. */
2937 
2938 out:
2939 	mutex_unlock(&rpmb_mutex);
2940 	fat_entry_dir_deinit();
2941 	if (res)
2942 		rpmb_fs_dir_free(dir);
2943 
2944 	return res;
2945 }
2946 
2947 static TEE_Result rpmb_fs_opendir(const TEE_UUID *uuid, struct tee_fs_dir **dir)
2948 {
2949 	uint32_t len;
2950 	char path_local[TEE_RPMB_FS_FILENAME_LENGTH];
2951 	TEE_Result res = TEE_ERROR_GENERIC;
2952 	struct tee_fs_dir *rpmb_dir = NULL;
2953 
2954 	if (!uuid || !dir) {
2955 		res = TEE_ERROR_BAD_PARAMETERS;
2956 		goto out;
2957 	}
2958 
2959 	memset(path_local, 0, sizeof(path_local));
2960 	if (create_dirname(path_local, sizeof(path_local) - 1, uuid)) {
2961 		res = TEE_ERROR_BAD_PARAMETERS;
2962 		goto out;
2963 	}
2964 	len = strlen(path_local);
2965 
2966 	/* Add a slash to correctly match the full directory name. */
2967 	if (path_local[len - 1] != '/')
2968 		path_local[len] = '/';
2969 
2970 	rpmb_dir = calloc(1, sizeof(*rpmb_dir));
2971 	if (!rpmb_dir) {
2972 		res = TEE_ERROR_OUT_OF_MEMORY;
2973 		goto out;
2974 	}
2975 	SIMPLEQ_INIT(&rpmb_dir->next);
2976 
2977 	res = rpmb_fs_dir_populate(path_local, rpmb_dir);
2978 	if (res != TEE_SUCCESS) {
2979 		free(rpmb_dir);
2980 		rpmb_dir = NULL;
2981 		goto out;
2982 	}
2983 
2984 	*dir = rpmb_dir;
2985 
2986 out:
2987 	return res;
2988 }
2989 
2990 static TEE_Result rpmb_fs_readdir(struct tee_fs_dir *dir,
2991 				  struct tee_fs_dirent **ent)
2992 {
2993 	if (!dir)
2994 		return TEE_ERROR_GENERIC;
2995 
2996 	free(dir->current);
2997 
2998 	dir->current = SIMPLEQ_FIRST(&dir->next);
2999 	if (!dir->current)
3000 		return TEE_ERROR_ITEM_NOT_FOUND;
3001 
3002 	SIMPLEQ_REMOVE_HEAD(&dir->next, link);
3003 
3004 	*ent = &dir->current->entry;
3005 	return TEE_SUCCESS;
3006 }
3007 
3008 static void rpmb_fs_closedir(struct tee_fs_dir *dir)
3009 {
3010 	if (dir) {
3011 		rpmb_fs_dir_free(dir);
3012 		free(dir);
3013 	}
3014 }
3015 
3016 static TEE_Result rpmb_fs_open(struct tee_pobj *po, size_t *size,
3017 			       struct tee_file_handle **ret_fh)
3018 {
3019 	TEE_Result res;
3020 	struct rpmb_file_handle *fh = alloc_file_handle(po, po->temporary);
3021 
3022 	if (!fh)
3023 		return TEE_ERROR_OUT_OF_MEMORY;
3024 
3025 	mutex_lock(&rpmb_mutex);
3026 
3027 	res = rpmb_fs_open_internal(fh, &po->uuid, false);
3028 	if (!res && size)
3029 		*size = fh->fat_entry.data_size;
3030 
3031 	mutex_unlock(&rpmb_mutex);
3032 
3033 	if (res)
3034 		free(fh);
3035 	else
3036 		*ret_fh = (struct tee_file_handle *)fh;
3037 
3038 	return res;
3039 }
3040 
3041 static TEE_Result rpmb_fs_create(struct tee_pobj *po, bool overwrite,
3042 				 const void *head, size_t head_size,
3043 				 const void *attr, size_t attr_size,
3044 				 const void *data_core, const void *data_user,
3045 				 size_t data_size,
3046 				 struct tee_file_handle **ret_fh)
3047 {
3048 	TEE_Result res;
3049 	size_t pos = 0;
3050 	struct rpmb_file_handle *fh = alloc_file_handle(po, po->temporary);
3051 
3052 	/* One of data_core and data_user must be NULL */
3053 	assert(!data_core || !data_user);
3054 
3055 	if (!fh)
3056 		return TEE_ERROR_OUT_OF_MEMORY;
3057 
3058 	mutex_lock(&rpmb_mutex);
3059 	res = rpmb_fs_open_internal(fh, &po->uuid, true);
3060 	if (res)
3061 		goto out;
3062 
3063 	if (head && head_size) {
3064 		res = rpmb_fs_write_primitive(fh, pos, head, head_size);
3065 		if (res)
3066 			goto out;
3067 		pos += head_size;
3068 	}
3069 
3070 	if (attr && attr_size) {
3071 		res = rpmb_fs_write_primitive(fh, pos, attr, attr_size);
3072 		if (res)
3073 			goto out;
3074 		pos += attr_size;
3075 	}
3076 
3077 	if (data_size) {
3078 		if (data_core) {
3079 			res = rpmb_fs_write_primitive(fh, pos, data_core,
3080 						      data_size);
3081 			if (res)
3082 				goto out;
3083 		} else if (data_user) {
3084 			uint32_t f = TEE_MEMORY_ACCESS_READ |
3085 				     TEE_MEMORY_ACCESS_ANY_OWNER;
3086 
3087 			res = check_user_access(f, data_user, data_size);
3088 			if (res)
3089 				goto out;
3090 			enter_user_access();
3091 			res = rpmb_fs_write_primitive(fh, pos, data_user,
3092 						      data_size);
3093 			exit_user_access();
3094 			if (res)
3095 				goto out;
3096 		}
3097 	}
3098 
3099 	if (po->temporary) {
3100 		/*
3101 		 * If it's a temporary filename (which it normally is)
3102 		 * rename into the final filename now that the file is
3103 		 * fully initialized.
3104 		 */
3105 		po->temporary = false;
3106 		res = rpmb_fs_rename_internal(po, NULL, overwrite);
3107 		if (res) {
3108 			po->temporary = true;
3109 			goto out;
3110 		}
3111 		/* Update file handle after rename. */
3112 		create_filename(fh->filename, sizeof(fh->filename), po, false);
3113 	}
3114 
3115 out:
3116 	if (res) {
3117 		rpmb_fs_remove_internal(fh);
3118 		free(fh);
3119 	} else {
3120 		*ret_fh = (struct tee_file_handle *)fh;
3121 	}
3122 	mutex_unlock(&rpmb_mutex);
3123 
3124 	return res;
3125 }
3126 
3127 const struct tee_file_operations rpmb_fs_ops = {
3128 	.open = rpmb_fs_open,
3129 	.create = rpmb_fs_create,
3130 	.close = rpmb_fs_close,
3131 	.read = rpmb_fs_read,
3132 	.write = rpmb_fs_write,
3133 	.truncate = rpmb_fs_truncate,
3134 	.rename = rpmb_fs_rename,
3135 	.remove = rpmb_fs_remove,
3136 	.opendir = rpmb_fs_opendir,
3137 	.closedir = rpmb_fs_closedir,
3138 	.readdir = rpmb_fs_readdir,
3139 };
3140 
3141 TEE_Result tee_rpmb_fs_raw_open(const char *fname, bool create,
3142 				struct tee_file_handle **ret_fh)
3143 {
3144 	TEE_Result res;
3145 	struct rpmb_file_handle *fh = calloc(1, sizeof(*fh));
3146 	static const TEE_UUID uuid = { 0 };
3147 
3148 	if (!fh)
3149 		return TEE_ERROR_OUT_OF_MEMORY;
3150 
3151 	snprintf(fh->filename, sizeof(fh->filename), "/%s", fname);
3152 
3153 	mutex_lock(&rpmb_mutex);
3154 
3155 	res = rpmb_fs_open_internal(fh, &uuid, create);
3156 
3157 	mutex_unlock(&rpmb_mutex);
3158 
3159 	if (res) {
3160 		if (create)
3161 			rpmb_fs_remove_internal(fh);
3162 		free(fh);
3163 	} else {
3164 		*ret_fh = (struct tee_file_handle *)fh;
3165 	}
3166 
3167 	return res;
3168 }
3169 
3170 bool __weak plat_rpmb_key_is_ready(void)
3171 {
3172 	return true;
3173 }
3174