Compare commits

..

28 Commits

Author SHA1 Message Date
Marc Hartmayer
074de1e14e genprotimg: add host-key document verification support
Add host-key document verification support to genprotimg. This ensures
that a host-key document is genuine and provided by IBM. For this the
user must provide the IBM Z signing key, the intermediate CA
certificate (signed by the root CA used) so a chain of trust starting
from the host-key document and ending in the root CA can be
established.

By default, genprotimg tries to download all revocation lists needed
by looking up in the corresponding certificate on how CRL information
can be obtained (see https://tools.ietf.org/html/rfc5280#section-4.2.1.13
for details).

Acked-by: Patrick Steuer <patrick.steuer@de.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Ingo Franzki
07d181e29b zkey: Fix APQN property names
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Marc Hartmayer
895a88b2f8 genprotimg: require argument for 'ramdisk' and 'parmfile' options
A argument is required for the optional options 'ramdisk' and
'parmfile'.

Fixes: 65b9fc442c ("genprotimg: introduce new tool for the creation of PV images")
Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Ingo Franzki
f01f8b240c zkey-ekmfweb: Fix typo in message
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Jan Höppner
be2bc610b7 netboot: Add version information to scripts
Add the -v short option for version information to the mk-s390image and
mk-pxelinux-ramfs. Adjust the Makefile accordingly to set the correct
s390-tools version during installation.

Acked-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Marc Hartmayer
c48d45ba92 common.mak: use '--' for rm calls to distinguish between options and files
Use '--' for rm calls to distinguish between options and files. This
fixes, for example, the following error:

make[1]: Entering directory '/root/git/s390-tools/genprotimg/src'
rm -f *.gcda *.gcno *.gcov
rm: invalid option -- '.'
Try 'rm ./-.gcno' to remove the file '-.gcno'.
Try 'rm --help' for more information.
make[1]: *** [../../common.mak:369: clean_gcov] Error 1

Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Thomas Richter
886476a207 cpumf/chcpumf.c: Print proper error message on non-root invocation
chcpumf must be executed as root. A non-root user sees this error
message:

[tester@t35lp46 ~]$ chcpumf -m 1000
Error: /sys/module/kernel/parameters/cpum_sfb_size: Permission denied
[tester@t35lp46 ~]$

Enhance the error message and be clear about the root cause:
[tester@t35lp46 ~]$ chcpumf-new  -m 1000
Error: Must run as root
[tester@t35lp46 ~]$

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Thomas Richter
86685f001d cpumf/lscpumf.c: Check for help and version options first
Check command line arguments for help text and version
string first, before doing any action. This ensures this
information is always printed, even when invoked as non-root
user.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/97
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-18 11:28:35 +01:00
Jan Höppner
d619b492e9 lsdasd: Add FC Endpoint Security information
Provide the status of the FC Endpoint Security information via the long
output of lsdasd for online Base and Alias devices.

New Output:

$ lsdasd -l c600
0.0.c600/dasdd/9412
  status:                               n/f
  type:                                 ECKD
  blksz:                                512
  size:
  blocks:
  extent_size:                          1113
  logical_capacity:                     1113
  space_allocated:                      1113
  use_diag:                             0
  readonly:                             0
  eer_enabled:                          0
  erplog:                               0
  hpf:                                  1
  uid:                                  IBM.750000000KMV11.c600.00
  fc_security:                          Encryption
  paths_installed:                      38 39 3a 3b
  paths_in_use:                         38 39 3a 3b
  paths_non_preferred:
  paths_invalid_cabling:
  paths_cuir_quiesced:
  paths_invalid_hpf_characteristics:
  paths_error_threshold_exceeded:

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-12 10:50:48 +01:00
Jan Höppner
79e4798061 zdev: Add FC Endpoint Security information for DASD devices
Provide information for the DASD device attribute 'fc_security'.
The help output for this attribute can be queried like this:

chzdev dasd --help-attribute

The lszdev tool can be used to display the current state of the FC
Endpoint Security information:

lszdev dasd -a -c TYPE,ID,ATTR:fc_security,ATTRPATH:fc_security

Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-12 10:50:48 +01:00
Ingo Franzki
cf2311f1f1 zcryptstats: Fix handling of partial results with many domains
When many domains per card are available, then the results of the SCDMD
CHSC call may not fit into the output area, and a partial result is
returned. The further results must be retrieved with another CHSC call.

Fix the code to pass the correct next-domain to the subsequent CHSC call
of a partial response. Otherwise the same set of domains 1 to n are
retrieved again, resulting in an infinite loop, because this will always
produce a partial result.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-12 08:06:11 +01:00
Colin Walters
7e832da790 systemd/cpi.service: Add RemainAfterExit=yes
Noticed this while looking at the unit file for a different
RHEL CoreOS issue.

See https://github.com/ostreedev/ostree/pull/1697
and https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=750683

Omitting this can cause the service to run multiple times if
something else ends up depending on it, which I'm guessing
we don't want.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/72
Signed-off-by: Colin Walters <walters@verbum.org>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Dan Horák
3b402a0630 lscpumf: add z15 Model T02
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/87
Signed-off-by: Dan Horák <dan@danny.cz>
Reviewed-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Dan Horák
3437c9bb90 netboot/mk-s390image: add simple man page
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/94
Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Philipp Kern
8898650266 scripts/zipl-switch-to-blscfg.1: Fix some typos
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/90
Signed-off-by: Philipp Kern <pkern@google.com>
Acked-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Prashanth Sundararaman
3ae2100d5e systemd/cpi.service: Add sysinit.target dependency to make sure /var is created
Noticed on RHEL CoreOS that the CPI service failed to start with:

"Cannot access lock file: /var/lock/cpictl.lock"

This was a timing issue where /var was not created yet and the symlink
to /run/lock was not present. Add sysinit.target to fix this.
This fix has been tested with RHEL CoreOS.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/82
Signed-off-by: Prashanth Sundararaman <psundara@redhat.com>
Suggested-by: Colin Walters <walters@verbum.org>
Reviewed-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Alexander Egorenkov
93e4249fd3 zkey/ekmfweb: fix linking of libekmfweb
Use -L compiler's parameter instead of the environment variable
LIBRARY_PATH.

Fixes the following problem on buildroot:

buildroot/qemu-s390x/host/bin/s390x-linux-gcc -shared -Wl,--version-script=zkey-ekmfweb.map -Wl,-z,defs,-Bsymbolic -Wl,-soname,zkey-ekmfweb.so.1 zkey-ekmfweb.o properties.o pkey.o cca.o ep11.o utils.o ../..//libutil/libutil.a -lekmfweb -ldl -lcrypto -o zkey-ekmfweb.so
buildroot/qemu-s390x/host/bin/s390x-linux-gcc -I ../../include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I ../include -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -DS390_TOOLS_RELEASE=2.15.1-build-20201105 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -D_GNU_SOURCE -c udev_ccwgroup.c -o udev_ccwgroup.o
buildroot/qemu-s390x/host/bin/s390x-linux-gcc -I ../../include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I ../include -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -DS390_TOOLS_RELEASE=2.15.1-build-20201105 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -D_GNU_SOURCE -c iscsi.c -o iscsi.o
buildroot/qemu-s390x/host/bin/s390x-linux-gcc -I ../../include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I ../include -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -DS390_TOOLS_RELEASE=2.15.1-build-20201105 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -D_GNU_SOURCE -c dasd.c -o dasd.o
buildroot/qemu-s390x/host/opt/ext-toolchain/bin/../lib/gcc/s390x-buildroot-linux-gnu/9.3.0/../../../../s390x-buildroot-linux-gnu/bin/ld: cannot find -lekmfweb
collect2: error: ld returned 1 exit status
make[4]: *** [Makefile:36: zkey-ekmfweb.so] Error 1
make[3]: *** [Makefile:128: ekmfweb] Error 2
buildroot/qemu-s390x/host/bin/s390x-linux-gcc -I ../../include -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -I ../include -std=gnu99 -Wno-unused-parameter -Wno-missing-field-initializers -DS390_TOOLS_RELEASE=2.15.1-build-20201105 -DS390_TOOLS_LIBDIR=/lib/s390-tools -DS390_TOOLS_DATADIR=/usr/share/s390-tools -DS390_TOOLS_SYSCONFDIR=/etc -DS390_TOOLS_BINDIR=/sbin -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64  -Os   -D_GNU_SOURCE -c zfcp.c -o zfcp.o
make[2]: *** [Makefile:43: zkey] Error 2
make[2]: *** Waiting for unfinished jobs....

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-11 14:25:46 +01:00
Jan Höppner
8ec4705239 libutil: Compare proc entries to vfstype
Modern systems have systemd manage system mount points like sysfs which
specify 'sysfs' as a keyword for the device as there is no device
associated with this special filesystem. However, any arbitrary string
could be specified here and the determination of the sysfs mount point
would fail in such a case.
To make sure that the mount point of the sysfs is still found when
mounted with a device keyword specified other than 'sysfs', check for
the filesystem type instead, which is more specific.

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/91
Suggested-by: Mark Post <mpost@suse.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-09 12:24:32 +01:00
Jan Höppner
cad450fdf9 dasdfmt: Make error function less error-prone
Add a proper definition to the dasdfmt header file of the error()
function that lets the compiler check the format string against the
provided parameters.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-09 12:24:32 +01:00
Dan Horák
3a1cda59ce libekmfweb: fix permissions for ekmfweb.h
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/96
Signed-off-by: Dan Horák <dan@danny.cz>
Acked-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-09 10:39:46 +01:00
Wenjia Zhang
0566a492ae hsci: Add new tool to control HiperSockets Converged Interfaces
hsci is used to control and show HSCI (HiperSockets Converged Interfaces)
settings. A HiperSockets interface and an external network interface are
converged to an HSCI interface.

Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-09 10:16:22 +01:00
Marc Hartmayer
bc7359d2a3 iucvterm: abort if one of the recursive targets is failing
Abort processing as soon as one of the recursive targets is failing.

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-06 16:18:21 +01:00
Marc Hartmayer
db6f272607 genprotimg: fix two memory leaks
==1005844== HEAP SUMMARY:
==1005844==     in use at exit: 18,907 bytes in 14 blocks
==1005844==   total heap usage: 82 allocs, 68 frees, 32,529 bytes allocated
==1005844==
==1005844== 136 (104 direct, 32 indirect) bytes in 1 blocks are definitely lost in loss record 12 of 14
==1005844==    at 0x483885A: calloc (vg_replace_malloc.c:760)
==1005844==    by 0x48C950D: g_malloc0 (gmem.c:132)
==1005844==    by 0x100EC41: pv_args_new (pv_args.c:364)
==1005844==    by 0x100587F: main (genprotimg.c:122)
==1005844==
==1005844== LEAK SUMMARY:
==1005844==    definitely lost: 104 bytes in 1 blocks
==1005844==    indirectly lost: 32 bytes in 1 blocks
==1005844==      possibly lost: 0 bytes in 0 blocks
==1005844==    still reachable: 18,771 bytes in 12 blocks
==1005844==         suppressed: 0 bytes in 0 blocks
==1005844== Reachable blocks (those to which a pointer was found) are not shown.
==1005844== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1005844==
==1005844== For lists of detected and suppressed errors, rerun with: -s
==1005844== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-06 16:18:21 +01:00
Marc Hartmayer
6db7fbe018 genprotimg: abort if one of the recursive targets is failing
Abort compilation as soon as one of the recursive targets is failing.

