// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2016 Broadcom
 */

#include <linux/kernel.h>
#include <linux/string.h>

#include "util.h"
#include "spu.h"
#include "spum.h"
#include "cipher.h"

char *hash_alg_name[] = { "None", "md5", "sha1", "sha224", "sha256", "aes",
	"sha384", "sha512", "sha3_224", "sha3_256", "sha3_384", "sha3_512" };

char *aead_alg_name[] = { "ccm(aes)", "gcm(aes)", "authenc" };

/* Assumes SPU-M messages are in big endian */
void spum_dump_msg_hdr(u8 *buf, unsigned int buf_len)
{
	u8 *ptr = buf;
	struct SPUHEADER *spuh = (struct SPUHEADER *)buf;
	unsigned int hash_key_len = 0;
	unsigned int hash_state_len = 0;
	unsigned int cipher_key_len = 0;
	unsigned int iv_len;
	u32 pflags;
	u32 cflags;
	u32 ecf;
	u32 cipher_alg;
	u32 cipher_mode;
	u32 cipher_type;
	u32 hash_alg;
	u32 hash_mode;
	u32 hash_type;
	u32 sctx_size;   /* SCTX length in words */
	u32 sctx_pl_len; /* SCTX payload length in bytes */

	packet_log("\n");
	packet_log("SPU Message header %p len: %u\n", buf, buf_len);

	/* ========== Decode MH ========== */
	packet_log("  MH 0x%08x\n", be32_to_cpup((__be32 *)ptr));
	if (spuh->mh.flags & MH_SCTX_PRES)
		packet_log("    SCTX  present\n");
	if (spuh->mh.flags & MH_BDESC_PRES)
		packet_log("    BDESC present\n");
	if (spuh->mh.flags & MH_MFM_PRES)
		packet_log("    MFM   present\n");
	if (spuh->mh.flags & MH_BD_PRES)
		packet_log("    BD    present\n");
	if (spuh->mh.flags & MH_HASH_PRES)
		packet_log("    HASH  present\n");
	if (spuh->mh.flags & MH_SUPDT_PRES)
		packet_log("    SUPDT present\n");
	packet_log("    Opcode 0x%02x\n", spuh->mh.op_code);

	ptr += sizeof(spuh->mh) + sizeof(spuh->emh);  /* skip emh. unused */

	/* ========== Decode SCTX ========== */
	if (spuh->mh.flags & MH_SCTX_PRES) {
		pflags = be32_to_cpu(spuh->sa.proto_flags);
		packet_log("  SCTX[0] 0x%08x\n", pflags);
		sctx_size = pflags & SCTX_SIZE;
		packet_log("    Size %u words\n", sctx_size);

		cflags = be32_to_cpu(spuh->sa.cipher_flags);
		packet_log("  SCTX[1] 0x%08x\n", cflags);
		packet_log("    Inbound:%lu (1:decrypt/vrfy 0:encrypt/auth)\n",
			   (cflags & CIPHER_INBOUND) >> CIPHER_INBOUND_SHIFT);
		packet_log("    Order:%lu (1:AuthFirst 0:EncFirst)\n",
			   (cflags & CIPHER_ORDER) >> CIPHER_ORDER_SHIFT);
		packet_log("    ICV_IS_512:%lx\n",
			   (cflags & ICV_IS_512) >> ICV_IS_512_SHIFT);
		cipher_alg = (cflags & CIPHER_ALG) >> CIPHER_ALG_SHIFT;
		cipher_mode = (cflags & CIPHER_MODE) >> CIPHER_MODE_SHIFT;
		cipher_type = (cflags & CIPHER_TYPE) >> CIPHER_TYPE_SHIFT;
		packet_log("    Crypto Alg:%u Mode:%u Type:%u\n",
			   cipher_alg, cipher_mode, cipher_type);
		hash_alg = (cflags & HASH_ALG) >> HASH_ALG_SHIFT;
		hash_mode = (cflags & HASH_MODE) >> HASH_MODE_SHIFT;
		hash_type = (cflags & HASH_TYPE) >> HASH_TYPE_SHIFT;
		packet_log("    Hash   Alg:%x Mode:%x Type:%x\n",
			   hash_alg, hash_mode, hash_type);
		packet_log("    UPDT_Offset:%u\n", cflags & UPDT_OFST);

		ecf = be32_to_cpu(spuh->sa.ecf);
		packet_log("  SCTX[2] 0x%08x\n", ecf);
		packet_log("    WriteICV:%lu CheckICV:%lu ICV_SIZE:%u ",
			   (ecf & INSERT_ICV) >> INSERT_ICV_SHIFT,
			   (ecf & CHECK_ICV) >> CHECK_ICV_SHIFT,
			   (ecf & ICV_SIZE) >> ICV_SIZE_SHIFT);
		packet_log("BD_SUPPRESS:%lu\n",
			   (ecf & BD_SUPPRESS) >> BD_SUPPRESS_SHIFT);
		packet_log("    SCTX_IV:%lu ExplicitIV:%lu GenIV:%lu ",
			   (ecf & SCTX_IV) >> SCTX_IV_SHIFT,
			   (ecf & EXPLICIT_IV) >> EXPLICIT_IV_SHIFT,
			   (ecf & GEN_IV) >> GEN_IV_SHIFT);
		packet_log("IV_OV_OFST:%lu EXP_IV_SIZE:%u\n",
			   (ecf & IV_OFFSET) >> IV_OFFSET_SHIFT,
			   ecf & EXP_IV_SIZE);

		ptr += sizeof(struct SCTX);

		if (hash_alg && hash_mode) {
			char *name = "NONE";

			switch (hash_alg) {
			case HASH_ALG_MD5:
				hash_key_len = 16;
				name = "MD5";
				break;
			case HASH_ALG_SHA1:
				hash_key_len = 20;
				name = "SHA1";
				break;
			case HASH_ALG_SHA224:
				hash_key_len = 28;
				name = "SHA224";
				break;
			case HASH_ALG_SHA256:
				hash_key_len = 32;
				name = "SHA256";
				break;
			case HASH_ALG_SHA384:
				hash_key_len = 48;
				name = "SHA384";
				break;
			case HASH_ALG_SHA512:
				hash_key_len = 64;
				name = "SHA512";
				break;
			case HASH_ALG_AES:
				hash_key_len = 0;
				name = "AES";
				break;
			case HASH_ALG_NONE:
				break;
			}

			packet_log("    Auth Key Type:%s Length:%u Bytes\n",
				   name, hash_key_len);
			packet_dump("    KEY: ", ptr, hash_key_len);
			ptr += hash_key_len;
		} else if ((hash_alg == HASH_ALG_AES) &&
			   (hash_mode == HASH_MODE_XCBC)) {
			char *name = "NONE";

			switch (cipher_type) {
			case CIPHER_TYPE_AES128:
				hash_key_len = 16;
				name = "AES128-XCBC";
				break;
			case CIPHER_TYPE_AES192:
				hash_key_len = 24;
				name = "AES192-XCBC";
				break;
			case CIPHER_TYPE_AES256:
				hash_key_len = 32;
				name = "AES256-XCBC";
				break;
			}
			packet_log("    Auth Key Type:%s Length:%u Bytes\n",
				   name, hash_key_len);
			packet_dump("    KEY: ", ptr, hash_key_len);
			ptr += hash_key_len;
		}

		if (hash_alg && (hash_mode == HASH_MODE_NONE) &&
		    (hash_type == HASH_TYPE_UPDT)) {
			char *name = "NONE";

			switch (hash_alg) {
			case HASH_ALG_MD5:
				hash_state_len = 16;
				name = "MD5";
				break;
			case HASH_ALG_SHA1:
				hash_state_len = 20;
				name = "SHA1";
				break;
			case HASH_ALG_SHA224:
				hash_state_len = 32;
				name = "SHA224";
				break;
			case HASH_ALG_SHA256:
				hash_state_len = 32;
				name = "SHA256";
				break;
			case HASH_ALG_SHA384:
				hash_state_len = 48;
				name = "SHA384";
				break;
			case HASH_ALG_SHA512:
				hash_state_len = 64;
				name = "SHA512";
				break;
			case HASH_ALG_AES:
				hash_state_len = 0;
				name = "AES";
				break;
			case HASH_ALG_NONE:
				break;
			}

			packet_log("    Auth State Type:%s Length:%u Bytes\n",
				   name, hash_state_len);
			packet_dump("    State: ", ptr, hash_state_len);
			ptr += hash_state_len;
		}

		if (cipher_alg) {
			char *name = "NONE";

			switch (cipher_alg) {
			case CIPHER_ALG_DES:
				cipher_key_len = 8;
				name = "DES";
				break;
			case CIPHER_ALG_3DES:
				cipher_key_len = 24;
				name = "3DES";
				break;
			case CIPHER_ALG_AES:
				switch (cipher_type) {
				case CIPHER_TYPE_AES128:
					cipher_key_len = 16;
					name = "AES128";
					break;
				case CIPHER_TYPE_AES192:
					cipher_key_len = 24;
					name = "AES192";
					break;
				case CIPHER_TYPE_AES256:
					cipher_key_len = 32;
					name = "AES256";
					break;
				}
				break;
			case CIPHER_ALG_NONE:
				break;
			}

			packet_log("    Cipher Key Type:%s Length:%u Bytes\n",
				   name, cipher_key_len);

			/* XTS has two keys */
			if (cipher_mode == CIPHER_MODE_XTS) {
				packet_dump("    KEY2: ", ptr, cipher_key_len);
				ptr += cipher_key_len;
				packet_dump("    KEY1: ", ptr, cipher_key_len);
				ptr += cipher_key_len;

				cipher_key_len *= 2;
			} else {
				packet_dump("    KEY: ", ptr, cipher_key_len);
				ptr += cipher_key_len;
			}

			if (ecf & SCTX_IV) {
				sctx_pl_len = sctx_size * sizeof(u32) -
					sizeof(struct SCTX);
				iv_len = sctx_pl_len -
					(hash_key_len + hash_state_len +
					 cipher_key_len);
				packet_log("    IV Length:%u Bytes\n", iv_len);
				packet_dump("    IV: ", ptr, iv_len);
				ptr += iv_len;
			}
		}
	}

	/* ========== Decode BDESC ========== */
	if (spuh->mh.flags & MH_BDESC_PRES) {
		struct BDESC_HEADER *bdesc = (struct BDESC_HEADER *)ptr;

		packet_log("  BDESC[0] 0x%08x\n", be32_to_cpup((__be32 *)ptr));
		packet_log("    OffsetMAC:%u LengthMAC:%u\n",
			   be16_to_cpu(bdesc->offset_mac),
			   be16_to_cpu(bdesc->length_mac));
		ptr += sizeof(u32);

		packet_log("  BDESC[1] 0x%08x\n", be32_to_cpup((__be32 *)ptr));
		packet_log("    OffsetCrypto:%u LengthCrypto:%u\n",
			   be16_to_cpu(bdesc->offset_crypto),
			   be16_to_cpu(bdesc->length_crypto));
		ptr += sizeof(u32);

		packet_log("  BDESC[2] 0x%08x\n", be32_to_cpup((__be32 *)ptr));
		packet_log("    OffsetICV:%u OffsetIV:%u\n",
			   be16_to_cpu(bdesc->offset_icv),
			   be16_to_cpu(bdesc->offset_iv));
		ptr += sizeof(u32);
	}

	/* ========== Decode BD ========== */
	if (spuh->mh.flags & MH_BD_PRES) {
		struct BD_HEADER *bd = (struct BD_HEADER *)ptr;

		packet_log("  BD[0] 0x%08x\n", be32_to_cpup((__be32 *)ptr));
		packet_log("    Size:%ubytes PrevLength:%u\n",
			   be16_to_cpu(bd->size), be16_to_cpu(bd->prev_length));
		ptr += 4;
	}

	/* Double check sanity */
	if (buf + buf_len != ptr) {
		packet_log(" Packet parsed incorrectly. ");
		packet_log("buf:%p buf_len:%u buf+buf_len:%p ptr:%p\n",
			   buf, buf_len, buf + buf_len, ptr);
	}

	packet_log("\n");
}

