1 /*
2 * Copyright (C) 2015-2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "block_device_tipc.h"
18
19 #include <errno.h>
20 #include <inttypes.h>
21 #include <stdint.h>
22 #include <string.h>
23
24 #include <lib/system_state/system_state.h>
25 #include <lib/tipc/tipc.h>
26 #include <lk/compiler.h>
27 #include <trusty_ipc.h>
28 #include <uapi/err.h>
29
30 #include <interface/storage/storage.h>
31
32 #include <openssl/mem.h>
33 #include <openssl/rand.h>
34
35 #include "aidl_service.h"
36 #include "block_cache.h"
37 #include "client_tipc.h"
38 #include "fs.h"
39 #include "ipc.h"
40 #include "rpmb.h"
41 #include "tipc_ns.h"
42
43 #ifdef APP_STORAGE_RPMB_BLOCK_SIZE
44 #define BLOCK_SIZE_RPMB (APP_STORAGE_RPMB_BLOCK_SIZE)
45 #else
46 #define BLOCK_SIZE_RPMB (512)
47 #endif
48 #ifdef APP_STORAGE_RPMB_BLOCK_COUNT
49 #define BLOCK_COUNT_RPMB (APP_STORAGE_RPMB_BLOCK_COUNT)
50 #else
51 #define BLOCK_COUNT_RPMB (0) /* Auto detect */
52 #endif
53 #ifdef APP_STORAGE_MAIN_BLOCK_SIZE
54 #define BLOCK_SIZE_MAIN (APP_STORAGE_MAIN_BLOCK_SIZE)
55 #else
56 #define BLOCK_SIZE_MAIN (2048)
57 #endif
58
59 /*
60 * This is here in case we're using an old storageproxyd that does not have
61 * support for STORAGE_FILE_GET_MAX_SIZE
62 */
63 #ifdef APP_STORAGE_MAIN_BLOCK_COUNT
64 #define BLOCK_COUNT_MAIN (APP_STORAGE_MAIN_BLOCK_COUNT)
65 #else
66 #define BLOCK_COUNT_MAIN (0x10000000000 / BLOCK_SIZE_MAIN)
67 #endif
68
69 #define BLOCK_SIZE_RPMB_BLOCKS (BLOCK_SIZE_RPMB / RPMB_BUF_SIZE)
70
71 STATIC_ASSERT(BLOCK_SIZE_RPMB_BLOCKS == 1 || BLOCK_SIZE_RPMB_BLOCKS == 2);
72 STATIC_ASSERT((BLOCK_SIZE_RPMB_BLOCKS * RPMB_BUF_SIZE) == BLOCK_SIZE_RPMB);
73
74 STATIC_ASSERT(BLOCK_COUNT_RPMB == 0 || BLOCK_COUNT_RPMB >= 8);
75
76 STATIC_ASSERT(BLOCK_SIZE_MAIN >= 256);
77 STATIC_ASSERT(BLOCK_COUNT_MAIN >= 8);
78 STATIC_ASSERT(BLOCK_SIZE_MAIN >= BLOCK_SIZE_RPMB);
79
80 /* Ensure that we can fit a superblock + backup in an RPMB block */
81 STATIC_ASSERT(BLOCK_SIZE_RPMB >= 256);
82
83 #define SS_ERR(args...) fprintf(stderr, "ss: " args)
84 #define SS_WARN(args...) fprintf(stderr, "ss: " args)
85
86 #ifdef SS_DATA_DEBUG_IO
87 #define SS_DBG_IO(args...) fprintf(stdout, "ss: " args)
88 #else
89 #define SS_DBG_IO(args...) \
90 do { \
91 } while (0)
92 #endif
93
94 const char file_system_id_td[] = "td";
95 const char file_system_id_tdea[] = "tdea";
96 const char file_system_id_tdp[] = "tdp";
97 const char file_system_id_tp[] = "tp";
98 const char file_system_id_nsp[] = "nsp";
99
100 struct rpmb_key_derivation_in {
101 uint8_t prefix[sizeof(struct key)];
102 uint8_t block_data[RPMB_BUF_SIZE];
103 };
104
105 struct rpmb_key_derivation_out {
106 struct rpmb_key rpmb_key;
107 uint8_t unused[sizeof(struct key)];
108 };
109
rpmb_check(struct block_device_tipc * state,uint16_t block)110 static int rpmb_check(struct block_device_tipc* state, uint16_t block) {
111 int ret;
112 uint8_t tmp[RPMB_BUF_SIZE];
113 ret = rpmb_read(state->rpmb_state, tmp, block, 1);
114 SS_DBG_IO("%s: check rpmb_block %d, ret %d\n", __func__, block, ret);
115 return ret;
116 }
117
rpmb_search_size(struct block_device_tipc * state,uint16_t hint)118 static uint32_t rpmb_search_size(struct block_device_tipc* state,
119 uint16_t hint) {
120 int ret;
121 uint32_t low = 0;
122 uint16_t high = UINT16_MAX;
123 uint16_t curr = hint ? hint - 1 : UINT16_MAX;
124
125 while (low <= high) {
126 ret = rpmb_check(state, curr);
127 switch (ret) {
128 case 0:
129 low = curr + 1;
130 break;
131 case -ENOENT:
132 high = curr - 1;
133 break;
134 default:
135 return 0;
136 };
137 if (ret || curr != hint) {
138 curr = (low + high) / 2;
139 hint = curr;
140 } else {
141 curr = curr + 1;
142 }
143 }
144 assert((uint32_t)high + 1 == low);
145 return low;
146 }
147
dev_rpmb_to_state(struct block_device * dev)148 static struct block_device_rpmb* dev_rpmb_to_state(struct block_device* dev) {
149 assert(dev);
150 return containerof(dev, struct block_device_rpmb, dev);
151 }
152
block_device_tipc_rpmb_start_read(struct block_device * dev,data_block_t block)153 static void block_device_tipc_rpmb_start_read(struct block_device* dev,
154 data_block_t block) {
155 int ret;
156 uint8_t tmp[BLOCK_SIZE_RPMB]; /* TODO: pass data in? */
157 uint16_t rpmb_block;
158 struct block_device_rpmb* dev_rpmb = dev_rpmb_to_state(dev);
159
160 assert(block < dev->block_count);
161 rpmb_block = block + dev_rpmb->base;
162
163 ret = rpmb_read(dev_rpmb->state->rpmb_state, tmp,
164 rpmb_block * BLOCK_SIZE_RPMB_BLOCKS,
165 BLOCK_SIZE_RPMB_BLOCKS);
166
167 SS_DBG_IO("%s: block %" PRIu64 ", base %d, rpmb_block %d, ret %d\n",
168 __func__, block, dev_rpmb->base, rpmb_block, ret);
169
170 block_cache_complete_read(dev, block, tmp, BLOCK_SIZE_RPMB,
171 ret ? BLOCK_READ_IO_ERROR : BLOCK_READ_SUCCESS);
172 }
173
translate_write_error(int rc)174 static inline enum block_write_error translate_write_error(int rc) {
175 switch (rc) {
176 case 0:
177 return BLOCK_WRITE_SUCCESS;
178 case -EUCLEAN:
179 return BLOCK_WRITE_FAILED_UNKNOWN_STATE;
180 case ERR_IO:
181 return BLOCK_WRITE_SYNC_FAILED;
182 default:
183 return BLOCK_WRITE_FAILED;
184 }
185 }
186
block_device_tipc_rpmb_start_write(struct block_device * dev,data_block_t block,const void * data,size_t data_size,bool sync)187 static void block_device_tipc_rpmb_start_write(struct block_device* dev,
188 data_block_t block,
189 const void* data,
190 size_t data_size,
191 bool sync) {
192 int ret;
193 uint16_t rpmb_block;
194 struct block_device_rpmb* dev_rpmb = dev_rpmb_to_state(dev);
195
196 /* We currently sync every rpmb write. TODO: can we avoid this? */
197 (void)sync;
198
199 assert(data_size == BLOCK_SIZE_RPMB);
200 assert(block < dev->block_count);
201
202 rpmb_block = block + dev_rpmb->base;
203
204 ret = rpmb_write(dev_rpmb->state->rpmb_state, data,
205 rpmb_block * BLOCK_SIZE_RPMB_BLOCKS,
206 BLOCK_SIZE_RPMB_BLOCKS, true, dev_rpmb->is_userdata);
207
208 SS_DBG_IO("%s: block %" PRIu64 ", base %d, rpmb_block %d, ret %d\n",
209 __func__, block, dev_rpmb->base, rpmb_block, ret);
210
211 block_cache_complete_write(dev, block, translate_write_error(ret));
212 }
213
block_device_tipc_rpmb_wait_for_io(struct block_device * dev)214 static void block_device_tipc_rpmb_wait_for_io(struct block_device* dev) {
215 assert(0); /* TODO: use async read/write */
216 }
217
to_block_device_ns(struct block_device * dev)218 static struct block_device_ns* to_block_device_ns(struct block_device* dev) {
219 assert(dev);
220 return containerof(dev, struct block_device_ns, dev);
221 }
222
block_device_tipc_ns_start_read(struct block_device * dev,data_block_t block)223 static void block_device_tipc_ns_start_read(struct block_device* dev,
224 data_block_t block) {
225 int ret;
226 enum block_read_error res;
227 uint8_t tmp[BLOCK_SIZE_MAIN]; /* TODO: pass data in? */
228 struct block_device_ns* dev_ns = to_block_device_ns(dev);
229
230 ret = ns_read_pos(dev_ns->state->ipc_handle, dev_ns->ns_handle,
231 block * BLOCK_SIZE_MAIN, tmp, BLOCK_SIZE_MAIN);
232 SS_DBG_IO("%s: block %" PRIu64 ", ret %d\n", __func__, block, ret);
233 if (ret == 0) {
234 res = BLOCK_READ_NO_DATA;
235 } else if (ret == BLOCK_SIZE_MAIN) {
236 res = BLOCK_READ_SUCCESS;
237 } else {
238 res = BLOCK_READ_IO_ERROR;
239 }
240 block_cache_complete_read(dev, block, tmp, BLOCK_SIZE_MAIN, res);
241 }
242
block_device_tipc_ns_start_write(struct block_device * dev,data_block_t block,const void * data,size_t data_size,bool sync)243 static void block_device_tipc_ns_start_write(struct block_device* dev,
244 data_block_t block,
245 const void* data,
246 size_t data_size,
247 bool sync) {
248 int ret;
249 enum block_write_error res = BLOCK_WRITE_FAILED;
250 struct block_device_ns* dev_ns = to_block_device_ns(dev);
251
252 assert(data_size == BLOCK_SIZE_MAIN);
253
254 ret = ns_write_pos(dev_ns->state->ipc_handle, dev_ns->ns_handle,
255 block * BLOCK_SIZE_MAIN, data, data_size,
256 dev_ns->is_userdata, sync);
257 SS_DBG_IO("%s: block %" PRIu64 ", ret %d\n", __func__, block, ret);
258 if (ret == BLOCK_SIZE_MAIN) {
259 res = BLOCK_WRITE_SUCCESS;
260 } else if (ret < 0) {
261 res = translate_write_error(ret);
262 }
263 block_cache_complete_write(dev, block, res);
264 }
265
block_device_tipc_ns_wait_for_io(struct block_device * dev)266 static void block_device_tipc_ns_wait_for_io(struct block_device* dev) {
267 assert(0); /* TODO: use async read/write */
268 }
269
block_device_tipc_init_dev_rpmb(struct block_device_rpmb * dev_rpmb,struct block_device_tipc * state,uint16_t base,uint32_t block_count,bool is_userdata)270 static void block_device_tipc_init_dev_rpmb(struct block_device_rpmb* dev_rpmb,
271 struct block_device_tipc* state,
272 uint16_t base,
273 uint32_t block_count,
274 bool is_userdata) {
275 dev_rpmb->dev.start_read = block_device_tipc_rpmb_start_read;
276 dev_rpmb->dev.start_write = block_device_tipc_rpmb_start_write;
277 dev_rpmb->dev.wait_for_io = block_device_tipc_rpmb_wait_for_io;
278 dev_rpmb->dev.block_count = block_count;
279 dev_rpmb->dev.block_size = BLOCK_SIZE_RPMB;
280 dev_rpmb->dev.block_num_size = 2;
281 dev_rpmb->dev.mac_size = 2;
282 dev_rpmb->dev.tamper_detecting = true;
283 list_initialize(&dev_rpmb->dev.io_ops);
284 dev_rpmb->state = state;
285 dev_rpmb->base = base;
286 dev_rpmb->is_userdata = is_userdata;
287 }
288
block_device_tipc_init_dev_ns(struct block_device_ns * dev_ns,struct block_device_tipc * state,bool is_userdata)289 static void block_device_tipc_init_dev_ns(struct block_device_ns* dev_ns,
290 struct block_device_tipc* state,
291 bool is_userdata) {
292 dev_ns->dev.start_read = block_device_tipc_ns_start_read;
293 dev_ns->dev.start_write = block_device_tipc_ns_start_write;
294 dev_ns->dev.wait_for_io = block_device_tipc_ns_wait_for_io;
295 dev_ns->dev.block_size = BLOCK_SIZE_MAIN;
296 dev_ns->dev.block_num_size = sizeof(data_block_t);
297 dev_ns->dev.mac_size = sizeof(struct mac);
298 dev_ns->dev.tamper_detecting = false;
299 list_initialize(&dev_ns->dev.io_ops);
300 dev_ns->state = state;
301 dev_ns->ns_handle = 0; /* Filled in later */
302 dev_ns->is_userdata = is_userdata;
303 }
304
305 /**
306 * hwkey_derive_rpmb_key() - Derive rpmb key through hwkey server.
307 * @session: The hwkey session handle.
308 * @in: The input data to derive rpmb key.
309 * @out: The output data from deriving rpmb key.
310 *
311 * Return: NO_ERROR on success, error code less than 0 on error.
312 */
hwkey_derive_rpmb_key(hwkey_session_t session,const struct rpmb_key_derivation_in * in,struct rpmb_key_derivation_out * out)313 static int hwkey_derive_rpmb_key(hwkey_session_t session,
314 const struct rpmb_key_derivation_in* in,
315 struct rpmb_key_derivation_out* out) {
316 uint32_t kdf_version = HWKEY_KDF_VERSION_1;
317 const void* in_buf = in;
318 void* out_buf = out;
319 uint32_t key_size = sizeof(*out);
320 STATIC_ASSERT(sizeof(*in) >= sizeof(*out));
321
322 int ret = hwkey_derive(session, &kdf_version, in_buf, out_buf, key_size);
323 if (ret < 0) {
324 SS_ERR("%s: failed to get key: %d\n", __func__, ret);
325 return ret;
326 }
327
328 return NO_ERROR;
329 }
330
331 /**
332 * block_device_tipc_program_key() - Program a rpmb key derived through hwkey
333 * server.
334 * @state: The rpmb state.
335 * @rpmb_key_part_base: The base of rpmb_key_part in rpmb partition.
336 * @in The input rpmb key derivation data.
337 * @out The output rpmb key derivation data.
338 * @hwkey_session: The hwkey session handle.
339 *
340 * Return: NO_ERROR on success, error code less than 0 on error.
341 */
block_device_tipc_program_key(struct rpmb_state * state,uint16_t rpmb_key_part_base,struct rpmb_key_derivation_in * in,struct rpmb_key_derivation_out * out,hwkey_session_t hwkey_session)342 static int block_device_tipc_program_key(struct rpmb_state* state,
343 uint16_t rpmb_key_part_base,
344 struct rpmb_key_derivation_in* in,
345 struct rpmb_key_derivation_out* out,
346 hwkey_session_t hwkey_session) {
347 int ret;
348
349 if (!system_state_provisioning_allowed()) {
350 ret = ERR_NOT_ALLOWED;
351 SS_ERR("%s: rpmb key provisioning is not allowed (%d)\n", __func__,
352 ret);
353 return ret;
354 }
355
356 STATIC_ASSERT(sizeof(in->block_data) >= sizeof(out->rpmb_key));
357 RAND_bytes(in->block_data, sizeof(out->rpmb_key.byte));
358 ret = hwkey_derive_rpmb_key(hwkey_session, in, out);
359 if (ret < 0) {
360 SS_ERR("%s: hwkey_derive_rpmb_key failed (%d)\n", __func__, ret);
361 return ret;
362 }
363
364 ret = rpmb_program_key(state, &out->rpmb_key);
365 if (ret < 0) {
366 SS_ERR("%s: rpmb_program_key failed (%d)\n", __func__, ret);
367 return ret;
368 }
369
370 rpmb_set_key(state, &out->rpmb_key);
371
372 ret = rpmb_write(state, in->block_data,
373 rpmb_key_part_base * BLOCK_SIZE_RPMB_BLOCKS, 1, false,
374 false);
375 if (ret < 0) {
376 SS_ERR("%s: rpmb_write failed (%d)\n", __func__, ret);
377 return ret;
378 }
379
380 return 0;
381 }
382
block_device_tipc_derive_rpmb_key(struct rpmb_state * state,uint16_t rpmb_key_part_base,hwkey_session_t hwkey_session)383 static int block_device_tipc_derive_rpmb_key(struct rpmb_state* state,
384 uint16_t rpmb_key_part_base,
385 hwkey_session_t hwkey_session) {
386 int ret;
387 struct rpmb_key_derivation_in in = {
388 .prefix = {
389 0x74, 0x68, 0x43, 0x49, 0x2b, 0xa2, 0x4f, 0x77,
390 0xb0, 0x8e, 0xd1, 0xd4, 0xb7, 0x01, 0x0e, 0xc6,
391 0x86, 0x4c, 0xa9, 0xe5, 0x28, 0xf0, 0x20, 0xb1,
392 0xb8, 0x1e, 0x73, 0x3d, 0x8c, 0x9d, 0xb9, 0x96,
393 }};
394 struct rpmb_key_derivation_out out;
395
396 ret = rpmb_read_no_mac(state, in.block_data,
397 rpmb_key_part_base * BLOCK_SIZE_RPMB_BLOCKS, 1);
398
399 if (ret < 0) {
400 ret = block_device_tipc_program_key(state, rpmb_key_part_base, &in,
401 &out, hwkey_session);
402 if (ret < 0) {
403 SS_ERR("%s: program_key failed (%d)\n", __func__, ret);
404 return ret;
405 }
406
407 return 0;
408 }
409
410 ret = hwkey_derive_rpmb_key(hwkey_session, &in, &out);
411 if (ret < 0) {
412 SS_ERR("%s: hwkey_derive_rpmb_key failed (%d)\n", __func__, ret);
413 return ret;
414 }
415
416 rpmb_set_key(state, &out.rpmb_key);
417
418 /*
419 * Validate that the derived rpmb key is correct as we use it to check
420 * both mac and content of the block_data.
421 */
422 ret = rpmb_verify(state, in.block_data,
423 rpmb_key_part_base * BLOCK_SIZE_RPMB_BLOCKS, 1);
424 if (ret < 0) {
425 SS_ERR("%s: rpmb_verify failed with the derived rpmb key (%d)\n",
426 __func__, ret);
427 return ret;
428 }
429
430 return 0;
431 }
432
block_device_tipc_init_rpmb_key(struct rpmb_state * state,const struct rpmb_key * rpmb_key,uint16_t rpmb_key_part_base,hwkey_session_t hwkey_session)433 static int block_device_tipc_init_rpmb_key(struct rpmb_state* state,
434 const struct rpmb_key* rpmb_key,
435 uint16_t rpmb_key_part_base,
436 hwkey_session_t hwkey_session) {
437 int ret = 0;
438
439 if (rpmb_key) {
440 rpmb_set_key(state, rpmb_key);
441 } else {
442 ret = block_device_tipc_derive_rpmb_key(state, rpmb_key_part_base,
443 hwkey_session);
444 }
445
446 return ret;
447 }
448
check_storage_size(handle_t handle,struct block_device_ns * dev_ns,data_block_t * sz)449 static int check_storage_size(handle_t handle,
450 struct block_device_ns* dev_ns,
451 data_block_t* sz) {
452 int ret;
453
454 assert(sz != NULL);
455
456 ret = ns_get_max_size(handle, dev_ns->ns_handle, sz);
457 if (ret < 0) {
458 /* In case we have an old storageproxyd, use default */
459 if (ret == ERR_NOT_IMPLEMENTED) {
460 *sz = BLOCK_COUNT_MAIN * dev_ns->dev.block_size;
461 ret = 0;
462 } else {
463 SS_ERR("%s: Could not get max size: %d\n", __func__, ret);
464 }
465 } else if (*sz < (dev_ns->dev.block_size * 8)) {
466 SS_ERR("%s: max storage file size %" PRIu64 " is too small\n", __func__,
467 *sz);
468 ret = -1;
469 }
470 return ret;
471 }
472
block_device_tipc_init(struct block_device_tipc * state,struct tipc_hset * hset,struct storage_service_aidl_context * aidl_ctx,handle_t ipc_handle,const struct key * fs_key,const struct rpmb_key * rpmb_key,hwkey_session_t hwkey_session)473 int block_device_tipc_init(struct block_device_tipc* state,
474 struct tipc_hset* hset,
475 struct storage_service_aidl_context* aidl_ctx,
476 handle_t ipc_handle,
477 const struct key* fs_key,
478 const struct rpmb_key* rpmb_key,
479 hwkey_session_t hwkey_session) {
480 int ret;
481 bool alternate_data_partition = false;
482 uint32_t ns_init_flags = FS_INIT_FLAGS_NONE;
483 #if HAS_FS_TDP
484 uint32_t tdp_init_flags = FS_INIT_FLAGS_NONE;
485 #endif
486 uint8_t probe;
487 uint16_t rpmb_key_part_base = 0;
488 uint32_t rpmb_block_count;
489 uint32_t rpmb_part_sb_ns_block_count = 2;
490 /*
491 * First block is reserved for rpmb key derivation data, whose base is
492 * rpmb_key_part_base
493 */
494 uint16_t rpmb_part1_base = 1;
495 uint16_t rpmb_part2_base = rpmb_part1_base + rpmb_part_sb_ns_block_count;
496
497 data_block_t sz;
498 #if HAS_FS_TDP
499 uint16_t rpmb_part_sb_tdp_base = rpmb_part2_base;
500 rpmb_part2_base += rpmb_part_sb_ns_block_count;
501 #endif
502 state->ipc_handle = ipc_handle;
503 state->aidl_ctx = aidl_ctx;
504
505 /* init rpmb */
506 ret = rpmb_init(&state->rpmb_state, &state->ipc_handle);
507 if (ret < 0) {
508 SS_ERR("%s: rpmb_init failed (%d)\n", __func__, ret);
509 goto err_rpmb_init;
510 }
511
512 ret = block_device_tipc_init_rpmb_key(state->rpmb_state, rpmb_key,
513 rpmb_key_part_base, hwkey_session);
514 if (ret < 0) {
515 SS_ERR("%s: block_device_tipc_init_rpmb_key failed (%d)\n", __func__,
516 ret);
517 goto err_init_rpmb_key;
518 }
519
520 if (BLOCK_COUNT_RPMB) {
521 rpmb_block_count = BLOCK_COUNT_RPMB;
522 ret = rpmb_check(state, rpmb_block_count * BLOCK_SIZE_RPMB_BLOCKS - 1);
523 if (ret) {
524 SS_ERR("%s: bad static rpmb size, %d\n", __func__,
525 rpmb_block_count);
526 goto err_bad_rpmb_size;
527 }
528 } else {
529 rpmb_block_count =
530 rpmb_search_size(state, 0); /* TODO: get hint from ns */
531 rpmb_block_count /= BLOCK_SIZE_RPMB_BLOCKS;
532 }
533 if (rpmb_block_count < rpmb_part2_base) {
534 ret = -1;
535 SS_ERR("%s: bad rpmb size, %d\n", __func__, rpmb_block_count);
536 goto err_bad_rpmb_size;
537 }
538
539 block_device_tipc_init_dev_rpmb(&state->dev_rpmb, state, rpmb_part2_base,
540 rpmb_block_count - rpmb_part2_base, false);
541
542 /* TODO: allow non-rpmb based tamper proof storage */
543 ret = fs_init(&state->tr_state_rpmb, file_system_id_tp, fs_key,
544 &state->dev_rpmb.dev, &state->dev_rpmb.dev,
545 FS_INIT_FLAGS_NONE);
546 if (ret < 0) {
547 goto err_init_tr_state_rpmb;
548 }
549
550 state->fs_rpmb.tr_state = &state->tr_state_rpmb;
551
552 storage_aidl_enable_filesystem(aidl_ctx, state->fs_rpmb.tr_state,
553 STORAGE_AIDL_TP);
554 ret = client_create_port(hset, &state->fs_rpmb.client_ctx,
555 STORAGE_CLIENT_TP_PORT);
556 if (ret < 0) {
557 goto err_fs_rpmb_create_port;
558 }
559
560 state->fs_rpmb_boot.tr_state = &state->tr_state_rpmb;
561
562 storage_aidl_enable_filesystem(aidl_ctx, state->fs_rpmb_boot.tr_state,
563 STORAGE_AIDL_TDEA);
564 ret = client_create_port(hset, &state->fs_rpmb_boot.client_ctx,
565 STORAGE_CLIENT_TDEA_PORT);
566 if (ret < 0) {
567 goto err_fs_rpmb_boot_create_port;
568 }
569
570 block_device_tipc_init_dev_ns(&state->dev_ns, state, true);
571
572 ret = ns_open_file(state->ipc_handle, "0", &state->dev_ns.ns_handle, true);
573 if (ret < 0) {
574 /*
575 * Only attempt to open the alternate file if allowed, and if not
576 * supported or available fall back to TP only.
577 */
578 #if STORAGE_NS_ALTERNATE_SUPERBLOCK_ALLOWED
579 ret = ns_open_file(state->ipc_handle, "alternate/0",
580 &state->dev_ns.ns_handle, true);
581 #endif
582 if (ret >= 0) {
583 alternate_data_partition = true;
584 } else {
585 /* RPMB fs only */
586 state->dev_ns.dev.block_count = 0;
587 return 0;
588 }
589 }
590
591 ret = check_storage_size(state->ipc_handle, &state->dev_ns, &sz);
592 if (ret < 0) {
593 goto err_get_td_max_size;
594 }
595 state->dev_ns.dev.block_count = sz / state->dev_ns.dev.block_size;
596
597 #if HAS_FS_TDP
598 block_device_tipc_init_dev_ns(&state->dev_ns_tdp, state, false);
599
600 ret = ns_open_file(state->ipc_handle, "persist/0",
601 &state->dev_ns_tdp.ns_handle, true);
602 if (ret < 0) {
603 SS_ERR("%s: failed to open tdp file (%d)\n", __func__, ret);
604 goto err_open_tdp;
605 }
606
607 ret = check_storage_size(state->ipc_handle, &state->dev_ns_tdp, &sz);
608 if (ret < 0) {
609 goto err_get_tdp_max_size;
610 }
611 state->dev_ns_tdp.dev.block_count = sz / state->dev_ns_tdp.dev.block_size;
612
613 state->fs_tdp.tr_state = &state->tr_state_ns_tdp;
614
615 block_device_tipc_init_dev_rpmb(&state->dev_ns_tdp_rpmb, state,
616 rpmb_part_sb_tdp_base,
617 rpmb_part_sb_ns_block_count, false);
618
619 #if STORAGE_TDP_AUTO_CHECKPOINT_ENABLED
620 if (!system_state_provisioning_allowed()) {
621 /*
622 * Automatically create a checkpoint if we are done provisioning but do
623 * not already have a checkpoint.
624 */
625 tdp_init_flags |= FS_INIT_FLAGS_AUTO_CHECKPOINT;
626 }
627 #endif
628
629 ret = fs_init(&state->tr_state_ns_tdp, file_system_id_tdp, fs_key,
630 &state->dev_ns_tdp.dev, &state->dev_ns_tdp_rpmb.dev,
631 tdp_init_flags);
632 if (ret < 0) {
633 goto err_init_fs_ns_tdp_tr_state;
634 }
635
636 #if STORAGE_TDP_RECOVERY_CHECKPOINT_RESTORE_ALLOWED
637 if (fs_check(&state->tr_state_ns_tdp) == FS_CHECK_INVALID_BLOCK) {
638 SS_ERR("%s: TDP filesystem check failed with invalid block, "
639 "attempting to restore checkpoint\n",
640 __func__);
641 fs_destroy(&state->tr_state_ns_tdp);
642 ret = fs_init(&state->tr_state_ns_tdp, file_system_id_tdp, fs_key,
643 &state->dev_ns_tdp.dev, &state->dev_ns_tdp_rpmb.dev,
644 tdp_init_flags | FS_INIT_FLAGS_RESTORE_CHECKPOINT);
645 if (ret < 0) {
646 goto err_init_fs_ns_tdp_tr_state;
647 }
648 }
649 #endif
650
651 #else
652 /*
653 * Create STORAGE_CLIENT_TDP_PORT alias after we know the backing file for
654 * STORAGE_CLIENT_TD_PORT is available. On future devices, using HAS_FS_TDP,
655 * STORAGE_CLIENT_TDP_PORT will not be available when the bootloader is
656 * running, so we limit access to this alias as well to prevent apps
657 * developed on old devices from relying on STORAGE_CLIENT_TDP_PORT being
658 * available early.
659 */
660 state->fs_tdp.tr_state = &state->tr_state_rpmb;
661 #endif
662
663 storage_aidl_enable_filesystem(aidl_ctx, state->fs_tdp.tr_state,
664 STORAGE_AIDL_TDP);
665 ret = client_create_port(hset, &state->fs_tdp.client_ctx,
666 STORAGE_CLIENT_TDP_PORT);
667 if (ret < 0) {
668 goto err_fs_rpmb_tdp_create_port;
669 }
670
671 /* Request empty file system if file is empty */
672 ret = ns_read_pos(state->ipc_handle, state->dev_ns.ns_handle, 0, &probe,
673 sizeof(probe));
674 if (ret < (int)sizeof(probe)) {
675 ns_init_flags |= FS_INIT_FLAGS_DO_CLEAR;
676 }
677
678 state->fs_ns.tr_state = &state->tr_state_ns;
679
680 block_device_tipc_init_dev_rpmb(&state->dev_ns_rpmb, state, rpmb_part1_base,
681 rpmb_part_sb_ns_block_count, true);
682
683 #if STORAGE_NS_RECOVERY_CLEAR_ALLOWED
684 ns_init_flags |= FS_INIT_FLAGS_RECOVERY_CLEAR_ALLOWED;
685 #endif
686
687 /*
688 * This must be false if STORAGE_NS_ALTERNATE_SUPERBLOCK_ALLOWED is
689 * false.
690 */
691 if (alternate_data_partition) {
692 ns_init_flags |= FS_INIT_FLAGS_ALTERNATE_DATA;
693 }
694
695 ret = fs_init(&state->tr_state_ns, file_system_id_td, fs_key,
696 &state->dev_ns.dev, &state->dev_ns_rpmb.dev, ns_init_flags);
697 if (ret < 0) {
698 goto err_init_fs_ns_tr_state;
699 }
700
701 storage_aidl_enable_filesystem(aidl_ctx, state->fs_ns.tr_state,
702 STORAGE_AIDL_TD);
703 ret = client_create_port(hset, &state->fs_ns.client_ctx,
704 STORAGE_CLIENT_TD_PORT);
705 if (ret < 0) {
706 goto err_fs_ns_create_port;
707 }
708
709 #if HAS_FS_NSP
710 block_device_tipc_init_dev_ns(&state->dev_ns_nsp, state, false);
711
712 ret = ns_open_file(state->ipc_handle, "persist/nsp",
713 &state->dev_ns_nsp.ns_handle, true);
714 if (ret < 0) {
715 SS_ERR("%s: failed to open NSP file (%d)\n", __func__, ret);
716 goto err_open_nsp;
717 }
718
719 ret = check_storage_size(state->ipc_handle, &state->dev_ns_nsp, &sz);
720 if (ret < 0) {
721 goto err_get_nsp_max_size;
722 }
723 state->dev_ns_nsp.dev.block_count = sz / state->dev_ns_nsp.dev.block_size;
724
725 state->fs_nsp.tr_state = &state->tr_state_ns_nsp;
726
727 ret = fs_init(&state->tr_state_ns_nsp, file_system_id_nsp, fs_key,
728 &state->dev_ns_nsp.dev, &state->dev_ns_nsp.dev,
729 FS_INIT_FLAGS_RECOVERY_CLEAR_ALLOWED |
730 FS_INIT_FLAGS_ALLOW_TAMPERING);
731 if (ret < 0) {
732 goto err_init_fs_ns_nsp_tr_state;
733 }
734
735 /*
736 * Check that all files are accessible and attempt to clear the FS if files
737 * cannot be accessed.
738 */
739 if (fs_check(&state->tr_state_ns_nsp) != FS_CHECK_NO_ERROR) {
740 SS_ERR("%s: NSP filesystem check failed, attempting to clear\n",
741 __func__);
742 fs_destroy(&state->tr_state_ns_nsp);
743 block_cache_dev_destroy(&state->dev_ns_nsp.dev);
744
745 ret = fs_init(&state->tr_state_ns_nsp, file_system_id_nsp, fs_key,
746 &state->dev_ns_nsp.dev, &state->dev_ns_nsp.dev,
747 FS_INIT_FLAGS_DO_CLEAR | FS_INIT_FLAGS_ALLOW_TAMPERING);
748 if (ret < 0) {
749 goto err_init_fs_ns_nsp_tr_state;
750 }
751 }
752
753 #else
754 /*
755 * Create STORAGE_CLIENT_NSP_PORT alias to TDP if we don't support NSP on
756 * this build. TDP has stronger security properties than NSP, and NSP may be
757 * reset at any point, so this should be acceptable for clients.
758 */
759 state->fs_nsp.tr_state = state->fs_tdp.tr_state;
760 #endif
761
762 storage_aidl_enable_filesystem(aidl_ctx, state->fs_nsp.tr_state,
763 STORAGE_AIDL_NSP);
764 ret = client_create_port(hset, &state->fs_nsp.client_ctx,
765 STORAGE_CLIENT_NSP_PORT);
766 if (ret < 0) {
767 goto err_fs_nsp_create_port;
768 }
769
770 return 0;
771
772 err_fs_nsp_create_port:
773 #if HAS_FS_NSP
774 fs_destroy(&state->tr_state_ns_nsp);
775 err_init_fs_ns_nsp_tr_state:
776 block_cache_dev_destroy(&state->dev_ns_nsp.dev);
777 err_get_nsp_max_size:
778 ns_close_file(state->ipc_handle, state->dev_ns_nsp.ns_handle);
779 err_open_nsp:
780 #endif
781 ipc_port_destroy(&state->fs_ns.client_ctx);
782 err_fs_ns_create_port:
783 fs_destroy(&state->tr_state_ns);
784 err_init_fs_ns_tr_state:
785 block_cache_dev_destroy(&state->dev_ns.dev);
786 ipc_port_destroy(&state->fs_tdp.client_ctx);
787 err_fs_rpmb_tdp_create_port:
788 #if HAS_FS_TDP
789 fs_destroy(&state->tr_state_ns_tdp);
790 err_init_fs_ns_tdp_tr_state:
791 block_cache_dev_destroy(&state->dev_ns_tdp.dev);
792 err_get_tdp_max_size:
793 ns_close_file(state->ipc_handle, state->dev_ns_tdp.ns_handle);
794 err_open_tdp:
795 #endif
796 err_get_td_max_size:
797 ns_close_file(state->ipc_handle, state->dev_ns.ns_handle);
798 ipc_port_destroy(&state->fs_rpmb_boot.client_ctx);
799 err_fs_rpmb_boot_create_port:
800 ipc_port_destroy(&state->fs_rpmb.client_ctx);
801 err_fs_rpmb_create_port:
802 fs_destroy(&state->tr_state_rpmb);
803 err_init_tr_state_rpmb:
804 block_cache_dev_destroy(&state->dev_rpmb.dev);
805 err_bad_rpmb_size:
806 err_init_rpmb_key:
807 rpmb_uninit(state->rpmb_state);
808 err_rpmb_init:
809 return ret;
810 }
811
block_device_tipc_uninit(struct block_device_tipc * state)812 void block_device_tipc_uninit(struct block_device_tipc* state) {
813 if (state->dev_ns.dev.block_count) {
814 storage_aidl_disable_filesystem(state->aidl_ctx, STORAGE_AIDL_TD);
815 ipc_port_destroy(&state->fs_ns.client_ctx);
816 fs_destroy(&state->tr_state_ns);
817 block_cache_dev_destroy(&state->dev_ns.dev);
818 ns_close_file(state->ipc_handle, state->dev_ns.ns_handle);
819
820 storage_aidl_disable_filesystem(state->aidl_ctx, STORAGE_AIDL_TDP);
821 ipc_port_destroy(&state->fs_tdp.client_ctx);
822 #if HAS_FS_TDP
823 fs_destroy(&state->tr_state_ns_tdp);
824 block_cache_dev_destroy(&state->dev_ns_tdp.dev);
825 ns_close_file(state->ipc_handle, state->dev_ns_tdp.ns_handle);
826 #endif
827
828 storage_aidl_disable_filesystem(state->aidl_ctx, STORAGE_AIDL_NSP);
829 ipc_port_destroy(&state->fs_nsp.client_ctx);
830 #if HAS_FS_NSP
831 fs_destroy(&state->tr_state_ns_nsp);
832 block_cache_dev_destroy(&state->dev_ns_nsp.dev);
833 ns_close_file(state->ipc_handle, state->dev_ns_nsp.ns_handle);
834 #endif
835 }
836 storage_aidl_disable_filesystem(state->aidl_ctx, STORAGE_AIDL_TDEA);
837 ipc_port_destroy(&state->fs_rpmb_boot.client_ctx);
838 storage_aidl_disable_filesystem(state->aidl_ctx, STORAGE_AIDL_TP);
839 ipc_port_destroy(&state->fs_rpmb.client_ctx);
840 fs_destroy(&state->tr_state_rpmb);
841 block_cache_dev_destroy(&state->dev_rpmb.dev);
842 rpmb_uninit(state->rpmb_state);
843 }
844