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