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