// SPDX-License-Identifier: GPL-2.0
/*
 *  pkey pckmo specific code
 *
 *  Copyright IBM Corp. 2024
 */

#define KMSG_COMPONENT "pkey"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/init.h>
#include <linux/module.h>
#include <linux/cpufeature.h>
#include <asm/cpacf.h>
#include <crypto/aes.h>
#include <linux/random.h>

#include "zcrypt_ccamisc.h"
#include "pkey_base.h"

MODULE_LICENSE("GPL");
MODULE_AUTHOR("IBM Corporation");
MODULE_DESCRIPTION("s390 protected key PCKMO handler");

/*
 * Check key blob for known and supported here.
 */
static bool is_pckmo_key(const u8 *key, u32 keylen)
{
	struct keytoken_header *hdr = (struct keytoken_header *)key;
	struct clearkeytoken *t = (struct clearkeytoken *)key;

	if (keylen < sizeof(*hdr))
		return false;

	switch (hdr->type) {
	case TOKTYPE_NON_CCA:
		switch (hdr->version) {
		case TOKVER_CLEAR_KEY:
			if (pkey_keytype_to_size(t->keytype))
				return true;
			return false;
		case TOKVER_PROTECTED_KEY:
			return true;
		default:
			return false;
		}
	default:
		return false;
	}
}

static bool is_pckmo_keytype(enum pkey_key_type keytype)
{
	switch (keytype) {
	case PKEY_TYPE_PROTKEY:
		return true;
	default:
		return false;
	}
}

/*
 * Create a protected key from a clear key value via PCKMO instruction.
 */
static int pckmo_clr2protkey(u32 keytype, const u8 *clrkey, u32 clrkeylen,
			     u8 *protkey, u32 *protkeylen, u32 *protkeytype)
{
	/* mask of available pckmo subfunctions */
	static cpacf_mask_t pckmo_functions;

	int keysize, rc = -EINVAL;
	u8 paramblock[160];
	u32 pkeytype = 0;
	unsigned int fc;

	switch (keytype) {
	case PKEY_KEYTYPE_AES_128:
		fc = CPACF_PCKMO_ENC_AES_128_KEY;
		break;
	case PKEY_KEYTYPE_AES_192:
		fc = CPACF_PCKMO_ENC_AES_192_KEY;
		break;
	case PKEY_KEYTYPE_AES_256:
		fc = CPACF_PCKMO_ENC_AES_256_KEY;
		break;
	case PKEY_KEYTYPE_ECC_P256:
		pkeytype = PKEY_KEYTYPE_ECC;
		fc = CPACF_PCKMO_ENC_ECC_P256_KEY;
		break;
	case PKEY_KEYTYPE_ECC_P384:
		pkeytype = PKEY_KEYTYPE_ECC;
		fc = CPACF_PCKMO_ENC_ECC_P384_KEY;
		break;
	case PKEY_KEYTYPE_ECC_P521:
		pkeytype = PKEY_KEYTYPE_ECC;
		fc = CPACF_PCKMO_ENC_ECC_P521_KEY;
		break;
	case PKEY_KEYTYPE_ECC_ED25519:
		pkeytype = PKEY_KEYTYPE_ECC;
		fc = CPACF_PCKMO_ENC_ECC_ED25519_KEY;
		break;
	case PKEY_KEYTYPE_ECC_ED448:
		pkeytype = PKEY_KEYTYPE_ECC;
		fc = CPACF_PCKMO_ENC_ECC_ED448_KEY;
		break;
	case PKEY_KEYTYPE_AES_XTS_128:
		fc = CPACF_PCKMO_ENC_AES_XTS_128_DOUBLE_KEY;
		break;
	case PKEY_KEYTYPE_AES_XTS_256:
		fc = CPACF_PCKMO_ENC_AES_XTS_256_DOUBLE_KEY;
		break;
	case PKEY_KEYTYPE_HMAC_512:
		fc = CPACF_PCKMO_ENC_HMAC_512_KEY;
		break;
	case PKEY_KEYTYPE_HMAC_1024:
		fc = CPACF_PCKMO_ENC_HMAC_1024_KEY;
		break;
	default:
		PKEY_DBF_ERR("%s unknown/unsupported keytype %u\n",
			     __func__, keytype);
		goto out;
	}

	keysize = pkey_keytype_to_size(keytype);
	pkeytype = pkeytype ?: keytype;

	if (clrkeylen && clrkeylen < keysize) {
		PKEY_DBF_ERR("%s clear key size too small: %u < %d\n",
			     __func__, clrkeylen, keysize);
		goto out;
	}
	if (*protkeylen < keysize + AES_WK_VP_SIZE) {
		PKEY_DBF_ERR("%s prot key buffer size too small: %u < %d\n",
			     __func__, *protkeylen, keysize + AES_WK_VP_SIZE);
		goto out;
	}

	/* Did we already check for PCKMO ? */
	if (!pckmo_functions.bytes[0]) {
		/* no, so check now */
		if (!cpacf_query(CPACF_PCKMO, &pckmo_functions)) {
			PKEY_DBF_ERR("%s cpacf_query() failed\n", __func__);
			rc = -ENODEV;
			goto out;
		}
	}
	/* check for the pckmo subfunction we need now */
	if (!cpacf_test_func(&pckmo_functions, fc)) {
		PKEY_DBF_ERR("%s pckmo fc 0x%02x not available\n",
			     __func__, fc);
		rc = -ENODEV;
		goto out;
	}

	/* prepare param block */
	memset(paramblock, 0, sizeof(paramblock));
	memcpy(paramblock, clrkey, keysize);

	/* call the pckmo instruction */
	cpacf_pckmo(fc, paramblock);

	/* copy created protected key to key buffer including the wkvp block */
	*protkeylen = keysize + AES_WK_VP_SIZE;
	memcpy(protkey, paramblock, *protkeylen);
	*protkeytype = pkeytype;

	rc = 0;

out:
	pr_debug("rc=%d\n", rc);
	return rc;
}

