Compare commits

...

144 Commits

Author SHA1 Message Date
Jan Höppner
1bb9a9ec5b New release s390-tools-2.16.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 15:46:37 +01:00
Nikita Dubrovskii
4a3957fab5 zipl: fix reading 4k disk's geometry
On 4k SCSI disks zipl stores wrong values to 'scsi_mbr.program_table_pointer',
which makes system unbootable.
This happens in 'zipl/src/disk.c:656':

```
/* Convert file system block to physical */
*physical = mapped * phy_per_fs + subblock;
/* Add partition start */
*physical += info->geo.start;

```

So 'hd_geometry.start' should be adjusted before being used.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1918723
Closes: https://github.com/ibm-s390-linux/s390-tools/pull/107
Signed-off-by: Nikita Dubrovskii <nikita@linux.ibm.com>
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:47:07 +01:00
Ingo Franzki
e506c94839 zkey-ekmfweb: Fix typos in messages
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:47:07 +01:00
Wenjia Zhang
dfd9f52873 hsci: fix packet loss caused by large MTU
For maximum performance the MTU of an HSCI interface was set to the value
of the MTU of its HiperSockets interface. However, the MTU of a
HiperSockets interface can be very large, and when the data packets are
not sent over the HiperSocket but over the corresponding ethernet
interface (which usually has a smaller MTU size) then it can happen that
the large packets are silently dropped. One example would be communication
from an HSCI in one CEC to another HSCI in another CEC via Ethernet.

To solve the problem, the MTU setting in this tool is removed, and the
default MTU value is used. Thus, the minimum value of the MTUs of the both
converged interfaces is used as the MTU of the HSCI interface.

Fixes: 0566a492ae ("s390-tools: add hsci tool")
Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:47:07 +01:00
Jan Höppner
14ca7c5080 s390-tools: Change GitHub link to new name
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:47:07 +01:00
Steffen Maier
4fc1a92a8d zfcpdbf: deal with crash 7.2.9 change in caller name formatting
Since crash 7.2.9 commit
f1f43bf355
in support of kernel v5.9 commit 0990d836cecb
("s390/debug: debug feature version 3"),
the symbolic caller function name is left aligned instead of right
aligned, so now we alternatively have to remove whitespace between
function name and offset.

Otherwise, zfcpdbf output contains wrong warnings about ambiguous payload
records with wrong values for reqid and area, as well as incorrectly
decoded trace records with wrong content values and potential error
messages on not defined record id, and finally a potential list of
occurrences of unknown tags which should empty:

Loading trace records ...(this might take a while)
Warning: Ambiguous PAYload records. reqid:>>>wrong<<< area:V^D^@fcp_
Warning: Ambiguous PAYload records. reqid:>>>wrong<<< area:W^D^@fsf_
Warning: Ambiguous PAYload records. reqid:>>>wrong<<< area:i^B^@san_

...

Timestamp      : ...
Area           : SAN
Subarea        : 00
Level          : 1
Exception      : -
CPU ID         : 0001
Caller         : <zfcp_dbf_san_in_els
Record ID      : 0
Tag            : 6^B^Cfcie
Request ID     : >>>wrong<<<
Destination ID : >>>wrong<<<
SAN record id=0 not defined.
Timestamp      : ...
Area           : SAN
Subarea        : 00
Level          : 1
Exception      : -
CPU ID         : 0002
Caller         : <zfcp_dbf_san_in_els
Record ID      : 0
Tag            : 6^B^Cfcie
Request ID     : >>>wrong<<<
Destination ID : >>>wrong<<<
SAN record id=0 not defined.

...

occurrences of unknown tags:
...

Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:46:54 +01:00
Ingo Franzki
d73d7f91ac zkey-ekmfweb: Fix typos in man page
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Alexander Egorenkov
800df6bef8 zipl/boot: fix heap OOM in stage2 of DASD dumper
For the stage2 of zipl's boot loaders only 3 heap pages are available
[0x6000, 0x6000 + 0x3000]. Therefore, stage2 code needs to be very careful
when and for how long it allocates a heap page.

The heap OOM problem in stage2 was hidden until the commit 252be376
("zipl/boot: fix potential heap overflow in stage2"). Before this commit,
stage2 assumed that heap is 4 pages large which is apparently very wrong
but get_zeroed_page() still allowed allocating an extra 4th page by
overriding the memory segment following the heap area of stage2 (stage3
parameter area).

Try to avoid allocating a heap page and keeping it allocated over a long
period of time in the DASD dumpers. Free a heap page as soon as possible
if not required anymore.

And be extra careful with printf() because it always tries to allocate
a free heap page.

Fixes: 252be376 ("zipl/boot: fix potential heap overflow in stage2")
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Marc Hartmayer
3c661da4ee genprotimg: boot: make boot loader -march=z900 compatible
Replace the `lgfi` opcode with equivalents as z900 has no support for
it.

While at it, fix a comment in `genprotimg/boot/head.S` and remove a
useless label in `genprotimg/boot/stage3b_reloc.S`.

Closes: https://github.com/ibm-s390-tools/s390-tools/issues/86
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Ingo Franzki
bf5ca4367d libekmfweb: Check length of JWK EC public key coordinates
RFC 7517 requires that the x and y coordinates of a ECC JSON Web Key
(JWK) are specified in its full size of a coordinate for the curve used.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Wenjia Zhang
faf26220a7 hsci: fix failed to delete an HSCI connected with VLAN
Deleting an HSCI interface, the connected HiperSockets interface's name
and the connected Ethernet interface's name are extracted from "ip link
show". Currently the extracted names are directly used in "bridge -d link
show dev ifname" for further checking. If "iflink" and "ifindex" of an
interface are not matched, ip commands will print @ifXX appended to the
real interface's name. Thus, it will be failed if the interface's name
with the ending @ifXX is used in "bridge -d link show dev ifname" for
further checking.

To solve the problem, the ending @ifXX must be removed before the
interface name is used further.

Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Wenjia Zhang
522252d18a hsci: fix wrong return code
In the current code, after the function check_pnetids() and the function
verify_precon() are called, $? from each function is used twice
successively. It is used for the first time in the condition of the IF
statement, while for the second time as return code of the current
function. In bash, $? can be used to get the return code, but only for
the first time directly after the previous function is called.
Afterwards, $? will be reset to "0". Thus, the right return code can not
be get, if $? is used second time.

To solve the problem, using $? for the second time should be avoided.

Signed-off-by: Wenjia Zhang <wenjia@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Alexander Egorenkov
42889edc0c make: add address sanitizer support
Install libasan first, e.g. on Fedora 32:
  dnf install -y libasan libasan-static.

To compile with address sanitizer, pass ASAN=1 to make.
AdressSanitizer helps to catch various memory bugs for which C/C++ is
infamous.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Alexander Egorenkov
13016ebc5a cmsfs-fuse: ASAN fix dec_to_hex() and hex_to_dec()
This fixes the following compiler errors when ASAN is enabled:

  CC      cmsfs-fuse/cmsfs-fuse.o
cmsfs-fuse.c: Assembler messages:
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:310: Error: operand out of range (0xffffffffffffff00 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)
cmsfs-fuse.c:302: Error: operand out of range (0xfffffffffffffda0 is not between 0x0000000000000000 and 0x0000000000000fff)

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-02-19 13:43:41 +01:00
Ingo Franzki
c4546daf34 zkey-ekmfweb: Avoid sequence number clash when generating keys
When keys are generated concurrently in EKMF Web from multiple clients,
and the key labels use a sequence number tag, then the assignment logic
of the sequence number may cause a duplicate sequence number to be used,
because another key might have already been generated with the same
sequence number, since the next-to-use sequence number has been retrieved
from EKMF Web. This results in a HTTP response code of 409 and a -EEXIST
return code from ekmf_generate_key().

Instead of getting the last used sequence number from EKMFWeb, tell
EKMFWeb to automatically use the next available sequence number when
generating a key. When the sequence number label tag value is 'next'
then EKMFWeb will automatically assign the next available sequence number
to the label tag and increment the sequence number in an atomic way.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Alexander Egorenkov
1e18429f69 zdump: fix invalid memory access on memory chunk's data
If a memory chunk is added to mem_phys as well as mem_virt
in dfi_mem_chunk_add_vol() then an illegal memory access might occur
when accessing mem_chunk->data e.g. in dfi_elf_mem_chunk_read_fn()
because the data block pointed to by the data field is now being referenced
by two memory chunks, one in mem_phys and one in mem_virt. If it happens
that the memory chunk from mem_virt is freed in mem_unmap() then
the memory chunk in mem_phys still points to the common data block
which has been already freed. This leads to all sort of bad behavior
in dfi_elf_mem_chunk_read_fn() and other places where mem_chunk->data
might be accessed.

Fixes the following bug:
zgetdump: Unexpected end of file for "dump.all.elf"

And this was found by AddressSanitizer:

=================================================================
==81170==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000570 at pc 0x00000101ac10 bp 0x03ffd897e250 sp 0x03ffd897e248
READ of size 8 at 0x602000000570 thread T0
    #0 0x101ac0f in dfi_elf_mem_chunk_read_fn s390-tools/zdump/dfi_elf.c:27
    #1 0x100d8a5 in mem_read s390-tools/zdump/dfi.c:339
    #2 0x100d8a5 in dfi_mem_phys_read s390-tools/zdump/dfi.c:616
    #3 0x100d8a5 in mem_chunk_map_read_fn s390-tools/zdump/dfi.c:353
    #4 0x100fd29 in mem_read s390-tools/zdump/dfi.c:339
    #5 0x100fd29 in dfi_mem_read s390-tools/zdump/dfi.c:608
    #6 0x1018e89 in os_info_get s390-tools/zdump/dfi_vmcoreinfo.c:65
    #7 0x1018e89 in dfi_vmcoreinfo_init s390-tools/zdump/dfi_vmcoreinfo.c:86
    #8 0x10175b3 in dfi_init s390-tools/zdump/dfi.c:1215
    #9 0x1006e71 in do_stdout s390-tools/zdump/zgetdump.c:161
    #10 0x1006e71 in main s390-tools/zdump/zgetdump.c:180
    #11 0x3ffb07abb89 in __libc_start_main (/lib64/libc.so.6+0x2bb89)
    #12 0x1007e8d  (s390-tools/zdump/zgetdump+0x1007e8d)

0x602000000570 is located 0 bytes inside of 8-byte region [0x602000000570,0x602000000578)
freed by thread T0 here:
    #0 0x3ffb0bc961b in free (/lib64/libasan.so.6+0xc961b)
    #1 0x100d2d9 in mem_unmap s390-tools/zdump/dfi.c:1050

previously allocated by thread T0 here:
    #0 0x3ffb0bc9aa9 in calloc (/lib64/libasan.so.6+0xc9aa9)
    #1 0x100a271 in zg_alloc s390-tools/zdump/zg.c:93

SUMMARY: AddressSanitizer: heap-use-after-free s390-tools/zdump/dfi_elf.c:27 in dfi_elf_mem_chunk_read_fn
Shadow bytes around the buggy address:
  0x100c0400000050: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c0400000060: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c0400000070: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c0400000080: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c0400000090: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
=>0x100c04000000a0: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa[fd]fa
  0x100c04000000b0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x100c04000000c0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa 04 fa
  0x100c04000000d0: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x100c04000000e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x100c04000000f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==81170==ABORTING

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Alexander Egorenkov
11e78cada5 zdump: catch attempts to seek past end of file in zg_seek()
Make zg_seek() more robust.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Alexander Egorenkov
0a7df9e030 zdump: improve error handling in pt_load_add()
Verify the given ELF header before adding any memory chunks otherwise
a memory chunk might be added even if the given ELF header is invalid.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Vineeth Vijayan
7dd03eaeec zdev: Add build option to update initial RAM-disk by default
Some Linux distributions always include a copy of all persistent device
configuration data when updating the initial RAM-disk. This makes
chzdev's persistent device configuration changes ineffective because
device configuration directives applied in the RAM-disk take precedence
over those stored in the root filesystem.

This patch introduces a new build-time switch which allows distributions
to specify that whenever there is a persistent device configuration
change, the RAM-disk is updated automatically.

This feature can be enabled by adding 'ZDEV_ALWAYS_UPDATE_INITRD=1' as
a zdev build option. Where, by default ZDEV_ALWAYS_UPDATE_INITRD is 0.

