Message ID | d95f7c6865bcad5ee37dcbec240e79aa742f5e1d.1641900831.git.msuchanek@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KEXEC_SIG with appended signature | expand |
Michal Suchanek <msuchanek@suse.de> writes: > Copy the code from s390x > > Both powerpc and s390x use appended signature format (as opposed to EFI > based patforms using PE format). > > Signed-off-by: Michal Suchanek <msuchanek@suse.de> > --- > v3: - Philipp Rudo <prudo@redhat.com>: Update the comit message with > explanation why the s390 code is usable on powerpc. > - Include correct header for mod_check_sig > - Nayna <nayna@linux.vnet.ibm.com>: Mention additional IMA features > in kconfig text > --- > arch/powerpc/Kconfig | 16 ++++++++++++++++ > arch/powerpc/kexec/elf_64.c | 36 ++++++++++++++++++++++++++++++++++++ > 2 files changed, 52 insertions(+) I haven't tested this on powerpc, but assuming you have Michal this looks OK to me. Acked-by: Michael Ellerman <mpe@ellerman.id.au> cheers
Dear Michal, Thank you for the patch. Am 11.01.22 um 12:37 schrieb Michal Suchanek: Could you please remove the dot/period at the end of the git commit message summary? > Copy the code from s390x > > Both powerpc and s390x use appended signature format (as opposed to EFI > based patforms using PE format). patforms → platforms How can this be tested? > Signed-off-by: Michal Suchanek <msuchanek@suse.de> > --- > v3: - Philipp Rudo <prudo@redhat.com>: Update the comit message with > explanation why the s390 code is usable on powerpc. > - Include correct header for mod_check_sig > - Nayna <nayna@linux.vnet.ibm.com>: Mention additional IMA features > in kconfig text > --- > arch/powerpc/Kconfig | 16 ++++++++++++++++ > arch/powerpc/kexec/elf_64.c | 36 ++++++++++++++++++++++++++++++++++++ > 2 files changed, 52 insertions(+) > > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > index dea74d7717c0..1cde9b6c5987 100644 > --- a/arch/powerpc/Kconfig > +++ b/arch/powerpc/Kconfig > @@ -560,6 +560,22 @@ config KEXEC_FILE > config ARCH_HAS_KEXEC_PURGATORY > def_bool KEXEC_FILE > > +config KEXEC_SIG > + bool "Verify kernel signature during kexec_file_load() syscall" > + depends on KEXEC_FILE && MODULE_SIG_FORMAT > + help > + This option makes kernel signature verification mandatory for > + the kexec_file_load() syscall. > + > + In addition to that option, you need to enable signature > + verification for the corresponding kernel image type being > + loaded in order for this to work. > + > + Note: on powerpc IMA_ARCH_POLICY also implements kexec'ed kernel > + verification. In addition IMA adds kernel hashes to the measurement > + list, extends IMA PCR in the TPM, and implements kernel image > + blacklist by hash. So, what is the takeaway for the user? IMA_ARCH_POLICY is preferred? What is the disadvantage, and two implementations(?) needed then? More overhead? > + > config RELOCATABLE > bool "Build a relocatable kernel" > depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE)) > diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c > index eeb258002d1e..98d1cb5135b4 100644 > --- a/arch/powerpc/kexec/elf_64.c > +++ b/arch/powerpc/kexec/elf_64.c > @@ -23,6 +23,7 @@ > #include <linux/of_fdt.h> > #include <linux/slab.h> > #include <linux/types.h> > +#include <linux/module_signature.h> > > static void *elf64_load(struct kimage *image, char *kernel_buf, > unsigned long kernel_len, char *initrd, > @@ -151,7 +152,42 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, > return ret ? ERR_PTR(ret) : NULL; > } > > +#ifdef CONFIG_KEXEC_SIG > +int elf64_verify_sig(const char *kernel, unsigned long kernel_len) > +{ > + const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; > + struct module_signature *ms; > + unsigned long sig_len; Use size_t to match the signature of `verify_pkcs7_signature()`? > + int ret; > + > + if (marker_len > kernel_len) > + return -EKEYREJECTED; > + > + if (memcmp(kernel + kernel_len - marker_len, MODULE_SIG_STRING, > + marker_len)) > + return -EKEYREJECTED; > + kernel_len -= marker_len; > + > + ms = (void *)kernel + kernel_len - sizeof(*ms); > + ret = mod_check_sig(ms, kernel_len, "kexec"); > + if (ret) > + return ret; > + > + sig_len = be32_to_cpu(ms->sig_len); > + kernel_len -= sizeof(*ms) + sig_len; > + > + return verify_pkcs7_signature(kernel, kernel_len, > + kernel + kernel_len, sig_len, > + VERIFY_USE_PLATFORM_KEYRING, > + VERIFYING_MODULE_SIGNATURE, > + NULL, NULL); > +} > +#endif /* CONFIG_KEXEC_SIG */ > + > const struct kexec_file_ops kexec_elf64_ops = { > .probe = kexec_elf_probe, > .load = elf64_load, > +#ifdef CONFIG_KEXEC_SIG > + .verify_sig = elf64_verify_sig, > +#endif > }; Kind regards, Paul
Hello, On Wed, Feb 09, 2022 at 07:44:15AM +0100, Paul Menzel wrote: > Dear Michal, > > > Thank you for the patch. > > > Am 11.01.22 um 12:37 schrieb Michal Suchanek: > > Could you please remove the dot/period at the end of the git commit message > summary? Sure > > Copy the code from s390x > > > > Both powerpc and s390x use appended signature format (as opposed to EFI > > based patforms using PE format). > > patforms → platforms Thanks for noticing > How can this be tested? Apparently KEXEC_SIG_FORCE is x86 only although the use of the option is arch neutral: arch/x86/Kconfig:config KEXEC_SIG_FORCE kernel/kexec_file.c: if (IS_ENABLED(CONFIG_KEXEC_SIG_FORCE)) { Maybe it should be moved? I used a patched kernel that enables lockdown in secure boot, and then verified that signed kernel can be loaded by kexec and unsigned not, with KEXEC_SIG enabled and IMA_KEXEC disabled. The lockdown support can be enabled on any platform, and although I can't find it documented anywhere there appears to be code in kexec_file to take it into account: kernel/kexec.c: result = security_locked_down(LOCKDOWN_KEXEC); kernel/kexec_file.c: security_locked_down(LOCKDOWN_KEXEC)) kernel/module.c: return security_locked_down(LOCKDOWN_MODULE_SIGNATURE); kernel/params.c: security_locked_down(LOCKDOWN_MODULE_PARAMETERS)) and lockdown can be enabled with a buildtime option, a kernel parameter, or a debugfs file. Still for testing lifting KEXEC_SIG_FORCE to some arch-neutral Kconfig file is probably the simplest option. kexec -s option should be used to select kexec_file rather than the old style kexec which would either fail always or succeed always regardelss of signature. > > Signed-off-by: Michal Suchanek <msuchanek@suse.de> > > --- > > v3: - Philipp Rudo <prudo@redhat.com>: Update the comit message with > > explanation why the s390 code is usable on powerpc. > > - Include correct header for mod_check_sig > > - Nayna <nayna@linux.vnet.ibm.com>: Mention additional IMA features > > in kconfig text > > --- > > arch/powerpc/Kconfig | 16 ++++++++++++++++ > > arch/powerpc/kexec/elf_64.c | 36 ++++++++++++++++++++++++++++++++++++ > > 2 files changed, 52 insertions(+) > > > > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > > index dea74d7717c0..1cde9b6c5987 100644 > > --- a/arch/powerpc/Kconfig > > +++ b/arch/powerpc/Kconfig > > @@ -560,6 +560,22 @@ config KEXEC_FILE > > config ARCH_HAS_KEXEC_PURGATORY > > def_bool KEXEC_FILE > > +config KEXEC_SIG > > + bool "Verify kernel signature during kexec_file_load() syscall" > > + depends on KEXEC_FILE && MODULE_SIG_FORMAT > > + help > > + This option makes kernel signature verification mandatory for > > + the kexec_file_load() syscall. > > + > > + In addition to that option, you need to enable signature > > + verification for the corresponding kernel image type being > > + loaded in order for this to work. > > + > > + Note: on powerpc IMA_ARCH_POLICY also implements kexec'ed kernel > > + verification. In addition IMA adds kernel hashes to the measurement > > + list, extends IMA PCR in the TPM, and implements kernel image > > + blacklist by hash. > > So, what is the takeaway for the user? IMA_ARCH_POLICY is preferred? What is > the disadvantage, and two implementations(?) needed then? More overhead? IMA_KEXEC does more than KEXEC_SIG. The overhead is probably not big unless you are trying to really minimize the kernel code size. Arguably the simpler implementation hass less potential for bugs, too. Both in code and in user configuration required to enable the feature. Interestingly IMA_ARCH_POLICY depends on KEXEC_SIG rather than IMA_KEXEC. Just mind-boggling. The main problem with IMA_KEXEC from my point of view is it is not portable. To record the measurements TPM support is requireed which is not available on all platforms. It does not support PE so it cannot be used on platforms that use PE kernel signature format. > > > + > > config RELOCATABLE > > bool "Build a relocatable kernel" > > depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE)) > > diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c > > index eeb258002d1e..98d1cb5135b4 100644 > > --- a/arch/powerpc/kexec/elf_64.c > > +++ b/arch/powerpc/kexec/elf_64.c > > @@ -23,6 +23,7 @@ > > #include <linux/of_fdt.h> > > #include <linux/slab.h> > > #include <linux/types.h> > > +#include <linux/module_signature.h> > > static void *elf64_load(struct kimage *image, char *kernel_buf, > > unsigned long kernel_len, char *initrd, > > @@ -151,7 +152,42 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, > > return ret ? ERR_PTR(ret) : NULL; > > } > > +#ifdef CONFIG_KEXEC_SIG > > +int elf64_verify_sig(const char *kernel, unsigned long kernel_len) > > +{ > > + const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; > > + struct module_signature *ms; > > + unsigned long sig_len; > > Use size_t to match the signature of `verify_pkcs7_signature()`? Nope. struct module_signature uses unsigned long, and this needs to be matched to avoid type errors on 32bit. Technically using size_t for in-memory buffers is misguided because AFAICT no memory buffer can be bigger than ULONG_MAX, and size_t is non-native type on 32bit. Sure, the situation with ssize_t/int is different but that's not what we are dealing with here. Thanks Michal
Dear Michal, Am 09.02.22 um 13:01 schrieb Michal Suchánek: > On Wed, Feb 09, 2022 at 07:44:15AM +0100, Paul Menzel wrote: >> Am 11.01.22 um 12:37 schrieb Michal Suchanek: […] >> How can this be tested? > > Apparently KEXEC_SIG_FORCE is x86 only although the use of the option is > arch neutral: > > arch/x86/Kconfig:config KEXEC_SIG_FORCE > kernel/kexec_file.c: if (IS_ENABLED(CONFIG_KEXEC_SIG_FORCE)) > { > > Maybe it should be moved? Sounds good. > I used a patched kernel that enables lockdown in secure boot, and then > verified that signed kernel can be loaded by kexec and unsigned not, > with KEXEC_SIG enabled and IMA_KEXEC disabled. > > The lockdown support can be enabled on any platform, and although I > can't find it documented anywhere there appears to be code in kexec_file > to take it into account: > kernel/kexec.c: result = security_locked_down(LOCKDOWN_KEXEC); > kernel/kexec_file.c: security_locked_down(LOCKDOWN_KEXEC)) > kernel/module.c: return security_locked_down(LOCKDOWN_MODULE_SIGNATURE); > kernel/params.c: security_locked_down(LOCKDOWN_MODULE_PARAMETERS)) > and lockdown can be enabled with a buildtime option, a kernel parameter, or a > debugfs file. > > Still for testing lifting KEXEC_SIG_FORCE to some arch-neutral Kconfig file is > probably the simplest option. > > kexec -s option should be used to select kexec_file rather than the old > style kexec which would either fail always or succeed always regardelss > of signature. Thank you. >>> Signed-off-by: Michal Suchanek <msuchanek@suse.de> >>> --- >>> v3: - Philipp Rudo <prudo@redhat.com>: Update the comit message with >>> explanation why the s390 code is usable on powerpc. >>> - Include correct header for mod_check_sig >>> - Nayna <nayna@linux.vnet.ibm.com>: Mention additional IMA features >>> in kconfig text >>> --- >>> arch/powerpc/Kconfig | 16 ++++++++++++++++ >>> arch/powerpc/kexec/elf_64.c | 36 ++++++++++++++++++++++++++++++++++++ >>> 2 files changed, 52 insertions(+) >>> >>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig >>> index dea74d7717c0..1cde9b6c5987 100644 >>> --- a/arch/powerpc/Kconfig >>> +++ b/arch/powerpc/Kconfig >>> @@ -560,6 +560,22 @@ config KEXEC_FILE >>> config ARCH_HAS_KEXEC_PURGATORY >>> def_bool KEXEC_FILE >>> +config KEXEC_SIG >>> + bool "Verify kernel signature during kexec_file_load() syscall" >>> + depends on KEXEC_FILE && MODULE_SIG_FORMAT >>> + help >>> + This option makes kernel signature verification mandatory for >>> + the kexec_file_load() syscall. >>> + >>> + In addition to that option, you need to enable signature >>> + verification for the corresponding kernel image type being >>> + loaded in order for this to work. >>> + >>> + Note: on powerpc IMA_ARCH_POLICY also implements kexec'ed kernel >>> + verification. In addition IMA adds kernel hashes to the measurement >>> + list, extends IMA PCR in the TPM, and implements kernel image >>> + blacklist by hash. >> >> So, what is the takeaway for the user? IMA_ARCH_POLICY is preferred? What is >> the disadvantage, and two implementations(?) needed then? More overhead? > > IMA_KEXEC does more than KEXEC_SIG. The overhead is probably not big > unless you are trying to really minimize the kernel code size. > > Arguably the simpler implementation has less potential for bugs, too. > Both in code and in user configuration required to enable the feature. > > Interestingly IMA_ARCH_POLICY depends on KEXEC_SIG rather than > IMA_KEXEC. Just mind-boggling. I have not looked into that. > The main problem with IMA_KEXEC from my point of view is it is not portable. > To record the measurements TPM support is requireed which is not available on > all platforms. It does not support PE so it cannot be used on platforms > that use PE kernel signature format. Could you add that to the comment please? >>> + >>> config RELOCATABLE >>> bool "Build a relocatable kernel" >>> depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE)) >>> diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c >>> index eeb258002d1e..98d1cb5135b4 100644 >>> --- a/arch/powerpc/kexec/elf_64.c >>> +++ b/arch/powerpc/kexec/elf_64.c >>> @@ -23,6 +23,7 @@ >>> #include <linux/of_fdt.h> >>> #include <linux/slab.h> >>> #include <linux/types.h> >>> +#include <linux/module_signature.h> >>> static void *elf64_load(struct kimage *image, char *kernel_buf, >>> unsigned long kernel_len, char *initrd, >>> @@ -151,7 +152,42 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, >>> return ret ? ERR_PTR(ret) : NULL; >>> } >>> +#ifdef CONFIG_KEXEC_SIG >>> +int elf64_verify_sig(const char *kernel, unsigned long kernel_len) >>> +{ >>> + const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; >>> + struct module_signature *ms; >>> + unsigned long sig_len; >> >> Use size_t to match the signature of `verify_pkcs7_signature()`? > > Nope. struct module_signature uses unsigned long, and this needs to be > matched to avoid type errors on 32bit. I meant for `sig_len`. > Technically using size_t for in-memory buffers is misguided because > AFAICT no memory buffer can be bigger than ULONG_MAX, and size_t is > non-native type on 32bit. > > Sure, the situation with ssize_t/int is different but that's not what we > are dealing with here. True. In my experience it prevents compiler warnings when building for 32 bit or 64 bit. Anyway, not that important. Kind regards, Paul
Hi Michal, On Wed, 2022-02-09 at 13:01 +0100, Michal Suchánek wrote: > > > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > > > index dea74d7717c0..1cde9b6c5987 100644 > > > --- a/arch/powerpc/Kconfig > > > +++ b/arch/powerpc/Kconfig > > > @@ -560,6 +560,22 @@ config KEXEC_FILE > > > config ARCH_HAS_KEXEC_PURGATORY > > > def_bool KEXEC_FILE > > > +config KEXEC_SIG > > > + bool "Verify kernel signature during kexec_file_load() syscall" > > > + depends on KEXEC_FILE && MODULE_SIG_FORMAT > > > + help > > > + This option makes kernel signature verification mandatory for > > > + the kexec_file_load() syscall. > > > + > > > + In addition to that option, you need to enable signature > > > + verification for the corresponding kernel image type being > > > + loaded in order for this to work. > > > + > > > + Note: on powerpc IMA_ARCH_POLICY also implements kexec'ed kernel > > > + verification. In addition IMA adds kernel hashes to the measurement > > > + list, extends IMA PCR in the TPM, and implements kernel image > > > + blacklist by hash. > > > > So, what is the takeaway for the user? IMA_ARCH_POLICY is preferred? What is > > the disadvantage, and two implementations(?) needed then? More overhead? > > IMA_KEXEC does more than KEXEC_SIG. The overhead is probably not big > unless you are trying to really minimize the kernel code size. > > Arguably the simpler implementation hass less potential for bugs, too. > Both in code and in user configuration required to enable the feature. > > Interestingly IMA_ARCH_POLICY depends on KEXEC_SIG rather than > IMA_KEXEC. Just mind-boggling. FYI, a soft boot doesn't clear the TPM PCRs. To be able to verify the IMA measurement list after a kexec against a TPM quote, requires carrying the measurement list across kexec. The "IMA_KEXEC" config enables carrying the IMA measurement list across kexec. It has nothing to do with verifying the appended signature. That is based on kernel module appended signature code. > > The main problem with IMA_KEXEC from my point of view is it is not portable. > To record the measurements TPM support is requireed which is not available on > all platforms. Measuring the kexec kernel image and extending the TPM with the measurement is required for trusted boot. Boot loaders extend the TPM's BIOS measurements. Similarly, IMA does not require a TPM, but if one is available the kexec kernel image measurement is extended into the IMA measurement list. Otherwise, IMA goes into "TPM by-pass" mode. > It does not support PE so it cannot be used on platforms > that use PE kernel signature format. True. However, a kernel image with an appended signature may be kexec'ed, regardless of the architecture. Because some boot loaders don't support appended signatures, from my point of view does not make IMA kexec support not portable.
Hi Michal, On Tue, 2022-01-11 at 12:37 +0100, Michal Suchanek wrote: > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > index dea74d7717c0..1cde9b6c5987 100644 > --- a/arch/powerpc/Kconfig > +++ b/arch/powerpc/Kconfig > @@ -560,6 +560,22 @@ config KEXEC_FILE > config ARCH_HAS_KEXEC_PURGATORY > def_bool KEXEC_FILE > > +config KEXEC_SIG > + bool "Verify kernel signature during kexec_file_load() syscall" > + depends on KEXEC_FILE && MODULE_SIG_FORMAT > + help > + This option makes kernel signature verification mandatory for > + the kexec_file_load() syscall. When KEXEC_SIG is enabled on other architectures, IMA does not define a kexec 'appraise' policy rule. Refer to the policy rules in security/ima/ima_efi.c. Similarly the kexec 'appraise' policy rule in arch/powerpc/kernel/ima_policy.c should not be defined.
Hi Michal, On Sun, 2022-02-13 at 21:59 -0500, Mimi Zohar wrote: > > On Tue, 2022-01-11 at 12:37 +0100, Michal Suchanek wrote: > > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > > index dea74d7717c0..1cde9b6c5987 100644 > > --- a/arch/powerpc/Kconfig > > +++ b/arch/powerpc/Kconfig > > @@ -560,6 +560,22 @@ config KEXEC_FILE > > config ARCH_HAS_KEXEC_PURGATORY > > def_bool KEXEC_FILE > > > > +config KEXEC_SIG > > + bool "Verify kernel signature during kexec_file_load() syscall" > > + depends on KEXEC_FILE && MODULE_SIG_FORMAT > > + help > > + This option makes kernel signature verification mandatory for > > + the kexec_file_load() syscall. > > When KEXEC_SIG is enabled on other architectures, IMA does not define a > kexec 'appraise' policy rule. Refer to the policy rules in > security/ima/ima_efi.c. Similarly the kexec 'appraise' policy rule in > arch/powerpc/kernel/ima_policy.c should not be defined. The discussion shouldn't only be about IMA vs. KEXEC_SIG kernel image signature verification. Let's try and reframe the problem a bit. 1. Unify and simply the existing kexec signature verification so verifying the KEXEC kernel image signature works irrespective of signature type - PE, appended signature. solution: enable KEXEC_SIG (This patch set, with the above powerpc IMA policy changes.) 2. Measure and include the kexec kernel image in a log for attestation, if desired. solution: enable IMA_ARCH_POLICY - Powerpc: requires trusted boot to be enabled. - EFI: requires secure boot to be enabled. The IMA efi policy doesn't differentiate between secure and trusted boot. 3. Carry the kexec kernel image measurement across kexec, if desired and supported on the architecture. solution: enable IMA_KEXEC Comparison: - Are there any differences between IMA vs. KEXEC_SIG measuring the kexec kernel image? One of the main differences is "what" is included in the measurement list differs. In both cases, the 'd-ng' field of the IMA measurement list template (e.g. ima-ng, ima-sig, ima-modsig) is the full file hash including the appended signature. With IMA and the 'ima-modsig' template, an additional hash without the appended signature is defined, as well as including the appended signature in the 'sig' field. Including the file hash and appended signature in the measurement list allows an attestation server, for example, to verify the appended signature without having to know the file hash without the signature. Other differences are already included in the Kconfig KEXEC_SIG "Notes" section.
Hello, On Mon, Feb 14, 2022 at 10:14:16AM -0500, Mimi Zohar wrote: > Hi Michal, > > On Sun, 2022-02-13 at 21:59 -0500, Mimi Zohar wrote: > > > > > On Tue, 2022-01-11 at 12:37 +0100, Michal Suchanek wrote: > > > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > > > index dea74d7717c0..1cde9b6c5987 100644 > > > --- a/arch/powerpc/Kconfig > > > +++ b/arch/powerpc/Kconfig > > > @@ -560,6 +560,22 @@ config KEXEC_FILE > > > config ARCH_HAS_KEXEC_PURGATORY > > > def_bool KEXEC_FILE > > > > > > +config KEXEC_SIG > > > + bool "Verify kernel signature during kexec_file_load() syscall" > > > + depends on KEXEC_FILE && MODULE_SIG_FORMAT > > > + help > > > + This option makes kernel signature verification mandatory for This is actually wrong. KEXEC_SIG makes it mandatory that any signature that is appended is valid and made by a key that is part of the platform keyiring (which is also wrong, built-in keys should be also accepted). KEXEC_SIG_FORCE or an IMA policy makes it mandatory that the signature is present. > > > + the kexec_file_load() syscall. > > > > When KEXEC_SIG is enabled on other architectures, IMA does not define a > > kexec 'appraise' policy rule. Refer to the policy rules in > > security/ima/ima_efi.c. Similarly the kexec 'appraise' policy rule in I suppose you mean security/integrity/ima/ima_efi.c I also think it's misguided because KEXEC_SIG in itself does not enforce the signature. KEXEC_SIG_FORCE does. > > arch/powerpc/kernel/ima_policy.c should not be defined. I suppose you mean arch/powerpc/kernel/ima_arch.c - see above. Thanks for taking the time to reseach and summarize the differences. > The discussion shouldn't only be about IMA vs. KEXEC_SIG kernel image > signature verification. Let's try and reframe the problem a bit. > > 1. Unify and simply the existing kexec signature verification so > verifying the KEXEC kernel image signature works irrespective of > signature type - PE, appended signature. > > solution: enable KEXEC_SIG (This patch set, with the above powerpc IMA > policy changes.) > > 2. Measure and include the kexec kernel image in a log for attestation, > if desired. > > solution: enable IMA_ARCH_POLICY > - Powerpc: requires trusted boot to be enabled. > - EFI: requires secure boot to be enabled. The IMA efi policy > doesn't differentiate between secure and trusted boot. > > 3. Carry the kexec kernel image measurement across kexec, if desired > and supported on the architecture. > > solution: enable IMA_KEXEC > > Comparison: > - Are there any differences between IMA vs. KEXEC_SIG measuring the > kexec kernel image? > > One of the main differences is "what" is included in the measurement > list differs. In both cases, the 'd-ng' field of the IMA measurement > list template (e.g. ima-ng, ima-sig, ima-modsig) is the full file hash > including the appended signature. With IMA and the 'ima-modsig' > template, an additional hash without the appended signature is defined, > as well as including the appended signature in the 'sig' field. > > Including the file hash and appended signature in the measurement list > allows an attestation server, for example, to verify the appended > signature without having to know the file hash without the signature. I don't understand this part. Isn't the hash *with* signature always included, and the distinguishing part about IMA is the hash *without* signature which is the same irrespective of signature type (PE, appended xattr) and irrespective of the keyt used for signoing? > Other differences are already included in the Kconfig KEXEC_SIG "Notes" > section. Which besides what is already described above would be blacklisting specific binaries, which is much more effective if you have hashes of binaries without signature. Thanks Michal
On Mon, 2022-02-14 at 16:55 +0100, Michal Suchánek wrote: > Hello, > > On Mon, Feb 14, 2022 at 10:14:16AM -0500, Mimi Zohar wrote: > > Hi Michal, > > > > On Sun, 2022-02-13 at 21:59 -0500, Mimi Zohar wrote: > > > > > > > > On Tue, 2022-01-11 at 12:37 +0100, Michal Suchanek wrote: > > > > diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig > > > > index dea74d7717c0..1cde9b6c5987 100644 > > > > --- a/arch/powerpc/Kconfig > > > > +++ b/arch/powerpc/Kconfig > > > > @@ -560,6 +560,22 @@ config KEXEC_FILE > > > > config ARCH_HAS_KEXEC_PURGATORY > > > > def_bool KEXEC_FILE > > > > > > > > +config KEXEC_SIG > > > > + bool "Verify kernel signature during kexec_file_load() syscall" > > > > + depends on KEXEC_FILE && MODULE_SIG_FORMAT > > > > + help > > > > + This option makes kernel signature verification mandatory for > > This is actually wrong. KEXEC_SIG makes it mandatory that any signature > that is appended is valid and made by a key that is part of the platform > keyiring (which is also wrong, built-in keys should be also accepted). > KEXEC_SIG_FORCE or an IMA policy makes it mandatory that the signature > is present. I'm aware of MODULE_SIG_FORCE, which isn't normally enabled by distros, but enabling MODULE_SIG allows MODULE_SIG_FORCE to be enabled on the boot command line. In the IMA arch policies, if MODULE_SIG is enabled, it is then enforced, otherwise an IMA "appraise" policy rule is defined. This rule would prevent the module_load syscall. I'm not aware of KEXEC_SIG_FORCE. If there is such a Kconfig, then I assume it could work similarly. > > > > > + the kexec_file_load() syscall. > > > > > > When KEXEC_SIG is enabled on other architectures, IMA does not define a > > > kexec 'appraise' policy rule. Refer to the policy rules in > > > security/ima/ima_efi.c. Similarly the kexec 'appraise' policy rule in > > I suppose you mean security/integrity/ima/ima_efi.c Yes > > I also think it's misguided because KEXEC_SIG in itself does not enforce > the signature. KEXEC_SIG_FORCE does. Right, which is why the IMA efi policy calls set_module_sig_enforced(). > > > > arch/powerpc/kernel/ima_policy.c should not be defined. > > I suppose you mean arch/powerpc/kernel/ima_arch.c - see above. Sorry, yes. > > > Thanks for taking the time to reseach and summarize the differences. > > > The discussion shouldn't only be about IMA vs. KEXEC_SIG kernel image > > signature verification. Let's try and reframe the problem a bit. > > > > 1. Unify and simply the existing kexec signature verification so > > verifying the KEXEC kernel image signature works irrespective of > > signature type - PE, appended signature. > > > > solution: enable KEXEC_SIG (This patch set, with the above powerpc IMA > > policy changes.) > > > > 2. Measure and include the kexec kernel image in a log for attestation, > > if desired. > > > > solution: enable IMA_ARCH_POLICY > > - Powerpc: requires trusted boot to be enabled. > > - EFI: requires secure boot to be enabled. The IMA efi policy > > doesn't differentiate between secure and trusted boot. > > > > 3. Carry the kexec kernel image measurement across kexec, if desired > > and supported on the architecture. > > > > solution: enable IMA_KEXEC > > > > Comparison: > > - Are there any differences between IMA vs. KEXEC_SIG measuring the > > kexec kernel image? > > > > One of the main differences is "what" is included in the measurement > > list differs. In both cases, the 'd-ng' field of the IMA measurement > > list template (e.g. ima-ng, ima-sig, ima-modsig) is the full file hash > > including the appended signature. With IMA and the 'ima-modsig' > > template, an additional hash without the appended signature is defined, > > as well as including the appended signature in the 'sig' field. > > > > Including the file hash and appended signature in the measurement list > > allows an attestation server, for example, to verify the appended > > signature without having to know the file hash without the signature. > > I don't understand this part. Isn't the hash *with* signature always > included, and the distinguishing part about IMA is the hash *without* > signature which is the same irrespective of signature type (PE, appended > xattr) and irrespective of the keyt used for signoing? Roberto Sassu added support for IMA templates. These are the definitions of 'ima-sig' and 'ima-modsig'. {.name = "ima-sig", .fmt = "d-ng|n-ng|sig"}, {.name = "ima-modsig", .fmt = "d-ng|n-ng|sig|d-modsig|modsig"} d-ng: is the file hash. With the proposed IMA support for fs-verity digests, the 'd-ng' field may also include the fsverity digest, based on policy. n-ng: is the file pathname. sig: is the file signature stored as a 'security.ima' xattr (may be NULL). d-modsig: is the file hash without the appended signature (may be NULL). FYI, changing from "module signature" to "appended signature", might impact the template field and name. :) modsig: is the appended signature (May be NULL). I really haven't looked at PE signatures, so I can't comment on them. > > > Other differences are already included in the Kconfig KEXEC_SIG "Notes" > > section. > > Which besides what is already described above would be blacklisting > specific binaries, which is much more effective if you have hashes of > binaries without signature. Thanks, Nayna will be happy to hear you approve. FYI, IMA calculates the file hash once, which is then added to the IMA measurement list, extended into the TPM (when available), used to verify signatures, and included in the audit log. With the KEXEC_SIG support, assuming the IMA arch policy is enabled, the file hash would be calculated twice - once for verifying the file signature and again for the measurement.
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index dea74d7717c0..1cde9b6c5987 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -560,6 +560,22 @@ config KEXEC_FILE config ARCH_HAS_KEXEC_PURGATORY def_bool KEXEC_FILE +config KEXEC_SIG + bool "Verify kernel signature during kexec_file_load() syscall" + depends on KEXEC_FILE && MODULE_SIG_FORMAT + help + This option makes kernel signature verification mandatory for + the kexec_file_load() syscall. + + In addition to that option, you need to enable signature + verification for the corresponding kernel image type being + loaded in order for this to work. + + Note: on powerpc IMA_ARCH_POLICY also implements kexec'ed kernel + verification. In addition IMA adds kernel hashes to the measurement + list, extends IMA PCR in the TPM, and implements kernel image + blacklist by hash. + config RELOCATABLE bool "Build a relocatable kernel" depends on PPC64 || (FLATMEM && (44x || FSL_BOOKE)) diff --git a/arch/powerpc/kexec/elf_64.c b/arch/powerpc/kexec/elf_64.c index eeb258002d1e..98d1cb5135b4 100644 --- a/arch/powerpc/kexec/elf_64.c +++ b/arch/powerpc/kexec/elf_64.c @@ -23,6 +23,7 @@ #include <linux/of_fdt.h> #include <linux/slab.h> #include <linux/types.h> +#include <linux/module_signature.h> static void *elf64_load(struct kimage *image, char *kernel_buf, unsigned long kernel_len, char *initrd, @@ -151,7 +152,42 @@ static void *elf64_load(struct kimage *image, char *kernel_buf, return ret ? ERR_PTR(ret) : NULL; } +#ifdef CONFIG_KEXEC_SIG +int elf64_verify_sig(const char *kernel, unsigned long kernel_len) +{ + const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1; + struct module_signature *ms; + unsigned long sig_len; + int ret; + + if (marker_len > kernel_len) + return -EKEYREJECTED; + + if (memcmp(kernel + kernel_len - marker_len, MODULE_SIG_STRING, + marker_len)) + return -EKEYREJECTED; + kernel_len -= marker_len; + + ms = (void *)kernel + kernel_len - sizeof(*ms); + ret = mod_check_sig(ms, kernel_len, "kexec"); + if (ret) + return ret; + + sig_len = be32_to_cpu(ms->sig_len); + kernel_len -= sizeof(*ms) + sig_len; + + return verify_pkcs7_signature(kernel, kernel_len, + kernel + kernel_len, sig_len, + VERIFY_USE_PLATFORM_KEYRING, + VERIFYING_MODULE_SIGNATURE, + NULL, NULL); +} +#endif /* CONFIG_KEXEC_SIG */ + const struct kexec_file_ops kexec_elf64_ops = { .probe = kexec_elf_probe, .load = elf64_load, +#ifdef CONFIG_KEXEC_SIG + .verify_sig = elf64_verify_sig, +#endif };
Copy the code from s390x Both powerpc and s390x use appended signature format (as opposed to EFI based patforms using PE format). Signed-off-by: Michal Suchanek <msuchanek@suse.de> --- v3: - Philipp Rudo <prudo@redhat.com>: Update the comit message with explanation why the s390 code is usable on powerpc. - Include correct header for mod_check_sig - Nayna <nayna@linux.vnet.ibm.com>: Mention additional IMA features in kconfig text --- arch/powerpc/Kconfig | 16 ++++++++++++++++ arch/powerpc/kexec/elf_64.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+)