579 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * pkey ep11 specific code4 *5 * Copyright IBM Corp. 20246 */7 8#define KMSG_COMPONENT "pkey"9#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt10 11#include <linux/init.h>12#include <linux/module.h>13#include <linux/cpufeature.h>14 15#include "zcrypt_api.h"16#include "zcrypt_ccamisc.h"17#include "zcrypt_ep11misc.h"18#include "pkey_base.h"19 20MODULE_LICENSE("GPL");21MODULE_AUTHOR("IBM Corporation");22MODULE_DESCRIPTION("s390 protected key EP11 handler");23 24#if IS_MODULE(CONFIG_PKEY_EP11)25static struct ap_device_id pkey_ep11_card_ids[] = {26 { .dev_type = AP_DEVICE_TYPE_CEX4 },27 { .dev_type = AP_DEVICE_TYPE_CEX5 },28 { .dev_type = AP_DEVICE_TYPE_CEX6 },29 { .dev_type = AP_DEVICE_TYPE_CEX7 },30 { .dev_type = AP_DEVICE_TYPE_CEX8 },31 { /* end of list */ },32};33MODULE_DEVICE_TABLE(ap, pkey_ep11_card_ids);34#endif35 36/*37 * Check key blob for known and supported EP11 key.38 */39static bool is_ep11_key(const u8 *key, u32 keylen)40{41 struct keytoken_header *hdr = (struct keytoken_header *)key;42 43 if (keylen < sizeof(*hdr))44 return false;45 46 switch (hdr->type) {47 case TOKTYPE_NON_CCA:48 switch (hdr->version) {49 case TOKVER_EP11_AES:50 case TOKVER_EP11_AES_WITH_HEADER:51 case TOKVER_EP11_ECC_WITH_HEADER:52 return true;53 default:54 return false;55 }56 default:57 return false;58 }59}60 61static bool is_ep11_keytype(enum pkey_key_type key_type)62{63 switch (key_type) {64 case PKEY_TYPE_EP11:65 case PKEY_TYPE_EP11_AES:66 case PKEY_TYPE_EP11_ECC:67 return true;68 default:69 return false;70 }71}72 73static int ep11_apqns4key(const u8 *key, u32 keylen, u32 flags,74 struct pkey_apqn *apqns, size_t *nr_apqns)75{76 struct keytoken_header *hdr = (struct keytoken_header *)key;77 u32 _nr_apqns, *_apqns = NULL;78 int rc;79 80 if (!flags)81 flags = PKEY_FLAGS_MATCH_CUR_MKVP;82 83 if (keylen < sizeof(struct keytoken_header) || flags == 0)84 return -EINVAL;85 86 zcrypt_wait_api_operational();87 88 if (hdr->type == TOKTYPE_NON_CCA &&89 (hdr->version == TOKVER_EP11_AES_WITH_HEADER ||90 hdr->version == TOKVER_EP11_ECC_WITH_HEADER) &&91 is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) {92 struct ep11keyblob *kb = (struct ep11keyblob *)93 (key + sizeof(struct ep11kblob_header));94 int minhwtype = 0, api = 0;95 96 if (flags != PKEY_FLAGS_MATCH_CUR_MKVP)97 return -EINVAL;98 if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) {99 minhwtype = ZCRYPT_CEX7;100 api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;101 }102 rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,103 minhwtype, api, kb->wkvp);104 if (rc)105 goto out;106 107 } else if (hdr->type == TOKTYPE_NON_CCA &&108 hdr->version == TOKVER_EP11_AES &&109 is_ep11_keyblob(key)) {110 struct ep11keyblob *kb = (struct ep11keyblob *)key;111 int minhwtype = 0, api = 0;112 113 if (flags != PKEY_FLAGS_MATCH_CUR_MKVP)114 return -EINVAL;115 if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) {116 minhwtype = ZCRYPT_CEX7;117 api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;118 }119 rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,120 minhwtype, api, kb->wkvp);121 if (rc)122 goto out;123 124 } else {125 PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",126 __func__, hdr->type, hdr->version);127 return -EINVAL;128 }129 130 if (apqns) {131 if (*nr_apqns < _nr_apqns)132 rc = -ENOSPC;133 else134 memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));135 }136 *nr_apqns = _nr_apqns;137 138out:139 kfree(_apqns);140 pr_debug("rc=%d\n", rc);141 return rc;142}143 144static int ep11_apqns4type(enum pkey_key_type ktype,145 u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,146 struct pkey_apqn *apqns, size_t *nr_apqns)147{148 u32 _nr_apqns, *_apqns = NULL;149 int rc;150 151 zcrypt_wait_api_operational();152 153 if (ktype == PKEY_TYPE_EP11 ||154 ktype == PKEY_TYPE_EP11_AES ||155 ktype == PKEY_TYPE_EP11_ECC) {156 u8 *wkvp = NULL;157 int api;158 159 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)160 wkvp = cur_mkvp;161 api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;162 rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,163 ZCRYPT_CEX7, api, wkvp);164 if (rc)165 goto out;166 167 } else {168 PKEY_DBF_ERR("%s unknown/unsupported key type %d\n",169 __func__, (int)ktype);170 return -EINVAL;171 }172 173 if (apqns) {174 if (*nr_apqns < _nr_apqns)175 rc = -ENOSPC;176 else177 memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));178 }179 *nr_apqns = _nr_apqns;180 181out:182 kfree(_apqns);183 pr_debug("rc=%d\n", rc);184 return rc;185}186 187static int ep11_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,188 const u8 *key, u32 keylen,189 u8 *protkey, u32 *protkeylen, u32 *protkeytype)190{191 struct keytoken_header *hdr = (struct keytoken_header *)key;192 struct pkey_apqn *local_apqns = NULL;193 int i, rc;194 195 if (keylen < sizeof(*hdr))196 return -EINVAL;197 198 if (hdr->type == TOKTYPE_NON_CCA &&199 hdr->version == TOKVER_EP11_AES_WITH_HEADER &&200 is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) {201 /* EP11 AES key blob with header */202 if (ep11_check_aes_key_with_hdr(pkey_dbf_info,203 3, key, keylen, 1))204 return -EINVAL;205 } else if (hdr->type == TOKTYPE_NON_CCA &&206 hdr->version == TOKVER_EP11_ECC_WITH_HEADER &&207 is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) {208 /* EP11 ECC key blob with header */209 if (ep11_check_ecc_key_with_hdr(pkey_dbf_info,210 3, key, keylen, 1))211 return -EINVAL;212 } else if (hdr->type == TOKTYPE_NON_CCA &&213 hdr->version == TOKVER_EP11_AES &&214 is_ep11_keyblob(key)) {215 /* EP11 AES key blob with header in session field */216 if (ep11_check_aes_key(pkey_dbf_info, 3, key, keylen, 1))217 return -EINVAL;218 } else {219 PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",220 __func__, hdr->type, hdr->version);221 return -EINVAL;222 }223 224 zcrypt_wait_api_operational();225 226 if (!apqns || (nr_apqns == 1 &&227 apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {228 nr_apqns = MAXAPQNSINLIST;229 local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),230 GFP_KERNEL);231 if (!local_apqns)232 return -ENOMEM;233 rc = ep11_apqns4key(key, keylen, 0, local_apqns, &nr_apqns);234 if (rc)235 goto out;236 apqns = local_apqns;237 }238 239 for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {240 if (hdr->type == TOKTYPE_NON_CCA &&241 hdr->version == TOKVER_EP11_AES_WITH_HEADER &&242 is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) {243 rc = ep11_kblob2protkey(apqns[i].card, apqns[i].domain,244 key, hdr->len, protkey,245 protkeylen, protkeytype);246 } else if (hdr->type == TOKTYPE_NON_CCA &&247 hdr->version == TOKVER_EP11_ECC_WITH_HEADER &&248 is_ep11_keyblob(key + sizeof(struct ep11kblob_header))) {249 rc = ep11_kblob2protkey(apqns[i].card, apqns[i].domain,250 key, hdr->len, protkey,251 protkeylen, protkeytype);252 } else if (hdr->type == TOKTYPE_NON_CCA &&253 hdr->version == TOKVER_EP11_AES &&254 is_ep11_keyblob(key)) {255 rc = ep11_kblob2protkey(apqns[i].card, apqns[i].domain,256 key, hdr->len, protkey,257 protkeylen, protkeytype);258 } else {259 rc = -EINVAL;260 break;261 }262 }263 264out:265 kfree(local_apqns);266 pr_debug("rc=%d\n", rc);267 return rc;268}269 270/*271 * Generate EP11 secure key.272 * As of now only EP11 AES secure keys are supported.273 * keytype is one of the PKEY_KEYTYPE_* constants,274 * subtype may be PKEY_TYPE_EP11 or PKEY_TYPE_EP11_AES275 * or 0 (results in subtype PKEY_TYPE_EP11_AES),276 * keybitsize is the bit size of the key (may be 0 for277 * keytype PKEY_KEYTYPE_AES_*).278 */279static int ep11_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,280 u32 keytype, u32 subtype,281 u32 keybitsize, u32 flags,282 u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)283{284 struct pkey_apqn *local_apqns = NULL;285 int i, len, rc;286 287 /* check keytype, subtype, keybitsize */288 switch (keytype) {289 case PKEY_KEYTYPE_AES_128:290 case PKEY_KEYTYPE_AES_192:291 case PKEY_KEYTYPE_AES_256:292 len = pkey_keytype_aes_to_size(keytype);293 if (keybitsize && keybitsize != 8 * len) {294 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",295 __func__, keybitsize);296 return -EINVAL;297 }298 keybitsize = 8 * len;299 switch (subtype) {300 case PKEY_TYPE_EP11:301 case PKEY_TYPE_EP11_AES:302 break;303 default:304 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",305 __func__, subtype);306 return -EINVAL;307 }308 break;309 default:310 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",311 __func__, keytype);312 return -EINVAL;313 }314 315 zcrypt_wait_api_operational();316 317 if (!apqns || (nr_apqns == 1 &&318 apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {319 nr_apqns = MAXAPQNSINLIST;320 local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),321 GFP_KERNEL);322 if (!local_apqns)323 return -ENOMEM;324 rc = ep11_apqns4type(subtype, NULL, NULL, 0,325 local_apqns, &nr_apqns);326 if (rc)327 goto out;328 apqns = local_apqns;329 }330 331 for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {332 rc = ep11_genaeskey(apqns[i].card, apqns[i].domain,333 keybitsize, flags,334 keybuf, keybuflen, subtype);335 }336 337out:338 kfree(local_apqns);339 pr_debug("rc=%d\n", rc);340 return rc;341}342 343/*344 * Generate EP11 secure key with given clear key value.345 * As of now only EP11 AES secure keys are supported.346 * keytype is one of the PKEY_KEYTYPE_* constants,347 * subtype may be PKEY_TYPE_EP11 or PKEY_TYPE_EP11_AES348 * or 0 (assumes PKEY_TYPE_EP11_AES then).349 * keybitsize is the bit size of the key (may be 0 for350 * keytype PKEY_KEYTYPE_AES_*).351 */352static int ep11_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,353 u32 keytype, u32 subtype,354 u32 keybitsize, u32 flags,355 const u8 *clrkey, u32 clrkeylen,356 u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)357{358 struct pkey_apqn *local_apqns = NULL;359 int i, len, rc;360 361 /* check keytype, subtype, clrkeylen, keybitsize */362 switch (keytype) {363 case PKEY_KEYTYPE_AES_128:364 case PKEY_KEYTYPE_AES_192:365 case PKEY_KEYTYPE_AES_256:366 len = pkey_keytype_aes_to_size(keytype);367 if (keybitsize && keybitsize != 8 * len) {368 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",369 __func__, keybitsize);370 return -EINVAL;371 }372 keybitsize = 8 * len;373 if (clrkeylen != len) {374 PKEY_DBF_ERR("%s invalid clear key len %d != %d\n",375 __func__, clrkeylen, len);376 return -EINVAL;377 }378 switch (subtype) {379 case PKEY_TYPE_EP11:380 case PKEY_TYPE_EP11_AES:381 break;382 default:383 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",384 __func__, subtype);385 return -EINVAL;386 }387 break;388 default:389 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",390 __func__, keytype);391 return -EINVAL;392 }393 394 zcrypt_wait_api_operational();395 396 if (!apqns || (nr_apqns == 1 &&397 apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {398 nr_apqns = MAXAPQNSINLIST;399 local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),400 GFP_KERNEL);401 if (!local_apqns)402 return -ENOMEM;403 rc = ep11_apqns4type(subtype, NULL, NULL, 0,404 local_apqns, &nr_apqns);405 if (rc)406 goto out;407 apqns = local_apqns;408 }409 410 for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {411 rc = ep11_clr2keyblob(apqns[i].card, apqns[i].domain,412 keybitsize, flags, clrkey,413 keybuf, keybuflen, subtype);414 }415 416out:417 kfree(local_apqns);418 pr_debug("rc=%d\n", rc);419 return rc;420}421 422static int ep11_verifykey(const u8 *key, u32 keylen,423 u16 *card, u16 *dom,424 u32 *keytype, u32 *keybitsize, u32 *flags)425{426 struct keytoken_header *hdr = (struct keytoken_header *)key;427 u32 nr_apqns, *apqns = NULL;428 int rc;429 430 if (keylen < sizeof(*hdr))431 return -EINVAL;432 433 zcrypt_wait_api_operational();434 435 if (hdr->type == TOKTYPE_NON_CCA &&436 hdr->version == TOKVER_EP11_AES) {437 struct ep11keyblob *kb = (struct ep11keyblob *)key;438 int api;439 440 rc = ep11_check_aes_key(pkey_dbf_info, 3, key, keylen, 1);441 if (rc)442 goto out;443 *keytype = PKEY_TYPE_EP11;444 *keybitsize = kb->head.bitlen;445 446 api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;447 rc = ep11_findcard2(&apqns, &nr_apqns, *card, *dom,448 ZCRYPT_CEX7, api,449 ep11_kb_wkvp(key, keylen));450 if (rc)451 goto out;452 453 *flags = PKEY_FLAGS_MATCH_CUR_MKVP;454 455 *card = ((struct pkey_apqn *)apqns)->card;456 *dom = ((struct pkey_apqn *)apqns)->domain;457 458 } else if (hdr->type == TOKTYPE_NON_CCA &&459 hdr->version == TOKVER_EP11_AES_WITH_HEADER) {460 struct ep11kblob_header *kh = (struct ep11kblob_header *)key;461 int api;462 463 rc = ep11_check_aes_key_with_hdr(pkey_dbf_info,464 3, key, keylen, 1);465 if (rc)466 goto out;467 *keytype = PKEY_TYPE_EP11_AES;468 *keybitsize = kh->bitlen;469 470 api = ap_is_se_guest() ? EP11_API_V6 : EP11_API_V4;471 rc = ep11_findcard2(&apqns, &nr_apqns, *card, *dom,472 ZCRYPT_CEX7, api,473 ep11_kb_wkvp(key, keylen));474 if (rc)475 goto out;476 477 *flags = PKEY_FLAGS_MATCH_CUR_MKVP;478 479 *card = ((struct pkey_apqn *)apqns)->card;480 *dom = ((struct pkey_apqn *)apqns)->domain;481 482 } else {483 /* unknown/unsupported key blob */484 rc = -EINVAL;485 }486 487out:488 kfree(apqns);489 pr_debug("rc=%d\n", rc);490 return rc;491}492 493/*494 * This function provides an alternate but usually slow way495 * to convert a 'clear key token' with AES key material into496 * a protected key. That is done via an intermediate step497 * which creates an EP11 AES secure key first and then derives498 * the protected key from this secure key.499 */500static int ep11_slowpath_key2protkey(const struct pkey_apqn *apqns,501 size_t nr_apqns,502 const u8 *key, u32 keylen,503 u8 *protkey, u32 *protkeylen,504 u32 *protkeytype)505{506 const struct keytoken_header *hdr = (const struct keytoken_header *)key;507 const struct clearkeytoken *t = (const struct clearkeytoken *)key;508 u32 tmplen, keysize = 0;509 u8 *tmpbuf;510 int i, rc;511 512 if (keylen < sizeof(*hdr))513 return -EINVAL;514 515 if (hdr->type == TOKTYPE_NON_CCA &&516 hdr->version == TOKVER_CLEAR_KEY)517 keysize = pkey_keytype_aes_to_size(t->keytype);518 if (!keysize || t->len != keysize)519 return -EINVAL;520 521 /* alloc tmp key buffer */522 tmpbuf = kmalloc(MAXEP11AESKEYBLOBSIZE, GFP_ATOMIC);523 if (!tmpbuf)524 return -ENOMEM;525 526 /* try two times in case of failure */527 for (i = 0, rc = -ENODEV; i < 2 && rc; i++) {528 tmplen = MAXEP11AESKEYBLOBSIZE;529 rc = ep11_clr2key(NULL, 0, t->keytype, PKEY_TYPE_EP11,530 8 * keysize, 0, t->clearkey, t->len,531 tmpbuf, &tmplen, NULL);532 pr_debug("ep11_clr2key()=%d\n", rc);533 if (rc)534 continue;535 rc = ep11_key2protkey(NULL, 0, tmpbuf, tmplen,536 protkey, protkeylen, protkeytype);537 pr_debug("ep11_key2protkey()=%d\n", rc);538 }539 540 kfree(tmpbuf);541 pr_debug("rc=%d\n", rc);542 return rc;543}544 545static struct pkey_handler ep11_handler = {546 .module = THIS_MODULE,547 .name = "PKEY EP11 handler",548 .is_supported_key = is_ep11_key,549 .is_supported_keytype = is_ep11_keytype,550 .key_to_protkey = ep11_key2protkey,551 .slowpath_key_to_protkey = ep11_slowpath_key2protkey,552 .gen_key = ep11_gen_key,553 .clr_to_key = ep11_clr2key,554 .verify_key = ep11_verifykey,555 .apqns_for_key = ep11_apqns4key,556 .apqns_for_keytype = ep11_apqns4type,557};558 559/*560 * Module init561 */562static int __init pkey_ep11_init(void)563{564 /* register this module as pkey handler for all the ep11 stuff */565 return pkey_handler_register(&ep11_handler);566}567 568/*569 * Module exit570 */571static void __exit pkey_ep11_exit(void)572{573 /* unregister this module as pkey handler */574 pkey_handler_unregister(&ep11_handler);575}576 577module_init(pkey_ep11_init);578module_exit(pkey_ep11_exit);579