// SPDX-License-Identifier: GPL-2.0
#define pr_fmt(fmt) "ASYM-TPM: "fmt
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/seq_file.h>
#include <linux/scatterlist.h>
#include <linux/tpm.h>
#include <linux/tpm_command.h>
#include <crypto/akcipher.h>
#include <crypto/hash.h>
#include <crypto/sha.h>
#include <asm/unaligned.h>
#include <keys/asymmetric-subtype.h>
#include <keys/trusted_tpm.h>
#include <crypto/asym_tpm_subtype.h>
#include <crypto/public_key.h>

#define TPM_ORD_FLUSHSPECIFIC	186
#define TPM_ORD_LOADKEY2	65
#define TPM_ORD_UNBIND		30
#define TPM_ORD_SIGN		60

#define TPM_RT_KEY                      0x00000001

/*
 * Load a TPM key from the blob provided by userspace
 */
static int tpm_loadkey2(struct tpm_buf *tb,
			uint32_t keyhandle, unsigned char *keyauth,
			const unsigned char *keyblob, int keybloblen,
			uint32_t *newhandle)
{
	unsigned char nonceodd[TPM_NONCE_SIZE];
	unsigned char enonce[TPM_NONCE_SIZE];
	unsigned char authdata[SHA1_DIGEST_SIZE];
	uint32_t authhandle = 0;
	unsigned char cont = 0;
	uint32_t ordinal;
	int ret;

	ordinal = htonl(TPM_ORD_LOADKEY2);

	/* session for loading the key */
	ret = oiap(tb, &authhandle, enonce);
	if (ret < 0) {
		pr_info("oiap failed (%d)\n", ret);
		return ret;
	}

	/* generate odd nonce */
	ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
	if (ret < 0) {
		pr_info("tpm_get_random failed (%d)\n", ret);
		return ret;
	}

	/* calculate authorization HMAC value */
	ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
			   nonceodd, cont, sizeof(uint32_t), &ordinal,
			   keybloblen, keyblob, 0, 0);
	if (ret < 0)
		return ret;

	/* build the request buffer */
	tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_LOADKEY2);
	tpm_buf_append_u32(tb, keyhandle);
	tpm_buf_append(tb, keyblob, keybloblen);
	tpm_buf_append_u32(tb, authhandle);
	tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
	tpm_buf_append_u8(tb, cont);
	tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);

	ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
	if (ret < 0) {
		pr_info("authhmac failed (%d)\n", ret);
		return ret;
	}

	ret = TSS_checkhmac1(tb->data, ordinal, nonceodd, keyauth,
			     SHA1_DIGEST_SIZE, 0, 0);
	if (ret < 0) {
		pr_info("TSS_checkhmac1 failed (%d)\n", ret);
		return ret;
	}

	*newhandle = LOAD32(tb->data, TPM_DATA_OFFSET);
	return 0;
}

/*
 * Execute the FlushSpecific TPM command
 */
static int tpm_flushspecific(struct tpm_buf *tb, uint32_t handle)
{
	tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_FLUSHSPECIFIC);
	tpm_buf_append_u32(tb, handle);
	tpm_buf_append_u32(tb, TPM_RT_KEY);

	return trusted_tpm_send(tb->data, MAX_BUF_SIZE);
}

/*
 * Decrypt a blob provided by userspace using a specific key handle.
 * The handle is a well known handle or previously loaded by e.g. LoadKey2
 */
