From: Eric Farman <farman@linux.ibm.com>
To: Zhuoying Cai <zycai@linux.ibm.com>,
qemu-s390x@nongnu.org, qemu-devel@nongnu.org
Subject: Re: [PATCH v13 23/33] pc-bios/s390-ccw: Add signature verification for secure IPL in audit mode
Date: Fri, 03 Jul 2026 20:43:38 -0400 [thread overview]
Message-ID: <76c7a257398ff5bfa12168b372695de1bdf85fee.camel@linux.ibm.com> (raw)
In-Reply-To: <6fa4c5f7-0388-4acb-bacb-f929ecff1a09@linux.ibm.com>
On Fri, 2026-07-03 at 09:56 -0400, Zhuoying Cai wrote:
> On 7/3/26 7:40 AM, Eric Farman wrote:
> > On Thu, 2026-07-02 at 22:29 -0400, Zhuoying Cai wrote:
> > > Enable secure IPL in audit mode, which performs signature verification,
> > > but any error does not terminate the boot process. Only warnings will be
> > > logged to the console instead.
> > >
> > > Secure IPL in audit mode requires at least one certificate provided in
> > > the key store along with necessary facilities (Secure IPL Facility,
> > > Certificate Store Facility and secure IPL extension support).
> > >
> > > Note: Secure IPL in audit mode is implemented for the SCSI scheme of
> > > virtio-blk/virtio-scsi devices.
> > >
> > > Signed-off-by: Zhuoying Cai <zycai@linux.ibm.com>
> > > ---
> > > docs/system/s390x/secure-ipl.rst | 15 ++
> > > hw/s390x/ipl.c | 9 +
> > > pc-bios/s390-ccw/Makefile | 2 +-
> > > pc-bios/s390-ccw/bootmap.c | 27 +++
> > > pc-bios/s390-ccw/bootmap.h | 9 +
> > > pc-bios/s390-ccw/jump2ipl.c | 7 +
> > > pc-bios/s390-ccw/main.c | 18 +-
> > > pc-bios/s390-ccw/s390-ccw.h | 20 ++
> > > pc-bios/s390-ccw/sclp.c | 27 +++
> > > pc-bios/s390-ccw/sclp.h | 6 +
> > > pc-bios/s390-ccw/secure-ipl.c | 363 +++++++++++++++++++++++++++++++
> > > pc-bios/s390-ccw/secure-ipl.h | 115 ++++++++++
> > > 12 files changed, 616 insertions(+), 2 deletions(-)
> > > create mode 100644 pc-bios/s390-ccw/secure-ipl.c
> > > create mode 100644 pc-bios/s390-ccw/secure-ipl.h
> > >
> >
> > ...snip...
> >
> > > diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
> > > index cd3d0776b0..7484429c9a 100644
> > > --- a/pc-bios/s390-ccw/main.c
> > > +++ b/pc-bios/s390-ccw/main.c
> > > @@ -20,6 +20,7 @@
> > > #include "dasd-ipl.h"
> > > #include "clp.h"
> > > #include "virtio-pci.h"
> > > +#include "secure-ipl.h"
> > >
> > > static SubChannelId blk_schid = { .one = 1 };
> > > static char loadparm_str[LOADPARM_LEN + 1];
> > > @@ -383,6 +384,8 @@ static void probe_boot_device(void)
> > >
> > > void main(void)
> > > {
> > > + int vcssb_len;
> > > +
> > > iplb = &ipl_blocks.iplb;
> > >
> > > copy_qipl();
> > > @@ -394,7 +397,20 @@ void main(void)
> > > probe_boot_device();
> > > }
> > >
> > > - boot_mode = ZIPL_BOOT_MODE_NORMAL;
> > > + boot_mode = get_boot_mode(iplb->hdr_flags);
> > > + switch (boot_mode) {
> > > + case ZIPL_BOOT_MODE_SECURE_AUDIT:
> > > + if (!secure_ipl_supported()) {
> > > + panic("Unable to boot in audit mode");
> > > + }
> > > +
> > > + vcssb_len = zipl_secure_get_vcssb();
> > > + if (vcssb_len == 0) {
> > > + panic("Failed to query certificate storage information!");
> > > + }
> >
> > break? fallthrough?
> >
>
> Thanks for catching this!
>
> > > + default:
> > > + break;
> > > + }
> > >
> > > while (have_iplb) {
> > > boot_setup();
> > > diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
> > > index 5420443ad2..ca2737054d 100644
> > > --- a/pc-bios/s390-ccw/s390-ccw.h
> > > +++ b/pc-bios/s390-ccw/s390-ccw.h
> > > @@ -40,6 +40,22 @@ typedef unsigned long long u64;
> > > ((b) == 0 ? (a) : (MIN(a, b))))
> > > #endif
> > >
> > > +/*
> > > + * Round number down to multiple. Requires that d be a power of 2.
> > > + * Works even if d is a smaller type than n.
> > > + */
> > > +#ifndef ROUND_DOWN
> > > +#define ROUND_DOWN(n, d) ((n) & -(0 ? (n) : (d)))
> > > +#endif
> > > +
> > > +/*
> > > + * Round number up to multiple. Requires that d be a power of 2.
> > > + * Works even if d is a smaller type than n.
> > > + */
> > > +#ifndef ROUND_UP
> > > +#define ROUND_UP(n, d) ROUND_DOWN((n) + (d) - 1, (d))
> > > +#endif
> > > +
> > > #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
> > >
> > > #include "cio.h"
> > > @@ -64,6 +80,8 @@ void sclp_print(const char *string);
> > > void sclp_set_write_mask(uint32_t receive_mask, uint32_t send_mask);
> > > void sclp_setup(void);
> > > void sclp_get_loadparm_ascii(char *loadparm);
> > > +bool sclp_is_diag320_on(void);
> > > +bool sclp_is_fac_ipl_flag_on(uint16_t fac_ipl_flag);
> > > int sclp_read(char *str, size_t count);
> > >
> > > /* bootmap.c */
> > > @@ -71,9 +89,11 @@ void zipl_load(void);
> > >
> > > typedef enum ZiplBootMode {
> > > ZIPL_BOOT_MODE_NORMAL = 0,
> > > + ZIPL_BOOT_MODE_SECURE_AUDIT = 1,
> > > } ZiplBootMode;
> > >
> > > extern ZiplBootMode boot_mode;
> > > +ZiplBootMode get_boot_mode(uint8_t hdr_flags);
> > >
> > > /* jump2ipl.c */
> > > void write_reset_psw(uint64_t psw);
> > > diff --git a/pc-bios/s390-ccw/sclp.c b/pc-bios/s390-ccw/sclp.c
> > > index 4a07de018d..48bdfedf1f 100644
> > > --- a/pc-bios/s390-ccw/sclp.c
> > > +++ b/pc-bios/s390-ccw/sclp.c
> > > @@ -113,6 +113,33 @@ void sclp_get_loadparm_ascii(char *loadparm)
> > > }
> > > }
> > >
> > > +bool sclp_is_diag320_on(void)
> > > +{
> > > + ReadInfo *sccb = (void *)_sccb;
> > > +
> > > + memset((char *)_sccb, 0, sizeof(ReadInfo));
> > > + sccb->h.length = SCCB_SIZE;
> > > + if (!sclp_service_call(SCLP_CMDW_READ_SCP_INFO, sccb)) {
> > > + return sccb->fac134 & SCCB_FAC134_DIAG320_BIT;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +/* check if specified IPL facility flag is enabled */
> > > +bool sclp_is_fac_ipl_flag_on(uint16_t fac_ipl_flag)
> > > +{
> > > + ReadInfo *sccb = (void *)_sccb;
> > > +
> > > + memset((char *)_sccb, 0, sizeof(ReadInfo));
> > > + sccb->h.length = SCCB_SIZE;
> > > + if (!sclp_service_call(SCLP_CMDW_READ_SCP_INFO, sccb)) {
> > > + return sccb->fac_ipl & fac_ipl_flag;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > int sclp_read(char *str, size_t count)
> > > {
> > > ReadEventData *sccb = (void *)_sccb;
> > > diff --git a/pc-bios/s390-ccw/sclp.h b/pc-bios/s390-ccw/sclp.h
> > > index 64b53cad29..a8a41cd004 100644
> > > --- a/pc-bios/s390-ccw/sclp.h
> > > +++ b/pc-bios/s390-ccw/sclp.h
> > > @@ -50,6 +50,8 @@ typedef struct SCCBHeader {
> > > } __attribute__((packed)) SCCBHeader;
> > >
> > > #define SCCB_DATA_LEN (SCCB_SIZE - sizeof(SCCBHeader))
> > > +#define SCCB_FAC134_DIAG320_BIT 0x4
> > > +#define SCCB_FAC_IPL_SIPL_BIT 0x4000
> > >
> > > typedef struct ReadInfo {
> > > SCCBHeader h;
> > > @@ -57,6 +59,10 @@ typedef struct ReadInfo {
> > > uint8_t rnsize;
> > > uint8_t reserved[13];
> > > uint8_t loadparm[LOADPARM_LEN];
> > > + uint8_t reserved1[102];
> > > + uint8_t fac134;
> > > + uint8_t reserved2;
> > > + uint16_t fac_ipl;
> > > } __attribute__((packed)) ReadInfo;
> > >
> > > typedef struct SCCB {
> > > diff --git a/pc-bios/s390-ccw/secure-ipl.c b/pc-bios/s390-ccw/secure-ipl.c
> > > new file mode 100644
> > > index 0000000000..2cfa16fb68
> > > --- /dev/null
> > > +++ b/pc-bios/s390-ccw/secure-ipl.c
> > > @@ -0,0 +1,363 @@
> > > +/*
> > > + * S/390 Secure IPL
> > > + *
> > > + * Functions to support IPL in secure boot mode (DIAG 320, DIAG 508,
> > > + * signature verification, and certificate handling).
> > > + *
> > > + * For secure IPL overview: docs/system/s390x/secure-ipl.rst
> > > + * For secure IPL technical: docs/specs/s390x-secure-ipl.rst
> > > + *
> > > + * Copyright 2025 IBM Corp.
> > > + * Author(s): Zhuoying Cai <zycai@linux.ibm.com>
> > > + *
> > > + * SPDX-License-Identifier: GPL-2.0-or-later
> > > + */
> > > +
> > > +#include <stdlib.h>
> > > +#include <string.h>
> > > +#include <stdio.h>
> > > +#include "s390-ccw.h"
> > > +#include "sclp.h"
> > > +#include "secure-ipl.h"
> > > +
> > > +static VCStorageSizeBlock vcssb __attribute__((__aligned__(8)));
> > > +
> > > +#define for_each_rb_entry(entry, list) \
> > > + for (entry = (void *)(list) + sizeof((list)->ipl_info_header); \
> > > + (void *)(entry) + sizeof(*(entry)) <= \
> > > + (void *)(list) + (list)->ipl_info_header.len; \
> > > + entry++)
> > > +
> > > +int zipl_secure_get_vcssb(void)
> > > +{
> > > + /* avoid retrieving vcssb multiple times */
> > > + if (vcssb.length == VCSSB_LEN_VALID) {
> > > + goto out;
> > > + }
> > > +
> > > + vcssb.length = VCSSB_LEN_VALID;
> > > + if (_diag320(&vcssb, DIAG_320_SUBC_QUERY_VCSI) != DIAG_320_RC_OK) {
> > > + vcssb.length = 0;
> > > + }
> > > +
> > > +out:
> > > + return vcssb.length;
> > > +}
> > > +
> > > +static uint32_t request_certificate(uint8_t *cert_buf, uint8_t index)
> > > +{
> > > + VCEntryHeader *vce_hdr;
> > > + struct vcb {
> > > + VCBlockHeader vcb_hdr;
> > > + struct vce {
> > > + VCEntryHeader vce_hdr;
> > > + uint8_t cert_buf[CERT_BUF_MAX_LEN];
> > > + } vce;
> > > + } __attribute__((__aligned__(PAGE_SIZE))) vcb = { 0 };
> > > +
> > > + /*
> > > + * Request single entry
> > > + * Fill input fields of single-entry VCB
> > > + *
> > > + * First and last index must be equal because only one
> > > + * VCE per VCB is currently supported
> > > + */
> > > + vcb.vcb_hdr.in_len = ROUND_UP(vcssb.max_single_vcb_len, PAGE_SIZE);
> >
> > Don't you need to convert max_single_vcb_len from be to cpu?
> >
>
> I don't think we need to convert max_single_vcb_len here, but please
> correct me if I'm missing something. If I understand correctly, the
> fields are written and read in big-endian format, so no additional
> conversion should be necessary.
No, you're right... Got my wires crossed about qemu vs bios. Sorry about that.
>
> > > + vcb.vcb_hdr.first_vc_index = index;
> > > + vcb.vcb_hdr.last_vc_index = index;
> > > +
> > > + if (_diag320(&vcb, DIAG_320_SUBC_STORE_VC) != DIAG_320_RC_OK) {
> > > + puts("Could not get certificate");
> > > + return 0;
> > > + }
> > > +
> > > + if (vcb.vcb_hdr.out_len == sizeof(VCBlockHeader)) {
> > > + puts("No certificate entry");
> > > + return 0;
> > > + }
> > > +
> > > + if (vcb.vcb_hdr.remain_ct != 0) {
> > > + panic("Not enough memory to store requested certificate");
> > > + }
> > > +
> > > + vce_hdr = &vcb.vce.vce_hdr;
> > > + if (!(vce_hdr->flags & DIAG_320_VCE_FLAGS_VALID)) {
> > > + puts("Invalid certificate");
> > > + return 0;
> > > + }
> > > +
> > > + memcpy(cert_buf, (uint8_t *)&vcb.vce + vce_hdr->cert_offset, vce_hdr->cert_len);
> > > +
> > > + return vce_hdr->cert_len;
> > > +}
> > > +
> [...]
next prev parent reply other threads:[~2026-07-04 0:44 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-03 2:28 [PATCH v13 00/33] Secure IPL Support for SCSI Scheme of virtio-blk/virtio-scsi Devices Zhuoying Cai
2026-07-03 2:28 ` [PATCH v13 01/33] Add boot-certs to s390-ccw-virtio machine type option Zhuoying Cai
2026-07-03 13:24 ` Matthew Rosato
2026-07-03 2:29 ` [PATCH v13 02/33] crypto/x509-utils: Refactor with GNUTLS fallback Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 03/33] crypto/x509-utils: Add helper functions for certificate store Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 04/33] hw/s390x/ipl: Create " Zhuoying Cai
2026-07-03 16:56 ` Matthew Rosato
2026-07-03 2:29 ` [PATCH v13 05/33] s390x/diag: Introduce DIAG 320 for Certificate Store Facility Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 06/33] s390x/diag: Refactor address validation check from diag308_parm_check Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 07/33] s390x/diag: Implement DIAG 320 subcode 1 Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 08/33] crypto/x509-utils: Add helper functions for DIAG 320 subcode 2 Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 09/33] s390x/diag: Implement " Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 10/33] hw/s390x: Define finite size for single entry VCEntry Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 11/33] s390x/diag: Introduce DIAG 508 for secure IPL operations Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 12/33] crypto/x509-utils: Add helper functions for DIAG 508 subcode 1 Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 13/33] s390x/diag: Generalize s390_ipl_read/write to accept void * Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 14/33] s390x/diag: Implement DIAG 508 subcode 1 for signature verification Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 15/33] s390x/ipl: Introduce IPL Information Report Block (IIRB) Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 16/33] pc-bios/s390-ccw: Define memory for IPLB and convert IPLB to pointers Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 17/33] hw/s390x/ipl: Add IPIB flags to IPL Parameter Block Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 18/33] hw/s390x/ipl: Rework s390_ipl_map_iplb_chain for certificate storage Zhuoying Cai
2026-07-03 13:47 ` Eric Farman
2026-07-03 2:29 ` [PATCH v13 19/33] s390x: Guest support for Secure-IPL Facility Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 20/33] pc-bios/s390-ccw: Refactor zipl_run() Zhuoying Cai
2026-07-03 2:40 ` Philippe Mathieu-Daudé
2026-07-03 2:29 ` [PATCH v13 21/33] pc-bios/s390-ccw: Rework zipl_load_segment function Zhuoying Cai
2026-07-03 2:38 ` Philippe Mathieu-Daudé
2026-07-03 14:28 ` Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 22/33] pc-bios/s390-ccw: Introduce ZiplBootMode enum for IPL mode selection Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 23/33] pc-bios/s390-ccw: Add signature verification for secure IPL in audit mode Zhuoying Cai
2026-07-03 11:40 ` Eric Farman
2026-07-03 13:56 ` Zhuoying Cai
2026-07-04 0:43 ` Eric Farman [this message]
2026-07-03 13:58 ` Eric Farman
2026-07-03 2:29 ` [PATCH v13 24/33] pc-bios/s390-ccw: Add signed component address overlap checks Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 25/33] s390x: Guest support for Secure-IPL Code Loading Attributes Facility (SCLAF) Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 26/33] pc-bios/s390-ccw: Add additional security checks for secure boot Zhuoying Cai
2026-07-03 12:17 ` Eric Farman
2026-07-03 2:29 ` [PATCH v13 27/33] Add secure-boot to s390-ccw-virtio machine type option Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 28/33] hw/s390x/ipl: Set IPIB flags for secure IPL Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 29/33] pc-bios/s390-ccw: Handle true secure IPL mode Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 30/33] hw/s390x/ipl: Handle secure boot with multiple boot devices Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 31/33] tests/functional/s390x: Add secure IPL functional test Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 32/33] docs/specs: Add secure IPL documentation Zhuoying Cai
2026-07-03 2:29 ` [PATCH v13 33/33] docs/system/s390x: " Zhuoying Cai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=76c7a257398ff5bfa12168b372695de1bdf85fee.camel@linux.ibm.com \
--to=farman@linux.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-s390x@nongnu.org \
--cc=zycai@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.