Co-developed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Ingo Franzki
663262c962 zkey: Prevent sporadic error during key verification pattern generation
After a master key change, it can happen that the AF_ALG setkey
operation returns EINVAL, although the key is valid. This is a
temporary situation and the operation will succeed, once the firmware
has completed some internal processing related with the master key
change. Delay 1 second and retry up to 10 times.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2021-01-25 13:19:33 +01:00
Nikita Dubrovskii
bf9482709f fdasd: Use increased retry count for dasd_reread_partition_table
If fdasd is used right after dasdfmt, it may fail with the following
error due to udev still processing events for the device:

```
fdasd error:  IOCTL error: Error while rereading partition table.
```

Call dasd_reread_partition_table() with an increased retry value to
circumvent this issue.

Closes: https://github.com/ibm-s390-tools/s390-tools/pull/103
Signed-off-by: Nikita Dubrovskii <nikita@linux.ibm.com>
[hoeppner@linux.ibm.com: Reword commit message]
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Dan Horák
cdf0b5d66f hsci: fix help text
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/102
Signed-off-by: Dan Horák <dan@danny.cz>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Vance Morris
4aafd6962a netboot: Bump busybox version in pxelinux.0 build
`stime` was removed in glibc-2.31.
Busybox fixes this in https://git.busybox.net/busybox/patch/?id=d3539be8f27b8cbfdfee460fe08299158f08bcd9

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/100
Closes: https://github.com/ibm-s390-tools/s390-tools/pull/101
Signed-off-by: Vance Morris <vmorris@us.ibm.com>
Reviewed-by: Viktor Mihajlovski mihajlov@de.ibm.com
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki
863e1c3fa4 zkey: Remove warning about sector size support with crypttab
Current distributions should now all support the sector size option
in crypttab entries for plain mode dm-crypt volumes.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki
7c47ea8e09 zkey: Add support to store LUKS2 dummy passphrase in key repository
Extend zkey to allow to store a (dummy) LUKS2 passphrase together with a
secure key, for use with LUKS2 volumes. That way, when the repository is
backed up, or archived, also the passphrases of the associated LUKS2
volumes are backed up, or archived, and thus can not be forgotten.
This passphrase is then used in generated commands to format and open
the LUKS2 volumes.

Because of the use of secure keys to encrypt the volumes, the LUKS2
passphrase is of no or less relevance for security. It is therefore OK to
store the passphrase in clear text in the key repository, and also use
them in /etc/crypttab. Therefore, the passphrase could actually be a
trivial passphrase, or a dummy passphrase.

Note: Such a dummy passphrase is NOT considered a secret that needs to
be protected. If for a certain usage the passphrase is of relevance for
security, then the zkey dummy passphrase option must not be used to store
the passphrase.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Juergen Christ <jchrist@linux.ibm.com>
Reviewed-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Alexander Egorenkov
c239d99379 genprotimg: do not fail on inline warnings caused by glib
gcc's -Werror switch also enables -Werror=inline which leads to a compilation
failure due to inline warnings caused by GLIB macros. To fix it, disable
the conversion of inline warnings into errors.

In file included from buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/lib/glib-2.0/include/glibconfig.h:9,
                 from buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/include/glib-2.0/glib/gtypes.h:32,
                 from buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/include/glib-2.0/glib/galloca.h:32,
                 from buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/include/glib-2.0/glib.h:30,
                 from pv/pv_hdr.c:10:
buildroot/qemu-s390x/build/s390-tools-2.15.1/genprotimg/src/utils/buffer.h: In function ‘pv_hdr_new’:
buildroot/qemu-s390x/host/bin/../s390x-buildroot-linux-gnu/sysroot/usr/include/glib-2.0/glib/gmacros.h:1028:49: error: inlining failed in call to ‘glib_autoptr_clear_Buffer’: call is unlikely and code size would grow [-Werror=inline]
 1028 | #define _GLIB_AUTOPTR_CLEAR_FUNC_NAME(TypeName) glib_autoptr_clear_##TypeName
      |                                                 ^~~~~~~~~~~~~~~~~~~

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Bjoern Walk <bwalk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Alexander Egorenkov
6c6e3a2b0e zipl/boot: fix potential heap overflow in stage2
Current heap size in stage2 is three pages long [0x6000-0x9000] but
get_zeroed_page() assumes it is one page more which might lead to
a heap overflow which will corrupt data located at 0x9000 (stage3
parameters). Calculate the heap size of a stage at run-time
by using the symbols provided by linker.

Furthermore, validate the given address in free_page() to stop illegal
memory accesses.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Alexander Egorenkov
2dca5d193f zipl/boot: fix memory use after free in stage2
Prevent access to freed memory still pointed to by entry.
entry still points into load_page that has been released with free_page.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki
75675ec627 libekmfweb: Make install directory for shared libraries configurable
If LIBDIR is not passed to the make invocation, install shared libraries
to USRLIB64DIR (/usr/lib64/), even though LIBDIR defaults to /lib/. If
LIBDIR is overridden for the make invocation, install shared libraries to
whatever is specified as LIBDIR.

Closes: https://github.com/ibm-s390-tools/s390-tools/issues/98

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki
18bf2cce06 zkey/zkey-ekmfweb: Install KMS plugins into configurable location
Install KMS plugins into a configurable location. The default KMS plugin
location is '/usr/lib64/zkey/', but one can set ZKEYKMSPLUGINDIR on the make
invocation to change the plugin location, e.g. to '/usr/libexec/zkey/'.

Closes: https://github.com/ibm-s390-tools/s390-tools/issues/98

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki
8781dd3e7b zkey-ekmfweb: Fix selection of key properties to set or remove
When some of the key properties are skipped due to null_values_only
being true or false, then the resulting EKMF tag list might be built
incorrectly.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Ingo Franzki
6380e77f28 zkey-ekmfweb: Allow NULL as property value to remove a property
To remove a KMS property function kms_set_key_properties() can be
called with the property value set to NULL. Do not assert for non-NULL
property values.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Marc Hartmayer
733b86c02a genprotimg: remove -Winline cflag
`-Winline` can cause problems with the cleanup functions defined by
glib. Therefore let's remove the cflag for now.