static int tpm_unbind(struct tpm_buf *tb,
			uint32_t keyhandle, unsigned char *keyauth,
			const unsigned char *blob, uint32_t bloblen,
			void *out, uint32_t outlen)
{
	unsigned char nonceodd[TPM_NONCE_SIZE];
	unsigned char enonce[TPM_NONCE_SIZE];
	unsigned char authdata[SHA1_DIGEST_SIZE];
	uint32_t authhandle = 0;
	unsigned char cont = 0;
	uint32_t ordinal;
	uint32_t datalen;
	int ret;

	ordinal = htonl(TPM_ORD_UNBIND);
	datalen = htonl(bloblen);

	/* session for loading the key */
	ret = oiap(tb, &authhandle, enonce);
	if (ret < 0) {
		pr_info("oiap failed (%d)\n", ret);
		return ret;
	}

	/* generate odd nonce */
	ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
	if (ret < 0) {
		pr_info("tpm_get_random failed (%d)\n", ret);
		return ret;
	}

	/* calculate authorization HMAC value */
	ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
			   nonceodd, cont, sizeof(uint32_t), &ordinal,
			   sizeof(uint32_t), &datalen,
			   bloblen, blob, 0, 0);
	if (ret < 0)
		return ret;

	/* build the request buffer */
	tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_UNBIND);
	tpm_buf_append_u32(tb, keyhandle);
	tpm_buf_append_u32(tb, bloblen);
	tpm_buf_append(tb, blob, bloblen);
	tpm_buf_append_u32(tb, authhandle);
	tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
	tpm_buf_append_u8(tb, cont);
	tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);

	ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
	if (ret < 0) {
		pr_info("authhmac failed (%d)\n", ret);
		return ret;
	}

	datalen = LOAD32(tb->data, TPM_DATA_OFFSET);

	ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
			     keyauth, SHA1_DIGEST_SIZE,
			     sizeof(uint32_t), TPM_DATA_OFFSET,
			     datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
			     0, 0);
	if (ret < 0) {
		pr_info("TSS_checkhmac1 failed (%d)\n", ret);
		return ret;
	}

	memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
	       min(outlen, datalen));

	return datalen;
}

/*
 * Sign a blob provided by userspace (that has had the hash function applied)
 * using a specific key handle.  The handle is assumed to have been previously
 * loaded by e.g. LoadKey2.
 *
 * Note that the key signature scheme of the used key should be set to
 * TPM_SS_RSASSAPKCS1v15_DER.  This allows the hashed input to be of any size
 * up to key_length_in_bytes - 11 and not be limited to size 20 like the
 * TPM_SS_RSASSAPKCS1v15_SHA1 signature scheme.
 */
static int tpm_sign(struct tpm_buf *tb,
		    uint32_t keyhandle, unsigned char *keyauth,
		    const unsigned char *blob, uint32_t bloblen,
		    void *out, uint32_t outlen)
{
	unsigned char nonceodd[TPM_NONCE_SIZE];
	unsigned char enonce[TPM_NONCE_SIZE];
	unsigned char authdata[SHA1_DIGEST_SIZE];
	uint32_t authhandle = 0;
	unsigned char cont = 0;
	uint32_t ordinal;
	uint32_t datalen;
	int ret;

	ordinal = htonl(TPM_ORD_SIGN);
	datalen = htonl(bloblen);

	/* session for loading the key */
	ret = oiap(tb, &authhandle, enonce);
	if (ret < 0) {
		pr_info("oiap failed (%d)\n", ret);
		return ret;
	}

	/* generate odd nonce */
	ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
	if (ret < 0) {
		pr_info("tpm_get_random failed (%d)\n", ret);
		return ret;
	}

	/* calculate authorization HMAC value */
	ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
			   nonceodd, cont, sizeof(uint32_t), &ordinal,
			   sizeof(uint32_t), &datalen,
			   bloblen, blob, 0, 0);
	if (ret < 0)
		return ret;

	/* build the request buffer */
	tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_SIGN);
	tpm_buf_append_u32(tb, keyhandle);
	tpm_buf_append_u32(tb, bloblen);
	tpm_buf_append(tb, blob, bloblen);
	tpm_buf_append_u32(tb, authhandle);
	tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
	tpm_buf_append_u8(tb, cont);
	tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);

	ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
	if (ret < 0) {
		pr_info("authhmac failed (%d)\n", ret);
		return ret;
	}

	datalen = LOAD32(tb->data, TPM_DATA_OFFSET);

	ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
			     keyauth, SHA1_DIGEST_SIZE,
			     sizeof(uint32_t), TPM_DATA_OFFSET,
			     datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
			     0, 0);
	if (ret < 0) {
		pr_info("TSS_checkhmac1 failed (%d)\n", ret);
		return ret;
	}

	memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
	       min(datalen, outlen));

	return datalen;
}

