diff --git a/zconf/zcrypt/chzcrypt.8 b/zconf/zcrypt/chzcrypt.8 index 2697c961..a73ff27d 100644 --- a/zconf/zcrypt/chzcrypt.8 +++ b/zconf/zcrypt/chzcrypt.8 @@ -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 +[...] ) +.TP +.B chzcrypt .RB "[ " -p " | " -n " ] [ " -t .I ] @@ -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 -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) diff --git a/zconf/zcrypt/chzcrypt.c b/zconf/zcrypt/chzcrypt.c index 2fc8441a..78ecc38e 100644 --- a/zconf/zcrypt/chzcrypt.c +++ b/zconf/zcrypt/chzcrypt.c @@ -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; } diff --git a/zconf/zcrypt/lszcrypt.8 b/zconf/zcrypt/lszcrypt.8 index f9ce4a5f..69de9380 100644 --- a/zconf/zcrypt/lszcrypt.8 +++ b/zconf/zcrypt/lszcrypt.8 @@ -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 diff --git a/zconf/zcrypt/lszcrypt.c b/zconf/zcrypt/lszcrypt.c index 1b2befec..5fcd278d 100644 --- a/zconf/zcrypt/lszcrypt.c +++ b/zconf/zcrypt/lszcrypt.c @@ -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"); }