Fixes: 65b9fc442c ("genprotimg: introduce new tool for the creation of PV images")
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-06 16:18:21 +01:00
Sven Schnelle
2f154fa49d cmsfs-fuse: fix pointer block level calculation
Adding one to the pointer per block value results in a wrong
calculation of pointer block levels. When writing a file that
would result in about 454MB size, the code would calculate that
it needs a two level pointer directory but correct would be a three
level pointer directory. This causes an invalid filesystem state:
besides missing all the records of one top level pointer directory
entry, it would also record a higher record number in the FST than
what is present in the pointer blocks.

Note that this bug only hits when the file is about 454MB and the write
is stopped (means the file is closed) - if file writing continues the
problem doesn't happen because at some point in time cmsfs-fuse would
switch to three levels of pointer blocks anyways as the file grows.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-06 16:18:21 +01:00
Jan Höppner
148d3f9b64 dasdfmt: Fix segfault when an incorrect option is specified
When specifying an incorrect program option, dasdfmt segfaults as the
format string for the corresponding error message has no parameter.
Add the missing parameter to fix this.

Fixes: 732b3dddab ("dasdfmt: Replace ERRMSG_EXIT macro with an error handling function")
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-03 09:05:29 +01:00
Brian C. Lane
702dc96264 netboot: Clear kernel cmdline data before writing new parmfile
If this isn't cleared first it can end up with an unexpected cmdline if
it doesn't completely overwrite the default data.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/95
Reviewed-by: Viktor Mihajlovski <mihajlov@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-03 09:05:29 +01:00
Jan Höppner
313092b202 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-11-03 09:05:29 +01:00
40 changed files with 2636 additions and 120 deletions

View File

@@ -1,5 +1,15 @@
Release history for s390-tools (MIT version)
--------------------------------------------
* __v2.15.x (2020-xx-xx)__
For Linux kernel version: 5.x
Changes of existing tools:
- hsci: New tool to manage HSCI interfaces
- genprotimg: Add host-key document verification support
Bug Fixes:
* __v2.15.1 (2020-10-28)__
For Linux kernel version: 5.9

View File

@@ -9,7 +9,7 @@ TOOL_DIRS = zipl zdump fdasd dasdfmt dasdview tunedasd \
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 lsstp
genprotimg lsstp hsci
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)

View File

@@ -249,6 +249,9 @@ Package contents
Management Foundation - Web Edition, and is used to manage keys in an
enterprise.
* hsci:
Manage HiperSockets Converged Interfaces (HSCI).
For more information refer to the following publications:
* "Device Drivers, Features, and Commands" chapter "Useful Linux commands"
@@ -277,7 +280,7 @@ build options:
| cryptsetup | `HAVE_CRYPTSETUP2` | zkey-cryptsetup |
| json-c | `HAVE_JSONC` | zkey-cryptsetup, libekmfweb |
| glib2 | `HAVE_GLIB2` | genprotimg |
| libcurl | `HAVE_LIBCURL` | libekmfweb |
| libcurl | `HAVE_LIBCURL` | genprotimg, libekmfweb |
This table lists additional build or install options:

View File

@@ -2050,7 +2050,7 @@ static int update_dir_levels(int blocks)
if (blocks < 2)
return 0;
while (blocks / (PTRS_PER_BLOCK + 1)) {
while (blocks / PTRS_PER_BLOCK) {
levels++;
blocks /= PTRS_PER_BLOCK;
}
@@ -3103,7 +3103,7 @@ static void update_levels(struct file *f)
return;
}
while (blocks / (per_block + 1)) {
while (blocks / per_block) {
levels++;
blocks /= per_block;
}

View File

@@ -366,9 +366,9 @@ install: install_echo install_dirs
clean_echo:
$(call echocmd," CLEAN ")
clean_gcov:
rm -f *.gcda *.gcno *.gcov
rm -f -- *.gcda *.gcno *.gcov
clean_dep:
rm -f .*.o.d
rm -f -- .*.o.d
clean: clean_echo clean_gcov clean_dep
endif

View File

@@ -91,13 +91,18 @@ static int read_sfb(unsigned long *min, unsigned long *max)
int rc = EXIT_SUCCESS;
FILE *fp;
if (geteuid()) {
fprintf(stderr, "Error: Must run as root\n");
return EXIT_FAILURE;
}
fp = fopen(PERF_SFB_SIZE, "r");
if (fp == NULL) {
linux_error(PERF_SFB_SIZE);
return EXIT_FAILURE;
}
if (fscanf(fp, "%ld,%ld", &cur_min_sdb, &cur_max_sdb) != 2) {
fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE);
fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE
"\n");
rc = EXIT_FAILURE;
} else {
if (*min == 0)

View File

@@ -2572,6 +2572,7 @@ static const char *machine_name(void)
case 3906: return "IBM z14";
case 3907: return "IBM z14 ZR1";
case 8561: return "IBM z15";
case 8562: return "IBM z15 Model T02";
}
return "Unknown hardware model";
}
@@ -3094,11 +3095,11 @@ int main(int argc, char **argv)
util_prg_init(&prg);
util_opt_init(opt_vec, NULL);
ret = read_info();
if (ret == EXIT_FAILURE)
return ret;
ret = parse_args(argc, argv);
if (read_info() == EXIT_FAILURE)
return EXIT_FAILURE;
switch ((ret = parse_args(argc, argv))) {
switch (ret) {
case ACTION_CNT:
case ACTION_CNTALL:
all = ret == ACTION_CNTALL;
@@ -3114,6 +3115,7 @@ int main(int argc, char **argv)
case ACTION_NONE:
case ACTION_INFO:
show_info(&cpumf, ret == ACTION_INFO);
ret = EXIT_SUCCESS;
break;
}
return ret;

View File

@@ -1637,7 +1637,7 @@ int main(int argc, char *argv[])
/* End of options string - start of devices list */
break;
default:
error("Try '%s --help' for more information.");
error("Try '%s --help' for more information.", prog_name);
}
if (rc == -1)

View File

@@ -41,6 +41,10 @@ static const char mode_str[3][10] = {
"Full", "Quick", "Expand"
};
/* Report error, free memory, and exit */
static void error(const char *format, ...)
__attribute__((__noreturn__, __format__(__printf__, 1, 2)));
#define DASD_PARTN_BITS 2
#define PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)

View File

@@ -21,7 +21,7 @@ clean: clean-recursive
$(RECURSIVE_TARGETS):
@target=`echo $@ |sed s/-recursive//`; \
for d in $(SUBDIRS); do \
$(MAKE) -C $$d $$target; \
$(MAKE) -C $$d $$target || exit 1; \
done
.PHONY: all install clean $(RECURSIVE_TARGETS)

View File

@@ -2,7 +2,7 @@
.\" 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 GENPROTIMG 8 "March 2020" "s390-tools"
.TH GENPROTIMG 8 "November 2020" "s390-tools"
.SH NAME
genprotimg \- Create a protected virtualization image
@@ -10,6 +10,7 @@ genprotimg \- Create a protected virtualization image
.SY
.B genprotimg
\fB\-k\fR \fIHOST_KEY_DOCUMENT\fR...
\fB\-C\fR \fICERTIFICATE\fR...
\fB\-i\fR \fIVMLINUZ\fR
[\fB\-r\fR \fIRAMDISK\fR]
[\fB\-p\fR \fIPARMFILE\fR]
@@ -21,15 +22,19 @@ genprotimg \- Create a protected virtualization image
.PP
Use \fBgenprotimg\fR to generate a single bootable image file with
encrypted and integrity-protected parts. The command requires a kernel
image, a host-key document, and an output file name. Optionally,
specify an initial RAM filesystem, and a file containing the kernel
parameters. Should special circumstances require it, you can
image, a host-key document, certificates for the host-key document
verification, and an output file name. Optionally, specify an initial
RAM filesystem, and a file containing the kernel parameters. If the
command should be run offline, use the \fB\-\-offline\fR option and
specify the certificate revocation lists (CRLs) by using the
\fB\-\-crl\fR option. Should special circumstances require it, you can
optionally specify your own keys for the encryption by using the
experimental options. In the resulting image file, a plain text boot
loader, the encrypted components for kernel, initial RAM disk, kernel
parameters, and the encrypted and integrity-protected header are
concatenated. The header contains metadata necessary for running the
guest in protected mode.
experimental options. For all certificates, CRLs, and host-key
documents, both the PEM and DER input formats are supported. In the
resulting image file, a plain text boot loader, the encrypted
components for kernel, initial RAM disk, kernel parameters, and the
encrypted and integrity-protected header are concatenated. The header
contains metadata necessary for running the guest in protected mode.
.PP
Use this image file as a kernel image for zipl or for a direct kernel
boot using QEMU.
@@ -53,6 +58,12 @@ Specifies a host-key document. At least one is required. Specify this
option multiple times to enable the image to run on more than one
host.
.TP
\fB\-C\fR, \fB\-\-cert\fR=\fI\,FILE\/\fR
Specifies the certificate that is used to establish a chain of trust
for the verification of the host-key documents. Specify this option
twice to specify the IBM Z signing key and the intermediate CA
certificate (signed by the root CA). Required.
.TP
\fB\-o\fR, \fB\-\-output\fR=\fI\,OUTPUT_FILE\/\fR
Specifies the output file. Required.
.TP
@@ -65,6 +76,20 @@ Specifies the RAM disk image. Optional.
\fB\-p\fR, \fB\-\-parmfile\fR=\fI\,PARMFILE\/\fR
Specifies the kernel command line stored in \fI\,PARMFILE\/\fR. Optional.
.TP
\fB\-\-crl\fR=\fI\,FILE\/\fR
Specifies the revocation list that is used to check whether a
certificate of the chain of trust is revoked. Specify this option
multiple times to use multiple CRLs. Optional.
.TP
\fB\-\-offline\fR
Specifies offline mode, in which no attempt is made to download
CRLs. Optional.
.TP
\fB\-\-root\-ca\fR=\fI\,FILE\/\fR
Specifies the root CA certificate for the verification. If omitted,
the DigiCert root CA certificate installed on the system is used. Use
this only if you trust the specified certificate. Optional.
.TP
\fB\-\-no-verify\fR
Do not require the host-key documents to be valid. For testing
purposes, do not use for a production image. Optional.
@@ -77,11 +102,13 @@ Prints version information, then exits.
Generate a protected virtualization image in
\fI\,/boot/vmlinuz.pv\/\fR, using the kernel file \fI\,vmlinuz\/\fR,
the initrd in \fI\,initramfs\/\fR, the kernel parameters contained in
\fI\,parmfile\/\fR, and the host-key document in \fI\,host_key.crt\/\fR:
\fI\,parmfile\/\fR, the intermediate CA in \fI\,DigiCertCA.crt\/\fR,
the IBM Z signing key in \fI\,ibm-z-host-key-signing.crt\/\fR, and the
host-key document in \fI\,host_key.crt\/\fR:
.PP
.Vb 1
.EX
\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-o \fI\,/boot/vmlinuz.pv\/\fR
\& genprotimg \-i \fI\,vmlinuz\/\fR \-r \fI\,initramfs\/\fR \-p \fI\,parmfile\/\fR \-k \fI\,host_key.crt\/\fR \-C \fI\,ibm-z-host-key-signing.crt\/\fR \-C \fI\,DigiCertCA.crt \-o \fI\,/boot/vmlinuz.pv\/\fR
.EE
.Ve
.PP