/* Room to fit two u32 zeros for algo id and parameters length. */
#define SETKEY_PARAMS_SIZE (sizeof(u32) * 2)

/*
 * Maximum buffer size for the BER/DER encoded public key.  The public key
 * is of the form SEQUENCE { INTEGER n, INTEGER e } where n is a maximum 2048
 * bit key and e is usually 65537
 * The encoding overhead is:
 * - max 4 bytes for SEQUENCE
 *   - max 4 bytes for INTEGER n type/length
 *     - 257 bytes of n
 *   - max 2 bytes for INTEGER e type/length
 *     - 3 bytes of e
 * - 4+4 of zeros for set_pub_key parameters (SETKEY_PARAMS_SIZE)
 */
#define PUB_KEY_BUF_SIZE (4 + 4 + 257 + 2 + 3 + SETKEY_PARAMS_SIZE)

/*
 * Provide a part of a description of the key for /proc/keys.
 */
static void asym_tpm_describe(const struct key *asymmetric_key,
			      struct seq_file *m)
{
	struct tpm_key *tk = asymmetric_key->payload.data[asym_crypto];

	if (!tk)
		return;

	seq_printf(m, "TPM1.2/Blob");
}

static void asym_tpm_destroy(void *payload0, void *payload3)
{
	struct tpm_key *tk = payload0;

	if (!tk)
		return;

	kfree(tk->blob);
	tk->blob_len = 0;

	kfree(tk);
}

/* How many bytes will it take to encode the length */
static inline uint32_t definite_length(uint32_t len)
{
	if (len <= 127)
		return 1;
	if (len <= 255)
		return 2;
	return 3;
}

static inline uint8_t *encode_tag_length(uint8_t *buf, uint8_t tag,
					 uint32_t len)
{
	*buf++ = tag;

	if (len <= 127) {
		buf[0] = len;
		return buf + 1;
	}

	if (len <= 255) {
		buf[0] = 0x81;
		buf[1] = len;
		return buf + 2;
	}

	buf[0] = 0x82;
	put_unaligned_be16(len, buf + 1);
	return buf + 3;
}

static uint32_t derive_pub_key(const void *pub_key, uint32_t len, uint8_t *buf)
{
	uint8_t *cur = buf;
	uint32_t n_len = definite_length(len) + 1 + len + 1;
	uint32_t e_len = definite_length(3) + 1 + 3;
	uint8_t e[3] = { 0x01, 0x00, 0x01 };

	/* SEQUENCE */
	cur = encode_tag_length(cur, 0x30, n_len + e_len);
	/* INTEGER n */
	cur = encode_tag_length(cur, 0x02, len + 1);
	cur[0] = 0x00;
	memcpy(cur + 1, pub_key, len);
	cur += len + 1;
	cur = encode_tag_length(cur, 0x02, sizeof(e));
	memcpy(cur, e, sizeof(e));
	cur += sizeof(e);
	/* Zero parameters to satisfy set_pub_key ABI. */
	memset(cur, 0, SETKEY_PARAMS_SIZE);

	return cur - buf;
}

/*
 * Determine the crypto algorithm name.
 */
static int determine_akcipher(const char *encoding, const char *hash_algo,
			      char alg_name[CRYPTO_MAX_ALG_NAME])
{
	if (strcmp(encoding, "pkcs1") == 0) {
		if (!hash_algo) {
			strcpy(alg_name, "pkcs1pad(rsa)");
			return 0;
		}

		if (snprintf(alg_name, CRYPTO_MAX_ALG_NAME, "pkcs1pad(rsa,%s)",
			     hash_algo) >= CRYPTO_MAX_ALG_NAME)
			return -EINVAL;

		return 0;
	}

	if (strcmp(encoding, "raw") == 0) {
		strcpy(alg_name, "rsa");
		return 0;
	}

	return -ENOPKG;
}

/*
 * Query information about a key.
 */
