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