/**
 * spum_ns2_ctx_max_payload() - Determine the max length of the payload for a
 * SPU message for a given cipher and hash alg context.
 * @cipher_alg:		The cipher algorithm
 * @cipher_mode:	The cipher mode
 * @blocksize:		The size of a block of data for this algo
 *
 * The max payload must be a multiple of the blocksize so that if a request is
 * too large to fit in a single SPU message, the request can be broken into
 * max_payload sized chunks. Each chunk must be a multiple of blocksize.
 *
 * Return: Max payload length in bytes
 */
u32 spum_ns2_ctx_max_payload(enum spu_cipher_alg cipher_alg,
			     enum spu_cipher_mode cipher_mode,
			     unsigned int blocksize)
{
	u32 max_payload = SPUM_NS2_MAX_PAYLOAD;
	u32 excess;

	/* In XTS on SPU-M, we'll need to insert tweak before input data */
	if (cipher_mode == CIPHER_MODE_XTS)
		max_payload -= SPU_XTS_TWEAK_SIZE;

	excess = max_payload % blocksize;

	return max_payload - excess;
}

/**
 * spum_nsp_ctx_max_payload() - Determine the max length of the payload for a
 * SPU message for a given cipher and hash alg context.
 * @cipher_alg:		The cipher algorithm
 * @cipher_mode:	The cipher mode
 * @blocksize:		The size of a block of data for this algo
 *
 * The max payload must be a multiple of the blocksize so that if a request is
 * too large to fit in a single SPU message, the request can be broken into
 * max_payload sized chunks. Each chunk must be a multiple of blocksize.
 *
 * Return: Max payload length in bytes
 */