/*
 * Verify a raw protected key blob.
 */
static int pckmo_verify_protkey(const u8 *protkey, u32 protkeylen,
				u32 protkeytype)
{
	u8 clrkey[16] = { 0 }, tmpkeybuf[16 + AES_WK_VP_SIZE];
	u32 tmpkeybuflen, tmpkeytype;
	int keysize, rc = -EINVAL;
	u8 *wkvp;

	/* check protkey type and size */
	keysize = pkey_keytype_to_size(protkeytype);
	if (!keysize) {
		PKEY_DBF_ERR("%s unknown/unsupported keytype %u\n", __func__,
			     protkeytype);
		goto out;
	}
	if (protkeylen < keysize + AES_WK_VP_SIZE)
		goto out;

	/* generate a dummy AES 128 protected key */
	tmpkeybuflen = sizeof(tmpkeybuf);
	rc = pckmo_clr2protkey(PKEY_KEYTYPE_AES_128,
			       clrkey, sizeof(clrkey),
			       tmpkeybuf, &tmpkeybuflen, &tmpkeytype);
	if (rc)
		goto out;
	memzero_explicit(tmpkeybuf, 16);
	wkvp = tmpkeybuf + 16;

	/* compare WK VP from the temp key with that of the given prot key */
	if (memcmp(wkvp, protkey + keysize, AES_WK_VP_SIZE)) {
		PKEY_DBF_ERR("%s protected key WK VP mismatch\n", __func__);
		rc = -EKEYREJECTED;
		goto out;
	}

out:
	pr_debug("rc=%d\n", rc);
	return rc;
}

