xref: /linux/drivers/s390/crypto/pkey_cca.c (revision 6f7e6393d1ce636bb7ec77a7fe7b77458fddf701)
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 	if (pflags & PKEY_XFLAG_NOCLEARKEY) {
394 		PKEY_DBF_ERR("%s clear key but xflag NOCLEARKEY\n", __func__);
395 		return -EINVAL;
396 	}
397 
398 	xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
399 
400 	/* check keytype, subtype, clrkeylen, keybitsize */
401 	switch (keytype) {
402 	case PKEY_KEYTYPE_AES_128:
403 	case PKEY_KEYTYPE_AES_192:
404 	case PKEY_KEYTYPE_AES_256:
405 		len = pkey_keytype_aes_to_size(keytype);
406 		if (keybitsize && keybitsize != 8 * len) {
407 			PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
408 				     __func__, keybitsize);
409 			return -EINVAL;
410 		}
411 		keybitsize = 8 * len;
412 		if (clrkeylen != len) {
413 			PKEY_DBF_ERR("%s invalid clear key len %d != %d\n",
414 				     __func__, clrkeylen, len);
415 			return -EINVAL;
416 		}
417 		switch (subtype) {
418 		case PKEY_TYPE_CCA_DATA:
419 		case PKEY_TYPE_CCA_CIPHER:
420 			break;
421 		default:
422 			PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
423 				     __func__, subtype);
424 			return -EINVAL;
425 		}
426 		break;
427 	default:
428 		PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
429 			     __func__, keytype);
430 		return -EINVAL;
431 	}
432 
433 	zcrypt_wait_api_operational();
434 
435 	if (!apqns || (nr_apqns == 1 &&
436 		       apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
437 		nr_apqns = MAXAPQNSINLIST;
438 		rc = cca_apqns4type(subtype, NULL, NULL, 0,
439 				    _apqns, &nr_apqns, pflags);
440 		if (rc)
441 			goto out;
442 		apqns = _apqns;
443 	}
444 
445 	for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
446 		if (subtype == PKEY_TYPE_CCA_CIPHER) {
447 			rc = cca_clr2cipherkey(apqns[i].card, apqns[i].domain,
448 					       keybitsize, flags, clrkey,
449 					       keybuf, keybuflen, xflags);
450 		} else {
451 			/* PKEY_TYPE_CCA_DATA */
452 			rc = cca_clr2seckey(apqns[i].card, apqns[i].domain,
453 					    keybitsize, clrkey, keybuf, xflags);
454 			*keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
455 		}
456 	}
457 
458 out:
459 	pr_debug("rc=%d\n", rc);
460 	return rc;
461 }
462 
463 static int cca_verifykey(const u8 *key, u32 keylen,
464 			 u16 *card, u16 *dom,
465 			 u32 *keytype, u32 *keybitsize, u32 *flags, u32 pflags)
466 {
467 	struct keytoken_header *hdr = (struct keytoken_header *)key;
468 	u32 apqns[MAXAPQNSINLIST], nr_apqns = ARRAY_SIZE(apqns);
469 	u32 xflags;
470 	int rc;
471 
472 	xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
473 
474 	if (keylen < sizeof(*hdr))
475 		return -EINVAL;
476 
477 	zcrypt_wait_api_operational();
478 
479 	if (hdr->type == TOKTYPE_CCA_INTERNAL &&
480 	    hdr->version == TOKVER_CCA_AES) {
481 		struct secaeskeytoken *t = (struct secaeskeytoken *)key;
482 
483 		rc = cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0);
484 		if (rc)
485 			goto out;
486 		*keytype = PKEY_TYPE_CCA_DATA;
487 		*keybitsize = t->bitsize;
488 		rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
489 				   ZCRYPT_CEX3C, AES_MK_SET,
490 				   t->mkvp, 0, xflags);
491 		if (!rc)
492 			*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
493 		if (rc == -ENODEV) {
494 			nr_apqns = ARRAY_SIZE(apqns);
495 			rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
496 					   ZCRYPT_CEX3C, AES_MK_SET,
497 					   0, t->mkvp, xflags);
498 			if (!rc)
499 				*flags = PKEY_FLAGS_MATCH_ALT_MKVP;
500 		}
501 		if (rc)
502 			goto out;
503 
504 		*card = ((struct pkey_apqn *)apqns)->card;
505 		*dom = ((struct pkey_apqn *)apqns)->domain;
506 
507 	} else if (hdr->type == TOKTYPE_CCA_INTERNAL &&
508 		   hdr->version == TOKVER_CCA_VLSC) {
509 		struct cipherkeytoken *t = (struct cipherkeytoken *)key;
510 
511 		rc = cca_check_secaescipherkey(pkey_dbf_info, 3, key, 0, 1);
512 		if (rc)
513 			goto out;
514 		*keytype = PKEY_TYPE_CCA_CIPHER;
515 		*keybitsize = PKEY_SIZE_UNKNOWN;
516 		if (!t->plfver && t->wpllen == 512)
517 			*keybitsize = PKEY_SIZE_AES_128;
518 		else if (!t->plfver && t->wpllen == 576)
519 			*keybitsize = PKEY_SIZE_AES_192;
520 		else if (!t->plfver && t->wpllen == 640)
521 			*keybitsize = PKEY_SIZE_AES_256;
522 		rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
523 				   ZCRYPT_CEX6, AES_MK_SET,
524 				   t->mkvp0, 0, xflags);
525 		if (!rc)
526 			*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
527 		if (rc == -ENODEV) {
528 			nr_apqns = ARRAY_SIZE(apqns);
529 			rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
530 					   ZCRYPT_CEX6, AES_MK_SET,
531 					   0, t->mkvp0, xflags);
532 			if (!rc)
533 				*flags = PKEY_FLAGS_MATCH_ALT_MKVP;
534 		}
535 		if (rc)
536 			goto out;
537 
538 		*card = ((struct pkey_apqn *)apqns)->card;
539 		*dom = ((struct pkey_apqn *)apqns)->domain;
540 
541 	} else {
542 		/* unknown/unsupported key blob */
543 		rc = -EINVAL;
544 	}
545 
546 out:
547 	pr_debug("rc=%d\n", rc);
548 	return rc;
549 }
550 
551 /*
552  * This function provides an alternate but usually slow way
553  * to convert a 'clear key token' with AES key material into
554  * a protected key. This is done via an intermediate step
555  * which creates a CCA AES DATA secure key first and then
556  * derives the protected key from this secure key.
557  */
558 static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns,
559 				    size_t nr_apqns,
560 				    const u8 *key, u32 keylen,
561 				    u8 *protkey, u32 *protkeylen,
562 				    u32 *protkeytype, u32 pflags)
563 {
564 	const struct keytoken_header *hdr = (const struct keytoken_header *)key;
565 	const struct clearkeytoken *t = (const struct clearkeytoken *)key;
566 	u8 tmpbuf[SECKEYBLOBSIZE]; /* 64 bytes */
567 	u32 tmplen, keysize = 0;
568 	int i, rc;
569 
570 	if (keylen < sizeof(*hdr))
571 		return -EINVAL;
572 
573 	if (hdr->type == TOKTYPE_NON_CCA &&
574 	    hdr->version == TOKVER_CLEAR_KEY)
575 		keysize = pkey_keytype_aes_to_size(t->keytype);
576 	if (!keysize || t->len != keysize)
577 		return -EINVAL;
578 
579 	/* try two times in case of failure */
580 	for (i = 0, rc = -ENODEV; i < 2 && rc; i++) {
581 		tmplen = SECKEYBLOBSIZE;
582 		rc = cca_clr2key(NULL, 0, t->keytype, PKEY_TYPE_CCA_DATA,
583 				 8 * keysize, 0, t->clearkey, t->len,
584 				 tmpbuf, &tmplen, NULL, pflags);
585 		pr_debug("cca_clr2key()=%d\n", rc);
586 		if (rc)
587 			continue;
588 		rc = cca_key2protkey(NULL, 0, tmpbuf, tmplen,
589 				     protkey, protkeylen, protkeytype, pflags);
590 		pr_debug("cca_key2protkey()=%d\n", rc);
591 	}
592 
593 	pr_debug("rc=%d\n", rc);
594 	return rc;
595 }
596 
597 static struct pkey_handler cca_handler = {
598 	.module			 = THIS_MODULE,
599 	.name			 = "PKEY CCA handler",
600 	.is_supported_key	 = is_cca_key,
601 	.is_supported_keytype	 = is_cca_keytype,
602 	.key_to_protkey		 = cca_key2protkey,
603 	.slowpath_key_to_protkey = cca_slowpath_key2protkey,
604 	.gen_key		 = cca_gen_key,
605 	.clr_to_key		 = cca_clr2key,
606 	.verify_key		 = cca_verifykey,
607 	.apqns_for_key		 = cca_apqns4key,
608 	.apqns_for_keytype	 = cca_apqns4type,
609 };
610 
611 /*
612  * Module init
613  */
614 static int __init pkey_cca_init(void)
615 {
616 	/* register this module as pkey handler for all the cca stuff */
617 	return pkey_handler_register(&cca_handler);
618 }
619 
620 /*
621  * Module exit
622  */
623 static void __exit pkey_cca_exit(void)
624 {
625 	/* unregister this module as pkey handler */
626 	pkey_handler_unregister(&cca_handler);
627 }
628 
629 module_init(pkey_cca_init);
630 module_exit(pkey_cca_exit);
631