File Index
Files and directories
Sign in
FILE

pkey_pckmo.c

File preview with syntax highlighting.

linux-6.19.14/drivers/s390/crypto/pkey_pckmo.c C
  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
 20MODULE_LICENSE("GPL");
 21MODULE_AUTHOR("IBM Corporation");
 22MODULE_DESCRIPTION("s390 protected key PCKMO handler");
 23
 24/*
 25 * Check key blob for known and supported here.
 26 */
 27static 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
 52static 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 */
 65static 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
169out:
170	pr_debug("rc=%d\n", rc);
171	return rc;
172}
173
174/*
175 * Verify a raw protected key blob.
176 */
177static 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
212out:
213	pr_debug("rc=%d\n", rc);
214	return rc;
215}
216
217static int pckmo_key2protkey(const u8 *key, u32 keylen,
218			     u8 *protkey, u32 *protkeylen, u32 *protkeytype)
219{
220	struct keytoken_header *hdr = (struct keytoken_header *)key;
221	int rc = -EINVAL;
222
223	if (keylen < sizeof(*hdr))
224		return -EINVAL;
225	if (hdr->type != TOKTYPE_NON_CCA)
226		return -EINVAL;
227
228	switch (hdr->version) {
229	case TOKVER_PROTECTED_KEY: {
230		struct protkeytoken *t = (struct protkeytoken *)key;
231		u32 keysize;
232
233		if (keylen < sizeof(*t))
234			goto out;
235		keysize = pkey_keytype_to_size(t->keytype);
236		if (!keysize) {
237			PKEY_DBF_ERR("%s protected key token: unknown keytype %u\n",
238				     __func__, t->keytype);
239			goto out;
240		}
241		switch (t->keytype) {
242		case PKEY_KEYTYPE_AES_128:
243		case PKEY_KEYTYPE_AES_192:
244		case PKEY_KEYTYPE_AES_256:
245			if (t->len != keysize + AES_WK_VP_SIZE ||
246			    keylen < sizeof(struct protaeskeytoken))
247				goto out;
248			rc = pckmo_verify_protkey(t->protkey, t->len,
249						  t->keytype);
250			if (rc)
251				goto out;
252			break;
253		default:
254			if (t->len != keysize + AES_WK_VP_SIZE ||
255			    keylen < sizeof(*t) + keysize + AES_WK_VP_SIZE)
256				goto out;
257			break;
258		}
259		memcpy(protkey, t->protkey, t->len);
260		*protkeylen = t->len;
261		*protkeytype = t->keytype;
262		rc = 0;
263		break;
264	}
265	case TOKVER_CLEAR_KEY: {
266		struct clearkeytoken *t = (struct clearkeytoken *)key;
267		u32 keysize;
268
269		if (keylen < sizeof(*t) ||
270		    keylen < sizeof(*t) + t->len)
271			goto out;
272		keysize = pkey_keytype_to_size(t->keytype);
273		if (!keysize) {
274			PKEY_DBF_ERR("%s clear key token: unknown keytype %u\n",
275				     __func__, t->keytype);
276			goto out;
277		}
278		if (t->len != keysize) {
279			PKEY_DBF_ERR("%s clear key token: invalid key len %u\n",
280				     __func__, t->len);
281			goto out;
282		}
283		rc = pckmo_clr2protkey(t->keytype, t->clearkey, t->len,
284				       protkey, protkeylen, protkeytype);
285		break;
286	}
287	default:
288		PKEY_DBF_ERR("%s unknown non-CCA token version %d\n",
289			     __func__, hdr->version);
290		break;
291	}
292
293out:
294	pr_debug("rc=%d\n", rc);
295	return rc;
296}
297
298/*
299 * Generate a random protected key.
300 */
301static int pckmo_gen_protkey(u32 keytype, u32 subtype,
302			     u8 *protkey, u32 *protkeylen, u32 *protkeytype)
303{
304	u8 clrkey[128];
305	int keysize;
306	int rc;
307
308	keysize = pkey_keytype_to_size(keytype);
309	if (!keysize) {
310		PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
311			     __func__, keytype);
312		return -EINVAL;
313	}
314	if (subtype != PKEY_TYPE_PROTKEY) {
315		PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
316			     __func__, subtype);
317		return -EINVAL;
318	}
319
320	switch (keytype) {
321	case PKEY_KEYTYPE_AES_128:
322	case PKEY_KEYTYPE_AES_192:
323	case PKEY_KEYTYPE_AES_256:
324	case PKEY_KEYTYPE_AES_XTS_128:
325	case PKEY_KEYTYPE_AES_XTS_256:
326	case PKEY_KEYTYPE_HMAC_512:
327	case PKEY_KEYTYPE_HMAC_1024:
328		break;
329	default:
330		PKEY_DBF_ERR("%s unsupported keytype %d\n",
331			     __func__, keytype);
332		return -EINVAL;
333	}
334
335	/* generate a dummy random clear key */
336	get_random_bytes(clrkey, keysize);
337
338	/* convert it to a dummy protected key */
339	rc = pckmo_clr2protkey(keytype, clrkey, keysize,
340			       protkey, protkeylen, protkeytype);
341	if (rc)
342		goto out;
343
344	/* replace the key part of the protected key with random bytes */
345	get_random_bytes(protkey, keysize);
346
347out:
348	pr_debug("rc=%d\n", rc);
349	return rc;
350}
351
352/*
353 * Verify a protected key token blob.
354 */
355static int pckmo_verify_key(const u8 *key, u32 keylen)
356{
357	struct keytoken_header *hdr = (struct keytoken_header *)key;
358	int rc = -EINVAL;
359
360	if (keylen < sizeof(*hdr))
361		return -EINVAL;
362	if (hdr->type != TOKTYPE_NON_CCA)
363		return -EINVAL;
364
365	switch (hdr->version) {
366	case TOKVER_PROTECTED_KEY: {
367		struct protkeytoken *t = (struct protkeytoken *)key;
368		u32 keysize;
369
370		if (keylen < sizeof(*t))
371			goto out;
372		keysize = pkey_keytype_to_size(t->keytype);
373		if (!keysize || t->len != keysize + AES_WK_VP_SIZE)
374			goto out;
375		switch (t->keytype) {
376		case PKEY_KEYTYPE_AES_128:
377		case PKEY_KEYTYPE_AES_192:
378		case PKEY_KEYTYPE_AES_256:
379			if (keylen < sizeof(struct protaeskeytoken))
380				goto out;
381			break;
382		default:
383			if (keylen < sizeof(*t) + keysize + AES_WK_VP_SIZE)
384				goto out;
385			break;
386		}
387		rc = pckmo_verify_protkey(t->protkey, t->len, t->keytype);
388		break;
389	}
390	default:
391		PKEY_DBF_ERR("%s unknown non-CCA token version %d\n",
392			     __func__, hdr->version);
393		break;
394	}
395
396out:
397	pr_debug("rc=%d\n", rc);
398	return rc;
399}
400
401/*
402 * Wrapper functions used for the pkey handler struct
403 */
404
405static int pkey_pckmo_key2protkey(const struct pkey_apqn *_apqns,
406				  size_t _nr_apqns,
407				  const u8 *key, u32 keylen,
408				  u8 *protkey, u32 *protkeylen, u32 *keyinfo,
409				  u32 _xflags __always_unused)
410{
411	return pckmo_key2protkey(key, keylen,
412				 protkey, protkeylen, keyinfo);
413}
414
415static int pkey_pckmo_gen_key(const struct pkey_apqn *_apqns, size_t _nr_apqns,
416			      u32 keytype, u32 keysubtype,
417			      u32 _keybitsize, u32 _flags,
418			      u8 *keybuf, u32 *keybuflen, u32 *keyinfo,
419			      u32 _xflags __always_unused)
420{
421	return pckmo_gen_protkey(keytype, keysubtype,
422				 keybuf, keybuflen, keyinfo);
423}
424
425static int pkey_pckmo_verifykey(const u8 *key, u32 keylen,
426				u16 *_card, u16 *_dom,
427				u32 *_keytype, u32 *_keybitsize,
428				u32 *_flags, u32 _xflags __always_unused)
429{
430	return pckmo_verify_key(key, keylen);
431}
432
433static struct pkey_handler pckmo_handler = {
434	.module		      = THIS_MODULE,
435	.name		      = "PKEY PCKMO handler",
436	.is_supported_key     = is_pckmo_key,
437	.is_supported_keytype = is_pckmo_keytype,
438	.key_to_protkey	      = pkey_pckmo_key2protkey,
439	.gen_key	      = pkey_pckmo_gen_key,
440	.verify_key	      = pkey_pckmo_verifykey,
441};
442
443/*
444 * Module init
445 */
446static int __init pkey_pckmo_init(void)
447{
448	cpacf_mask_t func_mask;
449
450	/*
451	 * The pckmo instruction should be available - even if we don't
452	 * actually invoke it. This instruction comes with MSA 3 which
453	 * is also the minimum level for the kmc instructions which
454	 * are able to work with protected keys.
455	 */
456	if (!cpacf_query(CPACF_PCKMO, &func_mask))
457		return -ENODEV;
458
459	/* register this module as pkey handler for all the pckmo stuff */
460	return pkey_handler_register(&pckmo_handler);
461}
462
463/*
464 * Module exit
465 */
466static void __exit pkey_pckmo_exit(void)
467{
468	/* unregister this module as pkey handler */
469	pkey_handler_unregister(&pckmo_handler);
470}
471
472module_cpu_feature_match(S390_CPU_FEATURE_MSA, pkey_pckmo_init);
473module_exit(pkey_pckmo_exit);
~/ Read-only file preview.