UKIFY(1) ukify UKIFY(1) ukify - (UKI) UEFI ukify [...] build ukify [...] genkey ukify [...] inspect ... ukify ( initrd systemd-stub(7) UEFI stub) (UKI)[1] UAPI.5 -- PE . UKI stub . UKI (firmware) . qemu[2] UKI " " . ukify UKI . build . ukify (SecureBoot) PCR genkey . ukify inspect . : build (UKI). build Linux=/--linux= Initrd=/--initrd=. Initrd= --initrd= . UKI . Microcode=/--microcode= Cmdline=/--cmdline= OSRelease=/--os-release= DeviceTree=/--devicetree= DeviceTreeAuto=/--devicetree-auto= HWIDs=/--hwids= Splash=/--splash= PCRPKey=/--pcrpkey= Uname=/--uname= SBAT=/--sbat= --section= . ukify PE . PCR PCRPrivateKey=/--pcr-private-key= PCRPublicKey=/--pcr-public-key= PCRCertificate=/--pcr-certificate= PCR initrd UKI. systemd-measure(1) . PCR . Phases=/--phases=. systemd-measure. PCRPrivateKey=/--pcr-private-key= PCRPublicKey=/--pcr-public-key= PCRCertificate=/--pcr-certificate= Phases=/--phases= . . --phases= --pcr-private-key= n n. . PCRPrivateKey= PCRPublicKey= Phases= . SigningEngine=/--signing-engine= SigningProvider=/--signing-provider= openssl(1) (URIs) X.509 OpenSSL . (SecureBoot) SecureBootPrivateKey=/--secureboot-private-key= PE UKI . systemd-boot(7). stub ".sbat" UKI UKI Shim. SBAT Shim[3]. genkey PCR (SecureBoot). build . PCRPrivateKey=/--pcr-private-key= PCRPublicKey=/--pcr-public-key= SecureBootPrivateKey=/--secureboot-private-key= . . inspect . --all . --section= . UKI. sha256 . . -j/--json= --section=. UKI: llvm-objdump(1) -p pe-inspect. ( =) ( --=). . . . . --config= ukify : /etc/systemd/ukify.conf /run/systemd/ukify.conf /usr/local/lib/systemd/ukify.conf /usr/lib/systemd/ukify.conf . ukify . LINUX INITRD Linux= Initrd= . initrd PE . (microcode) initrd . : --config= . . . 254. --measure --no-measure systemd-measure(1) PCR . (false). 253. --policy-digest --no-policy-digest systemd-measure(1) TPM2 . PCR . (false). 258. --section=:|@ --section=:text|binary[@] inspect . "". "@" . . () ".linux" . inspect . ( ). "text" . . . 253. --join-profile= PE . ukify. PCR. PE UKI PE UKI . UKI . PE UKI ".text" . 257. --sign-profile= ukify PCR . --join-profile= . PCR . 258. --join-pcrsig= --pcrsig=|@ --join-pcrsig= PE UKI . --pcrsig= pcrsig JSON . UKI. ukify pcrsig JSON UKI. --policy-digest UKI TPM2 . 258. --tools= . ukify $PATH . 253. --output=_ . LINUX ".unsigned.efi" ".signed.efi" (SecureBoot). 253. --summary . . 254. --all ( inspect). 255. --json JSON ( inspect). 255. -h --help . --version . [UKI] Linux=LINUX --linux=LINUX . 254. OSRelease=|@ --os-release=|@ ( ".osrel"). "@" . os-release(5) . ".osrel" UKI ( UKI kernel-install bootctl). 253. Cmdline=|@ --cmdline=|@ ( ".cmdline"). "@" . . 253. Initrd=INITRD... --initrd=LINUX initrd. . initrd initrd . 254. Microcode=UCODE --microcode=UCODE initrd . . 256. Splash= --splash= ( ".splash"). BMP. . 253. DeviceTree= --devicetree= ( ".dtb"). DeviceTree . . 253. DeviceTreeAuto=... --devicetree-auto= DeviceTree . . ".dtbauto" . 257. HWIDs= --hwids= ( ".hwids"). HWID JSON. JSON "name" "compatible" "hwids". "name" "compatible" "hwids" UUID CHIDs/HWIDs. : { "type": "devicetree", "name": "Example Laptop 16 Gen 7", "compatible": "example,laptop-16-g7", "hwids": [ "5dc05bf4-01f6-4089-b464-a08c47ea9295", "3e3f8f3c-2003-46f2-811c-85554f7d5952" ] } "Example Laptop 16 Gen 7" "" ( ) "example,laptop-16-g7" "" ( ) "hwids" CHIDs/HWIDs ( fwupdtool hwids). "/usr/lib/systemd/boot/hwids/[EFI_ARCH]/" ( ) . DeviceTrees . 257. Uname= --uname= ( uname -r ".uname"). . . . 253. SBAT=|@ --sbat=|@ SBAT UKI . SBAT UKI DBX/MOKX. uki,1,UKI,uki,1,https://uapi-group.org/specifications/specs/unified_kernel_image/ UKIs uki-addon,1,UKI Addon,addon,1,https://www.freedesktop.org/software/systemd/man/latest/systemd-stub.html . SBAT Shim[3]. 254. PCRPKey= --pcrpkey= ".pcrpkey". PCRPublicKey=/--pcr-public-key= PCRCertificate=/--pcr-certificate= . . 253. Profile= --profile= UKI ".profile". UKI --join-profile= UKI . 257. PCRBanks= --pcr-banks= PCR . ("sha1" "sha256" "sha384" "sha512") . 253. SecureBootSigningTool= --signtool= "sbsign" "pesign" "systemd-sbsign". . "sbsign". 254. SecureBootPrivateKey=SB_KEY, --secureboot-private-key=SB_KEY . SigningEngine=/--signing-engine= SigningProvider=/--signing-provider= . SecureBootSigningTool=sbsign/--signtool=sbsign SecureBootSigningTool=systemd-sbsign/--signtool=systemd-sbsign. 253. SecureBootCertificate=SB_CERT, --secureboot-certificate=SB_CERT . SigningEngine=/--signing-engine= SigningProvider=/--signing-provider= . SecureBootSigningTool=sbsign/--signtool=sbsign SecureBootSigningTool=systemd-sbsign/--signtool=systemd-sbsign. 253. SecureBootCertificateDir=SB_PATH, --secureboot-certificate-dir=SB_PATH nss . SecureBootSigningTool=pesign/--signtool=pesign. /etc/pki/pesign. 254. SecureBootCertificateName=SB_CERTNAME, --secureboot-certificate-name=SB_CERTNAME nss . SecureBootSigningTool=pesign/--signtool=pesign. 254. SecureBootCertificateValidity=DAYS, --secureboot-certificate-validity=DAYS () genkey. 3650 10 . 254. SigningEngine=ENGINE, --signing-engine=ENGINE OpenSSL PCR openssl-engine(1). 253. SigningProvider=PROVIDER, --signing-provider=PROVIDER OpenSSL PCR provider(7). systemd-sbsign . 257. CertificateProvider=PROVIDER, --certificate-provider=PROVIDER OpenSSL PCR provider(7). systemd-sbsign . 257. SignKernel=BOOL, --sign-kernel, --no-sign-kernel . SecureBootPrivateKey=/--secureboot-private-key= . SignKernel=/--sign-kernel . 253. [PCRSignature:] . . . PCRPrivateKey= --pcr-private-key= PCR. . 253. PCRPublicKey= --pcr-public-key= PCR. --pcr-private-key=. . --pcr-private-key=. --pcr-certificate=. 253. PCRCertificate= --pcr-certificate= X.509 PCR. --pcr-private-key=. . --pcr-private-key=. --pcr-public-key=. 258. Phases= --phases= . . systemd-measure(1). --pcr-private-key=. 253. 1. $ ukify build \ --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \ --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img \ --cmdline='quiet rw' UKI ./vmlinuz.unsigned.efi. Example 2. Direct kernel boot in a virtual machine qemu[2] OVMF[4] ( UEFI ) -kernel UKI. : qemu-kvm -drive if=pflash,format=qcow2,readonly=on,file=/usr/share/edk2/ovmf/OVMF_CODE_4M.qcow2 -kernel ./vmlinuz.unsigned.efi [ ... ] ( .) -drive . 3. $ ukify build \ --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \ --initrd=early_cpio \ --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img \ --sbat='sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md uki.author.myimage,1,UKI for System,uki.author.myimage,1,https://uapi-group.org/specifications/specs/unified_kernel_image/' \ --pcr-private-key=tpm2-pcr-initrd-private-key.pem \ --pcr-public-key=tpm2-pcr-initrd-public-key.pem \ --phases='enter-initrd' \ --pcr-private-key=tpm2-pcr-private-key-system.pem \ --pcr-public-key=tpm2-pcr-public-key-system.pem \ --phases='enter-initrd:leave-initrd enter-initrd:leave-initrd:sysinit \ enter-initrd:leave-initrd:sysinit:ready' \ --pcr-banks=sha384,sha512 \ --secureboot-private-key=secureboot-private-key.pem \ --secureboot-certificate=secureboot-certificate.pem \ --sign-kernel \ --cmdline='quiet rw rhgb' UKI ./vmlinuz.signed.efi. initrd early_cpio initramfs-6.0.9-300.fc37.x86_64.img. ".pcrsig" initrd ( enter-initrd) tpm2-pcr-initrd-private-key.pem ( leave-initrd sysinit ready) tpm2-pcr-private-key-system.pem. secureboot-private-key.pem. 4. : $ cat ukify.conf [UKI] Initrd=early_cpio Cmdline=quiet rw rhgb SecureBootPrivateKey=secureboot-private-key.pem SecureBootCertificate=secureboot-certificate.pem SignKernel=yes PCRBanks=sha384,sha512 [PCRSignature:initrd] PCRPrivateKey=tpm2-pcr-initrd-private-key.pem PCRPublicKey=tpm2-pcr-initrd-public-key.pem Phases=enter-initrd [PCRSignature:system] PCRPrivateKey=tpm2-pcr-private-key-system.pem PCRPublicKey=tpm2-pcr-public-key-system.pem Phases=enter-initrd:leave-initrd enter-initrd:leave-initrd:sysinit enter-initrd:leave-initrd:sysinit:ready $ ukify -c ukify.conf build \ --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \ --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img "initrd" (early_cpio) (initramfs-6.0.9-300.fc37.x86_64.img) . initrd (microcode) initrd . 5. PE ukify build \ --secureboot-private-key=secureboot-private-key.pem \ --secureboot-certificate=secureboot-certificate.pem \ --cmdline='debug' \ --sbat='sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md uki-addon.author,1,UKI Addon for System,uki-addon.author,1,https://www.freedesktop.org/software/systemd/man/systemd-stub.html' --output=debug.addon.efi PE "debug" SBAT . 6. : # cat >/etc/kernel/uki.conf < : # ukify genkey --config=/etc/kernel/uki.conf Writing SecureBoot private key to /etc/kernel/secureboot-private-key.pem Writing SecureBoot certificate to /etc/kernel/secureboot-certificate.pem Writing private key for PCR signing to /etc/systemd/tpm2-pcr-initrd-private-key.pem Writing public key for PCR signing to /etc/systemd/tpm2-pcr-initrd-public-key.pem Writing private key for PCR signing to /etc/systemd/tpm2-pcr-private-key-system.pem Writing public key for PCR signing to /etc/systemd/tpm2-pcr-public-key-system.pem ( /etc/kernel/.) (ukify build --config=/etc/kernel/uki.conf) . kernel-install(8) 60-ukify.install /etc/kernel/uki.conf UKI kernel-install . 7. UKI : $ ukify build \ --profile='TITLE=Base' \ --output=profile0.efi (@1): $ ukify build \ --profile='TITLE=Boot into Storage Target Mode ID=storagetm' \ --cmdline='quiet rw rd.systemd.unit=storage-target-mode.target' \ --output=profile1.efi (@2): $ ukify build \ --profile='TITLE=Factory Reset ID=factory-reset' \ --cmdline='quiet rw systemd.unit=factory-reset.target' \ --output=profile2.efi UKI : $ ukify build \ --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \ --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img \ --cmdline='quiet rw' \ --join-profile=profile0.efi \ --join-profile=profile1.efi \ --join-profile=profile2.efi \ --output=base.efi UKI base-with-profile-0-1-2.efi . 8. pcrsig UKI PCR JSON: $ ukify build \ --linux=/lib/modules/6.0.9-300.fc37.x86_64/vmlinuz \ --initrd=/some/path/initramfs-6.0.9-300.fc37.x86_64.img \ --cmdline='quiet rw' \ --pcr-public-key=tpm2-pcr-initrd-public-key.pem \ --policy-digest \ --json=short \ --output=base.efi >base.pcrs PCR JSON: #!/usr/bin/python3 import base64, json, subprocess priv_key = '/home/zbyszek/src/systemd/tpm2-pcr-private.pem' base_file = 'base.pcrs' base = json.load(open(base_file)) for bank,policies in base.items(): for policy in policies: pol = base64.b16decode(policy['pol'].upper()) call = subprocess.run(['openssl', 'dgst', f'-{bank}', '-sign', priv_key], input=pol, check=True, capture_output=True) sig = base64.b64encode(call.stdout).decode() policy['sig'] = sig print(json.dumps(base)) JSON UKI: $ ukify build \ --join-pcrsig=base.efi \ --pcrsig=@base.pcrs \ --json=short \ --output=base-signed.efi UKI base-signed.efi PCR . systemd(1) systemd-stub(7) systemd-boot(7) systemd-measure(1) systemd-pcrphase.service(8) 1. (UKI) UAPI.5 https://uapi-group.org/specifications/specs/unified_kernel_image/ 2. qemu https://www.qemu.org/docs/master/ 3. Shim https://github.com/rhboot/shim/blob/main/SBAT.md 4. OVMF https://www.linux-kvm.org/downloads/lersek/ovmf-whitepaper-c770f8c.txt 3 . . : . systemd 260.1 UKIFY(1)