/*
 * Key Wrapping: RFC3394 / NIST SP800-38F
 *
 * Copyright (C) 2015, Stephan Mueller <smueller@chronox.de>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, and the entire permission notice in its entirety,
 *    including the disclaimer of warranties.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.
 *
 * ALTERNATIVELY, this product may be distributed under the terms of
 * the GNU General Public License, in which case the provisions of the GPL2
 * are required INSTEAD OF the above restrictions.  (This clause is
 * necessary due to a potential bad interaction between the GPL and
 * the restrictions contained in a BSD-style copyright.)
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
 * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

/*
 * Note for using key wrapping:
 *
 *	* The result of the encryption operation is the ciphertext starting
 *	  with the 2nd semiblock. The first semiblock is provided as the IV.
 *	  The IV used to start the encryption operation is the default IV.
 *
 *	* The input for the decryption is the first semiblock handed in as an
 *	  IV. The ciphertext is the data starting with the 2nd semiblock. The
 *	  return code of the decryption operation will be EBADMSG in case an
 *	  integrity error occurs.
 *
 * To obtain the full result of an encryption as expected by SP800-38F, the
 * caller must allocate a buffer of plaintext + 8 bytes:
 *
 *	unsigned int datalen = ptlen + crypto_skcipher_ivsize(tfm);
 *	u8 data[datalen];
 *	u8 *iv = data;
 *	u8 *pt = data + crypto_skcipher_ivsize(tfm);
 *		<ensure that pt contains the plaintext of size ptlen>
 *	sg_init_one(&sg, ptdata, ptlen);
 *	skcipher_request_set_crypt(req, &sg, &sg, ptlen, iv);
 *
 *	==> After encryption, data now contains full KW result as per SP800-38F.
 *
 * In case of decryption, ciphertext now already has the expected length
 * and must be segmented appropriately:
 *
 *	unsigned int datalen = CTLEN;
 *	u8 data[datalen];
 *		<ensure that data contains full ciphertext>
 *	u8 *iv = data;
 *	u8 *ct = data + crypto_skcipher_ivsize(tfm);
 *	unsigned int ctlen = datalen - crypto_skcipher_ivsize(tfm);
 *	sg_init_one(&sg, ctdata, ctlen);
 *	skcipher_request_set_crypt(req, &sg, &sg, ptlen, iv);
 *
 *	==> After decryption (which hopefully does not return EBADMSG), the ct
 *	pointer now points to the plaintext of size ctlen.
 *
 * Note 2: KWP is not implemented as this would defy in-place operation.
 *	   If somebody wants to wrap non-aligned data, he should simply pad
 *	   the input with zeros to fill it up to the 8 byte boundary.
 */

#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <crypto/scatterwalk.h>
#include <crypto/internal/skcipher.h>

struct crypto_kw_ctx {
	struct crypto_cipher *child;
};

struct crypto_kw_block {
#define SEMIBSIZE 8
	u8 A[SEMIBSIZE];
	u8 R[SEMIBSIZE];
};

/* convert 64 bit integer into its string representation */
static inline void crypto_kw_cpu_to_be64(u64 val, u8 *buf)
{
	__be64 *a = (__be64 *)buf;

	*a = cpu_to_be64(val);
}

/*
 * Fast forward the SGL to the "end" length minus SEMIBSIZE.
 * The start in the SGL defined by the fast-forward is returned with
 * the walk variable
 */
static void crypto_kw_scatterlist_ff(struct scatter_walk *walk,
				     struct scatterlist *sg,
				     unsigned int end)
{
	unsigned int skip = 0;

	/* The caller should only operate on full SEMIBLOCKs. */
	BUG_ON(end < SEMIBSIZE);

	skip = end - SEMIBSIZE;
	while (sg) {
		if (sg->length > skip) {
			scatterwalk_start(walk, sg);
			scatterwalk_advance(walk, skip);
			break;
		} else
			skip -= sg->length;

		sg = sg_next(sg);
	}
}

