mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25968033bb | ||
|
|
1e746990c0 | ||
|
|
3002e7f754 | ||
|
|
ea10995f4d | ||
|
|
8b31319ddf | ||
|
|
1df4d66387 | ||
|
|
37348ef662 | ||
|
|
644432ba23 | ||
|
|
6eddae9a8a | ||
|
|
d19f0915c3 | ||
|
|
0ecf18b66d | ||
|
|
26c544998e | ||
|
|
edaa72d68a | ||
|
|
041e3ad996 | ||
|
|
301eece09b | ||
|
|
36bd05c4ba | ||
|
|
8aa3f064af | ||
|
|
48a7da096d | ||
|
|
094f52d604 | ||
|
|
0626dc7a72 | ||
|
|
0180054d07 | ||
|
|
800fe15d21 | ||
|
|
c570f51f5f | ||
|
|
57b70a0fe0 | ||
|
|
cc0d030ce9 | ||
|
|
9dce6793ab | ||
|
|
d8054d1a1a | ||
|
|
5a9c381225 | ||
|
|
3c6890317a | ||
|
|
1c42b9e3e4 | ||
|
|
beb6a1d6fd | ||
|
|
40e4b71159 | ||
|
|
8c0f2491a3 | ||
|
|
e44ae22989 | ||
|
|
3be8be4ac7 | ||
|
|
544c88ca39 | ||
|
|
c7afb5baec | ||
|
|
cc9b202a9b | ||
|
|
9f99706c26 | ||
|
|
8137128a96 | ||
|
|
1cdfb4946e | ||
|
|
5fb30f1e6f | ||
|
|
d8089e69fa | ||
|
|
cbf7f02d69 | ||
|
|
91b1692b16 | ||
|
|
cd8a733c82 | ||
|
|
bcce1e8d18 | ||
|
|
f832428109 | ||
|
|
1d7bb283fd | ||
|
|
a2f14fcfd7 | ||
|
|
bb6a47db55 | ||
|
|
35dd59d04c | ||
|
|
3fa511cfb9 | ||
|
|
c6c4df9697 | ||
|
|
1b0ab844b4 | ||
|
|
92fc94f152 | ||
|
|
f25aaf32b8 | ||
|
|
13f8709ec2 | ||
|
|
6a860a01c3 | ||
|
|
131a910ac5 | ||
|
|
7007937456 |
17
.gitignore
vendored
17
.gitignore
vendored
@@ -34,6 +34,9 @@ iucvterm/src/iucvconn
|
||||
iucvterm/src/iucvtty
|
||||
iucvterm/src/ttyrun
|
||||
iucvterm/test/test_afiucv
|
||||
libekmfweb/check-dep-libekmfweb
|
||||
libekmfweb/detect-openssl-version.dep
|
||||
libekmfweb/libekmfweb.so
|
||||
libutil/util_base_example
|
||||
libutil/util_file_example
|
||||
libutil/util_libc_example
|
||||
@@ -44,8 +47,9 @@ libutil/util_path_example
|
||||
libutil/util_prg_example
|
||||
libutil/util_rec_example
|
||||
libutil/util_scandir_example
|
||||
libzds/libzds.a
|
||||
libvmcp/vmcp_example
|
||||
libzds/libzds.a
|
||||
lsstp/lsstp
|
||||
mon_tools/mon_fsstatd
|
||||
mon_tools/mon_procd
|
||||
osasnmpd/osasnmpd
|
||||
@@ -75,10 +79,10 @@ zdev/src/lszdev
|
||||
zdev/src/lszdev_usage.c
|
||||
zdsfs/zdsfs
|
||||
zdump/zgetdump
|
||||
zfcpdump/cpioinit
|
||||
zfcpdump/zfcpdump_part
|
||||
zfcpdump/zfcpdump-initrd
|
||||
zfcpdump/10-zfcpdump.install
|
||||
zfcpdump/cpioinit
|
||||
zfcpdump/zfcpdump-initrd
|
||||
zfcpdump/zfcpdump_part
|
||||
ziomon/ziomon_mgr
|
||||
ziomon/ziomon_util
|
||||
ziomon/ziomon_zfcpdd
|
||||
@@ -90,9 +94,10 @@ zipl/boot/data.h
|
||||
zipl/src/chreipl_helper.device-mapper
|
||||
zipl/src/zipl
|
||||
zipl/src/zipl_helper.device-mapper
|
||||
zkey/zkey
|
||||
zkey/zkey-cryptsetup
|
||||
zkey/check-dep-zkey
|
||||
zkey/check-dep-zkey-cryptsetup
|
||||
zkey/detect-libcryptsetup.dep
|
||||
zkey/ekmfweb/zkey-ekmfweb.so
|
||||
zkey/zkey
|
||||
zkey/zkey-cryptsetup
|
||||
zpcictl/zpcictl
|
||||
|
||||
@@ -19,6 +19,7 @@ List of all individuals having contributed content to s390-tools
|
||||
- Despina Papadopoulou
|
||||
- Dimitri John Ledkov
|
||||
- Eberhard Pasch
|
||||
- Eduard Shishkin
|
||||
- Einar Lueck
|
||||
- Eric Sandeen
|
||||
- Erwin Vicari
|
||||
@@ -97,6 +98,7 @@ List of all individuals having contributed content to s390-tools
|
||||
- Steffen Maier
|
||||
- Steffen Thoss
|
||||
- Susanne Wintenberger
|
||||
- Sven Schnelle
|
||||
- Sven Schuetz
|
||||
- Swen Schillig
|
||||
- Taraka R. Bodireddy
|
||||
|
||||
25
CHANGELOG.md
25
CHANGELOG.md
@@ -1,5 +1,30 @@
|
||||
Release history for s390-tools (MIT version)
|
||||
--------------------------------------------
|
||||
* __v2.15.0 (2020-10-15)__
|
||||
|
||||
For Linux kernel version: 5.9
|
||||
|
||||
Add new tool:
|
||||
- lsstp: A small utility to display the Server Time Protocol (STP) information present in sysfs
|
||||
|
||||
Changes of existing tools:
|
||||
- dumpconf: support NVMe dump/reipl device
|
||||
- ipl_tools: support clear attribute for nvme re-IPL
|
||||
- zcrypt: Support new config state with lszcrypt and chzcrypt
|
||||
- zkey: Add support for key management system plugins
|
||||
including the KMS commands:
|
||||
bind, unbind, info, configure, rencipher, list, import, refresh
|
||||
- zkey: Add EKMFWeb support to remotely generate secure keys
|
||||
- libekmfweb: Add new EKMFWeb client library
|
||||
- libutil: Add util_file_read_va()
|
||||
- libutil: Add util_file_read_i()/util_file_read_ui()
|
||||
|
||||
Bug Fixes:
|
||||
- cpumf: Fix version and help printout when CPUMF is not installed
|
||||
- ziomon/ziorep_printers: fix virtual adapter CSV output
|
||||
- zipl: Fix Error when title is not the first field in BLS file
|
||||
|
||||
|
||||
* __v2.14.0 (2020-08-21)__
|
||||
|
||||
For Linux kernel version: 5.7 / 5.8
|
||||
|
||||
4
Makefile
4
Makefile
@@ -3,13 +3,13 @@ ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/ar
|
||||
# Include common definitions
|
||||
include common.mak
|
||||
|
||||
LIB_DIRS = libvtoc libutil libzds libdasd libvmdump libccw libvmcp
|
||||
LIB_DIRS = libvtoc libutil libzds libdasd libvmdump libccw libvmcp libekmfweb
|
||||
TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
|
||||
tape390 osasnmpd qetharp ip_watcher qethconf scripts zconf \
|
||||
vmconvert vmcp man mon_tools dasdinfo vmur cpuplugd ipl_tools \
|
||||
ziomon iucvterm hyptop cmsfs-fuse qethqoat zfcpdump zdsfs cpumf \
|
||||
systemd hmcdrvfs cpacfstats zdev dump2tar zkey netboot etc zpcictl \
|
||||
genprotimg
|
||||
genprotimg lsstp
|
||||
|
||||
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)
|
||||
|
||||
|
||||
19
README.md
19
README.md
@@ -243,6 +243,12 @@ Package contents
|
||||
Provides simple tools to create a binary that can be used to implement
|
||||
simple network boot setups following the PXELINUX conventions.
|
||||
|
||||
* libekmfweb:
|
||||
A shared library that provides functions to communicate with an EKMF Web
|
||||
server via REST calls over HTTPS. EKMF Web stands for IBM Enterprise Key
|
||||
Management Foundation - Web Edition, and is used to manage keys in an
|
||||
enterprise.
|
||||
|
||||
For more information refer to the following publications:
|
||||
|
||||
* "Device Drivers, Features, and Commands" chapter "Useful Linux commands"
|
||||
@@ -267,10 +273,11 @@ build options:
|
||||
| pfm | `HAVE_PFM` | cpacfstats |
|
||||
| net-snmp | `HAVE_SNMP` | osasnmpd |
|
||||
| glibc-static | `HAVE_LIBC_STATIC` | zfcpdump |
|
||||
| openssl | `HAVE_OPENSSL` | genprotimg,zkey |
|
||||
| openssl | `HAVE_OPENSSL` | genprotimg, zkey, libekmfweb |
|
||||
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
|
||||
| json-c | `HAVE_JSONC` | zkey-cryptsetup |
|
||||
| json-c | `HAVE_JSONC` | zkey-cryptsetup, libekmfweb |
|
||||
| glib2 | `HAVE_GLIB2` | genprotimg |
|
||||
| libcurl | `HAVE_LIBCURL` | libekmfweb |
|
||||
|
||||
This table lists additional build or install options:
|
||||
|
||||
@@ -397,3 +404,11 @@ the different tools are provided:
|
||||
tool must be added to this group. The owner of the default key repository
|
||||
'/etc/zkey/repository' must be set to group 'zkeyadm' with write permission
|
||||
for this group.
|
||||
|
||||
* libekmfweb:
|
||||
For building the libekmfweb shared library you need openssl version 1.1.1 or
|
||||
newer installed (openssl-devel.rpm). Also required are json-c version 0.13 or
|
||||
newer (json-c-devel.rpm), and libcurl version 7.59 or newer
|
||||
(libcurl-devel.rpm).
|
||||
Tip: you may skip the libekmfweb build by adding `HAVE_OPENSSL=0`,
|
||||
`HAVE_JSONC=0`, or `HAVE_LIBCURL=0` to the make invocation.
|
||||
|
||||
13
common.mak
13
common.mak
@@ -5,7 +5,7 @@ COMMON_INCLUDED = true
|
||||
# The variable "DISTRELEASE" should be overwritten in rpm spec files with:
|
||||
# "make DISTRELEASE=%{release}" and "make install DISTRELEASE=%{release}"
|
||||
VERSION = 2
|
||||
RELEASE = 14
|
||||
RELEASE = 15
|
||||
PATCHLEVEL = 0
|
||||
DISTRELEASE = build-$(shell date +%Y%m%d)
|
||||
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
|
||||
@@ -163,6 +163,7 @@ USRSBINDIR = $(INSTALLDIR)/usr/sbin
|
||||
USRBINDIR = $(INSTALLDIR)/usr/bin
|
||||
BINDIR = $(INSTALLDIR)/sbin
|
||||
LIBDIR = $(INSTALLDIR)/lib
|
||||
LIB64DIR = $(INSTALLDIR)/lib64
|
||||
SYSCONFDIR = $(INSTALLDIR)/etc
|
||||
MANDIR = $(INSTALLDIR)/usr/share/man
|
||||
VARDIR = $(INSTALLDIR)/var
|
||||
@@ -172,14 +173,16 @@ ZFCPDUMP_DIR = $(TOOLS_LIBDIR)/zfcpdump
|
||||
# Systemd support files are installed only if a directory is specified
|
||||
# for SYSTEMDSYSTEMUNITDIR (e.g. /lib/systemd/system)
|
||||
SYSTEMDSYSTEMUNITDIR =
|
||||
USRINCLUDEDIR = $(INSTALLDIR)/usr/include
|
||||
|
||||
INSTDIRS = $(USRSBINDIR) $(USRBINDIR) $(BINDIR) $(LIBDIR) $(MANDIR) \
|
||||
$(SYSCONFDIR) $(SYSCONFDIR)/sysconfig \
|
||||
$(TOOLS_LIBDIR) $(TOOLS_DATADIR) \
|
||||
$(ZFCPDUMP_DIR) $(SYSTEMDSYSTEMUNITDIR)
|
||||
$(ZFCPDUMP_DIR) $(SYSTEMDSYSTEMUNITDIR) \
|
||||
$(LIB64DIR) $(USRINCLUDEDIR)
|
||||
OWNER = $(shell id -un)
|
||||
GROUP = $(shell id -gn)
|
||||
export INSTALLDIR BINDIR LIBDIR MANDIR OWNER GROUP
|
||||
export INSTALLDIR BINDIR LIBDIR LIB64DIR MANDIR OWNER GROUP
|
||||
|
||||
# Special defines for zfcpdump
|
||||
ZFCPDUMP_IMAGE = zfcpdump-image
|
||||
@@ -339,6 +342,10 @@ $(rootdir)/libvmcp/libvmcp.a: $(rootdir)/libvmcp
|
||||
$(MAKE) -C $(rootdir)/libvmcp/ libvmcp.a
|
||||
.PHONY: $(rootdir)/libvmcp
|
||||
|
||||
$(rootdir)/libekmfweb/libekmfweb.so: $(rootdir)/libekmfweb
|
||||
$(MAKE) -C $(rootdir)/libekmfweb/ libekmfweb.so
|
||||
.PHONY: $(rootdir)/libekmfweb
|
||||
|
||||
$(rootdir)/zipl/boot/data.o:
|
||||
$(MAKE) -C $(rootdir)/zipl/boot/ data.o
|
||||
|
||||
|
||||
@@ -60,10 +60,6 @@ static const struct util_prg prg = {
|
||||
}
|
||||
};
|
||||
|
||||
/* Parse tool parameters. Fill in global variables keep_case, buffersize and
|
||||
* command according to parameters. Return VMCP_OK on success, VMCP_OPT
|
||||
* in case of parameter errors. In case of --help or --version, print
|
||||
* respective text to stdout and exit. */
|
||||
static long parse_buffersize(char *string)
|
||||
{
|
||||
char *suffix;
|
||||
@@ -91,6 +87,7 @@ static long parse_buffersize(char *string)
|
||||
|
||||
static int read_sfb(unsigned long *min, unsigned long *max)
|
||||
{
|
||||
unsigned long cur_min_sdb, cur_max_sdb;
|
||||
int rc = EXIT_SUCCESS;
|
||||
FILE *fp;
|
||||
|
||||
@@ -99,9 +96,14 @@ static int read_sfb(unsigned long *min, unsigned long *max)
|
||||
linux_error(PERF_SFB_SIZE);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (fscanf(fp, "%ld,%ld", min, max) != 2) {
|
||||
if (fscanf(fp, "%ld,%ld", &cur_min_sdb, &cur_max_sdb) != 2) {
|
||||
fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE);
|
||||
rc = EXIT_FAILURE;
|
||||
} else {
|
||||
if (*min == 0)
|
||||
*min = cur_min_sdb;
|
||||
if (*max == 0)
|
||||
*max = cur_max_sdb;
|
||||
}
|
||||
fclose(fp);
|
||||
return rc;
|
||||
@@ -196,6 +198,7 @@ int main(int argc, char **argv)
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
|
||||
parse_args(argc, argv);
|
||||
if (stat(PERF_PATH PERF_SF, &sbuf) != 0) {
|
||||
fprintf(stderr,
|
||||
"No CPU-measurement sampling facility detected\n");
|
||||
@@ -203,8 +206,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
if (read_sfb(&min_sdb, &max_sdb))
|
||||
return ret;
|
||||
/* Overwrite min_sdb and/or max_sdb */
|
||||
parse_args(argc, argv);
|
||||
if (min_sdb >= max_sdb) {
|
||||
fprintf(stderr, "The specified maximum must be greater "
|
||||
"than the minimum\n");
|
||||
|
||||
@@ -19,9 +19,11 @@ lscpumf \- display information about CPU-measurement facilities
|
||||
.RB [ \-i | \-\-info ]
|
||||
.br
|
||||
.B lscpumf
|
||||
.RB [ \-c | \-\-list\-counters ] [ \-n ]
|
||||
.RB [ \-C | \-\-list\-all\-counters ] [ \-n ]
|
||||
.RB [ \-s | \-\-list\-sampling\-events ]
|
||||
.RB \-c | \-\-list\-counters | \-C | \-\-list\-all\-counters
|
||||
.RB [ \-n ]
|
||||
.br
|
||||
.B lscpumf
|
||||
.RB \-s | \-\-list\-sampling\-events
|
||||
.br
|
||||
.B lscpumf
|
||||
.BR \-h | \-\-help
|
||||
|
||||
@@ -225,7 +225,7 @@ function CheckDeviceString() {
|
||||
fi
|
||||
}
|
||||
|
||||
setup_device()
|
||||
setup_ccw_device()
|
||||
{
|
||||
DEV="$(CheckDeviceString $DEVICE)"
|
||||
if [ "$DEV" != "" ]; then
|
||||
@@ -235,27 +235,37 @@ setup_device()
|
||||
pr_error "ERROR: Invalid DEVICE '$DEVICE'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
if [ $2 == "fcp" ]; then
|
||||
echo $WWPN > $1/fcp/wwpn 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid WWPN '$WWPN'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
echo $LUN > $1/fcp/lun 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid LUN '$LUN'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
echo $BOOTPROG > $1/fcp/bootprog 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid BOOTPROG '$BOOTPROG'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
echo $BR_LBA > $1/fcp/br_lba 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid BR_LBA '$BR_LBA'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
setup_fcp_device()
|
||||
{
|
||||
DEV="$(CheckDeviceString $DEVICE)"
|
||||
if [ "$DEV" != "" ]; then
|
||||
echo $DEV > $1/$2/device
|
||||
else
|
||||
RETVAL=1
|
||||
pr_error "ERROR: Invalid DEVICE '$DEVICE'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
echo $WWPN > $1/fcp/wwpn 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid WWPN '$WWPN'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
echo $LUN > $1/fcp/lun 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid LUN '$LUN'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
echo $BOOTPROG > $1/fcp/bootprog 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid BOOTPROG '$BOOTPROG'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
echo $BR_LBA > $1/fcp/br_lba 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid BR_LBA '$BR_LBA'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -264,6 +274,30 @@ setup_nss_device()
|
||||
echo $NSS_NAME > $1/nss/name || RETVAL=1
|
||||
}
|
||||
|
||||
setup_nvme_device()
|
||||
{
|
||||
echo $FID > $1/nvme/fid 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid FID '$FID'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
echo $NSID > $1/nvme/nsid 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid NSID '$NSID'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
echo $BOOTPROG > $1/nvme/bootprog 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid BOOTPROG '$BOOTPROG'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
echo $BR_LBA > $1/nvme/br_lba 2>/dev/null || RETVAL=1
|
||||
if [ $RETVAL -eq 1 ]; then
|
||||
pr_error "ERROR: Invalid BR_LBA '$BR_LBA'." $ERRMSG
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
setup_reipl()
|
||||
{
|
||||
if [ "$REIPL_TYPE" == "" ]; then
|
||||
@@ -271,15 +305,25 @@ setup_reipl()
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$REIPL_TYPE" == "ccw" ] || [ "$REIPL_TYPE" == "fcp" ]; then
|
||||
setup_device $REIPL_CONFIG_DIR $REIPL_TYPE
|
||||
elif [ "$REIPL_TYPE" == "nss" ]; then
|
||||
setup_nss_device $REIPL_CONFIG_DIR
|
||||
else
|
||||
pr_error "ERROR: Unknown reipl type '$REIPL_TYPE'." $ERRMSG
|
||||
RETVAL=1
|
||||
return
|
||||
fi
|
||||
case "$REIPL_TYPE" in
|
||||
ccw)
|
||||
setup_ccw_device $REIPL_CONFIG_DIR $REIPL_TYPE
|
||||
;;
|
||||
fcp)
|
||||
setup_fcp_device $REIPL_CONFIG_DIR $REIPL_TYPE
|
||||
;;
|
||||
nvme)
|
||||
setup_nvme_device $REIPL_CONFIG_DIR
|
||||
;;
|
||||
nss)
|
||||
setup_nss_device $REIPL_CONFIG_DIR
|
||||
;;
|
||||
*)
|
||||
pr_error "ERROR: Unknown reipl type '$REIPL_TYPE'." $ERRMSG
|
||||
RETVAL=1
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
echo $REIPL_TYPE > $REIPL_CONFIG_DIR/reipl_type || RETVAL=1
|
||||
|
||||
@@ -292,13 +336,24 @@ setup_reipl()
|
||||
|
||||
setup_dump()
|
||||
{
|
||||
if [ "$DUMP_TYPE" == "ccw" ] || [ "$DUMP_TYPE" == "fcp" ]; then
|
||||
setup_device $DUMP_CONFIG_DIR $DUMP_TYPE
|
||||
elif [ "$DUMP_TYPE" != "none" ]; then
|
||||
pr_error "ERROR: Unknown dump type '$DUMP_TYPE'." $ERRMSG
|
||||
RETVAL=1
|
||||
return
|
||||
fi
|
||||
case "$DUMP_TYPE" in
|
||||
ccw)
|
||||
setup_ccw_device $DUMP_CONFIG_DIR $DUMP_TYPE
|
||||
;;
|
||||
fcp)
|
||||
setup_fcp_device $DUMP_CONFIG_DIR $DUMP_TYPE
|
||||
;;
|
||||
nvme)
|
||||
setup_nvme_device $DUMP_CONFIG_DIR
|
||||
;;
|
||||
none)
|
||||
;;
|
||||
*)
|
||||
pr_error "ERROR: Unknown dump type '$DUMP_TYPE'." $ERRMSG
|
||||
RETVAL=1
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
echo $DUMP_TYPE > $DUMP_CONFIG_DIR/dump_type || RETVAL=1
|
||||
|
||||
@@ -358,6 +413,18 @@ print_ccw_device()
|
||||
pr_info "device..: $DEVICE"
|
||||
}
|
||||
|
||||
print_nvme_device()
|
||||
{
|
||||
FID=$(cat $1/nvme/fid) || RETVAL=1
|
||||
pr_info "fid.....: $FID"
|
||||
NSID=$(cat $1/nvme/nsid) || RETVAL=1
|
||||
pr_info "nsid....: $NSID"
|
||||
BOOTPROG=$(cat $1/nvme/bootprog) || RETVAL=1
|
||||
pr_info "bootprog: $BOOTPROG"
|
||||
BR_LBA=$(cat $1/nvme/br_lba) || RETVAL=1
|
||||
pr_info "br_lba..: $BR_LBA"
|
||||
}
|
||||
|
||||
print_nss_name()
|
||||
{
|
||||
NAME=$(cat $1/nss/device) || RETVAL=1
|
||||
@@ -367,35 +434,52 @@ print_nss_name()
|
||||
status_dump()
|
||||
{
|
||||
CONF_DUMP_TYPE=$(cat $DUMP_CONFIG_DIR/dump_type) || RETVAL=1
|
||||
if [ "$CONF_DUMP_TYPE" == "none" ]; then
|
||||
pr_info "type....: no dump device configured"
|
||||
elif [ "$CONF_DUMP_TYPE" == "ccw" ]; then
|
||||
pr_info "type....: ccw"
|
||||
print_ccw_device $DUMP_CONFIG_DIR
|
||||
verify_ccw_dump_device $(cat $DUMP_CONFIG_DIR/ccw/device)
|
||||
elif [ "$CONF_DUMP_TYPE" == "fcp" ]; then
|
||||
pr_info "type....: fcp"
|
||||
print_fcp_device $DUMP_CONFIG_DIR
|
||||
else
|
||||
pr_error "ERROR: Unknown dump device type '$CONF_DUMP_TYPE'!"
|
||||
pr_error " Please check if you have the latest dumpconf package!"
|
||||
fi
|
||||
case "$CONF_DUMP_TYPE" in
|
||||
none)
|
||||
pr_info "type....: no dump device configured"
|
||||
;;
|
||||
ccw)
|
||||
pr_info "type....: ccw"
|
||||
print_ccw_device $DUMP_CONFIG_DIR
|
||||
verify_ccw_dump_device $(cat $DUMP_CONFIG_DIR/ccw/device)
|
||||
;;
|
||||
fcp)
|
||||
pr_info "type....: fcp"
|
||||
print_fcp_device $DUMP_CONFIG_DIR
|
||||
;;
|
||||
nvme)
|
||||
pr_info "type....: nvme"
|
||||
print_nvme_device $DUMP_CONFIG_DIR
|
||||
;;
|
||||
*)
|
||||
pr_error "ERROR: Unknown dump device type '$CONF_DUMP_TYPE'!"
|
||||
pr_error " Please check if you have the latest dumpconf package!"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
status_reipl()
|
||||
{
|
||||
REIPL_TYPE=$(cat $REIPL_CONFIG_DIR/reipl_type) || RETVAL=1
|
||||
pr_info "type....: $REIPL_TYPE"
|
||||
if [ "$REIPL_TYPE" == "ccw" ]; then
|
||||
print_ccw_device $REIPL_CONFIG_DIR
|
||||
elif [ "$REIPL_TYPE" == "fcp" ]; then
|
||||
print_fcp_device $REIPL_CONFIG_DIR
|
||||
elif [ "$REIPL_TYPE" == "nss" ]; then
|
||||
print_nss_name $REIPL_CONFIG_DIR
|
||||
else
|
||||
pr_error "ERROR: Unknown reipl device type '$REIPL_TYPE'!"
|
||||
pr_error " Please check if you have the latest dumpconf package!"
|
||||
fi
|
||||
case "$REIPL_TYPE" in
|
||||
ccw)
|
||||
print_ccw_device $REIPL_CONFIG_DIR
|
||||
;;
|
||||
fcp)
|
||||
print_fcp_device $REIPL_CONFIG_DIR
|
||||
;;
|
||||
nvme)
|
||||
print_nvme_device $REIPL_CONFIG_DIR
|
||||
;;
|
||||
nss)
|
||||
print_nss_name $REIPL_CONFIG_DIR
|
||||
;;
|
||||
*)
|
||||
pr_error "ERROR: Unknown reipl device type '$REIPL_TYPE'!"
|
||||
pr_error " Please check if you have the latest dumpconf package!"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
status_dump_reipl()
|
||||
|
||||
@@ -39,6 +39,16 @@
|
||||
# BOOTPROG=0
|
||||
# BR_LBA=0
|
||||
|
||||
#
|
||||
# Dump on nvme device (NVMe Disk)
|
||||
#
|
||||
# ON_PANIC=dump
|
||||
# DUMP_TYPE=nvme
|
||||
# FID=0x00000300
|
||||
# NSID=0x00000001
|
||||
# BOOTPROG=3
|
||||
# BR_LBA=0
|
||||
|
||||
#
|
||||
# Use VMDUMP
|
||||
#
|
||||
|
||||
1071
include/ekmfweb/ekmfweb.h
Normal file
1071
include/ekmfweb/ekmfweb.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,8 +12,10 @@
|
||||
#define LIB_UTIL_FILE_H
|
||||
|
||||
int util_file_read_line(char *str, size_t size, const char *fmt, ...);
|
||||
int util_file_read_i(int *val, int base, const char *fmt, ...);
|
||||
int util_file_read_l(long *val, int base, const char *fmt, ...);
|
||||
int util_file_read_ll(long long *val, int base, const char *fmt, ...);
|
||||
int util_file_read_ui(unsigned int *val, int base, const char *fmt, ...);
|
||||
int util_file_read_ul(unsigned long *val, int base, const char *fmt, ...);
|
||||
int util_file_read_ull(unsigned long long *val, int base, const char *fmt, ...);
|
||||
|
||||
@@ -23,4 +25,5 @@ int util_file_write_ll(long long val, int base, const char *fmt, ...);
|
||||
int util_file_write_ul(unsigned long val, int base, const char *fmt, ...);
|
||||
int util_file_write_ull(unsigned long long val, int base, const char *fmt, ...);
|
||||
|
||||
int util_file_read_va(const char *path, const char *fmt, ...);
|
||||
#endif /** LIB_UTIL_FILE_H @} */
|
||||
|
||||
@@ -79,6 +79,7 @@ static const char *const usage_chreipl =
|
||||
" -s --nsid <NAMESPACE_ID> Namespace ID of NVME IPL device (decimal, default 1)\n"
|
||||
" -b, --bootprog <BPROG> Bootprog specification\n"
|
||||
" -L, --loadparm <PARM> Loadparm specification\n"
|
||||
" -c, --clear 0|1 Control if memory is cleared on re-IPL\n"
|
||||
"\n"
|
||||
"Options for nss target:\n"
|
||||
" -n, --name <NAME> Identifier of the NSS\n"
|
||||
@@ -794,6 +795,11 @@ static void chreipl_nvme(void)
|
||||
strlen(l.bootparms), BOOTPARMS_FCP_MAX);
|
||||
}
|
||||
|
||||
if (l.reipl_clear >= 0) {
|
||||
check_exists("reipl/nvme/clear", "NVME re-IPL clear attribute");
|
||||
write_str(l.reipl_clear ? "1" : "0", "reipl/nvme/clear");
|
||||
}
|
||||
|
||||
write_str_optional(l.loadparm, "reipl/nvme/loadparm", l.loadparm_set,
|
||||
"loadparm");
|
||||
write_str_optional(l.bootparms, "reipl/nvme/scp_data", l.bootparms_set,
|
||||
|
||||
@@ -92,6 +92,7 @@ void print_nvme(int show_ipl, int dump)
|
||||
char *path_loadparm = show_ipl ? "/sys/firmware/ipl/loadparm" :
|
||||
"/sys/firmware/reipl/nvme/loadparm";
|
||||
char loadparm[9], loadparm_path[PATH_MAX];
|
||||
char *path_reipl_clear = "/sys/firmware/reipl/nvme/clear";
|
||||
|
||||
if (dump)
|
||||
printf("%-12s nvme_dump\n", get_ipl_banner(show_ipl));
|
||||
@@ -111,6 +112,8 @@ void print_nvme(int show_ipl, int dump)
|
||||
}
|
||||
if (access(path_bootparms, R_OK) == 0)
|
||||
print_fw_str("Bootparms: \"%s\"\n", dir, "scp_data");
|
||||
if (!show_ipl && access(path_reipl_clear, R_OK) == 0)
|
||||
print_fw_str("clear: %s\n", dir, "clear");
|
||||
}
|
||||
|
||||
void print_ccw(int show_ipl)
|
||||
|
||||
@@ -238,6 +238,13 @@ configuration that is defined by the
|
||||
boot menu. Instead it can be used to control higher level boot loaders
|
||||
like GRUB. For more details refer to distribution specific documentation.
|
||||
|
||||
.TP
|
||||
.BR "\-c" " or " "\-\-clear"
|
||||
Specify whether memory should be cleared on re-IPL. Possible values are 0 to
|
||||
disable and 1 to enable memory clearing on re-IPL.
|
||||
Memory clearing is supported if the "clear" attribute is present in
|
||||
/sys/firmware/reipl/nvme/.
|
||||
|
||||
.PP
|
||||
\fBExamples:\fP
|
||||
.br
|
||||
|
||||
85
libekmfweb/Makefile
Normal file
85
libekmfweb/Makefile
Normal file
@@ -0,0 +1,85 @@
|
||||
include ../common.mak
|
||||
|
||||
ifneq (${HAVE_OPENSSL},0)
|
||||
ifneq (${HAVE_JSONC},0)
|
||||
ifneq (${HAVE_LIBCURL},0)
|
||||
BUILD_TARGETS += libekmfweb.so
|
||||
INSTALL_TARGETS += install-libekmfweb.so
|
||||
else
|
||||
BUILD_TARGETS += skip-libekmfweb-curl
|
||||
INSTALL_TARGETS += skip-libekmfweb-curl
|
||||
endif
|
||||
else
|
||||
BUILD_TARGETS += skip-libekmfweb-jsonc
|
||||
INSTALL_TARGETS += skip-libekmfweb-jsonc
|
||||
endif
|
||||
else
|
||||
BUILD_TARGETS += skip-libekmfweb-openssl
|
||||
INSTALL_TARGETS += skip-libekmfweb-openssl
|
||||
endif
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
detect-openssl-version.dep:
|
||||
echo "#include <openssl/opensslv.h>" > detect-openssl-version.dep
|
||||
echo "#include <openssl/evp.h>" >> detect-openssl-version.dep
|
||||
echo "#if OPENSSL_VERSION_NUMBER < 0x10101000L" >> detect-openssl-version.dep
|
||||
echo " #error openssl version 1.1.1 is required" >> detect-openssl-version.dep
|
||||
echo "#endif" >> detect-openssl-version.dep
|
||||
echo "static void __attribute__((unused)) test(void) {" >> detect-openssl-version.dep
|
||||
echo " EVP_PKEY_meth_remove(NULL);" >> detect-openssl-version.dep
|
||||
echo "}" >> detect-openssl-version.dep
|
||||
|
||||
check-dep-libekmfweb: detect-openssl-version.dep
|
||||
$(call check_dep, \
|
||||
"libekmfweb", \
|
||||
"detect-openssl-version.dep", \
|
||||
"openssl-devel version >= 1.1.1", \
|
||||
"HAVE_OPENSSL=0", \
|
||||
-I. -lcrypto)
|
||||
$(call check_dep, \
|
||||
"libekmfweb", \
|
||||
"json-c/json.h", \
|
||||
"json-c-devel", \
|
||||
"HAVE_JSONC=0")
|
||||
$(call check_dep, \
|
||||
"libekmfweb", \
|
||||
"curl/curl.h", \
|
||||
"libcurl-devel", \
|
||||
"HAVE_LIBCURL=0")
|
||||
touch check-dep-libekmfweb
|
||||
|
||||
skip-libekmfweb-openssl:
|
||||
echo " SKIP libekmfweb due to HAVE_OPENSSL=0"
|
||||
|
||||
skip-libekmfweb-jsonc:
|
||||
echo " SKIP libekmfweb due to HAVE_JSONC=0"
|
||||
|
||||
skip-libekmfweb-curl:
|
||||
echo " SKIP libekmfweb due to HAVE_LIBCURL=0"
|
||||
|
||||
all: $(BUILD_TARGETS)
|
||||
|
||||
ekmfweb.o: check-dep-libekmfweb ekmfweb.c utilities.h cca.h $(rootdir)include/ekmfweb/ekmfweb.h
|
||||
utilities.o: check-dep-libekmfweb utilities.c utilities.h $(rootdir)include/ekmfweb/ekmfweb.h
|
||||
cca.o: check-dep-libekmfweb cca.c cca.h utilities.h $(rootdir)include/ekmfweb/ekmfweb.h
|
||||
|
||||
libekmfweb.so: ALL_CFLAGS += -fPIC
|
||||
libekmfweb.so: LDLIBS = -ljson-c -lcrypto -lssl -lcurl -ldl -shared
|
||||
libekmfweb.so: LDFLAGS = -shared -Wl,--version-script=libekmfweb.map \
|
||||
-Wl,-z,defs,-Bsymbolic
|
||||
libekmfweb.so: ekmfweb.o utilities.o cca.o
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
install-libekmfweb.so: libekmfweb.so
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 -T libekmfweb.so $(DESTDIR)$(LIB64DIR)/libekmfweb.so
|
||||
$(INSTALL) -d -m 770 $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 $(rootdir)include/ekmfweb/ekmfweb.h $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
|
||||
|
||||
install: all $(INSTALL_TARGETS)
|
||||
|
||||
clean:
|
||||
rm -f *.o libekmfweb.so check-dep-libekmfweb detect-openssl-version.dep
|
||||
|
||||
.PHONY: all install clean skip-libekmfweb-openssl skip-libekmfweb-jsonc \
|
||||
skip-libekmfweb-curl install-libekmfweb.so
|
||||
1793
libekmfweb/cca.c
Normal file
1793
libekmfweb/cca.c
Normal file
File diff suppressed because it is too large
Load Diff
247
libekmfweb/cca.h
Normal file
247
libekmfweb/cca.h
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* libekmfweb - EKMFWeb client library
|
||||
*
|
||||
* Copyright IBM Corp. 2020
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef CCA_H
|
||||
#define CCA_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <json-c/json.h>
|
||||
|
||||
#include "ekmfweb/ekmfweb.h"
|
||||
|
||||
/* CCA PKA Key Generate function */
|
||||
typedef void (*CSNDPKG_t)(long *return_code,
|
||||
long *reason_code,
|
||||
long *exit_data_length,
|
||||
unsigned char *exit_data,
|
||||
long *rule_array_count,
|
||||
unsigned char *rule_array,
|
||||
long *regeneration_data_length,
|
||||
unsigned char *regeneration_data,
|
||||
long *skeleton_key_token_length,
|
||||
unsigned char *skeleton_key_token,
|
||||
unsigned char *transport_key_identifier,
|
||||
long *generated_key_identifier_length,
|
||||
unsigned char *generated_key_identifier);
|
||||
|
||||
/* CCA PKA Key Token Build function */
|
||||
typedef void (*CSNDPKB_t)(long *return_code,
|
||||
long *reason_code,
|
||||
long *exit_data_length,
|
||||
unsigned char *exit_data,
|
||||
long *rule_array_count,
|
||||
unsigned char *rule_array,
|
||||
long *key_values_structure_length,
|
||||
unsigned char *key_values_structure,
|
||||
long *key_name_ln,
|
||||
unsigned char *key_name,
|
||||
long *reserved_1_length,
|
||||
unsigned char *reserved_1,
|
||||
long *reserved_2_length,
|
||||
unsigned char *reserved_2,
|
||||
long *reserved_3_length,
|
||||
unsigned char *reserved_3,
|
||||
long *reserved_4_length,
|
||||
unsigned char *reserved_4,
|
||||
long *reserved_5_length,
|
||||
unsigned char *reserved_5,
|
||||
long *token_length, unsigned char *token);
|
||||
|
||||
/* CCA PKA Key Token Change function */
|
||||
typedef void (*CSNDKTC_t)(long *return_code,
|
||||
long *reason_code,
|
||||
long *exit_data_length,
|
||||
unsigned char *exit_data,
|
||||
long *rule_array_count,
|
||||
unsigned char *rule_array,
|
||||
long *key_identifier_length,
|
||||
unsigned char *key_identifier);
|
||||
|
||||
/* CCA Digital Signature Generate function */
|
||||
typedef void (*CSNDDSG_t)(long *return_code,
|
||||
long *reason_code,
|
||||
long *exit_data_length,
|
||||
unsigned char *exit_data,
|
||||
long *rule_array_count,
|
||||
unsigned char *rule_array,
|
||||
long *PKA_private_key_identifier_length,
|
||||
unsigned char *PKA_private_key_identifier,
|
||||
long *hash_length,
|
||||
unsigned char *hash,
|
||||
long *signature_field_length,
|
||||
long *signature_bit_length,
|
||||
unsigned char *signature_field);
|
||||
|
||||
/* CCA Key Token Build2 function */
|
||||
typedef void (*CSNBKTB2_t)(long *return_code,
|
||||
long *reason_code,
|
||||
long *exit_data_length,
|
||||
unsigned char *exit_data,
|
||||
long *rule_array_count,
|
||||
unsigned char *rule_array,
|
||||
long *clear_key_bit_length,
|
||||
unsigned char *clear_key_value,
|
||||
long *key_name_length,
|
||||
unsigned char *key_name,
|
||||
long *user_associated_data_length,
|
||||
unsigned char *user_associated_data,
|
||||
long *token_data_length,
|
||||
unsigned char *token_data,
|
||||
long *verb_data_length,
|
||||
unsigned char *verb_data,
|
||||
long *target_key_token_length,
|
||||
unsigned char *target_key_token);
|
||||
|
||||
/* CCA EC Diffie-Hellman function */
|
||||
typedef void (*CSNDEDH_t)(long *return_code,
|
||||
long *reason_code,
|
||||
long *exit_data_length,
|
||||
unsigned char *exit_data,
|
||||
long *rule_array_count,
|
||||
unsigned char *rule_array,
|
||||
long *private_key_identifier_length,
|
||||
unsigned char *private_key_identifier,
|
||||
long *private_KEK_key_identifier_length,
|
||||
unsigned char *private_KEK_key_identifier,
|
||||
long *public_key_identifier_length,
|
||||
unsigned char *public_key_identifier,
|
||||
long *chaining_vector_length,
|
||||
unsigned char *chaining_vector,
|
||||
long *party_info_length,
|
||||
unsigned char *party_info,
|
||||
long *key_bit_length,
|
||||
long *reserved_1_length,
|
||||
unsigned char *reserved_1,
|
||||
long *reserved_2_length,
|
||||
unsigned char *reserved_2,
|
||||
long *reserved_3_length,
|
||||
unsigned char *reserved_3,
|
||||
long *reserved_4_length,
|
||||
unsigned char *reserved_4,
|
||||
long *reserved_5_length,
|
||||
unsigned char *reserved_5,
|
||||
long *output_KEK_key_identifier_length,
|
||||
unsigned char *output_KEK_key_identifier,
|
||||
long *output_key_identifier_length,
|
||||
unsigned char *output_key_identifier);
|
||||
|
||||
/* CCA Symmetric Key Import2 function */
|
||||
typedef void (*CSNDSYI2_t)(long *return_code,
|
||||
long *reason_code,
|
||||
long *exit_data_length,
|
||||
unsigned char *exit_data,
|
||||
long *rule_array_count,
|
||||
unsigned char *rule_array,
|
||||
long *enciphered_key_length,
|
||||
unsigned char *enciphered_key,
|
||||
long *transport_key_identifier_length,
|
||||
unsigned char *transport_key_identifier,
|
||||
long *key_name_length,
|
||||
unsigned char *key_name,
|
||||
long *target_key_identifier_length,
|
||||
unsigned char *target_key_identifier);
|
||||
|
||||
struct cca_lib {
|
||||
CSNDPKB_t dll_CSNDPKB;
|
||||
CSNDPKG_t dll_CSNDPKG;
|
||||
CSNDKTC_t dll_CSNDKTC;
|
||||
CSNDDSG_t dll_CSNDDSG;
|
||||
CSNBKTB2_t dll_CSNBKTB2;
|
||||
CSNDEDH_t dll_CSNDEDH;
|
||||
CSNDSYI2_t dll_CSNDSYI2;
|
||||
};
|
||||
|
||||
#define CCA_MAX_PKA_KEY_TOKEN_SIZE 3500
|
||||
#define CCA_MAX_SYM_KEY_TOKEN_SIZE 725
|
||||
|
||||
int cca_generate_ecc_key_pair(const struct ekmf_cca_lib *cca_lib,
|
||||
int curve_nid, unsigned char *key_token,
|
||||
size_t *key_token_length, bool verbose);
|
||||
|
||||
int cca_generate_rsa_key_pair(const struct ekmf_cca_lib *cca_lib,
|
||||
size_t modulus_bits, unsigned int pub_exp,
|
||||
unsigned char *key_token,
|
||||
size_t *key_token_length, bool verbose);
|
||||
|
||||
int cca_get_key_type(const unsigned char *key_token, size_t key_token_length,
|
||||
int *pkey_type);
|
||||
|
||||
int cca_reencipher_key(const struct ekmf_cca_lib *cca_lib,
|
||||
const unsigned char *key_token, size_t key_token_length,
|
||||
bool to_new, bool verbose);
|
||||
|
||||
int cca_get_ecc_pub_key_as_pkey(const unsigned char *key_token,
|
||||
size_t key_token_length,
|
||||
EVP_PKEY **pkey, bool verbose);
|
||||
|
||||
int cca_get_ecc_pub_key_as_json_web_key(const unsigned char *key_token,
|
||||
size_t key_token_length,
|
||||
json_object **jwk, bool verbose);
|
||||
|
||||
int cca_get_rsa_pub_key_as_pkey(const unsigned char *key_token,
|
||||
size_t key_token_length,
|
||||
int pkey_type, EVP_PKEY **pkey, bool verbose);
|
||||
|
||||
int cca_import_key_from_json_web_key(const struct ekmf_cca_lib *cca_lib,
|
||||
json_object *jwk, unsigned char *key_token,
|
||||
size_t *key_token_length, bool verbose);
|
||||
|
||||
enum cca_kdf {
|
||||
CCA_KDF_ANS_X9_63_CCA = 1, /* CCA DERIVE01 method */
|
||||
CCA_KDF_ANS_X9_63_SHA224 = 2, /* CCA DERIVE02 method with SHA-224 */
|
||||
CCA_KDF_ANS_X9_63_SHA256 = 3, /* CCA DERIVE02 method with SHA-256 */
|
||||
CCA_KDF_ANS_X9_63_SHA384 = 4, /* CCA DERIVE02 method with SHA-284 */
|
||||
CCA_KDF_ANS_X9_63_SHA512 = 5, /* CCA DERIVE02 method with SHA-512 */
|
||||
};
|
||||
|
||||
int cca_ec_dh_derive_importer(const struct ekmf_cca_lib *cca_lib,
|
||||
const unsigned char *priv_ecc_key_token,
|
||||
size_t priv_ecc_key_token_length,
|
||||
const unsigned char *pub_ecc_key_token,
|
||||
size_t pub_ecc_key_token_length,
|
||||
const unsigned char *party_info,
|
||||
size_t party_info_length,
|
||||
enum cca_kdf kdf,
|
||||
unsigned char *derived_key_token,
|
||||
size_t *derived_key_token_length,
|
||||
bool verbose);
|
||||
|
||||
int cca_import_external_key(const struct ekmf_cca_lib *cca_lib,
|
||||
const unsigned char *external_key_token,
|
||||
size_t external_key_token_length,
|
||||
const unsigned char *importer_key_token,
|
||||
size_t importer_key_token_length,
|
||||
unsigned char *imported_key_token,
|
||||
size_t *imported_key_token_length,
|
||||
bool verbose);
|
||||
|
||||
int cca_rsa_sign(const struct ekmf_cca_lib *cca_lib,
|
||||
const unsigned char *key_token, size_t key_token_length,
|
||||
unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen,
|
||||
int padding_type, int digest_nid, bool verbose);
|
||||
|
||||
int cca_rsa_pss_sign(const struct ekmf_cca_lib *cca_lib,
|
||||
const unsigned char *key_token, size_t key_token_length,
|
||||
unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen,
|
||||
int digest_nid, int mgf_digest_nid, int saltlen,
|
||||
bool verbose);
|
||||
|
||||
int cca_ecdsa_sign(const struct ekmf_cca_lib *cca_lib,
|
||||
const unsigned char *key_token, size_t key_token_length,
|
||||
unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen, int digest_nid,
|
||||
bool verbose);
|
||||
|
||||
#endif
|
||||
5631
libekmfweb/ekmfweb.c
Normal file
5631
libekmfweb/ekmfweb.c
Normal file
File diff suppressed because it is too large
Load Diff
30
libekmfweb/libekmfweb.map
Normal file
30
libekmfweb/libekmfweb.map
Normal file
@@ -0,0 +1,30 @@
|
||||
LIBEKMFWEB_1.0 {
|
||||
global:
|
||||
ekmf_get_server_cert_chain;
|
||||
ekmf_print_certificates;
|
||||
ekmf_check_login_token;
|
||||
ekmf_login;
|
||||
ekmf_generate_identity_key;
|
||||
ekmf_reencipher_identity_key;
|
||||
ekmf_generate_csr;
|
||||
ekmf_generate_ss_cert;
|
||||
ekmf_get_public_key;
|
||||
ekmf_get_settings;
|
||||
ekmf_check_feature;
|
||||
ekmf_retrieve_key;
|
||||
ekmf_list_templates;
|
||||
ekmf_get_template;
|
||||
ekmf_get_last_seq_no;
|
||||
ekmf_clone_template_info;
|
||||
ekmf_free_template_info;
|
||||
ekmf_list_keys;
|
||||
ekmf_get_key_info;
|
||||
ekmf_set_key_state;
|
||||
ekmf_set_key_tags;
|
||||
ekmf_delete_key_tags;
|
||||
ekmf_clone_key_info;
|
||||
ekmf_free_key_info;
|
||||
ekmf_generate_key;
|
||||
ekmf_curl_destroy;
|
||||
local: *;
|
||||
};
|
||||
3528
libekmfweb/utilities.c
Normal file
3528
libekmfweb/utilities.c
Normal file
File diff suppressed because it is too large
Load Diff
179
libekmfweb/utilities.h
Normal file
179
libekmfweb/utilities.h
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* libekmfweb - EKMFWeb client library
|
||||
*
|
||||
* Copyright IBM Corp. 2020
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef UTILITIES_H
|
||||
#define UTILITIES_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#include <json-c/json.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "ekmfweb/ekmfweb.h"
|
||||
|
||||
int decode_base64url(unsigned char *output, size_t *outlen,
|
||||
const char *input, size_t inlen);
|
||||
|
||||
int encode_base64url(char *output, size_t *outlen,
|
||||
const unsigned char *input, size_t inlen);
|
||||
|
||||
int parse_json_web_token(const char *token, json_object **header_obj,
|
||||
json_object **payload_obj, unsigned char **signature,
|
||||
size_t *signature_len);
|
||||
|
||||
int create_json_web_signature(const char *algorithm, bool b64, const char *kid,
|
||||
const unsigned char *payload, size_t payload_len,
|
||||
bool detached_payload, EVP_MD_CTX *md_ctx,
|
||||
char **jws);
|
||||
|
||||
int verify_json_web_signature(const char *jws, const unsigned char *payload,
|
||||
size_t payload_len, EVP_PKEY *pkey);
|
||||
|
||||
json_object *get_json_timestamp(void);
|
||||
|
||||
int json_build_tag_def_list(json_object *array,
|
||||
struct ekmf_tag_def_list *tag_def_list,
|
||||
bool copy);
|
||||
int clone_tag_def_list(const struct ekmf_tag_def_list *src,
|
||||
struct ekmf_tag_def_list *dest);
|
||||
void free_tag_def_list(struct ekmf_tag_def_list *tag_def_list, bool free_tags);
|
||||
|
||||
int json_build_template_info(json_object *obj,
|
||||
struct ekmf_template_info *template,
|
||||
bool copy);
|
||||
int clone_template_info(const struct ekmf_template_info *src,
|
||||
struct ekmf_template_info *dest);
|
||||
void free_template_info(struct ekmf_template_info *template);
|
||||
|
||||
int json_build_tag_list(json_object *array, struct ekmf_tag_list *tag_list,
|
||||
bool copy);
|
||||
int build_json_tag_list(const struct ekmf_tag_list *tag_list,
|
||||
json_object **tags_obj);
|
||||
int clone_tag_list(const struct ekmf_tag_list *src,
|
||||
struct ekmf_tag_list *dest);
|
||||
void free_tag_list(struct ekmf_tag_list *tag_list, bool free_tags);
|
||||
|
||||
int json_build_export_control(json_object *export_control,
|
||||
struct ekmf_export_control *export_info,
|
||||
bool copy);
|
||||
int clone_export_control(const struct ekmf_export_control *src,
|
||||
struct ekmf_export_control *dest);
|
||||
void free_export_control(struct ekmf_export_control *export_control,
|
||||
bool free_keys);
|
||||
|
||||
int json_build_key_info(json_object *obj, json_object *custom_tags,
|
||||
json_object *export_control,
|
||||
struct ekmf_key_info *key, bool copy);
|
||||
int clone_key_info(const struct ekmf_key_info *src,
|
||||
struct ekmf_key_info *dest);
|
||||
void free_key_info(struct ekmf_key_info *key);
|
||||
|
||||
char *get_http_header_value(const struct curl_slist *headers, const char *name);
|
||||
|
||||
size_t ecc_get_curve_prime_bits(int curve_nid);
|
||||
size_t ecc_get_curve_prime_length(int curve_nid);
|
||||
const char *ecc_get_curve_id(int curve_nid);
|
||||
bool ecc_is_prime_curve(int curve_nid);
|
||||
bool ecc_is_brainpool_curve(int curve_nid);
|
||||
int ecc_get_curve_by_id(const char *curve_id);
|
||||
int ecc_get_prime_curve_by_prime_bits(size_t prime_bits);
|
||||
int ecc_get_brainpool_curve_by_prime_bits(size_t prime_bits);
|
||||
|
||||
int ecc_calculate_y_coordinate(int nid, size_t prime_len,
|
||||
const unsigned char *x, int y_bit,
|
||||
unsigned char *y);
|
||||
|
||||
int ecc_pub_key_as_pkey(int nid, size_t prime_len, const unsigned char *x,
|
||||
const unsigned char *y, EVP_PKEY **pkey);
|
||||
|
||||
int rsa_pub_key_as_pkey(const unsigned char *modulus, size_t modulus_length,
|
||||
const unsigned char *pub_exp, size_t pub_exp_length,
|
||||
int pkey_type, EVP_PKEY **pkey);
|
||||
|
||||
int json_web_key_as_pkey(json_object *jwk, int pkey_type, EVP_PKEY **pkey);
|
||||
|
||||
int write_key_blob(const char *filename, unsigned char *key_blob,
|
||||
size_t key_blob_len);
|
||||
|
||||
int read_key_blob(const char *filename, unsigned char *key_blob,
|
||||
size_t *key_blob_len);
|
||||
|
||||
int read_x509_certificate(const char *pem_filename, X509 **cert);
|
||||
|
||||
int write_x509_certificate(const char *pem_filename, X509 *cert);
|
||||
|
||||
int write_x509_request(const char *pem_filename, X509_REQ *req, bool new_hdr);
|
||||
|
||||
int read_public_key(const char *pem_filename, EVP_PKEY **pkey);
|
||||
|
||||
int write_public_key(const char *pem_filename, EVP_PKEY *pkey);
|
||||
|
||||
typedef int (*rsa_sign_t)(const unsigned char *key_blob, size_t key_blob_length,
|
||||
unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen,
|
||||
int padding_type, int md_nid,
|
||||
void *private);
|
||||
typedef int (*rsa_pss_sign_t)(const unsigned char *key_blob,
|
||||
size_t key_blob_length, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen, int md_nid, int mfgmd_nid,
|
||||
int saltlen, void *private);
|
||||
typedef int (*ecdsa_sign_t)(const unsigned char *key_blob,
|
||||
size_t key_blob_length, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen, int md_nid, void *private);
|
||||
|
||||
struct sk_pkey_sign_func {
|
||||
rsa_sign_t rsa_sign;
|
||||
rsa_pss_sign_t rsa_pss_sign;
|
||||
ecdsa_sign_t ecdsa_sign;
|
||||
};
|
||||
|
||||
int setup_secure_key_pkey_method(int pkey_id);
|
||||
int cleanup_secure_key_pkey_method(int pkey_id);
|
||||
int setup_secure_key_pkey_context(EVP_PKEY_CTX *pkey_ctx,
|
||||
const unsigned char *key_blob,
|
||||
size_t key_blob_len,
|
||||
struct sk_pkey_sign_func *sign_funcs,
|
||||
void *private);
|
||||
|
||||
int setup_rsa_pss_pkey_context(EVP_PKEY_CTX *pkey_ctx,
|
||||
struct ekmf_rsa_pss_params *rsa_pss_params);
|
||||
|
||||
int build_subject_name(X509_NAME **name, const char *rdns[], size_t num_rdns,
|
||||
bool utf8);
|
||||
|
||||
int build_certificate_extensions(X509 *cert, X509_REQ *req,
|
||||
const char *exts[], size_t num_exts,
|
||||
const STACK_OF(X509_EXTENSION) *addl_exts);
|
||||
|
||||
int generate_x509_serial_number(X509 *cert, size_t sn_bit_size);
|
||||
|
||||
const char *json_get_string(json_object *obj, const char *name);
|
||||
|
||||
int json_object_get_base64url(json_object *obj, const char *name,
|
||||
unsigned char *data, size_t *data_len);
|
||||
|
||||
json_object *json_object_new_base64url(const unsigned char *data, size_t len);
|
||||
|
||||
#ifndef JSON_C_OBJECT_ADD_KEY_IS_NEW
|
||||
#define JSON_C_OBJECT_ADD_KEY_IS_NEW (1 << 1)
|
||||
#define IMPLEMENT_LOCAL_JSON_OBJECT_OBJECT_ADD
|
||||
|
||||
int json_object_object_add_ex(struct json_object *obj, const char *const key,
|
||||
struct json_object *const val,
|
||||
const unsigned int opts);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -43,6 +43,7 @@ util_prg_example: util_prg_example.o $(lib)
|
||||
util_rec_example: util_rec_example.o $(lib)
|
||||
|
||||
$(lib): $(objects)
|
||||
$(lib): ALL_CFLAGS += -fPIC
|
||||
|
||||
install: all
|
||||
|
||||
|
||||
@@ -281,6 +281,44 @@ int util_file_write_ull(unsigned long long val, int base, const char *fmt, ...)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a file and convert it to signed int according to given base
|
||||
*
|
||||
* @param[out] val Buffer for value
|
||||
* @param[in] base Base for conversion, either 8, 10, or 16
|
||||
* @param[in] fmt Format string for generation of the path name
|
||||
* @param[in] ... Parameters for format string
|
||||
*
|
||||
* @retval 0 Integer has been read correctly
|
||||
* @retval -1 Error while reading file
|
||||
*/
|
||||
int util_file_read_i(int *val, int base, const char *fmt, ...)
|
||||
{
|
||||
char path[PATH_MAX], buf[512];
|
||||
va_list ap;
|
||||
int count;
|
||||
|
||||
/* Construct the file name */
|
||||
UTIL_VSPRINTF(path, fmt, ap);
|
||||
|
||||
if (file_gets(buf, sizeof(buf), path))
|
||||
return -1;
|
||||
switch (base) {
|
||||
case 8:
|
||||
count = sscanf(buf, "%do", val);
|
||||
break;
|
||||
case 10:
|
||||
count = sscanf(buf, "%dd", val);
|
||||
break;
|
||||
case 16:
|
||||
count = sscanf(buf, "%dx", val);
|
||||
break;
|
||||
default:
|
||||
util_panic("Invalid base: %d\n", base);
|
||||
}
|
||||
return (count == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a file and convert it to signed long according to given base
|
||||
*
|
||||
@@ -357,6 +395,44 @@ int util_file_read_ll(long long *val, int base, const char *fmt, ...)
|
||||
return (count == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a file and convert it to unsigned int according to given base
|
||||
*
|
||||
* @param[out] val Buffer for value
|
||||
* @param[in] base Base for conversion, either 8, 10, or 16
|
||||
* @param[in] fmt Format string for generation of the path name
|
||||
* @param[in] ... Parameters for format string
|
||||
*
|
||||
* @retval 0 Integer has been read correctly
|
||||
* @retval -1 Error while reading file
|
||||
*/
|
||||
int util_file_read_ui(unsigned int *val, int base, const char *fmt, ...)
|
||||
{
|
||||
char path[PATH_MAX], buf[512];
|
||||
va_list ap;
|
||||
int count;
|
||||
|
||||
/* Construct the file name */
|
||||
UTIL_VSPRINTF(path, fmt, ap);
|
||||
|
||||
if (file_gets(buf, sizeof(buf), path))
|
||||
return -1;
|
||||
switch (base) {
|
||||
case 8:
|
||||
count = sscanf(buf, "%uo", val);
|
||||
break;
|
||||
case 10:
|
||||
count = sscanf(buf, "%uu", val);
|
||||
break;
|
||||
case 16:
|
||||
count = sscanf(buf, "%ux", val);
|
||||
break;
|
||||
default:
|
||||
util_panic("Invalid base: %d\n", base);
|
||||
}
|
||||
return (count == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a file and convert it to unsigned long according to given base
|
||||
*
|
||||
@@ -432,3 +508,31 @@ int util_file_read_ull(unsigned long long *val, int base, const char *fmt, ...)
|
||||
}
|
||||
return (count == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a file and convert it according to format string
|
||||
*
|
||||
* @param[in] path File name to read
|
||||
* @param[in] fmt Format string for parsing the content
|
||||
* @param[out] ... Parameters for format string
|
||||
*
|
||||
* @retval != -1 Number of values parsed correctly
|
||||
* @retval -1 Error while reading file
|
||||
*/
|
||||
|
||||
int util_file_read_va(const char *path, const char *fmt, ...)
|
||||
{
|
||||
char buf[512];
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
if (file_gets(buf, sizeof(buf), path))
|
||||
return -1;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = vsscanf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
if (ret == EOF)
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
18
lsstp/Makefile
Normal file
18
lsstp/Makefile
Normal file
@@ -0,0 +1,18 @@
|
||||
include ../common.mak
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
all: lsstp
|
||||
|
||||
lsstp: lsstp.o $(libs)
|
||||
|
||||
install: all
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) \
|
||||
$(DESTDIR)$(MANDIR)/man8
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 lsstp $(DESTDIR)$(BINDIR)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 lsstp.8 \
|
||||
$(DESTDIR)$(MANDIR)/man8
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ lsstp core
|
||||
|
||||
.PHONY: all install clean
|
||||
79
lsstp/lsstp.8
Normal file
79
lsstp/lsstp.8
Normal file
@@ -0,0 +1,79 @@
|
||||
.\" Copyright 2020 IBM Corp.
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH LSSTP 8 "Jul 2020" "s390-tools" "Linux Administrator's Manual"
|
||||
.SH NAME
|
||||
.B "lsstp "
|
||||
\- tool to show STP system information
|
||||
.SH SYNOPSIS
|
||||
.BI "lsstp "
|
||||
|
||||
.SH DESCRIPTION
|
||||
.B lsstp
|
||||
displays information about the currenta Server Time Protocol (STP) configuration
|
||||
like Coordianted Timing Network (CTN) ID, Timing state and Leap seconds.
|
||||
.SH OUTPUT
|
||||
.TP
|
||||
.B STP online
|
||||
Whether the STP subsystem is online
|
||||
.TP
|
||||
.B CTN ID
|
||||
The ID of the Coordinated Time Network. If it can be decoded as EBCDIC it will be shown as EBCDIC String, otherwise a hexadecimal representation is shown.
|
||||
.TP
|
||||
.B CTN Type
|
||||
The type of timing network.
|
||||
.IP
|
||||
.B No CTN
|
||||
STP is not configured for attachment to a CTN.
|
||||
.IP
|
||||
.B STP-only
|
||||
STP is configured and attached to a CTN with only STP nodes.
|
||||
.IP
|
||||
.B Mixed
|
||||
STP is configured and attached to a CTN which contains both STP and External Time Reference (ETR) nodes.
|
||||
.TP
|
||||
.B Stratum
|
||||
The Stratum level of the STP clock. This indicates the number of servers in the timing path between the local STP clock and the selected primary time server.
|
||||
.TP
|
||||
.B Timing mode
|
||||
.IP
|
||||
.B Local
|
||||
The Time-of-day (TOD) clock is stepped to the local hardware oscillator and is not steered by the STP facility.
|
||||
.IP
|
||||
.B ETR
|
||||
The TOD clock is synchronized with an attached 9037 Sysplex Timer.
|
||||
.IP
|
||||
.B STP
|
||||
The TOD clock is steered by the STP facility to maintain synchronization with a Coordinated Server Time (CST).
|
||||
.IP
|
||||
.B Uninitialized
|
||||
The TOD clock is not initialized. The STP facility is allowed to perform a step adjustment to the TOD clock for synchronization.
|
||||
.TP
|
||||
.B Timing state
|
||||
The synchronization state of the STP facilty. Can be unsynchronzied, synchronized and stopped.
|
||||
.TP
|
||||
.B DST offset
|
||||
The Daylight savings time offset relative to UTC in minutes.
|
||||
.TP
|
||||
.B Timezone offset
|
||||
The offset of the local time relative to UTC in minutes.
|
||||
.TP
|
||||
.B Time offset
|
||||
The total time offset at the server. This field is only valid in mixed CTN configurations.
|
||||
.TP
|
||||
.B Active Leap seconds
|
||||
The number of Leap seconds that are currently in effect at the STP facility.
|
||||
.TP
|
||||
.B Leap second <insertion|delation> at
|
||||
If a Leap second insertion or deletetion is scheduled in the STP facility, this field will show the Day and Time of the scheduled change.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI "-v|--version"
|
||||
Print version number.
|
||||
.TP
|
||||
.BI "-h|--help"
|
||||
Print usage text.
|
||||
|
||||
.SH AUTHORS
|
||||
Sven Schnelle <svens@linux.ibm.com>
|
||||
218
lsstp/lsstp.c
Normal file
218
lsstp/lsstp.c
Normal file
@@ -0,0 +1,218 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <iconv.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "lib/util_opt.h"
|
||||
#include "lib/util_file.h"
|
||||
#include "lib/util_prg.h"
|
||||
#include "lib/util_path.h"
|
||||
|
||||
static const struct util_prg prg = {
|
||||
.desc = "Display STP system information",
|
||||
.args = "",
|
||||
.copyright_vec = {
|
||||
{
|
||||
.owner = "IBM Corp.",
|
||||
.pub_first = 2020,
|
||||
},
|
||||
UTIL_PRG_COPYRIGHT_END
|
||||
}
|
||||
};
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
UTIL_OPT_HELP,
|
||||
UTIL_OPT_VERSION,
|
||||
UTIL_OPT_END
|
||||
};
|
||||
|
||||
struct stp_parms {
|
||||
uint64_t ctn_id;
|
||||
unsigned int online;
|
||||
unsigned int leap_seconds;
|
||||
int leap_seconds_diff;
|
||||
unsigned int leap_seconds_utc;
|
||||
unsigned int stratum;
|
||||
unsigned int ctn_type;
|
||||
unsigned int timing_mode;
|
||||
unsigned int timing_state;
|
||||
int dst_offset;
|
||||
int time_offset;
|
||||
int time_zone_offset;
|
||||
};
|
||||
|
||||
static int convert_ctn_id(char *in, char *out)
|
||||
{
|
||||
iconv_t ic;
|
||||
size_t inlen = sizeof(unsigned long long);
|
||||
size_t outlen = sizeof(unsigned long long);
|
||||
|
||||
ic = iconv_open("ISO-8859-1", "EBCDIC-US");
|
||||
if (ic == (iconv_t)-1) {
|
||||
warn("Could not initialize EBCDIC to ISO-8859-1 conversion table");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (iconv(ic, &in, &inlen, (char **)&out, &outlen) == (size_t)-1) {
|
||||
warn("Code page translation EBCDIC to ISO-8859-1 failed");
|
||||
iconv_close(ic);
|
||||
return -1;
|
||||
}
|
||||
iconv_close(ic);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *ctn_type_str(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case 0:
|
||||
return "No CTN defined";
|
||||
case 1:
|
||||
return "STP-only";
|
||||
case 2:
|
||||
return "mixed";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *tmd_to_str(int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case 0:
|
||||
return "Local";
|
||||
case 1:
|
||||
return "ETR";
|
||||
case 2:
|
||||
return "STP";
|
||||
case 15:
|
||||
return "Uninitialized";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *tst_to_str(int mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case 0:
|
||||
return "Unsynchronized";
|
||||
case 1:
|
||||
return "Synchronized";
|
||||
case 2:
|
||||
return "Physical clock stopped";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char *yesno_str(int val)
|
||||
{
|
||||
return val ? "yes" : "no";
|
||||
}
|
||||
|
||||
#define read_sysfs_attr(attr, parm, func, base) \
|
||||
do { \
|
||||
path = util_path_sysfs("devices/system/stp/%s", attr); \
|
||||
ret = func(parm, base, path); \
|
||||
if (ret) { \
|
||||
fprintf(stderr, "failed to open %s: %s\n", path, strerror(errno)); \
|
||||
free(path); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
free(path); \
|
||||
} while (0)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct stp_parms parm = { 0 };
|
||||
char ctn_id[32] = { 0 };
|
||||
char *path;
|
||||
int ret, c;
|
||||
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
|
||||
for (;;) {
|
||||
c = util_opt_getopt_long(argc, argv);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'v':
|
||||
util_prg_print_version();
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'h':
|
||||
util_prg_print_help();
|
||||
util_opt_print_help();
|
||||
exit(EXIT_SUCCESS);
|
||||
default:
|
||||
fprintf(stderr, "Try 'lsstp --help' for more information.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
read_sysfs_attr("online", &parm.online, util_file_read_ui, 10);
|
||||
if (!parm.online) {
|
||||
printf("STP disabled\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
read_sysfs_attr("ctn_id", &parm.ctn_id, util_file_read_ul, 16);
|
||||
read_sysfs_attr("ctn_type", &parm.ctn_type, util_file_read_ui, 10);
|
||||
read_sysfs_attr("stratum", &parm.stratum, util_file_read_ui, 10);
|
||||
read_sysfs_attr("leap_seconds", &parm.leap_seconds, util_file_read_ui, 10);
|
||||
read_sysfs_attr("timing_mode", &parm.timing_mode, util_file_read_ui, 10);
|
||||
read_sysfs_attr("timing_state", &parm.timing_state, util_file_read_ui, 10);
|
||||
read_sysfs_attr("dst_offset", &parm.dst_offset, util_file_read_i, 10);
|
||||
read_sysfs_attr("time_offset", &parm.time_offset, util_file_read_i, 10);
|
||||
read_sysfs_attr("time_zone_offset", &parm.time_zone_offset, util_file_read_i, 10);
|
||||
|
||||
if (convert_ctn_id((char *)&parm.ctn_id, ctn_id))
|
||||
snprintf(ctn_id, sizeof(ctn_id)-1, "%016" PRIx64, parm.ctn_id);
|
||||
|
||||
printf("STP online: %s\n"
|
||||
"CTN ID: %s\n"
|
||||
"CTN type: %s\n"
|
||||
"Stratum: %d\n"
|
||||
"Timing mode: %s\n"
|
||||
"Timing state: %s\n"
|
||||
"DST offset: %d\n"
|
||||
"Timezone offset: %d\n"
|
||||
"Time offset: %d\n"
|
||||
"Active leap seconds: %d\n",
|
||||
yesno_str(parm.online),
|
||||
ctn_id,
|
||||
ctn_type_str(parm.ctn_type),
|
||||
parm.stratum,
|
||||
tmd_to_str(parm.timing_mode),
|
||||
tst_to_str(parm.timing_state),
|
||||
parm.dst_offset,
|
||||
parm.time_zone_offset,
|
||||
parm.time_offset,
|
||||
parm.leap_seconds);
|
||||
|
||||
printf("Scheduled leap second: ");
|
||||
|
||||
path = util_path_sysfs("devices/system/stp/leap_seconds_scheduled");
|
||||
if (util_file_read_va(path, "%d,%d", &parm.leap_seconds_utc,
|
||||
&parm.leap_seconds_diff) == 2 &&
|
||||
parm.leap_seconds_diff && parm.leap_seconds_utc) {
|
||||
time_t lsoup = parm.leap_seconds_utc;
|
||||
|
||||
printf("%s at: %s UTC",
|
||||
parm.leap_seconds_diff > 0 ? "insertion" : "deletion",
|
||||
ctime(&lsoup));
|
||||
} else {
|
||||
printf("-\n");
|
||||
}
|
||||
free(path);
|
||||
return 0;
|
||||
out:
|
||||
return 1;
|
||||
}
|
||||
@@ -45,7 +45,7 @@ vmcmd: Trigger CP command according to the 'VMCMD_X' configuration in
|
||||
|
||||
.TP
|
||||
\fB - DUMP_TYPE:\fR
|
||||
Type of dump device. Possible values are 'ccw' and 'fcp'.
|
||||
Type of dump device. Possible values are 'ccw', 'fcp' and 'nvme'.
|
||||
|
||||
.TP
|
||||
\fB - DEVICE:\fR
|
||||
@@ -59,6 +59,14 @@ WWPN for SCSI dump device.
|
||||
\fB - LUN\fR
|
||||
LUN for SCSI dump device.
|
||||
|
||||
.TP
|
||||
\fB - FID\fR
|
||||
Function ID for NVMe dump device.
|
||||
|
||||
.TP
|
||||
\fB - NSID\fR
|
||||
Namespace ID for NVMe dump device.
|
||||
|
||||
.TP
|
||||
\fB - BOOTPROG:\fR
|
||||
Boot program selector.
|
||||
@@ -159,6 +167,25 @@ BOOTPROG=0
|
||||
BR_LBA=0
|
||||
.br
|
||||
|
||||
#
|
||||
.br
|
||||
# Example configuration for an NVMe dump device (NVMe Disk)
|
||||
.br
|
||||
#
|
||||
.br
|
||||
ON_PANIC=dump
|
||||
.br
|
||||
DUMP_TYPE=nvme
|
||||
.br
|
||||
FID=0x0300
|
||||
.br
|
||||
NSID=0x0001
|
||||
.br
|
||||
BOOTPROG=0
|
||||
.br
|
||||
BR_LBA=0
|
||||
.br
|
||||
|
||||
#
|
||||
.br
|
||||
# Example configuration for CP commands
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
.\" Copyright 2019 IBM Corp.
|
||||
.\" chzcrypt.8
|
||||
.\"
|
||||
.\" Copyright 2020 IBM Corp.
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH CHZCRYPT 8 "AUG 2019" "s390-tools"
|
||||
.TH CHZCRYPT 8 "OCT 2020" "s390-tools"
|
||||
.SH NAME
|
||||
chzcrypt \- modify zcrypt configuration
|
||||
.SH SYNOPSIS
|
||||
@@ -16,6 +18,14 @@ chzcrypt \- modify zcrypt configuration
|
||||
[...] )
|
||||
.TP
|
||||
.B chzcrypt
|
||||
.B --config-on
|
||||
.RB "|"
|
||||
.B --config-off
|
||||
.RB "( " -a " | "
|
||||
.I <device id>
|
||||
[...] )
|
||||
.TP
|
||||
.B chzcrypt
|
||||
.RB "[ " -p " | " -n " ] [ " -t
|
||||
.I <timeout>
|
||||
]
|
||||
@@ -54,11 +64,22 @@ Set the given cryptographic device(s) offline.
|
||||
.B -a, --all
|
||||
Set all available cryptographic device(s) online or offline.
|
||||
.TP 8
|
||||
.B --config-on
|
||||
Set the given cryptographic card device(s) config on ('configured').
|
||||
.TP 8
|
||||
.B --config-off
|
||||
Set the given cryptographic card device(s) config off ('deconfigured').
|
||||
.TP 8
|
||||
.B <device id>
|
||||
Specifies a cryptographic device which will be set either online or offline.
|
||||
The device can either be a card device or a queue device.
|
||||
A queue device can only get switched online when the providing card is online.
|
||||
|
||||
Specifies a cryptographic device which will be set either online or
|
||||
offline or configured on or off. For online and offline the device can
|
||||
either be a card device or a queue device. A queue device can only get
|
||||
switched online when the providing card is online.
|
||||
.br
|
||||
For config on/off the device needs to be a card device. A card or
|
||||
queue device cannot get switched online if the card is in deconfigured
|
||||
state.
|
||||
.br
|
||||
Please note that the card device and queue device representation are both
|
||||
in hexadecimal notation.
|
||||
.TP 8
|
||||
@@ -103,11 +124,25 @@ Will set the cryptographic device '10.0038' respectively card id 16
|
||||
.B chzcrypt -d -a
|
||||
Will set all available cryptographic devices offline.
|
||||
.TP
|
||||
.B chzcrypt --config-on -a -V
|
||||
Set all available crypto cards to config on, be verbose.
|
||||
.TP
|
||||
.B chzcrypt -V --config-off card01 card03
|
||||
Switch the two crypto cards 1 and 3 to deconfigured, be verbose.
|
||||
.TP
|
||||
.B chzcrypt -c 60 -n
|
||||
Will set configuration timer for re-scanning the AP bus to 60 seconds and
|
||||
disable zcrypt's poll thread.
|
||||
.TP
|
||||
.B chzcrypt -q 67
|
||||
Will set the default domain to 67.
|
||||
.SH NOTES
|
||||
Support for crypto cards to get switched config on or off requires a
|
||||
Linux kernel supporting this. If the required sysfs attribute file
|
||||
does not exist, it is assumed there is an older kernel running and
|
||||
chzcrypt exits with an appropriate message. Even more config on/off
|
||||
may require support from a hypervisor like KVM or zVM and may fail if
|
||||
the Linux kernel is unable to perform the SCLP command. Check syslog
|
||||
on failure.
|
||||
.SH SEE ALSO
|
||||
\fBlszcrypt\fR(8)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* chzcrypt - Tool to modify zcrypt configuration
|
||||
*
|
||||
* Copyright IBM Corp. 2008, 2019
|
||||
* Copyright IBM Corp. 2008, 2020
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -47,7 +47,7 @@ const struct util_prg prg = {
|
||||
{
|
||||
.owner = "IBM Corp.",
|
||||
.pub_first = 2008,
|
||||
.pub_last = 2019,
|
||||
.pub_last = 2020,
|
||||
},
|
||||
UTIL_PRG_COPYRIGHT_END
|
||||
}
|
||||
@@ -56,6 +56,10 @@ const struct util_prg prg = {
|
||||
/*
|
||||
* Configuration of command line options
|
||||
*/
|
||||
|
||||
#define OPT_CONFIG_ON 0x80
|
||||
#define OPT_CONFIG_OFF 0x81
|
||||
|
||||
static struct util_opt opt_vec[] = {
|
||||
{
|
||||
.option = { "enable", no_argument, NULL, 'e'},
|
||||
@@ -73,6 +77,18 @@ static struct util_opt opt_vec[] = {
|
||||
"online/offline, must be used in conjunction "
|
||||
"with the enable or disable option",
|
||||
},
|
||||
{
|
||||
.option = { "config-on", no_argument, NULL, OPT_CONFIG_ON},
|
||||
.argument = "DEVICE_IDS",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
.desc = "Set the given cryptographic card device(s) configured"
|
||||
},
|
||||
{
|
||||
.option = { "config-off", no_argument, NULL, OPT_CONFIG_OFF},
|
||||
.argument = "DEVICE_IDS",
|
||||
.flags = UTIL_OPT_FLAG_NOSHORT,
|
||||
.desc = "Set the given cryptographic card device(s) deconfigured"
|
||||
},
|
||||
{
|
||||
.option = { "poll-thread-enable", no_argument, NULL, 'p'},
|
||||
.desc = "Enable zcrypt's poll thread",
|
||||
@@ -212,6 +228,116 @@ static void default_domain_set(const char *default_domain_str)
|
||||
free(attr);
|
||||
}
|
||||
|
||||
static void set_online(const char *online, const char *online_text,
|
||||
char *dev_list, size_t len)
|
||||
{
|
||||
long value;
|
||||
int id, dom;
|
||||
char *dev, *dev_path;
|
||||
char device[256], online_read[32];
|
||||
|
||||
for (dev = dev_list; dev != NULL; dev = argz_next(dev_list, len, dev)) {
|
||||
if (strncmp(dev, "card", 4) == 0) {
|
||||
/* dev == "card2" */
|
||||
if (sscanf(dev, "card%02x", &id) != 1)
|
||||
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
||||
sprintf(device, "card%02x", id);
|
||||
} else if (strncmp(dev, "0x", 2) == 0) {
|
||||
/* dev == "0x.." */
|
||||
if (sscanf(dev, "0x%02x", &id) != 1)
|
||||
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
||||
sprintf(device, "card%02x", id);
|
||||
} else if (misc_regex_match(dev, "^[0-9a-fA-F]+$")) {
|
||||
/* dev == "2" */
|
||||
if (sscanf(dev, "%02x", &id) != 1)
|
||||
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
||||
sprintf(device, "card%02x", id);
|
||||
} else {
|
||||
/* Form: 01.0003 ? */
|
||||
if (sscanf(dev, "%02x.%04x", &id, &dom) != 2)
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - cryptographic device %s malformed.", dev);
|
||||
sprintf(device, "card%02x/%02x.%04x", id, id, dom);
|
||||
}
|
||||
dev_path = util_path_sysfs("bus/ap/devices/%s", device);
|
||||
if (!util_path_is_dir(dev_path))
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - cryptographic device %s does not exist.", device);
|
||||
if (!util_path_is_writable("%s/online", dev_path))
|
||||
errx(EXIT_FAILURE, "Error - can't write to %s/online.\n"
|
||||
" Wrong permissions or wrong tools version.", dev_path);
|
||||
if (*online == '1' && util_path_is_readable("%s/config", dev_path)) {
|
||||
util_file_read_l(&value, 10, "%s/config", dev_path);
|
||||
if (value <= 0) {
|
||||
warnx("Warning - device %s is deconfigured,"
|
||||
" can't set to online.\n", dev);
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
verbose("Setting cryptographic device %s %s\n", device, online_text);
|
||||
util_file_write_s(online, "%s/online", dev_path);
|
||||
util_file_read_line(online_read, sizeof(online_read), "%s/online", dev_path);
|
||||
if (strcmp(online, online_read) != 0)
|
||||
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
|
||||
device, online_text);
|
||||
next:
|
||||
free(dev_path);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_config(const char *config, const char *config_text,
|
||||
char *dev_list, size_t len)
|
||||
{
|
||||
int id;
|
||||
char *dev, *dev_path;
|
||||
char device[256], config_read[32];
|
||||
|
||||
for (dev = dev_list; dev != NULL; dev = argz_next(dev_list, len, dev)) {
|
||||
if (strncmp(dev, "card", 4) == 0) {
|
||||
/* dev == "card2" */
|
||||
if (sscanf(dev, "card%02x", &id) != 1)
|
||||
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
||||
sprintf(device, "card%02x", id);
|
||||
} else if (strncmp(dev, "0x", 2) == 0) {
|
||||
/* dev == "0x.." */
|
||||
if (sscanf(dev, "0x%02x", &id) != 1)
|
||||
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
||||
sprintf(device, "card%02x", id);
|
||||
} else if (misc_regex_match(dev, "^[0-9a-fA-F]+$")) {
|
||||
/* dev == "2" */
|
||||
if (sscanf(dev, "%02x", &id) != 1)
|
||||
errx(EXIT_FAILURE, "Error - unable to parse '%s'.", dev);
|
||||
sprintf(device, "card%02x", id);
|
||||
} else {
|
||||
errx(EXIT_FAILURE, "Error - invalid device %s\n"
|
||||
" Config on/off is only valid for card devices.", dev);
|
||||
}
|
||||
dev_path = util_path_sysfs("bus/ap/devices/%s", device);
|
||||
if (!util_path_is_dir(dev_path))
|
||||
errx(EXIT_FAILURE,
|
||||
"Error - cryptographic device %s does not exist.", device);
|
||||
if (!util_path_is_readable("%s/config", dev_path))
|
||||
errx(EXIT_FAILURE, "Error - can't read %s/config.\n"
|
||||
"File may not exist due to an older zcrypt device driver.", dev_path);
|
||||
util_file_read_line(config_read, sizeof(config_read), "%s/config", dev_path);
|
||||
if (strcmp(config, config_read) == 0) {
|
||||
warnx("Warning - device %s is already %s.", device, config_text);
|
||||
goto next;
|
||||
}
|
||||
if (!util_path_is_writable("%s/config", dev_path))
|
||||
errx(EXIT_FAILURE, "Error - can't write to %s/config.\n"
|
||||
"Wrong permissions or wrong tools version.", dev_path);
|
||||
verbose("Setting cryptographic device %s %s\n", device, config_text);
|
||||
util_file_write_s(config, "%s/config", dev_path);
|
||||
util_file_read_line(config_read, sizeof(config_read), "%s/config", dev_path);
|
||||
if (strcmp(config, config_read) != 0)
|
||||
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
|
||||
device, config_text);
|
||||
next:
|
||||
free(dev_path);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print invalid commandline error message and then exit with error code
|
||||
*/
|
||||
@@ -276,7 +402,6 @@ void print_adapter_id_help(void)
|
||||
printf(" Enable the cryptographic devices with card id '03' and domain id '0005'.\n");
|
||||
printf(" #>chzcrypt -e 03.0005\n");
|
||||
printf(" \n");
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -284,19 +409,19 @@ void print_adapter_id_help(void)
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *online, *online_text = NULL, *poll_thread, *config_time;
|
||||
const char *poll_timeout, *default_domain;
|
||||
char *path, *dev_path, *dev, *dev_list, device[256], online_read[32];
|
||||
const char *online = NULL, *online_text = NULL, *poll_thread = NULL;
|
||||
const char *config_time = NULL, *poll_timeout = NULL;
|
||||
const char *default_domain = NULL, *config = NULL, *config_text = NULL;
|
||||
char *path, *dev_list;
|
||||
bool all = false, actionset = false;
|
||||
size_t len;
|
||||
int id, dom, c, i, j;
|
||||
int c, i, j;
|
||||
|
||||
for (i=0; i < argc; i++)
|
||||
for (j=2; j < (int) strlen(argv[i]); j++)
|
||||
if (argv[i][j] == '_')
|
||||
argv[i][j] = '-';
|
||||
|
||||
online = poll_thread = config_time = poll_timeout = default_domain = NULL;
|
||||
util_prg_init(&prg);
|
||||
util_opt_init(opt_vec, NULL);
|
||||
while (1) {
|
||||
@@ -348,6 +473,16 @@ int main(int argc, char *argv[])
|
||||
case 'v':
|
||||
util_prg_print_version();
|
||||
return EXIT_SUCCESS;
|
||||
case OPT_CONFIG_ON:
|
||||
actionset = true;
|
||||
config = "1";
|
||||
config_text = "config on";
|
||||
break;
|
||||
case OPT_CONFIG_OFF:
|
||||
actionset = true;
|
||||
config = "0";
|
||||
config_text = "config off";
|
||||
break;
|
||||
default:
|
||||
util_opt_print_parse_error(c, argv);
|
||||
return EXIT_FAILURE;
|
||||
@@ -380,42 +515,13 @@ int main(int argc, char *argv[])
|
||||
else
|
||||
dev_list_argv(&dev_list, &len, &argv[optind]);
|
||||
|
||||
if (online && len == 0)
|
||||
if ((online || config) && len == 0)
|
||||
errx(EXIT_FAILURE, "Error - missing cryptographic device id(s).");
|
||||
|
||||
for (dev = dev_list; dev != NULL; dev = argz_next(dev_list, len, dev)) {
|
||||
if (strncmp(dev, "card", 4) == 0) {
|
||||
/* dev == "card2" */
|
||||
sscanf(dev, "card%02x", &id);
|
||||
sprintf(device, "card%02x", id);
|
||||
} else if (strncmp(dev, "0x", 2) == 0) {
|
||||
/* dev == "0x.." */
|
||||
sscanf(dev, "0x%02x", &id);
|
||||
sprintf(device, "card%02x", id);
|
||||
} else if (misc_regex_match(dev, "^[0-9a-fA-F]+$")) {
|
||||
/* dev == "2" */
|
||||
sscanf(dev, "%02x", &id);
|
||||
sprintf(device, "card%02x", id);
|
||||
} else {
|
||||
/* Form: 01.0003 ? */
|
||||
if (sscanf(dev, "%02x.%04x", &id, &dom) != 2)
|
||||
errx(EXIT_FAILURE, "Error - cryptographic device %s malformed.", dev);
|
||||
sprintf(device, "card%02x/%02x.%04x", id, id, dom);
|
||||
}
|
||||
dev_path = util_path_sysfs("bus/ap/devices/%s", device);
|
||||
if (!util_path_is_dir(dev_path))
|
||||
errx(EXIT_FAILURE, "Error - cryptographic device %s does not exist.", device);
|
||||
if (!util_path_is_writable("%s/online", dev_path))
|
||||
errx(EXIT_FAILURE, "Error - can't write to %s/online.\n Wrong permissions"
|
||||
" or wrong tools version.", dev_path);
|
||||
verbose("Setting cryptographic device %s %s\n", device, online_text);
|
||||
util_file_write_s(online, "%s/online", dev_path);
|
||||
util_file_read_line(online_read, sizeof(online_read), "%s/online", dev_path);
|
||||
if (strcmp(online, online_read) != 0)
|
||||
errx(EXIT_FAILURE, "Error - unable to set cryptographic device %s %s.",
|
||||
device, online_text);
|
||||
free(dev_path);
|
||||
}
|
||||
free(dev_list);
|
||||
if (online)
|
||||
set_online(online, online_text, dev_list, len);
|
||||
else if (config)
|
||||
set_config(config, config_text, dev_list, len);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
.\" nroff -man lszcrypt.8
|
||||
.\" to process this source
|
||||
.\"
|
||||
.TH LSZCRYPT 8 "AUG 2019" "s390-tools"
|
||||
.TH LSZCRYPT 8 "OCT 2020" "s390-tools"
|
||||
.SH NAME
|
||||
lszcrypt \- display zcrypt device and configuration information
|
||||
.SH SYNOPSIS
|
||||
@@ -111,9 +111,9 @@ Displays help text and exits.
|
||||
.TP 8
|
||||
.B -v, --version
|
||||
Displays version information and exits.
|
||||
.SH VERBOSE LISTING DETAILS
|
||||
Some of the columns showing up in verbose listing mode may need some
|
||||
explanation:
|
||||
.SH LISTING DETAILS
|
||||
Here is an explanation of the columns displayed. Please note that some
|
||||
of the columns show up in verbose mode only.
|
||||
.TP
|
||||
.B TYPE and HWTYPE
|
||||
The HWTYPE is a numeric value showing which type of hardware the zcrypt
|
||||
@@ -124,6 +124,31 @@ The TYPE is a human readable value showing the hardware type and the basic
|
||||
function type (A=Accelerator, C=CCA Coprocessor, P=EP11 Coprocessor). So
|
||||
for example CEX6P means a CEX6 card in EP11 Coprocessor mode.
|
||||
.TP
|
||||
.B MODE
|
||||
A crypto card can be configured to run into one of 3 modes:
|
||||
.br
|
||||
Accelerator - Acceleration of clear key RSA (CRT and ME) cryptographic
|
||||
operations.
|
||||
.br
|
||||
CCA Coprocessor - Support CCA secure key cryptographic operations.
|
||||
.br
|
||||
EP11 Coprocessor - Support EP11 secure key cryptographic operations.
|
||||
.TP
|
||||
.B STATUS
|
||||
A crypto card and/or a crypto queue may be switched offline to
|
||||
prohibit it's use. There are two levels of offline state. A software
|
||||
online/offline state is kept by the zcrypt device driver and can be
|
||||
switched on or off with the help of the chzcrypt application.
|
||||
.br
|
||||
A crypto card can also be 'configured' or 'deconfigured'. This state
|
||||
may be adjusted on the HMC or SE. The chzcrypt application can also
|
||||
trigger this state with the --config-on and --config-off options.
|
||||
.br
|
||||
lszcrypt shows 'online' when a card or queue is available for
|
||||
cryptograhic operations. 'offline' is displayed when a card or queue
|
||||
is switched to (software) offline. If a card is 'deconfigured' via
|
||||
HMC, SE or chzcrypt the field shows 'deconfig'.
|
||||
.TP
|
||||
.B REQUESTS
|
||||
This is the counter value of successful processed requests on card or queue
|
||||
level. Successful here means the request was processed without any failure
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* lszcrypt - Display zcrypt devices and configuration settings
|
||||
*
|
||||
* Copyright IBM Corp. 2008, 2019
|
||||
* Copyright IBM Corp. 2008, 2020
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -86,7 +86,7 @@ const struct util_prg prg = {
|
||||
{
|
||||
.owner = "IBM Corp.",
|
||||
.pub_first = 2008,
|
||||
.pub_last = 2019,
|
||||
.pub_last = 2020,
|
||||
},
|
||||
UTIL_PRG_COPYRIGHT_END
|
||||
}
|
||||
@@ -339,6 +339,7 @@ static void show_capability(const char *id_str)
|
||||
static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
||||
const char *sub_dev)
|
||||
{
|
||||
long value;
|
||||
char buf[256];
|
||||
unsigned long facility;
|
||||
|
||||
@@ -347,14 +348,25 @@ static void read_subdev_rec_default(struct util_rec *rec, const char *grp_dev,
|
||||
else
|
||||
util_rec_set(rec, "type", buf);
|
||||
|
||||
if (util_file_read_line(buf, sizeof(buf), "%s/%s/online",
|
||||
grp_dev, sub_dev))
|
||||
util_rec_set(rec, "online", "-");
|
||||
else
|
||||
if (strcmp(buf, "0") == 0)
|
||||
util_rec_set(rec, "online", "offline");
|
||||
else
|
||||
if (util_path_is_readable("%s/%s/online", grp_dev, sub_dev)) {
|
||||
util_file_read_l(&value, 10, "%s/%s/online", grp_dev, sub_dev);
|
||||
if (value > 0)
|
||||
util_rec_set(rec, "online", "online");
|
||||
else {
|
||||
/* device is offline, check config (if available) */
|
||||
if (util_path_is_readable("%s/%s/config", grp_dev, sub_dev)) {
|
||||
util_file_read_l(&value, 10, "%s/%s/config", grp_dev, sub_dev);
|
||||
if (value > 0)
|
||||
util_rec_set(rec, "online", "offline");
|
||||
else
|
||||
util_rec_set(rec, "online", "deconfig");
|
||||
} else
|
||||
util_rec_set(rec, "online", "offline");
|
||||
}
|
||||
} else {
|
||||
/* no online attribute */
|
||||
util_rec_set(rec, "online", "-");
|
||||
}
|
||||
|
||||
util_file_read_ul(&facility, 16, "%s/ap_functions", grp_dev);
|
||||
if (facility & MASK_COPRO)
|
||||
@@ -457,6 +469,7 @@ static void show_subdevices(struct util_rec *rec, const char *grp_dev)
|
||||
*/
|
||||
static void read_rec_default(struct util_rec *rec, const char *grp_dev)
|
||||
{
|
||||
long value;
|
||||
char buf[256];
|
||||
unsigned long facility;
|
||||
|
||||
@@ -475,13 +488,21 @@ static void read_rec_default(struct util_rec *rec, const char *grp_dev)
|
||||
else
|
||||
util_rec_set(rec, "mode", "Unknown");
|
||||
|
||||
if (util_file_read_line(buf, sizeof(buf), "%s/online", grp_dev))
|
||||
util_rec_set(rec, "online", "-");
|
||||
else
|
||||
if (strcmp(buf, "0") == 0)
|
||||
util_rec_set(rec, "online", "offline");
|
||||
else
|
||||
if (util_path_is_readable("%s/online", grp_dev)) {
|
||||
util_file_read_l(&value, 10, "%s/online", grp_dev);
|
||||
if (value > 0)
|
||||
util_rec_set(rec, "online", "online");
|
||||
else {
|
||||
if (util_path_is_readable("%s/config", grp_dev)) {
|
||||
util_file_read_l(&value, 10, "%s/config", grp_dev);
|
||||
if (value > 0)
|
||||
util_rec_set(rec, "online", "offline");
|
||||
else
|
||||
util_rec_set(rec, "online", "deconfig");
|
||||
} else
|
||||
util_rec_set(rec, "online", "offline");
|
||||
}
|
||||
}
|
||||
|
||||
util_file_read_line(buf, sizeof(buf), "%s/request_count", grp_dev);
|
||||
util_rec_set(rec, "requests", buf);
|
||||
@@ -567,7 +588,7 @@ static void define_rec_default(struct util_rec *rec)
|
||||
util_rec_def(rec, "card", UTIL_REC_ALIGN_LEFT, 11, "CARD.DOMAIN");
|
||||
util_rec_def(rec, "type", UTIL_REC_ALIGN_LEFT, 5, "TYPE");
|
||||
util_rec_def(rec, "mode", UTIL_REC_ALIGN_LEFT, 11, "MODE");
|
||||
util_rec_def(rec, "online", UTIL_REC_ALIGN_LEFT, 7, "STATUS");
|
||||
util_rec_def(rec, "online", UTIL_REC_ALIGN_LEFT, 8, "STATUS");
|
||||
util_rec_def(rec, "requests", UTIL_REC_ALIGN_RIGHT, 8, "REQUESTS");
|
||||
}
|
||||
|
||||
|
||||
@@ -420,7 +420,7 @@ void VirtAdapterPrinter::print_virt_adpt(FILE *fp, __u32 devno,
|
||||
int *rc)
|
||||
{
|
||||
if (m_csv)
|
||||
fprintf(fp, "%x,%x.%x.%04x,",
|
||||
fprintf(fp, "%x,%x.%x.%04x",
|
||||
m_cfg->get_chpid_by_devno(devno, rc),
|
||||
ZIOREP_BUSID_UNPACKED(devno));
|
||||
else
|
||||
@@ -517,7 +517,7 @@ void VirtAdapterPrinter::print_num_requests(FILE *fp, const struct blkiomon_stat
|
||||
void VirtAdapterPrinter::print_topline(FILE *fp)
|
||||
{
|
||||
if (m_csv)
|
||||
fprintf(fp, "timestamp,aggregated,CHPID,Bus-ID,qdio utilization max %%,qdio utilization avg %%,queue full,fail erc,throughput read / MS/s,throughput write / MS/s,I/O requests read,I/O requqests write\n");
|
||||
fprintf(fp, "timestamp,aggregated,CHPID,Bus-ID,qdio utilization max %%,qdio utilization avg %%,queue full,fail erc,throughput read / MS/s,throughput write / MS/s,I/O requests read,I/O requests write\n");
|
||||
else {
|
||||
fprintf(fp, "CHP Bus-ID |qdio util.%%|queu|fail|-thp in MB/s-|I/O reqs-|\n");
|
||||
fprintf(fp, " ID max avg full erc rd wrt rd wrt\n");
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
@@ -28,6 +29,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -730,6 +732,67 @@ scan_bls_field(struct misc_file_buffer *file, struct scan_token* scan,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* find a line with keyword "title" and move it to the top
|
||||
*/
|
||||
static int sort_bls_fields(struct misc_file_buffer *file, char *filename)
|
||||
{
|
||||
bool is_title = false;
|
||||
size_t title_len = 0;
|
||||
int nr_titles = 0;
|
||||
size_t title_off;
|
||||
char *title;
|
||||
int current;
|
||||
size_t len;
|
||||
|
||||
while (file->length - file->pos > 4 /* for "title" */) {
|
||||
if (strncmp("title", &file->buffer[file->pos], 5) == 0) {
|
||||
is_title = true;
|
||||
nr_titles++;
|
||||
title_off = file->pos;
|
||||
}
|
||||
for (len = 0;; file->pos++, len++) {
|
||||
current = misc_get_char(file, 0);
|
||||
if (current == '\n' || current == EOF)
|
||||
break;
|
||||
}
|
||||
if (is_title == true)
|
||||
title_len = len;
|
||||
if (current == EOF)
|
||||
break;
|
||||
file->pos++;
|
||||
}
|
||||
file->pos = 0;
|
||||
|
||||
if (nr_titles == 0) {
|
||||
error_reason("no title in %s", filename);
|
||||
return -1;
|
||||
}
|
||||
if (nr_titles > 1) {
|
||||
error_reason("more than one title in %s", filename);
|
||||
return -1;
|
||||
}
|
||||
if (title_off == 0)
|
||||
return 0;
|
||||
|
||||
title = misc_malloc(title_len);
|
||||
if (!title)
|
||||
return -1;
|
||||
/*
|
||||
* copy the title field w/o trailing '\n' to the temporary buffer
|
||||
*/
|
||||
memcpy(title, &file->buffer[title_off], title_len);
|
||||
/*
|
||||
* shift preceded memory region w/o trailing '\n' to the right
|
||||
*/
|
||||
assert(file->buffer[title_off - 1] == '\n');
|
||||
memmove(&file->buffer[title_len + 1], &file->buffer[0], title_off - 1);
|
||||
file->buffer[title_len] = '\n';
|
||||
memcpy(&file->buffer[0], title, title_len);
|
||||
|
||||
free(title);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
scan_bls(const char* blsdir, struct scan_token** token, int scan_size)
|
||||
@@ -780,6 +843,10 @@ scan_bls(const char* blsdir, struct scan_token** token, int scan_size)
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
rc = sort_bls_fields(&file, filename);
|
||||
if (rc)
|
||||
goto err;
|
||||
|
||||
while ((size_t)file.pos < file.length) {
|
||||
current = misc_get_char(&file, 0);
|
||||
switch (current) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
include ../common.mak
|
||||
|
||||
SUB_DIRS = ekmfweb
|
||||
|
||||
ifneq (${HAVE_OPENSSL},0)
|
||||
BUILD_TARGETS += zkey
|
||||
INSTALL_TARGETS += install-zkey
|
||||
@@ -62,7 +64,7 @@ zkey-cryptsetup-skip-cryptsetup2:
|
||||
zkey-cryptsetup-skip-jsonc:
|
||||
echo " SKIP zkey-cryptsetup due to HAVE_JSONC=0"
|
||||
|
||||
all: $(BUILD_TARGETS)
|
||||
all: $(BUILD_TARGETS) $(SUB_DIRS)
|
||||
|
||||
zkey.o: zkey.c pkey.h cca.h ep11.h misc.h
|
||||
pkey.o: pkey.c pkey.h cca.h ep11.h utils.h
|
||||
@@ -73,9 +75,10 @@ properties.o: check-dep-zkey properties.c properties.h
|
||||
keystore.o: keystore.c keystore.h properties.h pkey.h cca.h ep11.h utils.h
|
||||
zkey-cryptsetup.o: check-dep-zkey-cryptsetup zkey-cryptsetup.c pkey.h cca.h \
|
||||
ep11.h misc.h utils.h
|
||||
kms.o: kms.c kms.h kms-plugin.h utils.h pkey.h
|
||||
|
||||
zkey: LDLIBS = -ldl -lcrypto
|
||||
zkey: zkey.o pkey.o cca.o ep11.o properties.o keystore.o utils.o $(libs)
|
||||
zkey: zkey.o pkey.o cca.o ep11.o properties.o keystore.o utils.o kms.o $(libs)
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c -lcrypto
|
||||
@@ -86,22 +89,35 @@ install-common:
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
|
||||
|
||||
install-zkey:
|
||||
install-zkey: zkey
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -m 644 -c zkey.1 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey
|
||||
$(INSTALL) -d -m 770 $(DESTDIR)$(SYSCONFDIR)/zkey/repository
|
||||
$(INSTALL) -m 644 -c kms-plugins.conf $(DESTDIR)$(SYSCONFDIR)/zkey
|
||||
|
||||
install-zkey-cryptsetup:
|
||||
install-zkey-cryptsetup: zkey-cryptsetup
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 zkey-cryptsetup $(DESTDIR)$(USRBINDIR)
|
||||
$(INSTALL) -m 644 -c zkey-cryptsetup.1 $(DESTDIR)$(MANDIR)/man1
|
||||
|
||||
install: all install-common $(INSTALL_TARGETS)
|
||||
install: all install-common $(INSTALL_TARGETS) $(SUB_DIRS)
|
||||
|
||||
clean:
|
||||
clean: $(SUB_DIRS)
|
||||
rm -f *.o zkey zkey-cryptsetup detect-libcryptsetup.dep \
|
||||
check-dep-zkey check-dep-zkey-cryptsetup
|
||||
|
||||
#
|
||||
# For simple "make" we explicitly set the MAKECMDGOALS to "all".
|
||||
#
|
||||
ifeq ($(MAKECMDGOALS),)
|
||||
MAKECMDGOALS = all
|
||||
endif
|
||||
|
||||
$(SUB_DIRS):
|
||||
$(foreach goal,$(MAKECMDGOALS), \
|
||||
$(MAKE) -C $@ TOPDIR=$(TOPDIR) ARCH=$(ARCH) $(goal) ;)
|
||||
.PHONY: $(SUB_DIRS)
|
||||
|
||||
.PHONY: all install clean zkey-skip zkey-cryptsetup-skip-cryptsetup2 \
|
||||
zkey-cryptsetup-skip-jsonc install-common install-zkey \
|
||||
install-zkey-cryptsetup
|
||||
|
||||
11
zkey/cca.c
11
zkey/cca.c
@@ -554,7 +554,8 @@ static int get_cca_adapter_version(struct cca_lib *cca,
|
||||
* because the zcrypt kernel module is on an older level. -ENODEV is
|
||||
* returned if the APQN is not available.
|
||||
*/
|
||||
int select_cca_adapter(struct cca_lib *cca, int card, int domain, bool verbose)
|
||||
int select_cca_adapter(struct cca_lib *cca, unsigned int card,
|
||||
unsigned int domain, bool verbose)
|
||||
{
|
||||
unsigned int adapters, adapter;
|
||||
char adapter_serialnr[9];
|
||||
@@ -633,12 +634,12 @@ struct find_mkvp_info {
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
unsigned int flags;
|
||||
bool found;
|
||||
int card;
|
||||
int domain;
|
||||
unsigned int card;
|
||||
unsigned int domain;
|
||||
bool verbose;
|
||||
};
|
||||
|
||||
static int find_mkvp(int card, int domain, void *handler_data)
|
||||
static int find_mkvp(unsigned int card, unsigned int domain, void *handler_data)
|
||||
{
|
||||
struct find_mkvp_info *info = (struct find_mkvp_info *)handler_data;
|
||||
struct mk_info mk_info;
|
||||
@@ -711,7 +712,7 @@ int select_cca_adapter_by_mkvp(struct cca_lib *cca, u8 *mkvp, const char *apqns,
|
||||
|
||||
pr_verbose(verbose, "Select mkvp %s in APQNs %s for the CCA host "
|
||||
"library", printable_mkvp(CARD_TYPE_CCA, mkvp),
|
||||
apqns == 0 ? "ANY" : apqns);
|
||||
apqns == NULL ? "ANY" : apqns);
|
||||
|
||||
memcpy(info.mkvp, mkvp, sizeof(info.mkvp));
|
||||
info.flags = flags;
|
||||
|
||||
@@ -123,7 +123,8 @@ int key_token_change(struct cca_lib *cca,
|
||||
u8 *secure_key, unsigned int secure_key_size,
|
||||
char *method, bool verbose);
|
||||
|
||||
int select_cca_adapter(struct cca_lib *cca, int card, int domain, bool verbose);
|
||||
int select_cca_adapter(struct cca_lib *cca, unsigned int card,
|
||||
unsigned int domain, bool verbose);
|
||||
|
||||
#define FLAG_SEL_CCA_MATCH_CUR_MKVP 0x01
|
||||
#define FLAG_SEL_CCA_MATCH_OLD_MKVP 0x02
|
||||
|
||||
48
zkey/ekmfweb/Makefile
Normal file
48
zkey/ekmfweb/Makefile
Normal file
@@ -0,0 +1,48 @@
|
||||
include ../../common.mak
|
||||
|
||||
all: zkey-ekmfweb.so
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
|
||||
export LIBRARY_PATH = $(rootdir)/libekmfweb:$LIBRARY_PATH
|
||||
|
||||
zkey-ekmfweb.o: zkey-ekmfweb.c zkey-ekmfweb.h ../kms-plugin.h \
|
||||
../cca.h ../utils.h ../pkey.h ../properties.h \
|
||||
$(rootdir)include/ekmfweb/ekmfweb.h $(rootdir)/libekmfweb/libekmfweb.so
|
||||
|
||||
properties.o: ../properties.c ../properties.h
|
||||
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
|
||||
|
||||
pkey.o: ../pkey.c ../pkey.h ../cca.h ../ep11.h ../utils.h
|
||||
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
|
||||
|
||||
cca.o: ../cca.c ../cca.h ../pkey.h ../ep11.h ../utils.h
|
||||
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
|
||||
|
||||
ep11.o: ../ep11.c ../ep11.h ../pkey.h ../cca.h ../utils.h
|
||||
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
|
||||
|
||||
utils.o: ../utils.c ../utils.h ../pkey.h ../cca.h ../ep11.h
|
||||
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -fPIC -c $< -o $@
|
||||
|
||||
zkey-ekmfweb.so: ALL_CFLAGS += -fPIC
|
||||
zkey-ekmfweb.so: LDLIBS = -lekmfweb -ldl -lcrypto -shared
|
||||
zkey-ekmfweb.so: LDFLAGS = -shared -Wl,--version-script=zkey-ekmfweb.map \
|
||||
-Wl,-z,defs,-Bsymbolic
|
||||
zkey-ekmfweb.so: zkey-ekmfweb.o properties.o pkey.o cca.o ep11.o utils.o $(libs)
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
install-libekmfweb.dep:
|
||||
$(MAKE) -C $(rootdir)/libekmfweb/ TOPDIR=$(TOPDIR) ARCH=$(ARCH) install
|
||||
touch install-libekmfweb.dep
|
||||
|
||||
install: all install-libekmfweb.dep zkey-ekmfweb.so
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL) -m 644 -c zkey-ekmfweb.1 $(DESTDIR)$(MANDIR)/man1
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(LIB64DIR)
|
||||
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 -T zkey-ekmfweb.so $(DESTDIR)$(LIB64DIR)/zkey-ekmfweb.so
|
||||
|
||||
clean:
|
||||
rm -f *.o zkey-ekmfweb.so install-libekmfweb.dep
|
||||
|
||||
.PHONY: all install clean
|
||||
497
zkey/ekmfweb/zkey-ekmfweb.1
Normal file
497
zkey/ekmfweb/zkey-ekmfweb.1
Normal file
@@ -0,0 +1,497 @@
|
||||
.\" Copyright IBM Corp. 2020
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH ZKEY\-EKMFWEB 1 "July 2020" "s390-tools"
|
||||
.SH NAME
|
||||
zkey\-ekmfweb \- Key management system plugin for EKMF Web (IBM Enterprise Key
|
||||
Management Foundation \- Web Edition)
|
||||
.
|
||||
.
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
The \fBzkey\-ekmfweb.so\fP library is a key management system plugin for
|
||||
\fBzkey\fP and provides an interface to \fBEKMF Web\fP (IBM Enterprise Key
|
||||
Management Foundation \- Web Edition). It allows to integrate the external key
|
||||
management system EKMF Web into zkey.
|
||||
.PP
|
||||
Secure AES keys can be generated in EKMF Web and are then imported into the zkey
|
||||
secure key repository. The keys can be used to encrypt volumes, the same way
|
||||
as with secure AES keys generated by zkey locally.
|
||||
.PP
|
||||
EKMF Web supports secure keys of type \fBCCA\-AESCIPHER\fP, and requires one or
|
||||
multiple \fBIBM cryptographic adapters in CCA coprocessor mode\fP of version 6
|
||||
or later, e.g. a CEX6C.
|
||||
.
|
||||
.SS "Bind the zkey secure key repository to EKMF Web"
|
||||
.
|
||||
To use EKMF Web with zkey, the zkey secure key repository must first be bound to
|
||||
the EKMF Web key management system plugin.
|
||||
.PP
|
||||
Use the \fBzkey kms plugins\fP command to list available key management system
|
||||
plugins. The EKMF Web plugin appears as plugin \fBEKMFWeb\fP in the list of
|
||||
available plugins. If it does not appear, check if it is configured properly in
|
||||
configuration file \fB/etc/zkey/kms\-plugins.conf\fP. Refer to the \fBzkey\fP
|
||||
man page for details about this configuration file.
|
||||
.PP
|
||||
Use the \fBzkey kms bind EKMFWeb\fP command to bind the EKMF Web key management
|
||||
system plugin to the zkey repository. You must then configure the EKMF Web
|
||||
plugin with command \fBzkey kms configure\fP before it can be used.
|
||||
.
|
||||
.SS "Display information about the EKMF Web key management system plugin"
|
||||
.
|
||||
Use the \fBzkey kms info\fP command to display information about the EKMF Web
|
||||
key management system plugin and its configuration. If any of the settings are
|
||||
displayed as \fB'(configuration required)'\fP, then you must configure these
|
||||
settings before you can use the EKMF Web plugin. Use the \fBzkey kms
|
||||
configure\fP to do so.
|
||||
.
|
||||
.SS "Configure the EKMF Web key management system plugin"
|
||||
.
|
||||
Use the \fBzkey kms configure\fP command to configure or re\-configure the
|
||||
EKMF Web plugin. Use command \fBzkey kms configure \-\-help\fP to display the
|
||||
possible command line options to perform the configuration.
|
||||
.PP
|
||||
Configuring the EKMF Web plugin may be a multi-step task. You can supply all
|
||||
configuration options at once or use the \fBzkey kms configure\fP command
|
||||
several times supplying only one or a few configuration options each time.
|
||||
.PP
|
||||
The following settings must be configured:
|
||||
.RS 2
|
||||
.IP "\(bu" 2
|
||||
The \fBAPQNs\fP associated with the EKMF Web key management system plugin. These
|
||||
APQNs are used by the EKMF Web plugin to generate internally used secure keys
|
||||
(i.e. the identity key), as well as to import secure AES keys from EKMF Web into
|
||||
the zkey repository, enciphered with the current CCA master key. Secure keys
|
||||
imported from EKMF Web will automatically be associated with the APQNs
|
||||
associated with the EKMF Web plugin. Use the \fB\-\-apqns\fP option to specify
|
||||
the APQNs to associate with the EKMF Web plugin.
|
||||
.
|
||||
.IP "\(bu" 2
|
||||
The \fBconnection to the EKMF Web server\fP. The EKMF Web plugin communicates
|
||||
with EKMF Web via RESTful web services over HTTPS (Hypertext Transfer Protocol
|
||||
Secure). Use option \fB\-\-ekmfweb\-url\fP to specify the URL of the EKMF Web
|
||||
server. The URL should start with \fB'https://'\fP, and may contain a port
|
||||
number separated by a colon. If no port number is specified, 443 is used for
|
||||
HTTPS. Additional TLS (Transport Layer Security) specific options can be
|
||||
specified to control the behavior of the TLS protocol and the validation of the
|
||||
EKMF Web server's certificate. Use command \fBzkey kms configure \-\-help\fP to
|
||||
display the possible command line options.
|
||||
.
|
||||
.IP "\(bu" 2
|
||||
The \fBEKMF Web settings\fP, such as the EKMF Web server's public key and the
|
||||
key templates used by EKMF Web to generate keys. These settings are
|
||||
automatically retrieved from EKMF Web, once the connection to the EKMF Web
|
||||
server has been configured. Use option \fB\-\-refresh\-settings\fP to refresh
|
||||
the settings, when they have changed in EKMF Web.
|
||||
.
|
||||
.IP "\(bu" 2
|
||||
The secure \fBidentity key\fP used to identify the zkey client with EKMF Web,
|
||||
and to cryptographically sign requests sent to EKMF Web. The identity key
|
||||
is a secure key, and is automatically generated once the connection to the
|
||||
EKMF Web server has been configured. Use option \fB\-\-gen\-identity\-key\fP to
|
||||
re-generate the identity key, if needed. You must re-generate a
|
||||
registration certificate with the newly generated identity key and re-register
|
||||
this zkey client with the EKMF Web server.
|
||||
.
|
||||
.IP "\(bu" 2
|
||||
The \fBregistration certificate\fP to register the zkey client with EKMF Web.
|
||||
The registration certificate is an X.509 certificate generated with the secure
|
||||
identity key. Use option \fB\-\-gen\-csr\fP to generate a \fBcertificate signing
|
||||
request\fP (CSR) with the identity key. You pass this CSR to a certificate
|
||||
authority (CA) to have it issue a CA signed certificate for the EKMF Web
|
||||
plugin. Alternatively, use option \fB\-\-gen\-self\-signed\-cert\fP to generate
|
||||
a \fBself signed certificate\fP with the identity key for the EKMF Web plugin.
|
||||
Use options \fB\-\-cert\-subject\fP and \fB\-\-cert\-extensions\fP to specify
|
||||
the certificate subject name and extensions (if any). To renew an existing
|
||||
certificate, use option \fB\-\-renew\-cert\fP. The subject name and extensions
|
||||
are then read from the certificate that is to be renewed.
|
||||
.
|
||||
.IP "\(bu" 2
|
||||
\fBRegister\fP the zkey client with EKMF Web. Use option \fB\-\-register\fP to
|
||||
register the zkey client using the \fBregistration certificate\fP from the
|
||||
previous step. An identity key is generated in EKMF Web using the public
|
||||
key from the certificate. You may also need to use option
|
||||
\fB\-\-label\-tags\fP to specify the label tags for creating the identity key
|
||||
in EKMF Web. Use command \fBzkey kms info\fP to find out which label tags the
|
||||
identity key template uses.
|
||||
.RE
|
||||
.
|
||||
.SS "Re-encipher the secure identity key"
|
||||
.
|
||||
Use the \fBzkey kms reencipher\fP command to re-encipher the secure identity
|
||||
key of the EKMF Web plugin with a new master key.
|
||||
The secure identity key must be re-enciphered when the \fBAPKA master key\fP
|
||||
of the CCA cryptographic adapter changes.
|
||||
.PP
|
||||
See the man page of \fBzkey\fP for a description of the the \fBzkey kms
|
||||
reencipher\fP command.
|
||||
.PP
|
||||
\fBNote:\fP The \fBzkey kms reencipher\fP command does \fBnot\fP re-encipher
|
||||
secure keys that have been generated by or have been imported from EKMF Web and
|
||||
are now stored in the secure key repository. Use the regular \fBzkey
|
||||
reencipher\fP command to re-encipher those secure keys.
|
||||
.
|
||||
.SS "Generating secure AES keys with EKMF Web"
|
||||
.
|
||||
Use the \fBzkey generate\fP command to generate secure AES keys in EKMF Web and
|
||||
import the newly generated key into the secure key repository. When the zkey
|
||||
repository is bound to the EKMF Web plugin, then the \fBzkey generate\fP command
|
||||
always generates the keys in EKMF Web, except when the \fB\-\-local\fP
|
||||
option is specified.
|
||||
.PP
|
||||
Keys generated in EKMF Web are always of type \fBCCA\-AESCIPHER\fP. The
|
||||
cryptographic size of the keys depend on the underlying EKMF Web template.
|
||||
Use \fBzkey kms info\fP to display the names of the key templates configured.
|
||||
If option \fB\-\-key\-bits\fP is specified, it must match the key size in the
|
||||
template.
|
||||
.PP
|
||||
You may need to use option \fB\-\-label\-tags\fP to specify the label tags
|
||||
for creating keys in EKMF Web. Use command \fBzkey kms info\fP to find out
|
||||
which label tags the configured key template uses.
|
||||
.PP
|
||||
Keys generated with EKMF Web are bound to EKMF Web, and also inherit the APQN
|
||||
association from the EKMF Web plugin. You cannot associate different APQNs to
|
||||
a key that is bound to EKMF Web. Other additional information can be associated
|
||||
with a secure key as usual, using the \fB\-\-description\fP, \fB\-\-volumes\fP,
|
||||
\fB\-\-volume\-type\fP, or the \fB\-\-sector\-size\fP options. This associated
|
||||
information is also stored in EKMF Web with the key.
|
||||
.
|
||||
.SS "Remove secure keys bound to EKMF Web from the key repository"
|
||||
.
|
||||
Use the \fBzkey remove\fP command to remove an existing secure key from the
|
||||
secure key repository. If the key is bound to EKMF Web, then you can also
|
||||
change the state of the key in EKMF Web, while removing it. Use option
|
||||
\fB\-\-state\fP to specify the new state of the key in EKMF Web. If no state is
|
||||
specified, the key remains unchanged in EKMF Web, but is removed from the local
|
||||
secure key repository only.
|
||||
.
|
||||
.SS "Change secure keys bound to EKMF Web"
|
||||
.
|
||||
Use the \fBzkey change\fP command to change the description, the associated
|
||||
volumes, the sector size, and the volume type of a secure key contained in the
|
||||
secure key repository. If the key is bound to EKMF Web, then the changed
|
||||
information is also updated for the key in EKMF Web.
|
||||
.PP
|
||||
You cannot change the associated cryptographic adapters (APQNs) of a key that
|
||||
is bound to EKMF Web, because it inherits the APQN association from the EKMF
|
||||
Web plugin. To change the APQNs associated with the EKMF Web plugin, use the
|
||||
\fBzkey kms configure\fP command with the \fB--apqns\fP option. This also
|
||||
changes the APQN associations of all secure keys in the secure key repository,
|
||||
that are bound to the EKMF Web plugin.
|
||||
.
|
||||
.SS "Rename secure keys bound to EKMF Web"
|
||||
.
|
||||
Use the \fBzkey rename\fP command to rename an existing secure key in the
|
||||
secure key repository. If the key is bound to EKMF Web, then the new name
|
||||
is also updated for the key in EKMF Web. Note that the key label as it
|
||||
is known in EKMF Web cannot be changed. Only the associated zkey name is
|
||||
updated.
|
||||
.
|
||||
.SS "List secure keys managed by EKMF Web"
|
||||
.
|
||||
Use the \fBzkey kms list\fP command to display eligible secure keys managed by
|
||||
EKMF Web. You can filter the displayed list by key label, key name, associated
|
||||
volumes, and volume type. Refer to the man page of \fBzkey\fP for the details
|
||||
on these filter options.
|
||||
.PP
|
||||
Use option \fB\-\-states\fP to filter the list by the key state in EKMF Web.
|
||||
You can specify multiple states, separated by comma. If this option is omitted,
|
||||
then only keys in \fBACTIVE\fP state are displayed.
|
||||
.PP
|
||||
By default, only keys are displayed, which this zkey client is allowed to use.
|
||||
Only keys where the export control options include the identity key of this zkey
|
||||
client as allowed exporting key can be used by this zkey client.
|
||||
Specify option \fB\-\-all\fP to also list keys that this zkey client is
|
||||
not allowed to use. The EKMF Web operator can change the export control options
|
||||
of a key to allow a certain zkey identity key to export the key.
|
||||
.
|
||||
.SS "Import secure keys managed by EKMF Web into the repository"
|
||||
.
|
||||
Use the \fBzkey kms import\fP command to import secure keys managed by EKMF Web
|
||||
into the secure key repository. You can filter the list of keys to be imported
|
||||
by key label, key name, associated volumes, and volume type. Refer to the man
|
||||
page of \fBzkey\fP for the details on these filter options.
|
||||
.PP
|
||||
Only keys are imported, which this zkey client is allowed to use. Only keys
|
||||
where the export control options include the identity key of this zkey
|
||||
client as allowed exporting key can be used by this zkey client. The EKMF Web
|
||||
operator can change the export control options of a key, to allow a certain
|
||||
zkey identity key to export the key.
|
||||
.
|
||||
.SS "Refresh secure keys bound to EKMF Web"
|
||||
.
|
||||
Use the \fBzkey kms refresh\fP command to refresh secure keys that are bound to
|
||||
EKMF Web. You can filter the list of keys to be refreshed by name, associated
|
||||
volumes, volume type, and key type. Refreshing a key updates the secure key by
|
||||
re-importing it from EKMF Web. Use option \fB\-\-refresh\-properties\fP to also
|
||||
update the associated information, such as the textual description, associated
|
||||
volumes, volume type, and sector size, with the information stored with the key
|
||||
in EKMF Web. Refer to the man page of \fBzkey\fP for the details on the \fBzkey
|
||||
kms refresh\fP command.
|
||||
.PP
|
||||
The \fBzkey kms refresh\fP command can also help if the secure keys have not
|
||||
been re-enciphered properly after a CCA master key change, and thus became
|
||||
invalid. By refreshing the keys using the \fBzkey kms refresh\fP command, the
|
||||
secure key is re-imported under the current CCA master key. So this command
|
||||
could also be used as an alternative to the \fBzkey reencipher\fP command for
|
||||
keys that are bound to EKMF Web.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SH OPTIONS
|
||||
This section describes the EKMF Web plugin specific options of the \fBzkey\fP
|
||||
commands. Refer to the \fBzkey\fP man page for the remaining, non EKMF Web
|
||||
plugin specific options.
|
||||
.
|
||||
.SS "Options for the zkey kms configure command"
|
||||
.TP
|
||||
.BR \-u ", " \-\-ekmfweb\-url\~\fIurl\fP
|
||||
Specifies the URL of the EKMF Web server. The URL should start with
|
||||
\fBhttps://\fP, and may contain a port number separated by a colon. If no
|
||||
port number is specified, 443 is used for HTTPS.
|
||||
.TP
|
||||
.BR \-b ", " \-\-tls\-ca\-bundle\~\fIca\-bundle\fP
|
||||
Specifies the CA bundle PEM file or directory containing the CA certificates
|
||||
used to verify the EKMF Web server certificate during TLS handshake. If this
|
||||
specifies a directory path, then this directory must have been prepared
|
||||
with OpenSSL's \fBc_rehash\fP utility. Default are the system CA certificates.
|
||||
.TP
|
||||
.BR \-\-tls\-client\-cert\~\fIpem\-file\fP
|
||||
Specifies the PEM file containing the client's TLS certificate for use with
|
||||
TLS client authentication.
|
||||
.TP
|
||||
.BR \-\-tls\-client\-key\~\fIpem\-file\fP
|
||||
Specifies the PEM file containing the client's private key for use with TLS
|
||||
client authentication.
|
||||
.TP
|
||||
.BR \-\-tls\-client\-key\-passphrase\~\fIpassphrase\fP
|
||||
If the PEM file is passphrase protected, this option specifies the passphrase
|
||||
to unlock the PEM file that is specified with option \fB\-\-tls\-client\-key\fP.
|
||||
.TP
|
||||
.BR \-\-tls\-pin\-server\-pubkey
|
||||
Pin the EKMF Web server's public key to verify on every connection that the
|
||||
public key of the EKMF Web server's certificate is the same that was used when
|
||||
the connection to the EKMF Web server was configured. This option can only be
|
||||
used with CA signed EKMF Web server certificates.
|
||||
.TP
|
||||
.BR \-\-tls\-trust\-server\-cert
|
||||
Trust the EKMF Web server's certificate even if it is a self signed
|
||||
certificate, or could not be verified due to other reasons. This option can be
|
||||
used instead of option \fB\-\-tls\-pin\-server\-pubkey\fP with self signed
|
||||
EKMF Web server certificates.
|
||||
.TP
|
||||
.BR \-\-tls\-dont\-verify\-server\-cert
|
||||
Do not verify the authenticity of the EKMF Web server's certificate. For self
|
||||
signed EKMF Web server certificates, this is the default. Use option
|
||||
\fB\-\-tls\-pin\-server\-cert\fP to ensure the self signed certificate's
|
||||
authenticity explicitly. CA signed EKMF Web server certificates are verified by
|
||||
default. This option disables the verification.
|
||||
.TP
|
||||
.BR \-\-tls\-verify\-hostname
|
||||
Verify that the EKMF Web server certificate's \fBCommon Name\fP field or a
|
||||
\fBSubject Alternate Name\fP field matches the host name used to connect to the
|
||||
EKMF Web server.
|
||||
.TP
|
||||
.BR \-R ", " \-\-refresh\-settings
|
||||
Refresh the EKMF Web server settings. This is automatically performed when the
|
||||
connection to the EKMF Web server is (re-)configured. Use this option when the
|
||||
settings of the already configured EKMF Web server have changed.
|
||||
.TP
|
||||
.BR \-i ", " \-\-gen\-identity\-key
|
||||
Generate an identity key for the EKMF Web plugin. An identity key is
|
||||
automatically generated when the EKMF Web server connection has been configured.
|
||||
Use this option to generate a new identity key. You need to re-generate a
|
||||
registration certificate with the newly generated identity key, and re-register
|
||||
this zkey client with the EKMF Web server.
|
||||
.TP
|
||||
.BR \-c ", " \-\-gen\-csr\~\fIcsr\-pem\-file\fP
|
||||
Generate a certificate signing request (CSR) with the identity key and store it
|
||||
into the specified PEM file. You pass this CSR to a certificate authority (CA)
|
||||
to have it issue a CA signed certificate for the EKMF Web plugin. You need to
|
||||
register the certificate with EKMF Web before you can access EKMF Web.
|
||||
.TP
|
||||
.BR \-C ", " \-\-gen\-self\-signed\-cert\~\fIcert\-pem\-file\fP
|
||||
Generate a self signed certificate with the identity key and store it into the
|
||||
specified PEM file. You need to register the certificate with EKMF Web before
|
||||
you can access EKMF Web.
|
||||
.TP
|
||||
.BR \-s ", " \-\-cert\-subject\~\fIsubject\-rdns\fP
|
||||
Specifies the subject name for generating a certificate signing request (CSR)
|
||||
or self signed certificate, in the form
|
||||
\fB<type>=<value>(;<type>=<value>)*[;]\fP with types recognized by OpenSSL.
|
||||
.TP
|
||||
.BR \-s ", " \-\-cert\-extensions\~\fIextensions\fP
|
||||
Specifies the certificate extensions for generating a certificate signing
|
||||
request (CSR) or self signed certificate, in the form
|
||||
\fB<name>=[critical,]<value(s)>(;<name>=[critical,]<value(s)>)*[;]\fP
|
||||
with extension names and values recognized by OpenSSL.
|
||||
.TP
|
||||
.BR \-N ", " \-\-renew\-cert\~\fIcert\-pem\-file\fP
|
||||
Specifies an existing PEM file containing the certificate to be renewed. The
|
||||
certificate's subject name and extensions are used to generate the certificate
|
||||
signing request (CSR) or renewed self signed certificate.
|
||||
.TP
|
||||
.BR \-n ", " \-\-csr\-new\-header
|
||||
Adds the word \fBNEW\fP to the PEM file header and footer lines on the
|
||||
certificate signing request. Some software and some CAs need this.
|
||||
.TP
|
||||
.BR \-d ", " \-\-cert\-validity\-days\~\fIdays\fP
|
||||
Specifies the number of days to certify the self signed certificate. The
|
||||
default is 30 days.
|
||||
.TP
|
||||
.BR \-D ", " \-\-cert\-digest\~\fIdigest\fP
|
||||
Specifies the digest algorithm to use when generating a certificate signing
|
||||
request or self signed certificate. The default is determined by OpenSSL.
|
||||
.TP
|
||||
.BR \-r ", " \-\-register\~\fIcert\-file\fP
|
||||
Register the zkey client with EKMF Web by generating an identity key in EKMF
|
||||
Web using the certificate from the specified file. Supported certificate files
|
||||
formats are \fB.pem\fP, \fB.crt\fP, \fB.cert\fP, \fB.cer\fP, and \fB.der\fP
|
||||
(i.e. either base64 or DER encoded). If you want to register a self signed
|
||||
certificate that you are about to generate using option
|
||||
\fB\-\-gen\-self\-signed\-cert\fP, then specify the same certificate file
|
||||
name here, and the generated certificate is registered right away.
|
||||
.TP
|
||||
.BR \-T ", " \-\-label\-tags\~\fIlabel\-tags\fP
|
||||
Specifies the label tags for generating the identity key in EKMF Web when
|
||||
registering the zkey client, in the form
|
||||
\fB<tag>=<value>(,<tag>=<value>)*[,]\fP with tags as defined by the key
|
||||
template. Use the \fBzkey kms info\fP command to display the key templates used
|
||||
by zkey. For registration, the template for identity keys is used.
|
||||
.
|
||||
.SS "Options for the zkey generate command"
|
||||
.
|
||||
.TP
|
||||
.BR \-T ", " \-\-label\-tags\~\fIlabel\-tags\fP
|
||||
Specifies the label tags for generating a secure key in EKMF Web, in the form
|
||||
\fB<tag>=<value>(,<tag>=<value>)*[,]\fP with tags as defined by the key
|
||||
template. Use the \fBzkey kms info\fP command to display the key templates used
|
||||
by zkey. For XTS type keys the two templates for \fBXTS-Key1\fP and
|
||||
\fBXTS-Key2\fP are used. For non-XTS type keys, the template for \fBNon-XTS\fP
|
||||
keys is used.
|
||||
.
|
||||
.SS "Options for the zkey remove command"
|
||||
.
|
||||
.TP
|
||||
.BR \-s ", " \-\-state\~\fIstate\fP
|
||||
Specifies the state to which to change the key in EKMF Web, after removing
|
||||
the secure key from the local secure key repository. Possible states are
|
||||
\fBDEACTIVATED\fP, \fBCOMPROMISED\fP, \fBDESTROYED\fP, and
|
||||
\fBDESTROYED\-COMPROMISED\fP. If this option is not specified, the state of the
|
||||
key in EKMF Web is not changed, but the key is removed from the local secure
|
||||
key repository only.
|
||||
.
|
||||
.SS "Options for the zkey kms list command"
|
||||
.
|
||||
.TP
|
||||
.BR \-s ", " \-\-states\~\fIstates\fP
|
||||
Specifies the states of the keys that are to be listed. Multiple states can be
|
||||
separated by comma. Possible states are \fBPRE\-ACTIVATION\fP, \fBACTIVE\fP,
|
||||
\fBDEACTIVATED\fP, \fBCOMPROMISED\fP, \fBDESTROYED\fP, and
|
||||
\fBDESTROYED\-COMPROMISED\fP. If this option is not specified, only keys in
|
||||
state \fBACTIVE\fP are listed.
|
||||
.TP
|
||||
.BR \-a ", " \-\-all
|
||||
List all keys that can be used for volume encryption. If this option is not
|
||||
specified, then only volume encryption keys that are allowed to be exported by
|
||||
EKMF Web using the identity key of this zkey client are listed.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
.B zkey kms plugins
|
||||
Lists available key manamgement system plugins.
|
||||
.TP
|
||||
.B zkey kms bind EKMFWeb
|
||||
Binds the EKMF Web plugin to the current secure key repository.
|
||||
.TP
|
||||
.B zkey kms configure \-\-apqns 03.004c
|
||||
Configures the APQN '03.004c' to be associated with the EKMF Web plugin.
|
||||
.TP
|
||||
.B zkey kms configure \-\-ekmfweb\-url https://my.ekmfweb.server
|
||||
Configures the connection to the EKMF Web server on 'my.ekmfweb.server'.
|
||||
.TP
|
||||
.B zkey kms configure \-\-ekmfweb\-url https://my.ekmfweb.server \-\-tls\-pin\-server\-pubkey \-\-tls\-verify\-hostname
|
||||
Configures the connection to the EKMF Web server on 'my.ekmfweb.server' and
|
||||
pins the server's public key from the server's TSL certificate as well as
|
||||
enables verification of the host nmae to match the server's Common Name in the
|
||||
certificate.
|
||||
.TP
|
||||
.B zkey kms configure \-\-gen\-csr csr.pem \-\-cert\-subject \(dqCN=my.zkey.client;OU=Example;C=US\(dq
|
||||
Generates a certificate signing request with the identity key and the specified
|
||||
subject name and stores it in file 'csr.pem'.
|
||||
.TP
|
||||
.B zkey kms configure \-\-gen\-csr csr.pem \-\-renew\-cert cert.pem
|
||||
Generates a certificate signing request with the identity key to renew the
|
||||
existing certificate in file cert.pem and stores it in file 'csr.pem'.
|
||||
.TP
|
||||
.B zkey kms configure \-\-gen\-self\-signed\-cert cert.pem \-\-cert\-subject \(dqCN=my.zkey.client;OU=Example;C=US\(dq \-\-cert\-validity\-days 50
|
||||
Generates a self signed certificate with the identity key and the specified
|
||||
subject name and a validity of 50 days, and stores it in file 'cert.pem'.
|
||||
.TP
|
||||
.B zkey kms configure \-\-gen\-self\-signed\-cert cert.pem \-\-cert\-subject \(dqCN=my.zkey.client;OU=Example;C=US\(dq \-\-cert\-extensions \(dqkeyUsage=critical,digitalSignature,keyAgreement\(dq
|
||||
Generates a self signed certificate with the identity key and the specified
|
||||
subject name and a certificate extension to limit the key usage, and stores it
|
||||
in file 'cert.pem'.
|
||||
.TP
|
||||
.B zkey kms configure \-\-register cert.pem
|
||||
Registers the zkey client with EKMF Web using the certifcate in file 'cert.pem'.
|
||||
.TP
|
||||
.B zkey kms configure \-\-register cert.pem \-\-label\-tags \(dqENV=TEST,APP=LINUX\(dq
|
||||
Registers the zkey client with EKMF Web using the certifcate in file 'cert.pem'
|
||||
and the label tags 'ENV=TEST' and 'APP=LINUX' for the identity key.
|
||||
.TP
|
||||
.B zkey kms info
|
||||
Displays information about the EKMF Web plugin and its configuration.
|
||||
.TP
|
||||
.B zkey kms reencipher --staged
|
||||
Re-enciphers the EKMF Plugin's identity key with a new CCA master key in staged
|
||||
mode
|
||||
.TP
|
||||
.B zkey generate \-\-name seckey \-\-volumes /dev/dasdc1:encvol \-\-label\-tags \(dqENV=TEST,APP=LINUX\(dq
|
||||
Generates a secure AES key in EKMF Web using the label tags 'ENV=TEST' and
|
||||
'APP=LINUX' and stores it in the secure key repository using the name 'seckey'
|
||||
and associates it with block device '/dev/dasdc1' and device-mapper name
|
||||
'encvol'.
|
||||
.TP
|
||||
.B zkey generate \-\-name seckey \-\-xts \-\-volumes /dev/dasdc1:encvol \-\-volume-type luks2 \-\-label\-tags \(dqENV=TEST,APP=LINUX\(dq
|
||||
Generates a secure AES key for the XTS cipher mode in EKMF Web using the label
|
||||
tags 'ENV=TEST' and 'APP=LINUX' and stores it in the secure key repository
|
||||
using the name 'seckey' and associates it with block device '/dev/dasdc1' and
|
||||
device-mapper name 'encvol', and a volume type of luks2.
|
||||
.TP
|
||||
.B zkey remove \-\-name seckey \-\-state DEACTIVATED
|
||||
Removes secure key 'seckey' from the repository and sets the state of the key
|
||||
to 'DEACTIVATED' in EKMF Web.
|
||||
.TP
|
||||
.B zkey kms list
|
||||
Displays eligible secure keys managed by EKMF Web which this zkey client is
|
||||
allowed to use and are in state 'ACTIVE'
|
||||
.TP
|
||||
.B zkey kms list \-\-states ACTIVE,DEACTIVATED
|
||||
Displays eligible secure keys managed by EKMF Web which this zkey client is
|
||||
allowed to use and are in state 'ACTIVE' or 'DEACTIVATED'
|
||||
.TP
|
||||
.B zkey kms list \-\-all
|
||||
Displays eligible secure keys managed by EKMF Web, regardless if this zkey
|
||||
client is allowed to use it or not.
|
||||
.TP
|
||||
.B zkey kms list \-\-label \(dq*LUKS2*\(dq
|
||||
Displays eligible secure keys managed by EKMF Web where the label name in EKMF
|
||||
Web contains the work 'LUKS2'.
|
||||
.TP
|
||||
.B zkey kms import \-\-name seckey
|
||||
Imports the secure key managed by EKMF Web with a zkey name of 'seckey'.
|
||||
.TP
|
||||
.B zkey kms import \-\-volume\-type LUKS2
|
||||
Imports secure keys managed by EKMF Web that are associated with volumes of
|
||||
volume type LUKS2.
|
||||
.TP
|
||||
.B zkey kms refresh \-\-name \(dqsec*\(dq
|
||||
Refreshes secure keys from EKMF Web where the name starts with 'sec'.
|
||||
.TP
|
||||
.B zkey kms refresh \-\-name seckey \-\-refresh\-properties
|
||||
Refreshes the secure key with the name 'seckey' from EKMF Web and also refreshs
|
||||
the key properties.
|
||||
5745
zkey/ekmfweb/zkey-ekmfweb.c
Normal file
5745
zkey/ekmfweb/zkey-ekmfweb.c
Normal file
File diff suppressed because it is too large
Load Diff
108
zkey/ekmfweb/zkey-ekmfweb.h
Normal file
108
zkey/ekmfweb/zkey-ekmfweb.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* zkey-ekmfweb - EKMFWeb zkey KMS plugin
|
||||
*
|
||||
* Copyright IBM Corp. 2020
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef ZKEY_EKMFWEB_H
|
||||
#define ZKEY_EKMFWEB_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "ekmfweb/ekmfweb.h"
|
||||
|
||||
struct plugin_handle {
|
||||
const char *config_path;
|
||||
mode_t config_path_mode;
|
||||
gid_t config_path_owner;
|
||||
struct properties *properties;
|
||||
bool apqns_configured;
|
||||
bool connection_configured;
|
||||
bool settings_retrieved;
|
||||
bool templates_retrieved;
|
||||
bool identity_key_generated;
|
||||
bool registered;
|
||||
bool config_complete;
|
||||
struct ekmf_ext_lib ext_lib;
|
||||
struct ekmf_cca_lib cca;
|
||||
struct ekmf_config ekmf_config;
|
||||
CURL *curl_handle;
|
||||
char error_msg[1024];
|
||||
bool verbose;
|
||||
};
|
||||
|
||||
#define EKMFWEB_CONFIG_FILE "ekmfweb.conf"
|
||||
#define EKMFWEB_CONFIG_SERVER_CERT_FILE "server-cert.pem"
|
||||
#define EKMFWEB_CONFIG_SERVER_PUBKEY_FILE "server-pubkey.pem"
|
||||
#define EKMFWEB_CONFIG_LOGIN_TOKEN_FILE "login.token"
|
||||
#define EKMFWEB_CONFIG_EKMFWEB_PUBKEY_FILE "ekmfweb-pubkey.pem"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY_FILE "identity-key.skey"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY_REENC_FILE "identity-key.reenc"
|
||||
|
||||
#define EKMFWEB_CONFIG_APQNS "apqns"
|
||||
#define EKMFWEB_CONFIG_URL "url"
|
||||
#define EKMFWEB_CONFIG_CA_BUNDLE "ca-bundle"
|
||||
#define EKMFWEB_CONFIG_CLIENT_CERT "client-cert"
|
||||
#define EKMFWEB_CONFIG_CLIENT_KEY "client-key"
|
||||
#define EKMFWEB_CONFIG_CLIENT_KEY_PASSPHRASE "client-key-passphrase"
|
||||
#define EKMFWEB_CONFIG_SERVER_CERT "server-cert"
|
||||
#define EKMFWEB_CONFIG_SERVER_PUBKEY "server-pubkey"
|
||||
#define EKMFWEB_CONFIG_VERIFY_SERVER_CERT "verify-server-cert"
|
||||
#define EKMFWEB_CONFIG_VERIFY_HOSTNAME "verify-hostname"
|
||||
#define EKMFWEB_CONFIG_LOGIN_TOKEN "login-token"
|
||||
#define EKMFWEB_CONFIG_PASSCODE_URL "passcode-url"
|
||||
#define EKMFWEB_CONFIG_EKMFWEB_PUBKEY "ekmfweb-pubkey"
|
||||
#define EKMFWEB_CONFIG_TEMPLATE_XTS1 "template-xts1"
|
||||
#define EKMFWEB_CONFIG_TEMPLATE_XTS2 "template-xts2"
|
||||
#define EKMFWEB_CONFIG_TEMPLATE_NONXTS "template-nonxts"
|
||||
#define EKMFWEB_CONFIG_TEMPLATE_IDENTITY "template-identity"
|
||||
#define EKMFWEB_CONFIG_TEMPLATE_XTS1_LABEL "template-xts1-label"
|
||||
#define EKMFWEB_CONFIG_TEMPLATE_XTS2_LABEL "template-xts2-label"
|
||||
#define EKMFWEB_CONFIG_TEMPLATE_NONXTS_LABEL "template-nonxts-label"
|
||||
#define EKMFWEB_CONFIG_TEMPLATE_IDENTITY_LABEL "template-identity-label"
|
||||
#define EKMFWEB_CONFIG_TEMPLATE_XTS1_ID "template-xts1-id"
|
||||
#define EKMFWEB_CONFIG_TEMPLATE_XTS2_ID "template-xts2-id"
|
||||
#define EKMFWEB_CONFIG_TEMPLATE_NONXTS_ID "template-nonxts-id"
|
||||
#define EKMFWEB_CONFIG_TEMPLATE_IDENTITY_ID "template-identity-id"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY "identity-key"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY_ALGORITHM "identity-key-algorithm"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY_PARAMS "identity-key-params"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY_REENC "identity-key-reenc"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY_LABEL "identity-key-label"
|
||||
#define EKMFWEB_CONFIG_IDENTITY_KEY_ID "identity-key-id"
|
||||
#define EKMFWEB_CONFIG_SESSION_KEY_CURVE "session-key-curve"
|
||||
#ifdef EKMFWEB_SUPPORTS_RSA_DIGESTS_AND_PSS_SIGNATURES
|
||||
#define EKMFWEB_CONFIG_SESSION_RSA_SIGN_DIGEST "session-rsa-sign-digest"
|
||||
#define EKMFWEB_CONFIG_SESSION_RSA_SIGN_PSS "session-rsa-sign-pss"
|
||||
#endif
|
||||
|
||||
#define EKMFWEB_PASSCODE_URL "/administration/passcode"
|
||||
#define EKMFWEB_TEMPLATE_STATE_ACTIVE "ACTIVE"
|
||||
#define EKMFWEB_TEMPLATE_STATE_HISTORY "HISTORY"
|
||||
#define EKMFWEB_KEYSTORE_TYPE_PERV_ENCR "PERVASIVE_ENCRYPTION"
|
||||
#define EKMFWEB_KEYSTORE_TYPE_IDENTITY "IDENTITY"
|
||||
#define EKMFWEB_KEY_ALGORITHM_AES "AES"
|
||||
#define EKMFWEB_KEY_ALGORITHM_ECC "ECC"
|
||||
#define EKMFWEB_KEY_ALGORITHM_RSA "RSA"
|
||||
#define EKMFWEB_KEY_TYPE_CIPHER "CIPHER"
|
||||
#define EKMFWEB_KEY_STATE_PRE_ACTIVATION "PRE-ACTIVATION"
|
||||
#define EKMFWEB_KEY_STATE_ACTIVE "ACTIVE"
|
||||
#define EKMFWEB_KEY_STATE_DEACTIVATED "DEACTIVATED"
|
||||
#define EKMFWEB_KEY_STATE_COMPROMISED "COMPROMISED"
|
||||
#define EKMFWEB_KEY_STATE_DESTROYED "DESTROYED"
|
||||
#define EKMFWEB_KEY_STATE_DESTROYED_COMPROMISED "DESTROYED-COMPROMISED"
|
||||
#define EKMFWEB_CURVE_PRIME "PRIME_CURVE"
|
||||
#define EKMFWEB_CURVE_BAINPOOL "BRAINPOOL_CURVE"
|
||||
#define EKMFWEB_SEQNO_TAG "seqno"
|
||||
|
||||
#define DEFAULT_IDENTITY_KEY_PUBLIC_EXPONENT 65537
|
||||
|
||||
#define CCA_LIBRARY_NAME "libcsulcca.so"
|
||||
#define CCA_WEB_PAGE "http://www.ibm.com/security/cryptocards"
|
||||
|
||||
#endif
|
||||
5
zkey/ekmfweb/zkey-ekmfweb.map
Normal file
5
zkey/ekmfweb/zkey-ekmfweb.map
Normal file
@@ -0,0 +1,5 @@
|
||||
ZKEY_EKMFWEB_1.0 {
|
||||
global:
|
||||
kms_get_functions;
|
||||
local: *;
|
||||
};
|
||||
30
zkey/ep11.c
30
zkey/ep11.c
@@ -182,8 +182,9 @@ int load_ep11_library(struct ep11_lib *ep11, bool verbose)
|
||||
*
|
||||
* @returns 0 on success, a negative errno in case of errors
|
||||
*/
|
||||
int get_ep11_target_for_apqn(struct ep11_lib *ep11, int card, int domain,
|
||||
target_t *target, bool verbose)
|
||||
int get_ep11_target_for_apqn(struct ep11_lib *ep11, unsigned int card,
|
||||
unsigned int domain, target_t *target,
|
||||
bool verbose)
|
||||
{
|
||||
ep11_target_t *target_list;
|
||||
struct XCP_Module module;
|
||||
@@ -248,12 +249,12 @@ struct find_mkvp_info {
|
||||
u8 mkvp[MKVP_LENGTH];
|
||||
unsigned int flags;
|
||||
bool found;
|
||||
int card;
|
||||
int domain;
|
||||
unsigned int card;
|
||||
unsigned int domain;
|
||||
bool verbose;
|
||||
};
|
||||
|
||||
static int find_mkvp(int card, int domain, void *handler_data)
|
||||
static int find_mkvp(unsigned int card, unsigned int domain, void *handler_data)
|
||||
{
|
||||
struct find_mkvp_info *info = (struct find_mkvp_info *)handler_data;
|
||||
struct mk_info mk_info;
|
||||
@@ -312,8 +313,8 @@ static int find_mkvp(int card, int domain, void *handler_data)
|
||||
*/
|
||||
int select_ep11_apqn_by_mkvp(struct ep11_lib *ep11, u8 *mkvp,
|
||||
const char *apqns, unsigned int flags,
|
||||
target_t *target, int *card, int *domain,
|
||||
bool verbose)
|
||||
target_t *target, unsigned int *card,
|
||||
unsigned int *domain, bool verbose)
|
||||
{
|
||||
struct find_mkvp_info info;
|
||||
int rc;
|
||||
@@ -323,7 +324,7 @@ int select_ep11_apqn_by_mkvp(struct ep11_lib *ep11, u8 *mkvp,
|
||||
|
||||
pr_verbose(verbose, "Select mkvp %s in APQNs %s for the EP11 host "
|
||||
"library", printable_mkvp(CARD_TYPE_EP11, mkvp),
|
||||
apqns == 0 ? "ANY" : apqns);
|
||||
apqns == NULL ? "ANY" : apqns);
|
||||
|
||||
memcpy(info.mkvp, mkvp, sizeof(info.mkvp));
|
||||
info.flags = flags;
|
||||
@@ -369,8 +370,9 @@ int select_ep11_apqn_by_mkvp(struct ep11_lib *ep11, u8 *mkvp,
|
||||
*
|
||||
* @returns 0 on success, a negative errno in case of errors
|
||||
*/
|
||||
static int ep11_adm_reencrypt(struct ep11_lib *ep11, target_t target, int card,
|
||||
int domain, struct ep11keytoken *ep11key,
|
||||
static int ep11_adm_reencrypt(struct ep11_lib *ep11, target_t target,
|
||||
unsigned int card, unsigned int domain,
|
||||
struct ep11keytoken *ep11key,
|
||||
unsigned int ep11key_size, bool verbose)
|
||||
{
|
||||
CK_BYTE resp[MAX_BLOBSIZE];
|
||||
@@ -406,8 +408,8 @@ static int ep11_adm_reencrypt(struct ep11_lib *ep11, target_t target, int card,
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rv = ep11->dll_m_admin(resp, &resp_len, NULL, 0, req, req_len, NULL, 0,
|
||||
target);
|
||||
rv = ep11->dll_m_admin(resp, &resp_len, NULL, NULL, req, req_len, NULL,
|
||||
0, target);
|
||||
if (rv != CKR_OK || resp_len == 0) {
|
||||
pr_verbose(verbose, "Command XCP_ADM_REENCRYPT failed. "
|
||||
"rc = 0x%lx, resp_len = %ld", rv, resp_len);
|
||||
@@ -461,8 +463,8 @@ static int ep11_adm_reencrypt(struct ep11_lib *ep11, target_t target, int card,
|
||||
*
|
||||
* @returns 0 on success, a negative errno in case of errors
|
||||
*/
|
||||
int reencipher_ep11_key(struct ep11_lib *ep11, target_t target, int card,
|
||||
int domain, u8 *secure_key,
|
||||
int reencipher_ep11_key(struct ep11_lib *ep11, target_t target,
|
||||
unsigned int card, unsigned int domain, u8 *secure_key,
|
||||
unsigned int secure_key_size, bool verbose)
|
||||
{
|
||||
struct ep11keytoken *ep11key = (struct ep11keytoken *)secure_key;
|
||||
|
||||
13
zkey/ep11.h
13
zkey/ep11.h
@@ -158,8 +158,9 @@ struct ep11_lib {
|
||||
|
||||
int load_ep11_library(struct ep11_lib *ep11, bool verbose);
|
||||
|
||||
int get_ep11_target_for_apqn(struct ep11_lib *ep11, int card, int domain,
|
||||
target_t *target, bool verbose);
|
||||
int get_ep11_target_for_apqn(struct ep11_lib *ep11, unsigned int card,
|
||||
unsigned int domain, target_t *target,
|
||||
bool verbose);
|
||||
|
||||
void free_ep11_target_for_apqn(struct ep11_lib *ep11, target_t target);
|
||||
|
||||
@@ -168,11 +169,11 @@ void free_ep11_target_for_apqn(struct ep11_lib *ep11, target_t target);
|
||||
|
||||
int select_ep11_apqn_by_mkvp(struct ep11_lib *ep11, u8 *mkvp,
|
||||
const char *apqns, unsigned int flags,
|
||||
target_t *target, int *card, int *domain,
|
||||
bool verbose);
|
||||
target_t *target, unsigned int *card,
|
||||
unsigned int *domain, bool verbose);
|
||||
|
||||
int reencipher_ep11_key(struct ep11_lib *ep11, target_t target, int card,
|
||||
int domain, u8 *secure_key,
|
||||
int reencipher_ep11_key(struct ep11_lib *ep11, target_t target,
|
||||
unsigned int card, unsigned int domain, u8 *secure_key,
|
||||
unsigned int secure_key_size, bool verbose);
|
||||
|
||||
#endif
|
||||
|
||||
1428
zkey/keystore.c
1428
zkey/keystore.c
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Keystore handling functions
|
||||
*
|
||||
* Copyright IBM Corp. 2018
|
||||
* Copyright IBM Corp. 2018, 2020
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "pkey.h"
|
||||
#include "kms.h"
|
||||
|
||||
struct keystore {
|
||||
bool verbose;
|
||||
@@ -22,9 +23,31 @@ struct keystore {
|
||||
int lock_fd;
|
||||
mode_t mode;
|
||||
gid_t owner;
|
||||
struct kms_info *kms_info;
|
||||
};
|
||||
|
||||
struct keystore *keystore_new(const char *directory, bool verbose);
|
||||
#define PROP_NAME_KEY_TYPE "key-type"
|
||||
#define PROP_NAME_CIPHER "cipher"
|
||||
#define PROP_NAME_IV_MODE "iv-mode"
|
||||
#define PROP_NAME_DESCRIPTION "description"
|
||||
#define PROP_NAME_VOLUMES "volumes"
|
||||
#define PROP_NAME_APQNS "apqns"
|
||||
#define PROP_NAME_SECTOR_SIZE "sector-size"
|
||||
#define PROP_NAME_CREATION_TIME "creation-time"
|
||||
#define PROP_NAME_CHANGE_TIME "update-time"
|
||||
#define PROP_NAME_REENC_TIME "reencipher-time"
|
||||
#define PROP_NAME_KEY_VP "verification-pattern"
|
||||
#define PROP_NAME_VOLUME_TYPE "volume-type"
|
||||
#define PROP_NAME_KMS "kms"
|
||||
#define PROP_NAME_KMS_KEY_ID "kms-key-id"
|
||||
#define PROP_NAME_KMS_KEY_LABEL "kms-key-label"
|
||||
#define PROP_NAME_KMS_XTS_KEY1_ID "kms-xts-key1-id"
|
||||
#define PROP_NAME_KMS_XTS_KEY1_LABEL "kms-xts-key1-label"
|
||||
#define PROP_NAME_KMS_XTS_KEY2_ID "kms-xts-key2-id"
|
||||
#define PROP_NAME_KMS_XTS_KEY2_LABEL "kms-xts-key2-label"
|
||||
|
||||
struct keystore *keystore_new(const char *directory,
|
||||
struct kms_info *kms_info, bool verbose);
|
||||
|
||||
int keystore_generate_key(struct keystore *keystore, const char *name,
|
||||
const char *description, const char *volumes,
|
||||
@@ -33,6 +56,13 @@ int keystore_generate_key(struct keystore *keystore, const char *name,
|
||||
const char *clear_key_file, const char *volume_type,
|
||||
const char *key_type, int pkey_fd);
|
||||
|
||||
int keystore_generate_key_kms(struct keystore *keystore, const char *name,
|
||||
const char *description, const char *volumes,
|
||||
size_t sector_size, size_t keybits, bool xts,
|
||||
const char *volume_type, const char *key_type,
|
||||
struct kms_option *kms_options,
|
||||
size_t num_kms_options);
|
||||
|
||||
int keystore_import_key(struct keystore *keystore, const char *name,
|
||||
const char *description, const char *volumes,
|
||||
const char *apqns, bool noapqncheck, size_t sector_size,
|
||||
@@ -58,17 +88,19 @@ int keystore_reencipher_key(struct keystore *keystore, const char *name_filter,
|
||||
struct ext_lib *lib);
|
||||
|
||||
int keystore_copy_key(struct keystore *keystore, const char *name,
|
||||
const char *newname, const char *volumes);
|
||||
const char *newname, const char *volumes, bool local);
|
||||
|
||||
int keystore_export_key(struct keystore *keystore, const char *name,
|
||||
const char *export_file);
|
||||
|
||||
int keystore_remove_key(struct keystore *keystore, const char *name,
|
||||
bool quiet);
|
||||
bool quiet, struct kms_option *kms_options,
|
||||
size_t num_kms_options);
|
||||
|
||||
int keystore_list_keys(struct keystore *keystore, const char *name_filter,
|
||||
const char *volume_filter, const char *apqn_filter,
|
||||
const char *volume_type, const char *key_type);
|
||||
const char *volume_type, const char *key_type,
|
||||
bool local, bool kms_bound);
|
||||
|
||||
int keystore_cryptsetup(struct keystore *keystore, const char *volume_filter,
|
||||
bool execute, const char *volume_type,
|
||||
@@ -84,6 +116,31 @@ int keystore_convert_key(struct keystore *keystore, const char *name,
|
||||
const char *key_type, bool noapqncheck, bool quiet,
|
||||
int pkey_fd, struct ext_lib *lib);
|
||||
|
||||
int keystore_kms_keys_set_property(struct keystore *keystore,
|
||||
const char *key_type,
|
||||
const char *prop_name,
|
||||
const char *prop_value);
|
||||
|
||||
int keystore_kms_keys_unbind(struct keystore *keystore);
|
||||
|
||||
int keystore_msg_for_kms_key(struct keystore *keystore, const char *key_type,
|
||||
const char *msg);
|
||||
|
||||
int keystore_import_kms_keys(struct keystore *keystore,
|
||||
const char *label_filter,
|
||||
const char *name_filter,
|
||||
const char *volume_filter,
|
||||
const char *volume_type,
|
||||
struct kms_option *kms_options,
|
||||
size_t num_kms_options,
|
||||
bool batch_mode, bool novolcheck);
|
||||
|
||||
int keystore_refresh_kms_keys(struct keystore *keystore,
|
||||
const char *name_filter,
|
||||
const char *volume_filter,
|
||||
const char *volume_type, const char *key_type,
|
||||
bool refres_properties, bool novolcheck);
|
||||
|
||||
void keystore_free(struct keystore *keystore);
|
||||
|
||||
|
||||
|
||||
539
zkey/kms-plugin.h
Normal file
539
zkey/kms-plugin.h
Normal file
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
* zkey - Generate, re-encipher, and validate secure keys
|
||||
*
|
||||
* This header file defines the interface to a Key Management System (KMS)
|
||||
* Plugin.
|
||||
*
|
||||
* Copyright IBM Corp. 2020
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef KMS_PLUGIN_H
|
||||
#define KMS_PLUGIN_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "lib/util_opt.h"
|
||||
|
||||
/**
|
||||
* Informs a KMS plugin that it is bound to a zkey repository.
|
||||
*
|
||||
* Note: This function is called before kms_initialize()!
|
||||
*
|
||||
* @param config_path name of a directory where the KMS plugin can store
|
||||
* its configuration and other files it needs to store
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
*/
|
||||
int kms_bind(const char *config_path);
|
||||
|
||||
typedef void *kms_handle_t;
|
||||
|
||||
/**
|
||||
* Initializes a KMS plugin for usage by zkey. When a repository is bound to a
|
||||
* KMS plugin, zkey calls this function when opening the repository.
|
||||
*
|
||||
* @param config_path name of a directory where the KMS plugin can store
|
||||
* its configuration and other files it needs to store
|
||||
* @param verbose if true, the plugin should write verbose or debug
|
||||
* messages to stderr during further processing.
|
||||
*
|
||||
* @returns a KMS plugin handle, or NULL in case of an error.
|
||||
*/
|
||||
kms_handle_t kms_initialize(const char *config_path, bool verbose);
|
||||
|
||||
/**
|
||||
* Terminates the use of a KMS plugin. When a repository is bound to a KMS
|
||||
* plugin, zkey calls this function when closing the repository.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
*/
|
||||
int kms_terminate(const kms_handle_t handle);
|
||||
|
||||
/**
|
||||
* Returns a textual message about the last occurred error that occurred in the
|
||||
* last called KMS plugin function. If no error occurred (i.e. the last plugin
|
||||
* function returned rc = 0), then NULL is returned.
|
||||
* The returned string is static or contained within the handle. It is valid
|
||||
* only until the next KMS plugin function is called.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
*
|
||||
* @returns an error message of NULL
|
||||
*/
|
||||
const char *kms_get_last_error(const kms_handle_t handle);
|
||||
|
||||
/**
|
||||
* Returns true if the KMS plugin supports the specified key type.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
* @param key_type the zkey key type, euch as 'CCA-AESDATA',
|
||||
* 'CCA-AESCIPHER', 'EP11-AES'.
|
||||
*
|
||||
* @returns true if the KMS plugin supports the key type, false otherwise.
|
||||
*/
|
||||
bool kms_supports_key_type(const kms_handle_t handle, const char *key_type);
|
||||
|
||||
/**
|
||||
* Displays information about the KMS Plugin and its current configuration on
|
||||
* stdout.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
*/
|
||||
int kms_display_info(const kms_handle_t handle);
|
||||
|
||||
#define KMS_COMMAND_CONFIGURE "configure"
|
||||
#define KMS_COMMAND_REENCIPHER "reencipher"
|
||||
#define KMS_COMMAND_GENERATE "generate"
|
||||
#define KMS_COMMAND_REMOVE "remove"
|
||||
#define KMS_COMMAND_LIST "list"
|
||||
#define KMS_COMMAND_LIST_IMPORT "list-import"
|
||||
|
||||
/**
|
||||
* Returns a list of KMS specific command line options that zkey should accept
|
||||
* and pass to the appropriate KMS plugin function. The option list must be
|
||||
* terminated by an UTIL_OPT_END entry (see util_opt.h). The options returned
|
||||
* must not interfere with the already defined options of the zkey command.
|
||||
* Field 'command' of the returned options should either be NULL or specify
|
||||
* the command that it is for.
|
||||
*
|
||||
* If max_opts is not -1, then only up to max_opts options are allowed. If more
|
||||
* options are returned, only up to max_opts options are used by zkey.
|
||||
*
|
||||
* @param command the command for which the KMS-specific options are
|
||||
* to be returned, see KMS_COMMAND_xxx defines
|
||||
* @param max_opts maximum number of options allowed. If -1 then there
|
||||
* is no limit.
|
||||
*
|
||||
* @returns a list of options terminated by an UTIL_OPT_END entry, or NULL in
|
||||
* case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
*/
|
||||
const struct util_opt *kms_get_command_options(const char *command,
|
||||
int max_opts);
|
||||
|
||||
struct kms_apqn {
|
||||
unsigned short card;
|
||||
unsigned short domain;
|
||||
};
|
||||
|
||||
struct kms_option {
|
||||
int option; /** option character as in struct option */
|
||||
const char *argument; /** argument of the option (if any) */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Configures (or re-configures) a KMS plugin. This function can be called
|
||||
* several times to configure a KMS plugin is several steps (if supported by the
|
||||
* KMS plugin). In case a configuration is not fully complete, this function
|
||||
* may return -EAGAIN to indicate that it has accepted the configuration so far,
|
||||
* but the configuration needs to be completed.
|
||||
*
|
||||
* No kms_login is performed before calling this function. If the KMS plugin
|
||||
* requires a login for the configuration, it must perform it itself within this
|
||||
* function.
|
||||
*
|
||||
* A KMS plugin must be associated with at least one APQN. Thus, in a multi-step
|
||||
* configuration, a list f APQNs must be specified at least once.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
* @param apqns a list of APQNs to associate with the KMS plugin, or
|
||||
* NULL if no APQNs are specified.
|
||||
* @param num_apqns number of APQNs in above array. 0 if no APQNs are
|
||||
* specified.
|
||||
* @param options a list of options as specified by the user. These
|
||||
* options are a subset of the possible options as
|
||||
* returned by kms_get_command_options() with command
|
||||
* KMS_COMMAND_CONFIGURE.
|
||||
* @param num_options number of options in above array.
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
* -EAGAIN to indicate that the specified configuration was accepted so far, but
|
||||
* the configuration is still incomplete, and needs to be completed.
|
||||
*/
|
||||
int kms_configure(const kms_handle_t handle,
|
||||
const struct kms_apqn *apqns, size_t num_apqns,
|
||||
const struct kms_option *options, size_t num_options);
|
||||
|
||||
/**
|
||||
* De-configures a KMS plugin. This is called by zkey when a repository is
|
||||
* unbound from a KMS plugin. It gives the KMS plugin the chance to gracefully
|
||||
* remove any files that the plugin has stored in its config directory. zkey
|
||||
* will unconditionally remove all left over files when this function returns.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
*/
|
||||
int kms_deconfigure(const kms_handle_t handle);
|
||||
|
||||
/**
|
||||
* Allows the KMS plugin to perform a login to the KMS (if required). This
|
||||
* function is called at least once before any key operation function, typically
|
||||
* shortly after opening the repository.
|
||||
* The KMS plugin may prompt the user (by reading from stdin) for its
|
||||
* credentials, if needed.
|
||||
*
|
||||
* It is suggested that a KMS plugin performs a login with the KMS once, and
|
||||
* stores a login token (or similar) in its config directory. The next time
|
||||
* the kms_login function is called, the login token can be reused (if still
|
||||
* valid). This avoids to prompt the user for every key operation.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
*/
|
||||
int kms_login(const kms_handle_t handle);
|
||||
|
||||
enum kms_reencipher_mode {
|
||||
KMS_REENC_MODE_AUTO = 0,
|
||||
KMS_REENC_MODE_IN_PLACE = 1,
|
||||
KMS_REENC_MODE_STAGED = 2,
|
||||
KMS_REENC_MODE_STAGED_COMPLETE = 3,
|
||||
};
|
||||
|
||||
enum kms_reenc_mkreg {
|
||||
KMS_REENC_MKREG_AUTO = 0,
|
||||
KMS_REENC_MKREG_FROM_OLD = 1,
|
||||
KMS_REENC_MKREG_TO_NEW = 2,
|
||||
KMS_REENC_MKREG_FROM_OLD_TO_NEW = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when the master keys of an APQN associated with the KMS plugin has
|
||||
* been changed. The KMS plugin can then re-encipher all its secure keys (if
|
||||
* any) that it has stored in its config directory.
|
||||
*
|
||||
* Keys that have been generated by the KMS plugin and stored in the zkey
|
||||
* repository do not need to be re-enciphered by the KMS plugin. Those are
|
||||
* re-enciphered by zkey without the help of the KMS plugin.
|
||||
*
|
||||
* HSM have different master key registers. Typically a CURRENT and a NEW master
|
||||
* key register exists. The NEW register may be loaded with the new to be set
|
||||
* master key, and secure keys can be re-enciphered with it proactively.
|
||||
*
|
||||
* CCA also supports an OLD master key register, that contains the previously
|
||||
* used master key. You thus can re-encipher a secure key that is currently
|
||||
* enciphered with the master key from the OLD register with the master key
|
||||
* from the CURRENT register.
|
||||
*
|
||||
* HSMs may also support different master keys for different key types or
|
||||
* algorithms. It is up to the KMS plugin to know which master key registers
|
||||
* are used for its secure keys
|
||||
*
|
||||
* A staged re-encipherment is performed by re-enciphering a secure key with
|
||||
* the new HSM master key, without making it available for use in the first
|
||||
* stage. Only when the staged re-encipherment is completed, then the previously
|
||||
* re-enciphered secure key is make available for use and the old on is removed.
|
||||
*
|
||||
* An in-place re-encipherment replaces the secure key right away with its
|
||||
* re-enciphered version.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
* @param mode Re-encipherment mode
|
||||
* @param mkreg Re-encipherment register selection
|
||||
* @param options a list of options as specified by the user. These
|
||||
* options are a subset of the possible options as
|
||||
* returned by kms_get_command_options() with command
|
||||
* KMS_COMMAND_REENCIPHER.
|
||||
* @param num_options number of options in above array.
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
*/
|
||||
int kms_reenciper(const kms_handle_t handle,
|
||||
enum kms_reencipher_mode mode, enum kms_reenc_mkreg mkreg,
|
||||
const struct kms_option *options, size_t num_options);
|
||||
|
||||
struct kms_property {
|
||||
const char *name;
|
||||
const char *value;
|
||||
};
|
||||
|
||||
#define KMS_KEY_ID_SIZE 256
|
||||
#define KMS_KEY_LABEL_SIZE 256
|
||||
|
||||
enum kms_key_mode {
|
||||
KMS_KEY_MODE_NON_XTS = 0,
|
||||
KMS_KEY_MODE_XTS_1 = 1,
|
||||
KMS_KEY_MODE_XTS_2 = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates a key in or with the KMS and returns a secure key that is
|
||||
* enciphered under the current HSM master key.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
* @param key_type the zkey key type, euch as 'CCA-AESDATA',
|
||||
* 'CCA-AESCIPHER', 'EP11-AES'.
|
||||
* @param key_bits the key bit size (e.g. 256 for an AES 256 bit key).
|
||||
* 0 to use the plugin's default key size.
|
||||
* @param key_mode mode of the key, e.g. non-XTS key, or first/second
|
||||
* XTS key to be generated. A KMS plugin may need to
|
||||
* use different key templates for the different key
|
||||
* modes (i.e. key parts).
|
||||
* @param properties a list of properties to associate the key with
|
||||
* @param num_properties the number of properties in above array
|
||||
* @param options a list of options as specified by the user. These
|
||||
* options are a subset of the possible options as
|
||||
* returned by kms_get_command_options() with command
|
||||
* KMS_COMMAND_GENERATE.
|
||||
* @param num_options number of options in above array.
|
||||
* @param key_blob a buffer to return the key blob. The size of the
|
||||
* buffer is specified in key_blob_length
|
||||
* @param key_blob_length on entry: the size of the key_blob buffer.
|
||||
* on exit: the size of the key blob returned.
|
||||
* @param key_id a buffer to return the key-ID of the generated key.
|
||||
* The key-id is a textual identifier uniquely
|
||||
* identifying a key in the KMS and the KMS plugin.
|
||||
* The returned key-id contains the terminating zero.
|
||||
* @paran key_id_size size of the key_id buffer. It should be at least
|
||||
* KMS_KEY_ID_SIZE + 1 bytes large.
|
||||
* @param key_label a buffer to return the key-label of the generated
|
||||
* key. The key-label is a textual identifier used to
|
||||
* identify a key in the user interface of the KMS.
|
||||
* A key label may be equal to the key-ID, or it may
|
||||
* different. The returned key-label contains the
|
||||
* terminating zero.
|
||||
* @paran key_label_size size of the key_lanble buffer. It should be at least
|
||||
* KMS_KEY_LABEL_SIZE + 1 bytes large.
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
*/
|
||||
int kms_generate_key(const kms_handle_t handle, const char *key_type,
|
||||
size_t key_bits, enum kms_key_mode key_mode,
|
||||
const struct kms_property *properties,
|
||||
size_t num_properties, const struct kms_option *options,
|
||||
size_t num_options, unsigned char *key_blob,
|
||||
size_t *key_blob_length, char *key_id,
|
||||
size_t key_id_size, char *key_label,
|
||||
size_t key_label_size);
|
||||
|
||||
/**
|
||||
* Sets (adds/replaces/removes) properties of a key. Already existing properties
|
||||
* with the same property name are replaced, non-existing properties are added.
|
||||
* To remove a property, set the property value to NULL.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
* @param key_id the key-ID to set the properties for
|
||||
* @param properties a list of properties to set
|
||||
* @param num_properties the number of properties in above array
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
*/
|
||||
int kms_set_key_properties(const kms_handle_t handle, const char *key_id,
|
||||
const struct kms_property *properties,
|
||||
size_t num_properties);
|
||||
|
||||
/**
|
||||
* Gets properties of a key.
|
||||
*
|
||||
* The returned list of properties must be freed by the caller. Each property
|
||||
* name and value must be freed individually (using free()), as well as the
|
||||
* complete array.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
* @param key_id the key-ID to set the properties for
|
||||
* @param properties On return: a list of properties
|
||||
* @param num_properties On return: the number of properties in above array
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
*/
|
||||
int kms_get_key_properties(const kms_handle_t handle, const char *key_id,
|
||||
struct kms_property **properties,
|
||||
size_t *num_properties);
|
||||
|
||||
/**
|
||||
* Called when zkey removes a KMS-bound key from the zkey repository. The KMS
|
||||
* plugin can then set the state of the key in the KMS, or remove it also from
|
||||
* the KMS (this is usually not done).
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
* @param key_id the key-ID to set the properties for
|
||||
* @param options a list of options as specified by the user. These
|
||||
* options are a subset of the possible options as
|
||||
* returned by kms_get_command_options() with command
|
||||
* KMS_COMMAND_REMOVE.
|
||||
* @param num_options number of options in above array.
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
*/
|
||||
int kms_remove_key(const kms_handle_t handle, const char *key_id,
|
||||
const struct kms_option *options, size_t num_options);
|
||||
|
||||
/**
|
||||
* Callback used with the kms_list_keys() function. Called for each key.
|
||||
*
|
||||
* @param key_id the key-ID of the key
|
||||
* @param label the label of the key.
|
||||
* @param key_type the type of the key (CCA-AESDATA, etc)
|
||||
* @param key_bits the key size in bits
|
||||
* @param properties a list of properties of the key
|
||||
* @param num_properties the number of properties in above array
|
||||
* @param addl_info_argz an argz string containing additional KMS plugin
|
||||
* specific infos to be displayed, or NULL if none.
|
||||
* @param addl_info_len length of the argz string in addl_info_argz
|
||||
* @param private_data the private data pointer
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
*/
|
||||
typedef int (*kms_list_callback)(const char *key_id, const char *label,
|
||||
const char *key_type, size_t key_bits,
|
||||
const struct kms_property *properties,
|
||||
size_t num_properties,
|
||||
const char *addl_info_argz,
|
||||
size_t addl_info_len, void *private_data);
|
||||
|
||||
/**
|
||||
* List keys managed by the KMS. This list is independent of the zkey key
|
||||
* repository. It lists keys as known by the KMS.
|
||||
*
|
||||
* Note: The list function is used to display a list of keys managed by the KMS,
|
||||
* but also for producing a list of keys to import. Because the two use cases
|
||||
* might require different plugin specific options, kms_get_command_options()
|
||||
* allows two commands to get options for:
|
||||
* - KMS_COMMAND_LIST: Options for displaying a list.
|
||||
* - KMS_COMMAND_LIST_IMPORT: Options for building a list to import keys.
|
||||
* Functionkms_list_keys() is called for both cases with the appropriate
|
||||
* options as returned by kms_get_command_options() for the case.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
* @param label_pattern a pattern of the label used to filter the keys, or
|
||||
* NULL if no label pattern is specified.
|
||||
* @param properties a list of properties used to to filter the keys, or
|
||||
* NULL if no properties filter is specified.
|
||||
* @param num_properties the number of properties in above array.
|
||||
* @param options a list of options as specified by the user. These
|
||||
* options are a subset of the possible options as
|
||||
* returned by kms_get_command_options() with command
|
||||
* KMS_COMMAND_LIST or KMS_COMMAND_LIST_IMPORT.
|
||||
* @param num_options number of options in above array.*
|
||||
* @param callback a callback function that is called for each key that
|
||||
* matches the filter (if any).
|
||||
* @private_data a private pointer passed as is to the callback
|
||||
* function. Can be used to pass user specific
|
||||
* information to the callback.
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
*/
|
||||
int kms_list_keys(const kms_handle_t handle, const char *label_pattern,
|
||||
const struct kms_property *properties, size_t num_properties,
|
||||
const struct kms_option *options, size_t num_options,
|
||||
kms_list_callback callback, void *private_data);
|
||||
|
||||
/**
|
||||
* Imports a key from the KMS and returns a secure key that is
|
||||
* enciphered under the current HSM master key.
|
||||
*
|
||||
* @param handle the KMS plugin handle obtained from kms_initialize()
|
||||
* @param key_id the key-ID of the key to import
|
||||
* @param key_blob a buffer to return the key blob. The size of the
|
||||
* buffer is specified in key_blob_length
|
||||
* @param key_blob_length on entry: the size of the key_blob buffer.
|
||||
* on exit: the size of the key blob returned.
|
||||
*
|
||||
* @returns 0 on success, or a negative errno in case of an error.
|
||||
* Function kms_get_last_error() can be used to obtain more details about the
|
||||
* error.
|
||||
*/
|
||||
int kms_import_key(const kms_handle_t handle, const char *key_id,
|
||||
unsigned char *key_blob, size_t *key_blob_length);
|
||||
|
||||
#define KMS_API_VERSION_1 1
|
||||
|
||||
struct kms_functions {
|
||||
unsigned int api_version;
|
||||
int (*kms_bind)(const char *config_path);
|
||||
kms_handle_t (*kms_initialize)(const char *config_path, bool verbose);
|
||||
int (*kms_terminate)(const kms_handle_t handle);
|
||||
const char *(*kms_get_last_error)(const kms_handle_t handle);
|
||||
bool (*kms_supports_key_type)(const kms_handle_t handle,
|
||||
const char *key_type);
|
||||
int (*kms_display_info)(const kms_handle_t handle);
|
||||
const struct util_opt *(*kms_get_command_options)(
|
||||
const char *command, int max_opts);
|
||||
int (*kms_configure)(const kms_handle_t handle,
|
||||
const struct kms_apqn *apqns, size_t num_apqns,
|
||||
const struct kms_option *options,
|
||||
size_t num_options);
|
||||
int (*kms_deconfigure)(const kms_handle_t handle);
|
||||
int (*kms_login)(const kms_handle_t handle);
|
||||
int (*kms_reenciper)(const kms_handle_t handle,
|
||||
enum kms_reencipher_mode mode,
|
||||
enum kms_reenc_mkreg mkreg,
|
||||
const struct kms_option *options,
|
||||
size_t num_options);
|
||||
int (*kms_generate_key)(const kms_handle_t handle,
|
||||
const char *key_type, size_t key_bits,
|
||||
enum kms_key_mode key_mode,
|
||||
const struct kms_property *properties,
|
||||
size_t num_properties,
|
||||
const struct kms_option *options,
|
||||
size_t num_options,
|
||||
unsigned char *key_blob,
|
||||
size_t *key_blob_length, char *key_id,
|
||||
size_t key_id_size, char *key_label,
|
||||
size_t key_label_size);
|
||||
int (*kms_set_key_properties)(const kms_handle_t handle,
|
||||
const char *key_id,
|
||||
const struct kms_property *properties,
|
||||
size_t num_properties);
|
||||
int (*kms_get_key_properties)(const kms_handle_t handle,
|
||||
const char *key_id,
|
||||
struct kms_property **properties,
|
||||
size_t *num_properties);
|
||||
int (*kms_remove_key)(const kms_handle_t handle, const char *key_id,
|
||||
const struct kms_option *options,
|
||||
size_t num_options);
|
||||
int (*kms_list_keys)(const kms_handle_t handle,
|
||||
const char *label_pattern,
|
||||
const struct kms_property *properties,
|
||||
size_t num_properties,
|
||||
const struct kms_option *options,
|
||||
size_t num_options,
|
||||
kms_list_callback callback, void *private_data);
|
||||
int (*kms_import_key)(const kms_handle_t handle, const char *key_id,
|
||||
unsigned char *key_blob,
|
||||
size_t *key_blob_length);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an address of a structure containing the KMS plugin functions.
|
||||
* This function is exported by the KMS plugin, and its address is obtain
|
||||
* via dlsym() after loading the plugin via dlopen().
|
||||
* *
|
||||
* @returns the address of a structure or NULL in case of an error.
|
||||
*/
|
||||
const struct kms_functions *kms_get_functions(void);
|
||||
|
||||
#endif
|
||||
4
zkey/kms-plugins.conf
Normal file
4
zkey/kms-plugins.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
# List of zkey KMS plugins
|
||||
# Format:
|
||||
# <plugin-name>=<shared-library-file>
|
||||
EKMFWeb=zkey-ekmfweb.so
|
||||
3311
zkey/kms.c
Normal file
3311
zkey/kms.c
Normal file
File diff suppressed because it is too large
Load Diff
123
zkey/kms.h
Normal file
123
zkey/kms.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* zkey - Generate, re-encipher, and validate secure keys
|
||||
*
|
||||
* This header file defines functions for Key Management System (KMS) plugin
|
||||
* handling
|
||||
*
|
||||
* Copyright IBM Corp. 2020
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
*/
|
||||
|
||||
#ifndef KMS_H
|
||||
#define KMS_H
|
||||
|
||||
#include "kms-plugin.h"
|
||||
#include "properties.h"
|
||||
#include "keystore.h"
|
||||
|
||||
struct kms_info {
|
||||
void *plugin_lib;
|
||||
const struct kms_functions *funcs;
|
||||
char *plugin_name;
|
||||
struct properties *props;
|
||||
struct kms_apqn *apqns;
|
||||
size_t num_apqns;
|
||||
kms_handle_t handle;
|
||||
};
|
||||
|
||||
struct keystore;
|
||||
|
||||
int list_kms_plugins(bool verbose);
|
||||
|
||||
int check_for_kms_plugin(struct kms_info *kms_info, bool verbose);
|
||||
|
||||
int init_kms_plugin(struct kms_info *kms_info, bool verbose);
|
||||
|
||||
void free_kms_plugin(struct kms_info *kms_info);
|
||||
|
||||
void print_last_kms_error(const struct kms_info *kms_info);
|
||||
|
||||
int bind_kms_plugin(struct keystore *keystore, const char *plugin,
|
||||
bool verbose);
|
||||
|
||||
int unbind_kms_plugin(struct kms_info *kms_info, struct keystore *keystore,
|
||||
bool verbose);
|
||||
|
||||
int print_kms_info(struct kms_info *kms_info);
|
||||
|
||||
int get_kms_options(struct kms_info *kms_info, struct util_opt *opt_vec,
|
||||
const char *placeholder_cmd, const char *plugin_command,
|
||||
const char *opt_vec_command, int *first_plugin_opt,
|
||||
bool verbose);
|
||||
|
||||
int handle_kms_option(struct kms_info *kms_info, struct util_opt *opt_vec,
|
||||
int first_kms_option, const char *command, int option,
|
||||
const char *optarg, struct kms_option **kms_options,
|
||||
size_t *num_kms_options, bool verbose);
|
||||
|
||||
int configure_kms_plugin(struct keystore *keystore, const char *apqns,
|
||||
struct kms_option *kms_options, size_t num_kms_options,
|
||||
bool has_plugin_optins, bool verbose);
|
||||
|
||||
int reencipher_kms(struct kms_info *kms_info, bool from_old, bool to_new,
|
||||
bool inplace, bool staged, bool complete,
|
||||
struct kms_option *kms_options, size_t num_kms_options,
|
||||
bool verbose);
|
||||
|
||||
int perform_kms_login(struct kms_info *kms_info, bool verbose);
|
||||
|
||||
int get_kms_apqns_for_key_type(struct kms_info *kms_info, const char *key_type,
|
||||
bool cross_check, char **apqns, bool verbose);
|
||||
|
||||
int generate_kms_key(struct kms_info *kms_info, const char *name,
|
||||
const char *key_type, struct properties *key_props,
|
||||
bool xts, size_t keybits, const char *filename,
|
||||
struct kms_option *kms_options, size_t num_kms_options,
|
||||
bool verbose);
|
||||
|
||||
int set_kms_key_properties(struct kms_info *kms_info,
|
||||
struct properties *key_props,
|
||||
const char *name, const char *description,
|
||||
const char *volumes, const char *vol_type,
|
||||
const char *sector_size, bool verbose);
|
||||
|
||||
int remove_kms_key(struct kms_info *kms_info, struct properties *key_props,
|
||||
struct kms_option *kms_options, size_t num_kms_options,
|
||||
bool verbose);
|
||||
|
||||
typedef int (*kms_process_callback)(const char *key1_id, const char *key1_label,
|
||||
const char *key2_id, const char *key2_label,
|
||||
bool xts, const char *name,
|
||||
const char *key_type, size_t key_bits,
|
||||
const char *description, const char *cipher,
|
||||
const char *iv_mode, const char *volumes,
|
||||
const char *volume_type, size_t sector_size,
|
||||
const char *addl_info_argz,
|
||||
size_t addl_info_len,
|
||||
void *private_data);
|
||||
|
||||
int process_kms_keys(struct kms_info *kms_info,
|
||||
const char *label_filter, const char *name_filter,
|
||||
const char *volume_filter, const char *volume_type,
|
||||
struct kms_option *kms_options, size_t num_kms_options,
|
||||
kms_process_callback callback, void *private_data,
|
||||
bool verbose);
|
||||
|
||||
int list_kms_keys(struct kms_info *kms_info, const char *label_filter,
|
||||
const char *name_filter, const char *volume_filter,
|
||||
const char *volume_type, struct kms_option *kms_options,
|
||||
size_t num_kms_options, bool verbose);
|
||||
|
||||
int import_kms_key(struct kms_info *kms_info, const char *key1_id,
|
||||
const char *key2_id, bool xts, const char *name,
|
||||
unsigned char *key_blob, size_t *key_blob_length,
|
||||
bool verbose);
|
||||
|
||||
int refresh_kms_key(struct kms_info *kms_info, struct properties *key_props,
|
||||
char **description, char **cipher, char **iv_mode,
|
||||
char **volumes, char **volume_type, ssize_t *sector_size,
|
||||
const char *filename, bool verbose);
|
||||
|
||||
#endif
|
||||
15
zkey/misc.h
15
zkey/misc.h
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Local helper functions
|
||||
*
|
||||
* Copyright IBM Corp. 2017, 2018
|
||||
* Copyright IBM Corp. 2017, 2020
|
||||
*
|
||||
* s390-tools is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See LICENSE for details.
|
||||
@@ -25,10 +25,19 @@ static inline void misc_print_missing_command(void)
|
||||
util_prg_print_parse_error();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subcommand is missing
|
||||
*/
|
||||
static inline void misc_print_missing_sub_command(void)
|
||||
{
|
||||
warnx("Subcommand is required");
|
||||
util_prg_print_parse_error();
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalid command specified (for 'git' like tools)
|
||||
*/
|
||||
void misc_print_invalid_command(const char *command)
|
||||
static void misc_print_invalid_command(const char *command)
|
||||
{
|
||||
warnx("Invalid command '%s'", command);
|
||||
util_prg_print_parse_error();
|
||||
@@ -39,7 +48,7 @@ void misc_print_invalid_command(const char *command)
|
||||
*
|
||||
* @param[in] parm_name Parameter string
|
||||
*/
|
||||
void misc_print_required_parm(const char *parm_name)
|
||||
static void misc_print_required_parm(const char *parm_name)
|
||||
{
|
||||
warnx("Parameter '%s' is required", parm_name);
|
||||
util_prg_print_parse_error();
|
||||
|
||||
10
zkey/pkey.c
10
zkey/pkey.c
@@ -45,8 +45,6 @@
|
||||
|
||||
#define MAX_CIPHER_LEN 32
|
||||
|
||||
#define DEFAULT_KEYBITS 256
|
||||
|
||||
#define INITIAL_APQN_ENTRIES 16
|
||||
|
||||
/**
|
||||
@@ -1394,7 +1392,7 @@ int generate_key_verification_pattern(const u8 *key, size_t key_size,
|
||||
goto out;
|
||||
}
|
||||
|
||||
opfd = accept(tfmfd, NULL, 0);
|
||||
opfd = accept(tfmfd, NULL, NULL);
|
||||
if (opfd < 0) {
|
||||
rc = -errno;
|
||||
pr_verbose(verbose, "Failed to accept on the AF_ALG socket");
|
||||
@@ -1775,10 +1773,6 @@ int check_aes_cipher_key(const u8 *key, size_t key_size)
|
||||
"decryption\n");
|
||||
mismatch = true;
|
||||
}
|
||||
if (cipherkey->kuf1 & 0x2000) {
|
||||
printf("INFO: The secure key can be used for data translate\n");
|
||||
mismatch = true;
|
||||
}
|
||||
if (cipherkey->kuf1 & 0x1000) {
|
||||
printf("WARNING: The secure key can only be used in UDXs\n");
|
||||
mismatch = true;
|
||||
@@ -1929,8 +1923,8 @@ static int reencipher_ep11_secure_key(struct ep11_lib *ep11, u8 *secure_key,
|
||||
u8 *mkvp, bool *apqn_selected,
|
||||
bool verbose)
|
||||
{
|
||||
unsigned int card, domain;
|
||||
unsigned int flags;
|
||||
int card, domain;
|
||||
target_t target;
|
||||
int rc;
|
||||
|
||||
|
||||
13
zkey/pkey.h
13
zkey/pkey.h
@@ -115,10 +115,14 @@ struct ep11keytoken {
|
||||
#define AESCIPHER_KEY_SIZE sizeof(struct aescipherkeytoken)
|
||||
#define EP11_KEY_SIZE sizeof(struct ep11keytoken)
|
||||
|
||||
#define MAX_SECURE_KEY_SIZE MAX(EP11_KEY_SIZE, \
|
||||
MAX(AESDATA_KEY_SIZE, AESCIPHER_KEY_SIZE))
|
||||
#define MIN_SECURE_KEY_SIZE MIN(EP11_KEY_SIZE, \
|
||||
MIN(AESDATA_KEY_SIZE, AESCIPHER_KEY_SIZE))
|
||||
/* MAX/MIN from zt_common.h produces warnings for variable length arrays */
|
||||
#define _MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define _MAX(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
#define MAX_SECURE_KEY_SIZE _MAX(EP11_KEY_SIZE, \
|
||||
_MAX(AESDATA_KEY_SIZE, AESCIPHER_KEY_SIZE))
|
||||
#define MIN_SECURE_KEY_SIZE _MIN(EP11_KEY_SIZE, \
|
||||
_MIN(AESDATA_KEY_SIZE, AESCIPHER_KEY_SIZE))
|
||||
|
||||
struct pkey_seckey {
|
||||
u8 seckey[AESDATA_KEY_SIZE]; /* the secure key blob */
|
||||
@@ -263,6 +267,7 @@ struct pkey_apqns4keytype {
|
||||
#define KEY_TYPE_CCA_AESCIPHER "CCA-AESCIPHER"
|
||||
#define KEY_TYPE_EP11_AES "EP11-AES"
|
||||
|
||||
#define DEFAULT_KEYBITS 256
|
||||
#define PAES_BLOCK_SIZE 16
|
||||
#define ENC_ZERO_LEN (2 * PAES_BLOCK_SIZE)
|
||||
#define VERIFICATION_PATTERN_LEN (2 * ENC_ZERO_LEN + 1)
|
||||
|
||||
38
zkey/utils.c
38
zkey/utils.c
@@ -45,7 +45,7 @@
|
||||
* 0 if offline,
|
||||
* -1 if its not the specified type.
|
||||
*/
|
||||
int sysfs_is_card_online(int card, enum card_type cardtype)
|
||||
int sysfs_is_card_online(unsigned int card, enum card_type cardtype)
|
||||
{
|
||||
long int online;
|
||||
char *dev_path;
|
||||
@@ -106,7 +106,8 @@ out:
|
||||
* 0 if offline,
|
||||
* -1 if its not the specified type.
|
||||
*/
|
||||
int sysfs_is_apqn_online(int card, int domain, enum card_type cardtype)
|
||||
int sysfs_is_apqn_online(unsigned int card, unsigned int domain,
|
||||
enum card_type cardtype)
|
||||
{
|
||||
long int online;
|
||||
char *dev_path;
|
||||
@@ -144,7 +145,7 @@ out:
|
||||
*
|
||||
* @returns The card level, or -1 of the level can not be determined.
|
||||
*/
|
||||
int sysfs_get_card_level(int card)
|
||||
int sysfs_get_card_level(unsigned int card)
|
||||
{
|
||||
char *dev_path;
|
||||
char type[20];
|
||||
@@ -187,7 +188,7 @@ out:
|
||||
*
|
||||
* @returns The card type, or -1 of the type can not be determined.
|
||||
*/
|
||||
enum card_type sysfs_get_card_type(int card)
|
||||
enum card_type sysfs_get_card_type(unsigned int card)
|
||||
{
|
||||
char *dev_path;
|
||||
char type[20];
|
||||
@@ -235,7 +236,7 @@ out:
|
||||
* -ENOTSUP if the serialnr sysfs attribute is not available, because
|
||||
* the zcrypt kernel module is on an older level.
|
||||
*/
|
||||
int sysfs_get_serialnr(int card, char *serialnr, bool verbose)
|
||||
int sysfs_get_serialnr(unsigned int card, char *serialnr, bool verbose)
|
||||
{
|
||||
char *dev_path;
|
||||
int rc = 0;
|
||||
@@ -286,7 +287,7 @@ out:
|
||||
* the zcrypt kernel module is on an older level, or because the card
|
||||
* type does not provide this information.
|
||||
*/
|
||||
int sysfs_get_firmware_version(int card, struct fw_version *fw_version,
|
||||
int sysfs_get_firmware_version(unsigned int card, struct fw_version *fw_version,
|
||||
bool verbose)
|
||||
{
|
||||
char *dev_path;
|
||||
@@ -310,7 +311,7 @@ int sysfs_get_firmware_version(int card, struct fw_version *fw_version,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sscanf(buf, "%d.%d", &fw_version->major, &fw_version->minor) != 2) {
|
||||
if (sscanf(buf, "%u.%u", &fw_version->major, &fw_version->minor) != 2) {
|
||||
rc = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
@@ -321,7 +322,7 @@ int sysfs_get_firmware_version(int card, struct fw_version *fw_version,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sscanf(buf, "%d", &fw_version->api_ordinal) != 1) {
|
||||
if (sscanf(buf, "%u", &fw_version->api_ordinal) != 1) {
|
||||
rc = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
@@ -477,7 +478,8 @@ static int parse_ep11_mk_info(char *line, struct mk_info *mk_info)
|
||||
* -ENOTSUP if the mkvps sysfs attribute is not available, because the
|
||||
* zcrypt kernel module is on an older level.
|
||||
*/
|
||||
int sysfs_get_mkvps(int card, int domain, struct mk_info *mk_info, bool verbose)
|
||||
int sysfs_get_mkvps(unsigned int card, unsigned int domain,
|
||||
struct mk_info *mk_info, bool verbose)
|
||||
{
|
||||
enum card_type cardtype;
|
||||
char *dev_path;
|
||||
@@ -572,13 +574,14 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int scan_for_domains(int card, enum card_type cardtype,
|
||||
static int scan_for_domains(unsigned int card, enum card_type cardtype,
|
||||
apqn_handler_t handler, void *handler_data,
|
||||
bool verbose)
|
||||
{
|
||||
struct dirent **namelist;
|
||||
char fname[290];
|
||||
int i, n, domain, rc = 0;
|
||||
int i, n, rc = 0;
|
||||
unsigned int domain;
|
||||
|
||||
sprintf(fname, "/sys/devices/ap/card%02x/", card);
|
||||
n = util_scandir(&namelist, alphasort, fname,
|
||||
@@ -613,7 +616,8 @@ static int scan_for_apqns(enum card_type cardtype, apqn_handler_t handler,
|
||||
void *handler_data, bool verbose)
|
||||
{
|
||||
struct dirent **namelist;
|
||||
int i, n, card, rc = 0;
|
||||
int i, n, rc = 0;
|
||||
unsigned int card;
|
||||
|
||||
if (handler == NULL)
|
||||
return -EINVAL;
|
||||
@@ -663,7 +667,7 @@ static int scan_for_apqns(enum card_type cardtype, apqn_handler_t handler,
|
||||
int handle_apqns(const char *apqns, enum card_type cardtype,
|
||||
apqn_handler_t handler, void *handler_data, bool verbose)
|
||||
{
|
||||
int card, domain;
|
||||
unsigned int card, domain;
|
||||
char *copy, *tok;
|
||||
char *save;
|
||||
int rc = 0;
|
||||
@@ -702,7 +706,8 @@ struct print_apqn_info {
|
||||
bool verbose;
|
||||
};
|
||||
|
||||
static int print_apqn_mk_info(int card, int domain, void *handler_data)
|
||||
static int print_apqn_mk_info(unsigned int card, unsigned int domain,
|
||||
void *handler_data)
|
||||
{
|
||||
struct print_apqn_info *info = (struct print_apqn_info *)handler_data;
|
||||
struct mk_info mk_info;
|
||||
@@ -819,7 +824,8 @@ struct cross_check_info {
|
||||
bool verbose;
|
||||
};
|
||||
|
||||
static int cross_check_mk_info(int card, int domain, void *handler_data)
|
||||
static int cross_check_mk_info(unsigned int card, unsigned int domain,
|
||||
void *handler_data)
|
||||
{
|
||||
struct cross_check_info *info = (struct cross_check_info *)handler_data;
|
||||
struct fw_version fw_version;
|
||||
@@ -1050,7 +1056,7 @@ int cross_check_apqns(const char *apqns, u8 *mkvp, int min_level,
|
||||
enum card_type cardtype, bool print_mks, bool verbose)
|
||||
{
|
||||
struct cross_check_info info;
|
||||
char temp[200];
|
||||
char temp[250];
|
||||
int rc;
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
||||
20
zkey/utils.h
20
zkey/utils.h
@@ -16,17 +16,18 @@
|
||||
|
||||
#include "pkey.h"
|
||||
|
||||
int sysfs_is_card_online(int card, enum card_type cardtype);
|
||||
int sysfs_is_card_online(unsigned int card, enum card_type cardtype);
|
||||
|
||||
int sysfs_is_apqn_online(int card, int domain, enum card_type cardtype);
|
||||
int sysfs_is_apqn_online(unsigned int card, unsigned int domain,
|
||||
enum card_type cardtype);
|
||||
|
||||
int sysfs_get_card_level(int card);
|
||||
int sysfs_get_card_level(unsigned int card);
|
||||
|
||||
enum card_type sysfs_get_card_type(int card);
|
||||
enum card_type sysfs_get_card_type(unsigned int card);
|
||||
|
||||
#define SERIALNR_LENGTH 17
|
||||
|
||||
int sysfs_get_serialnr(int card, char *serialnr, bool verbose);
|
||||
int sysfs_get_serialnr(unsigned int card, char *serialnr, bool verbose);
|
||||
|
||||
struct fw_version {
|
||||
unsigned int major;
|
||||
@@ -34,7 +35,7 @@ struct fw_version {
|
||||
unsigned int api_ordinal;
|
||||
};
|
||||
|
||||
int sysfs_get_firmware_version(int card, struct fw_version *fw_version,
|
||||
int sysfs_get_firmware_version(unsigned int card, struct fw_version *fw_version,
|
||||
bool verbose);
|
||||
|
||||
#define MK_STATE_EMPTY 0
|
||||
@@ -57,10 +58,11 @@ struct mk_info {
|
||||
struct mk_info_reg old_mk; /* only available on CCA cards */
|
||||
};
|
||||
|
||||
int sysfs_get_mkvps(int card, int domain, struct mk_info *mk_info,
|
||||
bool verbose);
|
||||
int sysfs_get_mkvps(unsigned int card, unsigned int domain,
|
||||
struct mk_info *mk_info, bool verbose);
|
||||
|
||||
typedef int(*apqn_handler_t) (int card, int domain, void *handler_data);
|
||||
typedef int(*apqn_handler_t) (unsigned int card, unsigned int domain,
|
||||
void *handler_data);
|
||||
|
||||
int handle_apqns(const char *apqns, enum card_type cardtype,
|
||||
apqn_handler_t handler, void *handler_data, bool verbose);
|
||||
|
||||
@@ -73,7 +73,7 @@ static void misc_print_required_parms(const char *parm_name1,
|
||||
/*
|
||||
* Program configuration
|
||||
*/
|
||||
const struct util_prg prg = {
|
||||
static const struct util_prg prg = {
|
||||
.desc = "Manage secure volume keys of volumes encrypted with LUKS2 and "
|
||||
"the 'paes' cipher",
|
||||
.command_args = "COMMAND DEVICE",
|
||||
@@ -368,8 +368,8 @@ static void set_int_handler(void)
|
||||
pr_verbose("Installing SIGINT/SIGTERM handler");
|
||||
memset(&sigaction_open, 0, sizeof(struct sigaction));
|
||||
sigaction_open.sa_handler = int_handler;
|
||||
sigaction(SIGINT, &sigaction_open, 0);
|
||||
sigaction(SIGTERM, &sigaction_open, 0);
|
||||
sigaction(SIGINT, &sigaction_open, NULL);
|
||||
sigaction(SIGTERM, &sigaction_open, NULL);
|
||||
}
|
||||
|
||||
static void print_usage_command(const struct zkey_cryptsetup_command *command)
|
||||
@@ -2256,7 +2256,7 @@ static bool is_command(struct zkey_cryptsetup_command *command, const char *str)
|
||||
/*
|
||||
* Find the command in the command table
|
||||
*/
|
||||
struct zkey_cryptsetup_command *find_command(const char *command)
|
||||
static struct zkey_cryptsetup_command *find_command(const char *command)
|
||||
{
|
||||
struct zkey_cryptsetup_command *cmd = zkey_cryptsetup_commands;
|
||||
|
||||
|
||||
660
zkey/zkey.1
660
zkey/zkey.1
@@ -1,8 +1,8 @@
|
||||
.\" Copyright IBM Corp. 2017, 2018
|
||||
.\" Copyright IBM Corp. 2017, 2020
|
||||
.\" s390-tools is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the MIT license. See LICENSE for details.
|
||||
.\"
|
||||
.TH ZKEY 1 "May 2018" "s390-tools"
|
||||
.TH ZKEY 1 "July 2020" "s390-tools"
|
||||
.SH NAME
|
||||
zkey \- Manage secure AES keys
|
||||
.
|
||||
@@ -15,6 +15,12 @@ zkey \- Manage secure AES keys
|
||||
.
|
||||
.PP
|
||||
.B zkey
|
||||
.I command sub-command
|
||||
.RB [ OPTIONS ]
|
||||
.
|
||||
.
|
||||
.PP
|
||||
.B zkey
|
||||
.BR \-\-help | \-h
|
||||
.br
|
||||
.B zkey
|
||||
@@ -56,6 +62,17 @@ length of 128, or 256 bits each, for keys that are used for the XTS cipher mode.
|
||||
Note that the file size is not related to the key bit size, but is specific for
|
||||
the secure key type. The key is enciphered with the master key of the CCA or
|
||||
EP11 cryptographic adapter.
|
||||
.PP
|
||||
Secure keys in a key repository can either be generated locally, or by a \fBkey
|
||||
management system (KMS)\fP. A key repository can be bound to a key management
|
||||
system (KMS) via a key management system plugin (KMS plugin), which builds the
|
||||
interface to the key management system. This allows to integrate a zkey key
|
||||
repository into an enterprise key management system, that manages the keys in
|
||||
a larger environment.
|
||||
When a key repository is bound to a key management system, then all keys are
|
||||
generated by the key management system per default, and are thus also bound to
|
||||
the key management system. Any additional information associated with the keys
|
||||
in the repository is also stored in the key management system.
|
||||
.
|
||||
.
|
||||
.
|
||||
@@ -108,25 +125,36 @@ key repository.
|
||||
.IR clear\-key\-file ]
|
||||
.RB [ \-\-key-type | \-K
|
||||
.IR type ]
|
||||
.RB [ \-\-local | \-L ]
|
||||
.RB [ KMS\-plugin\ specific\ options ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.PP
|
||||
Use the
|
||||
.B generate
|
||||
command to generate a new secure AES key either randomly within the CCA or EP11
|
||||
cryptographic adapter, or from a clear AES key specified as input. When specifying
|
||||
a clear key as input, the clear key should be kept in a secure place, or be
|
||||
securely erased after creation of the secure key. The secure key itself does
|
||||
not need to be kept secure, because it can only be used together with a
|
||||
CCA or EP11 cryptographic adapter that contains the master key with which the
|
||||
secure key was generated.
|
||||
cryptographic adapter, from a clear AES key specified as input, or using a key
|
||||
management system plugin (KMS plugin). When specifying a clear key as input, the
|
||||
clear key should be kept in a secure place, or be securely erased after creation
|
||||
of the secure key. The secure key itself does not need to be kept secure,
|
||||
because it can only be used together with a CCA or EP11 cryptographic adapter
|
||||
that contains the master key with which the secure key was generated.
|
||||
.PP
|
||||
When the secure key repository is bound to a key management system plugin (KMS
|
||||
plugin), then the secure key is generated by using the key management system,
|
||||
except the \fB\-\-local\fP option is specified.
|
||||
.PP
|
||||
A key management system plugin may offer plugin specific options that can be
|
||||
specified with the \fBgenerate\fP command. Use \fBgenerate \-\-help\fP
|
||||
to display the plugin specific options and their meaning.
|
||||
.PP
|
||||
The generated secure key can either be stored in a file in the file system,
|
||||
or in the secure key repository. To store the generated secure key in a
|
||||
file, specify the file name with option \fIsecure\-key\-file\fP. To store the
|
||||
secure key in the secure key repository, specify the name of the key using the
|
||||
.B \-\-name
|
||||
option. When storing the secure key in a key repository,
|
||||
additional information can be associated with a secure key using the
|
||||
option. Secure keys generated using a key management system plugin can only be
|
||||
stored in a secure key repository. When storing the secure key in a key
|
||||
repository, additional information can be associated with a secure key using the
|
||||
.B \-\-description
|
||||
,
|
||||
.B \-\-volumes
|
||||
@@ -134,13 +162,18 @@ additional information can be associated with a secure key using the
|
||||
.B \-\-apqns
|
||||
, or the
|
||||
.B \-\-sector-size
|
||||
options.
|
||||
options. When the secure key repository is bound to a key management system
|
||||
plugin, then you can not associate specific APQNs with such keys, but the keys
|
||||
inherit the APQNs that are associated with the key management system plugin.
|
||||
.PP
|
||||
You can generate different types of secure keys: \fBCCA-AESDATA\fP keys,
|
||||
\fBCCA-AESCIPHER\fP, and \fBEP11-AES\fP keys.
|
||||
Specify the type of the secure key using the
|
||||
.B \-\-key\-type
|
||||
option. The default key type is CCA-AESDATA.
|
||||
option. Normally, the default key type is CCA-AESDATA. If the secure key
|
||||
repository is bound to a key management system plugin, and the plugin does not
|
||||
support keys of type CCA-AESDATA, then the default key type is CCA-AESCIPHER, or
|
||||
EP11-AES, whichever the plugin supports.
|
||||
.PP
|
||||
.B Note:
|
||||
Secure keys of type \fBCCA-AESCIPHER\fP require an IBM cryptographic
|
||||
@@ -402,6 +435,8 @@ The exported secure key also remains in the secure key repository.
|
||||
.IR type ]
|
||||
.RB [ \-\-key-type | \-K
|
||||
.IR type ]
|
||||
.RB [ \-\-local | \-L ]
|
||||
.RB [ \-\-kms\-bound | \-M ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
@@ -409,8 +444,9 @@ Use the
|
||||
.B list
|
||||
command to display a list of secure keys contained in the secure key repository.
|
||||
You can filter the displayed list by key name, associated volumes, associated
|
||||
cryptographic adapters (APQNs), and volume type. You can use wildcards for the
|
||||
key name, associated APQNs, and associated volumes. The device-mapper name of an
|
||||
cryptographic adapters (APQNs), volume type, and whether the keys are local or
|
||||
bound to a key management system (MKS). You can use wildcards for the key name,
|
||||
associated APQNs, and associated volumes. The device-mapper name of an
|
||||
associated volume can be omitted; if it is specified then only those keys are
|
||||
listed that are associated with the specified volume and device-mapper name.
|
||||
.PP
|
||||
@@ -419,8 +455,9 @@ The
|
||||
command displays the attributes of the secure keys, such as key sizes, key type,
|
||||
whether it is a secure key that can be used for the XTS cipher mode, the textual
|
||||
description, associated cryptographic adapters (APQNs) and volumes, the
|
||||
sector size, the key verification pattern, and timestamps for key creation, last
|
||||
modification and last re-encipherment.
|
||||
sector size, the key verification pattern, timestamps for key creation, last
|
||||
modification and last re-encipherment, and whether the key is local or
|
||||
bound to a key management systen (KMS).
|
||||
.
|
||||
.SS "Remove existing AES secure keys from the secure key repository"
|
||||
.
|
||||
@@ -429,6 +466,7 @@ modification and last re-encipherment.
|
||||
.B \-\-name | \-N
|
||||
.IR key-name
|
||||
.RB [ \-\-force | \-F ]
|
||||
.RB [ KMS\-plugin\ specific\ options ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
@@ -442,6 +480,16 @@ a confirmation, unless you specify the
|
||||
.B \-\-force
|
||||
option.
|
||||
.PP
|
||||
When the secure key that is to be removed is bound to a key management system,
|
||||
then the key management system plugin might also take an action in the key
|
||||
management system. It may for example change the state of the key in the key
|
||||
management system, instead of removing the key. Nevertheless, the secure key
|
||||
is removed from the local repository.
|
||||
.PP
|
||||
A key management system plugin may offer plugin specific options that can be
|
||||
specified with the \fBremove\fP command. Use \fBremove \-\-help\fP
|
||||
to display the plugin specific options and their meaning.
|
||||
.PP
|
||||
.B Note:
|
||||
When removing a secure key that is associated with one or multiple volumes,
|
||||
and the key's volume type is \fBplain\fP,
|
||||
@@ -499,6 +547,12 @@ options. You cannot mix \fI+\fP and
|
||||
\fI-\fP in one specification. You can either add or remove (or set) the
|
||||
associations with one command.
|
||||
.PP
|
||||
For secure AES keys that are bound to a key management system (KMS) you can not
|
||||
change the APQN association. KMS-bound secure AES keys are always bound to the
|
||||
APQNs that are associated with the key management system plugin.
|
||||
Other associated information is also changed in the key management system when
|
||||
changed using the change command.
|
||||
.PP
|
||||
.B Note:
|
||||
The secure key itself cannot be changed, only information about the secure
|
||||
key is changed. To rename a secure key, use the \fBrename\fP command.
|
||||
@@ -544,6 +598,7 @@ secure key is contained in the LUKS2 header.
|
||||
.IR new-key-name
|
||||
.RB [ \-\-volumes | \-l
|
||||
.IR volume1:dmname1[,volume2:dmname2[,...]] ]
|
||||
.RB [ \-\-local | \-L ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
@@ -563,6 +618,10 @@ a specific volume can only be associated with a single secure key. Specify the
|
||||
option to associate different
|
||||
volumes with the copied secure key, or use the \fBchange\fP command to associate
|
||||
volumes afterwards.
|
||||
.PP
|
||||
You can not copy secure keys that are bound to a key management system (KMS),
|
||||
except when the \fB\-\-local\fP option is specified. The copied secure key is
|
||||
then created as a local key.
|
||||
.
|
||||
.SS "Generate crypttab entries for volumes associated with secure AES keys"
|
||||
.
|
||||
@@ -720,6 +779,7 @@ Use the
|
||||
.B convert
|
||||
command to convert an existing secure key from one key type to another type.
|
||||
You can convert secure keys of type CCA-AESDATA to type CCA-AESCIPHER only.
|
||||
You can not convert keys that are bound to a key management system (KMS).
|
||||
|
||||
.B Note:
|
||||
Secure keys converted to type \fBCCA-AESCIPHER\fP require an IBM cryptographic
|
||||
@@ -760,6 +820,334 @@ is 6.3.27 or later. For the supported environments and downloads, see:
|
||||
\fIhttp://www.ibm.com/security/cryptocards\fP
|
||||
.
|
||||
.
|
||||
.SH COMMANDS FOR KEY MANAGEMENT SYSTEM INTEGRATION
|
||||
.
|
||||
Use the \fBkms\fP command to control the integration into key management
|
||||
systems. The \fBkms\fP command offers several subcommands for key management
|
||||
specific operations. Use \fBzkey kms \-\-help\fP to show the available
|
||||
subcommands.
|
||||
.
|
||||
.SS "List key management system plugins"
|
||||
.
|
||||
.B zkey kms
|
||||
.BR plugins | pl
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B kms plugins
|
||||
command to display a list of configured key management system plugins (KMS
|
||||
plugins). It displays the key management system plugin name, and the shared
|
||||
library that implements the plugin.
|
||||
.
|
||||
.P
|
||||
Key management system plugins are configured in configuration file
|
||||
\fB/etc/zkey/kms-plugins.conf\fP. This file contains the KMS plugin name and
|
||||
its shared library. Set environment variable \fBZKEY_KMS_PLUGINS\fP to point to
|
||||
a different file to use a different KMS plugin configuration file.
|
||||
.
|
||||
.SS "Bind the repository to a key management system"
|
||||
.
|
||||
.B zkey kms
|
||||
.BR bind | bi
|
||||
.I KMS\-plugin\-name
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B kms bind
|
||||
command to bind the repository to a key management system (KMS).
|
||||
The \fBkms plugins\fP command displays a list of configured key management
|
||||
system plugins that can be used.
|
||||
.
|
||||
.PP
|
||||
After binding a repository to a key management system, the KMS plugin must
|
||||
first be configured. Use the \fBkms configure\fP command to
|
||||
configure the plugin. As a minimum, you must associate APQNs with the key
|
||||
management system plugin. The plugin may require additional configuration
|
||||
before it is fully functioning. Use the \fBkms info\fP command to display
|
||||
information about the key management system plugin and its configuration.
|
||||
.
|
||||
.PP
|
||||
When a key repository is bound to a key management system, then all keys are
|
||||
generated by this key management system per default, and are thus also bound to
|
||||
the key management system. Any additional information associated with the keys
|
||||
in the repository is also stored in the key management system.
|
||||
.
|
||||
.SS "Unbind the repository from a key management system"
|
||||
.
|
||||
.B zkey kms
|
||||
.BR unbind | unb
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B kms unbind
|
||||
command to unbind the repository from a key management system (KMS). All keys
|
||||
that are currently bound to the key management system, are unbound and become
|
||||
local keys. You are prompted to confirm the unbinding.
|
||||
.
|
||||
.SS "Display information about a key management system plugin"
|
||||
.
|
||||
.B zkey kms
|
||||
.BR info | in
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B kms info
|
||||
command to display information about the currently bound key management system
|
||||
plugin (KMS plugin) and its configuration.
|
||||
.
|
||||
.SS "Configure or re\-configure a key management system plugin"
|
||||
.
|
||||
.B zkey kms
|
||||
.BR configure | con
|
||||
.RB [ \-\-apqns | \-a
|
||||
.IR [+|-]card1.domain1[,card2.domain2[,...]] ]
|
||||
.RB [ KMS\-plugin\ specific\ options ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B kms configure
|
||||
command to configure or re\-configure the currently bound key management system
|
||||
plugin (KMS plugin). As a minimum, you must associate APQNs with the key
|
||||
management system plugin. The plugin may require an initial configuration
|
||||
before it is fully functioning. Once configured, a plugin may allow you to
|
||||
change some configuration settings.
|
||||
.PP
|
||||
A key management system plugin may offer plugin specific options that can be
|
||||
specified with the \fBkms configure\fP command. Use \fBkms configure
|
||||
\-\-help\fP to display the plugin specific options and their meaning.
|
||||
.PP
|
||||
Configuring a key management system plugin may be a multi-step task. You can
|
||||
supply all configuration options at once or use the \fBkms configure\fP
|
||||
command several times supplying only one or a few configuration options each
|
||||
time, dependent on what the plugin supports. A plugin may also require to
|
||||
perform additional intermediate steps between two configuration attempts,
|
||||
e.g. perform tasks in the key management system user interface, or elsewhere.
|
||||
.PP
|
||||
Use the \fBkms info\fP command to display information about the key management
|
||||
system plugin and its current configuration.
|
||||
.
|
||||
.SS "Re-encipher secure keys used by a key management system plugin"
|
||||
.
|
||||
.B zkey kms
|
||||
.BR reencipher | re
|
||||
.RB [ \-\-to\-new | \-n ]
|
||||
.RB [ \-\-from\-old | \-o ]
|
||||
.RB [ \-\-in-place | \-i ]
|
||||
.RB [ \-\-staged | \-s ]
|
||||
.RB [ \-\-complete | \-c ]
|
||||
.RB [ KMS\-plugin\ specific\ options ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B kms reencipher
|
||||
command to re-encipher secure keys internally used by the currently bound
|
||||
key management system plugin (KMS plugin) with a new master key. This command
|
||||
must be run when the master keys of the CCA or EP11 cryptographic adapter,
|
||||
that are associated with the plugin have been changed. Dependent on what key
|
||||
types the key management system plugin supports, it may internally use secure
|
||||
keys with CCA or EP11 cryptographic adapters, or both.
|
||||
.PP
|
||||
A key management system plugin may offer plugin specific options that can be
|
||||
specified with the \fBkms reencipher\fP command. Use \fBkms reencipher
|
||||
\-\-help\fP to display the plugin specific options and their meaning.
|
||||
.PP
|
||||
.B Note:
|
||||
The \fBkms reencipher\fP command does \fBnot\fP re-encipher secure keys that
|
||||
have been generated by or have been imported from the key management system
|
||||
plugin and are stored in the repository. Use the regular \fBreencipher\fP
|
||||
command to re-encipher those secure keys.
|
||||
.PP
|
||||
The CCA cryptographic adapter has three different registers to store
|
||||
master keys:
|
||||
.RS 2
|
||||
.IP "\(bu" 2
|
||||
The \fBCURRENT\fP register contains the current master key.
|
||||
.
|
||||
.IP "\(bu" 2
|
||||
The \fBOLD\fP register contains the previously used master key.
|
||||
Secure keys enciphered with the master key contained in the \fBOLD\fP
|
||||
register can still be used until the master key is changed again.
|
||||
.
|
||||
.IP "\(bu" 2
|
||||
The \fBNEW\fP register contains the new master key to be set.
|
||||
The master key in the \fBNEW\fP register cannot be used until it is made
|
||||
the current master key. You can pro-actively re-encipher a secure key with the
|
||||
\fBNEW\fP master key before this key is made the \fBCURRENT\fP key. Use the
|
||||
.B \-\-to-new
|
||||
option to do this.
|
||||
.RE
|
||||
.PP
|
||||
\fBNote:\fP An EP11 cryptographic adapter has only two registers to store master
|
||||
keys, \fBCURRENT\fP and \fBNEW\fP.
|
||||
.PP
|
||||
Use the
|
||||
.B \-\-from\-old
|
||||
option to re-encipher a secure key that is currently enciphered with
|
||||
the master key in the \fBOLD\fP register with the master key in the
|
||||
\fBCURRENT\fP register. This option is only available for CCA-type secure keys.
|
||||
.PP
|
||||
.PP
|
||||
If both the
|
||||
.B \-\-from-old
|
||||
and
|
||||
.B \-\-to-new
|
||||
options are specified, a secure key that is currently enciphered
|
||||
with the master key in the \fBOLD\fP register is re-enciphered with the
|
||||
master key in the \fBNEW\fP register.
|
||||
.PP
|
||||
If both options are omitted, the key management system plugin may
|
||||
automatically detect whether the secure key is currently enciphered with the
|
||||
master key in the \fBOLD\fP register or with the master key in the \fBCURRENT\fP
|
||||
register. If currently enciphered with the master key in the \fBOLD\fP register,
|
||||
it is re-enciphered with the master key in the \fBCURRENT\fP register.
|
||||
If currently enciphered with the master key in the \fBCURRENT\fP
|
||||
register, it is re-enciphered with the master key in the \fBNEW\fP register.
|
||||
If for this case the \fBNEW\fP register does not contain a valid master key,
|
||||
then the re-encipher operation fails.
|
||||
.PP
|
||||
Re-enciphering a secure key used by a key management system plugin can be
|
||||
performed \fBin-place\fP, or in \fBstaged\fP mode.
|
||||
.PP
|
||||
\fB"In-place"\fP immediately replaces the secure key with the re-enciphered
|
||||
secure key. Re-enciphering from \fBOLD\fP to \fBCURRENT\fP is performed
|
||||
in-place per default. You can use option \fB\-\-in-place\fP to force an
|
||||
in-place re-enciphering for the \fBCURRENT\fP to \fBNEW\fP case.
|
||||
A secure key that was re-enciphered in-place from \fBCURRENT\fP to \fBNEW\fP
|
||||
is no longer valid, until the new CCA or EP11 master key has been made the
|
||||
current one.
|
||||
.PP
|
||||
\fBStaged\fP mode means that the re-enciphered secure key is stored separately.
|
||||
Thus the current secure key is still valid at this point. Once the new CCA or
|
||||
EP11 master key has been set (made active), you must rerun the \fBkms
|
||||
reencipher\fP command with option \fB\-\-complete\fP to complete the staged
|
||||
re-enciphering. Re-enciphering from \fBCURRENT\fP to \fBNEW\fP is performed in
|
||||
staged mode per default. You can use option \fB\-\-staged\fP to force a staged
|
||||
re-enciphering for the \fBOLD\fP to \fBCURRENT\fP case.
|
||||
.
|
||||
.SS "List secure keys managed by a key management system"
|
||||
.
|
||||
.B zkey kms
|
||||
.BR list | li
|
||||
.RB [ \-\-label | \-B
|
||||
.IR key-label ]
|
||||
.RB [ \-\-name | \-N
|
||||
.IR key-name ]
|
||||
.RB [ \-\-volumes | \-l
|
||||
.IR volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
||||
.RB [ \-\-volume-type | \-t
|
||||
.IR type ]
|
||||
.RB [ KMS\-plugin\ specific\ options ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B kms list
|
||||
command to display secure keys managed by a key management system (KMS).
|
||||
You can filter the displayed list by key label, key name, associated volumes,
|
||||
and volume type. You can use wildcards for the key label, key name, and
|
||||
associated volumes. The device-mapper name of an associated volume can be
|
||||
omitted. If specified, then only those keys are listed that are associated
|
||||
with the specified volume and device-mapper name.
|
||||
.PP
|
||||
A key management system plugin may offer plugin specific options that can be
|
||||
specified with the \fBkms list\fP command. Use \fBkms list \-\-help\fP
|
||||
to display the plugin specific options and their meaning.
|
||||
.PP
|
||||
The
|
||||
.B kms list
|
||||
command displays the attributes of the secure keys, such as key label, key name,
|
||||
whether it is a secure key that can be used for the XTS cipher mode, the textual
|
||||
description, associated volumes, the volume type, and sector size.
|
||||
.
|
||||
.SS "Import secure keys managed by a key management system into the repository"
|
||||
.
|
||||
.B zkey kms
|
||||
.BR import | im
|
||||
.RB [ \-\-label | \-B
|
||||
.IR key-label ]
|
||||
.RB [ \-\-name | \-N
|
||||
.IR key-name ]
|
||||
.RB [ \-\-volumes | \-l
|
||||
.IR volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
||||
.RB [ \-\-volume-type | \-t
|
||||
.IR type ]
|
||||
.RB [ \-\-batch\-mode | \-q ]
|
||||
.RB [ \-\-no\-volume\-check ]
|
||||
.RB [ KMS\-plugin\ specific\ options ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B kms import
|
||||
command to import secure keys managed by a key management system (KMS) into the
|
||||
secure key repository.
|
||||
You can filter the list of keys to be imported by key label, key name,
|
||||
associated volumes, and volume type. You can use wildcards for the key label,
|
||||
key name, and associated volumes. The device-mapper name of an associated
|
||||
volume can be omitted. If it is specified, then only those keys are listed that
|
||||
are associated with the specified volume and device-mapper name.
|
||||
.PP
|
||||
A key management system plugin may offer plugin specific options that can be
|
||||
specified with the \fBkms import\fP command. Use \fBkms import \-\-help\fP
|
||||
to display the plugin specific options and their meaning.
|
||||
.PP
|
||||
If a secure key with the same name as a key to be imported already exists in
|
||||
the repository, then you are prompted to enter an alternate name. You can skip
|
||||
the import of that key, or enter an alternate name. If option
|
||||
\fB\-\-batch\-mode\fP is specified, then already existing keys are skipped.
|
||||
.PP
|
||||
If a key to be imported is associated with one or multiple volumes, it is
|
||||
verified that the volumes are available, and are not already associated with
|
||||
another secure key in the repository. If one of the volumes or all of them are
|
||||
not available, or are already associated with another secure key, the import
|
||||
fails. Use option \fB\-\-no\-volume\-check\fP to omit the volume check, and
|
||||
import the keys even if the associated volume(s) do not exist.
|
||||
.
|
||||
.SS "Refresh secure keys that are bound to a key management system"
|
||||
.
|
||||
.B zkey kms
|
||||
.BR refresh | ref
|
||||
.RB [ \-\-name | \-N
|
||||
.IR key-name ]
|
||||
.RB [ \-\-volumes | \-l
|
||||
.IR volume1[:dmname1][,volume2[:dmname2][,...]] ]
|
||||
.RB [ \-\-volume-type | \-t
|
||||
.IR type ]
|
||||
.RB [ \-\-key-type | \-K
|
||||
.IR type ]
|
||||
.RB [ \-\-refresh\-properties | \-P ]
|
||||
.RB [ \-\-no\-volume\-check ]
|
||||
.RB [ \-\-verbose | \-V ]
|
||||
.
|
||||
.PP
|
||||
Use the
|
||||
.B kms refresh
|
||||
command to refresh secure keys that are bound to a key management system (KMS).
|
||||
Refreshing a key updates the secure key by re-importing it from the key
|
||||
management system. Use option \fB\-\-refresh\-properties\fP to also update the
|
||||
associated information, such as the textual description, associated volumes,
|
||||
volume type, and sector size, with the information stored in the key management
|
||||
system.
|
||||
.PP
|
||||
You can filter the list of keys to be refreshed by key name, associated volumes,
|
||||
volume type, and key type. You can use wildcards for the key name, and
|
||||
associated volumes. The device-mapper name of an associated volume can be
|
||||
omitted; if it is specified then only those keys are listed that are associated
|
||||
with the specified volume and device-mapper name.
|
||||
.PP
|
||||
If a refreshed key is associated with one or multiple volumes, it is
|
||||
verified that the volumes are available, and are not already associated with
|
||||
another secure key in the repository. If one of the volumes or all of them are
|
||||
not available, or are already associated with another secure key, the refresh
|
||||
fails. Use option \fB\-\-no\-volume\-check\fP to omit the volume check, and
|
||||
refresh the keys even if the associated volume(s) do not exist.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SH OPTIONS
|
||||
@@ -782,6 +1170,8 @@ determines the size of the AES key. If option \fB\-\-keybits\fP
|
||||
is specified, the size of the specified file must match the specified
|
||||
key size. Valid file sizes are of 16, 24, or 32 bytes, and of 32 or 64
|
||||
bytes for keys to be used with the XTS cipher mode.
|
||||
When the secure key is generated using a key management system, then this option
|
||||
can not be specified.
|
||||
.TP
|
||||
.BR \-N ", " \-\-name\~\fIkey-name\fP
|
||||
Specifies the name of the secure key in the secure key repository.
|
||||
@@ -808,6 +1198,8 @@ then the first online APQN is used to generate the key. If no APQNs are
|
||||
specified, then an APQN is selected automatically. All specified APQNs must be
|
||||
online, unless the \fB\-\-no\-apqn\-check\fP option is specified.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
When the secure key is generated using a key management system, then this option
|
||||
can not be specified.
|
||||
.TP
|
||||
.BR \-\-no\-apqn\-check
|
||||
Do not check if the specified APQNs are available. Use this option to
|
||||
@@ -837,6 +1229,18 @@ Secure keys of type \fBCCA-AESCIPHER\fP require an IBM cryptographic adapter
|
||||
in CCA coprocessor mode of version 6 or later, e.g. a CEX6C.
|
||||
Secure keys of type \fBEP11-AES\fP require an IBM cryptographic adapter
|
||||
in EP11 coprocessor mode of version 7 or later, e.g. a CEX7P.
|
||||
.TP
|
||||
.BR \-L ", "\-\-local
|
||||
Generate the secure AES key locally. This is the default when no key management
|
||||
system plugin (KMS plugin) is bound to the secure key repository. If the
|
||||
repository is bound to a key management system plugin, then keys are generated
|
||||
using the key management system by default.
|
||||
.TP
|
||||
.B KMS-plugin specific options
|
||||
A key management system plugin may offer and even require plugin specific
|
||||
options that can be specified with the generate command when the secure key
|
||||
repository is bound to a key management system plugin. Use \fBgenerate
|
||||
\-\-help\fP to display the plugin specific options and their meaning.
|
||||
.
|
||||
.
|
||||
.
|
||||
@@ -1024,6 +1428,21 @@ Specifies the key type of the secure key. Possible values are \fBCCA-AESDATA\fP,
|
||||
\fBCCA-AESCIPHER\fP, and \fBEP11-AES\fP. Only keys with the specified key type
|
||||
are listed.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-L ", " \-\-local\fP
|
||||
Lists only local keys. Local keys are not bound to a key management system
|
||||
(KMS).
|
||||
This option is only used for secure keys contained in the secure key repository,
|
||||
and can not be specified together with the
|
||||
.BR \-\-kms\-bound
|
||||
option.
|
||||
.TP
|
||||
.BR \-M ", " \-\-kms\-bound\fP
|
||||
Lists only keys that are bound to a key management system (KMS).
|
||||
This option is only used for secure keys contained in the secure key repository,
|
||||
and can not be specified together with the
|
||||
.BR \-\-local
|
||||
option.
|
||||
.
|
||||
.
|
||||
.
|
||||
@@ -1039,6 +1458,12 @@ The user is prompted to confirm the removal of a secure key from the secure
|
||||
key repository. Use this option to remove a secure key without prompting for
|
||||
a confirmation.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.B KMS-plugin specific options
|
||||
A key management system plugin may offer and even require plugin specific
|
||||
options that can be specified with the remove command when the secure key
|
||||
repository is bound to a key management system plugin. Use \fBremove
|
||||
\-\-help\fP to display the plugin specific options and their meaning.
|
||||
.
|
||||
.
|
||||
.
|
||||
@@ -1133,6 +1558,12 @@ These volumes are to be encrypted using dm-crypt with the secure AES key. The
|
||||
volume association also contains the device-mapper name, separated by a colon,
|
||||
used with dm-crypt.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-L ", "\-\-local
|
||||
Copy the secure key to a local key. This is the default when no key management
|
||||
system plugin (KMS plugin) is bound to the secure key repository. If the
|
||||
repository is bound to a key management system plugin, then the keys are bound
|
||||
to the KMS per default, and KMS-bound keys can only be copied to local keys.
|
||||
.
|
||||
.
|
||||
.
|
||||
@@ -1311,6 +1742,194 @@ to convert a secure key without prompting for a confirmation.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "Options for the kms configure command"
|
||||
.TP
|
||||
.BR \-a ", " \-\-apqns\~\fI[+|-]card1.domain1[,card2.domain2[,...]]\fP
|
||||
Specifies a comma-separated list of cryptographic adapters in CCA or EP11
|
||||
coprocessor mode (APQN) which are associated with the key management system
|
||||
plugin. Each APQN association specifies a card and domain number separated
|
||||
by a period (like lszcrypt displays it).
|
||||
To add an APQN to the associated APQNs, prefix the APQN with a \fI+\fP.
|
||||
To remove an APQN from the associated APQNs, prefix the APQN with a \fI-\fP.
|
||||
To set (replace) the APQN association do not specify a prefix.
|
||||
You cannot mix \fI+\fP and \fI-\fP in one specification. You can either add or
|
||||
remove (or set) the associations with one command.
|
||||
All APQNs being added or set (replaced) must be online.
|
||||
.TP
|
||||
.B KMS-plugin specific options
|
||||
A key management system plugin may offer plugin specific options that can be
|
||||
specified with the kms configure command. Use \fBkms configure \-\-help\fP to
|
||||
display the plugin specific options and their meaning.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "Options for the kms reencipher command"
|
||||
.TP
|
||||
.BR \-n ", " \-\-to\-new
|
||||
Re-enciphers key management system plugin internal secure keys that are
|
||||
currently enciphered with the master key in the CURRENT register with the
|
||||
master key in the NEW register.
|
||||
.TP
|
||||
.BR \-o ", " \-\-from\-old
|
||||
Re-enciphers key management system plugin internal secure keys that are
|
||||
currently enciphered with the master key in the OLD register with the master
|
||||
key in the CURRENT register.
|
||||
This option is only available for CCA-type secure keys.
|
||||
.TP
|
||||
.BR \-i ", " \-\-in-place
|
||||
Forces an in-place re-enciphering of key management system plugin internal
|
||||
secure keys. "In-place" immediately replaces the secure key with the
|
||||
re-enciphered secure key. Re-enciphering from OLD to CURRENT is performed
|
||||
in-place per default.
|
||||
.TP
|
||||
.BR \-s ", " \-\-staged
|
||||
Forces that the re-enciphering of key management system plugin internal secure
|
||||
keys is performed in staged mode. Staged mode means that the re-enciphered
|
||||
secure keys are stored separately. Thus the current secure keys are still valid
|
||||
at this point. Once the new CCA or EP11 master keys have been set (made active),
|
||||
you must rerun the \fBkms reencipher\fP command with option \fB\-\-complete\fP
|
||||
to complete the staged re-enciphering.
|
||||
Re-enciphering from CURRENT to NEW is performed in staged mode per default.
|
||||
.TP
|
||||
.BR \-p ", " \-\-complete
|
||||
Completes a staged re-enciphering. Use this option after the new CCA or EP11
|
||||
master keys have been set (made active). This option replaces the secure keys by
|
||||
their re-enciphered versions.
|
||||
.TP
|
||||
.B KMS-plugin specific options
|
||||
A key management system plugin may offer plugin specific options that can be
|
||||
specified with the kms reencipher command. Use \fBkms reencipher \-\-help\fP to
|
||||
display the plugin specific options and their meaning.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "Options for the kms list command"
|
||||
.TP
|
||||
.BR \-B ", " \-\-label\~\fIkey-label\fP
|
||||
Specifies the label of the secure key in the key management system (KMS).
|
||||
You can use wildcards to select multiple secure keys.
|
||||
When wildcards are used you must quote the value.
|
||||
Only keys with labels that match the pattern are listed.
|
||||
.TP
|
||||
.BR \-N ", " \-\-name\~\fIkey-name\fP
|
||||
Specifies the name of the secure key in the key management system (KMS).
|
||||
You can use wildcards to select multiple secure keys.
|
||||
When wildcards are used you must quote the value.
|
||||
Only keys with names that match the pattern are listed.
|
||||
This option is only used for secure keys contained in the secure key repository.
|
||||
.TP
|
||||
.BR \-l ", " \-\-volumes\~\fIvolume1[:dmname1][,volume2[:dmname2][,...]]\fP
|
||||
Specifies a comma-separated list of volumes (block devices) which are
|
||||
associated with the secure AES key in the key management system (KMS). Only
|
||||
those keys are listed, which are associated with the specified volumes.
|
||||
The volume association also contains the device-mapper name, separated by a
|
||||
colon, used with dm-crypt. You can omit the device-mapper name; if it is
|
||||
specified then only those keys are listed that are associated with the
|
||||
specified volume and device-mapper name. You can use wildcards to specify
|
||||
the volumes and device-mapper names.
|
||||
When wildcards are used you must quote the value.
|
||||
.TP
|
||||
.BR \-t ", " \-\-volume-type\~\fItype\fP
|
||||
Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
||||
values are \fBplain\fP and \fBluks2\fP. Only keys with the specified volume
|
||||
type are listed.
|
||||
This option is only available if
|
||||
.B zkey
|
||||
has been compiled with LUKS2 support enabled.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "Options for the kms import command"
|
||||
.TP
|
||||
.BR \-B ", " \-\-label\~\fIkey-label\fP
|
||||
Specifies the label of the secure key in the key management system (KMS).
|
||||
You can use wildcards to select multiple secure keys.
|
||||
When wildcards are used you must quote the value.
|
||||
Only keys with labels that match the pattern are imported.
|
||||
.TP
|
||||
.BR \-N ", " \-\-name\~\fIkey-name\fP
|
||||
Specifies the name of the secure key in the key management system (KMS).
|
||||
You can use wildcards to select multiple secure keys.
|
||||
When wildcards are used you must quote the value.
|
||||
Only keys with names that match the pattern are imported.
|
||||
.TP
|
||||
.BR \-l ", " \-\-volumes\~\fIvolume1[:dmname1][,volume2[:dmname2][,...]]\fP
|
||||
Specifies a comma-separated list of volumes (block devices) which are
|
||||
associated with the secure AES key in the key management system (KMS). Only
|
||||
those keys are imported, which are associated with the specified volumes.
|
||||
The volume association also contains the device-mapper name, separated by a
|
||||
colon, used with dm-crypt. You can omit the device-mapper name; if it is
|
||||
specified then only those keys are listed that are associated with the
|
||||
specified volume and device-mapper name. You can use wildcards to specify
|
||||
the volumes and device-mapper names.
|
||||
When wildcards are used you must quote the value.
|
||||
.TP
|
||||
.BR \-t ", " \-\-volume-type\~\fItype\fP
|
||||
Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
||||
values are \fBplain\fP and \fBluks2\fP. Only keys with the specified volume
|
||||
type are imported.
|
||||
This option is only available if
|
||||
.B zkey
|
||||
has been compiled with LUKS2 support enabled.
|
||||
.TP
|
||||
.BR \-q ", " \-\-batch\-mode
|
||||
Suppress prompts to skip or to enter an anternate name, if a secure key with the
|
||||
same name as the secure key to be imported already exists in the repository.
|
||||
When this option is specified, then keys with an altready existing name are
|
||||
skipped.
|
||||
.TP
|
||||
.BR \-\-no\-volume\-check
|
||||
Do not check if the volume(s) associated with the to be imported secure key(s)
|
||||
are available, or are already associated with other secure keys in the
|
||||
repository.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "Options for the kms refresh command"
|
||||
.TP
|
||||
.BR \-N ", " \-\-name\~\fIkey-name\fP
|
||||
Specifies the name of the secure key in the secure key repository. You can
|
||||
use wildcards to select multiple secure keys in the secure key repository.
|
||||
When wildcards are used you must quote the value.
|
||||
Only keys with names that match the pattern are refreshed.
|
||||
.TP
|
||||
.BR \-l ", " \-\-volumes\~\fIvolume1[:dmname1][,volume2[:dmname2][,...]]\fP
|
||||
Specifies a comma-separated list of volumes (block devices) which are
|
||||
associated with the secure AES key in the repository. Only those keys are
|
||||
refreshed, which are associated with the specified volumes.
|
||||
The volume association also contains the device-mapper name, separated by a
|
||||
colon, used with dm-crypt. You can omit the device-mapper name; if it is
|
||||
specified then only those keys are listed that are associated with the
|
||||
specified volume and device-mapper name. You can use wildcards to specify
|
||||
the volumes and device-mapper names.
|
||||
When wildcards are used you must quote the value.
|
||||
.TP
|
||||
.BR \-t ", " \-\-volume-type\~\fItype\fP
|
||||
Specifies the volume type of the associated volumes used with dm-crypt. Possible
|
||||
values are \fBplain\fP and \fBluks2\fP. Only keys with the specified volume
|
||||
type are refreshed.
|
||||
This option is only available if
|
||||
.B zkey
|
||||
has been compiled with LUKS2 support enabled.
|
||||
.TP
|
||||
.BR \-K ", " \-\-key-type\~\fItype\fP
|
||||
Specifies the key type of the secure key. Possible values are \fBCCA-AESDATA\fP,
|
||||
\fBCCA-AESCIPHER\fP, and \fBEP11-AES\fP. Only keys with the specified key type
|
||||
are refreshed.
|
||||
.TP
|
||||
.BR \-q ", " \-\-refresh\-properties
|
||||
Also update the associated information, such as the textual description,
|
||||
associated volumes, volume type, and sector size, with the information stored in
|
||||
the key management system.
|
||||
.TP
|
||||
.BR \-\-no\-volume\-check
|
||||
Do not check if the volume(s) associated with the secure key(s) to be refreshed
|
||||
are available, or are already associated with other secure keys in the
|
||||
repository. This option only has an effect when specified together with option
|
||||
\fB\-\-refresh\-properties\fP.
|
||||
.
|
||||
.
|
||||
.
|
||||
.SS "General options"
|
||||
.TP
|
||||
.BR \-V ", " \-\-verbose
|
||||
@@ -1410,4 +2029,11 @@ If
|
||||
.B $ZKEY_REPOSITORY
|
||||
is set, it specifies the location of the secure key repository.
|
||||
If it is not set, then the the default location of the secure key
|
||||
repository is \fB/etc/zkey/repository\fP.
|
||||
repository is \fB/etc/zkey/repository\fP.
|
||||
.TP
|
||||
.BR ZKEY_KMS_PLUGINS
|
||||
If
|
||||
.B $ZKEY_KMS_PLUGINS
|
||||
is set, it specifies the name of the KMS plugin configuration file.
|
||||
If it is not set, then the default KMS plugin configuration file
|
||||
\fB/etc/zkey/kms-plugins.conf\fP is used.
|
||||
993
zkey/zkey.c
993
zkey/zkey.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user