From 1a76ee21ce5119d182464d35aef21c815df7f5bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20Sj=C3=B6strom?= Date: Thu, 23 Jan 2025 12:11:57 +0100 Subject: [PATCH] feat: initial secure boot --- .woodpecker/ci.yaml | 13 +++- flake.nix | 3 + keys/DB.auth | Bin 0 -> 2092 bytes keys/KEK.auth | Bin 0 -> 2091 bytes keys/PK.auth | Bin 0 -> 2089 bytes modules/image/builder.nix | 1 + scripts/sbkeys | 154 ++++++++++++++++++++++++++++++++++++++ scripts/sign-release.sh | 19 +++++ 8 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 keys/DB.auth create mode 100644 keys/KEK.auth create mode 100644 keys/PK.auth create mode 100755 scripts/sbkeys create mode 100755 scripts/sign-release.sh diff --git a/.woodpecker/ci.yaml b/.woodpecker/ci.yaml index 3099d84..606a477 100644 --- a/.woodpecker/ci.yaml +++ b/.woodpecker/ci.yaml @@ -6,6 +6,17 @@ when: steps: check: - image: docker.io/nixpkgs/nix-flakes:nixos-24.05 + image: docker.io/nixpkgs/nix-flakes:nixos-25.05 commands: - nix flake check + + sign: + image: docker.io/nixpkgs/nix-flakes:nixos-25.05 + environment: + DB_KEY: + from_secret: secure_boot_key + DB_CRT: + from_secret: secure_boot_crt + commands: + - ./scripts/sign-release.sh + diff --git a/flake.nix b/flake.nix index 7648b8b..e5f4787 100644 --- a/flake.nix +++ b/flake.nix @@ -80,8 +80,11 @@ devShells.${system}.default = pkgs.mkShell { buildInputs = with pkgs; [ + efitools erofs-utils just + openssl + sbsigntool self.packages.${system}.qemu-uefi-tpm squashfs-tools-ng ]; diff --git a/keys/DB.auth b/keys/DB.auth new file mode 100644 index 0000000000000000000000000000000000000000..d8ce304ab5dcd9eccabe35c4093e7498daa916b0 GIT binary patch literal 2092 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 R#Ufd#18J9|vvCq(=HKjtYQO*h literal 0 HcmV?d00001 diff --git a/keys/PK.auth b/keys/PK.auth new file mode 100644 index 0000000000000000000000000000000000000000..77ce10ffeb80f9ff109269b36782368b8064f20d GIT binary patch literal 2089 zcmaFK&M3yuWXb>or&xe2rjLAcFRk~wpYhJKYo$r8d06UlgC>@BOpJ_%{06*ioC$3n zjH%2lOpL4y2Hb3%T5TR}-+39?85cA$D;qR1%NsN?u`gg|Vq{_xNj-Vub(He?nuKui zNr&~H9BwoCycuK!R1YIJ&-99+7~=68~U@;MC;OqErQ^{QMGy0B-|1 zab6=+14APtLlXldQ==$xUSkl~0Lmq7Kog@9vZX+GGdD5vGZ-{6axpbAGBT{IyJIe( zlqi|8u_=B-@3w%K;U^bb*2SD=J-g-=)9>QU#_b0#K97=)+_Ix1R_f9T&Wl&qZa);c z<;a{VvraMEJdIejWKE^tr^;(rRlYr3booSYQ!cxAMTp@4kI~Ve)Ze z@_8aLk@D(JFD=#xpN}~ovc5d>r$zr^$u7SPTf0>|1QuO>DR04?Q63ZhFXpOgc$&0C z*^;7bsV#jXQ~E>CyTmUk`midU`N4!EEB4u4_*Au?W74PBzv@2S=sw`X-YgcPD8#ej z7f;=bpIZ~QSXV6he{k30qwa1Gm!DvaE7!5l&3_vIE?|n*x;pnG|5S4JS+*-G#1^G< zw;s&SWnyMzU|bw*5NIF^j0agh7BLnPjSUw!&y>G6cNfzl;hEA+6Bmd2?>3MJNh`BR z7>G4sSHKTaAk4`4pM}+c8Au@qJ20++!OqAq@5MEinFqi3tvlKD;uW8t$GOFx}d^)LQ&dnA*}$Z#}Z^ytQWG|8FjA)1}O!{<2x~b_3(h z?5&5^g#-vqxO44c&&Se_3Ws9zx+IkAZSq#LsVp$T(A_c%@={?3C~atHqk^d{)Ug*hg|ovaCPT zdHDWQwf_;D{BJ4U7i?Ov`ThZh-045w_{;47lW{$=VIyz<-hGB)sh6F-mTx%!ApEvv zMAK{|1zD|`M^iMpy)>$=)$g7@`Bq6f@~Xfk*SKHd9zX6o?c)ku@8VYJTwtJ>p3!vN z$^65YIpJ@Q+!JWGDc}>lEv)a}vQf4?U}5BerB9|T_iEp|S~N!cLyM8L(t^K3 dmnB>IIWNyw;y&~!rG2!}8ZER&3oX2b764tZUCjUh literal 0 HcmV?d00001 diff --git a/modules/image/builder.nix b/modules/image/builder.nix index f510fe7..65dc08a 100644 --- a/modules/image/builder.nix +++ b/modules/image/builder.nix @@ -76,6 +76,7 @@ let contents = { "/EFI/BOOT/BOOT${lib.toUpper efiArch}.EFI".source = "${pkgs.systemdUkify}/lib/systemd/boot/efi/systemd-boot${efiArch}.efi"; "/EFI/Linux/${config.system.boot.loader.ukiFile}".source = "${config.system.build.uki}/${config.system.boot.loader.ukiFile}"; + "/EFI/loader/keys/patos".source = ../../keys; "/EFI/memtest86/memtest86.efi".source = "${pkgs.memtest86plus}/memtest.efi"; "/loader/entries/patos-factory-reset.conf".source = pkgs.writeText "patos-factory-reset.conf" '' title Patos Factory Reset diff --git a/scripts/sbkeys b/scripts/sbkeys new file mode 100755 index 0000000..a24e215 --- /dev/null +++ b/scripts/sbkeys @@ -0,0 +1,154 @@ +#!/usr/bin/env bash +# Copyright (c) 2015 by Roderick W. Smith +# Copyright (c) 2020 Corey Hinshaw +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +[ -n "${DEBUG}" ] && set -x +set -e + +usage() { + cat < myGUID.txt + + cert-to-efi-sig-list -g ${GUID} PK.crt PK.esl + cert-to-efi-sig-list -g ${GUID} KEK.crt KEK.esl + cert-to-efi-sig-list -g ${GUID} DB.crt DB.esl + rm -f noPK.esl + touch noPK.esl + + sign-efi-sig-list \ + -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \ + -k PK.key -c PK.crt \ + PK PK.esl PK.auth + sign-efi-sig-list \ + -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \ + -k PK.key -c PK.crt \ + PK noPK.esl noPK.auth + sign-efi-sig-list \ + -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \ + -k PK.key -c PK.crt \ + KEK KEK.esl KEK.auth + sign-efi-sig-list \ + -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \ + -k KEK.key -c KEK.crt \ + DB DB.esl DB.auth + + chmod 0600 *.key +} + +generate_ms_db() { + msguid=77fa9abd-0359-4d32-bd60-28f4e78f784b + + msdb="MS_db.esl add_MS_db.auth" + for file in $msdb; do + if [ -f $file ]; then + echo "Microsoft signature lists already exist in $(pwd)" + return + fi + done + + wget --user-agent="Mozilla" https://www.microsoft.com/pkiops/certs/MicWinProPCA2011_2011-10-19.crt + wget --user-agent="Mozilla" https://www.microsoft.com/pkiops/certs/MicCorUEFCA2011_2011-06-27.crt + + sbsiglist --owner "$msguid" --type x509 --output MS_Win_db.esl MicWinProPCA2011_2011-10-19.crt + sbsiglist --owner "$msguid" --type x509 --output MS_UEFI_db.esl MicCorUEFCA2011_2011-06-27.crt + cat MS_Win_db.esl MS_UEFI_db.esl > MS_db.esl + sign-efi-sig-list -a -g "$msguid" -k KEK.key -c KEK.crt DB MS_db.esl add_MS_db.auth + + rm MS_Win_db.esl MS_UEFI_db.esl MicWinProPCA2011_2011-10-19.crt MicCorUEFCA2011_2011-06-27.crt +} + +mskeys=0 + +while getopts ":hm" opt; do + case $opt in + h) + usage + cat <&2 + usage >&2 + exit 1 + ;; + esac +done + +generate_keys +if [ $mskeys -eq 1 ]; then + generate_ms_db +fi diff --git a/scripts/sign-release.sh b/scripts/sign-release.sh new file mode 100755 index 0000000..0de9aed --- /dev/null +++ b/scripts/sign-release.sh @@ -0,0 +1,19 @@ +#! /usr/bin/env nix-shell +#! nix-shell -i bash -p efitools + +set -eux + +mkdir signed +cp -L result/* signed/ + +loopdev=$(sudo losetup -f) +sudo losetup -P "$loopdev" signed/*.img +sudo mount "${loopdev}p1" /mnt -t vfat + +sudo find signed/ /mnt/ -name "*.efi" -type f -exec sbsign --key <(echo "$DB_KEY") --cert <(echo "$DB_CRT") --output {} {} \; + +sudo mkdir -p /mnt/loader/keys/patos +sudo cp keys/*.auth /mnt/loader/keys/patos/ + +sudo umount /mnt +sudo losetup -d "$loopdev"