brintos

brintos / linux-shallow public Read only

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