// SPDX-License-Identifier: GPL-2.0
/*
 *  pkey device driver
 *
 *  Copyright IBM Corp. 2017, 2023
 *
 *  Author(s): Harald Freudenberger
 */

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

#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>

#include "zcrypt_api.h"
#include "zcrypt_ccamisc.h"

#include "pkey_base.h"

/*
 * Helper functions
 */
static int key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
		       const u8 *key, size_t keylen,
		       u8 *protkey, u32 *protkeylen, u32 *protkeytype,
		       u32 xflags)
{
	int rc;

	/* try the direct way */
	rc = pkey_handler_key_to_protkey(apqns, nr_apqns,
					 key, keylen,
					 protkey, protkeylen,
					 protkeytype, xflags);

	/* if this did not work, try the slowpath way */
	if (rc == -ENODEV) {
		rc = pkey_handler_slowpath_key_to_protkey(apqns, nr_apqns,
							  key, keylen,
							  protkey, protkeylen,
							  protkeytype, xflags);
		if (rc)
			rc = -ENODEV;
	}

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

/*
 * In-Kernel function: Transform a key blob (of any type) into a protected key
 */
int pkey_key2protkey(const u8 *key, u32 keylen,
		     u8 *protkey, u32 *protkeylen, u32 *protkeytype, u32 xflags)
{
	int rc;

	rc = key2protkey(NULL, 0, key, keylen,
			 protkey, protkeylen, protkeytype, xflags);
	if (rc == -ENODEV) {
		pkey_handler_request_modules();
		rc = key2protkey(NULL, 0, key, keylen,
				 protkey, protkeylen, protkeytype, xflags);
	}

	return rc;
}
EXPORT_SYMBOL(pkey_key2protkey);

/*
 * Ioctl functions
 */

static void *_copy_key_from_user(void __user *ukey, size_t keylen)
{
	if (!ukey || keylen < MINKEYBLOBBUFSIZE || keylen > KEYBLOBBUFSIZE)
		return ERR_PTR(-EINVAL);

	return memdup_user(ukey, keylen);
}

static void *_copy_apqns_from_user(void __user *uapqns, size_t nr_apqns)
{
	if (!uapqns || nr_apqns == 0)
		return NULL;

	return memdup_array_user(uapqns, nr_apqns, sizeof(struct pkey_apqn));
}

static int pkey_ioctl_genseck(struct pkey_genseck __user *ugs)
{
	struct pkey_genseck kgs;
	struct pkey_apqn apqn;
	u32 keybuflen;
	int rc;

	if (copy_from_user(&kgs, ugs, sizeof(kgs)))
		return -EFAULT;

	apqn.card = kgs.cardnr;
	apqn.domain = kgs.domain;
	keybuflen = sizeof(kgs.seckey.seckey);
	rc = pkey_handler_gen_key(&apqn, 1,
				  kgs.keytype, PKEY_TYPE_CCA_DATA, 0, 0,
				  kgs.seckey.seckey, &keybuflen, NULL, 0);
	pr_debug("gen_key()=%d\n", rc);
	if (!rc && copy_to_user(ugs, &kgs, sizeof(kgs)))
		rc = -EFAULT;
	memzero_explicit(&kgs, sizeof(kgs));

	return rc;
}

static int pkey_ioctl_clr2seck(struct pkey_clr2seck __user *ucs)
{
	struct pkey_clr2seck kcs;
	struct pkey_apqn apqn;
	u32 keybuflen;
	int rc;

	if (copy_from_user(&kcs, ucs, sizeof(kcs)))
		return -EFAULT;

	apqn.card = kcs.cardnr;
	apqn.domain = kcs.domain;
	keybuflen = sizeof(kcs.seckey.seckey);
	rc = pkey_handler_clr_to_key(&apqn, 1,
				     kcs.keytype, PKEY_TYPE_CCA_DATA, 0, 0,
				     kcs.clrkey.clrkey,
				     pkey_keytype_aes_to_size(kcs.keytype),
				     kcs.seckey.seckey, &keybuflen, NULL, 0);
	pr_debug("clr_to_key()=%d\n", rc);
	if (!rc && copy_to_user(ucs, &kcs, sizeof(kcs)))
		rc = -EFAULT;
	memzero_explicit(&kcs, sizeof(kcs));

	return rc;
}

static int pkey_ioctl_sec2protk(struct pkey_sec2protk __user *usp)
{
	struct pkey_sec2protk ksp;
	struct pkey_apqn apqn;
	int rc;

	if (copy_from_user(&ksp, usp, sizeof(ksp)))
		return -EFAULT;

	apqn.card = ksp.cardnr;
	apqn.domain = ksp.domain;
	ksp.protkey.len = sizeof(ksp.protkey.protkey);
	rc = pkey_handler_key_to_protkey(&apqn, 1,
					 ksp.seckey.seckey,
					 sizeof(ksp.seckey.seckey),
					 ksp.protkey.protkey,
					 &ksp.protkey.len, &ksp.protkey.type,
					 0);
	pr_debug("key_to_protkey()=%d\n", rc);
	if (!rc && copy_to_user(usp, &ksp, sizeof(ksp)))
		rc = -EFAULT;
	memzero_explicit(&ksp, sizeof(ksp));

	return rc;
}

static int pkey_ioctl_clr2protk(struct pkey_clr2protk __user *ucp)
{
	struct pkey_clr2protk kcp;
	struct clearkeytoken *t;
	u32 keylen;
	u8 *tmpbuf;
	int rc;

	if (copy_from_user(&kcp, ucp, sizeof(kcp)))
		return -EFAULT;

	/* build a 'clear key token' from the clear key value */
	keylen = pkey_keytype_aes_to_size(kcp.keytype);
	if (!keylen) {
		PKEY_DBF_ERR("%s unknown/unsupported keytype %u\n",
			     __func__, kcp.keytype);
		memzero_explicit(&kcp, sizeof(kcp));
		return -EINVAL;
	}
	tmpbuf = kzalloc(sizeof(*t) + keylen, GFP_KERNEL);
	if (!tmpbuf) {
		memzero_explicit(&kcp, sizeof(kcp));
		return -ENOMEM;
	}
	t = (struct clearkeytoken *)tmpbuf;
	t->type = TOKTYPE_NON_CCA;
	t->version = TOKVER_CLEAR_KEY;
	t->keytype = (keylen - 8) >> 3;
	t->len = keylen;
	memcpy(t->clearkey, kcp.clrkey.clrkey, keylen);
	kcp.protkey.len = sizeof(kcp.protkey.protkey);

	rc = key2protkey(NULL, 0,
			 tmpbuf, sizeof(*t) + keylen,
			 kcp.protkey.protkey,
			 &kcp.protkey.len, &kcp.protkey.type, 0);
	pr_debug("key2protkey()=%d\n", rc);

	kfree_sensitive(tmpbuf);

	if (!rc && copy_to_user(ucp, &kcp, sizeof(kcp)))
		rc = -EFAULT;
	memzero_explicit(&kcp, sizeof(kcp));

	return rc;
}

static int pkey_ioctl_findcard(struct pkey_findcard __user *ufc)
{
	struct pkey_findcard kfc;
	struct pkey_apqn *apqns;
	size_t nr_apqns;
	int rc;

	if (copy_from_user(&kfc, ufc, sizeof(kfc)))
		return -EFAULT;

	nr_apqns = MAXAPQNSINLIST;
	apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn), GFP_KERNEL);
	if (!apqns)
		return -ENOMEM;

	rc = pkey_handler_apqns_for_key(kfc.seckey.seckey,
					sizeof(kfc.seckey.seckey),
					PKEY_FLAGS_MATCH_CUR_MKVP,
					apqns, &nr_apqns, 0);
	if (rc == -ENODEV)
		rc = pkey_handler_apqns_for_key(kfc.seckey.seckey,
						sizeof(kfc.seckey.seckey),
						PKEY_FLAGS_MATCH_ALT_MKVP,
						apqns, &nr_apqns, 0);
	pr_debug("apqns_for_key()=%d\n", rc);
	if (rc) {
		kfree(apqns);
		return rc;
	}
	kfc.cardnr = apqns[0].card;
	kfc.domain = apqns[0].domain;
	kfree(apqns);
	if (copy_to_user(ufc, &kfc, sizeof(kfc)))
		return -EFAULT;

	return 0;
}

