xref: /linux/drivers/s390/crypto/pkey_pckmo.c (revision 6f7e6393d1ce636bb7ec77a7fe7b77458fddf701)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  pkey pckmo 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 #include <asm/cpacf.h>
14 #include <crypto/aes.h>
15 #include <linux/random.h>
16 
17 #include "zcrypt_ccamisc.h"
18 #include "pkey_base.h"
19 
20 MODULE_LICENSE("GPL");
21 MODULE_AUTHOR("IBM Corporation");
22 MODULE_DESCRIPTION("s390 protected key PCKMO handler");
23 
24 /*
25  * Check key blob for known and supported here.
26  */
27 static bool is_pckmo_key(const u8 *key, u32 keylen)
28 {
29 	struct keytoken_header *hdr = (struct keytoken_header *)key;
30 	struct clearkeytoken *t = (struct clearkeytoken *)key;
31 
32 	if (keylen < sizeof(*hdr))
33 		return false;
34 
35 	switch (hdr->type) {
36 	case TOKTYPE_NON_CCA:
37 		switch (hdr->version) {
38 		case TOKVER_CLEAR_KEY:
39 			if (pkey_keytype_to_size(t->keytype))
40 				return true;
41 			return false;
42 		case TOKVER_PROTECTED_KEY:
43 			return true;
44 		default:
45 			return false;
46 		}
47 	default:
48 		return false;
49 	}
50 }
51 
52 static bool is_pckmo_keytype(enum pkey_key_type keytype)
53 {
54 	switch (keytype) {
55 	case PKEY_TYPE_PROTKEY:
56 		return true;
57 	default:
58 		return false;
59 	}
60 }
61 
62 /*
63  * Create a protected key from a clear key value via PCKMO instruction.
64  */
65 static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen,
66 			     u8 *protkey, u32 *protkeylen, u32 *protkeytype)
67 {
68 	/* mask of available pckmo subfunctions */
69 	static cpacf_mask_t pckmo_functions;
70 
71 	int keysize, rc = -EINVAL;
72 	u8 paramblock[160];
73 	u32 pkeytype = 0;
74 	unsigned int fc;
75 
76 	switch (keytype) {
77 	case PKEY_KEYTYPE_AES_128:
78 		fc = CPACF_PCKMO_ENC_AES_128_KEY;
79 		break;
80 	case PKEY_KEYTYPE_AES_192:
81 		fc = CPACF_PCKMO_ENC_AES_192_KEY;
82 		break;
83 	case PKEY_KEYTYPE_AES_256:
84 		fc = CPACF_PCKMO_ENC_AES_256_KEY;
85 		break;
86 	case PKEY_KEYTYPE_ECC_P256:
87 		pkeytype = PKEY_KEYTYPE_ECC;
88 		fc = CPACF_PCKMO_ENC_ECC_P256_KEY;
89 		break;
90 	case PKEY_KEYTYPE_ECC_P384:
91 		pkeytype = PKEY_KEYTYPE_ECC;
92 		fc = CPACF_PCKMO_ENC_ECC_P384_KEY;
93 		break;
94 	case PKEY_KEYTYPE_ECC_P521:
95 		pkeytype = PKEY_KEYTYPE_ECC;
96 		fc = CPACF_PCKMO_ENC_ECC_P521_KEY;
97 		break;
98 	case PKEY_KEYTYPE_ECC_ED25519:
99 		pkeytype = PKEY_KEYTYPE_ECC;
100 		fc = CPACF_PCKMO_ENC_ECC_ED25519_KEY;
101 		break;
102 	case PKEY_KEYTYPE_ECC_ED448:
103 		pkeytype = PKEY_KEYTYPE_ECC;
104 		fc = CPACF_PCKMO_ENC_ECC_ED448_KEY;
105 		break;
106 	case PKEY_KEYTYPE_AES_XTS_128:
107 		fc = CPACF_PCKMO_ENC_AES_XTS_128_DOUBLE_KEY;
108 		break;
109 	case PKEY_KEYTYPE_AES_XTS_256:
110 		fc = CPACF_PCKMO_ENC_AES_XTS_256_DOUBLE_KEY;
111 		break;
112 	case PKEY_KEYTYPE_HMAC_512:
113 		fc = CPACF_PCKMO_ENC_HMAC_512_KEY;
114 		break;
115 	case PKEY_KEYTYPE_HMAC_1024:
116 		fc = CPACF_PCKMO_ENC_HMAC_1024_KEY;
117 		break;
118 	default:
119 		PKEY_DBF_ERR("%s unknown/unsupported keytype %u\n",
120 			     __func__, keytype);
121 		goto out;
122 	}
123 
124 	keysize = pkey_keytype_to_size(keytype);
125 	pkeytype = pkeytype ?: keytype;
126 
127 	if (clrkeylen && clrkeylen < keysize) {
128 		PKEY_DBF_ERR("%s clear key size too small: %u < %d\n",
129 			     __func__, clrkeylen, keysize);
130 		goto out;
131 	}
132 	if (*protkeylen < keysize + AES_WK_VP_SIZE) {
133 		PKEY_DBF_ERR("%s prot key buffer size too small: %u < %d\n",
134 			     __func__, *protkeylen, keysize + AES_WK_VP_SIZE);
135 		goto out;
136 	}
137 
138 	/* Did we already check for PCKMO ? */
139 	if (!pckmo_functions.bytes[0]) {
140 		/* no, so check now */
141 		if (!cpacf_query(CPACF_PCKMO, &pckmo_functions)) {
142 			PKEY_DBF_ERR("%s cpacf_query() failed\n", __func__);
143 			rc = -ENODEV;
144 			goto out;
145 		}
146 	}
147 	/* check for the pckmo subfunction we need now */
148 	if (!cpacf_test_func(&pckmo_functions, fc)) {
149 		PKEY_DBF_ERR("%s pckmo fc 0x%02x not available\n",
150 			     __func__, fc);
151 		rc = -ENODEV;
152 		goto out;
153 	}
154 
155 	/* prepare param block */
156 	memset(paramblock, 0, sizeof(paramblock));
157 	memcpy(paramblock, clrkey, keysize);
158 
159 	/* call the pckmo instruction */
160 	cpacf_pckmo(fc, paramblock);
161 
162 	/* copy created protected key to key buffer including the wkvp block */
163 	*protkeylen = keysize + AES_WK_VP_SIZE;
164 	memcpy(protkey, paramblock, *protkeylen);
165 	*protkeytype = pkeytype;
166 
167 	rc = 0;
168 
169 out:
170 	pr_debug("rc=%d\n", rc);
171 	return rc;
172 }
173 
174 /*
175  * Verify a raw protected key blob.
176  */
177 static int pckmo_verify_protkey(const u8 *protkey, u32 protkeylen,
178 				u32 protkeytype)
179 {
180 	u8 clrkey[16] = { 0 }, tmpkeybuf[16 + AES_WK_VP_SIZE];
181 	u32 tmpkeybuflen, tmpkeytype;
182 	int keysize, rc = -EINVAL;
183 	u8 *wkvp;
184 
185 	/* check protkey type and size */
186 	keysize = pkey_keytype_to_size(protkeytype);
187 	if (!keysize) {
188 		PKEY_DBF_ERR("%s unknown/unsupported keytype %u\n", __func__,
189 			     protkeytype);
190 		goto out;
191 	}
192 	if (protkeylen < keysize + AES_WK_VP_SIZE)
193 		goto out;
194 
195 	/* generate a dummy AES 128 protected key */
196 	tmpkeybuflen = sizeof(tmpkeybuf);
197 	rc = pckmo_clr2protkey(PKEY_KEYTYPE_AES_128,
198 			       clrkey, sizeof(clrkey),
199 			       tmpkeybuf, &tmpkeybuflen, &tmpkeytype);
200 	if (rc)
201 		goto out;
202 	memzero_explicit(tmpkeybuf, 16);
203 	wkvp = tmpkeybuf + 16;
204 
205 	/* compare WK VP from the temp key with that of the given prot key */
206 	if (memcmp(wkvp, protkey + keysize, AES_WK_VP_SIZE)) {
207 		PKEY_DBF_ERR("%s protected key WK VP mismatch\n", __func__);
208 		rc = -EKEYREJECTED;
209 		goto out;
210 	}
211 
212 out:
213 	pr_debug("rc=%d\n", rc);
214 	return rc;
215 }
216 
217 static int pckmo_key2protkey(const u8 *key, u32 keylen,
218 			     u8 *protkey, u32 *protkeylen, u32 *protkeytype,
219 			     u32 xflags)
220 {
221 	struct keytoken_header *hdr = (struct keytoken_header *)key;
222 	int rc = -EINVAL;
223 
224 	if (keylen < sizeof(*hdr))
225 		return -EINVAL;
226 	if (hdr->type != TOKTYPE_NON_CCA)
227 		return -EINVAL;
228 
229 	switch (hdr->version) {
230 	case TOKVER_PROTECTED_KEY: {
231 		struct protkeytoken *t = (struct protkeytoken *)key;
232 		u32 keysize;
233 
234 		if (keylen < sizeof(*t))
235 			goto out;
236 		keysize = pkey_keytype_to_size(t->keytype);
237 		if (!keysize) {
238 			PKEY_DBF_ERR("%s protected key token: unknown keytype %u\n",
239 				     __func__, t->keytype);
240 			goto out;
241 		}
242 		switch (t->keytype) {
243 		case PKEY_KEYTYPE_AES_128:
244 		case PKEY_KEYTYPE_AES_192:
245 		case PKEY_KEYTYPE_AES_256:
246 			if (t->len != keysize + AES_WK_VP_SIZE ||
247 			    keylen < sizeof(struct protaeskeytoken))
248 				goto out;
249 			rc = pckmo_verify_protkey(t->protkey, t->len,
250 						  t->keytype);
251 			if (rc)
252 				goto out;
253 			break;
254 		default:
255 			if (t->len != keysize + AES_WK_VP_SIZE ||
256 			    keylen < sizeof(*t) + keysize + AES_WK_VP_SIZE)
257 				goto out;
258 			break;
259 		}
260 		memcpy(protkey, t->protkey, t->len);
261 		*protkeylen = t->len;
262 		*protkeytype = t->keytype;
263 		rc = 0;
264 		break;
265 	}
266 	case TOKVER_CLEAR_KEY: {
267 		struct clearkeytoken *t = (struct clearkeytoken *)key;
268 		u32 keysize;
269 
270 		if (xflags & PKEY_XFLAG_NOCLEARKEY) {
271 			PKEY_DBF_ERR("%s clear key token but xflag NOCLEARKEY\n",
272 				     __func__);
273 			goto out;
274 		}
275 		if (keylen < sizeof(*t) ||
276 		    keylen < sizeof(*t) + t->len)
277 			goto out;
278 		keysize = pkey_keytype_to_size(t->keytype);
279 		if (!keysize) {
280 			PKEY_DBF_ERR("%s clear key token: unknown keytype %u\n",
281 				     __func__, t->keytype);
282 			goto out;
283 		}
284 		if (t->len != keysize) {
285 			PKEY_DBF_ERR("%s clear key token: invalid key len %u\n",
286 				     __func__, t->len);
287 			goto out;
288 		}
289 		rc = pckmo_clr2protkey(t->keytype, t->clearkey, t->len,
290 				       protkey, protkeylen, protkeytype);
291 		break;
292 	}
293 	default:
294 		PKEY_DBF_ERR("%s unknown non-CCA token version %d\n",
295 			     __func__, hdr->version);
296 		break;
297 	}
298 
299 out:
300 	pr_debug("rc=%d\n", rc);
301 	return rc;
302 }
303 
304 /*
305  * Generate a random protected key.
306  */
307 static int pckmo_gen_protkey(u32 keytype, u32 subtype,
308 			     u8 *protkey, u32 *protkeylen, u32 *protkeytype)
309 {
310 	u8 clrkey[128];
311 	int keysize;
312 	int rc;
313 
314 	keysize = pkey_keytype_to_size(keytype);
315 	if (!keysize) {
316 		PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
317 			     __func__, keytype);
318 		return -EINVAL;
319 	}
320 	if (subtype != PKEY_TYPE_PROTKEY) {
321 		PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
322 			     __func__, subtype);
323 		return -EINVAL;
324 	}
325 
326 	switch (keytype) {
327 	case PKEY_KEYTYPE_AES_128:
328 	case PKEY_KEYTYPE_AES_192:
329 	case PKEY_KEYTYPE_AES_256:
330 	case PKEY_KEYTYPE_AES_XTS_128:
331 	case PKEY_KEYTYPE_AES_XTS_256:
332 	case PKEY_KEYTYPE_HMAC_512:
333 	case PKEY_KEYTYPE_HMAC_1024:
334 		break;
335 	default:
336 		PKEY_DBF_ERR("%s unsupported keytype %d\n",
337 			     __func__, keytype);
338 		return -EINVAL;
339 	}
340 
341 	/* generate a dummy random clear key */
342 	get_random_bytes(clrkey, keysize);
343 
344 	/* convert it to a dummy protected key */
345 	rc = pckmo_clr2protkey(keytype, clrkey, keysize,
346 			       protkey, protkeylen, protkeytype);
347 	if (rc)
348 		goto out;
349 
350 	/* replace the key part of the protected key with random bytes */
351 	get_random_bytes(protkey, keysize);
352 
353 out:
354 	pr_debug("rc=%d\n", rc);
355 	return rc;
356 }
357 
358 /*
359  * Verify a protected key token blob.
360  */
361 static int pckmo_verify_key(const u8 *key, u32 keylen)
362 {
363 	struct keytoken_header *hdr = (struct keytoken_header *)key;
364 	int rc = -EINVAL;
365 
366 	if (keylen < sizeof(*hdr))
367 		return -EINVAL;
368 	if (hdr->type != TOKTYPE_NON_CCA)
369 		return -EINVAL;
370 
371 	switch (hdr->version) {
372 	case TOKVER_PROTECTED_KEY: {
373 		struct protkeytoken *t = (struct protkeytoken *)key;
374 		u32 keysize;
375 
376 		if (keylen < sizeof(*t))
377 			goto out;
378 		keysize = pkey_keytype_to_size(t->keytype);
379 		if (!keysize || t->len != keysize + AES_WK_VP_SIZE)
380 			goto out;
381 		switch (t->keytype) {
382 		case PKEY_KEYTYPE_AES_128:
383 		case PKEY_KEYTYPE_AES_192:
384 		case PKEY_KEYTYPE_AES_256:
385 			if (keylen < sizeof(struct protaeskeytoken))
386 				goto out;
387 			break;
388 		default:
389 			if (keylen < sizeof(*t) + keysize + AES_WK_VP_SIZE)
390 				goto out;
391 			break;
392 		}
393 		rc = pckmo_verify_protkey(t->protkey, t->len, t->keytype);
394 		break;
395 	}
396 	default:
397 		PKEY_DBF_ERR("%s unknown non-CCA token version %d\n",
398 			     __func__, hdr->version);
399 		break;
400 	}
401 
402 out:
403 	pr_debug("rc=%d\n", rc);
404 	return rc;
405 }
406 
407 /*
408  * Wrapper functions used for the pkey handler struct
409  */
410 
411 static int pkey_pckmo_key2protkey(const struct pkey_apqn *_apqns,
412 				  size_t _nr_apqns,
413 				  const u8 *key, u32 keylen,
414 				  u8 *protkey, u32 *protkeylen, u32 *keyinfo,
415 				  u32 xflags)
416 {
417 	return pckmo_key2protkey(key, keylen,
418 				 protkey, protkeylen, keyinfo, xflags);
419 }
420 
421 static int pkey_pckmo_gen_key(const struct pkey_apqn *_apqns, size_t _nr_apqns,
422 			      u32 keytype, u32 keysubtype,
423 			      u32 _keybitsize, u32 _flags,
424 			      u8 *keybuf, u32 *keybuflen, u32 *keyinfo,
425 			      u32 _xflags __always_unused)
426 {
427 	return pckmo_gen_protkey(keytype, keysubtype,
428 				 keybuf, keybuflen, keyinfo);
429 }
430 
431 static int pkey_pckmo_verifykey(const u8 *key, u32 keylen,
432 				u16 *_card, u16 *_dom,
433 				u32 *_keytype, u32 *_keybitsize,
434 				u32 *_flags, u32 _xflags __always_unused)
435 {
436 	return pckmo_verify_key(key, keylen);
437 }
438 
439 static struct pkey_handler pckmo_handler = {
440 	.module		      = THIS_MODULE,
441 	.name		      = "PKEY PCKMO handler",
442 	.is_supported_key     = is_pckmo_key,
443 	.is_supported_keytype = is_pckmo_keytype,
444 	.key_to_protkey	      = pkey_pckmo_key2protkey,
445 	.gen_key	      = pkey_pckmo_gen_key,
446 	.verify_key	      = pkey_pckmo_verifykey,
447 };
448 
449 /*
450  * Module init
451  */
452 static int __init pkey_pckmo_init(void)
453 {
454 	cpacf_mask_t func_mask;
455 
456 	/*
457 	 * The pckmo instruction should be available - even if we don't
458 	 * actually invoke it. This instruction comes with MSA 3 which
459 	 * is also the minimum level for the kmc instructions which
460 	 * are able to work with protected keys.
461 	 */
462 	if (!cpacf_query(CPACF_PCKMO, &func_mask))
463 		return -ENODEV;
464 
465 	/* register this module as pkey handler for all the pckmo stuff */
466 	return pkey_handler_register(&pckmo_handler);
467 }
468 
469 /*
470  * Module exit
471  */
472 static void __exit pkey_pckmo_exit(void)
473 {
474 	/* unregister this module as pkey handler */
475 	pkey_handler_unregister(&pckmo_handler);
476 }
477 
478 module_cpu_feature_match(S390_CPU_FEATURE_MSA, pkey_pckmo_init);
479 module_exit(pkey_pckmo_exit);
480