View File

@@ -23,16 +23,16 @@ WARNINGS := -Wall -Wextra -Wshadow \
$(bin_PROGRAM)_SRCS := $(bin_PROGRAM).c pv/pv_stage3.c pv/pv_image.c \
pv/pv_comp.c pv/pv_hdr.c pv/pv_ipib.c utils/crypto.c utils/file_utils.c \
pv/pv_args.c utils/buffer.c pv/pv_comps.c pv/pv_error.c \
pv/pv_opt_item.c \
pv/pv_opt_item.c utils/curl.c \
$(NULL)
$(bin_PROGRAM)_OBJS := $($(bin_PROGRAM)_SRCS:.c=.o)
ALL_CFLAGS += -std=gnu11 -DPKGDATADIR=$(PKGDATADIR) \
$(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) \
$(GLIB2_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBCURL_CFLAGS) \
$(WARNINGS) \
$(NULL)
ALL_CPPFLAGS += $(INCLUDE_PARMS)
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS)
LDLIBS += $(GLIB2_LIBS) $(LIBCRYPTO_LIBS) $(LIBCURL_LIBS)
ifneq ($(shell sh -c 'command -v pkg-config'),)
@@ -40,21 +40,27 @@ GLIB2_CFLAGS := $(shell pkg-config --silence-errors --cflags glib-2.0)
GLIB2_LIBS := $(shell pkg-config --silence-errors --libs glib-2.0)
LIBCRYPTO_CFLAGS := $(shell pkg-config --silence-errors --cflags libcrypto)
LIBCRYPTO_LIBS := $(shell pkg-config --silence-errors --libs libcrypto)
LIBCURL_CFLAGS := $(shell pkg-config --silence-errors --cflags libcurl)
LIBCURL_LIBS := $(shell pkg-config --silence-errors --libs libcurl)
else
GLIB2_CFLAGS := -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include
GLIB2_LIBS := -lglib-2.0
LIBCRYPTO_CFLAGS :=
LIBCRYPTO_LIBS := -lcrypto
LIBCURL_CFLAGS :=
LIBCURL_LIBS := -lcurl
endif
BUILD_TARGETS := skip-$(bin_PROGRAM)
INSTALL_TARGETS := skip-$(bin_PROGRAM)
ifneq (${HAVE_OPENSSL},0)
ifneq (${HAVE_GLIB2},0)
ifneq (${HAVE_LIBCURL},0)
BUILD_TARGETS := $(bin_PROGRAM)
INSTALL_TARGETS := install-$(bin_PROGRAM)
endif
endif
endif
all: $(BUILD_TARGETS)
@@ -98,4 +104,9 @@ $($(bin_PROGRAM)_OBJS): .check-dep-$(bin_PROGRAM)
"openssl-devel / libssl-dev version >= 1.1.0", \
"HAVE_OPENSSL=0", \
"-I.")
$(call check_dep, \
"$(bin_PROGRAM)", \
"curl/curl.h", \
"libcurl-devel", \
"HAVE_LIBCURL=0")
touch $@

View File

@@ -18,6 +18,8 @@
#include "common.h"
#include "pv/pv_args.h"
#include "pv/pv_image.h"
#include "utils/crypto.h"
#include "utils/curl.h"
enum {
LOG_LEVEL_CRITICAL = 0,
@@ -117,6 +119,8 @@ static void remove_signal_handler(const gint *signals, const gsize signals_n)
signal(signals[i], SIG_DFL);
}
static void __attribute__((constructor)) __init(void);
static void __attribute__((destructor)) __cleanup(void);
gint main(gint argc, gchar *argv[])
{
g_autoptr(PvArgs) args = pv_args_new();
@@ -177,5 +181,20 @@ error:
rmdir_recursive(tmp_dir, NULL);
remove_signal_handler(signals, G_N_ELEMENTS(signals));
g_free(tmp_dir);
g_clear_pointer(&img, pv_img_free);
g_clear_pointer(&args, pv_args_free);
exit(ret);
}
static void __init(void)
{
pv_crypto_init();
if (curl_init() != 0)
g_abort();
}
static void __cleanup(void)
{
curl_cleanup();
pv_crypto_cleanup();
}

View File