DEBUG: /usr/include/glib-2.0/glib/gmacros.h:1031:43: error: inlining failed in call to 'glib_autoptr_cleanup_STACK_OF_X509_CRL.isra.0': call is unlikely and \
code size would grow [-Werror=inline]
DEBUG:  1031 | #define _GLIB_AUTOPTR_FUNC_NAME(TypeName) glib_autoptr_cleanup_##TypeName

Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
Marc Hartmayer
7827a791c9 genprotimg: add missing return
This should be no problem (if OpenSSL works correctly), because
`crls_download_cb` is only called out of the verification context of
OpenSSL. It's used to look up a CRL and therefore
X509_STORE_CTX_get_current_cert should always return a certificate
since X509_STORE_CTX_get_current_cert returns NULL only if an error
has occurred during the verification (see
https://www.openssl.org/docs/man1.1.0/man3/X509_STORE_CTX_get_current_cert.html).

Fixes: 074de1e14e ("genprotimg: add host-key document verification support")
Signed-off-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-12-15 11:10:50 +01:00
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
Jan Höppner
b098990abe New release s390-tools-2.15.1
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 15:31:59 +01:00
Stefan Haberland
6802b86414 libutil: determine base device address in case of given partition
util_sys_get_dev_addr() returns the device address for a given blockdevice.
This does not work for partitions but some tools rely on the ability to get
the device address for partitions.

Add code that first determines the base device for a partition.

Fixes: 6014d07cb1 ("dasdview/libdasd/zipl: Use util_sys_get_dev_addr() instead of u2s_getbusid()")
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 15:08:29 +01:00
Stefan Haberland
aa8c2945cc zipl: make use of util_sys functions to get base device
Remove the implementation in zipl and use the util_sys one.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 15:08:24 +01:00
Stefan Haberland
fa7a4dafa3 libutil: add function to get base device for blockdevice
Some operations are only possible on base devices not on partitions.
Add functions to determine if a given device is a partition or a base
device and to get the base device to a given partition.

Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
Reviewed-by: Philipp Rudo <prudo@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 15:08:02 +01:00
Jan Höppner
7eb04cdc54 zfcpdump: Fix dump location in README
Commit 724f1fea2c ("Makefile: Rename ZFCPDUMP_PART_* macros") renamed
the zfcpdump image from zfcpdump_part.image to zfcpdump-image. Fix the
image name in the README as well.

Closes: https://github.com/ibm-s390-tools/s390-tools/issues/89
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
d55b787d05 zgetdump: Fix device node determination via sysfs
When using zgetdump on a multi-volume device dump, the sysfs path to
determine the device node is incomplete, resulting in the following
error:

$ zgetdump -i /dev/dasdb1
zgetdump: Could not open "/sys/bus/ccw/devices/0.0.9300/dasdb/dev" (No
such file or directory)

A simple fix would be to add the missing "block" part in the sysfs path.
However, the logic still assumes sysfs links like "block:" that have
been deprecated a decade ago and are no longer present on modern
systems anyway.
Therefore, the logic can greatly be improved. Create a separate function
to determine whether a device is online, remove the logic for "block:"
entries, and use libutil functions to reduce the complexity even further.

Fixes: 70a79fab3c ("zgetdump: Avoid using PATH_MAX")
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
da4fdeeb82 dasdfmt: Set prog_name to last component of program name
In the process of switching to glibc defined error functions it becomes
apparent that self-defined error functions that do special things are
not in line with the output of the glibc functions.

To address this, set the prog_name variable to the last component of the
program name (stored in argv[0]) and guarantee a uniform error output.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
9fe491df27 dasdfmt: Improve error message construction
In check_track_format() the base error message is the same for all cases
but has different additional content depending on which mode dasdfmt is
running.

Currently the message is compiled by using different outputs. To make it
a little bit cleaner and for a better error message handling, construct
the message string completely before passing it to the error() function
for output.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
732b3dddab dasdfmt: Replace ERRMSG_EXIT macro with an error handling function
The ERRMSG_EXIT macro is a bit clunky in its usage and a change is
necessary in order to free memory in error cases.

Create a new function error() that takes only a format string and adds
all other relevant information by itself. This function frees memory
before terminating the program with the EXIT_FAILURE exit code.

This simplifies the error handling for pretty much all calls and makes
the code a bit cleaner.

While at it, the defines EXIT_MISUSE and EXIT_BUSY don't provide any
value. Neither are they documented nor are these standardized. Also, a
parent process is mostly interessted in success or failure only anyway.
Replace these by using only EXIT_FAILURE in the error() function.

Also, change multiline output to a combination of warnx and error to
have a uniformed output. So this:

WARNING: Device is formatted with a different blocksize (4096).
Use --mode=full to perform a clean format.

becomes this:

dasdfmt: WARNING: Device is formatted with a different blocksize (4096).
dasdfmt: Use --mode=full to perform a clean format.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
cb76e39cef dasdfmt: Fix bad file descriptor error when running on symlinks
When calling dasdfmt on device node symlinks like
/dev/disk/by-id/ccw-0X9300, dasdfmt fails with "dasdfmt: the ioctl to get
the blocksize of the device failed (Bad file descriptor)"

This is because before the actual formatting process starts, the disk
will be disabled calling the BIODASDDISABLE ioctl, resulting in the
removal of the symlink. Trying to open this file later in the process to
retrieve e.g. blocksize information results in the mentioned error, as
the file doesn't exist any longer.

This incorrect behaviour was introduced with commit 8826028bdc
("dasdfmt: Use libdasd provided ioctl functions") at which the use of a
globally available file descriptor was omitted. Instead, the ioctl
library functions require a device node to be passed as a function
parameter and will open a file descriptor themselves.
So, before that change, the global file descriptor was always valid even
when the file was removed.

In order to fix this without modifying the behaviour of libdasd,
introduce the two global variables dev_node and dev_path. dev_path is
the original device path entered by the user. dev_node on the other hand
is the reliable device node under /dev/block/ using the major and minor
numbers and is determined in get_device_name().
The dev_path is used for message output only and the dev_node variable
is used for the actual disk operations.

As these two variables are global, the device parameters for several
functions are removed to make the code a bit cleaner.

Fixes: 8826028bdc ("dasdfmt: Use libdasd provided ioctl functions")
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
09be935c54 dasdfmt: Make program relevant information global
The global program options (and other actually globally used
information) are currently passed through via function parameter
whenever this information is needed. However, in reality, this
information is used almost everywhere across the program.

Make this information globally available and get rid of all the
unnecessary function parameters for dasdfmt_info_t. This makes the code
a little bit cleaner and more readable. Also, rename the global struct
to a more suitable name.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
65e18bff67 dasdfmt: Remove function dasdfmt_format
dasdfmt_format() does nothing but calling process_tracks() with the same
parameters. Get rid of it, call process_tracks() directly, and avoid
confusion.

Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
07ab32fa8b dasdfmt: Fix whitespace
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Jan Höppner
353403824b libdasd: Fix dasd_get_host_access_count()
Since commit 75e3afb6a0 ("libdasd: Move get_host_access_count() to
libdasd") dasd_get_host_access_count() reports always 0 as the check for
unsuccessful execution of util_sys_get_dev_addr() is incorrect.
Fix the behaviour by turning the check around.

Fixes: 75e3afb6a0 ("libdasd: Move get_host_access_count() to libdasd")
Reviewed-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Ingo Franzki
8a58389e2f zkey: Add library versioning for libekmfweb and zkey-ekmfweb
Closes: https://github.com/ibm-s390-tools/s390-tools/issues/93

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Alexander Egorenkov
f2cc871b02 genprotimg/boot: disable SSP
SSP cannot work with boot loaders because it requires libc.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Alexander Egorenkov
4dbdc8dfab zipl/boot: disable SSP
SSP cannot work with boot loaders because it requires libc.

Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Ingo Franzki
60900de5e9 zkey: Skip build of zkey-ekmfweb.so if libekmfweb dependencies are missing
zkey-ekmfweb.so requires libekmfweb.so. If libekmfweb.so can not be built
due to missing build requirements, then zkey-ekmfweb.so can't be built
either.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Sven Schnelle
2bba362e9a lsstp: Improve wording and fix typos in man page
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:45 +01:00
Ingo Franzki
76044be98d zkey: Ensure zkey and friends are skipped with HAVE_OPENSSL=0
Building zkey-ekmfweb.so will also trigger to build libekmfweb.so,
which requires OpenSSL. So, skip zkey-ekmfweb.so if HAVE_OPENSSL=0.

zkey-cryptsetup also has a dependency on OpenSSL, so skip it also
if HAVE_OPENSSL=0

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-28 13:22:29 +01:00
Jan Höppner
885ff0a03f Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-15 15:56:15 +02:00
Jan Höppner
25968033bb New release s390-tools-2.15.0
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-15 15:56:15 +02:00
Jan Höppner
1e746990c0 gitignore: Sort ignore list
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-15 15:56:15 +02:00
Jan Höppner
3002e7f754 gitignore: Add zkey and libekmfweb generated files
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-15 15:56:15 +02:00
Thomas Richter
ea10995f4d cpumf/chcpumf.c: Fix version and help printout when CPUMF not installed.
chcpumf does not print out version (option -v) or help text
(option -h) when the CPU Measurement Sampling facility is not
installed. This was different up to and including release 4.10.
Fix this and hounour option -v and option -h even when
the sampling facility is not installed.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Sven Schnelle
8b31319ddf s390-tools: add lsstp utility
A small utility to display the STP information present in sysfs
in a more readable way.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Sven Schnelle
1df4d66387 libutil: add util_file_read_va()
Takes a format string and parses a file accordingly and returns the
parsed values.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Sven Schnelle
37348ef662 libutil: add util_file_read_i()/util_file_read_ui()
These functions parse a sysfs file and return either an
unsigned integer or signed integer.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Thomas Richter
644432ba23 cpumf/man/lscpumf.1: Fix invocation list in man page
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Harald Freudenberger
6eddae9a8a zcrypt: Support new config state with lszcrypt and chzcrypt
lszcrypt now shows a card/queue which is in 'deconfigured' state as
'deconfig' in the STATE column (verbose and non verbose mode).

chzcrypt became two new options: --config-on and --config-off to
switch one or more card devices to 'configured' or 'deconfigured'
state.

Both applications are able to handle older kernels which do now
provide the config sysfs attribute required for this new feature.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Alexander Egorenkov
d19f0915c3 dumpconf: support NVMe dump/reipl device
Signed-off-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Gerald Schaefer
0ecf18b66d ipl_tools: support clear attribute for nvme re-IPL
This patch adds support for the "clear" sysfs attribute for nvme re-IPL,
if available. This attribute allows to control whether the memory should
be cleared on re-IPL.

Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Reviewed-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Fedor Loshakov
26c544998e ziomon/ziorep_printers: fix virtual adapter CSV output
During using of ziorep_utilization utility for generating of CSV format output,
there is one extra comma added after Bus-ID column in virtual adapter report
for each line. This creates one extra column with empty content for each
line. As a result in CSV viewer programs 'qdio utilization max %' column has
no content, all subsequent columns have shifted content from previous
column and the last column has no header. Avoid this situation by deleting
of extra comma.

Before patch application typical line of virtual adapter report looks like:
2020-05-14 13:55:43,0,60,0.0.1906,,0.000000,0.782567,0,0,0.0,321.8,1,1251

After patch application typical line of virtual adapter report looks like:
2020-05-14 13:55:43,0,60,0.0.1906,0.000000,0.782567,0,0,0.0,321.8,1,1251

Signed-off-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
edaa72d68a libekmfweb: Fix sparse and gcc 10 warnings
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
041e3ad996 zkey: Fix sparse, gcc 10, and -Wpedantic warnings
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Eduard Shishkin
301eece09b zipl: fix Error when title is not the first field in BLS file
Problem:
zipl implementation (specifically the scan code) implicitly
assumes that title field is always on the top of BLS file,
and this assumption doesn't comply the bootloader standards:
https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/

Solution:
Before parsing in-memory BLS entry, rearrange its lines as
following: search for a line with keyword "title" and move it
to the top. The scan code is invariant against such transform

Fixes: https://github.com/ibm-s390-tools/s390-tools/issues/64
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
36bd05c4ba zkey-ekmfweb: Add man page for the EKMF Web plugin
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
8aa3f064af zkey-ekmfweb: Import keys from EKMF Web into zkey repository
Import existing keys that are stored in EKMF Web into the zkey repository.
The keys are imported including their associated information, such as
textual description, volumes, sector size, etc.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
48a7da096d zkey-ekmfweb: List keys stored in EKMF Web
Add the possibility to list keys stored in EKMF Web that are eligible to
be used with zkey. The list of keys can be filtered by name, label,
associated volumes, state and export-ability.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
094f52d604 zkey-ekmfweb: Change key state in EKMF Web when removing a key
When a key is removed from the zkey repository, the state of the key in
EKMF web can optionally be changed. Keys are usually not removed in EKMF
Web, but the state of the keys are changed to e.g. DEACTIVATED.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
0626dc7a72 zkey-ekmfweb: Set and get key properties
Add functions to get and set key properties (i.e. custom tags) of
keys stored in EKMF Web. The key properties are set when the information
associated with a key in the zkey repository is changed, e.g. using the
'zkey change' command.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
0180054d07 zkey-ekmfweb: Generate volume encryption keys in EKMF Web
Generate and import volume encryption keys of type CCA-AESCIPHER in
EKMF Web and import them int the zkey repository. Additional information
can be associated with the keys, such as a textual description, volumes
encrypted with the key, sector size of the volumes, etc. This is
also stored in EKMF Web with the keys as custom tags.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
800fe15d21 zkey-ekmfweb: Register the zkey client with EKMF Web
To register the zkey client with EKMF Web, the X.509 certificate
generated with the identity key is sent to EKMF Web, and an identity
key object is generated in EKMF Web with the public key from the
certificate. This identity key is then used to control the export of
keys stored in EKMF Web, and to verify the cryptographically signed
requests sent by the plugin.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
c570f51f5f zkey-ekmfweb: Generate certificate or CSR with identity key
To identify the zkey client with EKMF Web, an X.509 certificate must be
generated using the identity key, and must be made known to EKMF Web.
Either a self signed certificate can be generated, or a certificate
signing request (CSR) that is then passed to a certificate authority
(CA) to have a certificate issued.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
57b70a0fe0 zkey-ekmfweb: Re-encipher the identity key
The identity key of the plugin is a secure key. When the APKA master key
of the associated APQNs is changed, the identity key must be re-enciphered
under the new master key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
cc0d030ce9 zkey-ekmfweb: Generate an identity key
To identify the zkey client with EKMF Web, the plugin generates a secure
ECC or RSA identity key, and stores it in its configuration directory.
This key is then used to cryptographically sign requests sent to EKMF Web.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
9dce6793ab zkey-ekmfweb: Get EKMF Web system settings
Retrieve several settings from EKMF Web after the connection to
EKMF Web has been configured. This includes the EKMF Web server's
public key, which is user later on to verify cryptographically signed
responses. Also the key templates used by EKMF Web to generate keys
for zkey are retrieved, and it is checked if the require feature
'Pervasive Encryption' is available.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
d8054d1a1a zkey-ekmfweb: Add login support
To perform operations in EKMF Web, the user must log in with a EKMF Web
user id and a time based one time passcode. The passcode can be obtained
by the user from the EKMF Web user interface, after logging in into EKMF
Web. That way a two factor authentication is performed. The plugin passes
the passcode to EKMF Web retrieves a bearer token from EKMF Web which it
then uses on subsequent requests to authenticate with EKMF Web. Such a
bearer token is valid for several minutes, thus no re-login is required
for zkey commands run during that time.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
5a9c381225 zkey-ekmfweb: Configure EKMF Web server and TLS options
Allow the user to configure the connection to the EKMF Web server
using the 'zkey kms configure' command. The communication is based
on a RESTful API via HTTPS. Besides the URL of the EKMF Web server,
other TLS related settings can be configured.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
3c6890317a zkey-ekmfweb: Configure APQNs and cross check APKA master keys
The EKMF Web plugin requires APQNs of one or multiple IBM cryptographic
adapters in CCA coprocessor mode to operate. It makes use of secure
RSA and ECC keys, and thus requires the APKA master keys of the CCA APQNs
to be set.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:55 +02:00
Ingo Franzki
1c42b9e3e4 zkey-ekmfweb: Add zkey-ekmfweb KMS plugin
Add support to integrate the external key management system EKMF Web
(IBM Enterprise Key Management Foundation - Web Edition) into zkey by
providing a zkey KMS plugin for EKMF Web. The plugin communicates
with EKMF Web using libekmfweb via a RESTful API.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:12:52 +02:00
Ingo Franzki
beb6a1d6fd zkey: Do not check secure key for C-XLATE flag
The C-XLATE flag determines if the secure key can be used with the
CCA Cipher Text Translate2 verb. Cipher Text Translate2 deciphers
encrypted data under one key and re-enciphers it under another key
without having the data appear in the clear outside the cryptographic
coprocessor. Since this is not a security risk, the check can be
removed.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
40e4b71159 libekmfweb: Get EKMF Web settings and check features
Retrieve EKMF Web settings such as the template names used by
EKMF Web for generating identity keys, as well as volume encryption
keys (XTS and non-XTS). Also check that the EKMF Web server has the
required 'Pervasive Encryption' feature installed.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
8c0f2491a3 libekmfweb: Login to EKMF Web
To perform operations in EKMF Web, the user must log in with a EKMF Web
user id and a time based one time passcode. The passcode can be obtained
by the user from the EKMF Web user interface, after logging in into EKMF
Web. That way a two factor authentication is performed. The client passes
the passcode to EKMF Web retrieves a bearer token from EKMF Web which it
then uses on subsequent requests to authenticate with EKMF Web. Such a
bearer token is valid for several minutes, thus no re-login is required
for zkey commands run during that time.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
e44ae22989 libekmfweb: Add, change and delete key tags
Allow to add, change and delete custom tags of a key. Custom tags
can be used store any kind of textual information with a key. Tags
have a name and a value.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
3be8be4ac7 libekmfweb: Change the key state
EKMF Web maintains a key state for each key. Keys can be in state
PRE-ACTIVATION, ACTIVE, DEACTIVATED, COMPROMISED, DESTROYED, and
DESTROYED-COMPROMISED. Key states can be changed as defined in NIST
Special Publication 800-57 Part 1.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
544c88ca39 libekmfweb: Generate a new key in EKMF Web
Allow to request EKMF Web to generate a new key in its repository.
The newly generated key is generated based on the key template used.
Also, custom properties can be specified that are stored together with
the key, as well as export control information defining who is allowed
to request an export of the key later on.

Besides generating new random keys in EKMF Web, you can also register
the client's public identity key with EKMF Web by generating a new
identity key using an X.509 certificate containing the client's public
key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
c7afb5baec libekmfweb: Retrieve information about keys
Retrieve information about keys managed by EKMF Web, such as the
key algorithm, the key size and type. Additional, the key's tags
are retrieved. Label tags are used to build the label name of a key.
Custom tags can be used to store any kind of textual data together with
a key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
cc9b202a9b libekmfweb: Retrieve information about key templates
Key templates are used by EKMF Web to generate new keys. The template
specifies the key algorithm, the key size, and type (e.g. CCA DATA or
CIPHER). It also determines how a newly generated key is named through
a key label template containing label tags.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
9f99706c26 libekmfweb: Retrieve a key from EKMF Web using an EC-DH protocol
To retrieve a secure key from EKMF Web, a Elliptic-curve Diffie-Hellman
(EC-DH) protocol is used to securely transport the key, without revealing
the key to be transported in clear. The key to be transported remains
encrypted all the time, either encrypted with the master key of the
cryptographic adapter on the source or target side, or with a transport
key, that is derived using the EC-DH key agreement protocol. The transport
key is also a secure key, itself encrypted with the master key of the
cryptographic adapters on both sides.

To generate the transport key, each side generates a new secure ECC
session key with its cryptographic adapter. This session keys are then
used with EC-DH to derive the secure transport key. The secure key to
be transported is then exported by EKMF Web under the transport key, is
sent to the client, and is then imported using the transport key.

The key retrieval request is signed using the identity key of the client.
EKMF Web knows the public key of the client's identity key through a one
time registration process, and can therefore verify the signature with
the client's public key. The response is also signed by the EKMF Web
server's identity key, and the client can verify the signature with the
server's public key that it retrieved once during registration.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
8137128a96 libekmfweb: Generate certificate or CSR with identity key
To identify the client with EKMF Web, an X.509 certificate must be
generated using the identity key, and must be made known to EKMF Web.
Either a self signed certificate can be generated, or a certificate
signing request (CSR) that is then passed to a certificate authority
(CA) to have a certificate issued. The certificate is then used to
register the client with EKMF Web, so that EKMF Web knows the public
part of the client's identity key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
1cdfb4946e libekmfweb: Re-encipher the identity key
The identity key of the client is a secure key enciphered with the
master key of a cryptographic adapter (APQN). When the master key of
the used APQNs is changed, the identity key must be re-enciphered
under the new master key.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
5fb30f1e6f libekmfweb: Generate an identity key
To identify the client with EKMF Web, the client generates a secure
ECC or RSA identity key. This identity key is then used to
cryptographically sign certain requests sent to EKMF Web.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
d8089e69fa libekmfweb: Allow to check if a JSON Web Token (JWT) is expired
When login in with EKMF Web, a bearer token is retrieved from EKMF Web
which is then used on subsequent requests to authenticate with EKMF Web.
Such a bearer token is valid for several minutes, thus no re-login is
required during that time. The bearer token contains a JSON Web Token
(JWT, see RFC7519).

Allow to check such a token if it is still valid, or already expired.
That way a client application can check the token before issuing the next
request, and re-login if needed.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
cbf7f02d69 libekmfweb: Add EKMFWeb client library
The EKMFWeb client library 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.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
91b1692b16 zkey: Add 'zkey kms refresh' command to update a KMS-bound key
Allow to refresh or update a KMS-bound key in the repository.
The secure key is re-imported from the KMS, and optionally also
its properties are updates from the KMS.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
cd8a733c82 zkey: Add 'zkey kms import' command to import keys from a KMS
Allow to import keys that exist in a key management system into the
repository. The key together with its properties is imported.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
bcce1e8d18 zkey: Add 'zkey kms list' command to list keys in a KMS
Allow to list the keys managed by a key management system. The keys
are displayed together with the key properties stored in the KMS.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
f832428109 zkey: Add KMS support for the 'zkey remove' command
When removing a KMS-bound key from the local repository, call the
KMS plugin and let it perform an action in the KMS. Usually keys are
not removed from key management systems, instead the key state is
changed to non-active or similar.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
1d7bb283fd zkey: Update properties in the KMS for change and rename commands
When key properties are changed with the 'change' command, also update
the key properties in the KMS, if the key is bound to a KMS. Do not
allow to change the associated APQNs for KMS bound keys. KMS bound keys
inherit the APQNs from the KMS plugin.

When a key is renamed in the repository, also update the key name
property in the KMS if the key is KMS bound.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
a2f14fcfd7 zkey: Add KMS restrictions for the convert and copy commands
Do not allow to convert a KMS bound key. The key type of a KMS
bound key is determined by what the KMS plugin supports, thus it
can not be converted.

Do only allow to copy a KMS bound key, if the '--local' option is
specified. The result of the copy is a local key, that is not bound
to a KMS.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
bb6a47db55 zkey: Add KMS support for 'zkey generate' command
When a repository that is bound to a key management system, the
keys are generated by the key management system by default. To
generate a local key, add option '--local'.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
35dd59d04c zkey: Add more key management system specific commands
Add the following sub-commands for key management system plugin
handling:
- configure:  Configure a KMS plugin
- reencipher: Re-encipher secure keys used by a KMS plugin

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
3fa511cfb9 zkey: Support KMS plugin specific options
Some commands requires additional options that are to be determined
by the KMS plugin. Add support to let the KMS plugin provide an
option vector per command, and add the options to the already existing
command options.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
c6c4df9697 zkey: Add key management system specific commands
Add command 'kms' and the following sub-commands of it to handle
key management system plugin binding and unbinding:
- plugins: List available/configured KMS plugins
- bind:    Binds a KMS plugin to the repository
- unbind:  Unbinds a KMS plugin from the repository
- info:    Displays information about the currently bound KMS plugin

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
1b0ab844b4 zkey: Add helper functions for KMS-bound keys
Add helper functions to iterate over KMS-bound keys in the repository.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
92fc94f152 zkey: Add KMS key properties and show them with list and validate
To support keys that are bound to a key management system (via a KMS
plugin) add new key properties that reflect this. Display if a key is
bound to a KMS with the 'zkey list' and 'zkey validate' commands.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
f25aaf32b8 zkey: Add support for key management system plugins
Add support to integrate external key management systems into zkey
by using a plugin concept. Add helper functions to load, bind, and
unbind a key management system plugin.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
13f8709ec2 zkey: Add support for sub-commands
Add support for sub-commands to zkey. Sub-commands allow to group a
set of commands within a sub command.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Ingo Franzki
6a860a01c3 libutil: Add -fPIC option for building libutil objects
Add the -fPIC option when building the libutil objects to generate
position-independent code, and allow them to be used in dynamically
loaded shared libraries.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Acked-by: Jan Höppner <hoeppner@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Julian Wiedmann
131a910ac5 ziomon/ziorep_printers: fix typo in csv column headers
s/requqests/requests

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Fedor Loshakov <loshakov@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-10-12 13:11:21 +02:00
Jan Höppner
7007937456 Prepare for next release
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
2020-08-21 12:12:02 +02:00
119 changed files with 31490 additions and 1168 deletions

20
.gitignore vendored
View File

@@ -34,6 +34,11 @@ 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
libekmfweb/libekmfweb.so.1
libekmfweb/libekmfweb.so.1.0
libutil/util_base_example
libutil/util_file_example
libutil/util_libc_example
@@ -44,8 +49,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 +81,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 +96,11 @@ 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/libekmfweb.dep
zkey/ekmfweb/zkey-ekmfweb.so
zkey/zkey
zkey/zkey-cryptsetup
zpcictl/zpcictl

View File

@@ -9,16 +9,19 @@ List of all individuals having contributed content to s390-tools
- Arnd Bergmann
- Axel Wirbser
- Benjamin Block
- Brian C. Lane
- Carsten Otte
- Christian Borntraeger
- Christian Ehrhardt
- Christof Schmitt
- Claudio Imbrenda
- Clemens von Mann
- Colin Walters
- Dan Horak
- Despina Papadopoulou
- Dimitri John Ledkov
- Eberhard Pasch
- Eduard Shishkin
- Einar Lueck
- Eric Sandeen
- Erwin Vicari
@@ -74,11 +77,13 @@ List of all individuals having contributed content to s390-tools
- Michael Mueller
- Mijo Safradin
- Mikhail Zaslonko
- Nikita Dubrovskii
- Niklas Schnelle
- Peter Oberparleiter
- Peter Tiedemann
- Philipp Kern
- Philipp Rudo
- Prashanth Sundararaman
- Rafael Fonseca
- Raimund Schroeder
- Ralph Wuerthner
@@ -97,6 +102,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
@@ -107,7 +113,10 @@ List of all individuals having contributed content to s390-tools
- Tuan Hoang
- Ursula Braun
- Utz Bacher
- Vance Morris
- Vasily Gorbik
- Viktor Mihajlovski
- Vineeth Vijayan
- Volker Sameske
- Wenjia Zhang
- Wolfgang Taphorn

View File

@@ -1,5 +1,79 @@
Release history for s390-tools (MIT version)
--------------------------------------------
* __v2.16.0 (2021-02-19)__
For Linux kernel version: 5.10 / 5.11
Add new tool:
- hsci: New tool to manage HSCI (HiperSockets Converged Interfaces)
Changes of existing tools:
- genprotimg: Add host-key document verification support
- genprotimg: boot: Make boot loader -march=z900 compatible
- libekmfweb: Make install directory for shared libraries configurable
- lsdasd: Add FC Endpoint Security information
- make: Add address sanitizer support
- netboot: Add version information to scripts
- netboot: Bump busybox version in pxelinux.0 build
- zdev: Add FC Endpoint Security information for DASD devices
- zdev: Add build option to update initial RAM-disk by default
- zkey-ekmfweb: Avoid sequence number clash when generating keys
- zkey/zkey-ekmfweb: Install KMS plugins into configurable location
- zkey: Add support to store LUKS2 dummy passphrase in key repository
Bug Fixes:
- dasdfmt: Fix segfault when an incorrect option is specified
- genprotimg: Fix several build issues
- genprotimg: Require argument for 'ramdisk' and 'parmfile' options
- zcryptstats: Fix handling of partial results with many domains
- zfcpdbf: Deal with crash 7.2.9 change in caller name formatting
- zipl/boot: Fix memory use after free in stage2
- zipl/boot: Fix potential heap overflow in stage2
- zipl: Fix reading 4k disk's geometry
* __v2.15.1 (2020-10-28)__
For Linux kernel version: 5.9
Changes of existing tools:
- lsstp: Improve wording and fix typos in man page
- zkey: Ensure zkey and friends are skipped with HAVE_OPENSSL=0
- zkey: Add library versioning for libekmfweb and zkey-ekmfweb
- libutil: Add function to determine base device of a partition block device
Bug Fixes:
- dasdfmt: Fix bad file descriptor error when running on symlinks
- libdasd: Fix dasd_get_host_access_count()
- zipl: Fix multivolume dump
- zgetdump: Fix device node determination via sysfs to work with multivolume again
- genprotimg/boot: Fix build by disabling SSP
- zipl/boot: Fix build by disabling SSP
* __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

View File

@@ -72,7 +72,7 @@ In the examples below we use this fictive identity:
### Setup GitHub and local git
1. Create a fork of this repository by clicking the `Fork` button on the top
right of the [s390-tools](https://github.com/ibm-s390-tools/s390-tools)
right of the [s390-tools](https://github.com/ibm-s390-linux/s390-tools)
main page
2. Clone your forked repository to your local development system
@@ -84,7 +84,7 @@ In the examples below we use this fictive identity:
s390-tools repository on GitHub
```
$ cd s390-tools
~/s390-tools $ git remote add upstream https://github.com/ibm-s390-tools/s390-tools.git
~/s390-tools $ git remote add upstream https://github.com/ibm-s390-linux/s390-tools.git
```
4. Verify your remotes
@@ -92,8 +92,8 @@ In the examples below we use this fictive identity:
~/s390-tools $ git remote -v
origin https://github.com/random-developer/s390-tools.git (fetch)
origin https://github.com/random-developer/s390-tools.git (push)
upstream https://github.com/ibm-s390-tools/s390-tools.git (fetch)
upstream https://github.com/ibm-s390-tools/s390-tools.git (push)
upstream https://github.com/ibm-s390-linux/s390-tools.git (fetch)
upstream https://github.com/ibm-s390-linux/s390-tools.git (push)
```
You now have two remotes: The "origin" remote points to your fork
and the "upstream" remote to the official s390-tools repository.

View File

@@ -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 hsci
SUB_DIRS = $(LIB_DIRS) $(TOOL_DIRS)

View File

@@ -243,6 +243,15 @@ 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.
* hsci:
Manage HiperSockets Converged Interfaces (HSCI).
For more information refer to the following publications:
* "Device Drivers, Features, and Commands" chapter "Useful Linux commands"
@@ -267,17 +276,19 @@ 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` | genprotimg, libekmfweb |
This table lists additional build or install options:
| __COMPONENT__ | __OPTION__ | __TOOLS__ |
|----------------|:----------------:|:-------------------------------:|
| dracut | `HAVE_DRACUT` | zdev |
| initramfs-tools| `HAVE_INITRAMFS` | zdev |
| __COMPONENT__ | __OPTION__ | __TOOLS__ |
|------------------|:----------------------------:|:--------------:|
| dracut | `HAVE_DRACUT` | zdev |
| initramfs-tools | `HAVE_INITRAMFS` | zdev |
| | `ZDEV_ALWAYS_UPDATE_INITRD` | zdev |
The s390-tools build process uses "pkg-config" if available and hard-coded
compiler and linker options otherwise.
@@ -368,6 +379,17 @@ the different tools are provided:
Distributors with different boot or RAM-disk mechanisms should provide
a custom zdev-root-update helper script.
- `ZDEV_ALWAYS_UPDATE_INITRD=1` upon modification of any persistent device
configuration, chzdev updates the initial RAM-disk by default, without any
additional user interaction.
For some distributions, all the configuration attributes must be copied to
the initial RAM-disk. Because the device configuration directives applied
in the initial RAM-disk takes precedence over those stored in the root file-
system. This copying is done usually by explicitly invoking a command. This
build option makes it user-friendly and does this copying without any manual
intervention.
Some functions of zdev require that the following programs are available:
- modprobe (kmod)
@@ -397,3 +419,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.

View File

@@ -299,7 +299,7 @@ static unsigned long dec_to_hex(unsigned long long num)
{
unsigned long res;
asm volatile("cvb %0,%1" : "=d" (res) : "m" (num));
asm volatile("cvb %0,%1" : "=d" (res) : "Q" (num));
return res & 0xffffffff;
}
@@ -307,7 +307,7 @@ static unsigned int hex_to_dec(unsigned int num)
{
unsigned long long res;
asm volatile("cvd %1,%0" : "=m" (res) : "d" (num));
asm volatile("cvd %1,%0" : "=Q" (res) : "d" (num));
return res & 0xffffffff;
}
@@ -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

@@ -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 = 16
PATCHLEVEL = 0
DISTRELEASE = build-$(shell date +%Y%m%d)
S390_TOOLS_RELEASE = $(VERSION).$(RELEASE).$(PATCHLEVEL)-$(DISTRELEASE)
@@ -106,6 +106,11 @@ endif
DEFAULT_CPPFLAGS = -D_GNU_SOURCE
DEFAULT_LDFLAGS = -rdynamic
ifeq ("${ASAN}","1")
DEFAULT_CFLAGS += -fsanitize=address -fno-omit-frame-pointer
DEFAULT_LDFLAGS += -fsanitize=address
endif
#
# Check for build dependency
#
@@ -163,6 +168,7 @@ USRSBINDIR = $(INSTALLDIR)/usr/sbin
USRBINDIR = $(INSTALLDIR)/usr/bin
BINDIR = $(INSTALLDIR)/sbin
LIBDIR = $(INSTALLDIR)/lib
USRLIB64DIR = $(INSTALLDIR)/usr/lib64
SYSCONFDIR = $(INSTALLDIR)/etc
MANDIR = $(INSTALLDIR)/usr/share/man
VARDIR = $(INSTALLDIR)/var
@@ -172,14 +178,24 @@ 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
ZKEYKMSPLUGINDIR = $(USRLIB64DIR)/zkey
ifeq ($(LIBDIR),$(INSTALLDIR)/lib)
SOINSTALLDIR = $(USRLIB64DIR)
else
SOINSTALLDIR = $(LIBDIR)
endif
INSTDIRS = $(USRSBINDIR) $(USRBINDIR) $(BINDIR) $(LIBDIR) $(MANDIR) \
$(SYSCONFDIR) $(SYSCONFDIR)/sysconfig \
$(TOOLS_LIBDIR) $(TOOLS_DATADIR) \
$(ZFCPDUMP_DIR) $(SYSTEMDSYSTEMUNITDIR)
$(ZFCPDUMP_DIR) $(SYSTEMDSYSTEMUNITDIR) \
$(USRLIB64DIR) $(USRINCLUDEDIR) $(ZKEYKMSPLUGINDIR) \
$(SOINSTALLDIR)
OWNER = $(shell id -un)
GROUP = $(shell id -gn)
export INSTALLDIR BINDIR LIBDIR MANDIR OWNER GROUP
export INSTALLDIR BINDIR LIBDIR USRLIB64DIR MANDIR OWNER GROUP
# Special defines for zfcpdump
ZFCPDUMP_IMAGE = zfcpdump-image
@@ -261,6 +277,7 @@ help:
@echo ' G=1 Build with gcov to collect code coverage data'
@echo ' V=1 Generate verbose build output'
@echo ' W=1 Build with higher warning level'
@echo ' ASAN=1 Build with address sanitizer'
@echo ''
@echo 'EXAMPLES'
@echo ' # make clean all D=1 W=1 -j'
@@ -339,6 +356,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
@@ -359,9 +380,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

@@ -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,17 +87,28 @@ 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;
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", min, max) != 2) {
fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE);
if (fscanf(fp, "%ld,%ld", &cur_min_sdb, &cur_max_sdb) != 2) {
fprintf(stderr, "Error: Can not parse file " PERF_SFB_SIZE
"\n");
rc = EXIT_FAILURE;
} else {
if (*min == 0)
*min = cur_min_sdb;
if (*max == 0)
*max = cur_max_sdb;
}
fclose(fp);
return rc;
@@ -196,6 +203,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 +211,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");

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

@@ -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

File diff suppressed because it is too large Load Diff

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)
@@ -65,47 +69,24 @@ static const char mode_str[3][10] = {
"is in invalid format\n",prog_name);}
typedef struct bootstrap1 {
u_int32_t key;
u_int32_t data[6];
u_int32_t key;
u_int32_t data[6];
} __attribute__ ((packed)) bootstrap1_t;
typedef struct bootstrap2 {
u_int32_t key;
u_int32_t data[36];
u_int32_t key;
u_int32_t data[36];
} __attribute__ ((packed)) bootstrap2_t;
typedef struct dasdfmt_info {
dasd_information2_t dasd_info;
int verbosity;
int testmode;
int withoutprompt;
int print_progressbar;
int print_hashmarks, hashstep;
int print_percentage;
int force;
int writenolabel;
int labelspec;
int cdl_format;
int blksize_specified;
int reqsize_specified;
int keep_volser;
int force_host;
int layout_specified;
int check;
int mode_specified;
int ese;
int no_discard;
} dasdfmt_info_t;
/*
C9D7D3F1 000A0000 0000000F 03000000 00000001 00000000 00000000
*/
static bootstrap1_t ipl1 = {
0xC9D7D3F1, {
0x000A0000, 0x0000000F, 0x03000000,
0x00000001, 0x00000000, 0x00000000
}
0xC9D7D3F1, {
0x000A0000, 0x0000000F, 0x03000000,
0x00000001, 0x00000000, 0x00000000
}
};
/*
@@ -116,21 +97,20 @@ C9D7D3F2 07003AB8 40000006 31003ABE 40000005 08003AA0 00000000 06000000
00000000 00000000 00000000 00000000 00000000
*/
static bootstrap2_t ipl2 = {
0xC9D7D3F2, {
0x07003AB8, 0x40000006, 0x31003ABE,
0x40000005, 0x08003AA0, 0x00000000,
0x06000000, 0x20000000, 0x00000000,
0x00000000, 0x00000400, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000
}
0xC9D7D3F2, {
0x07003AB8, 0x40000006, 0x31003ABE,
0x40000005, 0x08003AA0, 0x00000000,
0x06000000, 0x20000000, 0x00000000,
0x00000000, 0x00000400, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000
}
};
#endif /* DASDFMT_H */

View File

@@ -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()

View File

@@ -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
#

View File

@@ -1232,7 +1232,7 @@ static void fdasd_reread_partition_table(fdasd_anchor_t *anc)
if (!anc->silent)
printf("rereading partition table...\n");
if (dasd_reread_partition_table(options.device, 1) != 0) {
if (dasd_reread_partition_table(options.device, 5) != 0) {
fdasd_error(anc, unable_to_ioctl, "Error while rereading "
"partition table.\nPlease reboot!");
}

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

@@ -12,7 +12,7 @@ ALL_CFLAGS := $(NO_PIE_CFLAGS) -Os -g \
-DENABLE_SCLP_ASCII=1 \
-DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
-fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \
-fno-delete-null-pointer-checks \
-fno-delete-null-pointer-checks -fno-stack-protector \
-fexec-charset=IBM1047 -m64 -mpacked-stack \
-mstack-size=4096 -mstack-guard=128 -msoft-float \
-Wall -Wformat-security -Wextra -Werror

View File

@@ -1,5 +1,5 @@
/*
* Entry code for stage 3a boot loader
* Entry code for stage 3a and stage 3b boot loader
*
* Copyright IBM Corp. 2020
*
@@ -24,6 +24,8 @@ _start:
sam64
/* Initialize stack */
lgfi %r15, STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
basr %r13, 0
.Lbase: llgf %r15, .Lstack - .Lbase(%r13)
brasl %r14, initialize
.Lstack: .long STACK_ADDRESS + STACK_SIZE - STACK_FRAME_OVERHEAD
.previous

View File

@@ -21,6 +21,8 @@ _init:
* kernel command line and the address and size of the
* ramdisk. Simply ignore this by starting at 0x11000.
*/
lgfi %r1, STAGE3A_ENTRY
basr %r13, 0
.Lbase: llgf %r1, .Lstage3a_entry - .Lbase(%r13)
br %r1
.Lstage3a_entry: .long STAGE3A_ENTRY
.previous

View File

@@ -31,12 +31,12 @@ stage3b_reloc_start:
sigp %r1, %r0, SIGP_SET_ARCHITECTURE
sam64
.copy_stage3b:
/* Location of stage3b in memory */
larl %r8, stage3b_start
/* Destination for stage3b */
lgfi %r9, STAGE3B_LOAD_ADDRESS
basr %r13, 0
.Lbase: llgf %r9, .Lstage3b_load_address - .Lbase(%r13)
/* Size of stage3b */
lghi %r11, stage3b_end - stage3b_start
@@ -45,8 +45,10 @@ stage3b_reloc_start:
MEMCPY %r9, %r8, %r11
/* Branch to STAGE3B_ENTRY */
lgfi %r9, STAGE3B_ENTRY
llgf %r9, .Lstage3b_entry - .Lbase(%r13)
br %r9
.Lstage3b_load_address: .long STAGE3B_LOAD_ADDRESS
.Lstage3b_entry: .long STAGE3B_ENTRY
stage3b_start:
.incbin "stage3b.bin"
stage3b_end:

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

@@ -15,24 +15,24 @@ INCLUDE_PARMS = $(addprefix -I,$(INCLUDE_PATHS))
WARNINGS := -Wall -Wextra -Wshadow \
-Wcast-align -Wwrite-strings -Wmissing-prototypes \
-Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline \
-Wmissing-declarations -Wredundant-decls -Wnested-externs \
-Wno-long-long -Wuninitialized -Wconversion -Wstrict-prototypes \
-Wpointer-arith -Werror \
-Wpointer-arith -Werror -Wno-error=inline \
$(NULL)
$(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

436
hsci/hsci Executable file
View File

@@ -0,0 +1,436 @@
#!/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
interface are converged into an HSCI interface.
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 1
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 1
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
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
bport=${bport%:}
if [[ $bport == *@* ]]; then
bport=${bport%@*}
fi
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

1071
include/ekmfweb/ekmfweb.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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 @} */

View File

@@ -12,6 +12,11 @@
#ifndef LIB_UTIL_SYS_H
#define LIB_UTIL_SYS_H
#include <stdbool.h>
int util_sys_get_dev_addr(const char *dev, char *addr);
bool util_sys_dev_is_partition(dev_t dev);
int util_sys_get_partnum(dev_t dev);
int util_sys_get_base_dev(dev_t dev, dev_t *base_dev);
#endif /** LIB_UTIL_SYS_H @} */

View File

@@ -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,

View File

@@ -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)

View File

@@ -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

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

@@ -214,7 +214,7 @@ int dasd_get_host_access_count(char *device)
char *path;
long value;
if (!util_sys_get_dev_addr(device, busid))
if (util_sys_get_dev_addr(device, busid) != 0)
return 0;
path = util_path_sysfs("bus/ccw/devices/%s/host_access_count", busid);

92
libekmfweb/Makefile Normal file
View File

@@ -0,0 +1,92 @@
include ../common.mak
VERSION = 1.0
VERM = $(shell echo $(VERSION) | cut -d '.' -f 1)
ifneq (${HAVE_OPENSSL},0)
ifneq (${HAVE_JSONC},0)
ifneq (${HAVE_LIBCURL},0)
BUILD_TARGETS += libekmfweb.so.$(VERSION)
INSTALL_TARGETS += install-libekmfweb.so.$(VERSION)
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.$(VERSION): ALL_CFLAGS += -fPIC
libekmfweb.so.$(VERSION): LDLIBS = -ljson-c -lcrypto -lssl -lcurl -ldl
libekmfweb.so.$(VERSION): ALL_LDFLAGS += -shared -Wl,--version-script=libekmfweb.map \
-Wl,-z,defs,-Bsymbolic -Wl,-soname,libekmfweb.so.$(VERM)
libekmfweb.so.$(VERSION): ekmfweb.o utilities.o cca.o
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
ln -srf libekmfweb.so.$(VERSION) libekmfweb.so.$(VERM)
ln -srf libekmfweb.so.$(VERSION) libekmfweb.so
install-libekmfweb.so.$(VERSION): libekmfweb.so.$(VERSION)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 -T libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERSION)
ln -srf $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERM)
ln -srf $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so.$(VERSION) $(DESTDIR)$(SOINSTALLDIR)/libekmfweb.so
$(INSTALL) -d -m 770 $(DESTDIR)$(USRINCLUDEDIR)/ekmfweb
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 644 $(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.$(VERSION)

1805
libekmfweb/cca.c Normal file

File diff suppressed because it is too large Load Diff

247
libekmfweb/cca.h Normal file
View 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

File diff suppressed because it is too large Load Diff

30
libekmfweb/libekmfweb.map Normal file
View 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: *;
};

