Skip to content

Commit e23a802

Browse files
Philipp RudoMartin Schwidefsky
authored andcommitted
s390/kexec_file: Signature verification prototype
Add kernel signature verification to kexec_file. The verification is based on module signature verification and works with kernel images signed via scripts/sign-file. Signed-off-by: Philipp Rudo <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent 653beba commit e23a802

File tree

8 files changed

+95
-0
lines changed

8 files changed

+95
-0
lines changed

arch/s390/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,17 @@ config ARCH_HAS_KEXEC_PURGATORY
553553
def_bool y
554554
depends on KEXEC_FILE
555555

556+
config KEXEC_VERIFY_SIG
557+
bool "Verify kernel signature during kexec_file_load() syscall"
558+
depends on KEXEC_FILE && SYSTEM_DATA_VERIFICATION
559+
help
560+
This option makes kernel signature verification mandatory for
561+
the kexec_file_load() syscall.
562+
563+
In addition to that option, you need to enable signature
564+
verification for the corresponding kernel image type being
565+
loaded in order for this to work.
566+
556567
config ARCH_RANDOM
557568
def_bool y
558569
prompt "s390 architectural random number generation API"

arch/s390/configs/debug_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ CONFIG_NUMA=y
6464
CONFIG_PREEMPT=y
6565
CONFIG_HZ_100=y
6666
CONFIG_KEXEC_FILE=y
67+
CONFIG_KEXEC_VERIFY_SIG=y
6768
CONFIG_EXPOLINE=y
6869
CONFIG_EXPOLINE_AUTO=y
6970
CONFIG_MEMORY_HOTPLUG=y

arch/s390/configs/performance_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ CONFIG_NR_CPUS=512
6565
CONFIG_NUMA=y
6666
CONFIG_HZ_100=y
6767
CONFIG_KEXEC_FILE=y
68+
CONFIG_KEXEC_VERIFY_SIG=y
6869
CONFIG_EXPOLINE=y
6970
CONFIG_EXPOLINE_AUTO=y
7071
CONFIG_MEMORY_HOTPLUG=y

arch/s390/defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ CONFIG_NR_CPUS=256
3939
CONFIG_NUMA=y
4040
CONFIG_HZ_100=y
4141
CONFIG_KEXEC_FILE=y
42+
CONFIG_KEXEC_VERIFY_SIG=y
4243
CONFIG_CRASH_DUMP=y
4344
CONFIG_HIBERNATION=y
4445
CONFIG_PM_DEBUG=y

arch/s390/include/asm/kexec.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ struct s390_load_data {
6565
size_t memsz;
6666
};
6767

68+
int s390_verify_sig(const char *kernel, unsigned long kernel_len);
6869
void *kexec_file_add_components(struct kimage *image,
6970
int (*add_kernel)(struct kimage *image,
7071
struct s390_load_data *data));

arch/s390/kernel/kexec_elf.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,7 @@ static int s390_elf_probe(const char *buf, unsigned long len)
125125
const struct kexec_file_ops s390_kexec_elf_ops = {
126126
.probe = s390_elf_probe,
127127
.load = s390_elf_load,
128+
#ifdef CONFIG_KEXEC_VERIFY_SIG
129+
.verify_sig = s390_verify_sig,
130+
#endif /* CONFIG_KEXEC_VERIFY_SIG */
128131
};

arch/s390/kernel/kexec_image.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,7 @@ static int s390_image_probe(const char *buf, unsigned long len)
5454
const struct kexec_file_ops s390_kexec_image_ops = {
5555
.probe = s390_image_probe,
5656
.load = s390_image_load,
57+
#ifdef CONFIG_KEXEC_VERIFY_SIG
58+
.verify_sig = s390_verify_sig,
59+
#endif /* CONFIG_KEXEC_VERIFY_SIG */
5760
};

arch/s390/kernel/machine_kexec_file.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
*/
99

1010
#include <linux/elf.h>
11+
#include <linux/errno.h>
1112
#include <linux/kexec.h>
13+
#include <linux/module.h>
14+
#include <linux/verification.h>
15+
#include <asm/ipl.h>
1216
#include <asm/setup.h>
1317

1418
const struct kexec_file_ops * const kexec_file_loaders[] = {
@@ -17,6 +21,76 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
1721
NULL,
1822
};
1923

24+
#ifdef CONFIG_KEXEC_VERIFY_SIG
25+
/*
26+
* Module signature information block.
27+
*
28+
* The constituents of the signature section are, in order:
29+
*
30+
* - Signer's name
31+
* - Key identifier
32+
* - Signature data
33+
* - Information block
34+
*/
35+
struct module_signature {
36+
u8 algo; /* Public-key crypto algorithm [0] */
37+
u8 hash; /* Digest algorithm [0] */
38+
u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */
39+
u8 signer_len; /* Length of signer's name [0] */
40+
u8 key_id_len; /* Length of key identifier [0] */
41+
u8 __pad[3];
42+
__be32 sig_len; /* Length of signature data */
43+
};
44+
45+
#define PKEY_ID_PKCS7 2
46+
47+
int s390_verify_sig(const char *kernel, unsigned long kernel_len)
48+
{
49+
const unsigned long marker_len = sizeof(MODULE_SIG_STRING) - 1;
50+
struct module_signature *ms;
51+
unsigned long sig_len;
52+
53+
/* Skip signature verification when not secure IPLed. */
54+
if (!ipl_secure_flag)
55+
return 0;
56+
57+
if (marker_len > kernel_len)
58+
return -EKEYREJECTED;
59+
60+
if (memcmp(kernel + kernel_len - marker_len, MODULE_SIG_STRING,
61+
marker_len))
62+
return -EKEYREJECTED;
63+
kernel_len -= marker_len;
64+
65+
ms = (void *)kernel + kernel_len - sizeof(*ms);
66+
kernel_len -= sizeof(*ms);
67+
68+
sig_len = be32_to_cpu(ms->sig_len);
69+
if (sig_len >= kernel_len)
70+
return -EKEYREJECTED;
71+
kernel_len -= sig_len;
72+
73+
if (ms->id_type != PKEY_ID_PKCS7)
74+
return -EKEYREJECTED;
75+
76+
if (ms->algo != 0 ||
77+
ms->hash != 0 ||
78+
ms->signer_len != 0 ||
79+
ms->key_id_len != 0 ||
80+
ms->__pad[0] != 0 ||
81+
ms->__pad[1] != 0 ||
82+
ms->__pad[2] != 0) {
83+
return -EBADMSG;
84+
}
85+
86+
return verify_pkcs7_signature(kernel, kernel_len,
87+
kernel + kernel_len, sig_len,
88+
VERIFY_USE_PLATFORM_KEYRING,
89+
VERIFYING_MODULE_SIGNATURE,
90+
NULL, NULL);
91+
}
92+
#endif /* CONFIG_KEXEC_VERIFY_SIG */
93+
2094
static int kexec_file_update_purgatory(struct kimage *image,
2195
struct s390_load_data *data)
2296
{

0 commit comments

Comments
 (0)