u32 spum_nsp_ctx_max_payload(enum spu_cipher_alg cipher_alg,
			     enum spu_cipher_mode cipher_mode,
			     unsigned int blocksize)
{
	u32 max_payload = SPUM_NSP_MAX_PAYLOAD;
	u32 excess;

	/* In XTS on SPU-M, we'll need to insert tweak before input data */
	if (cipher_mode == CIPHER_MODE_XTS)
		max_payload -= SPU_XTS_TWEAK_SIZE;

	excess = max_payload % blocksize;

	return max_payload - excess;
}

/** spum_payload_length() - Given a SPU-M message header, extract the payload
 * length.
 * @spu_hdr:	Start of SPU header
 *
 * Assumes just MH, EMH, BD (no SCTX, BDESC. Works for response frames.
 *
 * Return: payload length in bytes
 */
u32 spum_payload_length(u8 *spu_hdr)
{
	struct BD_HEADER *bd;
	u32 pl_len;

	/* Find BD header.  skip MH, EMH */
	bd = (struct BD_HEADER *)(spu_hdr + 8);
	pl_len = be16_to_cpu(bd->size);

	return pl_len;
}

/**
 * spum_response_hdr_len() - Given the length of the hash key and encryption
 * key, determine the expected length of a SPU response header.
 * @auth_key_len:	authentication key length (bytes)
 * @enc_key_len:	encryption key length (bytes)
 * @is_hash:		true if response message is for a hash operation
 *
 * Return: length of SPU response header (bytes)
 */
u16 spum_response_hdr_len(u16 auth_key_len, u16 enc_key_len, bool is_hash)
{
	if (is_hash)
		return SPU_HASH_RESP_HDR_LEN;
	else
		return SPU_RESP_HDR_LEN;
}

/**
 * spum_hash_pad_len() - Calculate the length of hash padding required to extend
 * data to a full block size.
 * @hash_alg:   hash algorithm
 * @hash_mode:       hash mode
 * @chunksize:  length of data, in bytes
 * @hash_block_size:  size of a block of data for hash algorithm
 *
 * Reserve space for 1 byte (0x80) start of pad and the total length as u64
 *
 * Return:  length of hash pad in bytes
 */
u16 spum_hash_pad_len(enum hash_alg hash_alg, enum hash_mode hash_mode,
		      u32 chunksize, u16 hash_block_size)
{
	unsigned int length_len;
	unsigned int used_space_last_block;
	int hash_pad_len;

	/* AES-XCBC hash requires just padding to next block boundary */
	if ((hash_alg == HASH_ALG_AES) && (hash_mode == HASH_MODE_XCBC)) {
		used_space_last_block = chunksize % hash_block_size;
		hash_pad_len = hash_block_size - used_space_last_block;
		if (hash_pad_len >= hash_block_size)
			hash_pad_len -= hash_block_size;
		return hash_pad_len;
	}

	used_space_last_block = chunksize % hash_block_size + 1;
	if ((hash_alg == HASH_ALG_SHA384) || (hash_alg == HASH_ALG_SHA512))
		length_len = 2 * sizeof(u64);
	else
		length_len = sizeof(u64);

	used_space_last_block += length_len;
	hash_pad_len = hash_block_size - used_space_last_block;
	if (hash_pad_len < 0)
		hash_pad_len += hash_block_size;

	hash_pad_len += 1 + length_len;
	return hash_pad_len;
}

/**
 * spum_gcm_ccm_pad_len() - Determine the required length of GCM or CCM padding.
 * @cipher_mode:	Algo type
 * @data_size:		Length of plaintext (bytes)
 *
 * Return: Length of padding, in bytes
 */
