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