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 17 MODULE_LICENSE("GPL"); 18 MODULE_AUTHOR("IBM Corporation"); 19 MODULE_DESCRIPTION("s390 protected key CCA handler"); 20 21 #if IS_MODULE(CONFIG_PKEY_CCA) 22 static 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 }; 30 MODULE_DEVICE_TABLE(ap, pkey_cca_card_ids); 31 #endif 32 33 /* 34 * Check key blob for known and supported CCA key. 35 */ 36 static 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 59 static 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 71 static 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 153 out: 154 pr_debug("rc=%d\n", rc); 155 return rc; 156 } 157 158 static 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 216 out: 217 pr_debug("rc=%d\n", rc); 218 return rc; 219 } 220 221 static 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 (cca_check_secaeskeytoken(pkey_dbf_info, 3, key, keylen, 0)) 240 return -EINVAL; 241 } else if (hdr->type == TOKTYPE_CCA_INTERNAL && 242 hdr->version == TOKVER_CCA_VLSC) { 243 /* CCA AES cipher key */ 244 if (cca_check_secaescipherkey(pkey_dbf_info, 245 3, key, keylen, 0, 1)) 246 return -EINVAL; 247 } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 248 /* CCA ECC (private) key */ 249 if (cca_check_sececckeytoken(pkey_dbf_info, 3, key, keylen, 1)) 250 return -EINVAL; 251 } else { 252 PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n", 253 __func__, hdr->type, hdr->version); 254 return -EINVAL; 255 } 256 257 zcrypt_wait_api_operational(); 258 259 if (!apqns || (nr_apqns == 1 && 260 apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) { 261 nr_apqns = MAXAPQNSINLIST; 262 rc = cca_apqns4key(key, keylen, 0, _apqns, &nr_apqns, pflags); 263 if (rc) 264 goto out; 265 apqns = _apqns; 266 } 267 268 for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) { 269 if (hdr->type == TOKTYPE_CCA_INTERNAL && 270 hdr->version == TOKVER_CCA_AES) { 271 rc = cca_sec2protkey(apqns[i].card, apqns[i].domain, 272 key, protkey, 273 protkeylen, protkeytype, xflags); 274 } else if (hdr->type == TOKTYPE_CCA_INTERNAL && 275 hdr->version == TOKVER_CCA_VLSC) { 276 rc = cca_cipher2protkey(apqns[i].card, apqns[i].domain, 277 key, protkey, 278 protkeylen, protkeytype, xflags); 279 } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) { 280 rc = cca_ecc2protkey(apqns[i].card, apqns[i].domain, 281 key, protkey, 282 protkeylen, protkeytype, xflags); 283 } else { 284 rc = -EINVAL; 285 break; 286 } 287 } 288 289 out: 290 pr_debug("rc=%d\n", rc); 291 return rc; 292 } 293 294 /* 295 * Generate CCA secure key. 296 * As of now only CCA AES Data or Cipher secure keys are 297 * supported. 298 * keytype is one of the PKEY_KEYTYPE_* constants, 299 * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER, 300 * keybitsize is the bit size of the key (may be 0 for 301 * keytype PKEY_KEYTYPE_AES_*). 302 */ 303 static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns, 304 u32 keytype, u32 subtype, 305 u32 keybitsize, u32 flags, 306 u8 *keybuf, u32 *keybuflen, u32 *_keyinfo, u32 pflags) 307 { 308 struct pkey_apqn _apqns[MAXAPQNSINLIST]; 309 int i, len, rc; 310 u32 xflags; 311 312 xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0; 313 314 /* check keytype, subtype, keybitsize */ 315 switch (keytype) { 316 case PKEY_KEYTYPE_AES_128: 317 case PKEY_KEYTYPE_AES_192: 318 case PKEY_KEYTYPE_AES_256: 319 len = pkey_keytype_aes_to_size(keytype); 320 if (keybitsize && keybitsize != 8 * len) { 321 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n", 322 __func__, keybitsize); 323 return -EINVAL; 324 } 325 keybitsize = 8 * len; 326 switch (subtype) { 327 case PKEY_TYPE_CCA_DATA: 328 case PKEY_TYPE_CCA_CIPHER: 329 break; 330 default: 331 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n", 332 __func__, subtype); 333 return -EINVAL; 334 } 335 break; 336 default: 337 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", 338 __func__, keytype); 339 return -EINVAL; 340 } 341 342 zcrypt_wait_api_operational(); 343 344 if (!apqns || (nr_apqns == 1 && 345 apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) { 346 nr_apqns = MAXAPQNSINLIST; 347 rc = cca_apqns4type(subtype, NULL, NULL, 0, 348 _apqns, &nr_apqns, pflags); 349 if (rc) 350 goto out; 351 apqns = _apqns; 352 } 353 354 for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) { 355 if (subtype == PKEY_TYPE_CCA_CIPHER) { 356 rc = cca_gencipherkey(apqns[i].card, apqns[i].domain, 357 keybitsize, flags, 358 keybuf, keybuflen, xflags); 359 } else { 360 /* PKEY_TYPE_CCA_DATA */ 361 rc = cca_genseckey(apqns[i].card, apqns[i].domain, 362 keybitsize, keybuf, xflags); 363 *keybuflen = (rc ? 0 : SECKEYBLOBSIZE); 364 } 365 } 366 367 out: 368 pr_debug("rc=%d\n", rc); 369 return rc; 370 } 371 372 /* 373 * Generate CCA secure key with given clear key value. 374 * As of now only CCA AES Data or Cipher secure keys are 375 * supported. 376 * keytype is one of the PKEY_KEYTYPE_* constants, 377 * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER, 378 * keybitsize is the bit size of the key (may be 0 for 379 * keytype PKEY_KEYTYPE_AES_*). 380 */ 381 static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns, 382 u32 keytype, u32 subtype, 383 u32 keybitsize, u32 flags, 384 const u8 *clrkey, u32 clrkeylen, 385 u8 *keybuf, u32 *keybuflen, u32 *_keyinfo, u32 pflags) 386 { 387 struct pkey_apqn _apqns[MAXAPQNSINLIST]; 388 int i, len, rc; 389 u32 xflags; 390 391 if (pflags & PKEY_XFLAG_NOCLEARKEY) { 392 PKEY_DBF_ERR("%s clear key but xflag NOCLEARKEY\n", __func__); 393 return -EINVAL; 394 } 395 396 xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0; 397 398 /* check keytype, subtype, clrkeylen, keybitsize */ 399 switch (keytype) { 400 case PKEY_KEYTYPE_AES_128: 401 case PKEY_KEYTYPE_AES_192: 402 case PKEY_KEYTYPE_AES_256: 403 len = pkey_keytype_aes_to_size(keytype); 404 if (keybitsize && keybitsize != 8 * len) { 405 PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n", 406 __func__, keybitsize); 407 return -EINVAL; 408 } 409 keybitsize = 8 * len; 410 if (clrkeylen != len) { 411 PKEY_DBF_ERR("%s invalid clear key len %d != %d\n", 412 __func__, clrkeylen, len); 413 return -EINVAL; 414 } 415 switch (subtype) { 416 case PKEY_TYPE_CCA_DATA: 417 case PKEY_TYPE_CCA_CIPHER: 418 break; 419 default: 420 PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n", 421 __func__, subtype); 422 return -EINVAL; 423 } 424 break; 425 default: 426 PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n", 427 __func__, keytype); 428 return -EINVAL; 429 } 430 431 zcrypt_wait_api_operational(); 432 433 if (!apqns || (nr_apqns == 1 && 434 apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) { 435 nr_apqns = MAXAPQNSINLIST; 436 rc = cca_apqns4type(subtype, NULL, NULL, 0, 437 _apqns, &nr_apqns, pflags); 438 if (rc) 439 goto out; 440 apqns = _apqns; 441 } 442 443 for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) { 444 if (subtype == PKEY_TYPE_CCA_CIPHER) { 445 rc = cca_clr2cipherkey(apqns[i].card, apqns[i].domain, 446 keybitsize, flags, clrkey, 447 keybuf, keybuflen, xflags); 448 } else { 449 /* PKEY_TYPE_CCA_DATA */ 450 rc = cca_clr2seckey(apqns[i].card, apqns[i].domain, 451 keybitsize, clrkey, keybuf, xflags); 452 *keybuflen = (rc ? 0 : SECKEYBLOBSIZE); 453 } 454 } 455 456 out: 457 pr_debug("rc=%d\n", rc); 458 return rc; 459 } 460 461 static int cca_verifykey(const u8 *key, u32 keylen, 462 u16 *card, u16 *dom, 463 u32 *keytype, u32 *keybitsize, u32 *flags, u32 pflags) 464 { 465 struct keytoken_header *hdr = (struct keytoken_header *)key; 466 u32 apqns[MAXAPQNSINLIST], nr_apqns = ARRAY_SIZE(apqns); 467 u32 xflags; 468 int rc; 469 470 xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0; 471 472 if (keylen < sizeof(*hdr)) 473 return -EINVAL; 474 475 zcrypt_wait_api_operational(); 476 477 if (hdr->type == TOKTYPE_CCA_INTERNAL && 478 hdr->version == TOKVER_CCA_AES) { 479 struct secaeskeytoken *t = (struct secaeskeytoken *)key; 480 481 rc = cca_check_secaeskeytoken(pkey_dbf_info, 3, key, keylen, 0); 482 if (rc) 483 goto out; 484 *keytype = PKEY_TYPE_CCA_DATA; 485 *keybitsize = t->bitsize; 486 rc = cca_findcard2(apqns, &nr_apqns, *card, *dom, 487 ZCRYPT_CEX3C, AES_MK_SET, 488 t->mkvp, NULL, xflags); 489 if (!rc) 490 *flags = PKEY_FLAGS_MATCH_CUR_MKVP; 491 if (rc == -ENODEV) { 492 nr_apqns = ARRAY_SIZE(apqns); 493 rc = cca_findcard2(apqns, &nr_apqns, *card, *dom, 494 ZCRYPT_CEX3C, AES_MK_SET, 495 NULL, t->mkvp, xflags); 496 if (!rc) 497 *flags = PKEY_FLAGS_MATCH_ALT_MKVP; 498 } 499 if (rc) 500 goto out; 501 502 *card = ((struct pkey_apqn *)apqns)->card; 503 *dom = ((struct pkey_apqn *)apqns)->domain; 504 505 } else if (hdr->type == TOKTYPE_CCA_INTERNAL && 506 hdr->version == TOKVER_CCA_VLSC) { 507 struct cipherkeytoken *t = (struct cipherkeytoken *)key; 508 509 rc = cca_check_secaescipherkey(pkey_dbf_info, 3, 510 key, keylen, 0, 1); 511 if (rc) 512 goto out; 513 *keytype = PKEY_TYPE_CCA_CIPHER; 514 *keybitsize = PKEY_SIZE_UNKNOWN; 515 if (!t->plfver && t->wpllen == 512) 516 *keybitsize = PKEY_SIZE_AES_128; 517 else if (!t->plfver && t->wpllen == 576) 518 *keybitsize = PKEY_SIZE_AES_192; 519 else if (!t->plfver && t->wpllen == 640) 520 *keybitsize = PKEY_SIZE_AES_256; 521 rc = cca_findcard2(apqns, &nr_apqns, *card, *dom, 522 ZCRYPT_CEX6, AES_MK_SET, 523 t->mkvp0, NULL, xflags); 524 if (!rc) 525 *flags = PKEY_FLAGS_MATCH_CUR_MKVP; 526 if (rc == -ENODEV) { 527 nr_apqns = ARRAY_SIZE(apqns); 528 rc = cca_findcard2(apqns, &nr_apqns, *card, *dom, 529 ZCRYPT_CEX6, AES_MK_SET, 530 NULL, t->mkvp0, xflags); 531 if (!rc) 532 *flags = PKEY_FLAGS_MATCH_ALT_MKVP; 533 } 534 if (rc) 535 goto out; 536 537 *card = ((struct pkey_apqn *)apqns)->card; 538 *dom = ((struct pkey_apqn *)apqns)->domain; 539 540 } else { 541 /* unknown/unsupported key blob */ 542 rc = -EINVAL; 543 } 544 545 out: 546 pr_debug("rc=%d\n", rc); 547 return rc; 548 } 549 550 /* 551 * This function provides an alternate but usually slow way 552 * to convert a 'clear key token' with AES key material into 553 * a protected key. This is done via an intermediate step 554 * which creates a CCA AES DATA secure key first and then 555 * derives the protected key from this secure key. 556 */ 557 static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns, 558 size_t nr_apqns, 559 const u8 *key, u32 keylen, 560 u8 *protkey, u32 *protkeylen, 561 u32 *protkeytype, u32 pflags) 562 { 563 const struct keytoken_header *hdr = (const struct keytoken_header *)key; 564 const struct clearkeytoken *t = (const struct clearkeytoken *)key; 565 u8 tmpbuf[SECKEYBLOBSIZE]; /* 64 bytes */ 566 u32 tmplen, keysize = 0; 567 int i, rc; 568 569 if (keylen < sizeof(*hdr)) 570 return -EINVAL; 571 572 if (hdr->type == TOKTYPE_NON_CCA && 573 hdr->version == TOKVER_CLEAR_KEY) 574 keysize = pkey_keytype_aes_to_size(t->keytype); 575 if (!keysize || t->len != keysize) 576 return -EINVAL; 577 578 /* try two times in case of failure */ 579 for (i = 0, rc = -ENODEV; i < 2 && rc; i++) { 580 tmplen = SECKEYBLOBSIZE; 581 rc = cca_clr2key(NULL, 0, t->keytype, PKEY_TYPE_CCA_DATA, 582 8 * keysize, 0, t->clearkey, t->len, 583 tmpbuf, &tmplen, NULL, pflags); 584 pr_debug("cca_clr2key()=%d\n", rc); 585 if (rc) 586 continue; 587 rc = cca_key2protkey(NULL, 0, tmpbuf, tmplen, 588 protkey, protkeylen, protkeytype, pflags); 589 pr_debug("cca_key2protkey()=%d\n", rc); 590 } 591 592 pr_debug("rc=%d\n", rc); 593 return rc; 594 } 595 596 static struct pkey_handler cca_handler = { 597 .module = THIS_MODULE, 598 .name = "PKEY CCA handler", 599 .is_supported_key = is_cca_key, 600 .is_supported_keytype = is_cca_keytype, 601 .key_to_protkey = cca_key2protkey, 602 .slowpath_key_to_protkey = cca_slowpath_key2protkey, 603 .gen_key = cca_gen_key, 604 .clr_to_key = cca_clr2key, 605 .verify_key = cca_verifykey, 606 .apqns_for_key = cca_apqns4key, 607 .apqns_for_keytype = cca_apqns4type, 608 }; 609 610 /* 611 * Module init 612 */ 613 static int __init pkey_cca_init(void) 614 { 615 /* register this module as pkey handler for all the cca stuff */ 616 return pkey_handler_register(&cca_handler); 617 } 618 619 /* 620 * Module exit 621 */ 622 static void __exit pkey_cca_exit(void) 623 { 624 /* unregister this module as pkey handler */ 625 pkey_handler_unregister(&cca_handler); 626 } 627 628 module_init(pkey_cca_init); 629 module_exit(pkey_cca_exit); 630