static int pkey_ioctl_skey2pkey(struct pkey_skey2pkey __user *usp)
{
	struct pkey_skey2pkey ksp;
	int rc;

	if (copy_from_user(&ksp, usp, sizeof(ksp)))
		return -EFAULT;

	ksp.protkey.len = sizeof(ksp.protkey.protkey);
	rc = pkey_handler_key_to_protkey(NULL, 0,
					 ksp.seckey.seckey,
					 sizeof(ksp.seckey.seckey),
					 ksp.protkey.protkey,
					 &ksp.protkey.len,
					 &ksp.protkey.type, 0);
	pr_debug("key_to_protkey()=%d\n", rc);
	if (!rc && copy_to_user(usp, &ksp, sizeof(ksp)))
		rc = -EFAULT;
	memzero_explicit(&ksp, sizeof(ksp));

	return rc;
}

static int pkey_ioctl_verifykey(struct pkey_verifykey __user *uvk)
{
	u32 keytype, keybitsize, flags;
	struct pkey_verifykey kvk;
	int rc;

	if (copy_from_user(&kvk, uvk, sizeof(kvk)))
		return -EFAULT;

	kvk.cardnr = 0xFFFF;
	kvk.domain = 0xFFFF;
	rc = pkey_handler_verify_key(kvk.seckey.seckey,
				     sizeof(kvk.seckey.seckey),
				     &kvk.cardnr, &kvk.domain,
				     &keytype, &keybitsize, &flags, 0);
	pr_debug("verify_key()=%d\n", rc);
	if (!rc && keytype != PKEY_TYPE_CCA_DATA)
		rc = -EINVAL;
	kvk.attributes = PKEY_VERIFY_ATTR_AES;
	kvk.keysize = (u16)keybitsize;
	if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
		kvk.attributes |= PKEY_VERIFY_ATTR_OLD_MKVP;
	if (!rc && copy_to_user(uvk, &kvk, sizeof(kvk)))
		rc = -EFAULT;
	memzero_explicit(&kvk, sizeof(kvk));

	return rc;
}