@@ -14,6 +14,24 @@
#include "lib/zt_common.h"
/* IBM signing key subject */
#define PV_IBM_Z_SUBJECT_COMMON_NAME "International Business Machines Corporation"
#define PV_IBM_Z_SUBJECT_COUNTRY_NAME "US"
#define PV_IBM_Z_SUBJECT_LOCALITY_NAME "Poughkeepsie"
#define PV_IBM_Z_SUBJECT_ORGANIZATIONONAL_UNIT_NAME_SUFFIX "Key Signing Service"
#define PV_IBM_Z_SUBJECT_ORGANIZATION_NAME "International Business Machines Corporation"
#define PV_IBM_Z_SUBJECT_STATE "New York"
#define PV_IMB_Z_SUBJECT_ENTRY_COUNT 6
/* Minimum security level for the keys/certificates used to establish a chain of
* trust (see https://www.openssl.org/docs/man1.1.1/man3/X509_VERIFY_PARAM_set_auth_level.html
* for details).
*/
#define PV_CERTS_SECURITY_LEVEL 2
/* SKID for DigiCert Assured ID Root CA */
#define DIGICERT_ASSURED_ID_ROOT_CA_SKID "45EBA2AFF492CB82312D518BA7A7219DF36DC80F"
union ecdh_pub_key {
struct {
uint8_t x[80];

View File

@@ -18,7 +18,9 @@
static gchar summary[] =
"Use genprotimg to create a protected virtualization kernel image file,\n"
"which can be loaded using zipl or QEMU.";
"which can be loaded using zipl or QEMU. For all certificates, revocation\n"
"lists, and host-key documents, both the PEM and DER input formats are\n"
"supported.";
static gint pv_arg_compare(gconstpointer arg_1, gconstpointer arg_2)
{
@@ -97,9 +99,14 @@ static gint pv_args_validate_options(PvArgs *args, GError **err)
return -1;
}
if (!args->no_verify) {
g_set_error(err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
_("Use the option '--no-verify' as the verification support is not available yet."));
if (!args->no_verify &&
(!args->untrusted_cert_paths ||
g_strv_length(args->untrusted_cert_paths) == 0)) {
g_set_error(
err, PV_PARSE_ERROR, PR_PARSE_ERROR_MISSING_ARGUMENT,
_("Either specify the IBM Z signing key and (DigiCert) intermediate CA certificate\n"
"by using the '--cert' option, or use the '--no-verify' flag to disable the\n"
"host-key document verification completely (at your own risk)."));
return -1;
}
@@ -141,6 +148,8 @@ static gboolean cb_set_string_option(const gchar *option, const gchar *value,
{
gchar **args_option = NULL;
if (g_str_equal(option, "--root-ca"))
args_option = &args->root_ca_path;
if (g_str_equal(option, "-o") || g_str_equal(option, "--output"))
args_option = &args->output_path;
if (g_str_equal(option, "--x-comp-key"))
@@ -211,6 +220,18 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
_("FILE specifies a host-key document. At least\n" INDENT
"one is required."),
.arg_description = _("FILE") },
{ .long_name = "cert",
.short_name = 'C',
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_FILENAME_ARRAY,
.arg_data = &args->untrusted_cert_paths,
.description = _(
"FILE contains a certificate that is used to\n" INDENT
"establish a chain of trust for the verification\n" INDENT
"of the host-key documents. The IBM Z signing\n" INDENT
"key and intermediate CA certificate (signed\n" INDENT
"by the root CA) are required."),
.arg_description = _("FILE") },
{ .long_name = "output",
.short_name = 'o',
.flags = G_OPTION_FLAG_FILENAME,
@@ -227,7 +248,7 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
.arg_description = _("IMAGE") },
{ .long_name = "ramdisk",
.short_name = 'r',
.flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_add_component,
.description = _("Use RAMDISK as the initial RAM disk\n" INDENT
@@ -235,12 +256,37 @@ gint pv_args_parse_options(PvArgs *args, gint *argc, gchar **argv[],
.arg_description = _("RAMDISK") },
{ .long_name = "parmfile",
.short_name = 'p',
.flags = G_OPTION_FLAG_OPTIONAL_ARG | G_OPTION_FLAG_FILENAME,
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_add_component,
.description = _("Use the kernel parameters stored in PARMFILE\n" INDENT
"(optional)."),
.arg_description = _("PARMFILE") },
{ .long_name = "crl",
.short_name = 0,
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_FILENAME_ARRAY,
.arg_data = &args->crl_paths,
.description = _(
"FILE contains a certificate revocation list\n" INDENT
"(optional)."),
.arg_description = _("FILE") },
{ .long_name = "offline",
.short_name = 0,
.flags = G_OPTION_FLAG_NONE,
.arg = G_OPTION_ARG_NONE,
.arg_data = &args->offline,
.description = _("Don't download CRLs (optional)."),
.arg_description = NULL },
{ .long_name = "root-ca",
.short_name = 0,
.flags = G_OPTION_FLAG_FILENAME,
.arg = G_OPTION_ARG_CALLBACK,
.arg_data = cb_set_string_option,
.description = _(
"Set FILE as the trusted root CA and don't use the\n" INDENT
"root CAs that are installed on the system (optional)."),
.arg_description = _("FILE") },
{ .long_name = "no-verify",
.short_name = 0,
.flags = G_OPTION_FLAG_NONE,
@@ -378,6 +424,9 @@ void pv_args_free(PvArgs *args)
g_free(args->cust_root_key_path);
g_free(args->cust_comm_key_path);
g_free(args->gcm_iv_path);
g_free(args->root_ca_path);
g_strfreev(args->crl_paths);
g_strfreev(args->untrusted_cert_paths);
g_strfreev(args->host_keys);
g_free(args->xts_key_path);
g_slist_free_full(args->comps, (GDestroyNotify)pv_arg_free);

View File

@@ -25,6 +25,7 @@ void pv_arg_free(PvArg *arg);
typedef struct {
gint log_level;
gint no_verify;
gboolean offline;
gchar *pcf;
gchar *scf;
gchar *psw_addr; /* PSW address which will be used for the start of
@@ -34,6 +35,11 @@ typedef struct {
gchar *cust_comm_key_path;
gchar *gcm_iv_path;
gchar **host_keys;
gchar *root_ca_path; /* Trusted root CA used for the verification of the
* chain of trust (if specified).
*/
gchar **untrusted_cert_paths;
gchar **crl_paths;
gchar *xts_key_path;
GSList *comps;
gchar *output_path;

View File

@@ -28,6 +28,8 @@ typedef enum {
PV_ERROR_IPIB_SIZE,
PV_ERROR_PV_HDR_SIZE,
PV_ERROR_INTERNAL,
PV_ERROR_CURL_INIT_FAILED,
PV_ERROR_DOWNLOAD_FAILED,
} PvErrors;
typedef enum {
@@ -57,6 +59,31 @@ typedef enum {
PV_CRYPTO_ERROR_RANDOMIZATION,
PV_CRYPTO_ERROR_INVALID_PARM,
PV_CRYPTO_ERROR_INVALID_KEY_SIZE,
PV_CRYPTO_ERROR_INVALID_VALIDITY_PERIOD,
PV_CRYPTO_ERROR_EXPIRED,
PV_CRYPTO_ERROR_NOT_VALID_YET,
PV_CRYPTO_ERROR_LOAD_CRL,
PV_CRYPTO_ERROR_NO_PUBLIC_KEY,
PV_CRYPTO_ERROR_INVALID_SIGNATURE_ALGORITHM,
PV_CRYPTO_ERROR_SIGNATURE_ALGORITHM_MISMATCH,
PV_CRYPTO_ERROR_INVALID_URI,
PV_CRYPTO_ERROR_CRL_DOWNLOAD_FAILED,
PV_CRYPTO_ERROR_CERT_SIGNATURE_INVALID,
PV_CRYPTO_ERROR_CRL_SIGNATURE_INVALID,
PV_CRYPTO_ERROR_CERT_SUBJECT_ISSUER_MISMATCH,
PV_CRYPTO_ERROR_CRL_SUBJECT_ISSUER_MISMATCH,
PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
PV_CRYPTO_ERROR_MALFORMED_CERTIFICATE,
PV_CRYPTO_ERROR_NO_CRL,
PV_CRYPTO_ERROR_LOAD_ROOT_CA,
PV_CRYPTO_ERROR_LOAD_DEFAULT_CA,
PV_CRYPTO_ERROR_MALFORMED_ROOT_CA,
PV_CRYPTO_ERROR_WRONG_CA_USED,
PV_CRYPTO_ERROR_SKID_AKID_MISMATCH,
PV_CRYPTO_ERROR_NO_ISSUER_IBM_Z_FOUND,
PV_CRYPTO_ERROR_FAILED_DOWNLOAD_CRL,
PV_CRYPTO_ERROR_NO_CRLDP,
PV_CRYPTO_ERROR_CERT_REVOKED,
} PvCryptoErrors;
#endif

View File

@@ -10,6 +10,7 @@
#include <errno.h>
#include <glib.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -138,22 +139,18 @@ static EVP_PKEY *pv_img_get_cust_pub_priv_key(gint nid, GError **err)
return generate_ec_key(nid, err);
}
static HostKeyList *pv_img_get_host_keys(gchar **host_cert_paths,
X509_STORE *store, gint nid,
static HostKeyList *pv_img_get_host_keys(GSList *host_keys_with_path, gint nid,
GError **err)
{
g_autoslist(EVP_PKEY) ret = NULL;
g_assert(host_cert_paths);
for (gchar **iterator = host_cert_paths; iterator != NULL && *iterator != NULL;
iterator++) {
for (GSList *iterator = host_keys_with_path; iterator;
iterator = iterator->next) {
x509_with_path *cert_with_path = iterator->data;
g_autoptr(EVP_PKEY) host_key = NULL;
const gchar *path = *iterator;
X509 *cert = cert_with_path->cert;
g_assert(path);
host_key = read_ec_pubkey_cert(store, nid, path, err);
host_key = read_ec_pubkey_cert(cert, nid, err);
if (!host_key)
return NULL;
@@ -253,10 +250,172 @@ static gint pv_img_set_control_flags(PvImage *img, const gchar *pcf_s,
return 0;
}
static gint pv_img_hostkey_verify(GSList *host_key_certs,
const gchar *root_ca_path,
const gchar *const *crl_paths,
const gchar *const *untrusted_cert_paths,
gboolean offline, GError **err)
{
g_autoslist(x509_with_path) untrusted_certs_with_path = NULL;
g_autoptr(STACK_OF_X509) ibm_signing_certs = NULL;
g_autoptr(STACK_OF_X509) untrusted_certs = NULL;
g_autoslist(x509_pair) ibm_z_pairs = NULL;
g_autoptr(X509_STORE) trusted = NULL;
gint ibm_signing_certs_count;
/* Load trusted root CAs of the system if and only if @root_ca_path is
* NULL, otherwise use the root CA specified by @root_ca_path.
*/
trusted = store_setup(root_ca_path, crl_paths, err);
if (!trusted)
goto error;
if (!offline) {
g_autoptr(STACK_OF_X509_CRL) downloaded_ibm_signing_crls = NULL;
/* Set up the download routine for the lookup of CRLs. */
store_setup_crl_download(trusted);
/* Try to download the CRLs of the IBM Z signing certificates
* specified in the host-key documents. Ignore download errors
* as it's still possible that a CRL is specified via command
* line.
*/
downloaded_ibm_signing_crls = try_load_crls_by_certs(host_key_certs);
/* Add the downloaded CRLs to the store so they can be used for
* the verification later.
*/
for (int i = 0; i < sk_X509_CRL_num(downloaded_ibm_signing_crls); i++) {
X509_CRL *crl = sk_X509_CRL_value(downloaded_ibm_signing_crls, i);
if (X509_STORE_add_crl(trusted, crl) != 1) {
g_set_error(err, PV_CRYPTO_ERROR,
PV_CRYPTO_ERROR_INTERNAL,
_("failed to load CRL"));
goto error;
}
}
}
/* Load all untrusted certificates (e.g. IBM Z signing key and
* DigiCert intermediate CA) that are required to establish a chain of
* trust starting from the host-key document up to the root CA (if not
* otherwise specified that's the DigiCert Assured ID Root CA).
*/
untrusted_certs_with_path = load_certificates(untrusted_cert_paths, err);
if (!untrusted_certs_with_path)
goto error;
/* Convert to STACK_OF(X509) */
untrusted_certs = get_x509_stack(untrusted_certs_with_path);
/* Find all IBM Z signing keys and remove them from the chain as we
* have to verify that they're valid. The last step of the chain of
* trust verification must be done manually, as the IBM Z signing keys
* are not marked as (intermediate) CA and therefore the standard
* `X509_verify_cert` function of OpenSSL cannot be used to verify the
* actual host-key documents.
*/
ibm_signing_certs = delete_ibm_signing_certs(untrusted_certs);
ibm_signing_certs_count = sk_X509_num(ibm_signing_certs);
if (ibm_signing_certs_count < 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
_("please specify at least one IBM Z signing key"));
goto error;
} else if (ibm_signing_certs_count > 1) {
g_set_error(err, PV_CRYPTO_ERROR, PV_CRYPTO_ERROR_NO_IBM_Z_SIGNING_KEY,
_("please specify only one IBM Z signing key"));
goto error;
}
if (store_set_verify_param(trusted, err) < 0)
goto error;
/* Verify that the IBM Z signing keys are trustable.
* For this we must check:
*
* 1. Can a chain of trust be established ending in a root CA
* 2. Is the correct root CA ued? It has either to be the
* 'DigiCert Assured ID Root CA' or the root CA specified via
* command line.
*/
for (gint i = 0; i < sk_X509_num(ibm_signing_certs); ++i) {
X509 *ibm_signing_cert = sk_X509_value(ibm_signing_certs, i);
g_autoptr(STACK_OF_X509_CRL) ibm_signing_crls = NULL;
g_autoptr(X509_STORE_CTX) ctx = NULL;
x509_pair *pair = NULL;
g_assert(ibm_signing_cert);
/* Create the verification context and set the trusted
* and chain parameters.
*/
ctx = create_store_ctx(trusted, untrusted_certs, err);
if (!ctx)
goto error;
/* Verify the IBM Z signing key */
if (verify_cert(ibm_signing_cert, ctx, err) < 0)
goto error;
/* Verify the build chain of trust chain. If the user passes a
* trusted root CA on the command line then the check for the
* Subject Key Identifier (SKID) is skipped, otherwise let's
* check if the SKID meets our expectation.
*/
if (!root_ca_path &&
check_chain_parameters(X509_STORE_CTX_get0_chain(ctx),
get_digicert_assured_id_root_ca_skid(),
err) < 0) {
goto error;
}
ibm_signing_crls = store_ctx_find_valid_crls(ctx, ibm_signing_cert, err);
if (!ibm_signing_crls) {
g_prefix_error(err, _("IBM Z signing key: "));
goto error;
}
/* Increment reference counter of @ibm_signing_cert as the
* certificate will now also be owned by @ibm_z_pairs.
*/
if (X509_up_ref(ibm_signing_cert) != 1)
g_abort();
pair = x509_pair_new(&ibm_signing_cert, &ibm_signing_crls);
ibm_z_pairs = g_slist_append(ibm_z_pairs, pair);
g_assert(!ibm_signing_cert);
g_assert(!ibm_signing_crls);
}
/* Verify host-key documents by using the IBM Z signing
* certificates and the corresponding certificate revocation
* lists.
*/
for (GSList *iterator = host_key_certs; iterator; iterator = iterator->next) {
x509_with_path *host_key_with_path = iterator->data;
const gchar *host_key_path = host_key_with_path->path;
X509 *host_key = host_key_with_path->cert;
gint flags = X509_V_FLAG_CRL_CHECK;
if (verify_host_key(host_key, ibm_z_pairs, flags,
PV_CERTS_SECURITY_LEVEL, err) < 0) {
g_prefix_error(err, "'%s': ", host_key_path);
goto error;
}
}
return 0;
error:
g_prefix_error(err, _("Failed to verify host-key document: "));
return -1;
}
/* read in the keys or auto-generate them */
static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err)
{
g_autoptr(X509_STORE) store = NULL;
g_autoslist(x509_with_path) host_key_certs = NULL;
g_assert(img->xts_cipher);
g_assert(img->cust_comm_cipher);
@@ -285,8 +444,25 @@ static gint pv_img_set_keys(PvImage *img, const PvArgs *args, GError **err)
if (!img->cust_pub_priv_key)
return -1;
/* Load all host-key documents specified on the command line */
host_key_certs = load_certificates((const gchar **)args->host_keys,
err);
if (!host_key_certs)
return -1;
if (!args->no_verify &&
pv_img_hostkey_verify(host_key_certs, args->root_ca_path,
(const gchar * const *)args->crl_paths,
(const gchar * const *)args->untrusted_cert_paths,
args->offline, err) < 0) {
return -1;
}
/* Loads the public keys stored in the host-key documents and verify
* that the correct elliptic curve is used.
*/
img->host_pub_keys =
pv_img_get_host_keys(args->host_keys, store, img->nid, err);
pv_img_get_host_keys(host_key_certs, img->nid, err);
if (!img->host_pub_keys)
return -1;
@@ -406,6 +582,9 @@ PvImage *pv_img_new(PvArgs *args, const gchar *stage3a_path, GError **err)
if (args->no_verify)
g_warning(_("host-key document verification is disabled. Your workload is not secured."));
if (args->root_ca_path)
g_warning(_("A different root CA than the default DigiCert root CA is selected. Ensure that this root CA is trusted."));
ret->comps = pv_img_comps_new(EVP_sha512(), EVP_sha512(), EVP_sha512(), err);
if (!ret->comps)
return NULL;

File diff suppressed because it is too large Load Diff

View File

@@ -11,14 +11,18 @@
#define PV_UTILS_CRYPTO_H
#include <glib.h>
#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/evp.h>
#include <openssl/ossl_typ.h>
#include <openssl/rand.h>
#include <openssl/safestack.h>
#include <openssl/sha.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <stdint.h>
#include "common.h"
@@ -33,6 +37,9 @@
#define AES_256_XTS_TWEAK_SIZE 16
#define AES_256_XTS_KEY_SIZE 64
#define CRL_DOWNLOAD_TIMEOUT_MS 3000
#define CRL_DOWNLOAD_MAX_SIZE (1024 * 1024) /* in bytes */
enum PvCryptoMode {
PV_ENCRYPT,
PV_DECRYPT,
@@ -40,7 +47,34 @@ enum PvCryptoMode {
typedef GSList HostKeyList;
/* play nice with g_autoptr */
typedef STACK_OF(DIST_POINT) STACK_OF_DIST_POINT;
typedef STACK_OF(X509) STACK_OF_X509;
typedef STACK_OF(X509_CRL) STACK_OF_X509_CRL;
void STACK_OF_DIST_POINT_free(STACK_OF_DIST_POINT *stack);
void STACK_OF_X509_free(STACK_OF_X509 *stack);
void STACK_OF_X509_CRL_free(STACK_OF_X509_CRL *stack);
typedef struct {
X509 *cert;
const gchar *path;
} x509_with_path;
x509_with_path *x509_with_path_new(X509 *cert, const gchar *path);
void x509_with_path_free(x509_with_path *cert);
typedef struct {
X509 *cert;
STACK_OF_X509_CRL *crls;
} x509_pair;
x509_pair *x509_pair_new(X509 **cert, STACK_OF_X509_CRL **crls);
void x509_pair_free(x509_pair *pair);
/* Register auto cleanup functions */
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_INTEGER, ASN1_INTEGER_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(ASN1_OCTET_STRING, ASN1_OCTET_STRING_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIGNUM, BN_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BIO, BIO_free_all)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(BN_CTX, BN_CTX_free)
@@ -51,10 +85,18 @@ WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_MD_CTX, EVP_MD_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY, EVP_PKEY_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(EVP_PKEY_CTX, EVP_PKEY_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_DIST_POINT, STACK_OF_DIST_POINT_free);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509, STACK_OF_X509_free);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(STACK_OF_X509_CRL, STACK_OF_X509_CRL_free);
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509, X509_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_CRL, X509_CRL_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_LOOKUP, X509_LOOKUP_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_NAME, X509_NAME_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_pair, x509_pair_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE, X509_STORE_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_STORE_CTX, X509_STORE_CTX_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free)
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(x509_with_path, x509_with_path_free)
union cmp_index {
struct {
@@ -79,8 +121,37 @@ struct cipher_parms {
const Buffer *iv_or_tweak;
};
EVP_PKEY *read_ec_pubkey_cert(X509_STORE *store, gint nid, const gchar *path,
GError **err);
int check_crl_valid_for_cert(X509_CRL *crl, X509 *cert,
gint verify_flags, GError **err);
void pv_crypto_init(void);
void pv_crypto_cleanup(void);
const ASN1_OCTET_STRING *get_digicert_assured_id_root_ca_skid(void);
gint verify_host_key(X509 *host_key, GSList *issuer_pairs,
gint verify_flags, int level, GError **err);
X509 *load_cert_from_file(const char *path, GError **err);
X509_CRL *load_crl_from_file(const gchar *path, GError **err);
GSList *load_certificates(const gchar *const *cert_paths, GError **err);
STACK_OF_X509 *get_x509_stack(const GSList *x509_with_path_list);
X509_STORE *store_setup(const gchar *root_ca_path,
const gchar * const *crl_paths,
GError **err);
int store_set_verify_param(X509_STORE *store, GError **err);
X509_CRL *load_crl_by_cert(X509 *cert, GError **err);
STACK_OF_X509_CRL *try_load_crls_by_certs(GSList *certs_with_path);
gint check_chain_parameters(const STACK_OF_X509 *chain,
const ASN1_OCTET_STRING *skid, GError **err);
X509_NAME *c2b_name(const X509_NAME *name);
STACK_OF_X509 *delete_ibm_signing_certs(STACK_OF_X509 *certs);
STACK_OF_X509_CRL *store_ctx_find_valid_crls(X509_STORE_CTX *ctx, X509 *cert,
GError **err);
X509_STORE_CTX *create_store_ctx(X509_STORE *trusted, STACK_OF_X509 *chain,
GError **err);
gint verify_cert(X509 *cert, X509_STORE_CTX *ctx, GError **err);
X509_CRL *get_first_valid_crl(X509_STORE_CTX *ctx, X509 *cert, GError **err);
void store_setup_crl_download(X509_STORE *st);
EVP_PKEY *read_ec_pubkey_cert(X509 *cert, gint nid, GError **err);
Buffer *compute_exchange_key(EVP_PKEY *cust, EVP_PKEY *host, GError **err);
Buffer *generate_aes_key(guint size, GError **err);
Buffer *generate_aes_iv(guint size, GError **err);

121
genprotimg/src/utils/curl.c Normal file
View File

@@ -0,0 +1,121 @@
/*
* Libcurl utils
*
* 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.
*/
#include <stdio.h>
#include <glib.h>
#include <glib/gtypes.h>
#include <curl/curl.h>
#include "lib/zt_common.h"
#include "pv/pv_error.h"
#include "curl.h"
struct UserData {
GByteArray *buffer;
guint max_size;
};
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
g_assert(userdata);
struct UserData *data = (struct UserData *)userdata;
GByteArray *buffer = data->buffer;
guint64 actual_size;
size_t err;
g_assert(buffer);
if (!g_uint64_checked_mul(&actual_size, size, nmemb))
g_abort();
/* Signal an error condition by returning a amount that differs
* from the amount passed to the callback. This results in a
* CURLE_WRITE_ERROR.
*/
err = actual_size + 1;
if (actual_size > G_MAXUINT)
return err;
data->buffer = g_byte_array_append(buffer, (guchar *)ptr, (guint)actual_size);
if (data->buffer->len > data->max_size)
return err;
return actual_size;
}
gint curl_init(void)
{
if (curl_global_init(CURL_GLOBAL_ALL) != 0)
return -1;
return 0;
}
void curl_cleanup(void)
{
curl_global_cleanup();
}
GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size,
GError **err)
{
g_autoptr(GByteArray) ret = NULL;
g_autoptr(CURL) handle = NULL;
g_autofree gchar *agent = NULL;
struct UserData userdata;
CURLcode rc;
/* set up curl session */
handle = curl_easy_init();
if (!handle)
g_abort();
/* follow redirection */
rc = curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1l);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_setopt(handle, CURLOPT_TIMEOUT_MS, timeout_ms);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_setopt(handle, CURLOPT_NOSIGNAL, 1l);
if (rc != CURLE_OK)
goto curl_err;
agent = g_strdup_printf("%s/%s", tool_name, RELEASE_STRING);
rc = curl_easy_setopt(handle, CURLOPT_USERAGENT, agent);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback);
if (rc != CURLE_OK)
goto curl_err;
ret = g_byte_array_new();
userdata.buffer = ret;
userdata.max_size = max_size;
rc = curl_easy_setopt(handle, CURLOPT_WRITEDATA, (void *)&userdata);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_setopt(handle, CURLOPT_URL, url);
if (rc != CURLE_OK)
goto curl_err;
rc = curl_easy_perform(handle);
if (rc != CURLE_OK) {
g_set_error(err, PV_ERROR, PV_ERROR_DOWNLOAD_FAILED,
_("download failed: %s"), curl_easy_strerror(rc));
return NULL;
}
return g_steal_pointer(&ret);
curl_err:
g_set_error(err, PV_ERROR,
PV_ERROR_CURL_INIT_FAILED,
_("cURL initialization failed: %s"),
curl_easy_strerror(rc));
return NULL;
}

View File

@@ -0,0 +1,25 @@
/*
* Libcurl utils
*
* 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 PV_UTILS_LIBCURL_H
#define PV_UTILS_LIBCURL_H
#include <glib.h>
#include <curl/curl.h>
#include "common.h"
WRAPPED_G_DEFINE_AUTOPTR_CLEANUP_FUNC(CURL, curl_easy_cleanup)
GByteArray *curl_download(const gchar *url, long timeout_ms, guint max_size,
GError **err);
gint curl_init(void);
void curl_cleanup(void);
#endif /* PV_UTILS_LIBCURL_H */

16
hsci/Makefile Normal file
View File

@@ -0,0 +1,16 @@
include ../common.mak
all:
install: hsci
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
< hsci >$(DESTDIR)$(BINDIR)/hsci; \
chown $(OWNER).$(GROUP) $(DESTDIR)$(BINDIR)/hsci; \
chmod 755 $(DESTDIR)$(BINDIR)/hsci; \
$(INSTALL) -d -m 755 $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 hsci.8 \
$(DESTDIR)$(MANDIR)/man8
clean:
.PHONY: all install clean

441
hsci/hsci Executable file
View File

@@ -0,0 +1,441 @@
#!/bin/bash
#
# hsci - Tool to manage HiperSockets Converged Interfaces (HSCI)
#
# 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.
#
hsdev=""
ndev=""
hsci=""
hsdev_mac=""
hsif_pnetid=""
netif_pnetid=""
hsci_pnetid=""
function usage {
cat <<-EOD
Usage: hsci COMMAND [OPTION]
This tool is designed to control and show HSCI (HiperSockets Converged
Interfaces) settings. A HiperSockets interface and an external network
COMMANDS
add HIPERSOCKETS_DEV NET_DEV Adds an HSCI interface
del HSCI_NAME Deletes an HSCI interface
show Lists the configured HSCI interfaces
OPTIONS:
-v, --version Prints the version number of the hsci tool and exits
-h, --help Displays the help information for the command
EOD
}
function prereqs_check {
if ! [ -x "$(command -v ip)" ]; then
echo "Error: No iproute2 installed on this system" >&2
return 1
fi
}
function check_pnetids {
# get PNETID of the HS
local hsif_pnetids=""
local netif_pnetids=""
if [ -e /sys/class/net/$hsdev/device/util_string ]; then
hsif_pnetids="$(cat /sys/class/net/$hsdev/device/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)"
else
if [ -e /sys/class/net/$hsdev/device/chpid ]; then
chpid="$(cat /sys/class/net/$hsdev/device/chpid | tr [:upper:] [:lower:])"
hsif_pnetids="$(cat /sys/devices/css0/chp0.$chpid/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)"
fi
fi
if [ "$hsif_pnetids" != "" ]; then
port_hsif="$(cat /sys/class/net/$hsdev/dev_port)"
(( idx=16*$port_hsif+1 ))
(( end=$idx+15 ))
hsif_pnetid="$(echo "$hsif_pnetids" | cut -c $idx-$end | tr -d ' ')"
fi
# get PNETID of the NET_DEV
if [ -e /sys/class/net/$ndev/device/util_string ]; then
netif_pnetids="$(cat /sys/class/net/$ndev/device/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)"
else
if [ -e /sys/class/net/$ndev/device/chpid ]; then
chpid="$(cat /sys/class/net/$ndev/device/chpid | tr [:upper:] [:lower:])"
netif_pnetids="$(cat /sys/devices/css0/chp0.$chpid/util_string | tr -d '\000' | iconv -f IBM-1047 -t ASCII)"
fi
fi
if [ "$netif_pnetids" != "" ]; then
port_netif="$(cat /sys/class/net/$ndev/dev_port)"
(( idx=16*$port_netif+1 ))
(( end=$idx+15 ))
netif_pnetid="$(echo "$netif_pnetids" | cut -c $idx-$end | tr -d ' ')"
fi
#Check PNETIDs
if [ "$hsif_pnetid" != "" ] && [ "$netif_pnetid" != "" ] && [ "$netif_pnetid" != "$hsif_pnetid" ]; then
echo "Error: $hsdev and $ndev have different PNETIDs! They are $hsif_pnetid and $netif_pnetid respectively" >&2
return 1
fi
if [ "$hsif_pnetid" != "" ] && [ "$netif_pnetid" != "" ] && [ "$netif_pnetid" == "$hsif_pnetid" ]; then
hsci_pnetid=$hsif_pnetid
fi
}
function verify_precon {
echo "Verifying net dev $ndev and HiperSockets dev $hsdev"
if [ ! -e /sys/class/net/$hsdev ]; then
echo "Error: $hsdev does not exist" >&2
return 1
fi
if [ "$(cat /sys/class/net/$hsdev/device/card_type)" != "HiperSockets" ]; then
echo "Error: $hsdev is not a HiperSockets device" >&2
return 1
fi
if [ "$(cat /sys/class/net/$hsdev/device/layer2)" != "1" ]; then
echo "Error: $hsdev is not in layer 2 mode" >&2
return 1
fi
if [ ! -e /sys/class/net/$hsdev/device/vnicc/bridge_invisible ]; then
echo "Error: Missing vnic-characteristics support" >&2
return 1
fi
if [ "$(cat /sys/class/net/$hsdev/device/vnicc/bridge_invisible)" == "n/a" ]; then
echo "Error: $hsdev does not support vnicc" >&2
return 1
fi
if [ $(ip link show $hsdev | grep UP | wc -l) -eq 0 ]; then
echo "Error: $hsdev is not in state UP" >&2
return 1
fi
if [ $(bridge -d link show dev $hsdev self | grep learning_sync | wc -l) -eq 0 ]; then
echo "Error: $hsdev does not support attribute learning_sync" >&2
return 1
fi
if [ $(ip link show $hsdev | grep master | wc -l) -ne 0 ]; then
echo "Error: $hsdev is already a bridge port" >&2
return 1
fi
#Pre-verify net_dev
if [ ! -e /sys/class/net/$ndev ]; then
echo "Error: $ndev does not exist" >&2
return 1
fi
if [ "$(cat /sys/class/net/$ndev/device/card_type)" == "HiperSockets" ]; then
echo "Error: $ndev is also a HiperSockets device" >&2
return 1
fi
if [ $(ip link show $ndev | grep UP | wc -l) -eq 0 ]; then
echo "Error: $ndev is not in state UP" >&2
return 1
fi
if [ $(ip link show $ndev | grep master | wc -l) -ne 0 ]; then
echo "Error: $ndev is already a bridge port" >&2
return 1
fi
#Check PNETIDs
check_pnetids
if [ $? -ne 0 ]; then
return $?
fi
return 0
}
function clean_up {
bridge link set dev $hsdev learning_sync off self >/dev/null 2>&1
echo 0 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible >/dev/null 2>&1
bridge fdb del $hsdev_mac dev $ndev >/dev/null 2>&1
ip link del $hsci >/dev/null 2>&1
}
##############################################################################
## add a new HSCI interface
##############################################################################
function add_hsci {
if [ $# != 2 ]; then
echo "hsci: Invalid parameters" >&2
echo "Use 'hsci --help' for more information" >&2
return 1
fi
hsdev=$1
ndev=$2
#### Verify preconditions
verify_precon
if [ $? -ne 0 ]; then
return $?
fi
hsci_postfix="$(readlink /sys/class/net/$hsdev/device/cdev0 | tail -c5)"
hsci=hsci$hsci_postfix
echo "Adding $hsci with a HiperSockets dev $hsdev and an external dev $ndev"
#### Create bridge
ip link add name $hsci type bridge stp_state 0 >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Could not create a bridge" >&2
return 1
fi
#### Prepare hsdev
# Set VNICC of hsdev to invisible
#(mandatory for co-existence with HS-OSA bridges!)
echo 1 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible
#### Create bridge ports
ip link set dev $ndev master $hsci >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Could not set master for $ndev" >&2
clean_up
return 1
fi
ip link set dev $hsdev master $hsci >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Could not set master for $hsdev" >&2
clean_up
return 1
fi
# no forwarding between ndev and hsdev -> isolated on
# ndev is default for outgoing unknown targets -> flood on
# no need to learn external LAN targets into fdb -> learning off
bridge link set dev $ndev isolated on learning off flood on mcast_flood on >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Failed to set bridge attributes on $ndev" >&2
clean_up
return 1
fi
# no forwarding between ndev and hsdev -> isolated on
# fdb will be populated by dev-to-bridge-notification, no need to learn
# -> learning off
# only send to hsdev, if listed in fdb -> flood off
# don't send MC/BC on hsdev -> mcast_flood off
bridge link set dev $hsdev isolated on learning off flood off mcast_flood off >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Failed to set bridge attributes on $hsdev" >&2
clean_up
return 1
fi
# NOTE: Although not required, BCs will be sent out on hsdev.
# NOTE: We need to receive BCs on hsdev, as z/OS HSCI does ARP requests on HS.
hsdev_mac="$(cat /sys/class/net/$hsdev/address)"
echo "Set $hsdev MAC $hsdev_mac on $ndev and $hsci"
# set HS MAC on OSA as secondary MAC
bridge fdb add $hsdev_mac dev $ndev >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Failed to set HS MAC on OSA as secondary MAC" >&2
clean_up
return 1
fi
# set HS MAC (common MAC) on HSCI as primary MAC
ip link set address $hsdev_mac dev $hsci >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Failed to set HiperSockets MAC (common MAC) on HSCI as primary MAC" >&2
clean_up
return 1
fi
# use hsdev MTU
if [ -e /sys/class/net/$hsdev/mtu ]; then
hs_mtu="$(cat /sys/class/net/$hsdev/mtu)"
ip link set dev $hsci mtu $hs_mtu >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Failed to set MTU for $hsci " >&2
clean_up
return 1
fi
fi
ip link set dev $hsci up >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Failed to set $hsci up" >&2
clean_up
return 1
fi
# Turn on device for bridge notification
bridge link set dev $hsdev learning_sync on self >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Failed to turn on device for bridge notification" >&2
clean_up
return 1
fi
echo "Successfully added HSCI interface $hsci"
return 0
}
##############################################################################
## Delete HSCI
##############################################################################
function del_hsci {
if [ $# != 1 ]; then
echo "hsci: invalid parameters" >&2
echo "Use 'hsci --help' for more information" >&2
return 1
fi
hsci=$1
if [ $(ip link show dev $hsci | wc -l) -eq 0 ]; then
echo "Error: $hsci does not exit" >&2
return 1
fi
if [ $(ip link show | grep "master $hsci" | wc -l) -eq 0 ]; then
echo "Error: $hsci is not an active HSCI interface" >&2
return 1
fi
bports="$(ip link show | grep "master $hsci" | awk '{print $2}')"
for bport in $bports; do
if [ $(bridge -d link show dev $bport | grep "learning_sync on" | wc -l) -ne 0 ]; then
hsdev=${bport%:}
else
ndev=${bport%:}
fi
done
if [ "$hsdev" == "" ]; then
echo "Error: $hsci has no active HiperSockets port" >&2
return 1
fi
echo "Deleting HSCI interface $hsci with the HiperSockets $hsdev and the external $ndev"
bridge link set dev $hsdev learning_sync off self >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Failed to turn off learning_sync on $hsdev" >&2
return 1
fi
echo 0 > /sys/class/net/$hsdev/device/vnicc/bridge_invisible
hsdev_mac="$(cat /sys/class/net/$hsdev/address)"
echo "Deleting $hsev MAC $hsdev_mac on $ndev"
bridge fdb del $hsdev_mac dev $ndev >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Failed to delete $hsev MAC $hsdev_mac on $ndev" >&2
return 1
fi
ip link del $hsci >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Error: Failed to delete $hsci" >&2
return 1
fi
echo "Successfully deleted device $hsci"
return 0
}
##############################################################################
## Show HSCI
##############################################################################
function list_active {
hsdev=$1
local ext=""
hsci="$(ip link show dev $hsdev | awk '{for(x=1;x<NF;x++) if($x~/master/) print $(x+1)}')"
ext="$(ip link show | grep "master $hsci" | grep --invert-match $hsdev | awk '{print $2}')"
# remove trailing ':'
ndev="${ext%:}"
check_pnetids
printf '%-8s %-16s %-15s %-15s\n' "$hsci" "$hsci_pnetid" "$hsdev" "$ndev"
return 0
}
function print_header {
if [ $header -eq 0 ]; then
echo "HSCI PNET_ID HiperSockets External "
echo "------------------------------------------------------------"
fi
}
function list_one {
local hsnetdev=$1
if [ $(bridge -d link show dev $hsnetdev | grep "learning_sync on" | wc -l) -ne 0 ]; then
print_header
list_active $hsnetdev
fi
return 0
}
function show_hsci {
if [ $# != 0 ]; then
echo "hsci: invalid parameters" >&2
echo "Use 'hsci --help' for more information" >&2
return 1
fi
header=0
for hs_net_dev in $(ls -1 /sys/class/net/); do
list_one $hs_net_dev
done
return 0
}
#==============================================================================
function print_version()
{
echo "hsci utility: version %S390_TOOLS_VERSION%"
echo "Copyright IBM Corp. 2020"
}
##############################################################################
##### Main
##############################################################################
prereqs_check
args="$(getopt -u -o hv -l help,version -- $*)"
[ $? -ne 0 ] && exit 2
set -- $args
while true; do
case $1 in
-v | --version)
print_version
exit 0
;;
-h | --help)
usage
exit 0
;;
--)
;;
add) shift
add_hsci "$@"
exit $?
;;
del) shift
del_hsci "$@"
exit $?
;;
show) shift
show_hsci "$@"
exit $?
;;
*) echo "hsci: Please specify a valid command or option" >&2
echo "Use 'hsci --help' for more information" >&2
exit 1
esac
shift
done

100
hsci/hsci.8 Normal file
View File

@@ -0,0 +1,100 @@
.\" Copyright IBM Corp. 2020
.TH HSCI 8 "November 2020" "s390-tools" "Linux Programmer's Manual"
.SH NAME
.B hsci
\- control and show HSCI settings.
.SH SYNOPSIS
.B hsci add
.I HSDEV
.I NETDEV
.br
.B hsci del
.I HSCINAME
.br
.B hsci show
.br
.B hsci [\-hv]
.SH DESCRIPTION
.BI hsci
is used to control and show HSCI (HiperSockets Converged Interfaces) settings. A HiperSockets interface and an external network interface are converged into an HSCI interface.
.SH COMMANDS
.TP
.B add \fIHSDEV\fR \fINETDEV\fR
.RS .4i
.PP
Adds an HSCI interface
.PP
.I HSDEV
is the interface name of the HiperSockets device to be converged into the HSCI interface.
.PP
.I NETDEV
is the interface name of the external network device to be converged into the HSCI interface.
.RE
.TP
.B del \fIHSCINAME\fR
.RS .4i
.PP
Deletes an HSCI interface
.PP
.I HSCINAME
is the name of the HSCI interface for the HiperSockets device and the external network device.
.RE
.TP
.B show
.RS .4i
.PP
Lists the configured HSCI interfaces.
.RE
.SH OPTIONS
.TP
.BR \-v ", " \-\-version
Prints the version number of hsci and exits.
.TP
.BR \-h ", " \-\-help
Displays the help information for the command.
.SH EXIT CODES
.TP
.BR "0"
The hsci command ran successfully.
.TP
.BR "1"
An error occurred.
.SH EXAMPLE
.BR "hsci show"
.TP
.RB
Lists the configured HSCI interfaces:
.RS 1.2i
HSCI PNET_ID HiperSockets External
.br
-----------------------------------------
.br
hsci8410 NET1 enc8410 encb040
.RE
.SH SEE ALSO
.nf
ip(8), bridge(8)
.fi
.SH AUTHOR
.nf
Written by Alexandra Winter <wintera@linux.ibm.com>
Wenjia Zhang <wenjia@linux.ibm.com>
.fi

View File

@@ -21,7 +21,7 @@ clean: clean-recursive
$(RECURSIVE_TARGETS):
@target=`echo $@ |sed s/-recursive//`; \
for d in $(SUBDIRS); do \
(cd $$d && $(MAKE) $$target) \
(cd $$d && $(MAKE) $$target) || exit 1; \
done

View File

@@ -81,7 +81,7 @@ install-libekmfweb.so.$(VERSION): libekmfweb.so.$(VERSION)
ln -srf $(DESTDIR)$(USRLIB64DIR)/libekmfweb.so.$(VERSION) $(DESTDIR)$(USRLIB64DIR)/libekmfweb.so.$(VERM)
ln -srf $(DESTDIR)$(USRLIB64DIR)/libekmfweb.so.$(VERSION) $(DESTDIR)$(USRLIB64DIR)/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) -g $(GROUP) -o $(OWNER) -m 644 $(rootdir)include/ekmfweb/ekmfweb.h $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
install: all $(INSTALL_TARGETS)

View File

@@ -460,7 +460,7 @@ int util_proc_mnt_get_entry(const char *file_name, const char *spec,
rc = scan_mnt_entry(&file, entry);
if (rc)
goto out_free;
if (!strcmp(entry->spec, spec)) {
if (!strcmp(entry->vfstype, spec)) {
rc = 0;
goto out_free;
}

View File

@@ -2,15 +2,27 @@
include ../common.mak
SCRIPTS = mk-s390image mk-pxelinux-ramfs
NETBOOT_SAMPLEDIR=$(TOOLS_DATADIR)/netboot
all:
install: all
$(INSTALL) -d -m 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR)
$(INSTALL) -m 755 mk-s390image mk-pxelinux-ramfs \
$(DESTDIR)$(NETBOOT_SAMPLEDIR)
$(INSTALL) -m 644 Dockerfile Makefile.pxelinux.0 README.md \
install: install-scripts
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 \
Dockerfile Makefile.pxelinux.0 README.md mk-s390image.1 \
$(DESTDIR)$(NETBOOT_SAMPLEDIR)
.PHONY: all install clean
install-scripts: $(SCRIPTS)
@if [ ! -d $(DESTDIR)$(NETBOOT_SAMPLEDIR) ]; then \
mkdir -p $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
chown $(OWNER).$(GROUP) $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
chmod 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR); \
fi; \
for i in $^; do \
$(SED) -e 's/%S390_TOOLS_VERSION%/$(S390_TOOLS_RELEASE)/' \
< $$i >$(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
chown $(OWNER).$(GROUP) $(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
chmod 755 $(DESTDIR)$(NETBOOT_SAMPLEDIR)/$$i; \
done
.PHONY: all install clean install-scripts

View File

@@ -54,9 +54,18 @@ OPTIONS
-b Search installed busybox in directory BUSYBOX_DIR
-k Use KERNEL_VERSION instead of currently running kernel
-h Print this help, then exit
-v Print version information, then exit
EOF
}
printversion()
{
cat <<-EOD
$cmd: version %S390_TOOLS_VERSION%
Copyright IBM Corp. 2017
EOD
}
# Get shared objects for binary
sharedobjs()
{
@@ -64,7 +73,7 @@ sharedobjs()
}
# Check args
args=$(getopt b:k:h $*)
args=$(getopt b:k:hv $*)
if [ $? = 0 ]
then
set -- $args
@@ -74,6 +83,7 @@ then
-b) busyboxdir=$2; shift 2;;
-k) kernelversion=$2; shift 2;;
-h) usage; exit 0;;
-v) printversion; exit 0;;
--) shift; break;;
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
esac