u32 spum_gcm_ccm_pad_len(enum spu_cipher_mode cipher_mode,
			 unsigned int data_size)
{
	u32 pad_len = 0;
	u32 m1 = SPU_GCM_CCM_ALIGN - 1;

	if ((cipher_mode == CIPHER_MODE_GCM) ||
	    (cipher_mode == CIPHER_MODE_CCM))
		pad_len = ((data_size + m1) & ~m1) - data_size;

	return pad_len;
}

/**
 * spum_assoc_resp_len() - Determine the size of the receive buffer required to
 * catch associated data.
 * @cipher_mode:	cipher mode
 * @assoc_len:		length of associated data (bytes)
 * @iv_len:		length of IV (bytes)
 * @is_encrypt:		true if encrypting. false if decrypting.
 *
 * Return: length of associated data in response message (bytes)
 */
u32 spum_assoc_resp_len(enum spu_cipher_mode cipher_mode,
			unsigned int assoc_len, unsigned int iv_len,
			bool is_encrypt)
{
	u32 buflen = 0;
	u32 pad;

	if (assoc_len)
		buflen = assoc_len;

	if (cipher_mode == CIPHER_MODE_GCM) {
		/* AAD needs to be padded in responses too */
		pad = spum_gcm_ccm_pad_len(cipher_mode, buflen);
		buflen += pad;
	}
	if (cipher_mode == CIPHER_MODE_CCM) {
		/*
		 * AAD needs to be padded in responses too
		 * for CCM, len + 2 needs to be 128-bit aligned.
		 */
		pad = spum_gcm_ccm_pad_len(cipher_mode, buflen + 2);
		buflen += pad;
	}

	return buflen;
}

/**
 * spum_aead_ivlen() - Calculate the length of the AEAD IV to be included
 * in a SPU request after the AAD and before the payload.
 * @cipher_mode:  cipher mode
 * @iv_len:   initialization vector length in bytes
 *
 * In Linux ~4.2 and later, the assoc_data sg includes the IV. So no need
 * to include the IV as a separate field in the SPU request msg.
 *
 * Return: Length of AEAD IV in bytes
 */
u8 spum_aead_ivlen(enum spu_cipher_mode cipher_mode, u16 iv_len)
{
	return 0;
}

/**
 * spum_hash_type() - Determine the type of hash operation.
 * @src_sent:  The number of bytes in the current request that have already
 *             been sent to the SPU to be hashed.
 *
 * We do not use HASH_TYPE_FULL for requests that fit in a single SPU message.
 * Using FULL causes failures (such as when the string to be hashed is empty).
 * For similar reasons, we never use HASH_TYPE_FIN. Instead, submit messages
 * as INIT or UPDT and do the hash padding in sw.
 */
enum hash_type spum_hash_type(u32 src_sent)
{
	return src_sent ? HASH_TYPE_UPDT : HASH_TYPE_INIT;
}

/**
 * spum_digest_size() - Determine the size of a hash digest to expect the SPU to
 * return.
 * @alg_digest_size: Number of bytes in the final digest for the given algo
 * @alg:             The hash algorithm
 * @htype:           Type of hash operation (init, update, full, etc)
 *
 * When doing incremental hashing for an algorithm with a truncated hash
 * (e.g., SHA224), the SPU returns the full digest so that it can be fed back as
 * a partial result for the next chunk.
 */
u32 spum_digest_size(u32 alg_digest_size, enum hash_alg alg,
		     enum hash_type htype)
{
	u32 digestsize = alg_digest_size;

	/* SPU returns complete digest when doing incremental hash and truncated
	 * hash algo.
	 */
	if ((htype == HASH_TYPE_INIT) || (htype == HASH_TYPE_UPDT)) {
		if (alg == HASH_ALG_SHA224)
			digestsize = SHA256_DIGEST_SIZE;
		else if (alg == HASH_ALG_SHA384)
			digestsize = SHA512_DIGEST_SIZE;
	}
	return digestsize;
}

/**
 * spum_create_request() - Build a SPU request message header, up to and
 * including the BD header. Construct the message starting at spu_hdr. Caller
 * should allocate this buffer in DMA-able memory at least SPU_HEADER_ALLOC_LEN
 * bytes long.
 * @spu_hdr: Start of buffer where SPU request header is to be written
 * @req_opts: SPU request message options
 * @cipher_parms: Parameters related to cipher algorithm
 * @hash_parms:   Parameters related to hash algorithm
 * @aead_parms:   Parameters related to AEAD operation
 * @data_size:    Length of data to be encrypted or authenticated. If AEAD, does
 *		  not include length of AAD.
 *
 * Return: the length of the SPU header in bytes. 0 if an error occurs.
 */