static int crypto_kw_decrypt(struct blkcipher_desc *desc,
			     struct scatterlist *dst, struct scatterlist *src,
			     unsigned int nbytes)
{
	struct crypto_blkcipher *tfm = desc->tfm;
	struct crypto_kw_ctx *ctx = crypto_blkcipher_ctx(tfm);
	struct crypto_cipher *child = ctx->child;

	unsigned long alignmask = max_t(unsigned long, SEMIBSIZE,
					crypto_cipher_alignmask(child));
	unsigned int i;

	u8 blockbuf[sizeof(struct crypto_kw_block) + alignmask];
	struct crypto_kw_block *block = (struct crypto_kw_block *)
					PTR_ALIGN(blockbuf + 0, alignmask + 1);

	u64 t = 6 * ((nbytes) >> 3);
	struct scatterlist *lsrc, *ldst;
	int ret = 0;

	/*
	 * Require at least 2 semiblocks (note, the 3rd semiblock that is
	 * required by SP800-38F is the IV.
	 */
	if (nbytes < (2 * SEMIBSIZE) || nbytes % SEMIBSIZE)
		return -EINVAL;

	/* Place the IV into block A */
	memcpy(block->A, desc->info, SEMIBSIZE);

	/*
	 * src scatterlist is read-only. dst scatterlist is r/w. During the
	 * first loop, lsrc points to src and ldst to dst. For any
	 * subsequent round, the code operates on dst only.
	 */
	lsrc = src;
	ldst = dst;

	for (i = 0; i < 6; i++) {
		u8 tbe_buffer[SEMIBSIZE + alignmask];
		/* alignment for the crypto_xor and the _to_be64 operation */
		u8 *tbe = PTR_ALIGN(tbe_buffer + 0, alignmask + 1);
		unsigned int tmp_nbytes = nbytes;
		struct scatter_walk src_walk, dst_walk;

		while (tmp_nbytes) {
			/* move pointer by tmp_nbytes in the SGL */
			crypto_kw_scatterlist_ff(&src_walk, lsrc, tmp_nbytes);
			/* get the source block */
			scatterwalk_copychunks(block->R, &src_walk, SEMIBSIZE,
					       false);

			/* perform KW operation: get counter as byte string */
			crypto_kw_cpu_to_be64(t, tbe);
			/* perform KW operation: modify IV with counter */
			crypto_xor(block->A, tbe, SEMIBSIZE);
			t--;
			/* perform KW operation: decrypt block */
			crypto_cipher_decrypt_one(child, (u8*)block,
						  (u8*)block);

			/* move pointer by tmp_nbytes in the SGL */
			crypto_kw_scatterlist_ff(&dst_walk, ldst, tmp_nbytes);
			/* Copy block->R into place */
			scatterwalk_copychunks(block->R, &dst_walk, SEMIBSIZE,
					       true);

			tmp_nbytes -= SEMIBSIZE;
		}

		/* we now start to operate on the dst SGL only */
		lsrc = dst;
		ldst = dst;
	}

	/* Perform authentication check */
	if (crypto_memneq("\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6", block->A,
			  SEMIBSIZE))
		ret = -EBADMSG;

	memzero_explicit(&block, sizeof(struct crypto_kw_block));

	return ret;
}

static int crypto_kw_encrypt(struct blkcipher_desc *desc,
			     struct scatterlist *dst, struct scatterlist *src,
			     unsigned int nbytes)
{
	struct crypto_blkcipher *tfm = desc->tfm;
	struct crypto_kw_ctx *ctx = crypto_blkcipher_ctx(tfm);
	struct crypto_cipher *child = ctx->child;

	unsigned long alignmask = max_t(unsigned long, SEMIBSIZE,
					crypto_cipher_alignmask(child));
	unsigned int i;

	u8 blockbuf[sizeof(struct crypto_kw_block) + alignmask];
	struct crypto_kw_block *block = (struct crypto_kw_block *)
					PTR_ALIGN(blockbuf + 0, alignmask + 1);

	u64 t = 1;
	struct scatterlist *lsrc, *ldst;

	/*
	 * Require at least 2 semiblocks (note, the 3rd semiblock that is
	 * required by SP800-38F is the IV that occupies the first semiblock.
	 * This means that the dst memory must be one semiblock larger than src.
	 * Also ensure that the given data is aligned to semiblock.
	 */
	if (nbytes < (2 * SEMIBSIZE) || nbytes % SEMIBSIZE)
		return -EINVAL;

	/*
	 * Place the predefined IV into block A -- for encrypt, the caller
	 * does not need to provide an IV, but he needs to fetch the final IV.
	 */
	memcpy(block->A, "\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6", SEMIBSIZE);

	/*
	 * src scatterlist is read-only. dst scatterlist is r/w. During the
	 * first loop, lsrc points to src and ldst to dst. For any
	 * subsequent round, the code operates on dst only.
	 */
	lsrc = src;
	ldst = dst;

	for (i = 0; i < 6; i++) {
		u8 tbe_buffer[SEMIBSIZE + alignmask];
		u8 *tbe = PTR_ALIGN(tbe_buffer + 0, alignmask + 1);
		unsigned int tmp_nbytes = nbytes;
		struct scatter_walk src_walk, dst_walk;

		scatterwalk_start(&src_walk, lsrc);
		scatterwalk_start(&dst_walk, ldst);

		while (tmp_nbytes) {
			/* get the source block */
			scatterwalk_copychunks(block->R, &src_walk, SEMIBSIZE,
					       false);

			/* perform KW operation: encrypt block */
			crypto_cipher_encrypt_one(child, (u8 *)block,
						  (u8 *)block);
			/* perform KW operation: get counter as byte string */
			crypto_kw_cpu_to_be64(t, tbe);
			/* perform KW operation: modify IV with counter */
			crypto_xor(block->A, tbe, SEMIBSIZE);
			t++;

			/* Copy block->R into place */
			scatterwalk_copychunks(block->R, &dst_walk, SEMIBSIZE,
					       true);

			tmp_nbytes -= SEMIBSIZE;
		}

		/* we now start to operate on the dst SGL only */
		lsrc = dst;
		ldst = dst;
	}

	/* establish the IV for the caller to pick up */
	memcpy(desc->info, block->A, SEMIBSIZE);

	memzero_explicit(&block, sizeof(struct crypto_kw_block));

	return 0;
}