static int tpm_key_query(const struct kernel_pkey_params *params,
			 struct kernel_pkey_query *info)
{
	struct tpm_key *tk = params->key->payload.data[asym_crypto];
	int ret;
	char alg_name[CRYPTO_MAX_ALG_NAME];
	struct crypto_akcipher *tfm;
	uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
	uint32_t der_pub_key_len;
	int len;

	/* TPM only works on private keys, public keys still done in software */
	ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
	if (ret < 0)
		return ret;

	tfm = crypto_alloc_akcipher(alg_name, 0, 0);
	if (IS_ERR(tfm))
		return PTR_ERR(tfm);

	der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
					 der_pub_key);

	ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
	if (ret < 0)
		goto error_free_tfm;

	len = crypto_akcipher_maxsize(tfm);

	info->key_size = tk->key_len;
	info->max_data_size = tk->key_len / 8;
	info->max_sig_size = len;
	info->max_enc_size = len;
	info->max_dec_size = tk->key_len / 8;

	info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT |
			      KEYCTL_SUPPORTS_DECRYPT |
			      KEYCTL_SUPPORTS_VERIFY |
			      KEYCTL_SUPPORTS_SIGN;

	ret = 0;
error_free_tfm:
	crypto_free_akcipher(tfm);
	pr_devel("<==%s() = %d\n", __func__, ret);
	return ret;
}

/*
 * Encryption operation is performed with the public key.  Hence it is done
 * in software
 */
static int tpm_key_encrypt(struct tpm_key *tk,
			   struct kernel_pkey_params *params,
			   const void *in, void *out)
{
	char alg_name[CRYPTO_MAX_ALG_NAME];
	struct crypto_akcipher *tfm;
	struct akcipher_request *req;
	struct crypto_wait cwait;
	struct scatterlist in_sg, out_sg;
	uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
	uint32_t der_pub_key_len;
	int ret;

	pr_devel("==>%s()\n", __func__);

	ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
	if (ret < 0)
		return ret;

	tfm = crypto_alloc_akcipher(alg_name, 0, 0);
	if (IS_ERR(tfm))
		return PTR_ERR(tfm);

	der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
					 der_pub_key);

	ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
	if (ret < 0)
		goto error_free_tfm;

	ret = -ENOMEM;
	req = akcipher_request_alloc(tfm, GFP_KERNEL);
	if (!req)
		goto error_free_tfm;

	sg_init_one(&in_sg, in, params->in_len);
	sg_init_one(&out_sg, out, params->out_len);
	akcipher_request_set_crypt(req, &in_sg, &out_sg, params->in_len,
				   params->out_len);
	crypto_init_wait(&cwait);
	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
				      CRYPTO_TFM_REQ_MAY_SLEEP,
				      crypto_req_done, &cwait);

	ret = crypto_akcipher_encrypt(req);
	ret = crypto_wait_req(ret, &cwait);

	if (ret == 0)
		ret = req->dst_len;

	akcipher_request_free(req);
error_free_tfm:
	crypto_free_akcipher(tfm);
	pr_devel("<==%s() = %d\n", __func__, ret);
	return ret;
}

/*
 * Decryption operation is performed with the private key in the TPM.
 */
static int tpm_key_decrypt(struct tpm_key *tk,
			   struct kernel_pkey_params *params,
			   const void *in, void *out)
{
	struct tpm_buf tb;
	uint32_t keyhandle;
	uint8_t srkauth[SHA1_DIGEST_SIZE];
	uint8_t keyauth[SHA1_DIGEST_SIZE];
	int r;

	pr_devel("==>%s()\n", __func__);

	if (params->hash_algo)
		return -ENOPKG;

	if (strcmp(params->encoding, "pkcs1"))
		return -ENOPKG;

	r = tpm_buf_init(&tb, 0, 0);
	if (r)
		return r;

	/* TODO: Handle a non-all zero SRK authorization */
	memset(srkauth, 0, sizeof(srkauth));

	r = tpm_loadkey2(&tb, SRKHANDLE, srkauth,
				tk->blob, tk->blob_len, &keyhandle);
	if (r < 0) {
		pr_devel("loadkey2 failed (%d)\n", r);
		goto error;
	}

	/* TODO: Handle a non-all zero key authorization */
	memset(keyauth, 0, sizeof(keyauth));

	r = tpm_unbind(&tb, keyhandle, keyauth,
		       in, params->in_len, out, params->out_len);
	if (r < 0)
		pr_devel("tpm_unbind failed (%d)\n", r);

	if (tpm_flushspecific(&tb, keyhandle) < 0)
		pr_devel("flushspecific failed (%d)\n", r);

error:
	tpm_buf_destroy(&tb);
	pr_devel("<==%s() = %d\n", __func__, r);
	return r;
}

