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