View File

@@ -60,9 +60,18 @@ OPTIONS
-p Use PARMFILE with kernel parameters in the image
-r Include RAMDISK in the image
-h Print this help, then exit
-v Print version information, then exit
EOF
}
printversion()
{
cat <<-EOD
$cmd: version %S390_TOOLS_VERSION%
Copyright IBM Corp. 2017
EOD
}
# Convert decimal number to big endian doubleword
dec2be64()
{
@@ -129,6 +138,9 @@ dobuild()
parmfile_size=$(du -b $parmfile | cut -f1)
if [ $parmfile_size -le $MAX_PARMFILE_SIZE ]
then
# Clear any previous parameters
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 count=$MAX_PARMFILE_SIZE \
if=/dev/zero of=$image conv=notrunc status=none
dd seek=$OFFS_COMMANDLINE_BYTES bs=1 if=$parmfile \
of=$image conv=notrunc status=none
else
@@ -142,7 +154,7 @@ dobuild()
}
# check args and build
args=$(getopt "r:p:h" $*)
args=$(getopt "r:p:hv" $*)
if [ $? = 0 ]
then
set -- $args
@@ -152,6 +164,7 @@ then
-r) ramdisk=$2; shift 2;;
-p) parmfile=$2; shift 2;;
-h) usage; exit 0;;
-v) printversion; exit 0;;
--) shift; break;;
*) echo "$cmd: Unexpected argument $1, exiting..." >&2; exit 1;;
esac

