diff mbox series

[v1,22/24] pc-bios/s390-ccw: Handle true secure IPL mode

Message ID 20250408155527.123341-23-zycai@linux.ibm.com (mailing list archive)
State New
Headers show
Series Secure IPL Support for SCSI Scheme of virtio-blk/virtio-scsi Devices | expand

Commit Message

Zhuoying Cai April 8, 2025, 3:55 p.m. UTC
When secure boot is enabled (-secure-boot on) and certificate(s) are
provided, the boot operates in True Secure IPL mode.

Any verification error during True Secure IPL mode will cause the
entire boot process to terminate.

Secure IPL in audit mode requires at least one certificate provided in
the key store along with necessary facilities. If secure boot is enabled
but no certificate is provided, the boot process will also terminate, as
this is not a valid secure boot configuration.

Note: True Secure IPL mode is implemented for the SCSI scheme of
virtio-blk/virtio-scsi devices.

Signed-off-by: Zhuoying Cai <zycai@linux.ibm.com>
---
 pc-bios/s390-ccw/bootmap.c  | 25 ++++++++++++++++++++-----
 pc-bios/s390-ccw/iplb.h     |  7 +++++++
 pc-bios/s390-ccw/main.c     |  6 +++++-
 pc-bios/s390-ccw/s390-ccw.h |  2 ++
 4 files changed, 34 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/pc-bios/s390-ccw/bootmap.c b/pc-bios/s390-ccw/bootmap.c
index 4bc6311802..a22061e1ad 100644
--- a/pc-bios/s390-ccw/bootmap.c
+++ b/pc-bios/s390-ccw/bootmap.c
@@ -757,6 +757,10 @@  static void valid_sclab_check(SclabOriginLocator *sclab_locator,
         comps->device_entries[comp_index].cei |= S390_IPL_COMPONENT_CEI_INVALID_SCLAB;
 
         /* a missing SCLAB will not be reported in audit mode */
+        if (boot_mode == ZIPL_SECURE_MODE) {
+            print_func(is_magic_match, "Magic is not matched. SCLAB does not exist");
+        }
+
         return;
     }
 
@@ -1164,7 +1168,11 @@  static int zipl_run_secure(ComponentEntry *entry, uint8_t *tmp_sec)
     int addr_range_index = 0;
 
     void (*print_func)(bool, const char *) = NULL;
-    print_func = &IPL_check;
+    if (boot_mode == ZIPL_SECURE_MODE) {
+        print_func = &IPL_assert;
+    } else if (boot_mode == ZIPL_SECURE_AUDIT_MODE) {
+        print_func = &IPL_check;
+    }
 
     if (!secure_ipl_supported()) {
         return -1;
@@ -1321,6 +1329,7 @@  static int zipl_run(ScsiBlockPtr *pte)
     entry = (ComponentEntry *)(&header[1]);
 
     switch (boot_mode) {
+    case ZIPL_SECURE_MODE:
     case ZIPL_SECURE_AUDIT_MODE:
         if (zipl_run_secure(entry, tmp_sec)) {
             return -1;
@@ -1692,10 +1701,16 @@  static int zipl_load_vscsi(void)
 int zipl_mode(void)
 {
     uint32_t cert_len;
+    bool secure;
 
     cert_len = request_certificate((uint64_t *)certs_sec, 0);
+    secure = is_secure_boot_on(iplb->hdr_flags);
 
-    return (cert_len > 0) ? ZIPL_SECURE_AUDIT_MODE : ZIPL_NORMAL_MODE;
+    if (secure) {
+        return (cert_len > 0) ? ZIPL_SECURE_MODE : ZIPL_SECURE_INVALID_MODE;
+    } else {
+        return (cert_len > 0) ? ZIPL_SECURE_AUDIT_MODE : ZIPL_NORMAL_MODE;
+    }
 }
 
 void zipl_load(void)
@@ -1703,7 +1718,7 @@  void zipl_load(void)
     VDev *vdev = virtio_get_device();
 
     if (vdev->is_cdrom) {
-        if (boot_mode == ZIPL_SECURE_AUDIT_MODE) {
+        if (boot_mode == ZIPL_SECURE_AUDIT_MODE || boot_mode == ZIPL_SECURE_MODE) {
             panic("Secure boot from ISO image is not supported!");
         }
         ipl_iso_el_torito();
@@ -1712,7 +1727,7 @@  void zipl_load(void)
     }
 
     if (virtio_get_device_type() == VIRTIO_ID_NET) {
-        if (boot_mode == ZIPL_SECURE_AUDIT_MODE) {
+        if (boot_mode == ZIPL_SECURE_AUDIT_MODE || boot_mode == ZIPL_SECURE_MODE) {
             panic("Virtio net boot device does not support secure boot!");
         }
         netmain();
@@ -1725,7 +1740,7 @@  void zipl_load(void)
         return;
     }
 
-    if (boot_mode == ZIPL_SECURE_AUDIT_MODE) {
+    if (boot_mode == ZIPL_SECURE_AUDIT_MODE || boot_mode == ZIPL_SECURE_MODE) {
         panic("ECKD boot device does not support secure boot!");
     }
 
diff --git a/pc-bios/s390-ccw/iplb.h b/pc-bios/s390-ccw/iplb.h
index 42a9e081fe..734d049f42 100644
--- a/pc-bios/s390-ccw/iplb.h
+++ b/pc-bios/s390-ccw/iplb.h
@@ -185,6 +185,13 @@  static inline bool load_next_iplb(void)
     return true;
 }
 
+static inline bool is_secure_boot_on(uint8_t hdr_flags)
+{
+    /* If secure boot is on, SIPL bit and IPLIR bit must be on. */
+    return (hdr_flags & DIAG308_IPIB_FLAGS_SIPL) &&
+           (hdr_flags & DIAG308_IPIB_FLAGS_IPLIR);
+}
+
 static inline uint64_t diag320(void *data, unsigned long subcode)
 {
     register unsigned long addr asm("0") = (unsigned long)data;
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 92004a6f82..6189a5a7ba 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -277,10 +277,14 @@  static void ipl_boot_device(void)
         boot_mode = zipl_mode();
     }
 
+    if (boot_mode == ZIPL_SECURE_INVALID_MODE) {
+        panic("Need at least one certificate for secure boot!");
+    }
+
     switch (cutype) {
     case CU_TYPE_DASD_3990:
     case CU_TYPE_DASD_2107:
-        if (boot_mode == ZIPL_SECURE_AUDIT_MODE) {
+        if (boot_mode == ZIPL_SECURE_AUDIT_MODE || boot_mode == ZIPL_SECURE_MODE) {
             panic("Passthrough (vfio) device does not support secure boot!");
         }
 
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index 20d6827a4c..e8ff3f7883 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -84,6 +84,8 @@  void zipl_load(void);
 
 #define ZIPL_NORMAL_MODE           1
 #define ZIPL_SECURE_AUDIT_MODE     2
+#define ZIPL_SECURE_MODE           3
+#define ZIPL_SECURE_INVALID_MODE  -1
 
 int zipl_mode(void);