static int pkey_ioctl_genprotk(struct pkey_genprotk __user *ugp)
{
	struct pkey_genprotk kgp;
	int rc;

	if (copy_from_user(&kgp, ugp, sizeof(kgp)))
		return -EFAULT;

	kgp.protkey.len = sizeof(kgp.protkey.protkey);
	rc = pkey_handler_gen_key(NULL, 0, kgp.keytype,
				  PKEY_TYPE_PROTKEY, 0, 0,
				  kgp.protkey.protkey, &kgp.protkey.len,
				  &kgp.protkey.type, 0);
	pr_debug("gen_key()=%d\n", rc);
	if (!rc && copy_to_user(ugp, &kgp, sizeof(kgp)))
		rc = -EFAULT;
	memzero_explicit(&kgp, sizeof(kgp));

	return rc;
}

static int pkey_ioctl_verifyprotk(struct pkey_verifyprotk __user *uvp)
{
	struct pkey_verifyprotk kvp;
	struct protaeskeytoken *t;
	u32 keytype;
	u8 *tmpbuf;
	int rc;

	if (copy_from_user(&kvp, uvp, sizeof(kvp)))
		return -EFAULT;

	keytype = pkey_aes_bitsize_to_keytype(8 * kvp.protkey.len);
	if (!keytype) {
		PKEY_DBF_ERR("%s unknown/unsupported protkey length %u\n",
			     __func__, kvp.protkey.len);
		memzero_explicit(&kvp, sizeof(kvp));
		return -EINVAL;
	}

	/* build a 'protected key token' from the raw protected key */
	tmpbuf = kzalloc(sizeof(*t), GFP_KERNEL);
	if (!tmpbuf) {
		memzero_explicit(&kvp, sizeof(kvp));
		return -ENOMEM;
	}
	t = (struct protaeskeytoken *)tmpbuf;
	t->type = TOKTYPE_NON_CCA;
	t->version = TOKVER_PROTECTED_KEY;
	t->keytype = keytype;
	t->len = kvp.protkey.len;
	memcpy(t->protkey, kvp.protkey.protkey, kvp.protkey.len);

	rc = pkey_handler_verify_key(tmpbuf, sizeof(*t),
				     NULL, NULL, NULL, NULL, NULL, 0);
	pr_debug("verify_key()=%d\n", rc);

	kfree_sensitive(tmpbuf);
	memzero_explicit(&kvp, sizeof(kvp));

	return rc;
}

