summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/boot/detached-luks.nix78
-rw-r--r--sys/boot/tpm.nix69
2 files changed, 125 insertions, 22 deletions
diff --git a/sys/boot/detached-luks.nix b/sys/boot/detached-luks.nix
index a7b1bc9..1e7cc2b 100644
--- a/sys/boot/detached-luks.nix
+++ b/sys/boot/detached-luks.nix
@@ -1,6 +1,11 @@
{ config, lib, pkgs, ... }:
with lib; let
cfg = config.local.boot.detachedLuks;
+
+ bootFs = config.fileSystems."/boot";
+ tpmInitrd = config.local.boot.tpm.initrd.enable;
+
+ pcrList = concatStringsSep "," (map toString config.local.boot.tpm.initrd.pcrs);
in
{
options.local.boot.detachedLuks = {
@@ -10,6 +15,11 @@ in
type = types.str;
};
+ tpmStorageFromBoot = mkOption {
+ type = types.str;
+ default = "tpm-boot";
+ };
+
crypt = mkOption {
type = types.str;
};
@@ -23,16 +33,16 @@ in
boot.initrd =
let
headerPath = "/initrd-boot/${cfg.headerFromBoot}";
+ headerPathEscaped = escapeShellArg headerPath;
+
+ tpmPath = escapeShellArg "/initrd-boot/${cfg.tpmStorageFromBoot}";
+ hardwareKeyPath = "/tpm/unsealed.luks-key";
in
{
- preDeviceCommands =
- let
- headerPathEscaped = escapeShellArg headerPath;
- in
- ''
- mkdir -p `dirname ${headerPathEscaped}`
- touch ${headerPathEscaped}
- '';
+ preDeviceCommands = ''
+ mkdir -p `dirname ${headerPathEscaped}`
+ touch ${headerPathEscaped}
+ '';
postDeviceCommands = mkIf (!config.boot.initrd.systemd.enable) ''
# Set the system time from the hardware clock to work around a
@@ -51,23 +61,51 @@ in
header = headerPath;
preLVM = false;
- preOpenCommands =
- let
- boot = config.fileSystems."/boot";
- in
- ''
- mount -o ro -t ${boot.fsType} ${boot.device} /initrd-boot
- '';
+ keyFile = mkIf tpmInitrd hardwareKeyPath;
+ fallbackToPassword = tpmInitrd;
- postOpenCommands = mkBefore ''
- umount /initrd-boot
+ preOpenCommands = ''
+ mount -o ro -t ${bootFs.fsType} ${bootFs.device} /initrd-boot
+ '' + optionalString tpmInitrd ''
+ mkdir /tpm
+
+ tpm2 createprimary -Q -C owner -g sha256 -G ecc -c /tpm/prim.ctx
+
+ tpm2 loadexternal -Q -C owner -G rsa -u ${tpmPath}/signing-key.pub -c /tpm/signing-key.ctx -n /tpm/signing-key.name
+ tpm2 verifysignature -Q -c /tpm/signing-key.ctx -g sha256 -m ${tpmPath}/auth.policy -s ${tpmPath}/auth.sig -t /tpm/verified.ticket -f rsassa
+
+ tpm2 startauthsession -Q -S /tpm/session.ctx --policy-session
+
+ tpm_resets=`tpm2 readclock | grep reset_count | sed 's/.*: //g'`
+ tpm2 policycountertimer -Q -S /tpm/session.ctx resets="$tpm_resets"
+ tpm2 policypcr -Q -S /tpm/session.ctx -l sha256:${pcrList}
+ tpm2 policyauthorize -Q -S /tpm/session.ctx -i ${tpmPath}/auth.policy -n /tpm/signing-key.name -t /tpm/verified.ticket
+
+ tpm2 load -Q -C /tpm/prim.ctx -u ${tpmPath}/key.pub -r ${tpmPath}/key.priv -c /tpm/key.ctx
+ tpm2 unseal -Q -c /tpm/key.ctx -p session:/tpm/session.ctx -o /tpm/unsealed.luks-key
+
+ echo "Unsealed!"
+ cat /tpm/unsealed.luks-key
+ echo "Unsealed! END"
+
+ tpm2 flushcontext /tpm/session.ctx
'';
+
+ postOpenCommands = mkBefore (''
+ umount /initrd-boot
+ '' + optionalString tpmInitrd ''
+ rm -r /tpm
+ '');
};
};
- local.boot.stack = {
- btrfsToplevelMultidrive.toplevel.device = "/dev/mapper/${cfg.target}";
- luksExt4FscryptImpermanence = { inherit (cfg) target; };
+ local.boot = {
+ stack = {
+ btrfsToplevelMultidrive.toplevel.device = "/dev/mapper/${cfg.target}";
+ luksExt4FscryptImpermanence = { inherit (cfg) target; };
+ };
+
+ tpm.initrd.enable = mkDefault config.local.boot.tpm.enable;
};
};
}
diff --git a/sys/boot/tpm.nix b/sys/boot/tpm.nix
index 4932b7c..1e446ab 100644
--- a/sys/boot/tpm.nix
+++ b/sys/boot/tpm.nix
@@ -1,10 +1,57 @@
{ config, lib, pkgs, ... }:
with lib; let
cfg = config.local.boot.tpm;
+
+ pcrList = concatStringsSep "," (map toString cfg.initrd.pcrs);
+
+ # Crear signing-key con:
+ # $ openssl genrsa -out ~/vtmp/signing-key.priv 2048
+ # $ openssl rsa -in ~/vtmp/signing-key.priv -out ~/vtmp/signing-key.pub -pubout
+ # Y copiar signing-key.pub a /boot/tpm-boot. Guardar signing-key.priv en lugar seguro.
+ #
+ # Crear llave con:
+ # $ tpm2_loadexternal -G rsa -C owner -u signing-key.pub -c signing-key.ctx -n signing-key.name
+ # $ tpm2_startauthsession -S session.ctx
+ # $ tpm2_policyauthorize -S session.ctx -L require-signed.policy -n signing-key.name
+ # $ tpm2_flushcontext session.ctx
+ # $ tpm2_createprimary -C owner -g sha256 -G ecc -c prim.ctx
+ # $ head -c128 /dev/urandom | tpm2_create -C prim.ctx -u key.pub -r key.priv -c key.ctx -L require-signed.policy -i-
+ # Y mover key.priv/key.pub a /boot/tpm-boot
+ #
+ # Usage: tpm2-grant-next-boot < signing-key.priv
+ # Genera auth.policy y auth.sig
+ tpm2-grant-next-boot = pkgs.writeShellApplication {
+ name = "tpm2-grant-next-boot";
+ runtimeInputs = [ pkgs.openssl pkgs.tpm2-tools ];
+
+ text = ''
+ ctx_dir="$(mktemp -d)"
+ trap 'rm -rf -- "$ctx_dir"' EXIT
+
+ tpm2_createprimary -Q -C owner -g sha256 -G ecc -c "$ctx_dir/prim.ctx"
+
+ tpm2_startauthsession -Q -S "$ctx_dir/session.ctx"
+ tpm_resets=$(tpm2_readclock | grep reset_count | sed 's/.*: //')
+ tpm2_policycountertimer -Q -S "$ctx_dir/session.ctx" resets="$((tpm_resets+1))"
+ tpm2_policypcr -Q -S "$ctx_dir/session.ctx" -L auth.policy -l sha256:${pcrList}
+ tpm2_flushcontext -Q "$ctx_dir/session.ctx"
+
+ openssl dgst -sha256 -sign /dev/stdin -out auth.sig auth.policy
+ '';
+ };
in
{
options.local.boot.tpm = {
enable = mkEnableOption "Trusted Platform Module 2.0";
+
+ initrd = {
+ enable = mkEnableOption "TPM2 in initrd";
+
+ pcrs = mkOption {
+ type = with types; listOf (ints.between 0 23);
+ default = [ 0 2 7 8 11 ];
+ };
+ };
};
config = mkIf cfg.enable {
@@ -13,6 +60,26 @@ in
assertion = config.local.boot.efi.enable;
message = "TPM2 requires EFI";
}
+ {
+ assertion = cfg.initrd.enable -> cfg.enable;
+ message = "TPM2 in initrd requires TPM2";
+ }
+ ];
+
+ boot.initrd = mkIf cfg.initrd.enable {
+ extraUtilsCommands = ''
+ copy_bin_and_libs ${pkgs.tpm2-tools}/bin/.tpm2-wrapped
+ mv $out/bin/{.tpm2-wrapped,tpm2}
+ cp {${pkgs.tpm2-tss},$out}/lib/libtss2-tcti-device.so.0
+ '';
+
+ kernelModules = [
+ "tpm_tis"
+ ];
+ };
+
+ environment.systemPackages = optionals cfg.initrd.enable [
+ tpm2-grant-next-boot
];
security.tpm2 = {
@@ -21,7 +88,5 @@ in
pkcs11.enable = true;
tctiEnvironment.enable = true;
};
-
- environment.systemPackages = [ pkgs.tpm2-tools ];
};
}