From 560b672bfad3c7bb6631ed4e1676a8b2c836e030 Mon Sep 17 00:00:00 2001 From: Ingo Franzki Date: Fri, 26 Jul 2019 10:19:18 +0200 Subject: [PATCH] zkey: Add support for re-enciphering AES CIPHER keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For secure keys of type CCA-AESCIPHER the CCA verb CSNBKTC2 (Key Token Change2) is used. CCA-AESDATA keys will continue to use CCA verb CSNBKTC (Key Token Change). Signed-off-by: Ingo Franzki Reviewed-by: Harald Freudenberger Signed-off-by: Jan Höppner --- zkey/cca.c | 81 ++++++++++++++++++++++++++++++++++++++++++++---------- zkey/cca.h | 10 +++++++ 2 files changed, 76 insertions(+), 15 deletions(-) diff --git a/zkey/cca.c b/zkey/cca.c index 9ad1558d..2d3835d8 100644 --- a/zkey/cca.c +++ b/zkey/cca.c @@ -142,6 +142,9 @@ int load_cca_library(struct cca_lib *cca, bool verbose) /* Get the Key Token Change function */ cca->dll_CSNBKTC = (t_CSNBKTC)dlsym(cca->lib_csulcca, "CSNBKTC"); + /* Get the Key Token Change 2 function */ + cca->dll_CSNBKTC2 = (t_CSNBKTC2)dlsym(cca->lib_csulcca, "CSNBKTC2"); + /* Get the Cryptographic Facility Query function */ cca->dll_CSUACFQ = (t_CSUACFQ)dlsym(cca->lib_csulcca, "CSUACFQ"); @@ -153,6 +156,7 @@ int load_cca_library(struct cca_lib *cca, bool verbose) if (cca->dll_CSUACFV == NULL || cca->dll_CSNBKTC == NULL || + cca->dll_CSNBKTC2 == NULL || cca->dll_CSUACFQ == NULL || cca->dll_CSUACRA == NULL || cca->dll_CSUACRD == NULL) { @@ -187,10 +191,13 @@ int key_token_change(struct cca_lib *cca, u8 *secure_key, unsigned int secure_key_size, char *method, bool verbose) { + struct aescipherkeytoken *cipherkey = + (struct aescipherkeytoken *)secure_key; long exit_data_len = 0, rule_array_count; unsigned char rule_array[2 * 8] = { 0, }; unsigned char exit_data[4] = { 0, }; long return_code, reason_code; + long key_token_length; util_assert(cca != NULL, "Internal error: cca is NULL"); util_assert(secure_key != NULL, "Internal error: secure_key is NULL"); @@ -202,33 +209,77 @@ int key_token_change(struct cca_lib *cca, memcpy(rule_array + 8, "AES ", 8); rule_array_count = 2; - cca->dll_CSNBKTC(&return_code, &reason_code, - &exit_data_len, exit_data, - &rule_array_count, rule_array, - secure_key); + if (is_cca_aes_data_key(secure_key, secure_key_size)) { + cca->dll_CSNBKTC(&return_code, &reason_code, + &exit_data_len, exit_data, + &rule_array_count, rule_array, + secure_key); + + pr_verbose(verbose, "CSNBKTC (Key Token Change) with '%s' " + "returned: return_code: %ld, reason_code: %ld", + method, return_code, reason_code); + } else if (is_cca_aes_cipher_key(secure_key, secure_key_size)) { + key_token_length = cipherkey->length; + cca->dll_CSNBKTC2(&return_code, &reason_code, + &exit_data_len, exit_data, + &rule_array_count, rule_array, + &key_token_length, + (unsigned char *)cipherkey); + + pr_verbose(verbose, "CSNBKTC2 (Key Token Change2) with '%s' " + "returned: return_code: %ld, reason_code: %ld", + method, return_code, reason_code); + + pr_verbose(verbose, "key_token_length: %lu", key_token_length); + } else { + warnx("Invalid key type specified"); + return -EINVAL; + } - pr_verbose(verbose, "CSNBKTC (Key Token Change) with '%s' returned: " - "return_code: %ld, reason_code: %ld", method, return_code, - reason_code); if (return_code != 0) { print_CCA_error(return_code, reason_code); return -EIO; } - if (secure_key_size == 2 * AESDATA_KEY_SIZE) { - cca->dll_CSNBKTC(&return_code, &reason_code, - &exit_data_len, exit_data, - &rule_array_count, rule_array, - secure_key + AESDATA_KEY_SIZE); + if (is_xts_key(secure_key, secure_key_size)) { + if (is_cca_aes_data_key(secure_key, secure_key_size)) { + cca->dll_CSNBKTC(&return_code, &reason_code, + &exit_data_len, exit_data, + &rule_array_count, rule_array, + secure_key + AESDATA_KEY_SIZE); + + pr_verbose(verbose, "CSNBKTC (Key Token Change) with " + "'%s' returned: return_code: %ld, " + "reason_code: %ld", method, return_code, + reason_code); + } else if (is_cca_aes_cipher_key(secure_key, secure_key_size)) { + cipherkey = (struct aescipherkeytoken *)(secure_key + + AESCIPHER_KEY_SIZE); + key_token_length = cipherkey->length; + cca->dll_CSNBKTC2(&return_code, &reason_code, + &exit_data_len, exit_data, + &rule_array_count, rule_array, + &key_token_length, + (unsigned char *)cipherkey); + + pr_verbose(verbose, "CSNBKTC2 (Key Token Change2) with " + "'%s' returned: return_code: %ld, " + "reason_code: %ld", method, return_code, + reason_code); + + pr_verbose(verbose, "key_token_length: %lu", + key_token_length); + } else { + warnx("Invalid key type specified"); + return -EINVAL; + } - pr_verbose(verbose, "CSNBKTC (Key Token Change) with '%s' " - "returned: return_code: %ld, reason_code: %ld", - method, return_code, reason_code); if (return_code != 0) { print_CCA_error(return_code, reason_code); return -EIO; } } + return 0; } diff --git a/zkey/cca.h b/zkey/cca.h index a79e2ee3..bf3e5108 100644 --- a/zkey/cca.h +++ b/zkey/cca.h @@ -25,6 +25,15 @@ typedef void (*t_CSNBKTC)(long *return_code, unsigned char *rule_array, unsigned char *key_identifier); +typedef void (*t_CSNBKTC2)(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); + typedef void (*t_CSUACFV)(long *return_code, long *reason_code, long *exit_data_length, @@ -68,6 +77,7 @@ struct cca_version { struct cca_lib { void *lib_csulcca; t_CSNBKTC dll_CSNBKTC; + t_CSNBKTC2 dll_CSNBKTC2; t_CSUACFV dll_CSUACFV; t_CSUACFQ dll_CSUACFQ; t_CSUACRA dll_CSUACRA;