u32 spum_create_request(u8 *spu_hdr,
			struct spu_request_opts *req_opts,
			struct spu_cipher_parms *cipher_parms,
			struct spu_hash_parms *hash_parms,
			struct spu_aead_parms *aead_parms,
			unsigned int data_size)
{
	struct SPUHEADER *spuh;
	struct BDESC_HEADER *bdesc;
	struct BD_HEADER *bd;

	u8 *ptr;
	u32 protocol_bits = 0;
	u32 cipher_bits = 0;
	u32 ecf_bits = 0;
	u8 sctx_words = 0;
	unsigned int buf_len = 0;

	/* size of the cipher payload */
	unsigned int cipher_len = hash_parms->prebuf_len + data_size +
				hash_parms->pad_len;

	/* offset of prebuf or data from end of BD header */
	unsigned int cipher_offset = aead_parms->assoc_size +
		aead_parms->iv_len + aead_parms->aad_pad_len;

	/* total size of the DB data (without STAT word padding) */
	unsigned int real_db_size = spu_real_db_size(aead_parms->assoc_size,
						 aead_parms->iv_len,
						 hash_parms->prebuf_len,
						 data_size,
						 aead_parms->aad_pad_len,
						 aead_parms->data_pad_len,
						 hash_parms->pad_len);

	unsigned int auth_offset = 0;
	unsigned int offset_iv = 0;

	/* size/offset of the auth payload */
	unsigned int auth_len;

	auth_len = real_db_size;

	if (req_opts->is_aead && req_opts->is_inbound)
		cipher_len -= hash_parms->digestsize;

	if (req_opts->is_aead && req_opts->is_inbound)
		auth_len -= hash_parms->digestsize;

	if ((hash_parms->alg == HASH_ALG_AES) &&
	    (hash_parms->mode == HASH_MODE_XCBC)) {
		auth_len -= hash_parms->pad_len;
		cipher_len -= hash_parms->pad_len;
	}

	flow_log("%s()\n", __func__);
	flow_log("  in:%u authFirst:%u\n",
		 req_opts->is_inbound, req_opts->auth_first);
	flow_log("  %s. cipher alg:%u mode:%u type %u\n",
		 spu_alg_name(cipher_parms->alg, cipher_parms->mode),
		 cipher_parms->alg, cipher_parms->mode, cipher_parms->type);
	flow_log("    key: %d\n", cipher_parms->key_len);
	flow_dump("    key: ", cipher_parms->key_buf, cipher_parms->key_len);
	flow_log("    iv: %d\n", cipher_parms->iv_len);
	flow_dump("    iv: ", cipher_parms->iv_buf, cipher_parms->iv_len);
	flow_log("  auth alg:%u mode:%u type %u\n",
		 hash_parms->alg, hash_parms->mode, hash_parms->type);
	flow_log("  digestsize: %u\n", hash_parms->digestsize);
	flow_log("  authkey: %d\n", hash_parms->key_len);
	flow_dump("  authkey: ", hash_parms->key_buf, hash_parms->key_len);
	flow_log("  assoc_size:%u\n", aead_parms->assoc_size);
	flow_log("  prebuf_len:%u\n", hash_parms->prebuf_len);
	flow_log("  data_size:%u\n", data_size);
	flow_log("  hash_pad_len:%u\n", hash_parms->pad_len);
	flow_log("  real_db_size:%u\n", real_db_size);
	flow_log(" auth_offset:%u auth_len:%u cipher_offset:%u cipher_len:%u\n",
		 auth_offset, auth_len, cipher_offset, cipher_len);
	flow_log("  aead_iv: %u\n", aead_parms->iv_len);

	/* starting out: zero the header (plus some) */
	ptr = spu_hdr;
	memset(ptr, 0, sizeof(struct SPUHEADER));

	/* format master header word */
	/* Do not set the next bit even though the datasheet says to */
	spuh = (struct SPUHEADER *)ptr;
	ptr += sizeof(struct SPUHEADER);
	buf_len += sizeof(struct SPUHEADER);

	spuh->mh.op_code = SPU_CRYPTO_OPERATION_GENERIC;
	spuh->mh.flags |= (MH_SCTX_PRES | MH_BDESC_PRES | MH_BD_PRES);

	/* Format sctx word 0 (protocol_bits) */
	sctx_words = 3;		/* size in words */

	/* Format sctx word 1 (cipher_bits) */
	if (req_opts->is_inbound)
		cipher_bits |= CIPHER_INBOUND;
	if (req_opts->auth_first)
		cipher_bits |= CIPHER_ORDER;

	/* Set the crypto parameters in the cipher.flags */
	cipher_bits |= cipher_parms->alg << CIPHER_ALG_SHIFT;
	cipher_bits |= cipher_parms->mode << CIPHER_MODE_SHIFT;
	cipher_bits |= cipher_parms->type << CIPHER_TYPE_SHIFT;

	/* Set the auth parameters in the cipher.flags */
	cipher_bits |= hash_parms->alg << HASH_ALG_SHIFT;
	cipher_bits |= hash_parms->mode << HASH_MODE_SHIFT;
	cipher_bits |= hash_parms->type << HASH_TYPE_SHIFT;

	/*
	 * Format sctx extensions if required, and update main fields if
	 * required)
	 */
	if (hash_parms->alg) {
		/* Write the authentication key material if present */
		if (hash_parms->key_len) {
			memcpy(ptr, hash_parms->key_buf, hash_parms->key_len);
			ptr += hash_parms->key_len;
			buf_len += hash_parms->key_len;
			sctx_words += hash_parms->key_len / 4;
		}

		if ((cipher_parms->mode == CIPHER_MODE_GCM) ||
		    (cipher_parms->mode == CIPHER_MODE_CCM))
			/* unpadded length */
			offset_iv = aead_parms->assoc_size;

		/* if GCM/CCM we need to write ICV into the payload */
		if (!req_opts->is_inbound) {
			if ((cipher_parms->mode == CIPHER_MODE_GCM) ||
			    (cipher_parms->mode == CIPHER_MODE_CCM))
				ecf_bits |= 1 << INSERT_ICV_SHIFT;
		} else {
			ecf_bits |= CHECK_ICV;
		}

		/* Inform the SPU of the ICV size (in words) */
		if (hash_parms->digestsize == 64)
			cipher_bits |= ICV_IS_512;
		else
			ecf_bits |=
			(hash_parms->digestsize / 4) << ICV_SIZE_SHIFT;
	}

	if (req_opts->bd_suppress)
		ecf_bits |= BD_SUPPRESS;

	/* copy the encryption keys in the SAD entry */
	if (cipher_parms->alg) {
		if (cipher_parms->key_len) {
			memcpy(ptr, cipher_parms->key_buf,
			       cipher_parms->key_len);
			ptr += cipher_parms->key_len;
			buf_len += cipher_parms->key_len;
			sctx_words += cipher_parms->key_len / 4;
		}

		/*
		 * if encrypting then set IV size, use SCTX IV unless no IV
		 * given here
		 */
		if (cipher_parms->iv_buf && cipher_parms->iv_len) {
			/* Use SCTX IV */
			ecf_bits |= SCTX_IV;

			/* cipher iv provided so put it in here */
			memcpy(ptr, cipher_parms->iv_buf, cipher_parms->iv_len);

			ptr += cipher_parms->iv_len;
			buf_len += cipher_parms->iv_len;
			sctx_words += cipher_parms->iv_len / 4;
		}
	}

	/*
	 * RFC4543 (GMAC/ESP) requires data to be sent as part of AAD
	 * so we need to override the BDESC parameters.
	 */
	if (req_opts->is_rfc4543) {
		if (req_opts->is_inbound)
			data_size -= hash_parms->digestsize;
		offset_iv = aead_parms->assoc_size + data_size;
		cipher_len = 0;
		cipher_offset = offset_iv;
		auth_len = cipher_offset + aead_parms->data_pad_len;
	}

	/* write in the total sctx length now that we know it */
	protocol_bits |= sctx_words;

	/* Endian adjust the SCTX */
	spuh->sa.proto_flags = cpu_to_be32(protocol_bits);
	spuh->sa.cipher_flags = cpu_to_be32(cipher_bits);
	spuh->sa.ecf = cpu_to_be32(ecf_bits);

	/* === create the BDESC section === */
	bdesc = (struct BDESC_HEADER *)ptr;

	bdesc->offset_mac = cpu_to_be16(auth_offset);
	bdesc->length_mac = cpu_to_be16(auth_len);
	bdesc->offset_crypto = cpu_to_be16(cipher_offset);
	bdesc->length_crypto = cpu_to_be16(cipher_len);

	/*
	 * CCM in SPU-M requires that ICV not be in same 32-bit word as data or
	 * padding.  So account for padding as necessary.
	 */
	if (cipher_parms->mode == CIPHER_MODE_CCM)
		auth_len += spum_wordalign_padlen(auth_len);

	bdesc->offset_icv = cpu_to_be16(auth_len);
	bdesc->offset_iv = cpu_to_be16(offset_iv);

	ptr += sizeof(struct BDESC_HEADER);
	buf_len += sizeof(struct BDESC_HEADER);

	/* === no MFM section === */

	/* === create the BD section === */

	/* add the BD header */
	bd = (struct BD_HEADER *)ptr;
	bd->size = cpu_to_be16(real_db_size);
	bd->prev_length = 0;

	ptr += sizeof(struct BD_HEADER);
	buf_len += sizeof(struct BD_HEADER);

	packet_dump("  SPU request header: ", spu_hdr, buf_len);

	return buf_len;
}

