image: support shim usage for uefi and disk

Fixes #5230
This commit is contained in:
Alexander Boettcher 2024-05-17 15:12:00 +02:00 committed by Norman Feske
parent 78a6d2bd0c
commit a3a84b25e8
5 changed files with 118 additions and 7 deletions

View File

@ -1 +1 @@
80d41dfe8a1d8d8a80c51f446553b7d28c3ce395
8c6a21b5e837a9491ebcb21611f5f865411544f5

View File

@ -3,10 +3,11 @@ VERSION := git
DOWNLOADS := g2fg.git
URL(g2fg) := https://github.com/alex-ab/g2fg.git
REV(g2fg) := 0d94ee016a3a4f991f502d04ef59e7d0d8e75346
REV(g2fg) := 95c79d8ca590eefaab7297c7a631125a64973266
DIR(g2fg) := boot
default: $(DOWNLOADS)
$(VERBOSE)tar -C boot -xJf boot/grub2.tar.xz
$(VERBOSE)unxz -kf boot/grub2-head.img.xz
$(VERBOSE)unxz -kf boot/grub2-head-big.img.xz
$(VERBOSE)unxz -kf boot/font.pf2.xz

View File

@ -1,15 +1,53 @@
##
# Create disk image with contents of the run directory
#
# \param --image-disk-size disk size in MiB
# \param --image-disk_size disk size in MiB
# \param --image-disk_shim nickname of certificate to use to sign GRUB2
#
source [genode_dir]/tool/run/grub2.inc
source [genode_dir]/tool/run/shim.inc
proc image_disk_size { } { return [get_cmd_arg --image-disk-size 0] }
proc image_disk_size { } { return [get_cmd_arg --image-disk_size 0] }
proc image_disk_shim { } { return [get_cmd_arg --image-disk_shim ""] }
proc prepare_grub2_files { } {
set sgdisk [installed_command sgdisk]
set mcopy [installed_command mcopy]
# make copy of template grub2 header, for signing use the larger header
if {[image_disk_shim] == ""} {
exec cp [get_grub2_dir]/boot/grub2-head.img [run_dir].header
} else {
exec cp [get_grub2_dir]/boot/grub2-head-big.img [run_dir].header
}
set efi_partition_info [exec $sgdisk -i 2 [run_dir].header]
set efi_first_sector [regexp -all -line -inline {First sector: ([0-9]+)} $efi_partition_info]
set efi_first_sector [lindex $efi_first_sector 1]
set efi_partition_offset [expr $efi_first_sector * 512]
exec mkdir -p [run_dir]/tmp/efi/boot
if {[image_disk_shim] == ""} {
# use unsigned efi binaries
exec cp [get_grub2_dir]/boot/grub2/grub2_32.efi [run_dir]/tmp/efi/boot/bootia32.efi
exec cp [get_grub2_dir]/boot/grub2/grub2_64.efi [run_dir]/tmp/efi/boot/bootx64.efi
} else {
# sign grub2 efi binary
setup_shim_and_sign_grub2 [image_disk_shim] [run_dir]/tmp/efi/boot
}
foreach file [exec ls [run_dir]/tmp/efi/boot] {
exec $mcopy -i [run_dir].header@@$efi_partition_offset -s [run_dir]/tmp/efi/boot/$file ::efi/boot/$file
}
exec rm -rf [run_dir]/tmp
}
##
# Create disk image with the content of the run directory
#
@ -17,8 +55,7 @@ proc run_image { } {
set sgdisk [installed_command sgdisk]
# make copy of template grub2 header image
exec cp [get_grub2_dir]/boot/grub2-head.img [run_dir].header
prepare_grub2_files
# remove template partition
exec $sgdisk --delete=3 [run_dir].header

View File

@ -1,12 +1,15 @@
source [genode_dir]/tool/run/grub2.inc
source [genode_dir]/tool/run/shim.inc
##
# Create GPT disk image with UEFI boot loaders and content of the run directory
#
# \param --image-uefi-size disk size in MiB
# \param --image-uefi_size disk size in MiB
# \param --image-disk_shim nickname of certificate to use to sign GRUB2
#
proc image_uefi_size { } { return [get_cmd_arg --image-uefi_size 0] }
proc image_uefi_shim { } { return [get_cmd_arg --image-uefi_shim ""] }
##
@ -45,6 +48,11 @@ proc install_uefi_bootloader_to_run_dir { } {
exec mkdir -p [run_dir]/efi/boot
exec cp [get_grub2_dir]/boot/grub2/grub2_32.efi [run_dir]/efi/boot/bootia32.efi
exec cp [get_grub2_dir]/boot/grub2/grub2_64.efi [run_dir]/efi/boot/bootx64.efi
if {[image_uefi_shim] != ""} {
setup_shim_and_sign_grub2 [image_uefi_shim] [run_dir]/efi/boot
}
exec mkdir -p [run_dir]/boot/grub
exec cp [genode_dir]/tool/boot/bender [run_dir]/boot/bender

65
tool/run/shim.inc Normal file
View File

@ -0,0 +1,65 @@
proc setup_shim_and_sign_grub2 { nickname target_dir } {
set host_shim_path "/usr/lib/shim"
set check_binaries "mmx64.efi shimx64.efi"
set host_binaries ""
foreach binary $check_binaries {
set filename "$host_shim_path/$binary"
if {[file exists "$filename.signed"]} {
lappend host_binaries $binary.signed
continue
}
if {[file exists "$filename"]} {
lappend host_binaries $binary
continue
}
puts "Error: shim binary file $host_shim_path/$binary missing"
puts "shim packages of your distribution are required"
exit -1
}
foreach binary $host_binaries {
catch {exec [installed_command sbverify] --list $host_shim_path/$binary} result
puts "using $host_shim_path/$binary "
puts $result
if {[regexp "No signature table present" $result]} {
puts "$binary has no signatures attached"
exit -1
}
}
exec cp $host_shim_path/[lindex $host_binaries 0] $target_dir/mmx64.efi
exec cp $host_shim_path/[lindex $host_binaries 1] $target_dir/bootx64.efi
puts "Export certificate for nickname '$nickname' to $target_dir/$nickname.cer"
try {
exec [installed_command sudo] [installed_command certutil] \
-d /etc/pki/pesign -n $nickname -Lr >$target_dir/$nickname.cer
} on error { } {
puts ""
puts "Certificate with nickname '$nickname' not found!"
puts ""
puts "Notes for creating a certificate:"
puts ""
puts " sudo efikeygen --self-sign --common-name 'CN=YOUR COMPANY' --nickname '$nickname'"
puts ""
puts " Hint: newer efikeygen version may require --kernel"
puts ""
puts " The public and private keys are stored in the /etc/pki/pesign/ directory."
puts " For more detailed information please consider documentation of efikeygen."
puts ""
exit -1
}
puts "Invoking 'pesign' for grub2 efi image"
exec [installed_command sudo] [installed_command pesign] \
--in=[get_grub2_dir]/boot/grub2/grub2_64.efi \
--out=$target_dir/grubx64.efi \
-c $nickname --sign
}