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