/**
 * spum_cipher_req_init() - Build a SPU request message header, up to and
 * including the BD header.
 * @spu_hdr:      Start of SPU request header (MH)
 * @cipher_parms: Parameters that describe the cipher request
 *
 * Construct the message starting at spu_hdr. Caller should allocate this buffer
 * in DMA-able memory at least SPU_HEADER_ALLOC_LEN bytes long.
 *
 * Return: the length of the SPU header in bytes. 0 if an error occurs.
 */
u16 spum_cipher_req_init(u8 *spu_hdr, struct spu_cipher_parms *cipher_parms)
{
	struct SPUHEADER *spuh;
	u32 protocol_bits = 0;
	u32 cipher_bits = 0;
	u32 ecf_bits = 0;
	u8 sctx_words = 0;

	flow_log("%s()\n", __func__);
	flow_log("  cipher alg:%u mode:%u type %u\n", cipher_parms->alg,
		 cipher_parms->mode, cipher_parms->type);
	flow_log("  cipher_iv_len: %u\n", cipher_parms->iv_len);
	flow_log("    key: %d\n", cipher_parms->key_len);
	flow_dump("    key: ", cipher_parms->key_buf, cipher_parms->key_len);

	/* starting out: zero the header (plus some) */
	memset(spu_hdr, 0, sizeof(struct SPUHEADER));

	/* format master header word */
	/* Do not set the next bit even though the datasheet says to */
	spuh = (struct SPUHEADER *)spu_hdr;

	spuh->mh.op_code = SPU_CRYPTO_OPERATION_GENERIC;
	spuh->mh.flags |= (MH_SCTX_PRES | MH_BDESC_PRES | MH_BD_PRES);

	/* Format sctx word 0 (protocol_bits) */
	sctx_words = 3;		/* size in words */

	/* copy the encryption keys in the SAD entry */
	if (cipher_parms->alg) {
		if (cipher_parms->key_len)
			sctx_words += cipher_parms->key_len / 4;

		/*
		 * if encrypting then set IV size, use SCTX IV unless no IV
		 * given here
		 */
		if (cipher_parms->iv_len) {
			/* Use SCTX IV */
			ecf_bits |= SCTX_IV;
			sctx_words += cipher_parms->iv_len / 4;
		}
	}

	/* Set the crypto parameters in the cipher.flags */
	cipher_bits |= cipher_parms->alg << CIPHER_ALG_SHIFT;
	cipher_bits |= cipher_parms->mode << CIPHER_MODE_SHIFT;
	cipher_bits |= cipher_parms->type << CIPHER_TYPE_SHIFT;

	/* copy the encryption keys in the SAD entry */
	if (cipher_parms->alg && cipher_parms->key_len)
		memcpy(spuh + 1, cipher_parms->key_buf, cipher_parms->key_len);

	/* write in the total sctx length now that we know it */
	protocol_bits |= sctx_words;

	/* Endian adjust the SCTX */
	spuh->sa.proto_flags = cpu_to_be32(protocol_bits);

	/* Endian adjust the SCTX */
	spuh->sa.cipher_flags = cpu_to_be32(cipher_bits);
	spuh->sa.ecf = cpu_to_be32(ecf_bits);

	packet_dump("  SPU request header: ", spu_hdr,
		    sizeof(struct SPUHEADER));

	return sizeof(struct SPUHEADER) + cipher_parms->key_len +
		cipher_parms->iv_len + sizeof(struct BDESC_HEADER) +
		sizeof(struct BD_HEADER);
}

