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