static int pkey_ioctl_kblob2protk(struct pkey_kblob2pkey __user *utp)
{
	struct pkey_kblob2pkey ktp;
	u8 *kkey;
	int rc;

	if (copy_from_user(&ktp, utp, sizeof(ktp)))
		return -EFAULT;
	kkey = _copy_key_from_user(ktp.key, ktp.keylen);
	if (IS_ERR(kkey))
		return PTR_ERR(kkey);
	ktp.protkey.len = sizeof(ktp.protkey.protkey);
	rc = key2protkey(NULL, 0, kkey, ktp.keylen,
			 ktp.protkey.protkey, &ktp.protkey.len,
			 &ktp.protkey.type, 0);
	pr_debug("key2protkey()=%d\n", rc);
	kfree_sensitive(kkey);
	if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
		rc = -EFAULT;
	memzero_explicit(&ktp, sizeof(ktp));

	return rc;
}

static int pkey_ioctl_genseck2(struct pkey_genseck2 __user *ugs)
{
	u32 klen = KEYBLOBBUFSIZE;
	struct pkey_genseck2 kgs;
	struct pkey_apqn *apqns;
	u8 *kkey;
	int rc;
	u32 u;

	if (copy_from_user(&kgs, ugs, sizeof(kgs)))
		return -EFAULT;
	u = pkey_aes_bitsize_to_keytype(kgs.size);
	if (!u) {
		PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
			     __func__, kgs.size);
		return -EINVAL;
	}
	apqns = _copy_apqns_from_user(kgs.apqns, kgs.apqn_entries);
	if (IS_ERR(apqns))
		return PTR_ERR(apqns);
	kkey = kzalloc(klen, GFP_KERNEL);
	if (!kkey) {
		kfree(apqns);
		return -ENOMEM;
	}
	rc = pkey_handler_gen_key(apqns, kgs.apqn_entries,
				  u, kgs.type, kgs.size, kgs.keygenflags,
				  kkey, &klen, NULL, 0);
	pr_debug("gen_key()=%d\n", rc);
	kfree(apqns);
	if (rc) {
		kfree_sensitive(kkey);
		return rc;
	}
	if (kgs.key) {
		if (kgs.keylen < klen) {
			kfree_sensitive(kkey);
			return -EINVAL;
		}
		if (copy_to_user(kgs.key, kkey, klen)) {
			kfree_sensitive(kkey);
			return -EFAULT;
		}
	}
	kgs.keylen = klen;
	if (copy_to_user(ugs, &kgs, sizeof(kgs)))
		rc = -EFAULT;
	kfree_sensitive(kkey);

	return rc;
}

static int pkey_ioctl_clr2seck2(struct pkey_clr2seck2 __user *ucs)
{
	u32 klen = KEYBLOBBUFSIZE;
	struct pkey_clr2seck2 kcs;
	struct pkey_apqn *apqns;
	u8 *kkey;
	int rc;
	u32 u;

	if (copy_from_user(&kcs, ucs, sizeof(kcs)))
		return -EFAULT;
	u = pkey_aes_bitsize_to_keytype(kcs.size);
	if (!u) {
		PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
			     __func__, kcs.size);
		memzero_explicit(&kcs, sizeof(kcs));
		return -EINVAL;
	}
	apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries);
	if (IS_ERR(apqns)) {
		memzero_explicit(&kcs, sizeof(kcs));
		return PTR_ERR(apqns);
	}
	kkey = kzalloc(klen, GFP_KERNEL);
	if (!kkey) {
		kfree(apqns);
		memzero_explicit(&kcs, sizeof(kcs));
		return -ENOMEM;
	}
	rc = pkey_handler_clr_to_key(apqns, kcs.apqn_entries,
				     u, kcs.type, kcs.size, kcs.keygenflags,
				     kcs.clrkey.clrkey, kcs.size / 8,
				     kkey, &klen, NULL, 0);
	pr_debug("clr_to_key()=%d\n", rc);
	kfree(apqns);
	if (rc) {
		kfree_sensitive(kkey);
		memzero_explicit(&kcs, sizeof(kcs));
		return rc;
	}
	if (kcs.key) {
		if (kcs.keylen < klen) {
			kfree_sensitive(kkey);
			memzero_explicit(&kcs, sizeof(kcs));
			return -EINVAL;
		}
		if (copy_to_user(kcs.key, kkey, klen)) {
			kfree_sensitive(kkey);
			memzero_explicit(&kcs, sizeof(kcs));
			return -EFAULT;
		}
	}
	kcs.keylen = klen;
	if (copy_to_user(ucs, &kcs, sizeof(kcs)))
		rc = -EFAULT;
	memzero_explicit(&kcs, sizeof(kcs));
	kfree_sensitive(kkey);

	return rc;
}

static int pkey_ioctl_verifykey2(struct pkey_verifykey2 __user *uvk)
{
	struct pkey_verifykey2 kvk;
	u8 *kkey;
	int rc;

	if (copy_from_user(&kvk, uvk, sizeof(kvk)))
		return -EFAULT;
	kkey = _copy_key_from_user(kvk.key, kvk.keylen);
	if (IS_ERR(kkey))
		return PTR_ERR(kkey);

	rc = pkey_handler_verify_key(kkey, kvk.keylen,
				     &kvk.cardnr, &kvk.domain,
				     &kvk.type, &kvk.size, &kvk.flags, 0);
	pr_debug("verify_key()=%d\n", rc);

	kfree_sensitive(kkey);
	if (!rc && copy_to_user(uvk, &kvk, sizeof(kvk)))
		return -EFAULT;

	return rc;
}

static int pkey_ioctl_kblob2protk2(struct pkey_kblob2pkey2 __user *utp)
{
	struct pkey_apqn *apqns = NULL;
	struct pkey_kblob2pkey2 ktp;
	u8 *kkey;
	int rc;

	if (copy_from_user(&ktp, utp, sizeof(ktp)))
		return -EFAULT;
	apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries);
	if (IS_ERR(apqns))
		return PTR_ERR(apqns);
	kkey = _copy_key_from_user(ktp.key, ktp.keylen);
	if (IS_ERR(kkey)) {
		kfree(apqns);
		return PTR_ERR(kkey);
	}
	ktp.protkey.len = sizeof(ktp.protkey.protkey);
	rc = key2protkey(apqns, ktp.apqn_entries, kkey, ktp.keylen,
			 ktp.protkey.protkey, &ktp.protkey.len,
			 &ktp.protkey.type, 0);
	pr_debug("key2protkey()=%d\n", rc);
	kfree(apqns);
	kfree_sensitive(kkey);
	if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
		rc = -EFAULT;
	memzero_explicit(&ktp, sizeof(ktp));

	return rc;
}

static int pkey_ioctl_apqns4k(struct pkey_apqns4key __user *uak)
{
	struct pkey_apqn *apqns = NULL;
	struct pkey_apqns4key kak;
	size_t nr_apqns, len;
	u8 *kkey;
	int rc;

	if (copy_from_user(&kak, uak, sizeof(kak)))
		return -EFAULT;
	nr_apqns = kak.apqn_entries;
	if (nr_apqns) {
		apqns = kmalloc_array(nr_apqns,
				      sizeof(struct pkey_apqn),
				      GFP_KERNEL);
		if (!apqns)
			return -ENOMEM;
	}
	kkey = _copy_key_from_user(kak.key, kak.keylen);
	if (IS_ERR(kkey)) {
		kfree(apqns);
		return PTR_ERR(kkey);
	}
	rc = pkey_handler_apqns_for_key(kkey, kak.keylen, kak.flags,
					apqns, &nr_apqns, 0);
	pr_debug("apqns_for_key()=%d\n", rc);
	kfree_sensitive(kkey);
	if (rc && rc != -ENOSPC) {
		kfree(apqns);
		return rc;
	}
	if (!rc && kak.apqns) {
		if (nr_apqns > kak.apqn_entries) {
			kfree(apqns);
			return -EINVAL;
		}
		len = nr_apqns * sizeof(struct pkey_apqn);
		if (len) {
			if (copy_to_user(kak.apqns, apqns, len)) {
				kfree(apqns);
				return -EFAULT;
			}
		}
	}
	kak.apqn_entries = nr_apqns;
	if (copy_to_user(uak, &kak, sizeof(kak)))
		rc = -EFAULT;
	kfree(apqns);

	return rc;
}

static int pkey_ioctl_apqns4kt(struct pkey_apqns4keytype __user *uat)
{
	struct pkey_apqn *apqns = NULL;
	struct pkey_apqns4keytype kat;
	size_t nr_apqns, len;
	int rc;

	if (copy_from_user(&kat, uat, sizeof(kat)))
		return -EFAULT;
	nr_apqns = kat.apqn_entries;
	if (nr_apqns) {
		apqns = kmalloc_array(nr_apqns,
				      sizeof(struct pkey_apqn),
				      GFP_KERNEL);
		if (!apqns)
			return -ENOMEM;
	}
	rc = pkey_handler_apqns_for_keytype(kat.type,
					    kat.cur_mkvp, kat.alt_mkvp,
					    kat.flags, apqns, &nr_apqns, 0);
	pr_debug("apqns_for_keytype()=%d\n", rc);
	if (rc && rc != -ENOSPC) {
		kfree(apqns);
		return rc;
	}
	if (!rc && kat.apqns) {
		if (nr_apqns > kat.apqn_entries) {
			kfree(apqns);
			return -EINVAL;
		}
		len = nr_apqns * sizeof(struct pkey_apqn);
		if (len) {
			if (copy_to_user(kat.apqns, apqns, len)) {
				kfree(apqns);
				return -EFAULT;
			}
		}
	}
	kat.apqn_entries = nr_apqns;
	if (copy_to_user(uat, &kat, sizeof(kat)))
		rc = -EFAULT;
	kfree(apqns);

	return rc;
}

static int pkey_ioctl_kblob2protk3(struct pkey_kblob2pkey3 __user *utp)
{
	u32 protkeylen = PROTKEYBLOBBUFSIZE;
	struct pkey_apqn *apqns = NULL;
	struct pkey_kblob2pkey3 ktp;
	u8 *kkey, *protkey;
	int rc;

	if (copy_from_user(&ktp, utp, sizeof(ktp)))
		return -EFAULT;
	apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries);
	if (IS_ERR(apqns))
		return PTR_ERR(apqns);
	kkey = _copy_key_from_user(ktp.key, ktp.keylen);
	if (IS_ERR(kkey)) {
		kfree(apqns);
		return PTR_ERR(kkey);
	}
	protkey = kmalloc(protkeylen, GFP_KERNEL);
	if (!protkey) {
		kfree(apqns);
		kfree_sensitive(kkey);
		return -ENOMEM;
	}
	rc = key2protkey(apqns, ktp.apqn_entries, kkey, ktp.keylen,
			 protkey, &protkeylen, &ktp.pkeytype, 0);
	pr_debug("key2protkey()=%d\n", rc);
	kfree(apqns);
	kfree_sensitive(kkey);
	if (rc) {
		kfree_sensitive(protkey);
		return rc;
	}
	if (ktp.pkey && ktp.pkeylen) {
		if (protkeylen > ktp.pkeylen) {
			kfree_sensitive(protkey);
			return -EINVAL;
		}
		if (copy_to_user(ktp.pkey, protkey, protkeylen)) {
			kfree_sensitive(protkey);
			return -EFAULT;
		}
	}
	kfree_sensitive(protkey);
	ktp.pkeylen = protkeylen;
	if (copy_to_user(utp, &ktp, sizeof(ktp)))
		return -EFAULT;

	return 0;
}