/**
 * spum_cipher_req_finish() - Finish building a SPU request message header for a
 * block cipher request. Assumes much of the header was already filled in at
 * setkey() time in spu_cipher_req_init().
 * @spu_hdr:         Start of the request message header (MH field)
 * @spu_req_hdr_len: Length in bytes of the SPU request header
 * @is_inbound:      0 encrypt, 1 decrypt
 * @cipher_parms:    Parameters describing cipher operation to be performed
 * @data_size:       Length of the data in the BD field
 *
 * Assumes much of the header was already filled in at setkey() time in
 * spum_cipher_req_init().
 * spum_cipher_req_init() fills in the encryption key.
 */
void spum_cipher_req_finish(u8 *spu_hdr,
			    u16 spu_req_hdr_len,
			    unsigned int is_inbound,
			    struct spu_cipher_parms *cipher_parms,
			    unsigned int data_size)
{
	struct SPUHEADER *spuh;
	struct BDESC_HEADER *bdesc;
	struct BD_HEADER *bd;
	u8 *bdesc_ptr = spu_hdr + spu_req_hdr_len -
	    (sizeof(struct BD_HEADER) + sizeof(struct BDESC_HEADER));

	u32 cipher_bits;

	flow_log("%s()\n", __func__);
	flow_log(" in: %u\n", is_inbound);
	flow_log(" cipher alg: %u, cipher_type: %u\n", cipher_parms->alg,
		 cipher_parms->type);

	/*
	 * In XTS mode, API puts "i" parameter (block tweak) in IV.  For
	 * SPU-M, should be in start of the BD; tx_sg_create() copies it there.
	 * IV in SPU msg for SPU-M should be 0, since that's the "j" parameter
	 * (block ctr within larger data unit) - given we can send entire disk
	 * block (<= 4KB) in 1 SPU msg, don't need to use this parameter.
	 */
	if (cipher_parms->mode == CIPHER_MODE_XTS)
		memset(cipher_parms->iv_buf, 0, cipher_parms->iv_len);

	flow_log(" iv len: %d\n", cipher_parms->iv_len);
	flow_dump("    iv: ", cipher_parms->iv_buf, cipher_parms->iv_len);
	flow_log(" data_size: %u\n", data_size);

	/* format master header word */
	/* Do not set the next bit even though the datasheet says to */
	spuh = (struct SPUHEADER *)spu_hdr;

	/* cipher_bits was initialized at setkey time */
	cipher_bits = be32_to_cpu(spuh->sa.cipher_flags);

	/* Format sctx word 1 (cipher_bits) */
	if (is_inbound)
		cipher_bits |= CIPHER_INBOUND;
	else
		cipher_bits &= ~CIPHER_INBOUND;

	if (cipher_parms->alg && cipher_parms->iv_buf && cipher_parms->iv_len)
		/* cipher iv provided so put it in here */
		memcpy(bdesc_ptr - cipher_parms->iv_len, cipher_parms->iv_buf,
		       cipher_parms->iv_len);

	spuh->sa.cipher_flags = cpu_to_be32(cipher_bits);

	/* === create the BDESC section === */
	bdesc = (struct BDESC_HEADER *)bdesc_ptr;
	bdesc->offset_mac = 0;
	bdesc->length_mac = 0;
	bdesc->offset_crypto = 0;

	/* XTS mode, data_size needs to include tweak parameter */
	if (cipher_parms->mode == CIPHER_MODE_XTS)
		bdesc->length_crypto = cpu_to_be16(data_size +
						  SPU_XTS_TWEAK_SIZE);
	else
		bdesc->length_crypto = cpu_to_be16(data_size);

	bdesc->offset_icv = 0;
	bdesc->offset_iv = 0;

	/* === no MFM section === */

	/* === create the BD section === */
	/* add the BD header */
	bd = (struct BD_HEADER *)(bdesc_ptr + sizeof(struct BDESC_HEADER));
	bd->size = cpu_to_be16(data_size);

	/* XTS mode, data_size needs to include tweak parameter */
	if (cipher_parms->mode == CIPHER_MODE_XTS)
		bd->size = cpu_to_be16(data_size + SPU_XTS_TWEAK_SIZE);
	else
		bd->size = cpu_to_be16(data_size);

	bd->prev_length = 0;

	packet_dump("  SPU request header: ", spu_hdr, spu_req_hdr_len);
}

/**
 * spum_request_pad() - Create pad bytes at the end of the data.
 * @pad_start:		Start of buffer where pad bytes are to be written
 * @gcm_ccm_padding:	length of GCM/CCM padding, in bytes
 * @hash_pad_len:	Number of bytes of padding extend data to full block
 * @auth_alg:		authentication algorithm
 * @auth_mode:		authentication mode
 * @total_sent:		length inserted at end of hash pad
 * @status_padding:	Number of bytes of padding to align STATUS word
 *
 * There may be three forms of pad:
 *  1. GCM/CCM pad - for GCM/CCM mode ciphers, pad to 16-byte alignment
 *  2. hash pad - pad to a block length, with 0x80 data terminator and
 *                size at the end
 *  3. STAT pad - to ensure the STAT field is 4-byte aligned
 */
void spum_request_pad(u8 *pad_start,
		      u32 gcm_ccm_padding,
		      u32 hash_pad_len,
		      enum hash_alg auth_alg,
		      enum hash_mode auth_mode,
		      unsigned int total_sent, u32 status_padding)
{
	u8 *ptr = pad_start;

	/* fix data alignent for GCM/CCM */
	if (gcm_ccm_padding > 0) {
		flow_log("  GCM: padding to 16 byte alignment: %u bytes\n",
			 gcm_ccm_padding);
		memset(ptr, 0, gcm_ccm_padding);
		ptr += gcm_ccm_padding;
	}

	if (hash_pad_len > 0) {
		/* clear the padding section */
		memset(ptr, 0, hash_pad_len);

		if ((auth_alg == HASH_ALG_AES) &&
		    (auth_mode == HASH_MODE_XCBC)) {
			/* AES/XCBC just requires padding to be 0s */
			ptr += hash_pad_len;
		} else {
			/* terminate the data */
			*ptr = 0x80;
			ptr += (hash_pad_len - sizeof(u64));

			/* add the size at the end as required per alg */
			if (auth_alg == HASH_ALG_MD5)
				*(__le64 *)ptr = cpu_to_le64(total_sent * 8ull);
			else		/* SHA1, SHA2-224, SHA2-256 */
				*(__be64 *)ptr = cpu_to_be64(total_sent * 8ull);
			ptr += sizeof(u64);
		}
	}

	/* pad to a 4byte alignment for STAT */
	if (status_padding > 0) {
		flow_log("  STAT: padding to 4 byte alignment: %u bytes\n",
			 status_padding);

		memset(ptr, 0, status_padding);
		ptr += status_padding;
	}
}