/*
 * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
 */
static const u8 digest_info_md5[] = {
	0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
	0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* OID */
	0x05, 0x00, 0x04, 0x10
};

static const u8 digest_info_sha1[] = {
	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
	0x2b, 0x0e, 0x03, 0x02, 0x1a,
	0x05, 0x00, 0x04, 0x14
};

static const u8 digest_info_rmd160[] = {
	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
	0x2b, 0x24, 0x03, 0x02, 0x01,
	0x05, 0x00, 0x04, 0x14
};

static const u8 digest_info_sha224[] = {
	0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
	0x05, 0x00, 0x04, 0x1c
};

static const u8 digest_info_sha256[] = {
	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
	0x05, 0x00, 0x04, 0x20
};

static const u8 digest_info_sha384[] = {
	0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
	0x05, 0x00, 0x04, 0x30
};

static const u8 digest_info_sha512[] = {
	0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
	0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
	0x05, 0x00, 0x04, 0x40
};

static const struct asn1_template {
	const char	*name;
	const u8	*data;
	size_t		size;
} asn1_templates[] = {
#define _(X) { #X, digest_info_##X, sizeof(digest_info_##X) }
	_(md5),
	_(sha1),
	_(rmd160),
	_(sha256),
	_(sha384),
	_(sha512),
	_(sha224),
	{ NULL }
#undef _
};

static const struct asn1_template *lookup_asn1(const char *name)
{
	const struct asn1_template *p;

	for (p = asn1_templates; p->name; p++)
		if (strcmp(name, p->name) == 0)
			return p;
	return NULL;
}

/*
 * Sign operation is performed with the private key in the TPM.
 */
static int tpm_key_sign(struct tpm_key *tk,
			struct kernel_pkey_params *params,
			const void *in, void *out)
{
	struct tpm_buf tb;
	uint32_t keyhandle;
	uint8_t srkauth[SHA1_DIGEST_SIZE];
	uint8_t keyauth[SHA1_DIGEST_SIZE];
	void *asn1_wrapped = NULL;
	uint32_t in_len = params->in_len;
	int r;

	pr_devel("==>%s()\n", __func__);

	if (strcmp(params->encoding, "pkcs1"))
		return -ENOPKG;

	if (params->hash_algo) {
		const struct asn1_template *asn1 =
						lookup_asn1(params->hash_algo);

		if (!asn1)
			return -ENOPKG;

		/* request enough space for the ASN.1 template + input hash */
		asn1_wrapped = kzalloc(in_len + asn1->size, GFP_KERNEL);
		if (!asn1_wrapped)
			return -ENOMEM;

		/* Copy ASN.1 template, then the input */
		memcpy(asn1_wrapped, asn1->data, asn1->size);
		memcpy(asn1_wrapped + asn1->size, in, in_len);

		in = asn1_wrapped;
		in_len += asn1->size;
	}

	if (in_len > tk->key_len / 8 - 11) {
		r = -EOVERFLOW;
		goto error_free_asn1_wrapped;
	}

	r = tpm_buf_init(&tb, 0, 0);
	if (r)
		goto error_free_asn1_wrapped;

	/* TODO: Handle a non-all zero SRK authorization */
	memset(srkauth, 0, sizeof(srkauth));

	r = tpm_loadkey2(&tb, SRKHANDLE, srkauth,
			 tk->blob, tk->blob_len, &keyhandle);
	if (r < 0) {
		pr_devel("loadkey2 failed (%d)\n", r);
		goto error_free_tb;
	}

	/* TODO: Handle a non-all zero key authorization */
	memset(keyauth, 0, sizeof(keyauth));

	r = tpm_sign(&tb, keyhandle, keyauth, in, in_len, out, params->out_len);
	if (r < 0)
		pr_devel("tpm_sign failed (%d)\n", r);

	if (tpm_flushspecific(&tb, keyhandle) < 0)
		pr_devel("flushspecific failed (%d)\n", r);

error_free_tb:
	tpm_buf_destroy(&tb);
error_free_asn1_wrapped:
	kfree(asn1_wrapped);
	pr_devel("<==%s() = %d\n", __func__, r);
	return r;
}

/*
 * Do encryption, decryption and signing ops.
 */
static int tpm_key_eds_op(struct kernel_pkey_params *params,
			  const void *in, void *out)
{
	struct tpm_key *tk = params->key->payload.data[asym_crypto];
	int ret = -EOPNOTSUPP;

	/* Perform the encryption calculation. */
	switch (params->op) {
	case kernel_pkey_encrypt:
		ret = tpm_key_encrypt(tk, params, in, out);
		break;
	case kernel_pkey_decrypt:
		ret = tpm_key_decrypt(tk, params, in, out);
		break;
	case kernel_pkey_sign:
		ret = tpm_key_sign(tk, params, in, out);
		break;
	default:
		BUG();
	}

	return ret;
}

/*
 * Verify a signature using a public key.
 */
static int tpm_key_verify_signature(const struct key *key,
				    const struct public_key_signature *sig)
{
	const struct tpm_key *tk = key->payload.data[asym_crypto];
	struct crypto_wait cwait;
	struct crypto_akcipher *tfm;
	struct akcipher_request *req;
	struct scatterlist src_sg[2];
	char alg_name[CRYPTO_MAX_ALG_NAME];
	uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
	uint32_t der_pub_key_len;
	int ret;

	pr_devel("==>%s()\n", __func__);

	BUG_ON(!tk);
	BUG_ON(!sig);
	BUG_ON(!sig->s);

	if (!sig->digest)
		return -ENOPKG;

	ret = determine_akcipher(sig->encoding, sig->hash_algo, alg_name);
	if (ret < 0)
		return ret;

	tfm = crypto_alloc_akcipher(alg_name, 0, 0);
	if (IS_ERR(tfm))
		return PTR_ERR(tfm);

	der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
					 der_pub_key);

	ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
	if (ret < 0)
		goto error_free_tfm;

	ret = -ENOMEM;
	req = akcipher_request_alloc(tfm, GFP_KERNEL);
	if (!req)
		goto error_free_tfm;

	sg_init_table(src_sg, 2);
	sg_set_buf(&src_sg[0], sig->s, sig->s_size);
	sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
	akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
				   sig->digest_size);
	crypto_init_wait(&cwait);
	akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
				      CRYPTO_TFM_REQ_MAY_SLEEP,
				      crypto_req_done, &cwait);
	ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);

	akcipher_request_free(req);
error_free_tfm:
	crypto_free_akcipher(tfm);
	pr_devel("<==%s() = %d\n", __func__, ret);
	if (WARN_ON_ONCE(ret > 0))
		ret = -EINVAL;
	return ret;
}

/*
 * Parse enough information out of TPM_KEY structure:
 * TPM_STRUCT_VER -> 4 bytes
 * TPM_KEY_USAGE -> 2 bytes
 * TPM_KEY_FLAGS -> 4 bytes
 * TPM_AUTH_DATA_USAGE -> 1 byte
 * TPM_KEY_PARMS -> variable
 * UINT32 PCRInfoSize -> 4 bytes
 * BYTE* -> PCRInfoSize bytes
 * TPM_STORE_PUBKEY
 * UINT32 encDataSize;
 * BYTE* -> encDataSize;
 *
 * TPM_KEY_PARMS:
 * TPM_ALGORITHM_ID -> 4 bytes
 * TPM_ENC_SCHEME -> 2 bytes
 * TPM_SIG_SCHEME -> 2 bytes
 * UINT32 parmSize -> 4 bytes
 * BYTE* -> variable
 */
