mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 77083b1cbb | |||
| 21c2a04347 | |||
| 8f2d77c9d3 | |||
| b6a4d7a6c1 | |||
| f223069f0b | |||
| 19a5af8da9 | |||
| 03b73ab3f9 | |||
| 080a6678fb | |||
| 1d6f7d0bec | |||
| a50d0485c9 | |||
| d2a6a771a5 | |||
| 7568a0790f | |||
| ca0ee966b8 | |||
| 36a7b2e6eb | |||
| 851f63eb03 | |||
| 3d679f61fc | |||
| 9237c5b675 | |||
| d1ab6be082 | |||
| d6c2bac99f |
@@ -1,6 +1,24 @@
|
|||||||
Release history for s390-tools (MIT version)
|
Release history for s390-tools (MIT version)
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
|
* __v2.42.1 (2026-05-22)__
|
||||||
|
|
||||||
|
For Linux kernel version: 7.0
|
||||||
|
|
||||||
|
Changes of existing tools:
|
||||||
|
- cpumf/pai: Improve -m XXX argument verification
|
||||||
|
- pvattest: Add -i -o option variant for check
|
||||||
|
- pvattest: Show perform -i & -o option in help
|
||||||
|
- pvebc: Disable unit logging to /boot
|
||||||
|
- pvsecret: Add -i -o option variants
|
||||||
|
|
||||||
|
Bug Fixes:
|
||||||
|
- cpumf/pai: Remove unnecessary const parameter definition
|
||||||
|
- pv: Fix error description
|
||||||
|
- pvebc: Fix dependency for non EBC guests
|
||||||
|
- pvebc: Fix kernel module dependencies
|
||||||
|
- zipl: Don't modify job->data.dump and job->data.mvdump sequentially
|
||||||
|
|
||||||
* __v2.42.0 (2026-04-30)__
|
* __v2.42.0 (2026-04-30)__
|
||||||
|
|
||||||
For Linux kernel version: 7.0
|
For Linux kernel version: 7.0
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ endif
|
|||||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||||
VERSION := 2
|
VERSION := 2
|
||||||
RELEASE := 42
|
RELEASE := 42
|
||||||
PATCHLEVEL := 0
|
PATCHLEVEL := 1
|
||||||
DISTRELEASE := build-$(shell date +%Y%m%d)
|
DISTRELEASE := build-$(shell date +%Y%m%d)
|
||||||
S390_TOOLS_RELEASE := $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
S390_TOOLS_RELEASE := $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||||
export S390_TOOLS_RELEASE
|
export S390_TOOLS_RELEASE
|
||||||
|
|||||||
+9
-15
@@ -894,7 +894,7 @@ static int parse_event_attr(char *cp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parse CPU list and event specifications */
|
/* Parse CPU list and event specifications */
|
||||||
static void parse_cpulist(int enr, const char *parm)
|
static void parse_cpulist(int enr, char *parm)
|
||||||
{
|
{
|
||||||
unsigned int evt_attr = 0;
|
unsigned int evt_attr = 0;
|
||||||
cpu_set_t cmdlist, result;
|
cpu_set_t cmdlist, result;
|
||||||
@@ -948,33 +948,27 @@ static const struct util_prg prg = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void record_cpus_crypto(const char *cp)
|
static void record_cpus_crypto(char *cp)
|
||||||
{
|
{
|
||||||
if (!libcpumf_have_pai_crypto())
|
if (!libcpumf_have_pai_crypto())
|
||||||
errx(EXIT_FAILURE, "No support for PAI crypto counters");
|
errx(EXIT_FAILURE, "No support for PAI crypto counters");
|
||||||
parse_cpulist(S390_EVT_PAI_CRYPTO, cp);
|
parse_cpulist(S390_EVT_PAI_CRYPTO, cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void record_cpus_nnpa(const char *cp)
|
static void record_cpus_nnpa(char *cp)
|
||||||
{
|
{
|
||||||
if (!libcpumf_have_pai_nnpa())
|
if (!libcpumf_have_pai_nnpa())
|
||||||
errx(EXIT_FAILURE, "No support for PAI nnpa counters");
|
errx(EXIT_FAILURE, "No support for PAI nnpa counters");
|
||||||
parse_cpulist(S390_EVT_PAI_NNPA, cp);
|
parse_cpulist(S390_EVT_PAI_NNPA, cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mapsize must be power of 2 and larger than 4. Count bits in n and
|
/* Mapsize must be power of 2 and larger than 4. Return true in this case.
|
||||||
* return 0 if input is invalid and has a bit count larger than one.
|
|
||||||
*/
|
*/
|
||||||
static unsigned long check_mapsize(unsigned long n)
|
static bool check_mapsize(unsigned long n)
|
||||||
{
|
{
|
||||||
int bit, cnt = 0;
|
|
||||||
|
|
||||||
if (n < 4)
|
if (n < 4)
|
||||||
return 0;
|
return 0;
|
||||||
for (bit = 0; bit < __BITS_PER_LONG; ++bit)
|
return (n & (n - 1)) == 0;
|
||||||
if (n & (1 << bit))
|
|
||||||
++cnt;
|
|
||||||
return cnt == 1 ? n : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setprio(const char *prio)
|
static void setprio(const char *prio)
|
||||||
@@ -1040,11 +1034,11 @@ int main(int argc, char **argv)
|
|||||||
errx(EXIT_FAILURE, "Invalid argument for -%c", ch);
|
errx(EXIT_FAILURE, "Invalid argument for -%c", ch);
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
errno = 0;
|
|
||||||
mapsize = strtoul(optarg, &slash, 0);
|
mapsize = strtoul(optarg, &slash, 0);
|
||||||
mapsize = check_mapsize(mapsize);
|
if (!mapsize || *slash)
|
||||||
if (errno || !mapsize || *slash)
|
|
||||||
errx(EXIT_FAILURE, "Invalid argument for -%c", ch);
|
errx(EXIT_FAILURE, "Invalid argument for -%c", ch);
|
||||||
|
if (!check_mapsize(mapsize))
|
||||||
|
errx(EXIT_FAILURE, "No power of 2 number for -%c", ch);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
record_cpus_nnpa(optarg);
|
record_cpus_nnpa(optarg);
|
||||||
|
|||||||
+3
-1
@@ -114,8 +114,10 @@ ifneq ($(HAVE_DRACUT),0)
|
|||||||
$(INSTALL) -m 755 pvebc/$(SEL_EBC_MODDIR)/module-setup.sh \
|
$(INSTALL) -m 755 pvebc/$(SEL_EBC_MODDIR)/module-setup.sh \
|
||||||
pvebc/$(SEL_EBC_MODDIR)/override-crypttab.sh \
|
pvebc/$(SEL_EBC_MODDIR)/override-crypttab.sh \
|
||||||
pvebc/$(SEL_EBC_MODDIR)/pvebc-wrapper.sh \
|
pvebc/$(SEL_EBC_MODDIR)/pvebc-wrapper.sh \
|
||||||
|
pvebc/$(SEL_EBC_MODDIR)/boot-mount.sh \
|
||||||
|
pvebc/$(SEL_EBC_MODDIR)/sel-ebc-modules.conf \
|
||||||
$(DESTDIR)$(DRACUTMODDIR)/$(SEL_EBC_MODDIR)
|
$(DESTDIR)$(DRACUTMODDIR)/$(SEL_EBC_MODDIR)
|
||||||
$(INSTALL) -m 644 pvebc/$(SEL_EBC_MODDIR)/boot.mount \
|
$(INSTALL) -m 644 pvebc/$(SEL_EBC_MODDIR)/sel-ebc-boot-mount.service \
|
||||||
pvebc/$(SEL_EBC_MODDIR)/sel-ebc-override-crypttab.service \
|
pvebc/$(SEL_EBC_MODDIR)/sel-ebc-override-crypttab.service \
|
||||||
pvebc/$(SEL_EBC_MODDIR)/sel-ebc-paes-enforce.service \
|
pvebc/$(SEL_EBC_MODDIR)/sel-ebc-paes-enforce.service \
|
||||||
pvebc/$(SEL_EBC_MODDIR)/sel-ebc-pvebc.service \
|
pvebc/$(SEL_EBC_MODDIR)/sel-ebc-pvebc.service \
|
||||||
|
|||||||
@@ -90,11 +90,11 @@ pub enum Error {
|
|||||||
#[error("Input does not contain an attestation request")]
|
#[error("Input does not contain an attestation request")]
|
||||||
NoArcb,
|
NoArcb,
|
||||||
|
|
||||||
#[error("The attestation request has an unknown version (.0)")]
|
#[error("The attestation request has an unknown version {0}")]
|
||||||
BinArcbInvVersion(u32),
|
BinArcbInvVersion(u32),
|
||||||
|
|
||||||
#[error(
|
#[error(
|
||||||
"The attestation request encrypted sice is to0 small (.0). Request probably tampered with."
|
"The attestation request encrypted sice is to0 small {0}. Request probably tampered with."
|
||||||
)]
|
)]
|
||||||
BinArcbSeaSmall(u32),
|
BinArcbSeaSmall(u32),
|
||||||
|
|
||||||
|
|||||||
+31
-7
@@ -17,7 +17,7 @@ Create an attestation measurement request
|
|||||||
|
|
||||||
- **perform**
|
- **perform**
|
||||||
<ul>
|
<ul>
|
||||||
Send the attestation request to the Ultravisor
|
Send the attestation request to the Ultravisor (s390x only.)
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
- **verify**
|
- **verify**
|
||||||
@@ -150,11 +150,11 @@ Print help (see a summary with '-h').
|
|||||||
### Synopsis
|
### Synopsis
|
||||||
`pvattest perform [OPTIONS] [IN] [OUT]`
|
`pvattest perform [OPTIONS] [IN] [OUT]`
|
||||||
### Description
|
### Description
|
||||||
Send the attestation request to the Ultravisor. Run a measurement of this system
|
Send the attestation request to the Ultravisor (s390x only.) Run a measurement
|
||||||
through ’/dev/uv’. This device must be accessible and the attestation
|
of this system through ’/dev/uv’. This device must be accessible and the
|
||||||
Ultravisor facility must be present. The input must be an attestation request
|
attestation Ultravisor facility must be present. The input must be an
|
||||||
created with ’pvattest create’. Output will contain the original request and
|
attestation request created with ’pvattest create’. Output will contain the
|
||||||
the response from the Ultravisor.
|
original request and the response from the Ultravisor. Only available on s390x.
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
`<IN>`
|
`<IN>`
|
||||||
@@ -171,6 +171,18 @@ Write the result to FILE.
|
|||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
|
`-i`, `--input <FILE>`
|
||||||
|
<ul>
|
||||||
|
Specify the request to be sent.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
`-o`, `--output <FILE>`
|
||||||
|
<ul>
|
||||||
|
Write the result to FILE.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
`-u`, `--user-data <File>`
|
`-u`, `--user-data <File>`
|
||||||
<ul>
|
<ul>
|
||||||
Provide up to 256 bytes of user input User-data is arbitrary user-defined data
|
Provide up to 256 bytes of user input User-data is arbitrary user-defined data
|
||||||
@@ -256,7 +268,7 @@ Print help (see a summary with '-h').
|
|||||||
|
|
||||||
## pvattest check
|
## pvattest check
|
||||||
### Synopsis
|
### Synopsis
|
||||||
`pvattest check [OPTIONS] <IN> <OUT>`
|
`pvattest check [OPTIONS] [IN] [OUT]`
|
||||||
### Description
|
### Description
|
||||||
Check if the attestation result matches defined policies. After the attestation
|
Check if the attestation result matches defined policies. After the attestation
|
||||||
verification, check whether the attestation result complies with user-defined
|
verification, check whether the attestation result complies with user-defined
|
||||||
@@ -277,6 +289,18 @@ Specify the output file for the check result.
|
|||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
|
`-i`, `--input <FILE>`
|
||||||
|
<ul>
|
||||||
|
Specify the attestation response to check whether the policies are validated.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
`-o`, `--output <FILE>`
|
||||||
|
<ul>
|
||||||
|
Specify the output file for the check result.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
`--format <FORMAT>`
|
`--format <FORMAT>`
|
||||||
<ul>
|
<ul>
|
||||||
Define the output format.
|
Define the output format.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVATTEST-CHECK" "1" "2025-03-12" "s390-tools" "Attestation Manual"
|
.TH "PVATTEST-CHECK" "1" "2026-05-19" "s390-tools" "Attestation Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -11,7 +11,7 @@ pvattest-check \- Check if the attestation result matches defined policies
|
|||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.fam C
|
.fam C
|
||||||
pvattest check [OPTIONS] <IN> <OUT>
|
pvattest check [OPTIONS] [IN] [OUT]
|
||||||
.fam C
|
.fam C
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
@@ -31,6 +31,18 @@ Specify the output file for the check result.
|
|||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\-i, \-\-input <FILE>
|
||||||
|
.RS 4
|
||||||
|
Specify the attestation response to check whether the policies are validated.
|
||||||
|
.RE
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
\-o, \-\-output <FILE>
|
||||||
|
.RS 4
|
||||||
|
Specify the output file for the check result.
|
||||||
|
.RE
|
||||||
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\-\-format <FORMAT>
|
\-\-format <FORMAT>
|
||||||
.RS 4
|
.RS 4
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVATTEST-CREATE" "1" "2026-02-12" "s390-tools" "Attestation Manual"
|
.TH "PVATTEST-CREATE" "1" "2026-05-20" "s390-tools" "Attestation Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -21,6 +21,7 @@ Workstation. To avoid compromising the attestation do not publish the
|
|||||||
attestation request protection key and shred it after verification. Every
|
attestation request protection key and shred it after verification. Every
|
||||||
\fBcreate\fR will generate a new, random protection key.
|
\fBcreate\fR will generate a new, random protection key.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\-k, \-\-host\-key\-document <FILE>
|
\-k, \-\-host\-key\-document <FILE>
|
||||||
.RS 4
|
.RS 4
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVATTEST-PERFORM" "1" "2025-03-12" "s390-tools" "Attestation Manual"
|
.TH "PVATTEST-PERFORM" "1" "2026-05-19" "s390-tools" "Attestation Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
pvattest-perform \- Send the attestation request to the Ultravisor
|
pvattest-perform \- Send the attestation request to the Ultravisor (s390x only.)
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.fam C
|
.fam C
|
||||||
@@ -18,7 +18,8 @@ pvattest perform [OPTIONS] [IN] [OUT]
|
|||||||
Run a measurement of this system through ’/dev/uv’. This device must be
|
Run a measurement of this system through ’/dev/uv’. This device must be
|
||||||
accessible and the attestation Ultravisor facility must be present. The input
|
accessible and the attestation Ultravisor facility must be present. The input
|
||||||
must be an attestation request created with ’pvattest create’. Output will
|
must be an attestation request created with ’pvattest create’. Output will
|
||||||
contain the original request and the response from the Ultravisor.
|
contain the original request and the response from the Ultravisor. Only
|
||||||
|
available on s390x.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.PP
|
.PP
|
||||||
<IN>
|
<IN>
|
||||||
@@ -33,6 +34,18 @@ Write the result to FILE.
|
|||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\-i, \-\-input <FILE>
|
||||||
|
.RS 4
|
||||||
|
Specify the request to be sent.
|
||||||
|
.RE
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
\-o, \-\-output <FILE>
|
||||||
|
.RS 4
|
||||||
|
Write the result to FILE.
|
||||||
|
.RE
|
||||||
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\-u, \-\-user\-data <File>
|
\-u, \-\-user\-data <File>
|
||||||
.RS 4
|
.RS 4
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVATTEST-VERIFY" "1" "2026-02-12" "s390-tools" "Attestation Manual"
|
.TH "PVATTEST-VERIFY" "1" "2026-05-20" "s390-tools" "Attestation Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -26,6 +26,7 @@ solely verifies that the Attestation measurement is correct. It does not check
|
|||||||
for the content of additional data or user data. See `pvattest check` for policy
|
for the content of additional data or user data. See `pvattest check` for policy
|
||||||
checks after you verified the Attestation measurement.
|
checks after you verified the Attestation measurement.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\-i, \-\-input <FILE>
|
\-i, \-\-input <FILE>
|
||||||
.RS 4
|
.RS 4
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVATTEST" "1" "2026-02-12" "s390-tools" "Attestation Manual"
|
.TH "PVATTEST" "1" "2026-05-19" "s390-tools" "Attestation Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -29,7 +29,7 @@ Create an attestation measurement request
|
|||||||
|
|
||||||
\fBpvattest\-perform(1)\fR
|
\fBpvattest\-perform(1)\fR
|
||||||
.RS 4
|
.RS 4
|
||||||
Send the attestation request to the Ultravisor
|
Send the attestation request to the Ultravisor (s390x only.)
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
@@ -47,6 +47,7 @@ Check if the attestation result matches defined policies
|
|||||||
.RE
|
.RE
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\-v, \-\-verbose
|
\-v, \-\-verbose
|
||||||
.RS 4
|
.RS 4
|
||||||
|
|||||||
+43
-11
@@ -113,20 +113,20 @@ pub enum AttAddFlags {
|
|||||||
#[derive(Args, Debug)]
|
#[derive(Args, Debug)]
|
||||||
pub struct PerformAttOpt {
|
pub struct PerformAttOpt {
|
||||||
/// Specify the request to be sent.
|
/// Specify the request to be sent.
|
||||||
#[arg(hide=true, short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
||||||
pub input: Option<String>,
|
input: Option<String>,
|
||||||
|
|
||||||
/// Specify the request to be sent.
|
/// Specify the request to be sent.
|
||||||
#[arg(value_name = "IN", value_hint = ValueHint::FilePath, required_unless_present("input"), conflicts_with("input"))]
|
#[arg(value_name = "IN", value_hint = ValueHint::FilePath, required_unless_present("input"), conflicts_with("input"))]
|
||||||
pub input_pos: Option<String>,
|
input_pos: Option<String>,
|
||||||
|
|
||||||
/// Write the result to FILE.
|
/// Write the result to FILE.
|
||||||
#[arg(hide=true, short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
||||||
pub output: Option<String>,
|
output: Option<String>,
|
||||||
|
|
||||||
/// Write the result to FILE.
|
/// Write the result to FILE.
|
||||||
#[arg(value_name = "OUT", value_hint = ValueHint::FilePath, required_unless_present("output"), conflicts_with("output"))]
|
#[arg(value_name = "OUT", value_hint = ValueHint::FilePath, required_unless_present("output"), conflicts_with("output"))]
|
||||||
pub output_pos: Option<String>,
|
output_pos: Option<String>,
|
||||||
|
|
||||||
/// Provide up to 256 bytes of user input
|
/// Provide up to 256 bytes of user input
|
||||||
///
|
///
|
||||||
@@ -134,7 +134,7 @@ pub struct PerformAttOpt {
|
|||||||
/// It is verified during the Attestation measurement verification.
|
/// It is verified during the Attestation measurement verification.
|
||||||
/// May be any arbitrary data, as long as it is less or equal to 256 bytes
|
/// May be any arbitrary data, as long as it is less or equal to 256 bytes
|
||||||
#[arg(short, long, value_name = "File", value_hint = ValueHint::FilePath,)]
|
#[arg(short, long, value_name = "File", value_hint = ValueHint::FilePath,)]
|
||||||
pub user_data: Option<String>,
|
user_data: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "s390x")]
|
#[cfg(target_arch = "s390x")]
|
||||||
@@ -217,12 +217,20 @@ pub enum OutputType {
|
|||||||
#[derive(Args, Debug)]
|
#[derive(Args, Debug)]
|
||||||
pub struct CheckOpt {
|
pub struct CheckOpt {
|
||||||
/// Specify the attestation response to check whether the policies are validated.
|
/// Specify the attestation response to check whether the policies are validated.
|
||||||
#[arg(value_name = "IN", value_hint = ValueHint::FilePath,)]
|
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
||||||
pub input: PathBuf,
|
input: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Specify the attestation response to check whether the policies are validated.
|
||||||
|
#[arg(value_name = "IN", value_hint = ValueHint::FilePath, required_unless_present("input"), conflicts_with("input"))]
|
||||||
|
input_pos: Option<PathBuf>,
|
||||||
|
|
||||||
/// Specify the output file for the check result.
|
/// Specify the output file for the check result.
|
||||||
#[arg(value_name = "OUT", value_hint = ValueHint::FilePath,)]
|
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
||||||
pub output: PathBuf,
|
output: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Specify the output file for the check result.
|
||||||
|
#[arg(value_name = "OUT", value_hint = ValueHint::FilePath, required_unless_present("output"), conflicts_with("output"))]
|
||||||
|
output_pos: Option<PathBuf>,
|
||||||
|
|
||||||
/// Define the output format.
|
/// Define the output format.
|
||||||
#[arg(long, value_enum, default_value_t)]
|
#[arg(long, value_enum, default_value_t)]
|
||||||
@@ -300,6 +308,30 @@ pub struct CheckOpt {
|
|||||||
pub firmware_verify_url: Option<String>,
|
pub firmware_verify_url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CheckOptIO<'a> {
|
||||||
|
pub input: &'a PathBuf,
|
||||||
|
pub output: &'a PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a CheckOpt> for CheckOptIO<'a> {
|
||||||
|
fn from(value: &'a CheckOpt) -> Self {
|
||||||
|
let input = match (&value.input, &value.input_pos) {
|
||||||
|
(None, Some(i)) => i,
|
||||||
|
(Some(i), None) => i,
|
||||||
|
(Some(_), Some(_)) => unreachable!(),
|
||||||
|
(None, None) => unreachable!(),
|
||||||
|
};
|
||||||
|
let output = match (&value.output, &value.output_pos) {
|
||||||
|
(None, Some(o)) => o,
|
||||||
|
(Some(o), None) => o,
|
||||||
|
(Some(_), Some(_)) => unreachable!(),
|
||||||
|
(None, None) => unreachable!(),
|
||||||
|
};
|
||||||
|
Self { input, output }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug)]
|
||||||
pub enum HostKeyCheckPolicy {
|
pub enum HostKeyCheckPolicy {
|
||||||
/// Check the host-key used for the attestation request.
|
/// Check the host-key used for the attestation request.
|
||||||
|
|||||||
@@ -12,7 +12,12 @@ use self::{
|
|||||||
secret_store::secret_store_check,
|
secret_store::secret_store_check,
|
||||||
secret_store::SecretStoreCheck,
|
secret_store::SecretStoreCheck,
|
||||||
};
|
};
|
||||||
use crate::{additional::AttestationResult, cli::CheckOpt, exchange::ExchangeFormatResponse};
|
use crate::{
|
||||||
|
additional::AttestationResult,
|
||||||
|
cli::{CheckOpt, CheckOptIO},
|
||||||
|
exchange::ExchangeFormatResponse,
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use log::{debug, info, warn};
|
use log::{debug, info, warn};
|
||||||
use pv::{
|
use pv::{
|
||||||
@@ -104,7 +109,8 @@ pub struct CheckResult<'a> {
|
|||||||
|
|
||||||
/// Perform the policy checks
|
/// Perform the policy checks
|
||||||
pub fn check(opt: &CheckOpt) -> Result<ExitCode> {
|
pub fn check(opt: &CheckOpt) -> Result<ExitCode> {
|
||||||
let mut input = open_file(&opt.input)?;
|
let opt_io = CheckOptIO::from(opt);
|
||||||
|
let mut input = open_file(opt_io.input)?;
|
||||||
let inp = ExchangeFormatResponse::read(&mut input)?;
|
let inp = ExchangeFormatResponse::read(&mut input)?;
|
||||||
let auth = AttestationRequest::auth_bin(inp.arcb())?;
|
let auth = AttestationRequest::auth_bin(inp.arcb())?;
|
||||||
let att_res = AttestationResult::from_exchange(&inp, auth.flags())?;
|
let att_res = AttestationResult::from_exchange(&inp, auth.flags())?;
|
||||||
@@ -139,7 +145,7 @@ pub fn check(opt: &CheckOpt) -> Result<ExitCode> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
debug!("res {res:?}");
|
debug!("res {res:?}");
|
||||||
let output = create_file(&opt.output)?;
|
let output = create_file(opt_io.output)?;
|
||||||
serde_yaml::to_writer(output, &res)?;
|
serde_yaml::to_writer(output, &res)?;
|
||||||
|
|
||||||
match res.successful {
|
match res.successful {
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
#
|
||||||
|
# Copyright IBM Corp.
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
mntp="/boot"
|
||||||
|
block_dev="$(blkid -L boot)"
|
||||||
|
|
||||||
|
if [[ -z "${block_dev}" ]]; then
|
||||||
|
echo "Unable to find partition with label boot"
|
||||||
|
exit 1
|
||||||
|
elif [[ ! -b "${block_dev}" ]]; then
|
||||||
|
echo "Unable to find block device ${block_dev}"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "Found block device ${block_dev}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d "${mntp}" ]]; then
|
||||||
|
echo "Mountpoint ${mntp} does not exist, creating..."
|
||||||
|
mkdir "${mntp}"
|
||||||
|
else
|
||||||
|
echo "Mountpoint ${mntp} exists"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Mounting ${block_dev} to ${mntp}"
|
||||||
|
mount --options ro "${block_dev}" "${mntp}"
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Mount /boot early in initramfs
|
|
||||||
|
|
||||||
# Initramfs requirement
|
|
||||||
DefaultDependencies=no
|
|
||||||
# Make absolutely sure this only runs in initramfs (and not post-pivot if the
|
|
||||||
# unit ever appears there)
|
|
||||||
ConditionPathExists=/etc/initrd-release
|
|
||||||
ConditionKernelCommandLine=root
|
|
||||||
|
|
||||||
# we use /dev/disk/by-label because it identifies the boot partition system
|
|
||||||
# independently IF set up correctly
|
|
||||||
Requires=dev-disk-by\x2dlabel-boot.device
|
|
||||||
|
|
||||||
# Ordering dependencies
|
|
||||||
After=dev-disk-by\x2dlabel-boot.device
|
|
||||||
Before=sel-ebc-pvebc.service
|
|
||||||
|
|
||||||
[Mount]
|
|
||||||
# system independent identification of boot partition requires that the label
|
|
||||||
# boot is set for the boot partition
|
|
||||||
What=/dev/disk/by-label/boot
|
|
||||||
Where=/boot
|
|
||||||
Type=auto
|
|
||||||
Options=defaults
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=sel-ebc-pvebc.service
|
|
||||||
@@ -23,11 +23,11 @@ depends() {
|
|||||||
# Called by dracut
|
# Called by dracut
|
||||||
installkernel() {
|
installkernel() {
|
||||||
# kernel modules needed for opening an encrypted rfs
|
# kernel modules needed for opening an encrypted rfs
|
||||||
instmods -c uvdevice
|
hostonly='' instmods -c uvdevice
|
||||||
instmods -c paes_s390
|
hostonly='' instmods -c paes_s390
|
||||||
instmods -c pkey_uv
|
hostonly='' instmods -c pkey_uv
|
||||||
instmods -c pkey_pckmo
|
hostonly='' instmods -c pkey_pckmo
|
||||||
instmods -c pkey
|
hostonly='' instmods -c pkey
|
||||||
}
|
}
|
||||||
|
|
||||||
# Called by dracut
|
# Called by dracut
|
||||||
@@ -43,8 +43,8 @@ install() {
|
|||||||
"$systemdsystemunitdir/sel-ebc-paes-enforce.service"
|
"$systemdsystemunitdir/sel-ebc-paes-enforce.service"
|
||||||
inst_simple "$moddir/sel-ebc-override-crypttab.service" \
|
inst_simple "$moddir/sel-ebc-override-crypttab.service" \
|
||||||
"$systemdsystemunitdir/sel-ebc-override-crypttab.service"
|
"$systemdsystemunitdir/sel-ebc-override-crypttab.service"
|
||||||
inst_simple "$moddir/boot.mount" \
|
inst_simple "$moddir/sel-ebc-boot-mount.service" \
|
||||||
"$systemdsystemunitdir/boot.mount"
|
"$systemdsystemunitdir/sel-ebc-boot-mount.service"
|
||||||
|
|
||||||
# already exisitng unit we depend on for kernel modules
|
# already exisitng unit we depend on for kernel modules
|
||||||
inst_simple /usr/lib/systemd/system/systemd-modules-load.service \
|
inst_simple /usr/lib/systemd/system/systemd-modules-load.service \
|
||||||
@@ -58,6 +58,14 @@ install() {
|
|||||||
inst_simple "$moddir/override-crypttab.sh" \
|
inst_simple "$moddir/override-crypttab.sh" \
|
||||||
"/etc/sel-ebc/override-crypttab.sh"
|
"/etc/sel-ebc/override-crypttab.sh"
|
||||||
|
|
||||||
|
# mount boot partition to /boot
|
||||||
|
inst_simple "$moddir/boot-mount.sh" \
|
||||||
|
"/etc/sel-ebc/boot-mount.sh"
|
||||||
|
|
||||||
|
# install kernel module dependencies
|
||||||
|
inst_simple "$moddir/sel-ebc-modules.conf" \
|
||||||
|
"/usr/lib/modules-load.d/sel-ebc-modules.conf"
|
||||||
|
|
||||||
# copy main application
|
# copy main application
|
||||||
inst_binary "/usr/bin/pvebc"
|
inst_binary "/usr/bin/pvebc"
|
||||||
inst_binary "/usr/bin/pvsecret"
|
inst_binary "/usr/bin/pvsecret"
|
||||||
@@ -72,5 +80,5 @@ install() {
|
|||||||
systemctl --root "$initdir" --no-reload --quiet enable sel-ebc-override-crypttab.service
|
systemctl --root "$initdir" --no-reload --quiet enable sel-ebc-override-crypttab.service
|
||||||
systemctl --root "$initdir" --no-reload --quiet enable sel-ebc-paes-enforce.service
|
systemctl --root "$initdir" --no-reload --quiet enable sel-ebc-paes-enforce.service
|
||||||
systemctl --root "$initdir" --no-reload --quiet enable systemd-modules-load.service
|
systemctl --root "$initdir" --no-reload --quiet enable systemd-modules-load.service
|
||||||
systemctl --root "$initdir" --no-reload --quiet enable boot.mount
|
systemctl --root "$initdir" --no-reload --quiet enable sel-ebc-boot-mount.service
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,20 @@
|
|||||||
#
|
#
|
||||||
# Copyright IBM Corp.
|
# Copyright IBM Corp.
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
IBM_RSRC_DIR="/etc/sel-ebc"
|
IBM_RSRC_DIR="/etc/sel-ebc"
|
||||||
|
block_dev="$(blkid -L cryptroot)"
|
||||||
|
|
||||||
|
if [[ -z "${block_dev}" ]]; then
|
||||||
|
echo "Unable to find partition with label cryptroot"
|
||||||
|
exit 1
|
||||||
|
elif [[ ! -b "${block_dev}" ]]; then
|
||||||
|
echo "Unable to find block device ${block_dev}"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "Found block device ${block_dev}"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ! -f "${IBM_RSRC_DIR}/crypttab" ]]; then
|
if [[ ! -f "${IBM_RSRC_DIR}/crypttab" ]]; then
|
||||||
echo "Error: source file $IBM_RSRC_DIR/crypttab does not exist"
|
echo "Error: source file $IBM_RSRC_DIR/crypttab does not exist"
|
||||||
@@ -15,6 +28,11 @@ cp "${IBM_RSRC_DIR}/crypttab" "/etc/crypttab"
|
|||||||
|
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
|
|
||||||
systemctl restart systemd-cryptsetup@cryptroot_mapper.service
|
udevadm trigger --subsystem-match=block --settle
|
||||||
|
|
||||||
|
if ! systemctl restart systemd-cryptsetup@cryptroot_mapper.service; then
|
||||||
|
systemctl status systemd-cryptsetup@cryptroot_mapper.service
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -48,16 +48,23 @@ fi
|
|||||||
pvebc --toc "$EBC_TMPFS/$TOC"
|
pvebc --toc "$EBC_TMPFS/$TOC"
|
||||||
rc=$?
|
rc=$?
|
||||||
if [[ $rc -ne 0 ]]; then
|
if [[ $rc -ne 0 ]]; then
|
||||||
|
echo "pvebc failed with rc=${rc}"
|
||||||
exit $rc
|
exit $rc
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Retrieve and check for dummy LUKS passphrase
|
# Retrieve and check for dummy LUKS passphrase
|
||||||
pvsecret retrieve --inform name -o "$EBC_TMPFS/$ASR_NAME" --outform bin "$ASR_NAME"
|
pvsecret retrieve --inform name -o "$EBC_TMPFS/$ASR_NAME" --outform bin "$ASR_NAME"
|
||||||
|
rc=$?
|
||||||
|
if [[ $rc -ne 0 ]]; then
|
||||||
|
echo "pvsecret failed with rc=${rc}"
|
||||||
|
exit $rc
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ! -f "$EBC_TMPFS/$ASR_NAME" ]]; then
|
if [[ ! -f "$EBC_TMPFS/$ASR_NAME" ]]; then
|
||||||
echo "$EBC_TMPFS/$ASR_NAME does not exist"
|
echo "$EBC_TMPFS/$ASR_NAME does not exist"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
chmod 400 "$EBC_TMPFS/$ASR_NAME"
|
chmod 400 "$EBC_TMPFS/$ASR_NAME"
|
||||||
|
|
||||||
exit 0
|
exit $?
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Mount a partition identified by label boot to /boot
|
||||||
|
|
||||||
|
# Ensure this runs before the handoff to the real root, if that's required:
|
||||||
|
Before=sel-ebc-pvebc.service
|
||||||
|
|
||||||
|
# Initramfs requirement
|
||||||
|
DefaultDependencies=no
|
||||||
|
# Make absolutely sure this only runs in initramfs
|
||||||
|
ConditionPathExists=/etc/initrd-release
|
||||||
|
ConditionKernelCommandLine=rd.sel-ebc
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/bin/bash /etc/sel-ebc/boot-mount.sh
|
||||||
|
RemainAfterExit=yes
|
||||||
|
# On failure immediately abort boot
|
||||||
|
FailureAction=poweroff-immediate
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
RequiredBy=sel-ebc-pvebc.service
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
uvdevice
|
||||||
|
paes_s390
|
||||||
|
pkey_uv
|
||||||
|
pkey_pckmo
|
||||||
|
pkey
|
||||||
@@ -4,10 +4,8 @@ Description=Override crypttab
|
|||||||
# boot partition contains SICS
|
# boot partition contains SICS
|
||||||
# Loading of kernel modules is required which are needed for protected keys
|
# Loading of kernel modules is required which are needed for protected keys
|
||||||
Requires=systemd-modules-load.service
|
Requires=systemd-modules-load.service
|
||||||
Requires=boot.mount
|
|
||||||
|
|
||||||
# Ensure this runs before the handoff to the real root, if that's required:
|
# Ensure this runs before the handoff to the real root, if that's required:
|
||||||
After=boot.mount
|
|
||||||
After=systemd-modules-load.service
|
After=systemd-modules-load.service
|
||||||
Before=cryptsetup-pre.target
|
Before=cryptsetup-pre.target
|
||||||
Before=cryptsetup.target
|
Before=cryptsetup.target
|
||||||
@@ -30,8 +28,8 @@ RemainAfterExit=yes
|
|||||||
FailureAction=poweroff-immediate
|
FailureAction=poweroff-immediate
|
||||||
# boot partition is unencrypted and contains SICS so we can get logs out this way
|
# boot partition is unencrypted and contains SICS so we can get logs out this way
|
||||||
# logs do not leek any sensitive information
|
# logs do not leek any sensitive information
|
||||||
StandardOutput=file:/boot/sics/log
|
StandardOutput=console
|
||||||
StandardError=file:/boot/sics/log
|
StandardError=console
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
RequiredBy=sel-ebc.target
|
RequiredBy=sel-ebc.target
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ FailureAction=poweroff-immediate
|
|||||||
RemainAfterExit=yes
|
RemainAfterExit=yes
|
||||||
|
|
||||||
# logs do not leek any sensitive information
|
# logs do not leek any sensitive information
|
||||||
StandardOutput=file:/boot/sics/log
|
StandardOutput=console
|
||||||
StandardError=file:/boot/sics/log
|
StandardError=console
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
RequiredBy=sel-ebc.target
|
RequiredBy=sel-ebc.target
|
||||||
|
|||||||
@@ -4,14 +4,14 @@ Description=Run pvebc during early boot to process SICS
|
|||||||
# boot partition contains SICS
|
# boot partition contains SICS
|
||||||
# Loading of kernel modules is required which are needed for protected keys
|
# Loading of kernel modules is required which are needed for protected keys
|
||||||
Requires=systemd-modules-load.service
|
Requires=systemd-modules-load.service
|
||||||
Wants=boot.mount
|
Requires=sel-ebc-boot-mount.service
|
||||||
|
|
||||||
# Ensure this runs before the handoff to the real root, if that's required:
|
# Ensure this runs before the handoff to the real root, if that's required:
|
||||||
Before=initrd-root-device.target
|
Before=initrd-root-device.target
|
||||||
Before=cryptsetup-pre.target
|
Before=cryptsetup-pre.target
|
||||||
Before=cryptsetup.target
|
Before=cryptsetup.target
|
||||||
After=boot.mount
|
|
||||||
After=systemd-modules-load.service
|
After=systemd-modules-load.service
|
||||||
|
After=sel-ebc-boot-mount.service
|
||||||
|
|
||||||
# Initramfs requirement
|
# Initramfs requirement
|
||||||
DefaultDependencies=no
|
DefaultDependencies=no
|
||||||
@@ -29,8 +29,8 @@ RemainAfterExit=yes
|
|||||||
FailureAction=poweroff-immediate
|
FailureAction=poweroff-immediate
|
||||||
# boot partition is unencrypted and contains SICS so we can get logs out this way
|
# boot partition is unencrypted and contains SICS so we can get logs out this way
|
||||||
# logs do not leek any sensitive information
|
# logs do not leek any sensitive information
|
||||||
StandardOutput=file:/boot/sics/log
|
StandardOutput=console
|
||||||
StandardError=file:/boot/sics/log
|
StandardError=console
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
RequiredBy=sel-ebc.target
|
RequiredBy=sel-ebc.target
|
||||||
|
|||||||
+75
-13
@@ -253,6 +253,28 @@ Optional. No user-data by default.
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
`--policy <FILE>`
|
||||||
|
<ul>
|
||||||
|
Links an Add‑Secret-Request (ASR) to a policy file. This option embeds a
|
||||||
|
PolicyReference in the ASR user data field. The PolicyReference includes the
|
||||||
|
relative file path and the SHA‑512 hash of the policy file, allowing the
|
||||||
|
policy’s integrity to be verified.
|
||||||
|
|
||||||
|
This option conflicts with --user-data, because both options use the same user
|
||||||
|
data field in the ASR structure.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
`--toc-policy <FILE>`
|
||||||
|
<ul>
|
||||||
|
Adds the AES‑GCM authentication tag to a TOC policy file. This option appends
|
||||||
|
the AES‑GCM authentication tag to the specified TOC policy file. This allows
|
||||||
|
the TOC policy to maintain a list of all ASR MAC tags for completeness
|
||||||
|
verification during boot. During verification, the TOC checks the MAC tags
|
||||||
|
against this list to ensure that all expected ASRs are present and unmodified.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
`--user-sign-key <FILE>`
|
`--user-sign-key <FILE>`
|
||||||
<ul>
|
<ul>
|
||||||
Use the content of FILE as user signing key. Adds a signature calculated from
|
Use the content of FILE as user signing key. Adds a signature calculated from
|
||||||
@@ -407,14 +429,14 @@ Print help (see a summary with '-h').
|
|||||||
|
|
||||||
## pvsecret add
|
## pvsecret add
|
||||||
### Synopsis
|
### Synopsis
|
||||||
`pvsecret add [OPTIONS] <FILE>`
|
`pvsecret add [OPTIONS] [INPUT]`
|
||||||
### Description
|
### Description
|
||||||
Submit an add-secret request to the Ultravisor (s390x only). Perform an
|
Submit an add-secret request to the Ultravisor (s390x only). Perform an
|
||||||
add-secret request using a previously generated add-secret request. Only
|
add-secret request using a previously generated add-secret request. Only
|
||||||
available on s390x.
|
available on s390x.
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
`<FILE>`
|
`<INPUT>`
|
||||||
<ul>
|
<ul>
|
||||||
Specify the request to be sent.
|
Specify the request to be sent.
|
||||||
</ul>
|
</ul>
|
||||||
@@ -422,6 +444,12 @@ Specify the request to be sent.
|
|||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
|
`-i`, `--input <FILE>`
|
||||||
|
<ul>
|
||||||
|
Specify the request to be sent.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
`-f`, `--force`
|
`-f`, `--force`
|
||||||
<ul>
|
<ul>
|
||||||
Force the addition of add-secret requests. Add an add-secret request even if
|
Force the addition of add-secret requests. Add an add-secret request even if
|
||||||
@@ -445,22 +473,27 @@ fail. Only available on s390x.
|
|||||||
|
|
||||||
## pvsecret list
|
## pvsecret list
|
||||||
### Synopsis
|
### Synopsis
|
||||||
`pvsecret list [OPTIONS] [FILE]`
|
`pvsecret list [OPTIONS] [OUTPUT]`
|
||||||
### Description
|
### Description
|
||||||
List all ultravisor secrets (s390x only). Lists the IDs of all non-null secrets
|
List all ultravisor secrets (s390x only). Lists the IDs of all non-null secrets
|
||||||
currently stored in the ultravisor for the currently running IBM Secure
|
currently stored in the ultravisor for the currently running IBM Secure
|
||||||
Execution guest. Only available on s390x.
|
Execution guest. Only available on s390x.
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
`<FILE>`
|
`<OUTPUT>`
|
||||||
<ul>
|
<ul>
|
||||||
Store the result in FILE.
|
Store the result in FILE.
|
||||||
Default value: '-'
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
|
`-o`, `--output <FILE>`
|
||||||
|
<ul>
|
||||||
|
Store the result in FILE.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
`--format <FORMAT>`
|
`--format <FORMAT>`
|
||||||
<ul>
|
<ul>
|
||||||
Define the output format of the list.
|
Define the output format of the list.
|
||||||
@@ -480,7 +513,7 @@ Print help (see a summary with '-h').
|
|||||||
|
|
||||||
## pvsecret verify
|
## pvsecret verify
|
||||||
### Synopsis
|
### Synopsis
|
||||||
`pvsecret verify [OPTIONS] <FILE>`
|
`pvsecret verify [OPTIONS] [INPUT] [OUTPUT]`
|
||||||
### Description
|
### Description
|
||||||
Verifies that the given request is an Add-Secret request by testing for some
|
Verifies that the given request is an Add-Secret request by testing for some
|
||||||
values to be present. If the request contains signed user-data, the signature
|
values to be present. If the request contains signed user-data, the signature
|
||||||
@@ -520,14 +553,27 @@ The verification process works as follows:
|
|||||||
|
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
`<FILE>`
|
`<INPUT>`
|
||||||
<ul>
|
<ul>
|
||||||
Specify the request to be checked.
|
Specify the request to be checked.
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
`<OUTPUT>`
|
||||||
|
<ul>
|
||||||
|
Store the result in FILE If the request contained abirtary user-data the output
|
||||||
|
contains this user-data with padded zeros if available.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
|
`-i`, `--input <FILE>`
|
||||||
|
<ul>
|
||||||
|
Specify the request to be checked.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
`--user-cert <FILE>`
|
`--user-cert <FILE>`
|
||||||
<ul>
|
<ul>
|
||||||
Certificate containing a public key used to verify the user data signature.
|
Certificate containing a public key used to verify the user data signature.
|
||||||
@@ -540,11 +586,10 @@ curve over a 521 bit prime field (secp521r1).
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
`-o`, `--output <FILE>`
|
`-o`, `--output <OUTPUT>`
|
||||||
<ul>
|
<ul>
|
||||||
Store the result in FILE If the request contained abirtary user-data the output
|
Store the result in FILE If the request contained abirtary user-data the output
|
||||||
contains this user-data with padded zeros if available.
|
contains this user-data with padded zeros if available.
|
||||||
Default value: '-'
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
@@ -556,13 +601,13 @@ Print help (see a summary with '-h').
|
|||||||
|
|
||||||
## pvsecret retrieve
|
## pvsecret retrieve
|
||||||
### Synopsis
|
### Synopsis
|
||||||
`pvsecret retrieve [OPTIONS] <ID>`
|
`pvsecret retrieve [OPTIONS] [INPUT] [OUTPUT]`
|
||||||
`pvsecret retr [OPTIONS] <ID>`
|
`pvsecret retr [OPTIONS] [INPUT] [OUTPUT]`
|
||||||
### Description
|
### Description
|
||||||
Retrieve a secret from the UV secret store (s390x only)
|
Retrieve a secret from the UV secret store (s390x only)
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
`<ID>`
|
`<INPUT>`
|
||||||
<ul>
|
<ul>
|
||||||
Specify the secret ID to be retrieved. Input type depends on '--inform'. If
|
Specify the secret ID to be retrieved. Input type depends on '--inform'. If
|
||||||
`yaml` (default) is specified, it must be a yaml created by the create
|
`yaml` (default) is specified, it must be a yaml created by the create
|
||||||
@@ -574,12 +619,29 @@ retrieved.
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
`<OUTPUT>`
|
||||||
|
<ul>
|
||||||
|
Specify the output path to place the secret value.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
|
`-i`, `--input <ID>`
|
||||||
|
<ul>
|
||||||
|
Specify the secret ID to be retrieved. Input type depends on '--inform'. If
|
||||||
|
`yaml` (default) is specified, it must be a yaml created by the create
|
||||||
|
subcommand of this tool. If `hex` is specified, it must be a 32 byte handle
|
||||||
|
encodes in hexadecimal. Leading zeros are required. If there are multiple
|
||||||
|
secrets in the store with the same Id there are no guarantees on which specific
|
||||||
|
secret is retrieved. Use --inform=idx to make sure a specific secret is
|
||||||
|
retrieved.
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
`-o`, `--output <FILE>`
|
`-o`, `--output <FILE>`
|
||||||
<ul>
|
<ul>
|
||||||
Specify the output path to place the secret value.
|
Specify the output path to place the secret value.
|
||||||
Default value: '-'
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVSECRET-ADD" "1" "2026-02-12" "s390-tools" "UV\-Secret Manual"
|
.TH "PVSECRET-ADD" "1" "2026-05-21" "s390-tools" "UV\-Secret Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -11,7 +11,7 @@ pvsecret-add \- Submit an add-secret request to the Ultravisor (s390x only)
|
|||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.fam C
|
.fam C
|
||||||
pvsecret add [OPTIONS] <FILE>
|
pvsecret add [OPTIONS] [INPUT]
|
||||||
.fam C
|
.fam C
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
@@ -19,12 +19,18 @@ Perform an add\-secret request using a previously generated add\-secret request.
|
|||||||
Only available on s390x.
|
Only available on s390x.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.PP
|
.PP
|
||||||
<FILE>
|
<INPUT>
|
||||||
.RS 4
|
.RS 4
|
||||||
Specify the request to be sent.
|
Specify the request to be sent.
|
||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\-i, \-\-input <FILE>
|
||||||
|
.RS 4
|
||||||
|
Specify the request to be sent.
|
||||||
|
.RE
|
||||||
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\-f, \-\-force
|
\-f, \-\-force
|
||||||
.RS 4
|
.RS 4
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVSECRET-CREATE-RETRIEVABLE" "1" "2026-02-12" "s390-tools" "UV\-Secret Manual"
|
.TH "PVSECRET-CREATE-RETRIEVABLE" "1" "2026-05-20" "s390-tools" "UV\-Secret Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -29,30 +29,30 @@ the following curves: secp256r1, secp384r1, secp521r1, ed25519, or ed448.
|
|||||||
\fBHMAC\-SHA preprocessing\fP
|
\fBHMAC\-SHA preprocessing\fP
|
||||||
|
|
||||||
.RS 2
|
.RS 2
|
||||||
The \fBHMAC\-SHA\fP key supplied in the plain bytes file is the key \fBK_0\fP
|
The \fBHMAC\-SHA\fP key supplied in the plain bytes file is the key \fBK_0\fP as
|
||||||
as of \fBFIPS\-198\-1\fP, i.e. the key \fBK\fP after any necessary
|
of \fBFIPS\-198\-1\fP, i.e. the key \fBK\fP after any necessary pre\-processing.
|
||||||
pre\-processing. The pre\-processing must be performed by the user prior to
|
The pre\-processing must be performed by the user prior to creating the
|
||||||
creating the retrievable secret.
|
retrievable secret.
|
||||||
.PP Pre\-processing means that if the key \fBK\fP is shorter than the block
|
.PP Pre\-processing means that if the key \fBK\fP is shorter than the block size
|
||||||
size of the to\-be\-used HMAC digest, then the key must be padded with binary
|
of the to\-be\-used HMAC digest, then the key must be padded with binary zeros
|
||||||
zeros to the right up to the block size. The block size of SHA\-224 and
|
to the right up to the block size. The block size of SHA\-224 and SHA\-256 is
|
||||||
SHA\-256 is 512 bits (64 bytes) and the bock size of SHA\-384 and SHA\-512 is
|
512 bits (64 bytes) and the bock size of SHA\-384 and SHA\-512 is 1024 bits (128
|
||||||
1024 bits (128 bytes). Such padding can for example be achieved by using the
|
bytes). Such padding can for example be achieved by using the \fBtruncate\fP
|
||||||
\fBtruncate\fP command with the desired size in bytes, e.g. \fB'truncate
|
command with the desired size in bytes, e.g. \fB'truncate \-\-size 64
|
||||||
\-\-size 64 <key\-file>'\fP for creating a \fBK_0\fP key for HMAC\-SHA\-224
|
<key\-file>'\fP for creating a \fBK_0\fP key for HMAC\-SHA\-224 and
|
||||||
and HMAC\-SHA\-256.
|
HMAC\-SHA\-256.
|
||||||
.PP
|
.PP
|
||||||
In case key \fBK\fP is longer than the block size of the to\-be\-used HMAC
|
In case key \fBK\fP is longer than the block size of the to\-be\-used HMAC
|
||||||
digest, then key \fBK\fP must first be hashed with the to\-be\-used HMAC
|
digest, then key \fBK\fP must first be hashed with the to\-be\-used HMAC digest,
|
||||||
digest, and the result must then be padded with binary zeros to the right up to
|
and the result must then be padded with binary zeros to the right up to the
|
||||||
the block size of the digest. This can be achieved by using the following
|
block size of the digest. This can be achieved by using the following OpenSSL
|
||||||
OpenSSL command followed by the \fBtruncate\fP command: \fB'openssl sha256
|
command followed by the \fBtruncate\fP command: \fB'openssl sha256 \-binary
|
||||||
\-binary \-out <key2\-file> <key\-file>'\fP and then \fB'truncate \-\-size
|
\-out <key2\-file> <key\-file>'\fP and then \fB'truncate \-\-size 64
|
||||||
64 <key2\-file>'\fP for creating a \fBK_0\fP key for HMAC\-SHA\-256.
|
<key2\-file>'\fP for creating a \fBK_0\fP key for HMAC\-SHA\-256.
|
||||||
.PP
|
.PP
|
||||||
\fBATTENTION:\fP The digest used for hashing the key \fBK\fP must be the exact
|
\fBATTENTION:\fP The digest used for hashing the key \fBK\fP must be the exact
|
||||||
same as the later to\-be\-used HMAC digest! If the pre\-processing and the
|
same as the later to\-be\-used HMAC digest! If the pre\-processing and the HMAC
|
||||||
HMAC calculation use different digests, then a wrong MAC is calculated!
|
calculation use different digests, then a wrong MAC is calculated!
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVSECRET-CREATE-UPDATE-CCK" "1" "2026-02-12" "s390-tools" "UV\-Secret Manual"
|
.TH "PVSECRET-CREATE-UPDATE-CCK" "1" "2026-05-20" "s390-tools" "UV\-Secret Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -18,6 +18,7 @@ pvsecret create cck \-\-secret <CCK\-FILE>
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Insert a customer communication key into a guest.
|
Insert a customer communication key into a guest.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\-\-secret <CCK\-FILE>
|
\-\-secret <CCK\-FILE>
|
||||||
.RS 4
|
.RS 4
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVSECRET-CREATE" "1" "2026-02-12" "s390-tools" "UV\-Secret Manual"
|
.TH "PVSECRET-CREATE" "1" "2026-05-19" "s390-tools" "UV\-Secret Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -55,6 +55,7 @@ Update customer communication key
|
|||||||
.RE
|
.RE
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\-k, \-\-host\-key\-document <FILE>
|
\-k, \-\-host\-key\-document <FILE>
|
||||||
.RS 4
|
.RS 4
|
||||||
@@ -196,23 +197,23 @@ Optional. No user\-data by default.
|
|||||||
.PP
|
.PP
|
||||||
\-\-policy <FILE>
|
\-\-policy <FILE>
|
||||||
.RS 4
|
.RS 4
|
||||||
Links an add\-secret request to a policy file.
|
Links an Add‑Secret\-Request (ASR) to a policy file. This option embeds a
|
||||||
This option embeds a reference to a policy in the add\-secret request user data field. The
|
PolicyReference in the ASR user data field. The PolicyReference includes the
|
||||||
reference includes the relative file path and the SHA-512 hash of the
|
relative file path and the SHA‑512 hash of the policy file, allowing the
|
||||||
policy file, enabling verification of the policy file’s integrity.
|
policy’s integrity to be verified.
|
||||||
This option conflicts with \fB\-\-user\-data\fR, because both options use the
|
|
||||||
same user data field in the add\-secret request structure.
|
This option conflicts with \-\-user\-data, because both options use the same
|
||||||
|
user data field in the ASR structure.
|
||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\-\-toc\-policy <FILE>
|
\-\-toc\-policy <FILE>
|
||||||
.RS 4
|
.RS 4
|
||||||
Adds the AES\-GCM authentication tag to a table-of-contents (TOC) policy file.
|
Adds the AES‑GCM authentication tag to a TOC policy file. This option appends
|
||||||
This option appends the AES\-GCM authentication tag to the specified TOC policy
|
the AES‑GCM authentication tag to the specified TOC policy file. This allows
|
||||||
file. This allows the TOC policy to maintain a list of all add\-secret request MAC tags for
|
the TOC policy to maintain a list of all ASR MAC tags for completeness
|
||||||
completeness verification during boot. During verification, the TOC checks the
|
verification during boot. During verification, the TOC checks the MAC tags
|
||||||
AES\-GCM tags against this list to ensure that all expected add\-secret request are present and
|
against this list to ensure that all expected ASRs are present and unmodified.
|
||||||
unmodified.
|
|
||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVSECRET-LIST" "1" "2024-12-19" "s390-tools" "UV-Secret Manual"
|
.TH "PVSECRET-LIST" "1" "2026-05-21" "s390-tools" "UV\-Secret Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -11,7 +11,7 @@ pvsecret-list \- List all ultravisor secrets (s390x only)
|
|||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.fam C
|
.fam C
|
||||||
pvsecret list [OPTIONS] [FILE]
|
pvsecret list [OPTIONS] [OUTPUT]
|
||||||
.fam C
|
.fam C
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
@@ -19,13 +19,18 @@ Lists the IDs of all non\-null secrets currently stored in the ultravisor for
|
|||||||
the currently running IBM Secure Execution guest. Only available on s390x.
|
the currently running IBM Secure Execution guest. Only available on s390x.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.PP
|
.PP
|
||||||
<FILE>
|
<OUTPUT>
|
||||||
.RS 4
|
.RS 4
|
||||||
Store the result in FILE.
|
Store the result in FILE.
|
||||||
[default: '-']
|
|
||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\-o, \-\-output <FILE>
|
||||||
|
.RS 4
|
||||||
|
Store the result in FILE.
|
||||||
|
.RE
|
||||||
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\-\-format <FORMAT>
|
\-\-format <FORMAT>
|
||||||
.RS 4
|
.RS 4
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVSECRET-RETRIEVE" "1" "2026-02-12" "s390-tools" "UV\-Secret Manual"
|
.TH "PVSECRET-RETRIEVE" "1" "2026-05-21" "s390-tools" "UV\-Secret Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -11,8 +11,8 @@ pvsecret-retrieve \- Retrieve a secret from the UV secret store (s390x only)
|
|||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.fam C
|
.fam C
|
||||||
pvsecret retrieve [OPTIONS] <ID>
|
pvsecret retrieve [OPTIONS] [INPUT] [OUTPUT]
|
||||||
pvsecret retr [OPTIONS] <ID>
|
pvsecret retr [OPTIONS] [INPUT] [OUTPUT]
|
||||||
.fam C
|
.fam C
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
@@ -24,7 +24,7 @@ keys the PEM name \fBIBM PROTECTED KEY\fP is used.
|
|||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.PP
|
.PP
|
||||||
<ID>
|
<INPUT>
|
||||||
.RS 4
|
.RS 4
|
||||||
Specify the secret ID to be retrieved. Input type depends on \fB\-\-inform\fR.
|
Specify the secret ID to be retrieved. Input type depends on \fB\-\-inform\fR.
|
||||||
If `yaml` (default) is specified, it must be a yaml created by the create
|
If `yaml` (default) is specified, it must be a yaml created by the create
|
||||||
@@ -35,12 +35,29 @@ secret is retrieved. Use \-\-inform=idx to make sure a specific secret is
|
|||||||
retrieved.
|
retrieved.
|
||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
|
.PP
|
||||||
|
<OUTPUT>
|
||||||
|
.RS 4
|
||||||
|
Specify the output path to place the secret value.
|
||||||
|
.RE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\-i, \-\-input <ID>
|
||||||
|
.RS 4
|
||||||
|
Specify the secret ID to be retrieved. Input type depends on \fB\-\-inform\fR.
|
||||||
|
If `yaml` (default) is specified, it must be a yaml created by the create
|
||||||
|
subcommand of this tool. If `hex` is specified, it must be a 32 byte handle
|
||||||
|
encodes in hexadecimal. Leading zeros are required. If there are multiple
|
||||||
|
secrets in the store with the same Id there are no guarantees on which specific
|
||||||
|
secret is retrieved. Use \-\-inform=idx to make sure a specific secret is
|
||||||
|
retrieved.
|
||||||
|
.RE
|
||||||
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\-o, \-\-output <FILE>
|
\-o, \-\-output <FILE>
|
||||||
.RS 4
|
.RS 4
|
||||||
Specify the output path to place the secret value.
|
Specify the output path to place the secret value.
|
||||||
[default: '-']
|
|
||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVSECRET-VERIFY" "1" "2026-02-12" "s390-tools" "UV\-Secret Manual"
|
.TH "PVSECRET-VERIFY" "1" "2026-05-21" "s390-tools" "UV\-Secret Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -11,7 +11,7 @@ pvsecret-verify \- Verify that an add-secret request is sane
|
|||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.fam C
|
.fam C
|
||||||
pvsecret verify [OPTIONS] <FILE>
|
pvsecret verify [OPTIONS] [INPUT] [OUTPUT]
|
||||||
.fam C
|
.fam C
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
@@ -81,12 +81,25 @@ verify the signature of the request but the last 16 bytes
|
|||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.PP
|
.PP
|
||||||
<FILE>
|
<INPUT>
|
||||||
.RS 4
|
.RS 4
|
||||||
Specify the request to be checked.
|
Specify the request to be checked.
|
||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
|
.PP
|
||||||
|
<OUTPUT>
|
||||||
|
.RS 4
|
||||||
|
Store the result in FILE If the request contained abirtary user\-data the output
|
||||||
|
contains this user\-data with padded zeros if available.
|
||||||
|
.RE
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\-i, \-\-input <FILE>
|
||||||
|
.RS 4
|
||||||
|
Specify the request to be checked.
|
||||||
|
.RE
|
||||||
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\-\-user\-cert <FILE>
|
\-\-user\-cert <FILE>
|
||||||
.RS 4
|
.RS 4
|
||||||
@@ -100,11 +113,10 @@ curve over a 521 bit prime field (secp521r1).
|
|||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
\-o, \-\-output <FILE>
|
\-o, \-\-output <OUTPUT>
|
||||||
.RS 4
|
.RS 4
|
||||||
Store the result in FILE If the request contained abirtary user\-data the output
|
Store the result in FILE If the request contained abirtary user\-data the output
|
||||||
contains this user\-data with padded zeros if available.
|
contains this user\-data with padded zeros if available.
|
||||||
[default: '-']
|
|
||||||
.RE
|
.RE
|
||||||
.RE
|
.RE
|
||||||
.PP
|
.PP
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||||
.\"
|
.\"
|
||||||
|
|
||||||
.TH "PVSECRET" "1" "2026-02-12" "s390-tools" "UV\-Secret Manual"
|
.TH "PVSECRET" "1" "2026-05-20" "s390-tools" "UV\-Secret Manual"
|
||||||
.nh
|
.nh
|
||||||
.ad l
|
.ad l
|
||||||
.SH NAME
|
.SH NAME
|
||||||
@@ -76,6 +76,7 @@ Retrieve a secret from the UV secret store (s390x only)
|
|||||||
.RE
|
.RE
|
||||||
|
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\-v, \-\-verbose
|
\-v, \-\-verbose
|
||||||
.RS 4
|
.RS 4
|
||||||
|
|||||||
+118
-13
@@ -6,7 +6,9 @@ use std::fmt::Display;
|
|||||||
|
|
||||||
use clap::error::ErrorKind::ValueValidation;
|
use clap::error::ErrorKind::ValueValidation;
|
||||||
use clap::{ArgGroup, Args, CommandFactory, Parser, Subcommand, ValueEnum, ValueHint};
|
use clap::{ArgGroup, Args, CommandFactory, Parser, Subcommand, ValueEnum, ValueHint};
|
||||||
use utils::{CertificateOptions, DeprecatedVerbosityOptions, STDOUT};
|
use utils::{
|
||||||
|
combined_path_opt, combined_path_req, CertificateOptions, DeprecatedVerbosityOptions, STDOUT,
|
||||||
|
};
|
||||||
|
|
||||||
/// Manage secrets for IBM Secure Execution guests.
|
/// Manage secrets for IBM Secure Execution guests.
|
||||||
///
|
///
|
||||||
@@ -292,8 +294,12 @@ impl Display for RetrieveableSecretInpKind {
|
|||||||
#[derive(Args, Debug)]
|
#[derive(Args, Debug)]
|
||||||
pub struct AddSecretOpt {
|
pub struct AddSecretOpt {
|
||||||
/// Specify the request to be sent.
|
/// Specify the request to be sent.
|
||||||
#[arg(value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
||||||
pub input: String,
|
input: Option<String>,
|
||||||
|
|
||||||
|
/// Specify the request to be sent.
|
||||||
|
#[arg(value_name = "INPUT", value_hint = ValueHint::FilePath, required_unless_present("input"), conflicts_with("input"))]
|
||||||
|
input_pos: Option<String>,
|
||||||
|
|
||||||
/// Force the addition of add-secret requests.
|
/// Force the addition of add-secret requests.
|
||||||
///
|
///
|
||||||
@@ -303,6 +309,22 @@ pub struct AddSecretOpt {
|
|||||||
pub force: bool,
|
pub force: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AddSecretOptComb<'a> {
|
||||||
|
pub input: &'a str,
|
||||||
|
pub force: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a AddSecretOpt> for AddSecretOptComb<'a> {
|
||||||
|
fn from(value: &'a AddSecretOpt) -> Self {
|
||||||
|
let input = combined_path_req(&value.input, &value.input_pos);
|
||||||
|
Self {
|
||||||
|
input,
|
||||||
|
force: value.force,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug, Default)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug, Default)]
|
||||||
pub enum ListSecretOutputType {
|
pub enum ListSecretOutputType {
|
||||||
/// Human-focused, non-parsable output format
|
/// Human-focused, non-parsable output format
|
||||||
@@ -317,19 +339,43 @@ pub enum ListSecretOutputType {
|
|||||||
#[derive(Args, Debug)]
|
#[derive(Args, Debug)]
|
||||||
pub struct ListSecretOpt {
|
pub struct ListSecretOpt {
|
||||||
/// Store the result in FILE
|
/// Store the result in FILE
|
||||||
#[arg(value_name = "FILE", default_value = STDOUT, value_hint = ValueHint::FilePath,)]
|
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
||||||
pub output: String,
|
output: Option<String>,
|
||||||
|
|
||||||
|
/// Store the result in FILE
|
||||||
|
#[arg(value_name = "OUTPUT", value_hint = ValueHint::FilePath, conflicts_with("output"))]
|
||||||
|
output_pos: Option<String>,
|
||||||
|
|
||||||
/// Define the output format of the list.
|
/// Define the output format of the list.
|
||||||
#[arg(long, value_enum, default_value_t)]
|
#[arg(long, value_enum, default_value_t)]
|
||||||
pub format: ListSecretOutputType,
|
pub format: ListSecretOutputType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ListSecretOptComb<'a> {
|
||||||
|
pub output: &'a str,
|
||||||
|
pub format: ListSecretOutputType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a ListSecretOpt> for ListSecretOptComb<'a> {
|
||||||
|
fn from(value: &'a ListSecretOpt) -> Self {
|
||||||
|
let output = combined_path_opt(&value.output, &value.output_pos, STDOUT);
|
||||||
|
Self {
|
||||||
|
output,
|
||||||
|
format: value.format,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Args, Debug)]
|
#[derive(Args, Debug)]
|
||||||
pub struct VerifyOpt {
|
pub struct VerifyOpt {
|
||||||
/// Specify the request to be checked.
|
/// Specify the request to be checked.
|
||||||
#[arg(value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath,)]
|
||||||
pub input: String,
|
input: Option<String>,
|
||||||
|
|
||||||
|
/// Specify the request to be checked.
|
||||||
|
#[arg(value_name = "INPUT", value_hint = ValueHint::FilePath, required_unless_present("input"), conflicts_with("input"))]
|
||||||
|
input_pos: Option<String>,
|
||||||
|
|
||||||
/// Certificate containing a public key used to verify the user data signature.
|
/// Certificate containing a public key used to verify the user data signature.
|
||||||
///
|
///
|
||||||
@@ -345,8 +391,34 @@ pub struct VerifyOpt {
|
|||||||
///
|
///
|
||||||
/// If the request contained abirtary user-data the output contains this user-data with padded
|
/// If the request contained abirtary user-data the output contains this user-data with padded
|
||||||
/// zeros if available.
|
/// zeros if available.
|
||||||
#[arg(short, long, value_name = "FILE", default_value = STDOUT, value_hint = ValueHint::FilePath,)]
|
#[arg(short, long, value_name = "OUTPUT", value_hint = ValueHint::FilePath,)]
|
||||||
pub output: String,
|
output: Option<String>,
|
||||||
|
|
||||||
|
/// Store the result in FILE
|
||||||
|
///
|
||||||
|
/// If the request contained abirtary user-data the output contains this user-data with padded
|
||||||
|
/// zeros if available.
|
||||||
|
#[arg(value_name = "OUTPUT", value_hint = ValueHint::FilePath, conflicts_with("output"))]
|
||||||
|
output_pos: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct VerifyOptComb<'a> {
|
||||||
|
pub input: &'a str,
|
||||||
|
pub user_cert: Option<&'a str>,
|
||||||
|
pub output: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a VerifyOpt> for VerifyOptComb<'a> {
|
||||||
|
fn from(value: &'a VerifyOpt) -> Self {
|
||||||
|
let input = combined_path_req(&value.input, &value.input_pos);
|
||||||
|
let output = combined_path_opt(&value.output, &value.output_pos, STDOUT);
|
||||||
|
Self {
|
||||||
|
input,
|
||||||
|
user_cert: value.user_cert.as_deref(),
|
||||||
|
output,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args, Debug)]
|
#[derive(Args, Debug)]
|
||||||
@@ -358,12 +430,26 @@ pub struct RetrSecretOptions {
|
|||||||
/// handle encodes in hexadecimal. Leading zeros are required. If there are multiple secrets in
|
/// handle encodes in hexadecimal. Leading zeros are required. If there are multiple secrets in
|
||||||
/// the store with the same Id there are no guarantees on which specific secret is retrieved.
|
/// the store with the same Id there are no guarantees on which specific secret is retrieved.
|
||||||
/// Use --inform=idx to make sure a specific secret is retrieved.
|
/// Use --inform=idx to make sure a specific secret is retrieved.
|
||||||
#[arg(value_name = "ID", value_hint = ValueHint::FilePath)]
|
#[arg(short, long, value_name = "ID", value_hint = ValueHint::FilePath)]
|
||||||
pub input: String,
|
input: Option<String>,
|
||||||
|
|
||||||
|
/// Specify the secret ID to be retrieved.
|
||||||
|
///
|
||||||
|
/// Input type depends on '--inform'. If `yaml` (default) is specified, it must be a yaml
|
||||||
|
/// created by the create subcommand of this tool. If `hex` is specified, it must be a 32 byte
|
||||||
|
/// handle encodes in hexadecimal. Leading zeros are required. If there are multiple secrets in
|
||||||
|
/// the store with the same Id there are no guarantees on which specific secret is retrieved.
|
||||||
|
/// Use --inform=idx to make sure a specific secret is retrieved.
|
||||||
|
#[arg(value_name = "INPUT", value_hint = ValueHint::FilePath, required_unless_present("input"), conflicts_with("input"))]
|
||||||
|
input_pos: Option<String>,
|
||||||
|
|
||||||
/// Specify the output path to place the secret value
|
/// Specify the output path to place the secret value
|
||||||
#[arg(short, long, value_name = "FILE", default_value = STDOUT, value_hint = ValueHint::FilePath)]
|
#[arg(short, long, value_name = "FILE", value_hint = ValueHint::FilePath)]
|
||||||
pub output: String,
|
output: Option<String>,
|
||||||
|
|
||||||
|
/// Specify the output path to place the secret value
|
||||||
|
#[arg(value_name = "OUTPUT", value_hint = ValueHint::FilePath, conflicts_with("output"))]
|
||||||
|
output_pos: Option<String>,
|
||||||
|
|
||||||
/// Define input type for the Secret ID
|
/// Define input type for the Secret ID
|
||||||
#[arg(long, value_enum, default_value_t)]
|
#[arg(long, value_enum, default_value_t)]
|
||||||
@@ -400,6 +486,25 @@ pub enum RetrOutFmt {
|
|||||||
Bin,
|
Bin,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RetrSecretOptionsComb<'a> {
|
||||||
|
pub input: &'a str,
|
||||||
|
pub output: &'a str,
|
||||||
|
pub inform: RetrInpFmt,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a RetrSecretOptions> for RetrSecretOptionsComb<'a> {
|
||||||
|
fn from(value: &'a RetrSecretOptions) -> Self {
|
||||||
|
let input = combined_path_req(&value.input, &value.input_pos);
|
||||||
|
let output = combined_path_opt(&value.output, &value.output_pos, STDOUT);
|
||||||
|
Self {
|
||||||
|
input,
|
||||||
|
output,
|
||||||
|
inform: value.inform,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
/// Create a new add-secret request.
|
/// Create a new add-secret request.
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
//
|
//
|
||||||
// Copyright IBM Corp. 2023
|
// Copyright IBM Corp. 2023
|
||||||
|
|
||||||
use crate::{cli::AddSecretOpt, cmd::list::list_uvc};
|
use crate::{
|
||||||
|
cli::{AddSecretOpt, AddSecretOptComb},
|
||||||
|
cmd::list::list_uvc,
|
||||||
|
};
|
||||||
use anyhow::{bail, Context, Result};
|
use anyhow::{bail, Context, Result};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use pv::{
|
use pv::{
|
||||||
@@ -13,15 +16,16 @@ use utils::get_reader_from_cli_file_arg;
|
|||||||
|
|
||||||
/// Do an Add Secret UVC
|
/// Do an Add Secret UVC
|
||||||
pub fn add(opt: &AddSecretOpt) -> Result<()> {
|
pub fn add(opt: &AddSecretOpt) -> Result<()> {
|
||||||
|
let opt_comb = AddSecretOptComb::from(opt);
|
||||||
let uv = UvDevice::open()?;
|
let uv = UvDevice::open()?;
|
||||||
let mut rd_in = get_reader_from_cli_file_arg(&opt.input)?;
|
let mut rd_in = get_reader_from_cli_file_arg(opt_comb.input)?;
|
||||||
let mut cmd =
|
let mut cmd =
|
||||||
AddCmd::new(&mut rd_in).context(format!("Processing input file {}", opt.input))?;
|
AddCmd::new(&mut rd_in).context(format!("Processing input file {}", opt_comb.input))?;
|
||||||
|
|
||||||
if let Some(id) = AddSecretRequest::bin_id(cmd.data().unwrap())? {
|
if let Some(id) = AddSecretRequest::bin_id(cmd.data().unwrap())? {
|
||||||
if list_uvc(&uv)?.iter().any(|e| e.id() == id.as_ref()) {
|
if list_uvc(&uv)?.iter().any(|e| e.id() == id.as_ref()) {
|
||||||
warn!("There is already a secret in the secret store with that id.");
|
warn!("There is already a secret in the secret store with that id.");
|
||||||
match opt.force {
|
match opt_comb.force {
|
||||||
true => warn!("'--force' specified: Adding the secret anyways."),
|
true => warn!("'--force' specified: Adding the secret anyways."),
|
||||||
false => bail!("Unable to add the secret due to duplicated IDs"),
|
false => bail!("Unable to add the secret due to duplicated IDs"),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,7 +322,7 @@ fn write_yaml<P: AsRef<Path>>(
|
|||||||
write_out(&yaml_path, secret_info, "secret information")?;
|
write_out(&yaml_path, secret_info, "secret information")?;
|
||||||
warn!(
|
warn!(
|
||||||
"Successfully wrote secret info to '{}'",
|
"Successfully wrote secret info to '{}'",
|
||||||
yaml_path.display().to_string()
|
yaml_path.display()
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
|
|
||||||
use crate::cli::{ListSecretOpt, ListSecretOutputType};
|
use crate::cli::{ListSecretOpt, ListSecretOptComb, ListSecretOutputType};
|
||||||
use anyhow::{Context, Error, Result};
|
use anyhow::{Context, Error, Result};
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use pv::uv::{ListCmd, SecretList, UvDevice};
|
use pv::uv::{ListCmd, SecretList, UvDevice};
|
||||||
@@ -34,11 +34,12 @@ pub fn list_uvc(uv: &UvDevice) -> Result<SecretList> {
|
|||||||
|
|
||||||
/// Do a List Secrets UVC and output the list in the requested format
|
/// Do a List Secrets UVC and output the list in the requested format
|
||||||
pub fn list(opt: &ListSecretOpt) -> Result<()> {
|
pub fn list(opt: &ListSecretOpt) -> Result<()> {
|
||||||
|
let opt_comb = ListSecretOptComb::from(opt);
|
||||||
let uv = UvDevice::open()?;
|
let uv = UvDevice::open()?;
|
||||||
let secret_list = list_uvc(&uv)?;
|
let secret_list = list_uvc(&uv)?;
|
||||||
let mut wr_out = get_writer_from_cli_file_arg(&opt.output)?;
|
let mut wr_out = get_writer_from_cli_file_arg(opt_comb.output)?;
|
||||||
|
|
||||||
match &opt.format {
|
match opt_comb.format {
|
||||||
ListSecretOutputType::Human => {
|
ListSecretOutputType::Human => {
|
||||||
write!(wr_out, "{secret_list}").context("Cannot generate output")?
|
write!(wr_out, "{secret_list}").context("Cannot generate output")?
|
||||||
}
|
}
|
||||||
@@ -50,10 +51,10 @@ pub fn list(opt: &ListSecretOpt) -> Result<()> {
|
|||||||
}
|
}
|
||||||
wr_out.flush()?;
|
wr_out.flush()?;
|
||||||
|
|
||||||
if opt.output != STDOUT {
|
if opt_comb.output != STDOUT {
|
||||||
warn!(
|
warn!(
|
||||||
"Successfully wrote the list of secrets to '{}'",
|
"Successfully wrote the list of secrets to '{}'",
|
||||||
&opt.output
|
opt_comb.output
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use pv::{
|
|||||||
use utils::get_writer_from_cli_file_arg;
|
use utils::get_writer_from_cli_file_arg;
|
||||||
|
|
||||||
use super::list::list_uvc;
|
use super::list::list_uvc;
|
||||||
use crate::cli::{RetrInpFmt, RetrOutFmt, RetrSecretOptions};
|
use crate::cli::{RetrInpFmt, RetrOutFmt, RetrSecretOptions, RetrSecretOptionsComb};
|
||||||
|
|
||||||
enum Value {
|
enum Value {
|
||||||
Id(SecretId),
|
Id(SecretId),
|
||||||
@@ -31,19 +31,19 @@ impl Display for Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&RetrSecretOptions> for Value {
|
impl TryFrom<&RetrSecretOptionsComb<'_>> for Value {
|
||||||
type Error = anyhow::Error;
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
fn try_from(opt: &RetrSecretOptions) -> Result<Self> {
|
fn try_from(opt: &RetrSecretOptionsComb) -> Result<Self> {
|
||||||
match opt.inform {
|
match opt.inform {
|
||||||
RetrInpFmt::Yaml => match serde_yaml::from_reader(&mut open_file(&opt.input)?)? {
|
RetrInpFmt::Yaml => match serde_yaml::from_reader(&mut open_file(opt.input)?)? {
|
||||||
GuestSecret::Retrievable { id, .. } => Ok(Self::Id(id)),
|
GuestSecret::Retrievable { id, .. } => Ok(Self::Id(id)),
|
||||||
gs => bail!("The file contains a {gs}-secret, which is not retrievable."),
|
gs => bail!("The file contains a {gs}-secret, which is not retrievable."),
|
||||||
},
|
},
|
||||||
RetrInpFmt::Hex => serde_yaml::from_str(&opt.input)
|
RetrInpFmt::Hex => serde_yaml::from_str(opt.input)
|
||||||
.context("Cannot parse SecretId information")
|
.context("Cannot parse SecretId information")
|
||||||
.map(Self::Id),
|
.map(Self::Id),
|
||||||
RetrInpFmt::Name => Ok(Self::Id(SecretId::from_string(&opt.input))),
|
RetrInpFmt::Name => Ok(Self::Id(SecretId::from_string(opt.input))),
|
||||||
RetrInpFmt::Idx => opt
|
RetrInpFmt::Idx => opt
|
||||||
.input
|
.input
|
||||||
.parse()
|
.parse()
|
||||||
@@ -104,8 +104,9 @@ fn retrieve(value: Value) -> Result<RetrievedSecret> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn retr(opt: &RetrSecretOptions) -> Result<()> {
|
pub fn retr(opt: &RetrSecretOptions) -> Result<()> {
|
||||||
let mut output = get_writer_from_cli_file_arg(&opt.output)?;
|
let opt_comb = RetrSecretOptionsComb::from(opt);
|
||||||
let retr_secret = retrieve(opt.try_into()?)
|
let mut output = get_writer_from_cli_file_arg(opt_comb.output)?;
|
||||||
|
let retr_secret = retrieve((&opt_comb).try_into()?)
|
||||||
.context("Could not retrieve the secret from the UV secret store.")?;
|
.context("Could not retrieve the secret from the UV secret store.")?;
|
||||||
|
|
||||||
let out_data = match opt.outform {
|
let out_data = match opt.outform {
|
||||||
@@ -115,7 +116,7 @@ pub fn retr(opt: &RetrSecretOptions) -> Result<()> {
|
|||||||
write(
|
write(
|
||||||
&mut output,
|
&mut output,
|
||||||
out_data.value(),
|
out_data.value(),
|
||||||
&opt.output,
|
opt_comb.output,
|
||||||
"IBM Protected Key",
|
"IBM Protected Key",
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// Copyright IBM Corp. 2024
|
// Copyright IBM Corp. 2024
|
||||||
|
|
||||||
use crate::cli::VerifyOpt;
|
use crate::cli::{VerifyOpt, VerifyOptComb};
|
||||||
use anyhow::{anyhow, Context, Result};
|
use anyhow::{anyhow, Context, Result};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use pv::misc::{read_certs, read_file};
|
use pv::misc::{read_certs, read_file};
|
||||||
@@ -22,16 +22,16 @@ fn read_sgn_key(path: &str) -> Result<PKey<Public>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify(opt: &VerifyOpt) -> Result<()> {
|
pub fn verify(opt: &VerifyOpt) -> Result<()> {
|
||||||
let mut rd_in = get_reader_from_cli_file_arg(&opt.input)?;
|
let opt_comb = VerifyOptComb::from(opt);
|
||||||
|
let mut rd_in = get_reader_from_cli_file_arg(opt_comb.input)?;
|
||||||
let mut data_in = Vec::with_capacity(0x1000);
|
let mut data_in = Vec::with_capacity(0x1000);
|
||||||
rd_in
|
rd_in
|
||||||
.read_to_end(&mut data_in)
|
.read_to_end(&mut data_in)
|
||||||
.with_context(|| format!("Cannot read input file {}", opt.input))?;
|
.with_context(|| format!("Cannot read input file {}", opt_comb.input))?;
|
||||||
|
|
||||||
let verify_cert = opt
|
let verify_cert = opt_comb
|
||||||
.user_cert
|
.user_cert
|
||||||
.as_ref()
|
.map(read_sgn_key)
|
||||||
.map(|p| read_sgn_key(p))
|
|
||||||
.transpose()
|
.transpose()
|
||||||
.context("Cannot read user-verification certificate.")?;
|
.context("Cannot read user-verification certificate.")?;
|
||||||
|
|
||||||
@@ -39,9 +39,9 @@ pub fn verify(opt: &VerifyOpt) -> Result<()> {
|
|||||||
.context("Could not verify the the Add-secret request")?;
|
.context("Could not verify the the Add-secret request")?;
|
||||||
|
|
||||||
if let Some(user_data) = user_data {
|
if let Some(user_data) = user_data {
|
||||||
get_writer_from_cli_file_arg(&opt.output)?
|
get_writer_from_cli_file_arg(opt_comb.output)?
|
||||||
.write_all(&user_data)
|
.write_all(&user_data)
|
||||||
.with_context(|| format!("Cannot write user data to {}", opt.output))?;
|
.with_context(|| format!("Cannot write user data to {}", opt_comb.output))?;
|
||||||
}
|
}
|
||||||
warn!("Successfully verified the request.");
|
warn!("Successfully verified the request.");
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -276,6 +276,29 @@ impl DeprecatedVerbosityOptions {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn combined_path_opt<'a, N: AsRef<str>, P: AsRef<str>>(
|
||||||
|
named: &'a Option<N>,
|
||||||
|
positional: &'a Option<P>,
|
||||||
|
default: &'a str,
|
||||||
|
) -> &'a str {
|
||||||
|
match (named, positional) {
|
||||||
|
(None, Some(i)) => i.as_ref(),
|
||||||
|
(Some(i), None) => i.as_ref(),
|
||||||
|
(Some(_), Some(_)) => unreachable!(),
|
||||||
|
(None, None) => default,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn combined_path_req<'a, N: AsRef<str>, P: AsRef<str>>(
|
||||||
|
named: &'a Option<N>,
|
||||||
|
positional: &'a Option<P>,
|
||||||
|
) -> &'a str {
|
||||||
|
match (named, positional) {
|
||||||
|
(None, Some(i)) => i.as_ref(),
|
||||||
|
(Some(i), None) => i.as_ref(),
|
||||||
|
(Some(_), Some(_)) => unreachable!(),
|
||||||
|
(None, None) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ pub use ::log::LevelFilter;
|
|||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
cli::{
|
cli::{
|
||||||
get_reader_from_cli_file_arg, get_writer_from_cli_file_arg, print_cli_error, print_error,
|
combined_path_opt, combined_path_req, get_reader_from_cli_file_arg,
|
||||||
CertificateOptions, DeprecatedVerbosityOptions, VerbosityOptions, STDIN, STDOUT,
|
get_writer_from_cli_file_arg, print_cli_error, print_error, CertificateOptions,
|
||||||
|
DeprecatedVerbosityOptions, VerbosityOptions, STDIN, STDOUT,
|
||||||
},
|
},
|
||||||
exit_code::{docstring, ExitCodeDoc, ExitCodeTrait, ExitCodeVariantDoc},
|
exit_code::{docstring, ExitCodeDoc, ExitCodeTrait, ExitCodeVariantDoc},
|
||||||
file::{AtomicFile, AtomicFileOperation},
|
file::{AtomicFile, AtomicFileOperation},
|
||||||
|
|||||||
@@ -34,6 +34,21 @@ All operations preserve the original base image. Logs are written to a
|
|||||||
temporary file, with the filename logged as the first message during runtime.
|
temporary file, with the filename logged as the first message during runtime.
|
||||||
Temporary artifacts are automatically cleaned up on completion or failure.
|
Temporary artifacts are automatically cleaned up on completion or failure.
|
||||||
|
|
||||||
|
.SH Base Image Prerequisites
|
||||||
|
The following prerequisites have to be fulfilled by the base image:
|
||||||
|
.IP \(bu 2
|
||||||
|
label of boot partition set to boot
|
||||||
|
.IP \(bu 2
|
||||||
|
label of root partition set to root
|
||||||
|
.IP \(bu 2
|
||||||
|
guest is to be backed by a qcow2 image
|
||||||
|
.IP \(bu 2
|
||||||
|
an initramfs containing the dracut module 95sel-ebc which is part of s390-tools
|
||||||
|
.IP \(bu 2
|
||||||
|
a boot loader specifying that initramfs and a kernel parameter line on which root is specified by label
|
||||||
|
.IP \(bu 2
|
||||||
|
any line starting with default= should be removed from /etc/zipl.conf
|
||||||
|
|
||||||
.SH ACTIONS
|
.SH ACTIONS
|
||||||
.TP
|
.TP
|
||||||
.B list
|
.B list
|
||||||
|
|||||||
@@ -160,6 +160,8 @@ struct job_data {
|
|||||||
int command_line;
|
int command_line;
|
||||||
int is_secure;
|
int is_secure;
|
||||||
int is_ldipl_dump;
|
int is_ldipl_dump;
|
||||||
|
int no_compress;
|
||||||
|
int force;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct target *target_at(struct job_target_data *data,
|
static inline struct target *target_at(struct job_target_data *data,
|
||||||
|
|||||||
+4
-2
@@ -1548,6 +1548,7 @@ get_job_from_section_data(char* data[], struct job_data* job, char* section)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
job->data.dump.mem = -1LL;
|
job->data.dump.mem = -1LL;
|
||||||
|
job->data.dump.no_compress = job->no_compress;
|
||||||
break;
|
break;
|
||||||
case section_mvdump:
|
case section_mvdump:
|
||||||
/* DUMP TO MULTI-VOLUME job */
|
/* DUMP TO MULTI-VOLUME job */
|
||||||
@@ -1570,6 +1571,7 @@ get_job_from_section_data(char* data[], struct job_data* job, char* section)
|
|||||||
(1024LL * 1024LL));
|
(1024LL * 1024LL));
|
||||||
} else
|
} else
|
||||||
job->data.mvdump.mem = -1LL;
|
job->data.mvdump.mem = -1LL;
|
||||||
|
job->data.mvdump.force = job->force;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Should not happen */
|
/* Should not happen */
|
||||||
@@ -2021,8 +2023,8 @@ job_get(int argc, char* argv[], struct job_data** data)
|
|||||||
job->noninteractive = cmdline.noninteractive;
|
job->noninteractive = cmdline.noninteractive;
|
||||||
job->verbose = cmdline.verbose;
|
job->verbose = cmdline.verbose;
|
||||||
job->add_files = cmdline.add_files;
|
job->add_files = cmdline.add_files;
|
||||||
job->data.dump.no_compress = cmdline.no_compress;
|
job->no_compress = cmdline.no_compress;
|
||||||
job->data.mvdump.force = cmdline.force;
|
job->force = cmdline.force;
|
||||||
job->dry_run = cmdline.dry_run;
|
job->dry_run = cmdline.dry_run;
|
||||||
job->is_secure = SECURE_BOOT_UNDEFINED;
|
job->is_secure = SECURE_BOOT_UNDEFINED;
|
||||||
job->is_ldipl_dump = cmdline.is_ldipl_dump;
|
job->is_ldipl_dump = cmdline.is_ldipl_dump;
|
||||||
|
|||||||
Reference in New Issue
Block a user