static int crypto_kw_setkey(struct crypto_tfm *parent, const u8 *key,
			    unsigned int keylen)
{
	struct crypto_kw_ctx *ctx = crypto_tfm_ctx(parent);
	struct crypto_cipher *child = ctx->child;
	int err;

	crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
	crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) &
				       CRYPTO_TFM_REQ_MASK);
	err = crypto_cipher_setkey(child, key, keylen);
	crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) &
				     CRYPTO_TFM_RES_MASK);
	return err;
}

static int crypto_kw_init_tfm(struct crypto_tfm *tfm)
{
	struct crypto_instance *inst = crypto_tfm_alg_instance(tfm);
	struct crypto_spawn *spawn = crypto_instance_ctx(inst);
	struct crypto_kw_ctx *ctx = crypto_tfm_ctx(tfm);
	struct crypto_cipher *cipher;

	cipher = crypto_spawn_cipher(spawn);
	if (IS_ERR(cipher))
		return PTR_ERR(cipher);

	ctx->child = cipher;
	return 0;
}

static void crypto_kw_exit_tfm(struct crypto_tfm *tfm)
{
	struct crypto_kw_ctx *ctx = crypto_tfm_ctx(tfm);

	crypto_free_cipher(ctx->child);
}

static struct crypto_instance *crypto_kw_alloc(struct rtattr **tb)
{
	struct crypto_instance *inst = NULL;
	struct crypto_alg *alg = NULL;
	int err;

	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
	if (err)
		return ERR_PTR(err);

	alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
				  CRYPTO_ALG_TYPE_MASK);
	if (IS_ERR(alg))
		return ERR_CAST(alg);

	inst = ERR_PTR(-EINVAL);
	/* Section 5.1 requirement for KW */
	if (alg->cra_blocksize != sizeof(struct crypto_kw_block))
		goto err;

	inst = crypto_alloc_instance("kw", alg);
	if (IS_ERR(inst))
		goto err;

	inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
	inst->alg.cra_priority = alg->cra_priority;
	inst->alg.cra_blocksize = SEMIBSIZE;
	inst->alg.cra_alignmask = 0;
	inst->alg.cra_type = &crypto_blkcipher_type;
	inst->alg.cra_blkcipher.ivsize = SEMIBSIZE;
	inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
	inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize;

	inst->alg.cra_ctxsize = sizeof(struct crypto_kw_ctx);

	inst->alg.cra_init = crypto_kw_init_tfm;
	inst->alg.cra_exit = crypto_kw_exit_tfm;

	inst->alg.cra_blkcipher.setkey = crypto_kw_setkey;
	inst->alg.cra_blkcipher.encrypt = crypto_kw_encrypt;
	inst->alg.cra_blkcipher.decrypt = crypto_kw_decrypt;

err:
	crypto_mod_put(alg);
	return inst;
}

static void crypto_kw_free(struct crypto_instance *inst)
{
	crypto_drop_spawn(crypto_instance_ctx(inst));
	kfree(inst);
}

static struct crypto_template crypto_kw_tmpl = {
	.name = "kw",
	.alloc = crypto_kw_alloc,
	.free = crypto_kw_free,
	.module = THIS_MODULE,
};

static int __init crypto_kw_init(void)
{
	return crypto_register_template(&crypto_kw_tmpl);
}

static void __exit crypto_kw_exit(void)
{
	crypto_unregister_template(&crypto_kw_tmpl);
}

module_init(crypto_kw_init);
module_exit(crypto_kw_exit);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
MODULE_DESCRIPTION("Key Wrapping (RFC3394 / NIST SP800-38F)");
MODULE_ALIAS_CRYPTO("kw");
