Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
openSUSE:Leap:15.2:Staging:N
s390-tools
s390-tools-sles15sp2-14-zkey-Add-function-to-se...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File s390-tools-sles15sp2-14-zkey-Add-function-to-select-a-specific-CCA-adapter.patch of Package s390-tools
Subject: zkey: Add function to select a specific CCA adapter From: Ingo Franzki <ifranzki@linux.ibm.com> Summary: zkey: check master key consistency Description: Enhances the zkey tool to perform a cross check whether the APQNs associated with a secure key have the same master key. Display the master key verification pattern of a secure key during the zkey validate command. This helps to better identify which master key is the correct one, in case of master key inconsistencies. Select an appropriate APQN when re-enciphering a secure key. Re-enciphering is done using the CCA host library. Special handling is required to select an appropriate APQN for use with the CCA host library. Upstream-ID: 016a0a56fcb3dd0bf8bed693e5d64873f6288995 Problem-ID: SEC1916 Upstream-Description: zkey: Add function to select a specific CCA adapter Some operations require the CCA host library to be used, such as re-enciphering a secure key. The CCA host library uses a different approach to select the APQN it operates with. To ensure that the desired APQN is used for an operation, a utility function is added to select a specific APQN for usage with the CCA host library. The CCA host library allows to set environment variables to override the default CCA APQN selection. The environment variables are inspected during CCA host library initialization only. To select a specific domain for CCA, the CSU_DEFAULT_DOMAIN environment variable is set, and then the CCA host library is un-loaded and re-loaded again. Furthermore, the 'Cryptographic Resource Allocate' verb of the CCA host library is used together with the 'Cryptographic Facility Query function' verb to iterate over the crypto cards known by the CCA host library, and to identify the desired crypto card based on its serial number. That way, a specific APQN can be selected for use with subsequent CCA verbs. Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com> Reviewed-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Jan Hoeppner <hoeppner@linux.ibm.com> Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com> --- zkey/Makefile | 4 zkey/cca.c | 296 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- zkey/cca.h | 32 ++++++ 3 files changed, 329 insertions(+), 3 deletions(-) --- a/zkey/Makefile +++ b/zkey/Makefile @@ -66,7 +66,7 @@ all: $(BUILD_TARGETS) zkey.o: zkey.c pkey.h cca.h misc.h pkey.o: pkey.c pkey.h -cca.o: cca.c cca.h pkey.h +cca.o: cca.c cca.h pkey.h utils.h utils.o: utils.h properties.o: check-dep-zkey properties.c properties.h keystore.o: keystore.c keystore.h properties.h pkey.h cca.h utils.h @@ -77,7 +77,7 @@ zkey: zkey.o pkey.o cca.o properties.o k $(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@ zkey-cryptsetup: LDLIBS = -ldl -lcryptsetup -ljson-c -zkey-cryptsetup: zkey-cryptsetup.o pkey.o cca.o $(libs) +zkey-cryptsetup: zkey-cryptsetup.o pkey.o cca.o utils.o $(libs) $(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@ install-common: --- a/zkey/cca.c +++ b/zkey/cca.c @@ -12,6 +12,7 @@ #include <errno.h> #include <stdbool.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <stdint.h> #include <sys/types.h> @@ -21,6 +22,7 @@ #include "cca.h" #include "pkey.h" +#include "utils.h" #define pr_verbose(verbose, fmt...) do { \ if (verbose) \ @@ -32,6 +34,8 @@ */ #define CCA_LIBRARY_NAME "libcsulcca.so" #define CCA_WEB_PAGE "http://www.ibm.com/security/cryptocards" +#define CCA_DOMAIN_ENVAR "CSU_DEFAULT_DOMAIN" +#define CCA_ADAPTER_ENVAR "CSU_DEFAULT_ADAPTER" /** * Prints CCA return and reason code information for certain known CCA @@ -136,8 +140,20 @@ int load_cca_library(struct cca_lib *cca /* Get the Key Token Change function */ cca->dll_CSNBKTC = (t_CSNBKTC)dlsym(cca->lib_csulcca, "CSNBKTC"); + /* Get the Cryptographic Facility Query function */ + cca->dll_CSUACFQ = (t_CSUACFQ)dlsym(cca->lib_csulcca, "CSUACFQ"); + + /* Get the Cryptographic Resource Allocate function */ + cca->dll_CSUACRA = (t_CSUACRA)dlsym(cca->lib_csulcca, "CSUACRA"); + + /* Cryptographic Resource Deallocate function */ + cca->dll_CSUACRD = (t_CSUACRD)dlsym(cca->lib_csulcca, "CSUACRD"); + if (cca->dll_CSUACFV == NULL || - cca->dll_CSNBKTC == NULL) { + cca->dll_CSNBKTC == NULL || + cca->dll_CSUACFQ == NULL || + cca->dll_CSUACRA == NULL || + cca->dll_CSUACRD == NULL) { pr_verbose(verbose, "%s", dlerror()); warnx("The command requires the IBM CCA Host Libraries and " "Tools.\nFor the supported environments and downloads, " @@ -213,3 +229,281 @@ int key_token_change(struct cca_lib *cca } return 0; } + +/** + * Queries the number of adapters known by the CCA host library + * + * @param[in] cca the CCA library structure + * @param[out] adapters the number of adapters + * @param[in] verbose if true, verbose messages are printed + * + * @returns 0 on success, a negative errno in case of an error. + */ +static int get_number_of_cca_adapters(struct cca_lib *cca, + unsigned int *adapters, bool verbose) +{ + long exit_data_len = 0, rule_array_count, verb_data_length = 0; + unsigned char rule_array[16 * 8] = { 0, }; + unsigned char exit_data[4] = { 0, }; + long return_code, reason_code; + + util_assert(cca != NULL, "Internal error: cca is NULL"); + util_assert(adapters != NULL, "Internal error: adapters is NULL"); + + memset(rule_array, 0, sizeof(rule_array)); + memcpy(rule_array, "STATCRD2", 8); + rule_array_count = 1; + + cca->dll_CSUACFQ(&return_code, &reason_code, + &exit_data_len, exit_data, + &rule_array_count, rule_array, + &verb_data_length, NULL); + + pr_verbose(verbose, "CSUACFQ (Cryptographic Facility Query) returned: " + "return_code: %ld, reason_code: %ld", return_code, + reason_code); + if (return_code != 0) { + print_CCA_error(return_code, reason_code); + return -EIO; + } + + rule_array[8] = '\0'; + if (sscanf((char *)rule_array, "%u", adapters) != 1) { + pr_verbose(verbose, "Unparsable output: %s", rule_array); + return -EIO; + } + + pr_verbose(verbose, "Number of CCA adapters: %u", *adapters); + return 0; +} + +/** + * Allocate a specific CCA adapter. + * + * @param[in] cca the CCA library structure + * @param[in] adapter the adapter number, starting at 1. If 0 is + * specified, then the AUTOSELECT option is + * enabled. + * @param[in] verbose if true, verbose messages are printed + * + * @returns 0 on success, a negative errno in case of an error. -ENODEV is + * returned if the adapter is not available. + */ +static int allocate_cca_adapter(struct cca_lib *cca, unsigned int adapter, + bool verbose) +{ + long exit_data_len = 0, rule_array_count; + unsigned char rule_array[8] = { 0, }; + unsigned char exit_data[4] = { 0, }; + long return_code, reason_code; + char res_name[9]; + long res_name_len; + + util_assert(cca != NULL, "Internal error: cca is NULL"); + + if (adapter > 0) + memcpy(rule_array, "DEVICE ", 8); + else + memcpy(rule_array, "DEV-ANY ", 8); + rule_array_count = 1; + + sprintf(res_name, "CRP%02d", adapter); + res_name_len = strlen(res_name); + + cca->dll_CSUACRA(&return_code, &reason_code, + &exit_data_len, exit_data, + &rule_array_count, rule_array, + &res_name_len, (unsigned char *)res_name); + + pr_verbose(verbose, "CSUACRA (Cryptographic Resource Allocate) " + "returned: return_code: %ld, reason_code: %ld", return_code, + reason_code); + if (return_code != 0) { + print_CCA_error(return_code, reason_code); + return -ENODEV; + } + + pr_verbose(verbose, "Adapter %u (%s) allocated", adapter, res_name); + return 0; +} + +/** + * Deallocate a specific CCA adapter. + * + * @param[in] cca the CCA library structure + * @param[in] adapter the adapter number, starting at 1. If 0 is + * specified, then the AUTOSELECT option is + * disabled. + * @param[in] verbose if true, verbose messages are printed + * + * @returns 0 on success, a negative errno in case of an error. -ENODEV is + * returned if the adapter is not available. + */ +static int deallocate_cca_adapter(struct cca_lib *cca, unsigned int adapter, + bool verbose) +{ + long exit_data_len = 0, rule_array_count; + unsigned char rule_array[8] = { 0, }; + unsigned char exit_data[4] = { 0, }; + long return_code, reason_code; + char res_name[9]; + long res_name_len; + + util_assert(cca != NULL, "Internal error: cca is NULL"); + + if (adapter > 0) + memcpy(rule_array, "DEVICE ", 8); + else + memcpy(rule_array, "DEV-ANY ", 8); + rule_array_count = 1; + + sprintf(res_name, "CRP%02d", adapter); + res_name_len = strlen(res_name); + + cca->dll_CSUACRD(&return_code, &reason_code, + &exit_data_len, exit_data, + &rule_array_count, rule_array, + &res_name_len, (unsigned char *)res_name); + + pr_verbose(verbose, "CSUACRD (Cryptographic Resource Deallocate) " + "returned: return_code: %ld, reason_code: %ld", return_code, + reason_code); + if (return_code != 0) { + print_CCA_error(return_code, reason_code); + return -ENODEV; + } + + pr_verbose(verbose, "Adapter %u (%s) deallocated", adapter, res_name); + return 0; +} + +/** + * Queries the serial number of the current CCA adapter + * + * @param[in] cca the CCA library structure + * @param[out] serialnr the buffer where the serial number is returned + * @param[in] verbose if true, verbose messages are printed + * + * @returns 0 on success, a negative errno in case of an error. + */ +static int get_cca_adapter_serialnr(struct cca_lib *cca, char serialnr[9], + bool verbose) +{ + long exit_data_len = 0, rule_array_count, verb_data_length = 0; + unsigned char rule_array[16 * 8] = { 0, }; + unsigned char exit_data[4] = { 0, }; + long return_code, reason_code; + + util_assert(cca != NULL, "Internal error: cca is NULL"); + + memset(rule_array, 0, sizeof(rule_array)); + memcpy(rule_array, "STATCRD2", 8); + rule_array_count = 1; + + cca->dll_CSUACFQ(&return_code, &reason_code, + &exit_data_len, exit_data, + &rule_array_count, rule_array, + &verb_data_length, NULL); + + pr_verbose(verbose, "CSUACFQ (Cryptographic Facility Query) returned: " + "return_code: %ld, reason_code: %ld", return_code, + reason_code); + if (return_code != 0) { + print_CCA_error(return_code, reason_code); + return -EIO; + } + + memcpy(serialnr, rule_array+14*8, 8); + serialnr[8] = '\0'; + + pr_verbose(verbose, "Serial number of CCA adapter: %s", serialnr); + return 0; +} + +/** + * Selects the specified APQN to be used for the CCA host library. + * + * @param[in] cca the CCA library structure + * @param[in] card the card number + * @param[in] domain the domain number + * @param[in] verbose if true, verbose messages are printed + * + * @returns 0 on success, a negative errno in case of an error. -ENOTSUP is + * returned when the serialnr sysfs attribute is not available, + * 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) +{ + unsigned int adapters, adapter; + char adapter_serialnr[9]; + char apqn_serialnr[9]; + char temp[10]; + int rc, found = 0; + + util_assert(cca != NULL, "Internal error: cca is NULL"); + + pr_verbose(verbose, "Select %02x.%04x for the CCA host library", card, + domain); + + rc = sysfs_get_serialnr(card, apqn_serialnr, verbose); + if (rc != 0) { + pr_verbose(verbose, "Failed to get the serial number: %s", + strerror(-rc)); + return rc; + } + + sprintf(temp, "%u", domain); + if (setenv(CCA_DOMAIN_ENVAR, temp, 1) != 0) { + rc = -errno; + pr_verbose(verbose, "Failed to set the %s environment variable:" + " %s", CCA_DOMAIN_ENVAR, strerror(-rc)); + return rc; + } + unsetenv(CCA_ADAPTER_ENVAR); + + /* + * Unload and reload the CCA host library so that it recognizes the + * changed CSU_DEFAULT_DOMAIN environment variable value. + */ + if (cca->lib_csulcca != NULL) + dlclose(cca->lib_csulcca); + memset(cca, 0, sizeof(struct cca_lib)); + + rc = load_cca_library(cca, verbose); + if (rc != 0) + return rc; + + rc = get_number_of_cca_adapters(cca, &adapters, verbose); + if (rc != 0) + return rc; + + /* Disable the AUTOSELECT option */ + rc = deallocate_cca_adapter(cca, 0, verbose); + if (rc != 0) + return rc; + + for (adapter = 1; adapter <= adapters; adapter++) { + rc = allocate_cca_adapter(cca, adapter, verbose); + if (rc != 0) + return rc; + + rc = get_cca_adapter_serialnr(cca, adapter_serialnr, verbose); + if (rc == 0) { + if (memcmp(apqn_serialnr, adapter_serialnr, 8) == 0) { + found = 1; + break; + } + } + + rc = deallocate_cca_adapter(cca, adapter, verbose); + if (rc != 0) + return rc; + } + + if (!found) + return -ENODEV; + + pr_verbose(verbose, "Selected adapter %u (CRP%02d)", adapter, adapter); + return 0; +} --- a/zkey/cca.h +++ b/zkey/cca.h @@ -32,6 +32,33 @@ typedef void (*t_CSUACFV)(long *return_c long *version_data_length, unsigned char *version_data); +typedef void (*t_CSUACFQ)(long *return_code, + long *reason_code, + long *exit_data_length, + unsigned char *exit_data, + long *rule_array_count, + unsigned char *rule_array, + long *verb_data_length, + unsigned char *verb_data); + +typedef void (*t_CSUACRA)(long *return_code, + long *reason_code, + long *exit_data_length, + unsigned char *exit_data, + long *rule_array_count, + unsigned char *rule_array, + long *ressource_name_length, + unsigned char *ressource_name); + +typedef void (*t_CSUACRD)(long *return_code, + long *reason_code, + long *exit_data_length, + unsigned char *exit_data, + long *rule_array_count, + unsigned char *rule_array, + long *ressource_name_length, + unsigned char *ressource_name); + struct cca_version { unsigned int ver; unsigned int rel; @@ -42,6 +69,9 @@ struct cca_lib { void *lib_csulcca; t_CSNBKTC dll_CSNBKTC; t_CSUACFV dll_CSUACFV; + t_CSUACFQ dll_CSUACFQ; + t_CSUACRA dll_CSUACRA; + t_CSUACRD dll_CSUACRD; struct cca_version version; }; @@ -51,4 +81,6 @@ 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); + #endif
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor