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