Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 634 lines 17 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * pkey cca specific code 4 * 5 * Copyright IBM Corp. 2024 6 */ 7 8#define pr_fmt(fmt) "pkey: " fmt 9 10#include <linux/init.h> 11#include <linux/module.h> 12#include <linux/cpufeature.h> 13 14#include "zcrypt_ccamisc.h" 15#include "pkey_base.h" 16 17MODULE_LICENSE("GPL"); 18MODULE_AUTHOR("IBM Corporation"); 19MODULE_DESCRIPTION("s390 protected key CCA handler"); 20 21#if IS_MODULE(CONFIG_PKEY_CCA) 22static struct ap_device_id pkey_cca_card_ids[] = { 23 { .dev_type = AP_DEVICE_TYPE_CEX4 }, 24 { .dev_type = AP_DEVICE_TYPE_CEX5 }, 25 { .dev_type = AP_DEVICE_TYPE_CEX6 }, 26 { .dev_type = AP_DEVICE_TYPE_CEX7 }, 27 { .dev_type = AP_DEVICE_TYPE_CEX8 }, 28 { /* end of list */ }, 29}; 30MODULE_DEVICE_TABLE(ap, pkey_cca_card_ids); 31#endif 32 33/* 34 * Check key blob for known and supported CCA key. 35 */ 36static bool is_cca_key(const u8 *key, u32 keylen) 37{ 38 struct keytoken_header *hdr = (struct keytoken_header *)key; 39 40 if (keylen < sizeof(*hdr)) 41 return false; 42 43 switch (hdr->type) { 44 case TOKTYPE_CCA_INTERNAL: 45 switch (hdr->version) { 46 case TOKVER_CCA_AES: 47 case TOKVER_CCA_VLSC: 48 return true; 49 default: 50 return false; 51 } 52 case TOKTYPE_CCA_INTERNAL_PKA: 53 return true; 54 default: 55 return false; 56 } 57} 58 59static bool is_cca_keytype(enum pkey_key_type key_type) 60{ 61 switch (key_type) { 62 case PKEY_TYPE_CCA_DATA: 63 case PKEY_TYPE_CCA_CIPHER: 64 case PKEY_TYPE_CCA_ECC: 65 return true; 66 default: 67 return false; 68 } 69} 70 71static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags, 72 struct pkey_apqn *apqns, size_t *nr_apqns, u32 pflags) 73{ 74 struct keytoken_header *hdr = (struct keytoken_header *)key; 75 u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns); 76 u32 xflags; 77 int rc; 78 79 xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0; 80 81 if (!flags) 82 flags = PKEY_FLAGS_MATCH_CUR_MKVP | PKEY_FLAGS_MATCH_ALT_MKVP; 83 84 if (keylen < sizeof(struct keytoken_header)) 85 return -EINVAL; 86 87 zcrypt_wait_api_operational(); 88 89 if (hdr->type == TOKTYPE_CCA_INTERNAL) { 90 const u8 *ptr_cur_mkvp = NULL; 91 const u8 *ptr_old_mkvp = NULL; 92 int minhwtype = ZCRYPT_CEX3C; 93 94 if (hdr->version == TOKVER_CCA_AES) { 95 struct secaeskeytoken *t = (struct secaeskeytoken *)key; 96 97 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 98 ptr_cur_mkvp = t->mkvp; 99 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 100 ptr_old_mkvp = t->mkvp; 101 } else if (hdr->version == TOKVER_CCA_VLSC) { 102 struct cipherkeytoken *t = (struct cipherkeytoken *)key; 103 104 minhwtype = ZCRYPT_CEX6; 105 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 106 ptr_cur_mkvp = t->mkvp0; 107 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 108 ptr_old_mkvp = t->mkvp0; 109 } else { 110 /* unknown CCA internal token type */ 111 return -EINVAL; 112 } 113 rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 114 minhwtype, AES_MK_SET, 115 ptr_cur_mkvp, ptr_old_mkvp, xflags); 116 if (rc) 117 goto out; 118 119 } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 120 struct eccprivkeytoken *t = (struct eccprivkeytoken *)key; 121 const u8 *ptr_cur_mkvp = NULL; 122 const u8 *ptr_old_mkvp = NULL; 123 124 if (t->secid == 0x20) { 125 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 126 ptr_cur_mkvp = t->mkvp; 127 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 128 ptr_old_mkvp = t->mkvp; 129 } else { 130 /* unknown CCA internal 2 token type */ 131 return -EINVAL; 132 } 133 rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 134 ZCRYPT_CEX7, APKA_MK_SET, 135 ptr_cur_mkvp, ptr_old_mkvp, xflags); 136 if (rc) 137 goto out; 138 139 } else { 140 PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n", 141 __func__, hdr->type, hdr->version); 142 return -EINVAL; 143 } 144 145 if (apqns) { 146 if (*nr_apqns < _nr_apqns) 147 rc = -ENOSPC; 148 else 149 memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); 150 } 151 *nr_apqns = _nr_apqns; 152 153out: 154 pr_debug("rc=%d\n", rc); 155 return rc; 156} 157 158static int cca_apqns4type(enum pkey_key_type ktype, 159 u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags, 160 struct pkey_apqn *apqns, size_t *nr_apqns, 161 u32 pflags) 162{ 163 u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns); 164 u32 xflags; 165 int rc; 166 167 xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0; 168 169 zcrypt_wait_api_operational(); 170 171 if (ktype == PKEY_TYPE_CCA_DATA || ktype == PKEY_TYPE_CCA_CIPHER) { 172 const u8 *ptr_cur_mkvp = NULL; 173 const u8 *ptr_old_mkvp = NULL; 174 int minhwtype = ZCRYPT_CEX3C; 175 176 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 177 ptr_cur_mkvp = cur_mkvp; 178 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 179 ptr_old_mkvp = alt_mkvp; 180 if (ktype == PKEY_TYPE_CCA_CIPHER) 181 minhwtype = ZCRYPT_CEX6; 182 rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 183 minhwtype, AES_MK_SET, 184 ptr_cur_mkvp, ptr_old_mkvp, xflags); 185 if (rc) 186 goto out; 187 188 } else if (ktype == PKEY_TYPE_CCA_ECC) { 189 const u8 *ptr_cur_mkvp = NULL; 190 const u8 *ptr_old_mkvp = NULL; 191 192 if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) 193 ptr_cur_mkvp = cur_mkvp; 194 if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) 195 ptr_old_mkvp = alt_mkvp; 196 rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, 197 ZCRYPT_CEX7, APKA_MK_SET, 198 ptr_cur_mkvp, ptr_old_mkvp, xflags); 199 if (rc) 200 goto out; 201 202 } else { 203 PKEY_DBF_ERR("%s unknown/unsupported key type %d", 204 __func__, (int)ktype); 205 return -EINVAL; 206 } 207 208 if (apqns) { 209 if (*nr_apqns < _nr_apqns) 210 rc = -ENOSPC; 211 else 212 memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); 213 } 214 *nr_apqns = _nr_apqns; 215 216out: 217 pr_debug("rc=%d\n", rc); 218 return rc; 219} 220 221static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns, 222 const u8 *key, u32 keylen, 223 u8 *protkey, u32 *protkeylen, u32 *protkeytype, 224 u32 pflags) 225{ 226 struct keytoken_header *hdr = (struct keytoken_header *)key; 227 struct pkey_apqn _apqns[MAXAPQNSINLIST]; 228 u32 xflags; 229 int i, rc; 230 231 xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0; 232 233 if (keylen < sizeof(*hdr)) 234 return -EINVAL; 235 236 if (hdr->type == TOKTYPE_CCA_INTERNAL && 237 hdr->version == TOKVER_CCA_AES) { 238 /* CCA AES data key */ 239 if (keylen < sizeof(struct secaeskeytoken)) 240 return -EINVAL; 241 if (cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0)) 242 return -EINVAL; 243 } else if (hdr->type == TOKTYPE_CCA_INTERNAL && 244 hdr->version == TOKVER_CCA_VLSC) { 245 /* CCA AES cipher key */ 246 if (keylen < hdr->len) 247 return -EINVAL; 248 if (cca_check_secaescipherkey(pkey_dbf_info, 249 3, key, 0, 1)) 250 return -EINVAL; 251 } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 252 /* CCA ECC (private) key */ 253 if (keylen < sizeof(struct eccprivkeytoken)) 254 return -EINVAL; 255 if (cca_check_sececckeytoken(pkey_dbf_info, 3, key, keylen, 1)) 256 return -EINVAL; 257 } else { 258 PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n", 259 __func__, hdr->type, hdr->version); 260 return -EINVAL; 261 } 262 263 zcrypt_wait_api_operational(); 264 265 if (!apqns || (nr_apqns == 1 && 266 apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) { 267 nr_apqns = MAXAPQNSINLIST; 268 rc = cca_apqns4key(key, keylen, 0, _apqns, &nr_apqns, pflags); 269 if (rc) 270 goto out; 271 apqns = _apqns; 272 } 273 274 for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) { 275 if (hdr->type == TOKTYPE_CCA_INTERNAL && 276 hdr->version == TOKVER_CCA_AES) { 277 rc = cca_sec2protkey(apqns[i].card, apqns[i].domain, 278 key, protkey, 279 protkeylen, protkeytype, xflags); 280 } else if (hdr->type == TOKTYPE_CCA_INTERNAL && 281 hdr->version == TOKVER_CCA_VLSC) { 282 rc = cca_cipher2protkey(apqns[i].card, apqns[i].domain, 283 key, protkey, 284 protkeylen, protkeytype, xflags); 285 } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 286 rc = cca_ecc2protkey(apqns[i].card, apqns[i].domain, 287 key, protkey, 288 protkeylen, protkeytype, xflags); 289 } else { 290 rc = -EINVAL; 291 break; 292 } 293 } 294 295out: 296 pr_debug("rc=%d\n", rc); 297 return rc; 298} 299 300/* 301 * Generate CCA secure key. 302 * As of now only CCA AES Data or Cipher secure keys are 303 * supported. 304 * keytype is one of the PKEY_KEYTYPE_* constants, 305 * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER, 306 * keybitsize is the bit size of the key (may be 0 for 307 * keytype PKEY_KEYTYPE_AES_*). 308 */ 309static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns, 310 u32 keytype, u32 subtype, 311 u32 keybitsize, u32 flags, 312 u8 *keybuf, u32 *keybuflen, u32 *_keyinfo, u32 pflags) 313{ 314 struct pkey_apqn _apqns[MAXAPQNSINLIST]; 315 int i, len, rc; 316 u32 xflags; 317 318 xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0; 319 320 /* check keytype, subtype, keybitsize */ 321 switch (keytype) { 322 case PKEY_KEYTYPE_AES_128: 323 case PKEY_KEYTYPE_AES_192: 324 case PKEY_KEYTYPE_AES_256: 325 len = pkey_keytype_aes_to_size(keytype); 326 if (keybitsize && keybitsize != 8 * len) { 327 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n", 328 __func__, keybitsize); 329 return -EINVAL; 330 } 331 keybitsize = 8 * len; 332 switch (subtype) { 333 case PKEY_TYPE_CCA_DATA: 334 case PKEY_TYPE_CCA_CIPHER: 335 break; 336 default: 337 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n", 338 __func__, subtype); 339 return -EINVAL; 340 } 341 break; 342 default: 343 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", 344 __func__, keytype); 345 return -EINVAL; 346 } 347 348 zcrypt_wait_api_operational(); 349 350 if (!apqns || (nr_apqns == 1 && 351 apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) { 352 nr_apqns = MAXAPQNSINLIST; 353 rc = cca_apqns4type(subtype, NULL, NULL, 0, 354 _apqns, &nr_apqns, pflags); 355 if (rc) 356 goto out; 357 apqns = _apqns; 358 } 359 360 for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) { 361 if (subtype == PKEY_TYPE_CCA_CIPHER) { 362 rc = cca_gencipherkey(apqns[i].card, apqns[i].domain, 363 keybitsize, flags, 364 keybuf, keybuflen, xflags); 365 } else { 366 /* PKEY_TYPE_CCA_DATA */ 367 rc = cca_genseckey(apqns[i].card, apqns[i].domain, 368 keybitsize, keybuf, xflags); 369 *keybuflen = (rc ? 0 : SECKEYBLOBSIZE); 370 } 371 } 372 373out: 374 pr_debug("rc=%d\n", rc); 375 return rc; 376} 377 378/* 379 * Generate CCA secure key with given clear key value. 380 * As of now only CCA AES Data or Cipher secure keys are 381 * supported. 382 * keytype is one of the PKEY_KEYTYPE_* constants, 383 * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER, 384 * keybitsize is the bit size of the key (may be 0 for 385 * keytype PKEY_KEYTYPE_AES_*). 386 */ 387static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns, 388 u32 keytype, u32 subtype, 389 u32 keybitsize, u32 flags, 390 const u8 *clrkey, u32 clrkeylen, 391 u8 *keybuf, u32 *keybuflen, u32 *_keyinfo, u32 pflags) 392{ 393 struct pkey_apqn _apqns[MAXAPQNSINLIST]; 394 int i, len, rc; 395 u32 xflags; 396 397 if (pflags & PKEY_XFLAG_NOCLEARKEY) { 398 PKEY_DBF_ERR("%s clear key but xflag NOCLEARKEY\n", __func__); 399 return -EINVAL; 400 } 401 402 xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0; 403 404 /* check keytype, subtype, clrkeylen, keybitsize */ 405 switch (keytype) { 406 case PKEY_KEYTYPE_AES_128: 407 case PKEY_KEYTYPE_AES_192: 408 case PKEY_KEYTYPE_AES_256: 409 len = pkey_keytype_aes_to_size(keytype); 410 if (keybitsize && keybitsize != 8 * len) { 411 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n", 412 __func__, keybitsize); 413 return -EINVAL; 414 } 415 keybitsize = 8 * len; 416 if (clrkeylen != len) { 417 PKEY_DBF_ERR("%s invalid clear key len %d != %d\n", 418 __func__, clrkeylen, len); 419 return -EINVAL; 420 } 421 switch (subtype) { 422 case PKEY_TYPE_CCA_DATA: 423 case PKEY_TYPE_CCA_CIPHER: 424 break; 425 default: 426 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n", 427 __func__, subtype); 428 return -EINVAL; 429 } 430 break; 431 default: 432 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", 433 __func__, keytype); 434 return -EINVAL; 435 } 436 437 zcrypt_wait_api_operational(); 438 439 if (!apqns || (nr_apqns == 1 && 440 apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) { 441 nr_apqns = MAXAPQNSINLIST; 442 rc = cca_apqns4type(subtype, NULL, NULL, 0, 443 _apqns, &nr_apqns, pflags); 444 if (rc) 445 goto out; 446 apqns = _apqns; 447 } 448 449 for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) { 450 if (subtype == PKEY_TYPE_CCA_CIPHER) { 451 rc = cca_clr2cipherkey(apqns[i].card, apqns[i].domain, 452 keybitsize, flags, clrkey, 453 keybuf, keybuflen, xflags); 454 } else { 455 /* PKEY_TYPE_CCA_DATA */ 456 rc = cca_clr2seckey(apqns[i].card, apqns[i].domain, 457 keybitsize, clrkey, keybuf, xflags); 458 *keybuflen = (rc ? 0 : SECKEYBLOBSIZE); 459 } 460 } 461 462out: 463 pr_debug("rc=%d\n", rc); 464 return rc; 465} 466 467static int cca_verifykey(const u8 *key, u32 keylen, 468 u16 *card, u16 *dom, 469 u32 *keytype, u32 *keybitsize, u32 *flags, u32 pflags) 470{ 471 struct keytoken_header *hdr = (struct keytoken_header *)key; 472 u32 apqns[MAXAPQNSINLIST], nr_apqns = ARRAY_SIZE(apqns); 473 u32 xflags; 474 int rc; 475 476 xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0; 477 478 if (keylen < sizeof(*hdr)) 479 return -EINVAL; 480 481 zcrypt_wait_api_operational(); 482 483 if (hdr->type == TOKTYPE_CCA_INTERNAL && 484 hdr->version == TOKVER_CCA_AES) { 485 struct secaeskeytoken *t = (struct secaeskeytoken *)key; 486 487 rc = cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0); 488 if (rc) 489 goto out; 490 *keytype = PKEY_TYPE_CCA_DATA; 491 *keybitsize = t->bitsize; 492 rc = cca_findcard2(apqns, &nr_apqns, *card, *dom, 493 ZCRYPT_CEX3C, AES_MK_SET, 494 t->mkvp, NULL, xflags); 495 if (!rc) 496 *flags = PKEY_FLAGS_MATCH_CUR_MKVP; 497 if (rc == -ENODEV) { 498 nr_apqns = ARRAY_SIZE(apqns); 499 rc = cca_findcard2(apqns, &nr_apqns, *card, *dom, 500 ZCRYPT_CEX3C, AES_MK_SET, 501 NULL, t->mkvp, xflags); 502 if (!rc) 503 *flags = PKEY_FLAGS_MATCH_ALT_MKVP; 504 } 505 if (rc) 506 goto out; 507 508 *card = ((struct pkey_apqn *)apqns)->card; 509 *dom = ((struct pkey_apqn *)apqns)->domain; 510 511 } else if (hdr->type == TOKTYPE_CCA_INTERNAL && 512 hdr->version == TOKVER_CCA_VLSC) { 513 struct cipherkeytoken *t = (struct cipherkeytoken *)key; 514 515 rc = cca_check_secaescipherkey(pkey_dbf_info, 3, key, 0, 1); 516 if (rc) 517 goto out; 518 *keytype = PKEY_TYPE_CCA_CIPHER; 519 *keybitsize = PKEY_SIZE_UNKNOWN; 520 if (!t->plfver && t->wpllen == 512) 521 *keybitsize = PKEY_SIZE_AES_128; 522 else if (!t->plfver && t->wpllen == 576) 523 *keybitsize = PKEY_SIZE_AES_192; 524 else if (!t->plfver && t->wpllen == 640) 525 *keybitsize = PKEY_SIZE_AES_256; 526 rc = cca_findcard2(apqns, &nr_apqns, *card, *dom, 527 ZCRYPT_CEX6, AES_MK_SET, 528 t->mkvp0, NULL, xflags); 529 if (!rc) 530 *flags = PKEY_FLAGS_MATCH_CUR_MKVP; 531 if (rc == -ENODEV) { 532 nr_apqns = ARRAY_SIZE(apqns); 533 rc = cca_findcard2(apqns, &nr_apqns, *card, *dom, 534 ZCRYPT_CEX6, AES_MK_SET, 535 NULL, t->mkvp0, xflags); 536 if (!rc) 537 *flags = PKEY_FLAGS_MATCH_ALT_MKVP; 538 } 539 if (rc) 540 goto out; 541 542 *card = ((struct pkey_apqn *)apqns)->card; 543 *dom = ((struct pkey_apqn *)apqns)->domain; 544 545 } else { 546 /* unknown/unsupported key blob */ 547 rc = -EINVAL; 548 } 549 550out: 551 pr_debug("rc=%d\n", rc); 552 return rc; 553} 554 555/* 556 * This function provides an alternate but usually slow way 557 * to convert a 'clear key token' with AES key material into 558 * a protected key. This is done via an intermediate step 559 * which creates a CCA AES DATA secure key first and then 560 * derives the protected key from this secure key. 561 */ 562static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns, 563 size_t nr_apqns, 564 const u8 *key, u32 keylen, 565 u8 *protkey, u32 *protkeylen, 566 u32 *protkeytype, u32 pflags) 567{ 568 const struct keytoken_header *hdr = (const struct keytoken_header *)key; 569 const struct clearkeytoken *t = (const struct clearkeytoken *)key; 570 u8 tmpbuf[SECKEYBLOBSIZE]; /* 64 bytes */ 571 u32 tmplen, keysize = 0; 572 int i, rc; 573 574 if (keylen < sizeof(*hdr)) 575 return -EINVAL; 576 577 if (hdr->type == TOKTYPE_NON_CCA && 578 hdr->version == TOKVER_CLEAR_KEY) 579 keysize = pkey_keytype_aes_to_size(t->keytype); 580 if (!keysize || t->len != keysize) 581 return -EINVAL; 582 583 /* try two times in case of failure */ 584 for (i = 0, rc = -ENODEV; i < 2 && rc; i++) { 585 tmplen = SECKEYBLOBSIZE; 586 rc = cca_clr2key(NULL, 0, t->keytype, PKEY_TYPE_CCA_DATA, 587 8 * keysize, 0, t->clearkey, t->len, 588 tmpbuf, &tmplen, NULL, pflags); 589 pr_debug("cca_clr2key()=%d\n", rc); 590 if (rc) 591 continue; 592 rc = cca_key2protkey(NULL, 0, tmpbuf, tmplen, 593 protkey, protkeylen, protkeytype, pflags); 594 pr_debug("cca_key2protkey()=%d\n", rc); 595 } 596 597 pr_debug("rc=%d\n", rc); 598 return rc; 599} 600 601static struct pkey_handler cca_handler = { 602 .module = THIS_MODULE, 603 .name = "PKEY CCA handler", 604 .is_supported_key = is_cca_key, 605 .is_supported_keytype = is_cca_keytype, 606 .key_to_protkey = cca_key2protkey, 607 .slowpath_key_to_protkey = cca_slowpath_key2protkey, 608 .gen_key = cca_gen_key, 609 .clr_to_key = cca_clr2key, 610 .verify_key = cca_verifykey, 611 .apqns_for_key = cca_apqns4key, 612 .apqns_for_keytype = cca_apqns4type, 613}; 614 615/* 616 * Module init 617 */ 618static int __init pkey_cca_init(void) 619{ 620 /* register this module as pkey handler for all the cca stuff */ 621 return pkey_handler_register(&cca_handler); 622} 623 624/* 625 * Module exit 626 */ 627static void __exit pkey_cca_exit(void) 628{ 629 /* unregister this module as pkey handler */ 630 pkey_handler_unregister(&cca_handler); 631} 632 633module_init(pkey_cca_init); 634module_exit(pkey_cca_exit);