diff options
author | AKASHI Takahiro <takahiro.akashi@linaro.org> | 2018-11-15 14:52:54 +0900 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2018-12-06 15:16:52 +0000 |
commit | 732b7b93d849f8a44886ead563dfb6adec7f4419 (patch) | |
tree | 29ec906b45eaec73cae4102a360dd7fea7f9198c /arch/arm64/kernel/kexec_image.c | |
parent | 702ed5bb75306c030ab6598b24b56ba8d21a48dd (diff) | |
download | talos-obmc-linux-732b7b93d849f8a44886ead563dfb6adec7f4419.tar.gz talos-obmc-linux-732b7b93d849f8a44886ead563dfb6adec7f4419.zip |
arm64: kexec_file: add kernel signature verification support
With this patch, kernel verification can be done without IMA security
subsystem enabled. Turn on CONFIG_KEXEC_VERIFY_SIG instead.
On x86, a signature is embedded into a PE file (Microsoft's format) header
of binary. Since arm64's "Image" can also be seen as a PE file as far as
CONFIG_EFI is enabled, we adopt this format for kernel signing.
You can create a signed kernel image with:
$ sbsign --key ${KEY} --cert ${CERT} Image
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Reviewed-by: James Morse <james.morse@arm.com>
[will: removed useless pr_debug()]
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/kernel/kexec_image.c')
-rw-r--r-- | arch/arm64/kernel/kexec_image.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c index 9f0d8b5d62d3..1ad1d5f8f024 100644 --- a/arch/arm64/kernel/kexec_image.c +++ b/arch/arm64/kernel/kexec_image.c @@ -12,7 +12,9 @@ #include <linux/errno.h> #include <linux/kernel.h> #include <linux/kexec.h> +#include <linux/pe.h> #include <linux/string.h> +#include <linux/verification.h> #include <asm/byteorder.h> #include <asm/cpufeature.h> #include <asm/image.h> @@ -20,13 +22,13 @@ static int image_probe(const char *kernel_buf, unsigned long kernel_len) { - const struct arm64_image_header *h; + const struct arm64_image_header *h = + (const struct arm64_image_header *)(kernel_buf); - h = (const struct arm64_image_header *)(kernel_buf); + if (!h || (kernel_len < sizeof(*h))) + return -EINVAL; - if (!h || (kernel_len < sizeof(*h)) || - memcmp(&h->magic, ARM64_IMAGE_MAGIC, - sizeof(h->magic))) + if (memcmp(&h->magic, ARM64_IMAGE_MAGIC, sizeof(h->magic))) return -EINVAL; return 0; @@ -107,7 +109,18 @@ static void *image_load(struct kimage *image, return ERR_PTR(ret); } +#ifdef CONFIG_KEXEC_IMAGE_VERIFY_SIG +static int image_verify_sig(const char *kernel, unsigned long kernel_len) +{ + return verify_pefile_signature(kernel, kernel_len, NULL, + VERIFYING_KEXEC_PE_SIGNATURE); +} +#endif + const struct kexec_file_ops kexec_image_ops = { .probe = image_probe, .load = image_load, +#ifdef CONFIG_KEXEC_IMAGE_VERIFY_SIG + .verify_sig = image_verify_sig, +#endif }; |