From 4e2ebe0370d9fb036b7554d5ac5df4418dbe0397 Mon Sep 17 00:00:00 2001 From: Ingo Franzki Date: Mon, 4 Apr 2022 16:38:41 +0200 Subject: [PATCH] libseckey: Fix re-enciphering of EP11 secure key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The re-enciphering of EP11 asymmetric secure keys does not work. First, the result of the re-encipher operation of the private key part must be copied back into the user supplied key token buffer. Second, the public key part, i.e. the MACed SubjectPublicKeyInfo (SPKI) structure must also be re-enciphered (i.e. re-MACed), since the MAC is calculated with the EP11 master key. Signed-off-by: Ingo Franzki Signed-off-by: Jan Höppner --- libseckey/sk_ep11.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/libseckey/sk_ep11.c b/libseckey/sk_ep11.c index b8676267..e3bd3c9f 100644 --- a/libseckey/sk_ep11.c +++ b/libseckey/sk_ep11.c @@ -1549,6 +1549,59 @@ int SK_EP11_reencipher_key(const struct sk_ext_ep11_lib *ep11_lib, return -EIO; } + memcpy(blob, lrb.payload, lrb.pllen); + + /* re-encipher MACed SPKI */ + rb.domain = domain; + lrb.domain = domain; + + resp_len = sizeof(resp); + req_len = ep11.dll_xcpa_cmdblock(req, sizeof(req), XCP_ADM_REENCRYPT, + &rb, NULL, key_token + hdr->len, + key_token_length - hdr->len); + if (req_len < 0) { + sk_debug(debug, "Failed to build XCP command block"); + return -EIO; + } + + rv = ep11.dll_m_admin(resp, &resp_len, NULL, NULL, req, req_len, NULL, + 0, ep11_lib->target); + if (rv != CKR_OK || resp_len == 0) { + sk_debug(debug, "Command XCP_ADM_REENCRYPT failed. " + "rc = 0x%lx, resp_len = %ld", rv, resp_len); + return -EIO; + } + + rc = ep11.dll_xcpa_internal_rv(resp, resp_len, &lrb, &rv); + if (rc != 0) { + sk_debug(debug, "Failed to parse response. rc = %d", rc); + return -EIO; + } + + if (rv != CKR_OK) { + sk_debug(debug, "Failed to re-encrypt the EP11 secure key. " + "rc = 0x%lx", rv); + switch (rv) { + case CKR_IBM_WKID_MISMATCH: + sk_debug(debug, "The EP11 secure key is currently " + "encrypted under a different master that does " + "not match the master key in the CURRENT " + "master key register of APQN %02X.%04X", + card, domain); + break; + } + return -EIO; + } + + if (key_token_length - hdr->len != lrb.pllen) { + sk_debug(debug, "Re-encrypted EP11 secure key size has " + "changed: org-len: %lu, new-len: %lu", + hdr->len - sizeof(*hdr), lrb.pllen); + return -EIO; + } + + memcpy(key_token + hdr->len, lrb.payload, lrb.pllen); + return 0; }