static int extract_key_parameters(struct tpm_key *tk)
{
	const void *cur = tk->blob;
	uint32_t len = tk->blob_len;
	const void *pub_key;
	uint32_t sz;
	uint32_t key_len;

	if (len < 11)
		return -EBADMSG;

	/* Ensure this is a legacy key */
	if (get_unaligned_be16(cur + 4) != 0x0015)
		return -EBADMSG;

	/* Skip to TPM_KEY_PARMS */
	cur += 11;
	len -= 11;

	if (len < 12)
		return -EBADMSG;

	/* Make sure this is an RSA key */
	if (get_unaligned_be32(cur) != 0x00000001)
		return -EBADMSG;

	/* Make sure this is TPM_ES_RSAESPKCSv15 encoding scheme */
	if (get_unaligned_be16(cur + 4) != 0x0002)
		return -EBADMSG;

	/* Make sure this is TPM_SS_RSASSAPKCS1v15_DER signature scheme */
	if (get_unaligned_be16(cur + 6) != 0x0003)
		return -EBADMSG;

	sz = get_unaligned_be32(cur + 8);
	if (len < sz + 12)
		return -EBADMSG;

	/* Move to TPM_RSA_KEY_PARMS */
	len -= 12;
	cur += 12;

	/* Grab the RSA key length */
	key_len = get_unaligned_be32(cur);

	switch (key_len) {
	case 512:
	case 1024:
	case 1536:
	case 2048:
		break;
	default:
		return -EINVAL;
	}

	/* Move just past TPM_KEY_PARMS */
	cur += sz;
	len -= sz;

	if (len < 4)
		return -EBADMSG;

	sz = get_unaligned_be32(cur);
	if (len < 4 + sz)
		return -EBADMSG;

	/* Move to TPM_STORE_PUBKEY */
	cur += 4 + sz;
	len -= 4 + sz;

	/* Grab the size of the public key, it should jive with the key size */
	sz = get_unaligned_be32(cur);
	if (sz > 256)
		return -EINVAL;

	pub_key = cur + 4;

	tk->key_len = key_len;
	tk->pub_key = pub_key;
	tk->pub_key_len = sz;

	return 0;
}

/* Given the blob, parse it and load it into the TPM */
struct tpm_key *tpm_key_create(const void *blob, uint32_t blob_len)
{
	int r;
	struct tpm_key *tk;

	r = tpm_is_tpm2(NULL);
	if (r < 0)
		goto error;

	/* We don't support TPM2 yet */
	if (r > 0) {
		r = -ENODEV;
		goto error;
	}

	r = -ENOMEM;
	tk = kzalloc(sizeof(struct tpm_key), GFP_KERNEL);
	if (!tk)
		goto error;

	tk->blob = kmemdup(blob, blob_len, GFP_KERNEL);
	if (!tk->blob)
		goto error_memdup;

	tk->blob_len = blob_len;

	r = extract_key_parameters(tk);
	if (r < 0)
		goto error_extract;

	return tk;

error_extract:
	kfree(tk->blob);
	tk->blob_len = 0;
error_memdup:
	kfree(tk);
error:
	return ERR_PTR(r);
}
EXPORT_SYMBOL_GPL(tpm_key_create);

/*
 * TPM-based asymmetric key subtype
 */
struct asymmetric_key_subtype asym_tpm_subtype = {
	.owner			= THIS_MODULE,
	.name			= "asym_tpm",
	.name_len		= sizeof("asym_tpm") - 1,
	.describe		= asym_tpm_describe,
	.destroy		= asym_tpm_destroy,
	.query			= tpm_key_query,
	.eds_op			= tpm_key_eds_op,
	.verify_signature	= tpm_key_verify_signature,
};
EXPORT_SYMBOL_GPL(asym_tpm_subtype);

MODULE_DESCRIPTION("TPM based asymmetric key subtype");
MODULE_AUTHOR("Intel Corporation");
MODULE_LICENSE("GPL v2");
