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>
This commit is contained in:
Harald Freudenberger
2020-10-05 18:03:26 +02:00
committed by Jan Höppner
parent d19f0915c3
commit 6eddae9a8a
4 changed files with 256 additions and 69 deletions

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