7
7
8
8
use std:: borrow:: Cow ;
9
9
use std:: fmt:: Display ;
10
+ use std:: io:: Write ;
10
11
use std:: process:: Command ;
11
12
use std:: process:: Stdio ;
12
13
@@ -52,13 +53,6 @@ pub(crate) enum Filesystem {
52
53
Btrfs ,
53
54
}
54
55
55
- impl Default for Filesystem {
56
- fn default ( ) -> Self {
57
- // Obviously this should be configurable.
58
- Self :: Xfs
59
- }
60
- }
61
-
62
56
impl Display for Filesystem {
63
57
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
64
58
self . to_possible_value ( ) . unwrap ( ) . get_name ( ) . fmt ( f)
@@ -161,6 +155,7 @@ pub(crate) fn install_create_rootfs(
161
155
state : & State ,
162
156
opts : InstallBlockDeviceOpts ,
163
157
) -> Result < RootSetup > {
158
+ let luks_name = "root" ;
164
159
// Verify that the target is empty (if not already wiped in particular, but it's
165
160
// also good to verify that the wipe worked)
166
161
let device = crate :: blockdev:: list_dev ( & opts. device ) ?;
@@ -291,11 +286,41 @@ pub(crate) fn install_create_rootfs(
291
286
292
287
crate :: blockdev:: udev_settle ( ) ?;
293
288
294
- match opts. block_setup {
295
- BlockSetup :: Direct => { }
296
- // TODO
297
- BlockSetup :: Tpm2Luks => anyhow:: bail!( "tpm2-luks is not implemented yet" ) ,
298
- }
289
+ let base_rootdev = format ! ( "{device}{ROOTPN}" ) ;
290
+ let ( rootdev, root_blockdev_kargs) = match opts. block_setup {
291
+ BlockSetup :: Direct => ( base_rootdev, None ) ,
292
+ BlockSetup :: Tpm2Luks => {
293
+ let uuid = uuid:: Uuid :: new_v4 ( ) . to_string ( ) ;
294
+ // This will be replaced via --wipe-slot=all when binding to tpm below
295
+ let dummy_passphrase = uuid:: Uuid :: new_v4 ( ) . to_string ( ) ;
296
+ let mut tmp_keyfile = tempfile:: NamedTempFile :: new ( ) ?;
297
+ tmp_keyfile. write_all ( dummy_passphrase. as_bytes ( ) ) ?;
298
+ tmp_keyfile. flush ( ) ?;
299
+ let tmp_keyfile = tmp_keyfile. path ( ) ;
300
+ let dummy_passphrase_input = Some ( dummy_passphrase. as_bytes ( ) ) ;
301
+
302
+ Task :: new ( "Initializing LUKS for root" , "cryptsetup" )
303
+ . args ( [ "luksFormat" , "--uuid" , uuid. as_str ( ) , "--key-file" ] )
304
+ . args ( [ tmp_keyfile] )
305
+ . args ( [ base_rootdev. as_str ( ) ] )
306
+ . run ( ) ?;
307
+ // The --wipe-slot=all removes our temporary passphrase, and binds to the local TPM device.
308
+ Task :: new ( "Enrolling root device with TPM" , "systemd-cryptenroll" )
309
+ . args ( [ "--wipe-slot=all" , "--tpm2-device=auto" , "--unlock-key-file" ] )
310
+ . args ( [ tmp_keyfile] )
311
+ . args ( [ base_rootdev. as_str ( ) ] )
312
+ . run_with_stdin_buf ( dummy_passphrase_input) ?;
313
+ Task :: new ( "Opening root LUKS device" , "cryptsetup" )
314
+ . args ( [ "luksOpen" , base_rootdev. as_str ( ) , luks_name] )
315
+ . run ( ) ?;
316
+ let rootdev = format ! ( "/dev/mapper/{luks_name}" ) ;
317
+ let kargs = vec ! [
318
+ format!( "luks.uuid={uuid}" ) ,
319
+ format!( "luks.options=tpm2-device=auto,headless=true" ) ,
320
+ ] ;
321
+ ( rootdev, Some ( kargs) )
322
+ }
323
+ } ;
299
324
300
325
// TODO: make this configurable
301
326
let bootfs_type = Filesystem :: Ext4 ;
@@ -305,19 +330,22 @@ pub(crate) fn install_create_rootfs(
305
330
let boot_uuid = mkfs ( bootdev, bootfs_type, Some ( "boot" ) , [ ] ) . context ( "Initializing /boot" ) ?;
306
331
307
332
// Initialize rootfs
308
- let rootdev = & format ! ( "{device}{ROOTPN}" ) ;
309
333
let root_filesystem = opts
310
334
. filesystem
311
335
. or ( state. install_config . root_fs_type )
312
336
. ok_or_else ( || anyhow:: anyhow!( "No root filesystem specified" ) ) ?;
313
- let root_uuid = mkfs ( rootdev, root_filesystem, Some ( "root" ) , [ ] ) ?;
337
+ let root_uuid = mkfs ( & rootdev, root_filesystem, Some ( "root" ) , [ ] ) ?;
314
338
let rootarg = format ! ( "root=UUID={root_uuid}" ) ;
315
339
let bootsrc = format ! ( "UUID={boot_uuid}" ) ;
316
340
let bootarg = format ! ( "boot={bootsrc}" ) ;
317
341
let boot = MountSpec :: new ( bootsrc. as_str ( ) , "/boot" ) ;
318
- let kargs = vec ! [ rootarg, RW_KARG . to_string( ) , bootarg] ;
342
+ let kargs = root_blockdev_kargs
343
+ . into_iter ( )
344
+ . flatten ( )
345
+ . chain ( [ rootarg, RW_KARG . to_string ( ) , bootarg] . into_iter ( ) )
346
+ . collect :: < Vec < _ > > ( ) ;
319
347
320
- mount:: mount ( rootdev, & rootfs) ?;
348
+ mount:: mount ( & rootdev, & rootfs) ?;
321
349
lsm_label ( & rootfs, "/" . into ( ) , false ) ?;
322
350
let rootfs_fd = Dir :: open_ambient_dir ( & rootfs, cap_std:: ambient_authority ( ) ) ?;
323
351
let bootfs = rootfs. join ( "boot" ) ;
@@ -339,7 +367,12 @@ pub(crate) fn install_create_rootfs(
339
367
mount:: mount ( & espdev, & efifs_path) ?;
340
368
}
341
369
370
+ let luks_device = match opts. block_setup {
371
+ BlockSetup :: Direct => None ,
372
+ BlockSetup :: Tpm2Luks => Some ( luks_name. to_string ( ) ) ,
373
+ } ;
342
374
Ok ( RootSetup {
375
+ luks_device,
343
376
device,
344
377
rootfs,
345
378
rootfs_fd,
0 commit comments