xref: /linux/drivers/s390/crypto/pkey_cca.c (revision 2a4c0c11c0193889446cdb6f1540cc2b9aff97dd)
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 (keylen < sizeof(struct secaeskeytoken))
240 			return -EINVAL;
241 		if (cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0))
242 			return -EINVAL;
243 	} else if (hdr->type == TOKTYPE_CCA_INTERNAL &&
244 		   hdr->version == TOKVER_CCA_VLSC) {
245 		/* CCA AES cipher key */
246 		if (keylen < hdr->len)
247 			return -EINVAL;
248 		if (cca_check_secaescipherkey(pkey_dbf_info,
249 					      3, key, 0, 1))
250 			return -EINVAL;
251 	} else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
252 		/* CCA ECC (private) key */
253 		if (keylen < sizeof(struct eccprivkeytoken))
254 			return -EINVAL;
255 		if (cca_check_sececckeytoken(pkey_dbf_info, 3, key, keylen, 1))
256 			return -EINVAL;
257 	} else {
258 		PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",
259 			     __func__, hdr->type, hdr->version);
260 		return -EINVAL;
261 	}
262 
263 	zcrypt_wait_api_operational();
264 
265 	if (!apqns || (nr_apqns == 1 &&
266 		       apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
267 		nr_apqns = MAXAPQNSINLIST;
268 		rc = cca_apqns4key(key, keylen, 0, _apqns, &nr_apqns, pflags);
269 		if (rc)
270 			goto out;
271 		apqns = _apqns;
272 	}
273 
274 	for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
275 		if (hdr->type == TOKTYPE_CCA_INTERNAL &&
276 		    hdr->version == TOKVER_CCA_AES) {
277 			rc = cca_sec2protkey(apqns[i].card, apqns[i].domain,
278 					     key, protkey,
279 					     protkeylen, protkeytype, xflags);
280 		} else if (hdr->type == TOKTYPE_CCA_INTERNAL &&
281 			   hdr->version == TOKVER_CCA_VLSC) {
282 			rc = cca_cipher2protkey(apqns[i].card, apqns[i].domain,
283 						key, protkey,
284 						protkeylen, protkeytype, xflags);
285 		} else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
286 			rc = cca_ecc2protkey(apqns[i].card, apqns[i].domain,
287 					     key, protkey,
288 					     protkeylen, protkeytype, xflags);
289 		} else {
290 			rc = -EINVAL;
291 			break;
292 		}
293 	}
294 
295 out:
296 	pr_debug("rc=%d\n", rc);
297 	return rc;
298 }
299 
300 /*
301  * Generate CCA secure key.
302  * As of now only CCA AES Data or Cipher secure keys are
303  * supported.
304  * keytype is one of the PKEY_KEYTYPE_* constants,
305  * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER,
306  * keybitsize is the bit size of the key (may be 0 for
307  * keytype PKEY_KEYTYPE_AES_*).
308  */
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)309 static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
310 		       u32 keytype, u32 subtype,
311 		       u32 keybitsize, u32 flags,
312 		       u8 *keybuf, u32 *keybuflen, u32 *_keyinfo, u32 pflags)
313 {
314 	struct pkey_apqn _apqns[MAXAPQNSINLIST];
315 	int i, len, rc;
316 	u32 xflags;
317 
318 	xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
319 
320 	/* check keytype, subtype, keybitsize */
321 	switch (keytype) {
322 	case PKEY_KEYTYPE_AES_128:
323 	case PKEY_KEYTYPE_AES_192:
324 	case PKEY_KEYTYPE_AES_256:
325 		len = pkey_keytype_aes_to_size(keytype);
326 		if (keybitsize && keybitsize != 8 * len) {
327 			PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
328 				     __func__, keybitsize);
329 			return -EINVAL;
330 		}
331 		keybitsize = 8 * len;
332 		switch (subtype) {
333 		case PKEY_TYPE_CCA_DATA:
334 		case PKEY_TYPE_CCA_CIPHER:
335 			break;
336 		default:
337 			PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
338 				     __func__, subtype);
339 			return -EINVAL;
340 		}
341 		break;
342 	default:
343 		PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
344 			     __func__, keytype);
345 		return -EINVAL;
346 	}
347 
348 	zcrypt_wait_api_operational();
349 
350 	if (!apqns || (nr_apqns == 1 &&
351 		       apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
352 		nr_apqns = MAXAPQNSINLIST;
353 		rc = cca_apqns4type(subtype, NULL, NULL, 0,
354 				    _apqns, &nr_apqns, pflags);
355 		if (rc)
356 			goto out;
357 		apqns = _apqns;
358 	}
359 
360 	for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
361 		if (subtype == PKEY_TYPE_CCA_CIPHER) {
362 			rc = cca_gencipherkey(apqns[i].card, apqns[i].domain,
363 					      keybitsize, flags,
364 					      keybuf, keybuflen, xflags);
365 		} else {
366 			/* PKEY_TYPE_CCA_DATA */
367 			rc = cca_genseckey(apqns[i].card, apqns[i].domain,
368 					   keybitsize, keybuf, xflags);
369 			*keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
370 		}
371 	}
372 
373 out:
374 	pr_debug("rc=%d\n", rc);
375 	return rc;
376 }
377 
378 /*
379  * Generate CCA secure key with given clear key value.
380  * As of now only CCA AES Data or Cipher secure keys are
381  * supported.
382  * keytype is one of the PKEY_KEYTYPE_* constants,
383  * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER,
384  * keybitsize is the bit size of the key (may be 0 for
385  * keytype PKEY_KEYTYPE_AES_*).
386  */
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)387 static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
388 		       u32 keytype, u32 subtype,
389 		       u32 keybitsize, u32 flags,
390 		       const u8 *clrkey, u32 clrkeylen,
391 		       u8 *keybuf, u32 *keybuflen, u32 *_keyinfo, u32 pflags)
392 {
393 	struct pkey_apqn _apqns[MAXAPQNSINLIST];
394 	int i, len, rc;
395 	u32 xflags;
396 
397 	if (pflags & PKEY_XFLAG_NOCLEARKEY) {
398 		PKEY_DBF_ERR("%s clear key but xflag NOCLEARKEY\n", __func__);
399 		return -EINVAL;
400 	}
401 
402 	xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
403 
404 	/* check keytype, subtype, clrkeylen, keybitsize */
405 	switch (keytype) {
406 	case PKEY_KEYTYPE_AES_128:
407 	case PKEY_KEYTYPE_AES_192:
408 	case PKEY_KEYTYPE_AES_256:
409 		len = pkey_keytype_aes_to_size(keytype);
410 		if (keybitsize && keybitsize != 8 * len) {
411 			PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
412 				     __func__, keybitsize);
413 			return -EINVAL;
414 		}
415 		keybitsize = 8 * len;
416 		if (clrkeylen != len) {
417 			PKEY_DBF_ERR("%s invalid clear key len %d != %d\n",
418 				     __func__, clrkeylen, len);
419 			return -EINVAL;
420 		}
421 		switch (subtype) {
422 		case PKEY_TYPE_CCA_DATA:
423 		case PKEY_TYPE_CCA_CIPHER:
424 			break;
425 		default:
426 			PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
427 				     __func__, subtype);
428 			return -EINVAL;
429 		}
430 		break;
431 	default:
432 		PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
433 			     __func__, keytype);
434 		return -EINVAL;
435 	}
436 
437 	zcrypt_wait_api_operational();
438 
439 	if (!apqns || (nr_apqns == 1 &&
440 		       apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
441 		nr_apqns = MAXAPQNSINLIST;
442 		rc = cca_apqns4type(subtype, NULL, NULL, 0,
443 				    _apqns, &nr_apqns, pflags);
444 		if (rc)
445 			goto out;
446 		apqns = _apqns;
447 	}
448 
449 	for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
450 		if (subtype == PKEY_TYPE_CCA_CIPHER) {
451 			rc = cca_clr2cipherkey(apqns[i].card, apqns[i].domain,
452 					       keybitsize, flags, clrkey,
453 					       keybuf, keybuflen, xflags);
454 		} else {
455 			/* PKEY_TYPE_CCA_DATA */
456 			rc = cca_clr2seckey(apqns[i].card, apqns[i].domain,
457 					    keybitsize, clrkey, keybuf, xflags);
458 			*keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
459 		}
460 	}
461 
462 out:
463 	pr_debug("rc=%d\n", rc);
464 	return rc;
465 }
466 
cca_verifykey(const u8 * key,u32 keylen,u16 * card,u16 * dom,u32 * keytype,u32 * keybitsize,u32 * flags,u32 pflags)467 static int cca_verifykey(const u8 *key, u32 keylen,
468 			 u16 *card, u16 *dom,
469 			 u32 *keytype, u32 *keybitsize, u32 *flags, u32 pflags)
470 {
471 	struct keytoken_header *hdr = (struct keytoken_header *)key;
472 	u32 apqns[MAXAPQNSINLIST], nr_apqns = ARRAY_SIZE(apqns);
473 	u32 xflags;
474 	int rc;
475 
476 	xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
477 
478 	if (keylen < sizeof(*hdr))
479 		return -EINVAL;
480 
481 	zcrypt_wait_api_operational();
482 
483 	if (hdr->type == TOKTYPE_CCA_INTERNAL &&
484 	    hdr->version == TOKVER_CCA_AES) {
485 		struct secaeskeytoken *t = (struct secaeskeytoken *)key;
486 
487 		rc = cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0);
488 		if (rc)
489 			goto out;
490 		*keytype = PKEY_TYPE_CCA_DATA;
491 		*keybitsize = t->bitsize;
492 		rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
493 				   ZCRYPT_CEX3C, AES_MK_SET,
494 				   t->mkvp, NULL, xflags);
495 		if (!rc)
496 			*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
497 		if (rc == -ENODEV) {
498 			nr_apqns = ARRAY_SIZE(apqns);
499 			rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
500 					   ZCRYPT_CEX3C, AES_MK_SET,
501 					   NULL, t->mkvp, xflags);
502 			if (!rc)
503 				*flags = PKEY_FLAGS_MATCH_ALT_MKVP;
504 		}
505 		if (rc)
506 			goto out;
507 
508 		*card = ((struct pkey_apqn *)apqns)->card;
509 		*dom = ((struct pkey_apqn *)apqns)->domain;
510 
511 	} else if (hdr->type == TOKTYPE_CCA_INTERNAL &&
512 		   hdr->version == TOKVER_CCA_VLSC) {
513 		struct cipherkeytoken *t = (struct cipherkeytoken *)key;
514 
515 		rc = cca_check_secaescipherkey(pkey_dbf_info, 3, key, 0, 1);
516 		if (rc)
517 			goto out;
518 		*keytype = PKEY_TYPE_CCA_CIPHER;
519 		*keybitsize = PKEY_SIZE_UNKNOWN;
520 		if (!t->plfver && t->wpllen == 512)
521 			*keybitsize = PKEY_SIZE_AES_128;
522 		else if (!t->plfver && t->wpllen == 576)
523 			*keybitsize = PKEY_SIZE_AES_192;
524 		else if (!t->plfver && t->wpllen == 640)
525 			*keybitsize = PKEY_SIZE_AES_256;
526 		rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
527 				   ZCRYPT_CEX6, AES_MK_SET,
528 				   t->mkvp0, NULL, xflags);
529 		if (!rc)
530 			*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
531 		if (rc == -ENODEV) {
532 			nr_apqns = ARRAY_SIZE(apqns);
533 			rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
534 					   ZCRYPT_CEX6, AES_MK_SET,
535 					   NULL, t->mkvp0, xflags);
536 			if (!rc)
537 				*flags = PKEY_FLAGS_MATCH_ALT_MKVP;
538 		}
539 		if (rc)
540 			goto out;
541 
542 		*card = ((struct pkey_apqn *)apqns)->card;
543 		*dom = ((struct pkey_apqn *)apqns)->domain;
544 
545 	} else {
546 		/* unknown/unsupported key blob */
547 		rc = -EINVAL;
548 	}
549 
550 out:
551 	pr_debug("rc=%d\n", rc);
552 	return rc;
553 }
554 
555 /*
556  * This function provides an alternate but usually slow way
557  * to convert a 'clear key token' with AES key material into
558  * a protected key. This is done via an intermediate step
559  * which creates a CCA AES DATA secure key first and then
560  * derives the protected key from this secure key.
561  */
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)562 static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns,
563 				    size_t nr_apqns,
564 				    const u8 *key, u32 keylen,
565 				    u8 *protkey, u32 *protkeylen,
566 				    u32 *protkeytype, u32 pflags)
567 {
568 	const struct keytoken_header *hdr = (const struct keytoken_header *)key;
569 	const struct clearkeytoken *t = (const struct clearkeytoken *)key;
570 	u8 tmpbuf[SECKEYBLOBSIZE]; /* 64 bytes */
571 	u32 tmplen, keysize = 0;
572 	int i, rc;
573 
574 	if (keylen < sizeof(*hdr))
575 		return -EINVAL;
576 
577 	if (hdr->type == TOKTYPE_NON_CCA &&
578 	    hdr->version == TOKVER_CLEAR_KEY)
579 		keysize = pkey_keytype_aes_to_size(t->keytype);
580 	if (!keysize || t->len != keysize)
581 		return -EINVAL;
582 
583 	/* try two times in case of failure */
584 	for (i = 0, rc = -ENODEV; i < 2 && rc; i++) {
585 		tmplen = SECKEYBLOBSIZE;
586 		rc = cca_clr2key(NULL, 0, t->keytype, PKEY_TYPE_CCA_DATA,
587 				 8 * keysize, 0, t->clearkey, t->len,
588 				 tmpbuf, &tmplen, NULL, pflags);
589 		pr_debug("cca_clr2key()=%d\n", rc);
590 		if (rc)
591 			continue;
592 		rc = cca_key2protkey(NULL, 0, tmpbuf, tmplen,
593 				     protkey, protkeylen, protkeytype, pflags);
594 		pr_debug("cca_key2protkey()=%d\n", rc);
595 	}
596 
597 	pr_debug("rc=%d\n", rc);
598 	return rc;
599 }
600 
601 static struct pkey_handler cca_handler = {
602 	.module			 = THIS_MODULE,
603 	.name			 = "PKEY CCA handler",
604 	.is_supported_key	 = is_cca_key,
605 	.is_supported_keytype	 = is_cca_keytype,
606 	.key_to_protkey		 = cca_key2protkey,
607 	.slowpath_key_to_protkey = cca_slowpath_key2protkey,
608 	.gen_key		 = cca_gen_key,
609 	.clr_to_key		 = cca_clr2key,
610 	.verify_key		 = cca_verifykey,
611 	.apqns_for_key		 = cca_apqns4key,
612 	.apqns_for_keytype	 = cca_apqns4type,
613 };
614 
615 /*
616  * Module init
617  */
pkey_cca_init(void)618 static int __init pkey_cca_init(void)
619 {
620 	/* register this module as pkey handler for all the cca stuff */
621 	return pkey_handler_register(&cca_handler);
622 }
623 
624 /*
625  * Module exit
626  */
pkey_cca_exit(void)627 static void __exit pkey_cca_exit(void)
628 {
629 	/* unregister this module as pkey handler */
630 	pkey_handler_unregister(&cca_handler);
631 }
632 
633 module_init(pkey_cca_init);
634 module_exit(pkey_cca_exit);
635