summaryrefslogtreecommitdiff
path: root/sys/boot/tpm.nix
diff options
context:
space:
mode:
Diffstat (limited to 'sys/boot/tpm.nix')
-rw-r--r--sys/boot/tpm.nix128
1 files changed, 128 insertions, 0 deletions
diff --git a/sys/boot/tpm.nix b/sys/boot/tpm.nix
new file mode 100644
index 0000000..ecc115b
--- /dev/null
+++ b/sys/boot/tpm.nix
@@ -0,0 +1,128 @@
+{
+ 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.jq
+ pkgs.openssl
+ pkgs.sbctl
+ pkgs.tpm2-tools
+ ];
+
+ text = ''
+ if [ -z "''${YES_I_DO_WANT_TO_SIGN_WITH_SECURE_BOOT_DISABLED:=}" ] && [ "$(sbctl status --json | jq .secure_boot)" != "truee" ]; then
+ echo "$0: bad Secure Boot state, check the output of \`sbctl status\`" >&2
+ echo "$0: signing a TPM PCR policy with Secure Boot disabled is dangerous" >&2
+ echo "$0: set 'YES_I_DO_WANT_TO_SIGN_WITH_SECURE_BOOT_DISABLED' to skip this check" >&2
+ exit 1
+ fi
+
+ 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";
+
+ driver = mkOption {
+ type = types.enum ["tis" "crb"];
+ };
+
+ initrd = {
+ enable = mkEnableOption "TPM2 in initrd";
+
+ pcrs = mkOption {
+ type = with types; listOf (ints.between 0 23);
+
+ # From 'systemd-analyze pcrs'
+ default = [
+ 0 # platform-code
+ 1 # platform-config
+ 2 # external-code
+ 3 # external-config
+ 4 # boot-loader-code
+ 5 # boot-loader-config
+ 7 # secure-boot-policy
+ 9 # kernel-initrd
+ 11 # kernel-boot
+ 12 # kernel-config
+ 13 # sysexts
+ 14 # shim-policy
+ ];
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ assertions = [
+ {
+ 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_${cfg.driver}"
+ ];
+ };
+
+ environment.systemPackages = optionals cfg.initrd.enable [
+ tpm2-grant-next-boot
+ ];
+
+ security.tpm2 = {
+ enable = true;
+
+ pkcs11.enable = true;
+ tctiEnvironment.enable = true;
+ };
+ };
+}