17
netboot/mk-s390image.1 Normal file
View File

@@ -0,0 +1,17 @@
.TH MK-S390IMAGE "1" "November 2020" "s390-tools" "User Commands"
.SH NAME
mk-s390image \- tool for creating bootable image
.SH SYNOPSIS
.B mk-s390image
\fI\,KERNEL BOOT_IMAGE \/\fR[\fI\,-r RAMDISK\/\fR] [\fI\,-p PARMFILE\/\fR]
.SH DESCRIPTION
Build an s390 image BOOT_IMAGE suitable for CD/tape/network boot or as a
KVM firmware image using a stripped Linux kernel file KERNEL.
.PP
.SH OPTIONS
.TP
\fB\-p\fR Use PARMFILE with kernel parameters in the image
.TP
\fB\-r\fR Include RAMDISK in the image
.TP
\fB\-h\fR Print usage message, then exit

View File

@@ -10,10 +10,11 @@ zipl-switch-to-blscfg \- Switch zipl to use BootLoaderSpec configuration
\fBzipl-switch-to-blscfg\fP {\-h|\-v}
.SH DESCRIPTION
This script switches the zipl boot-loader configuration to use BootLoaderSpec files
to define IPL sections. For each Linux kernel defined in the zipl.conf config file,
a BLS fragment is generated in the BLS directory specified. Also, the zipl.conf is
modified it only contains global configurations, all IPL sections comes from BLS.
This script switches the zipl boot-loader configuration to use BootLoaderSpec
files to define IPL sections. For each Linux kernel defined in the zipl.conf
config file, a BLS fragment is generated in the BLS directory specified. Also,
zipl.conf is modified to only contain global configuration. All IPL sections
come from BLS files.
.SH OPTIONS
.TP
@@ -30,7 +31,8 @@ The suffix used for backup files, defaults to .bak.
.TP
\fB\-\-bls-directory <DIRECTORY>\fP
The DIRECTORY where the BLS fragments will be generated. The directory is created if it doesn't exists, by default /boot/loader/entries is used.
The DIRECTORY where the BLS fragments will be stored. The directory is
created if it does not exist. By default /boot/loader/entries is used.
.TP
\fB\-\-config-file <FILE>\fP