static int pckmo_key2protkey(const u8 *key, u32 keylen,
			     u8 *protkey, u32 *protkeylen, u32 *protkeytype)
{
	struct keytoken_header *hdr = (struct keytoken_header *)key;
	int rc = -EINVAL;

	if (keylen < sizeof(*hdr))
		return -EINVAL;
	if (hdr->type != TOKTYPE_NON_CCA)
		return -EINVAL;

	switch (hdr->version) {
	case TOKVER_PROTECTED_KEY: {
		struct protkeytoken *t = (struct protkeytoken *)key;
		u32 keysize;

		if (keylen < sizeof(*t))
			goto out;
		keysize = pkey_keytype_to_size(t->keytype);
		if (!keysize) {
			PKEY_DBF_ERR("%s protected key token: unknown keytype %u\n",
				     __func__, t->keytype);
			goto out;
		}
		switch (t->keytype) {
		case PKEY_KEYTYPE_AES_128:
		case PKEY_KEYTYPE_AES_192:
		case PKEY_KEYTYPE_AES_256:
			if (t->len != keysize + AES_WK_VP_SIZE ||
			    keylen < sizeof(struct protaeskeytoken))
				goto out;
			rc = pckmo_verify_protkey(t->protkey, t->len,
						  t->keytype);
			if (rc)
				goto out;
			break;
		default:
			if (t->len != keysize + AES_WK_VP_SIZE ||
			    keylen < sizeof(*t) + keysize + AES_WK_VP_SIZE)
				goto out;
			break;
		}
		memcpy(protkey, t->protkey, t->len);
		*protkeylen = t->len;
		*protkeytype = t->keytype;
		rc = 0;
		break;
	}
	case TOKVER_CLEAR_KEY: {
		struct clearkeytoken *t = (struct clearkeytoken *)key;
		u32 keysize;

		if (keylen < sizeof(*t) ||
		    keylen < sizeof(*t) + t->len)
			goto out;
		keysize = pkey_keytype_to_size(t->keytype);
		if (!keysize) {
			PKEY_DBF_ERR("%s clear key token: unknown keytype %u\n",
				     __func__, t->keytype);
			goto out;
		}
		if (t->len != keysize) {
			PKEY_DBF_ERR("%s clear key token: invalid key len %u\n",
				     __func__, t->len);
			goto out;
		}
		rc = pckmo_clr2protkey(t->keytype, t->clearkey, t->len,
				       protkey, protkeylen, protkeytype);
		break;
	}
	default:
		PKEY_DBF_ERR("%s unknown non-CCA token version %d\n",
			     __func__, hdr->version);
		break;
	}

out:
	pr_debug("rc=%d\n", rc);
	return rc;
}

/*
 * Generate a random protected key.
 */
static int pckmo_gen_protkey(u32 keytype, u32 subtype,
			     u8 *protkey, u32 *protkeylen, u32 *protkeytype)
{
	u8 clrkey[128];
	int keysize;
	int rc;

	keysize = pkey_keytype_to_size(keytype);
	if (!keysize) {
		PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
			     __func__, keytype);
		return -EINVAL;
	}
	if (subtype != PKEY_TYPE_PROTKEY) {
		PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
			     __func__, subtype);
		return -EINVAL;
	}

	switch (keytype) {
	case PKEY_KEYTYPE_AES_128:
	case PKEY_KEYTYPE_AES_192:
	case PKEY_KEYTYPE_AES_256:
	case PKEY_KEYTYPE_AES_XTS_128:
	case PKEY_KEYTYPE_AES_XTS_256:
	case PKEY_KEYTYPE_HMAC_512:
	case PKEY_KEYTYPE_HMAC_1024:
		break;
	default:
		PKEY_DBF_ERR("%s unsupported keytype %d\n",
			     __func__, keytype);
		return -EINVAL;
	}

	/* generate a dummy random clear key */
	get_random_bytes(clrkey, keysize);

	/* convert it to a dummy protected key */
	rc = pckmo_clr2protkey(keytype, clrkey, keysize,
			       protkey, protkeylen, protkeytype);
	if (rc)
		goto out;

	/* replace the key part of the protected key with random bytes */
	get_random_bytes(protkey, keysize);