3538
libekmfweb/utilities.c Normal file

File diff suppressed because it is too large Load Diff

179
libekmfweb/utilities.h Normal file
View 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

View File

@@ -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

View File

@@ -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;
}

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

@@ -11,17 +11,114 @@
#include <err.h>
#include <errno.h>
#include <linux/fs.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <unistd.h>
#include "lib/util_file.h"
#include "lib/util_libc.h"
#include "lib/util_path.h"
#include "lib/util_sys.h"
/* lstat() doesn't work for sysfs files, a fixed size is therefore inevitable */
#define READLINK_SIZE 256
#define PAGE_SIZE 4096
/**
* Return the partition number of a given partition.
*
* @param[in] dev Device node of interest
*
* @retval int Partition number of the device
* @retval -1 Error when trying to read the partition number.
*/
int util_sys_get_partnum(dev_t dev)
{
int partnum = -1;
char *path;
path = util_path_sysfs("dev/block/%u:%u/partition",
major(dev), minor(dev));
if (util_file_read_i(&partnum, 10, path)) {
warnx("Could not read from path '%s'", path);
goto out;
}
if (partnum <= 0) {
warnx("Bad partition number in '%s'", path);
partnum = -1;
goto out;
}
out:
free(path);
return partnum;
}
/**
* Determine if the given device is a partition.
*
* @param[in] dev Device node of interest
*
* @retval true Device is partition
* @retval false Device is not a partition
*/
bool util_sys_dev_is_partition(dev_t dev)
{
bool is_part;
char *path;
path = util_path_sysfs("dev/block/%u:%u/partition",
major(dev), minor(dev));
is_part = util_path_exists(path);
free(path);
return is_part;
}
/**
* Determine base device
*
* This function determines the base device \p base_dev of a given
* device \p dev. If \p dev is a base device, \p base_dev becomes \p dev.
*
* @param[in] dev Device node of interest
* @param[out] base_dev Identified base device
*
* @retval 0 Success
* @retval -1 Error while reading device information or
* constructed path
*/
int util_sys_get_base_dev(dev_t dev, dev_t *base_dev)
{
int base_major, base_minor;
char buf[PAGE_SIZE];
char *path;
/* check if the device already is a base device */
if (!util_sys_dev_is_partition(dev)) {
*base_dev = makedev(major(dev), minor(dev));
return 0;
}
path = util_path_sysfs("dev/block/%d:%d/../dev",
major(dev), minor(dev));
if (util_file_read_line(buf, sizeof(buf), path)) {
warnx("Could not read from path '%s'", path);
free(path);
return -1;
}
free(path);
if (sscanf(buf, "%i:%i", &base_major, &base_minor) != 2) {
warn("Could not parse major:minor from string '%s'", buf);
return -1;
}
*base_dev = makedev(base_major, base_minor);
return 0;
}
/**
* Identify device address
@@ -44,13 +141,17 @@ int util_sys_get_dev_addr(const char *dev, char *addr)
unsigned int maj, min;
struct stat s;
ssize_t len;
dev_t base;
char *path;
if (stat(dev, &s) != 0)
return -1;
maj = major(s.st_rdev);
min = minor(s.st_rdev);
if (util_sys_get_base_dev(s.st_rdev, &base))
return -1;
maj = major(base);
min = minor(base);
if (S_ISBLK(s.st_mode))
path = util_path_sysfs("dev/block/%u:%u/device", maj, min);

18
lsstp/Makefile Normal file
View 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
View 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 "
\- Show STP configuration information
.SH SYNOPSIS
.BI "lsstp "
.SH DESCRIPTION
.B lsstp
displays information about the current Server Time Protocol (STP) configuration
like coordinated time network (CTN) ID, timing state and leap seconds.
.SH OUTPUT
.TP
.B STP online
Indication of the online state
.TP
.B CTN ID
The ID of the coordinated time network. If it can be decoded as EBCDIC it is shown as an 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 with both STP and external time reference (ETR) nodes.
.TP
.B Stratum
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 by 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 facility. Can be unsynchronized, synchronized or 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|deletion> at
If a leap second insertion or deletion is scheduled in the STP facility, this field shows 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
View 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;
}

View File

@@ -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

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

@@ -21,7 +21,7 @@ ifeq ($(KERNEL_IMAGE),)
$(error Could not find a kernel image under /boot)
endif
BUSYBOX=busybox-1.27.1
BUSYBOX=busybox-1.32.0
BBINSTALL=$(BUSYBOX)/_install
all: $(KERNEL_IMAGE) pxelinux.initramfs

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

@@ -227,6 +227,16 @@ sub get_common
# function name or hexadecimal caller address.
#
$line =~ s/<\s+/</;
#
# Since crash 7.2.9 commit
# https://github.com/crash-utility/crash/commit/f1f43bf355df2564543c39f5d7e13b15c67eb13d
# in support of kernel v5.9 commit 0990d836cecb
# ("s390/debug: debug feature version 3"),
# the symbolic caller function name is left aligned instead of right
# aligned, so now we alternatively have to remove whitespace between
# function name and offset.
#
$line =~ s/<([^+> ]+)[ \t]+/<\1/;
@common = split(/\s+/, $line);
#
# Process symbolic kernel module name, if necessary.
@@ -388,6 +398,17 @@ sub get_foreign_records
# caller address.
#
$line =~ s/<\s+/</;
#
# Since crash 7.2.9 commit
# https://github.com/crash-utility/crash/commit/f1f43bf355df2564543c39f5d7e13b15c67eb13d
# in support of kernel v5.9 commit 0990d836cecb
# ("s390/debug: debug feature version 3"),
# the symbolic caller function name is left aligned
# instead of right aligned, so now we alternatively
# have to remove whitespace between function name and
# offset.
#
$line =~ s/<([^+> ]+)[ \t]+/<\1/;
my @raw_rec = split(/\s+/,($line =~ /[|]/) ?
substr($line, 0, index($line, '|')):
$line);

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

@@ -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)

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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");
}

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

@@ -12,6 +12,6 @@
#include "exit_code.h"
exit_code_t root_check(void);
exit_code_t initrd_check(bool all_pers);
#endif /* ROOT_H */