View File

@@ -10,11 +10,12 @@
Description=Apply Control Program Identification (CPI)
DefaultDependencies=no
Conflicts=shutdown.target
After=local-fs.target
After=sysinit.target
ConditionPathIsReadWrite=/sys/firmware/cpi
[Service]
Type=oneshot
RemainAfterExit=yes
#
# Specify a file with the environment variables using the EnvironmentFile=
# service property.

View File

@@ -387,6 +387,7 @@ function extended()
read EXTSZ 2> /dev/null < $DEVPATH/extent_pool/extent_size
read CAPACITY 2> /dev/null < $DEVPATH/capacity/logical_capacity
read ALLOCATED 2> /dev/null < $DEVPATH/capacity/space_allocated
read FC_SEC 2> /dev/null < $DEVPATH/fc_security
# convert to hexadecimal values
PIM=0x$PIM
@@ -521,7 +522,7 @@ function extended()
elif [[ "$ALIAS" == 1 ]]; then
if [[ "$BASEONLY" == "false" ]]; then
ACTIVE="alias"
printf "%s:%s:%s# status:\t\t\t\t%s# type: \t\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s # uid: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
printf "%s:%s:%s# status:\t\t\t\t%s# type: \t\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s # uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
"$SORTKEYLEN" "$SORTKEY" \
"$BUSID" \
"$ACTIVE" \
@@ -532,6 +533,7 @@ function extended()
"$ERP" \
"$HPF" \
"$DEV_UID" \
"$FC_SEC" \
"${INSTALLED_PATHS[@]}" \
"${USED_PATHS[@]}" \
"${NP_PATHS[@]}" \
@@ -563,7 +565,7 @@ function extended()
DISCIPLINE="${DISCIPLINE} (ESE)"
fi
printf "%s:%s:%s/%s/%s%s%s# status:\t\t\t\t%s# type: \t\t\t\t%s# blksz:\t\t\t\t%s# size: \t\t\t\t%s# blocks:\t\t\t\t%s# extent_size:\t\t\t\t%s# logical_capacity:\t\t\t%s# space_allocated:\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s# uid: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
printf "%s:%s:%s/%s/%s%s%s# status:\t\t\t\t%s# type: \t\t\t\t%s# blksz:\t\t\t\t%s# size: \t\t\t\t%s# blocks:\t\t\t\t%s# extent_size:\t\t\t\t%s# logical_capacity:\t\t\t%s# space_allocated:\t\t\t%s# use_diag:\t\t\t\t%s# readonly:\t\t\t\t%s# eer_enabled:\t\t\t\t%s# erplog:\t\t\t\t%s# hpf:\t\t\t\t\t%s# uid: \t\t\t\t%s# fc_security: \t\t\t\t%s# paths_installed: \t\t\t%s %s %s %s %s %s %s %s# paths_in_use: \t\t\t%s %s %s %s %s %s %s %s# paths_non_preferred: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_cabling: \t\t%s %s %s %s %s %s %s %s# paths_cuir_quiesced: \t\t\t%s %s %s %s %s %s %s %s# paths_invalid_hpf_characteristics: \t%s %s %s %s %s %s %s %s# paths_error_threshold_exceeded: \t%s %s %s %s %s %s %s %s#\n" \
"$SORTKEYLEN" "$SORTKEY" \
"$BUSID" \
"$BLOCKNAME" \
@@ -584,6 +586,7 @@ function extended()
"$ERP" \
"$HPF" \
"$DEV_UID" \
"$FC_SEC" \
"${INSTALLED_PATHS[@]}" \
"${USED_PATHS[@]}" \
"${NP_PATHS[@]}" \