out:
	pr_debug("rc=%d\n", rc);
	return rc;
}

/*
 * Verify a protected key token blob.
 */
static int pckmo_verify_key(const u8 *key, u32 keylen)
{
	struct keytoken_header *hdr = (struct keytoken_header *)key;
	int rc = -EINVAL;

	if (keylen < sizeof(*hdr))
		return -EINVAL;
	if (hdr->type != TOKTYPE_NON_CCA)
		return -EINVAL;

	switch (hdr->version) {
	case TOKVER_PROTECTED_KEY: {
		struct protkeytoken *t = (struct protkeytoken *)key;
		u32 keysize;

		if (keylen < sizeof(*t))
			goto out;
		keysize = pkey_keytype_to_size(t->keytype);
		if (!keysize || t->len != keysize + AES_WK_VP_SIZE)
			goto out;
		switch (t->keytype) {
		case PKEY_KEYTYPE_AES_128:
		case PKEY_KEYTYPE_AES_192:
		case PKEY_KEYTYPE_AES_256:
			if (keylen < sizeof(struct protaeskeytoken))
				goto out;
			break;
		default:
			if (keylen < sizeof(*t) + keysize + AES_WK_VP_SIZE)
				goto out;
			break;
		}
		rc = pckmo_verify_protkey(t->protkey, t->len, t->keytype);
		break;
	}
	default:
		PKEY_DBF_ERR("%s unknown non-CCA token version %d\n",
			     __func__, hdr->version);
		break;
	}

out:
	pr_debug("rc=%d\n", rc);
	return rc;
}

/*
 * Wrapper functions used for the pkey handler struct
 */

static int pkey_pckmo_key2protkey(const struct pkey_apqn *_apqns,
				  size_t _nr_apqns,
				  const u8 *key, u32 keylen,
				  u8 *protkey, u32 *protkeylen, u32 *keyinfo)
{
	return pckmo_key2protkey(key, keylen,
				 protkey, protkeylen, keyinfo);
}

static int 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)
{
	return pckmo_gen_protkey(keytype, keysubtype,
				 keybuf, keybuflen, keyinfo);
}

static int pkey_pckmo_verifykey(const u8 *key, u32 keylen,
				u16 *_card, u16 *_dom,
				u32 *_keytype, u32 *_keybitsize, u32 *_flags)
{
	return pckmo_verify_key(key, keylen);
}

static struct pkey_handler pckmo_handler = {
	.module		      = THIS_MODULE,
	.name		      = "PKEY PCKMO handler",
	.is_supported_key     = is_pckmo_key,
	.is_supported_keytype = is_pckmo_keytype,
	.key_to_protkey	      = pkey_pckmo_key2protkey,
	.gen_key	      = pkey_pckmo_gen_key,
	.verify_key	      = pkey_pckmo_verifykey,
};

/*
 * Module init
 */
static int __init pkey_pckmo_init(void)
{
	cpacf_mask_t func_mask;

	/*
	 * The pckmo instruction should be available - even if we don't
	 * actually invoke it. This instruction comes with MSA 3 which
	 * is also the minimum level for the kmc instructions which
	 * are able to work with protected keys.
	 */
	if (!cpacf_query(CPACF_PCKMO, &func_mask))
		return -ENODEV;

	/* register this module as pkey handler for all the pckmo stuff */
	return pkey_handler_register(&pckmo_handler);
}

/*
 * Module exit
 */
static void __exit pkey_pckmo_exit(void)
{
	/* unregister this module as pkey handler */
	pkey_handler_unregister(&pckmo_handler);
}

module_cpu_feature_match(S390_CPU_FEATURE_MSA, pkey_pckmo_init);
module_exit(pkey_pckmo_exit);