/**
 * spum_xts_tweak_in_payload() - Indicate that SPUM DOES place the XTS tweak
 * field in the packet payload (rather than using IV)
 *
 * Return: 1
 */
u8 spum_xts_tweak_in_payload(void)
{
	return 1;
}

/**
 * spum_tx_status_len() - Return the length of the STATUS field in a SPU
 * response message.
 *
 * Return: Length of STATUS field in bytes.
 */
u8 spum_tx_status_len(void)
{
	return SPU_TX_STATUS_LEN;
}

/**
 * spum_rx_status_len() - Return the length of the STATUS field in a SPU
 * response message.
 *
 * Return: Length of STATUS field in bytes.
 */
u8 spum_rx_status_len(void)
{
	return SPU_RX_STATUS_LEN;
}

/**
 * spum_status_process() - Process the status from a SPU response message.
 * @statp:  start of STATUS word
 * Return:
 *   0 - if status is good and response should be processed
 *   !0 - status indicates an error and response is invalid
 */
int spum_status_process(u8 *statp)
{
	u32 status;

	status = __be32_to_cpu(*(__be32 *)statp);
	flow_log("SPU response STATUS %#08x\n", status);
	if (status & SPU_STATUS_ERROR_FLAG) {
		pr_err("%s() Warning: Error result from SPU: %#08x\n",
		       __func__, status);
		if (status & SPU_STATUS_INVALID_ICV)
			return SPU_INVALID_ICV;
		return -EBADMSG;
	}
	return 0;
}

/**
 * spum_ccm_update_iv() - Update the IV as per the requirements for CCM mode.
 *
 * @digestsize:		Digest size of this request
 * @cipher_parms:	(pointer to) cipher parmaeters, includes IV buf & IV len
 * @assoclen:		Length of AAD data
 * @chunksize:		length of input data to be sent in this req
 * @is_encrypt:		true if this is an output/encrypt operation
 * @is_esp:		true if this is an ESP / RFC4309 operation
 *
 */
void spum_ccm_update_iv(unsigned int digestsize,
			struct spu_cipher_parms *cipher_parms,
			unsigned int assoclen,
			unsigned int chunksize,
			bool is_encrypt,
			bool is_esp)
{
	u8 L;		/* L from CCM algorithm, length of plaintext data */
	u8 mprime;	/* M' from CCM algo, (M - 2) / 2, where M=authsize */
	u8 adata;

	if (cipher_parms->iv_len != CCM_AES_IV_SIZE) {
		pr_err("%s(): Invalid IV len %d for CCM mode, should be %d\n",
		       __func__, cipher_parms->iv_len, CCM_AES_IV_SIZE);
		return;
	}

	/*
	 * IV needs to be formatted as follows:
	 *
	 * |          Byte 0               | Bytes 1 - N | Bytes (N+1) - 15 |
	 * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Bits 7 - 0  |    Bits 7 - 0    |
	 * | 0 |Ad?|(M - 2) / 2|   L - 1   |    Nonce    | Plaintext Length |
	 *
	 * Ad? = 1 if AAD present, 0 if not present
	 * M = size of auth field, 8, 12, or 16 bytes (SPU-M) -or-
	 *                         4, 6, 8, 10, 12, 14, 16 bytes (SPU2)
	 * L = Size of Plaintext Length field; Nonce size = 15 - L
	 *
	 * It appears that the crypto API already expects the L-1 portion
	 * to be set in the first byte of the IV, which implicitly determines
	 * the nonce size, and also fills in the nonce.  But the other bits
	 * in byte 0 as well as the plaintext length need to be filled in.
	 *
	 * In rfc4309/esp mode, L is not already in the supplied IV and
	 * we need to fill it in, as well as move the IV data to be after
	 * the salt
	 */
	if (is_esp) {
		L = CCM_ESP_L_VALUE;	/* RFC4309 has fixed L */
	} else {
		/* L' = plaintext length - 1 so Plaintext length is L' + 1 */
		L = ((cipher_parms->iv_buf[0] & CCM_B0_L_PRIME) >>
		      CCM_B0_L_PRIME_SHIFT) + 1;
	}

	mprime = (digestsize - 2) >> 1;  /* M' = (M - 2) / 2 */
	adata = (assoclen > 0);  /* adata = 1 if any associated data */

	cipher_parms->iv_buf[0] = (adata << CCM_B0_ADATA_SHIFT) |
				  (mprime << CCM_B0_M_PRIME_SHIFT) |
				  ((L - 1) << CCM_B0_L_PRIME_SHIFT);

	/* Nonce is already filled in by crypto API, and is 15 - L bytes */

	/* Don't include digest in plaintext size when decrypting */
	if (!is_encrypt)
		chunksize -= digestsize;

	/* Fill in length of plaintext, formatted to be L bytes long */
	format_value_ccm(chunksize, &cipher_parms->iv_buf[15 - L + 1], L);
}

/**
 * spum_wordalign_padlen() - Given the length of a data field, determine the
 * padding required to align the data following this field on a 4-byte boundary.
 * @data_size: length of data field in bytes
 *
 * Return: length of status field padding, in bytes
 */
u32 spum_wordalign_padlen(u32 data_size)
{
	return ((data_size + 3) & ~3) - data_size;
}