static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
				unsigned long arg)
{
	int rc;

	switch (cmd) {
	case PKEY_GENSECK:
		rc = pkey_ioctl_genseck((struct pkey_genseck __user *)arg);
		break;
	case PKEY_CLR2SECK:
		rc = pkey_ioctl_clr2seck((struct pkey_clr2seck __user *)arg);
		break;
	case PKEY_SEC2PROTK:
		rc = pkey_ioctl_sec2protk((struct pkey_sec2protk __user *)arg);
		break;
	case PKEY_CLR2PROTK:
		rc = pkey_ioctl_clr2protk((struct pkey_clr2protk __user *)arg);
		break;
	case PKEY_FINDCARD:
		rc = pkey_ioctl_findcard((struct pkey_findcard __user *)arg);
		break;
	case PKEY_SKEY2PKEY:
		rc = pkey_ioctl_skey2pkey((struct pkey_skey2pkey __user *)arg);
		break;
	case PKEY_VERIFYKEY:
		rc = pkey_ioctl_verifykey((struct pkey_verifykey __user *)arg);
		break;
	case PKEY_GENPROTK:
		rc = pkey_ioctl_genprotk((struct pkey_genprotk __user *)arg);
		break;
	case PKEY_VERIFYPROTK:
		rc = pkey_ioctl_verifyprotk((struct pkey_verifyprotk __user *)arg);
		break;
	case PKEY_KBLOB2PROTK:
		rc = pkey_ioctl_kblob2protk((struct pkey_kblob2pkey __user *)arg);
		break;
	case PKEY_GENSECK2:
		rc = pkey_ioctl_genseck2((struct pkey_genseck2 __user *)arg);
		break;
	case PKEY_CLR2SECK2:
		rc = pkey_ioctl_clr2seck2((struct pkey_clr2seck2 __user *)arg);
		break;
	case PKEY_VERIFYKEY2:
		rc = pkey_ioctl_verifykey2((struct pkey_verifykey2 __user *)arg);
		break;
	case PKEY_KBLOB2PROTK2:
		rc = pkey_ioctl_kblob2protk2((struct pkey_kblob2pkey2 __user *)arg);
		break;
	case PKEY_APQNS4K:
		rc = pkey_ioctl_apqns4k((struct pkey_apqns4key __user *)arg);
		break;
	case PKEY_APQNS4KT:
		rc = pkey_ioctl_apqns4kt((struct pkey_apqns4keytype __user *)arg);
		break;
	case PKEY_KBLOB2PROTK3:
		rc = pkey_ioctl_kblob2protk3((struct pkey_kblob2pkey3 __user *)arg);
		break;
	default:
		/* unknown/unsupported ioctl cmd */
		return -ENOTTY;
	}

	return rc;
}

/*
 * File io operations
 */

static const struct file_operations pkey_fops = {
	.owner		= THIS_MODULE,
	.open		= nonseekable_open,
	.unlocked_ioctl = pkey_unlocked_ioctl,
};

static struct miscdevice pkey_dev = {
	.name	= "pkey",
	.minor	= MISC_DYNAMIC_MINOR,
	.mode	= 0666,
	.fops	= &pkey_fops,
	.groups = pkey_attr_groups,
};

int __init pkey_api_init(void)
{
	/* register as a misc device */
	return misc_register(&pkey_dev);
}

void __exit pkey_api_exit(void)
{
	misc_deregister(&pkey_dev);
}