View File

@@ -4,6 +4,16 @@ include ../../common.mak
ALL_CPPFLAGS += -I ../include -std=gnu99 -Wno-unused-parameter \
-Wno-missing-field-initializers
# Adding ZDEV_ALWAYS_UPDATE_INITRD=1 option will update the initial RAM-disk
# without the user interaction upon the modification of a persistent device
# configuration.
ifeq ($(ZDEV_ALWAYS_UPDATE_INITRD),1)
ALL_CPPFLAGS += -DZDEV_ALWAYS_UPDATE_INITRD=true
else
ALL_CPPFLAGS += -DZDEV_ALWAYS_UPDATE_INITRD=false
endif
# Core
chzdev_objects += attrib.o chzdev.o device.o devnode.o devtype.o exit_code.o \
export.o hash.o inuse.o misc.o namespace.o opts.o path.o \

View File

@@ -3027,7 +3027,7 @@ int main(int argc, char *argv[])
!dryrun) {
/* If the root device/device type or early devices have been
* modified, additional work might be necessary. */
rc = root_check();
rc = initrd_check(ZDEV_ALWAYS_UPDATE_INITRD);
if (rc && !drc)
drc = 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

@@ -58,11 +58,50 @@ static void add_early_removed(struct util_list *selected)
}
}
static void add_pers_removed(struct util_list *strlist)
{
int i, j;
struct devtype *dt;
struct subtype *st;
struct device *dev;
for (i = 0; devtypes[i]; i++) {
dt = devtypes[i];
for (j = 0; dt->subtypes[j]; j++) {
st = dt->subtypes[j];
util_list_iterate(&st->devices->hash.list, dev) {
if (dev->persistent.deconfigured) {
strlist_add(strlist, "%s %s",
dev->subtype->devname, dev->id);
}
}
}
}
}
static bool is_zdev_early_0(struct selected_dev_node *sel)
{
struct setting *s;
struct device *dev;
dev = device_list_find(sel->st->devices, sel->id, NULL);
if (!dev)
return false;
s = setting_list_find(dev->persistent.settings,
internal_attr_early.name);
if (!s)
return false;
if (s->specified && strcmp(s->value, "0") == 0)
return true;
return false;
}
/* Determine if initial RAM-disk needs updating. If so, run the corresponding
* scripts if available. */
exit_code_t root_check(void)
exit_code_t initrd_check(bool all_pers)
{
struct util_list *selected, *params, *mod = NULL;
struct util_list *selected, *params, *mod = strlist_new();
struct selected_dev_node *sel;
struct device *dev;
char *params_str;
@@ -76,6 +115,20 @@ exit_code_t root_check(void)
/* Get list of devices that provide the root device or require
* early configuration. */
selected = selected_dev_list_new();
if (all_pers) {
/* Add all persistently configured devices. */
select = select_opts_new();
select->configured = 1;
select_devices(select, selected, 1, 0, 0, config_persistent,
scope_mandatory, err_ignore);
select_opts_free(select);
/* Ensure that removed devices are considered. */
add_pers_removed(mod);
goto check_mod;
}
/* First add devices that had zdev:early removed or changed to 0.
* The subsequent call to select_devices() will filter out any
* duplicates. */
@@ -95,8 +148,8 @@ exit_code_t root_check(void)
err_ignore);
select_opts_free(select);
check_mod:
/* Determine if any of the devices or device types has been modified. */
mod = strlist_new();
util_list_iterate(selected, sel) {
dt = sel->st->devtype;
@@ -127,17 +180,22 @@ exit_code_t root_check(void)
goto out;
}
/* Ask for confirmation. */
if (!confirm("Update initial RAM-disk now?")) {
rc = EXIT_ABORTED;
goto out;
if (!all_pers) {
/* Ask for confirmation. */
if (!confirm("Update initial RAM-disk now?")) {
rc = EXIT_ABORTED;
goto out;
}
}
/* Build the command line. */
params = strlist_new();
util_list_iterate(selected, sel) {
strlist_add(params, "%s", sel->st->name);
strlist_add(params, "%s", sel->id);
/* From the selected list, remove the devices with zdev:early=0 */
if (!is_zdev_early_0(sel)) {
strlist_add(params, "%s", sel->st->name);
strlist_add(params, "%s", sel->id);
}
}
params_str = strlist_flatten(params, " ");
strlist_free(params);

View File

@@ -407,7 +407,7 @@ void dfi_mem_chunk_add_vol(u64 start, u64 size, void *data,
if (size == 0)
return;
mem_chunk_create(&l.mem_phys, start, size, data, read_fn, free_fn);
mem_chunk_create(&l.mem_virt, start, size, data, read_fn, free_fn);
mem_chunk_create(&l.mem_virt, start, size, data, read_fn, NULL);
l.mem_virt.chunk_cache->volnr = volnr;
}

View File

@@ -42,6 +42,8 @@ static int pt_load_add(Elf64_Phdr *phdr)
STDERR("Dump file \"%s\" is a user space core dump\n",
g.opts.device);
}
if (phdr->p_offset + phdr->p_filesz > zg_size(g.fh))
return -EINVAL;
if (phdr->p_filesz == 0) {
/* Add zero memory chunk */
dfi_mem_chunk_add(phdr->p_paddr, phdr->p_memsz, NULL,
@@ -52,8 +54,6 @@ static int pt_load_add(Elf64_Phdr *phdr)
dfi_mem_chunk_add(phdr->p_paddr, phdr->p_memsz, off_ptr,
dfi_elf_mem_chunk_read_fn, zg_free);
}
if (phdr->p_offset + phdr->p_filesz > zg_size(g.fh))
return -EINVAL;
return 0;
}

