diff --git a/grub2-s390x-secure-execution-support.patch b/grub2-s390x-secure-execution-support.patch new file mode 100644 index 0000000..b6b4244 --- /dev/null +++ b/grub2-s390x-secure-execution-support.patch @@ -0,0 +1,361 @@ +From 023b569648eece7a7fe2ae38d731185a1f2abeb5 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Fri, 23 Aug 2024 09:57:03 +0800 +Subject: [PATCH] s390x: add Secure Execution support + +To support Secure Execution, 2 extra files and 5 environment variables +are introduced. + +- se-parm.conf.in + The template file for the kernel parameter to be used by 'genprotimg' + +- se-zipl2grub.conf.in + The template file of zipl.conf for secure execution + +- SUSE_S390_SE_ENABLE + The variable to enable s390x Secure Execution + +- SUSE_S390_SE_HOST_KEY + The variable to set the file list to the host key documents + +- SUSE_S390_SE_HOST_KEY_SIGNING_KEY + The variable to set the file list to the signing key certificates + +- SUSE_S390_SE_CA_CERT + The variable to set the file path to the CA certificate + +- SUSE_S390_SE_REVOCATION_LIST + The variable to set the file list of the host key revocation lists + +When enabling Secure Execution, the zipl initrd is generated in +"/dev/shm/zipl-se" instead of "/boot/zipl" because the zipl initrd +may contain the LUKS key for the encrypted root partition. Then, +'genprotimg' stores the encrypted image, a combination of the zipl +kernel, zipl initrd, and the kernel parameters, as +"/boot/secure-linux-$version". To make the image ready for zipl, +it is copied to "/boot/zipl/secure-linux-$version" and linked to +"/boot/zipl/secure-linux" which is expected by the zipl config. +--- + Makefile.util.def | 17 +++ + util/s390x/se-parm.conf.in | 1 + + util/s390x/se-zipl2grub.conf.in | 17 +++ + util/s390x/zipl2grub.pl.in | 202 ++++++++++++++++++++++++++------ + 4 files changed, 198 insertions(+), 39 deletions(-) + create mode 100644 util/s390x/se-parm.conf.in + create mode 100644 util/s390x/se-zipl2grub.conf.in + +diff --git a/Makefile.util.def b/Makefile.util.def +index ffedea24a..722542933 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -796,6 +796,23 @@ data = { + emu_condition = COND_s390x; + }; + ++data = { ++ name = se-parm.conf.in; ++ common = util/s390x/se-parm.conf.in; ++ installdir = grubconf; ++ enable = emu; ++ emu_condition = COND_s390x; ++}; ++ ++data = { ++ name = se-zipl2grub.conf.in; ++ common = util/s390x/se-zipl2grub.conf.in; ++ installdir = grubconf; ++ enable = emu; ++ emu_condition = COND_s390x; ++}; ++ ++ + script = { + name = dracut-module-setup.sh; + common = util/s390x/dracut-module-setup.sh.in; +diff --git a/util/s390x/se-parm.conf.in b/util/s390x/se-parm.conf.in +new file mode 100644 +index 000000000..63959b753 +--- /dev/null ++++ b/util/s390x/se-parm.conf.in +@@ -0,0 +1 @@ ++root=@GRUB_DEVICE@ @GRUB_EMU_CONMODE@ @GRUB_CMDLINE_LINUX@ @GRUB_CMDLINE_LINUX_DEFAULT@ initgrub quiet splash=silent plymouth.enable=0 +diff --git a/util/s390x/se-zipl2grub.conf.in b/util/s390x/se-zipl2grub.conf.in +new file mode 100644 +index 000000000..e9feeb9b6 +--- /dev/null ++++ b/util/s390x/se-zipl2grub.conf.in +@@ -0,0 +1,17 @@ ++## This is the template for '@zipldir@/config' and is subject to ++## rpm's %config file handling in case of grub2-s390x-emu package update. ++ ++[defaultboot] ++defaultmenu = menu ++ ++[grub2-secure] ++ target = @zipldir@ ++ image = @zipldir@/secure-linux ++ ++:menu ++ target = @zipldir@ ++ timeout = 60 ++ default = 1 ++ prompt = 0 ++ secure = @SUSE_SECURE_BOOT@ ++ 1 = grub2-secure +diff --git a/util/s390x/zipl2grub.pl.in b/util/s390x/zipl2grub.pl.in +index 46b902209..930ecc4cd 100644 +--- a/util/s390x/zipl2grub.pl.in ++++ b/util/s390x/zipl2grub.pl.in +@@ -12,10 +12,19 @@ my $definitrd = "/boot/initrd"; + my $Image = "$defimage"; + my $previous = ".prev"; + my $zipldir = ""; ++my $imgdir = ""; + my $running = ""; + my $refresh = 1; # needs to default to "on" until most bugs are shaken out! + my $force = 0; + my $hostonly = 1; ++my $secure_exec = 0; ++my $sehostkey = ""; ++my $sesignkey = ""; ++my $secacert = ""; ++my $serevoke = ""; ++my $separm= ""; ++my $se_zipconf = '@sysconfdir@/default/se-zipl2grub.conf.in'; ++my $se_kernparm = '@sysconfdir@/default/se-parm.conf.in'; + my $verbose = 0; + my $debug = 0; + my $miss = 0; +@@ -183,6 +192,55 @@ sub ChkInitrd($$) { + return $found; + } + ++sub GenSEImage($$$$) { ++ my( $kernel, $initrd, $parm, $out_image) = @_; ++ ++ # genprotimg -i \ ++ # -r > \ ++ # -p \ ++ # --host-key-document \ ++ # --cert ibm-z-host-key-signing.crt \ ++ # --cert DigiCertCA.crt \ ++ # --crl revocation.crl \ ++ # -o /boot/zipl/secure-linux ++ ++ my @C = ( "genprotimg", "-i", $kernel, "-r", $initrd, "-p", $parm, ++ "--cert", $secacert); ++ ++ # Handle the host key document list ++ if ($sehostkey) { ++ my @sehostkey_list = split('[,\s]+', $sehostkey); ++ my $hkd; ++ foreach $hkd (@sehostkey_list) { ++ Panic( 1, "$C: host key document '$hkd' not readable!?\n") unless (-r $hkd); ++ push @C, "--host-key-document", $hkd; ++ } ++ } ++ ++ # Handle the signing key list ++ if ($sesignkey) { ++ my @sesignkey_list = split('[,\s]+', $sesignkey); ++ my $signkey; ++ foreach $signkey (@sesignkey_list) { ++ Panic( 1, "$C: signing key '$signkey' not readable!?\n") unless (-r $signkey); ++ push @C, "--cert", $signkey; ++ } ++ } ++ ++ # Handle the revocation list files ++ if ($serevoke) { ++ my @serevoke_list = split('[,\s]+', $serevoke); ++ my $crl; ++ foreach $crl (@serevoke_list) { ++ Panic( 1, "$C: revocation list '$crl' not readable!?\n") unless (-r $crl); ++ push @C, "--crl", $crl; ++ } ++ } ++ ++ push @C, "-o", "$out_image"; ++ System( @C); ++} ++ + sub Usage($) { + my @cat = ("", + "Parameter error.", +@@ -401,49 +459,91 @@ if ( $debug && $verbose > 2 ) { + } + } + +-open( IN, "< $in") || +- Panic( 1, "$C: Failed to open 'zipl.conf' template: $!.\n"); +-while ( ) { +- Info( 4, "$.. <$_$.. >"); +- if ( $. == 1 && m{^## This} ) { +- $_ = "## This file was written by 'grub2-install/$C'\n" . +- "## filling '$in' as template\n"; +- } elsif ( $. == 2 && m{^## rpm's} ) { +- $_ = "## with values from '$default'.\n" . +- "## In-place modifications will eventually go missing!\n"; ++# ++# s390x Secure Execution variables ++# ++# SUSE_S390_SE_ENABLE: enabling s390x Secure Execution ++# SUSE_S390_SE_HOST_KEY: the host key ++# SUSE_S390_SE_HOST_KEY_SIGNING_KEY: the signing key of the host key ++# SUSE_S390_SE_CA_CERT: the CA certificate ++# SUSE_S390_SE_REVOCATION_LIST: the revocation list ++# ++if ( -r $C{SUSE_S390_SE_HOST_KEY} && -r $C{SUSE_S390_SE_HOST_KEY_SIGNING_KEY} && ++ -r $C{SUSE_S390_SE_CA_CERT}) { ++ ++ $sehostkey = $C{SUSE_S390_SE_HOST_KEY}; ++ $sesignkey = $C{SUSE_S390_SE_HOST_KEY_SIGNING_KEY}; ++ $secacert = $C{SUSE_S390_SE_CA_CERT}; ++ ++ $serevoke = $C{SUSE_S390_SE_REVOCATION_LIST} if $C{SUSE_S390_SE_REVOCATION_LIST}; ++ ++ if ( $C{SUSE_S390_SE_ENABLE} =~ m{^(yes|true|1)$} ) { ++ $secure_exec = 1; + } +- while ( m{\@([^\@\s]+)\@} ) { +- my $k = $1; +- my $v; +- if ( exists( $C{$k}) ) { +- $v = $C{$k}; +- } elsif ( exists( $Mandatory{$k}) ) { +- $v = "$k"; +- $miss++; +- } else { +- $v = ""; ++} ++ ++sub MkConfig($$) { ++ my( $template, $name) = @_; ++ open( IN, "< $template") || ++ Panic( 1, "$C: Failed to open '$name' template: $!.\n"); ++ while ( ) { ++ Info( 4, "$.. <$_$.. >"); ++ if ( $. == 1 && m{^## This} ) { ++ $_ = "## This file was written by 'grub2-install/$C'\n" . ++ "## filling '$template' as template\n"; ++ } elsif ( $. == 2 && m{^## rpm's} ) { ++ $_ = "## with values from '$default'.\n" . ++ "## In-place modifications will eventually go missing!\n"; + } +- if ($k eq "GRUB_DEVICE") { +- if (($v !~ /^UUID/ && ! -e $v) || +- (exists( $C{SUSE_REMOVE_LINUX_ROOT_PARAM}) && +- $C{SUSE_REMOVE_LINUX_ROOT_PARAM} eq "true")) { +- s{root=\@$k\@}{}g; +- next; ++ while ( m{\@([^\@\s]+)\@} ) { ++ my $k = $1; ++ my $v; ++ if ( exists( $C{$k}) ) { ++ $v = $C{$k}; ++ } elsif ( exists( $Mandatory{$k}) ) { ++ $v = "$k"; ++ $miss++; ++ } else { ++ $v = ""; ++ } ++ if ($k eq "GRUB_DEVICE") { ++ if (($v !~ /^UUID/ && ! -e $v) || ++ (exists( $C{SUSE_REMOVE_LINUX_ROOT_PARAM}) && ++ $C{SUSE_REMOVE_LINUX_ROOT_PARAM} eq "true")) { ++ s{root=\@$k\@}{}g; ++ next; ++ } + } ++ s{\@$k\@}{$v}g; + } +- s{\@$k\@}{$v}g; ++ Info( 3, $_); ++ $cfg .= $_; ++ } ++ if ( $miss ) { ++ Info( 1, "Partially filled config:\n===\n$cfg===\n"); ++ Panic( 1, "$C: '$name' template could not be filled. \n"); + } +- Info( 3, $_); +- $cfg .= $_; + } +-if ( $miss ) { +- Info( 1, "Partially filled config:\n===\n$cfg===\n"); +- Panic( 1, "$C: 'zipl.conf' template could not be filled. \n"); ++ ++if ( $secure_exec ) { ++ # create the kernel parameter file ++ MkConfig($se_kernparm, "parm.conf"); ++ $separm = $cfg; ++ ++ # clean up $cfg to reuse the variable for zipl.conf ++ $cfg = ""; ++ MkConfig($se_zipconf, "zipl.conf"); ++ $imgdir = "/dev/shm/zipl-se"; ++ ++ mkdir ($imgdir, 0700) unless (-d $imgdir); ++} else { ++ MkConfig($in, "zipl.conf"); ++ $imgdir = $zipldir; + } + + # copy out kernel and initrd +-my $ziplimage = "$zipldir/image"; +-my $ziplinitrd = "$zipldir/initrd"; ++my $ziplimage = "$imgdir/image"; ++my $ziplinitrd = "$imgdir/initrd"; + + if ( ! $running && ! $force ) { + chomp( $running = qx{uname -r}); +@@ -478,18 +578,42 @@ my $initrd = "initrd-$version"; + $image = "image-$version"; + + if ( ! -r $ziplimage || ! -r $ziplinitrd || $refresh ) { +- BootCopy( $Image, $image, $zipldir, "image"); +- BootCopy( $initrd, $initrd, $zipldir, "initrd") ++ BootCopy( $Image, $image, $imgdir, "image"); ++ BootCopy( $initrd, $initrd, $imgdir, "initrd") + if (-r "/boot/$initrd" && ! exists( $fsdev{"/boot"})); + } +-if ( $refresh || ChkInitrd( $zipldir, "initrd") <= 0 ) { +- MkInitrd( $initrd, $zipldir, $version); ++if ( $refresh || ChkInitrd( $imgdir, "initrd") <= 0 ) { ++ MkInitrd( $initrd, $imgdir, $version); + } +-if ( ChkInitrd( $zipldir, "initrd") == 0 ) { ++if ( ChkInitrd( $imgdir, "initrd") == 0 ) { + Info( 0, "$C: dracut does not work as expected! Help needed!\n"); + $miss++; + } + ++if ( $secure_exec ) { ++ my $seimage = "secure-linux-$version"; ++ my $parmconf = "$imgdir/parm.conf"; ++ my $bootseimg = "/boot/$seimage"; ++ ++ # write parm.conf ++ if ( ! $debug ) { ++ open( OUT, "> $parmconf") || die; ++ print( OUT $separm) || die; ++ close( OUT); ++ } else { ++ print( STDERR $separm); ++ } ++ ++ # Create the secure-execution image in /boot first ++ GenSEImage( $ziplimage, $ziplinitrd, $parmconf, $bootseimg ); ++ ++ # check /boot/$seimage ++ Panic( 1, "$C: Secure Image '$bootseimg' not readable!?\n") unless (-r "$bootseimg"); ++ ++ # copy /boot/$seimage to $zipldir ++ BootCopy($seimage, $seimage, $zipldir, "secure-linux"); ++} ++ + # write zipl config file + my $ziplconf = "$zipldir/config"; + $cfg =~ s{#@}{}g if ( -r "$ziplimage$previous" && -r "$ziplinitrd$previous" ); +-- +2.43.0 + diff --git a/grub2-s390x-set-hostonly.patch b/grub2-s390x-set-hostonly.patch index 63b5679..89b376e 100644 --- a/grub2-s390x-set-hostonly.patch +++ b/grub2-s390x-set-hostonly.patch @@ -1,3 +1,24 @@ +From 2a86e5f9e3abb622d2e16ee5f05b1ba2df1f756d Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Tue, 6 Aug 2024 14:46:17 +0800 +Subject: [PATCH] zipl2grub.pl.in: add the switch for hostonly/no-hostonly + +Since the kiwi build environment could be very different from the real +system environment, it may cause some problem to build the zipl initrd +with '--hostonly' since some critical files could be omitted +accidentally. To avoid the potential issues, this commit introduces a +variable, SUSE_S390_DRACUT_HOSTONLY, as the switch to use hostonly or +no-hostonly for the zipl initrd. By default, it's detected automatically +by tracing the root partition to the root block device. If the root +block device is a loop device, then it's likely to be a build +environment, and then '--no-hostonly' will be used to create the zipl +initrd. + +Signed-off-by: Gary Lin +--- + util/s390x/zipl2grub.pl.in | 26 +++++++++++++++++++++++++- + 1 file changed, 25 insertions(+), 1 deletion(-) + diff --git a/util/s390x/zipl2grub.pl.in b/util/s390x/zipl2grub.pl.in index f4f997100..46b902209 100644 --- a/util/s390x/zipl2grub.pl.in @@ -50,3 +71,6 @@ index f4f997100..46b902209 100644 if ( $debug && $verbose > 2 ) { foreach ( sort( keys( %C)) ) { printf( "%s=\"%s\"\n", $_, $C{$_}); +-- +2.35.3 + diff --git a/grub2.changes b/grub2.changes index ad7584f..b7b101d 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Fri Nov 29 05:56:22 UTC 2024 - Gary Ching-Pang Lin + +- Support s390x Secure Execution (jsc#PED-9531) + * grub2-s390x-secure-execution-support.patch +- Update grub2-s390x-set-hostonly.patch to add the patch header + and the description + ------------------------------------------------------------------- Wed Nov 13 01:09:47 UTC 2024 - Michael Chang diff --git a/grub2.spec b/grub2.spec index 1128119..86f8b3a 100644 --- a/grub2.spec +++ b/grub2.spec @@ -415,6 +415,7 @@ Patch233: 0001-kern-ieee1275-init-Add-IEEE-1275-Radix-support-for-K.patch Patch234: 0001-cli_lock-Add-build-option-to-block-command-line-inte.patch Patch235: 0002-Requiring-authentication-after-tpm-unlock-for-CLI-ac.patch Patch236: 0001-kern-main-Fix-cmdpath-in-root-directory.patch +Patch237: grub2-s390x-secure-execution-support.patch %if 0%{?suse_version} > 1600 # Always requires a default cpu-platform package @@ -1193,7 +1194,11 @@ rm -f $R%{_sysconfdir}/grub.d/20_ppc_terminfo %ifarch s390x mv $R%{_sysconfdir}/{grub.d,default}/zipl2grub.conf.in +mv $R%{_sysconfdir}/{grub.d,default}/se-zipl2grub.conf.in +mv $R%{_sysconfdir}/{grub.d,default}/se-parm.conf.in chmod 600 $R%{_sysconfdir}/default/zipl2grub.conf.in +chmod 600 $R%{_sysconfdir}/default/se-zipl2grub.conf.in +chmod 600 $R%{_sysconfdir}/default/se-parm.conf.in %define dracutlibdir %{_prefix}/lib/dracut %define dracutgrubmoddir %{dracutlibdir}/modules.d/99grub2 @@ -1359,6 +1364,8 @@ grep -E ${EXTRA_PATTERN} %{grubarch}-mod-all.lst > %{grubarch}-mod-extras.lst %endif %ifarch s390x %config(noreplace) %{_sysconfdir}/default/zipl2grub.conf.in +%config(noreplace) %{_sysconfdir}/default/se-zipl2grub.conf.in +%config(noreplace) %{_sysconfdir}/default/se-parm.conf.in %{dracutlibdir} %{_sbindir}/%{name}-zipl-setup %{_datadir}/%{name}/zipl-refresh