View File

@@ -1178,8 +1178,14 @@ static int get_apqn_measurement_data(uint8_t card)
scdmd_area.request.header.code = 0x102d;
scdmd_area.request.header.length =
sizeof(struct chsc_scdmd_request);
scdmd_area.request.first_drid.ap_index = card;
scdmd_area.request.first_drid.domain_index = g.min_domain;
if (scdmd_area.response.p) {
scdmd_area.request.first_drid =
scdmd_area.response.crid;
} else {
scdmd_area.request.first_drid.ap_index = card;
scdmd_area.request.first_drid.domain_index =
g.min_domain;
}
scdmd_area.request.last_drid.ap_index = card;
scdmd_area.request.last_drid.domain_index = g.max_domain;
scdmd_area.request.s = 1;
@@ -1217,10 +1223,6 @@ static int get_apqn_measurement_data(uint8_t card)
rc = process_apqn_measurement_data(&scdmd_area);
if (rc != 0)
break;
if (scdmd_area.response.p)
scdmd_area.request.first_drid =
scdmd_area.response.crid;
} while (scdmd_area.response.p);
return rc;

View File

@@ -313,6 +313,22 @@ static struct attrib dasd_attr_safe_offline = {
.writeonly = 1,
};
static struct attrib dasd_attr_fc_security = {
.name = "fc_security",
.title = "Show FC Endpoint Security state of DASD device",
.desc =
"This read-only attribute shows the Fibre Channel Endpoint Security\n"
"status of the connection to the DASD device:\n"
" Unsupported : The DASD device does not support Fibre Channel\n"
" Endpoint Security\n"
" Inconsistent : The operational channel paths of the DASD device\n"
" report inconsistent Fibre Channel Endpoint\n"
" Security status\n"
" Authentication: The connection has been authenticated\n"
" Encryption : The connection is encrypted\n",
.readonly = 1,
};
/*
* DASD subtype methods.
*/
@@ -617,6 +633,7 @@ struct subtype dasd_subtype_eckd = {
&dasd_attr_reservation_policy,
&dasd_attr_last_known_reservation_state,
&dasd_attr_safe_offline,
&dasd_attr_fc_security,
&internal_attr_early,
),
.unknown_dev_attribs = 1,

View File

@@ -7,8 +7,6 @@ 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 libekmfweb.dep
@@ -29,7 +27,7 @@ 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
zkey-ekmfweb.so: LDLIBS = -L$(rootdir)/libekmfweb -lekmfweb -ldl -lcrypto
zkey-ekmfweb.so: ALL_LDFLAGS += -shared -Wl,--version-script=zkey-ekmfweb.map \
-Wl,-z,defs,-Bsymbolic -Wl,-soname,zkey-ekmfweb.so.$(VERM)
zkey-ekmfweb.so: zkey-ekmfweb.o properties.o pkey.o cca.o ep11.o utils.o $(libs)

View File

@@ -899,24 +899,24 @@ int kms_display_info(const kms_handle_t handle)
if (rc == 0) {
switch (type) {
case EVP_PKEY_EC:
printf(" EBMF Web public key: ECC (%s)\n",
printf(" EKMF Web public key: ECC (%s)\n",
OBJ_nid2sn(curve));
break;
case EVP_PKEY_RSA:
printf(" EBMF Web public key: RSA "
printf(" EKMF Web public key: RSA "
"(%d bits)\n", mod_bits);
break;
default:
printf(" EBMF Web public key: "
printf(" EKMF Web public key: "
"(unknown key type)\n");
break;
}
} else {
printf(" EBMF Web public key: (not available)\n");
printf(" EKMF Web public key: (not available)\n");
}
free(tmp);
} else {
printf(" EBMF Web public key: (configuration required)\n");
printf(" EKMF Web public key: (configuration required)\n");
}
printf(" Key templates:\n");

View File

@@ -46,8 +46,8 @@
#define KMS_CONFIG_PROP_KMS "kms"
#define KMS_CONFIG_PROP_KMS_CONFIG "config"
#define KMS_CONFIG_PROP_APQNS "apqns"
#define KMS_CONFIG_PROP_CCA_APQNS "ep11_apqns"
#define KMS_CONFIG_PROP_EP11_APQNS "cca_apqns"
#define KMS_CONFIG_PROP_CCA_APQNS "cca_apqns"
#define KMS_CONFIG_PROP_EP11_APQNS "ep11_apqns"
#define KMS_CONFIG_LOCAL "local"
#define KMS_KEY_PROP_NAME "zkey-name"