s390/ipl: read IPL report at early boot

Read the IPL Report block provided by secure-boot, add the entries
of the certificate list to the system key ring and print the list
of components.

PR: Adjust to Vasilys bootdata_preserved patch set. Preserve ipl_cert_list
for later use in kexec_file.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
diff --git a/security/integrity/Kconfig b/security/integrity/Kconfig
index 2ea4ec9..3ba1168 100644
--- a/security/integrity/Kconfig
+++ b/security/integrity/Kconfig
@@ -55,13 +55,22 @@
         bool "Provide keyring for platform/firmware trusted keys"
         depends on INTEGRITY_ASYMMETRIC_KEYS
         depends on SYSTEM_BLACKLIST_KEYRING
-        depends on EFI
         help
          Provide a separate, distinct keyring for platform trusted keys, which
          the kernel automatically populates during initialization from values
          provided by the platform for verifying the kexec'ed kerned image
          and, possibly, the initramfs signature.
 
+config LOAD_UEFI_KEYS
+       depends on INTEGRITY_PLATFORM_KEYRING
+       depends on EFI
+       def_bool y
+
+config LOAD_IPL_KEYS
+       depends on INTEGRITY_PLATFORM_KEYRING
+       depends on S390
+       def_bool y
+
 config INTEGRITY_AUDIT
 	bool "Enables integrity auditing support "
 	depends on AUDIT
diff --git a/security/integrity/Makefile b/security/integrity/Makefile
index 86df9ab..19faace 100644
--- a/security/integrity/Makefile
+++ b/security/integrity/Makefile
@@ -9,10 +9,10 @@
 integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
 integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
 integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
-integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o \
-						  platform_certs/efi_parser.o \
-						  platform_certs/load_uefi.o
-obj-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/load_uefi.o
+integrity-$(CONFIG_INTEGRITY_PLATFORM_KEYRING) += platform_certs/platform_keyring.o
+integrity-$(CONFIG_LOAD_UEFI_KEYS) += platform_certs/efi_parser.o \
+					platform_certs/load_uefi.o
+integrity-$(CONFIG_LOAD_IPL_KEYS) += platform_certs/load_ipl_s390.o
 $(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar
 
 subdir-$(CONFIG_IMA)			+= ima
diff --git a/security/integrity/platform_certs/load_ipl_s390.c b/security/integrity/platform_certs/load_ipl_s390.c
new file mode 100644
index 0000000..e769dcb
--- /dev/null
+++ b/security/integrity/platform_certs/load_ipl_s390.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cred.h>
+#include <linux/err.h>
+#include <linux/efi.h>
+#include <linux/slab.h>
+#include <keys/asymmetric-type.h>
+#include <keys/system_keyring.h>
+#include <asm/boot_data.h>
+#include "../integrity.h"
+
+/*
+ * Load the certs contained in the IPL report created by the machine loader
+ * into the platform trusted keyring.
+ */
+static int __init load_ipl_certs(void)
+{
+	void *ptr, *end;
+	unsigned int len;
+
+	if (!ipl_cert_list_addr)
+		return 0;
+	/* Copy the certificates to the system keyring */
+	ptr = (void *) ipl_cert_list_addr;
+	end = ptr + ipl_cert_list_size;
+	while ((void *) ptr < end) {
+		len = *(unsigned int *) ptr;
+		ptr += sizeof(unsigned int);
+		add_to_platform_keyring("IPL:db", ptr, len);
+		ptr += len;
+	}
+	return 0;
+}
+late_initcall(load_ipl_certs);