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