View File

@@ -21,6 +21,7 @@
#include <time.h>
#include <unistd.h>
#include "lib/util_file.h"
#include "lib/util_path.h"
#include "zgetdump.h"
@@ -98,6 +99,24 @@ static void em_init(struct vol *vol)
l.dump_incomplete = 1;
}
/*
* Check whether a device with a given busid is online
*/
static unsigned int dev_is_online(const char *busid)
{
unsigned int online;
char *path;
path = util_path_sysfs("%s/%s/online", SYSFS_BUSDIR, busid);
if (util_file_read_ui(&online, 10, path) != 0) {
warnx("Could not open \"%s\" (%s)", path, strerror(errno));
free(path);
exit(EXIT_FAILURE);
}
free(path);
return online;
}
/*
* Check sysfs, whether a device specified by its bus ID is defined and online.
@@ -106,67 +125,40 @@ static void em_init(struct vol *vol)
static enum dev_status dev_from_busid(char *bus_id, dev_t *dev)
{
struct dirent *direntp;
int fh, minor, major;
int minor, major;
char buf[10];
DIR *fh_dir;
char *sysfs;
sysfs = util_path_sysfs("%s/%s", SYSFS_BUSDIR, bus_id);
fh_dir = opendir(sysfs);
free(sysfs);
if (!fh_dir)
if (!util_path_is_dir(sysfs)) {
free(sysfs);
return DEV_UNDEFINED;
sysfs = util_path_sysfs("%s/%s/online", SYSFS_BUSDIR, bus_id);
fh = open(sysfs, O_RDONLY);
if (fh == -1) {
warnx("Could not open \"%s\" (%s)", sysfs, strerror(errno));
goto err;
}
free(sysfs);
if (read(fh, buf, 1) == -1)
ERR_EXIT_ERRNO("Could not read online attribute");
close(fh);
if (buf[0] != '1')
if (!dev_is_online(bus_id))
return DEV_OFFLINE;
while ((direntp = readdir(fh_dir)))
if (strncmp(direntp->d_name, "block:", 6) == 0)
break;
closedir(fh_dir);
if (direntp == NULL) {
sysfs = util_path_sysfs("%s/%s/block", SYSFS_BUSDIR, bus_id);
fh_dir = opendir(sysfs);
if (!fh_dir) {
warnx("Could not open \"%s\" (%s) ",
sysfs, strerror(errno));
goto err;
}
while ((direntp = readdir(fh_dir)))
if (strncmp(direntp->d_name, "dasd", 4) == 0)
break;
closedir(fh_dir);
if (direntp == NULL) {
warnx("Problem with contents of \"%s\"", sysfs);
goto err;
}
free(sysfs);
}
sysfs = util_path_sysfs("%s/%s/%s/dev",
SYSFS_BUSDIR, bus_id, direntp->d_name);
fh = open(sysfs, O_RDONLY);
if (fh == -1) {
warnx("Could not open \"%s\" (%s)", sysfs, strerror(errno));
sysfs = util_path_sysfs("%s/%s/block", SYSFS_BUSDIR, bus_id);
fh_dir = opendir(sysfs);
if (!fh_dir) {
warnx("Could not open \"%s\" (%s) ", sysfs, strerror(errno));
goto err;
}
if (read(fh, buf, sizeof(buf)) == -1) {
while ((direntp = readdir(fh_dir)))
if (strncmp(direntp->d_name, "dasd", 4) == 0)
break;
if (direntp == NULL) {
warnx("Problem with contents of \"%s\"", sysfs);
goto err;
}
if (util_file_read_line(buf, sizeof(buf), "%s/%s/dev", sysfs, direntp->d_name)) {
warnx("Could not read dev file (%s)", strerror(errno));
goto err;
}
close(fh);
closedir(fh_dir);
if (sscanf(buf, "%i:%i", &major, &minor) != 2) {
warnx("Malformed content of \"%s\": %s", sysfs, buf);
goto err;
@@ -178,6 +170,8 @@ static enum dev_status dev_from_busid(char *bus_id, dev_t *dev)
return DEV_ONLINE;
err:
if (fh_dir)
closedir(fh_dir);
free(sysfs);
exit(EXIT_FAILURE);
}

View File

@@ -280,6 +280,9 @@ off_t zg_seek(struct zg_fh *zg_fh, off_t off, enum zg_check check)
{
off_t rc;
if (off >= zg_fh->sb.st_size)
ERR_EXIT("Trying to seek past file end \"%s\"", zg_fh->path);
rc = lseek(zg_fh->fh, off, SEEK_SET);
if (rc == -1 && check != ZG_CHECK_NONE)
ERR_EXIT_ERRNO("Could not seek \"%s\"", zg_fh->path);

View File

@@ -3,6 +3,9 @@ include ../common.mak
CPIOINIT = $(call echocmd," CPIOINI ",/$@)./cpioinit
INSTALL_SCRIPTS = 10-zfcpdump.install
ALL_CFLAGS += -fno-sanitize=all
ALL_LDFLAGS += -fno-sanitize=all
ifeq (${HAVE_LIBC_STATIC},0)
all:

View File

@@ -31,7 +31,7 @@ configuration.
* Issue "make bzImage" to build the zfcpdump kernel image.
In a Linux distribution the zfcpdump enabled kernel image must be copied to
/lib/s390-tools/zfcpdump/zfcpdump_part.image, where the s390 zipl tool is
/lib/s390-tools/zfcpdump/zfcpdump-image, where the s390 zipl tool is
looking for the dump kernel when preparing a SCSI dump disk.
Create and install initrd

View File

@@ -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");

View File

@@ -7,10 +7,11 @@ INCLUDE_PARMS := $(addprefix -I,$(INCLUDE_PATHS))
ALL_CFLAGS = $(NO_PIE_CFLAGS) -Os -g $(INCLUDE_PARMS) \
-DS390_TOOLS_RELEASE=$(S390_TOOLS_RELEASE) \
-fno-builtin -ffreestanding -fno-asynchronous-unwind-tables \
-fno-delete-null-pointer-checks \
-fno-delete-null-pointer-checks -fno-stack-protector \
-fexec-charset=IBM1047 -m64 -mpacked-stack \
-mstack-size=4096 -mstack-guard=128 -msoft-float \
-W -Wall -Wformat-security
-W -Wall -Wformat-security -fno-sanitize=all
ALL_LDFLAGS += -fno-sanitize=all
FILES = fba0.bin fba1b.bin fba2.bin \
eckd0_ldl.bin eckd0_cdl.bin \

View File

@@ -449,13 +449,14 @@ void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count)
* block number
*/
unsigned long write_dump_segment(unsigned long blk,
struct df_s390_dump_segm_hdr *segm,
unsigned long zero_page)
struct df_s390_dump_segm_hdr *segm)
{
unsigned long addr, start_blk, blk_count;
unsigned long addr, start_blk, blk_count, zero_page;
/* Write the dump segment header itself (1 page) */
zero_page = get_zeroed_page();
writeblock(blk, (unsigned long)segm, m2b(PAGE_SIZE), zero_page);
free_page(zero_page);
blk += m2b(PAGE_SIZE);
/* Write the dump segment */
addr = segm->start;
@@ -464,7 +465,9 @@ unsigned long write_dump_segment(unsigned long blk,
/* Remaining blocks to write */
blk_count = m2b(segm->len) - (blk - start_blk);
blk_count = MIN(blk_count, eckd_blk_max);
zero_page = get_zeroed_page();
writeblock(blk, addr, blk_count, zero_page);
free_page(zero_page);
progress_print(addr);
blk += blk_count;
addr += b2m(blk_count);

View File

@@ -48,7 +48,6 @@ void writeblock(unsigned long blk, unsigned long addr, unsigned long blk_count,
unsigned long zero_page);
void readblock(unsigned long blk, unsigned long addr, unsigned long blk_count);
unsigned long write_dump_segment(unsigned long blk,
struct df_s390_dump_segm_hdr *segm,
unsigned long zero_page);
struct df_s390_dump_segm_hdr *segm);
#endif /* ECKD2DUMP_H */

View File

@@ -192,10 +192,13 @@ void dt_device_enable(void)
* Check for the volume timestamp and validate the dump signature
* before writing a dump.
*/
static void check_volume(unsigned long page)
static void check_volume(void)
{
struct mvdump_parm_table *mvdump_table_new;
struct df_s390_hdr *hdr_new;
unsigned long page;
page = get_zeroed_page();
/*
* Check whether parameter table on dump device has a valid
@@ -222,6 +225,8 @@ static void check_volume(unsigned long page)
if (dump_hdr->magic != hdr_new->mvdump_sign)
panic(ENOSIGN, "Wrong signature");
}
free_page(page);
}
/*
@@ -229,10 +234,10 @@ static void check_volume(unsigned long page)
* address to write for the next volume or memory size if the dump ended
* on this volume
*/
static unsigned long write_volume(unsigned long addr, unsigned long page,
static unsigned long write_volume(unsigned long addr,
struct df_s390_dump_segm_hdr *dump_segm)
{
unsigned long free_space, blk;
unsigned long free_space, blk, page;
/*
* Write dump header
@@ -245,7 +250,7 @@ static unsigned long write_volume(unsigned long addr, unsigned long page,
* header and the end marker)
*/
free_space = b2m(device.blk_end - blk + 1) - b2m(2);
memset((void *) page, 0, PAGE_SIZE);
/*
* Write dump data
*/
@@ -257,7 +262,7 @@ static unsigned long write_volume(unsigned long addr, unsigned long page,
addr = find_dump_segment(addr, dump_hdr->mem_size,
ROUND_DOWN(free_space, MIB),
dump_segm);
blk = write_dump_segment(blk, dump_segm, page);
blk = write_dump_segment(blk, dump_segm);
/* Update free space left on vol */
free_space -= dump_segm->len;
/* Reserve one block for the next segment header */
@@ -267,8 +272,10 @@ static unsigned long write_volume(unsigned long addr, unsigned long page,
/* Check if no more dump segments follow */
if (dump_segm->stop_marker) {
/* Write end marker */
page = get_zeroed_page();
df_s390_em_page_init(page);
writeblock(blk, page, 1, 0);
free_page(page);
return dump_hdr->mem_size;
}
/*
@@ -286,19 +293,18 @@ static unsigned long write_volume(unsigned long addr, unsigned long page,
void dt_dump_mem(void)
{
struct df_s390_dump_segm_hdr *dump_segm;
unsigned long addr, page;
unsigned long addr;
dump_hdr->mvdump_sign = DF_S390_MAGIC_EXT;
dump_hdr->mvdump = 1;
addr = 0;
total_dump_size = 0;
page = get_zeroed_page();
dump_segm = (void *)get_zeroed_page();
while (1) {
printf("Dumping to: 0.%x.%04x", device.sid.ssid, device.devno);
check_volume(page);
addr = write_volume(addr, page, dump_segm);
check_volume();
addr = write_volume(addr, dump_segm);
if (addr == dump_hdr->mem_size)
break;
/*
@@ -312,7 +318,6 @@ void dt_dump_mem(void)
set_device(device.sid, DISABLED);
dt_device_enable();
}
progress_print(addr);
free_page(page);
free_page(__pa(dump_segm));
progress_print(addr);
}

View File

@@ -66,7 +66,6 @@ void dt_dump_mem(void)
struct df_s390_dump_segm_hdr *dump_segm;
blk = device.blk_start;
page = get_zeroed_page();
dump_segm = (void *)get_zeroed_page();
/* Write dump header */
@@ -79,18 +78,19 @@ void dt_dump_mem(void)
end = dump_hdr->mem_size;
while (addr < end) {
addr = find_dump_segment(addr, end, 0, dump_segm);
blk = write_dump_segment(blk, dump_segm, page);
blk = write_dump_segment(blk, dump_segm);
total_dump_size += dump_segm->len;
if (dump_segm->stop_marker) {
addr = end;
break;
}
}
free_page(__pa(dump_segm));
progress_print(addr);
/* Write end marker */
page = get_zeroed_page();
df_s390_em_page_init(page);
writeblock(blk, page, 1, 0);
free_page(page);
free_page(__pa(dump_segm));
}

View File

@@ -141,13 +141,14 @@ static void writeblock_fba(unsigned long blk, unsigned long addr,
* block number
*/
unsigned long write_dump_segment_fba(unsigned long blk,
struct df_s390_dump_segm_hdr *dump_segm,
unsigned long zero_page)
struct df_s390_dump_segm_hdr *dump_segm)
{
unsigned long addr, start_blk, blk_count;
unsigned long addr, start_blk, blk_count, zero_page;
/* Write the dump segment header itself (1 page) */
zero_page = get_zeroed_page();
writeblock_fba(blk, __pa(dump_segm), BLK_PER_PAGE, zero_page);
free_page(zero_page);
blk += BLK_PER_PAGE;
/* Write the dump segment */
addr = dump_segm->start;
@@ -156,7 +157,9 @@ unsigned long write_dump_segment_fba(unsigned long blk,
/* Remaining blocks to write */
blk_count = m2b(dump_segm->len) - (blk - start_blk);
blk_count = MIN(blk_count, BLK_PWRT);
zero_page = get_zeroed_page();
writeblock_fba(blk, addr, blk_count, zero_page);
free_page(zero_page);
progress_print(addr);
blk += blk_count;
addr += b2m(blk_count);
@@ -198,7 +201,6 @@ void dt_dump_mem(void)
ccw_program_init();
blk = device.blk_start;
page = get_zeroed_page();
dump_segm = (void *)get_zeroed_page();
/* Write dump header */
@@ -211,18 +213,19 @@ void dt_dump_mem(void)
end = dump_hdr->mem_size;
while (addr < end) {
addr = find_dump_segment(addr, end, 0, dump_segm);
blk = write_dump_segment_fba(blk, dump_segm, page);
blk = write_dump_segment_fba(blk, dump_segm);
total_dump_size += dump_segm->len;
if (dump_segm->stop_marker) {
addr = end;
break;
}
}
free_page(__pa(dump_segm));
progress_print(addr);
/* Write end marker */
page = get_zeroed_page();
df_s390_em_page_init(page);
writeblock_fba(blk, page, 1, 0);
free_page(page);
free_page(__pa(dump_segm));
}

View File

@@ -32,9 +32,10 @@ struct ex_table_entry {
};
#define MEM_ALLOC_START ((unsigned long) __heap_start)
#define MEM_ALLOC_CNT 4
#define MEM_ALLOC_END ((unsigned long) __heap_stop)
#define MEM_ALLOC_MAX 4
static uint8_t mem_page_alloc_vec[MEM_ALLOC_CNT];
static uint8_t mem_page_alloc_vec[MEM_ALLOC_MAX];
/*
* Initialize memory with value
@@ -417,10 +418,11 @@ void printf(const char *fmt, ...)
*/
unsigned long get_zeroed_page(void)
{
const int page_count = MIN(MEM_ALLOC_MAX, (int)((MEM_ALLOC_END - MEM_ALLOC_START) / PAGE_SIZE));
unsigned long addr;
int i;
for (i = 0; i < MEM_ALLOC_CNT; i++) {
for (i = 0; i < page_count; i++) {
if (mem_page_alloc_vec[i] != 0)
continue;
addr = MEM_ALLOC_START + i * PAGE_SIZE;
@@ -436,6 +438,9 @@ unsigned long get_zeroed_page(void)
*/
void free_page(unsigned long addr)
{
if (addr < MEM_ALLOC_START || addr >= MEM_ALLOC_END)
libc_stop(EINTERNAL);
mem_page_alloc_vec[(addr - MEM_ALLOC_START) / PAGE_SIZE] = 0;
}

View File

@@ -90,6 +90,7 @@ void start(void)
void *load_address;
struct component_entry *entry;
disk_blockptr_t *blockptr;
uint64_t load_psw;
void *load_page;
int config_nr;
@@ -133,11 +134,13 @@ void start(void)
if (entry->type != COMPONENT_EXECUTE)
panic(EWRONGTYPE, "");
load_psw = entry->address.load_psw;
free_page((unsigned long)load_page);
io_irq_disable();
set_device(subchannel_id, DISABLED);
execute(entry->address.load_psw);
execute(load_psw);
}
void panic_notify(unsigned long UNUSED(reason))

View File

@@ -25,6 +25,7 @@
#include <linux/fiemap.h>
#include "lib/util_proc.h"
#include "lib/util_sys.h"
#include "disk.h"
#include "error.h"
@@ -89,88 +90,6 @@ disk_determine_dasd_type(struct disk_info *data,
return 0;
}
static int blkext_get_partnum(dev_t dev)
{
char path[PATH_MAX], *buf;
int dev_major, dev_minor, partnum = -1;
dev_major = major(dev);
dev_minor = minor(dev);
snprintf(path, PATH_MAX, "/sys/dev/block/%d:%d/partition",
dev_major, dev_minor);
if (misc_read_special_file(path, &buf, NULL, 1)) {
error_text("Could not read from path '%s'", path);
return -1;
}
partnum = atoi(buf);
free(buf);
if (partnum < 0) {
error_text("Bad partition number in '%s'", path);
return -1;
}
return partnum;
}
static int blkext_is_base_device(dev_t dev)
{
int dev_major, dev_minor;
char path[PATH_MAX];
struct stat stats;
dev_major = major(dev);
dev_minor = minor(dev);
snprintf(path, PATH_MAX, "/sys/dev/block/%d:%d/partition",
dev_major, dev_minor);
return (stat(path, &stats));
}
static int blkext_get_base_dev(dev_t dev, dev_t *base_dev)
{
int base_major, base_minor;
char dev_path[PATH_MAX], base_path[PATH_MAX];
char *temp_path, *buf;
misc_asprintf(&temp_path, "/sys/dev/block/%d:%d", major(dev), minor(dev));
if (!realpath(temp_path, dev_path)) {
error_reason(strerror(errno));
error_text("Could not resolve link %s", temp_path);
free(temp_path);
return -1;
}
free(temp_path);
misc_asprintf(&temp_path, "%s/..", dev_path);
if (!realpath(temp_path, base_path)) {
error_reason(strerror(errno));
error_text("Could not resolve path %s", temp_path);
free(temp_path);
return -1;
}
free(temp_path);
misc_asprintf(&temp_path, "%s/dev", base_path);
if (misc_read_special_file(temp_path, &buf, NULL, 1)) {
error_text("Could not read from path '%s'", temp_path);
free(temp_path);
return -1;
}
free(temp_path);
if (sscanf(buf, "%i:%i", &base_major, &base_minor) != 2) {
error_text("Could not parse major:minor from string '%s'", buf);
free(buf);
return -1;
}
free(buf);
*base_dev = makedev(base_major, base_minor);
return 0;
}
/* Return non-zero for ECKD type. */
int
disk_is_eckd(disk_type_t type)
@@ -492,15 +411,15 @@ disk_get_info(const char* device, struct job_target_data* target,
data->devno = -1;
data->type = disk_type_scsi;
if (blkext_is_base_device(stats.st_rdev)) {
data->device = stats.st_rdev;
data->partnum = 0;
} else {
if (blkext_get_base_dev(stats.st_rdev, &data->device))
if (util_sys_dev_is_partition(stats.st_rdev)) {
if (util_sys_get_base_dev(stats.st_rdev, &data->device))
goto out_close;
data->partnum = blkext_get_partnum(stats.st_rdev);
data->partnum = util_sys_get_partnum(stats.st_rdev);
if (data->partnum == -1)
goto out_close;
} else {
data->device = stats.st_rdev;
data->partnum = 0;
}
} else {
/* Driver name is unknown */
@@ -525,6 +444,9 @@ type_determined:
}
/* Convert device size to size in physical blocks */
data->phy_blocks = devsize / (data->phy_block_size / 512);
/* Adjust start on SCSI according to block_size. device-mapper devices are skipped */
if (data->type == disk_type_scsi && target->targetbase == NULL)
data->geo.start = data->geo.start / (data->phy_block_size / 512);
if (data->partnum != 0)
data->partition = stats.st_rdev;
/* Try to get device name */

View File

@@ -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) {

View File

@@ -3,6 +3,11 @@ include ../common.mak
ifneq (${HAVE_OPENSSL},0)
BUILD_TARGETS += zkey
INSTALL_TARGETS += install-zkey
ifneq (${HAVE_JSONC},0)
ifneq (${HAVE_LIBCURL},0)
SUB_DIRS += ekmfweb
endif
endif
else
BUILD_TARGETS += zkey-skip
INSTALL_TARGETS += zkey-skip
@@ -10,9 +15,14 @@ endif
ifneq (${HAVE_CRYPTSETUP2},0)
ifneq (${HAVE_JSONC},0)
BUILD_TARGETS += zkey-cryptsetup
INSTALL_TARGETS += install-zkey-cryptsetup
CPPFLAGS += -DHAVE_LUKS2_SUPPORT
ifneq (${HAVE_OPENSSL},0)
BUILD_TARGETS += zkey-cryptsetup
INSTALL_TARGETS += install-zkey-cryptsetup
CPPFLAGS += -DHAVE_LUKS2_SUPPORT
else
BUILD_TARGETS += zkey-cryptsetup-skip-openssl
INSTALL_TARGETS += zkey-cryptsetup-skip-openssl
endif
else
BUILD_TARGETS += zkey-cryptsetup-skip-jsonc
INSTALL_TARGETS += zkey-cryptsetup-skip-jsonc
@@ -24,6 +34,8 @@ endif
libs = $(rootdir)/libutil/libutil.a
CFLAGS += -DKMS_PLUGIN_LOCATION=\"$(ZKEYKMSPLUGINDIR)\"
detect-libcryptsetup.dep:
echo "#include <libcryptsetup.h>" > detect-libcryptsetup.dep
echo "#ifndef CRYPT_LUKS2" >> detect-libcryptsetup.dep
@@ -62,7 +74,10 @@ zkey-cryptsetup-skip-cryptsetup2:
zkey-cryptsetup-skip-jsonc:
echo " SKIP zkey-cryptsetup due to HAVE_JSONC=0"
all: $(BUILD_TARGETS)
zkey-cryptsetup-skip-openssl:
echo " SKIP zkey-cryptsetup due to HAVE_OPENSSL=0"
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 +88,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 +102,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

View File

@@ -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;

View File

@@ -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

53
zkey/ekmfweb/Makefile Normal file
View File

@@ -0,0 +1,53 @@
include ../../common.mak
VERSION = 1.0
VERM = $(shell echo $(VERSION) | cut -d '.' -f 1)
all: zkey-ekmfweb.so
libs = $(rootdir)/libutil/libutil.a
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
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 = -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)
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
install-libekmfweb.dep:
$(MAKE) -C $(rootdir)/libekmfweb/ TOPDIR=$(TOPDIR) ARCH=$(ARCH) install
touch install-libekmfweb.dep
libekmfweb.dep:
$(MAKE) -C $(rootdir)/libekmfweb/ TOPDIR=$(TOPDIR) ARCH=$(ARCH) all
touch 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)$(ZKEYKMSPLUGINDIR)
$(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 -T zkey-ekmfweb.so $(DESTDIR)$(ZKEYKMSPLUGINDIR)/zkey-ekmfweb.so
clean:
rm -f *.o zkey-ekmfweb.so install-libekmfweb.dep libekmfweb.dep
.PHONY: all install clean

497
zkey/ekmfweb/zkey-ekmfweb.1 Normal file
View 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 \-e ", " \-\-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 name 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 certificate 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 certificate 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 word '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.

Some files were not shown because too many files have changed in this diff Show More