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

/*
 * This file works with the SPU2 version of the SPU. SPU2 has different message
 * formats than the previous version of the SPU. All SPU message format
 * differences should be hidden in the spux.c,h files.
 */

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

#include "util.h"
#include "spu.h"
#include "spu2.h"

#define SPU2_TX_STATUS_LEN  0	/* SPU2 has no STATUS in input packet */

/*
 * Controlled by pkt_stat_cnt field in CRYPTO_SS_SPU0_CORE_SPU2_CONTROL0
 * register. Defaults to 2.
 */
#define SPU2_RX_STATUS_LEN  2

enum spu2_proto_sel {
	SPU2_PROTO_RESV = 0,
	SPU2_MACSEC_SECTAG8_ECB = 1,
	SPU2_MACSEC_SECTAG8_SCB = 2,
	SPU2_MACSEC_SECTAG16 = 3,
	SPU2_MACSEC_SECTAG16_8_XPN = 4,
	SPU2_IPSEC = 5,
	SPU2_IPSEC_ESN = 6,
	SPU2_TLS_CIPHER = 7,
	SPU2_TLS_AEAD = 8,
	SPU2_DTLS_CIPHER = 9,
	SPU2_DTLS_AEAD = 10
};

static char *spu2_cipher_type_names[] = { "None", "AES128", "AES192", "AES256",
	"DES", "3DES"
};

static char *spu2_cipher_mode_names[] = { "ECB", "CBC", "CTR", "CFB", "OFB",
	"XTS", "CCM", "GCM"
};

static char *spu2_hash_type_names[] = { "None", "AES128", "AES192", "AES256",
	"Reserved", "Reserved", "MD5", "SHA1", "SHA224", "SHA256", "SHA384",
	"SHA512", "SHA512/224", "SHA512/256", "SHA3-224", "SHA3-256",
	"SHA3-384", "SHA3-512"
};

static char *spu2_hash_mode_names[] = { "CMAC", "CBC-MAC", "XCBC-MAC", "HMAC",
	"Rabin", "CCM", "GCM", "Reserved"
};

static char *spu2_ciph_type_name(enum spu2_cipher_type cipher_type)
{
	if (cipher_type >= SPU2_CIPHER_TYPE_LAST)
		return "Reserved";
	return spu2_cipher_type_names[cipher_type];
}

static char *spu2_ciph_mode_name(enum spu2_cipher_mode cipher_mode)
{
	if (cipher_mode >= SPU2_CIPHER_MODE_LAST)
		return "Reserved";
	return spu2_cipher_mode_names[cipher_mode];
}

static char *spu2_hash_type_name(enum spu2_hash_type hash_type)
{
	if (hash_type >= SPU2_HASH_TYPE_LAST)
		return "Reserved";
	return spu2_hash_type_names[hash_type];
}

static char *spu2_hash_mode_name(enum spu2_hash_mode hash_mode)
{
	if (hash_mode >= SPU2_HASH_MODE_LAST)
		return "Reserved";
	return spu2_hash_mode_names[hash_mode];
}

/*
 * Convert from a software cipher mode value to the corresponding value
 * for SPU2.
 */
static int spu2_cipher_mode_xlate(enum spu_cipher_mode cipher_mode,
				  enum spu2_cipher_mode *spu2_mode)
{
	switch (cipher_mode) {
	case CIPHER_MODE_ECB:
		*spu2_mode = SPU2_CIPHER_MODE_ECB;
		break;
	case CIPHER_MODE_CBC:
		*spu2_mode = SPU2_CIPHER_MODE_CBC;
		break;
	case CIPHER_MODE_OFB:
		*spu2_mode = SPU2_CIPHER_MODE_OFB;
		break;
	case CIPHER_MODE_CFB:
		*spu2_mode = SPU2_CIPHER_MODE_CFB;
		break;
	case CIPHER_MODE_CTR:
		*spu2_mode = SPU2_CIPHER_MODE_CTR;
		break;
	case CIPHER_MODE_CCM:
		*spu2_mode = SPU2_CIPHER_MODE_CCM;
		break;
	case CIPHER_MODE_GCM:
		*spu2_mode = SPU2_CIPHER_MODE_GCM;
		break;
	case CIPHER_MODE_XTS:
		*spu2_mode = SPU2_CIPHER_MODE_XTS;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

/**
 * spu2_cipher_xlate() - Convert a cipher {alg/mode/type} triple to a SPU2
 * cipher type and mode.
 * @cipher_alg:  [in]  cipher algorithm value from software enumeration
 * @cipher_mode: [in]  cipher mode value from software enumeration
 * @cipher_type: [in]  cipher type value from software enumeration
 * @spu2_type:   [out] cipher type value used by spu2 hardware
 * @spu2_mode:   [out] cipher mode value used by spu2 hardware
 *
 * Return:  0 if successful
 */
static int spu2_cipher_xlate(enum spu_cipher_alg cipher_alg,
			     enum spu_cipher_mode cipher_mode,
			     enum spu_cipher_type cipher_type,
			     enum spu2_cipher_type *spu2_type,
			     enum spu2_cipher_mode *spu2_mode)
{
	int err;

	err = spu2_cipher_mode_xlate(cipher_mode, spu2_mode);
	if (err) {
		flow_log("Invalid cipher mode %d\n", cipher_mode);
		return err;
	}

	switch (cipher_alg) {
	case CIPHER_ALG_NONE:
		*spu2_type = SPU2_CIPHER_TYPE_NONE;
		break;
	case CIPHER_ALG_RC4:
		/* SPU2 does not support RC4 */
		err = -EINVAL;
		*spu2_type = SPU2_CIPHER_TYPE_NONE;
		break;
	case CIPHER_ALG_DES:
		*spu2_type = SPU2_CIPHER_TYPE_DES;
		break;
	case CIPHER_ALG_3DES:
		*spu2_type = SPU2_CIPHER_TYPE_3DES;
		break;
	case CIPHER_ALG_AES:
		switch (cipher_type) {
		case CIPHER_TYPE_AES128:
			*spu2_type = SPU2_CIPHER_TYPE_AES128;
			break;
		case CIPHER_TYPE_AES192:
			*spu2_type = SPU2_CIPHER_TYPE_AES192;
			break;
		case CIPHER_TYPE_AES256:
			*spu2_type = SPU2_CIPHER_TYPE_AES256;
			break;
		default:
			err = -EINVAL;
		}
		break;
	case CIPHER_ALG_LAST:
	default:
		err = -EINVAL;
		break;
	}

	if (err)
		flow_log("Invalid cipher alg %d or type %d\n",
			 cipher_alg, cipher_type);
	return err;
}

/*
 * Convert from a software hash mode value to the corresponding value
 * for SPU2. Note that HASH_MODE_NONE and HASH_MODE_XCBC have the same value.
 */
static int spu2_hash_mode_xlate(enum hash_mode hash_mode,
				enum spu2_hash_mode *spu2_mode)
{
	switch (hash_mode) {
	case HASH_MODE_XCBC:
		*spu2_mode = SPU2_HASH_MODE_XCBC_MAC;
		break;
	case HASH_MODE_CMAC:
		*spu2_mode = SPU2_HASH_MODE_CMAC;
		break;
	case HASH_MODE_HMAC:
		*spu2_mode = SPU2_HASH_MODE_HMAC;
		break;
	case HASH_MODE_CCM:
		*spu2_mode = SPU2_HASH_MODE_CCM;
		break;
	case HASH_MODE_GCM:
		*spu2_mode = SPU2_HASH_MODE_GCM;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

/**
 * spu2_hash_xlate() - Convert a hash {alg/mode/type} triple to a SPU2 hash type
 * and mode.
 * @hash_alg:  [in] hash algorithm value from software enumeration
 * @hash_mode: [in] hash mode value from software enumeration
 * @hash_type: [in] hash type value from software enumeration
 * @ciph_type: [in] cipher type value from software enumeration
 * @spu2_type: [out] hash type value used by SPU2 hardware
 * @spu2_mode: [out] hash mode value used by SPU2 hardware
 *
 * Return:  0 if successful
 */
static int
spu2_hash_xlate(enum hash_alg hash_alg, enum hash_mode hash_mode,
		enum hash_type hash_type, enum spu_cipher_type ciph_type,
		enum spu2_hash_type *spu2_type, enum spu2_hash_mode *spu2_mode)
{
	int err;

	err = spu2_hash_mode_xlate(hash_mode, spu2_mode);
	if (err) {
		flow_log("Invalid hash mode %d\n", hash_mode);
		return err;
	}

	switch (hash_alg) {
	case HASH_ALG_NONE:
		*spu2_type = SPU2_HASH_TYPE_NONE;
		break;
	case HASH_ALG_MD5:
		*spu2_type = SPU2_HASH_TYPE_MD5;
		break;
	case HASH_ALG_SHA1:
		*spu2_type = SPU2_HASH_TYPE_SHA1;
		break;
	case HASH_ALG_SHA224:
		*spu2_type = SPU2_HASH_TYPE_SHA224;
		break;
	case HASH_ALG_SHA256:
		*spu2_type = SPU2_HASH_TYPE_SHA256;
		break;
	case HASH_ALG_SHA384:
		*spu2_type = SPU2_HASH_TYPE_SHA384;
		break;
	case HASH_ALG_SHA512:
		*spu2_type = SPU2_HASH_TYPE_SHA512;
		break;
	case HASH_ALG_AES:
		switch (ciph_type) {
		case CIPHER_TYPE_AES128:
			*spu2_type = SPU2_HASH_TYPE_AES128;
			break;
		case CIPHER_TYPE_AES192:
			*spu2_type = SPU2_HASH_TYPE_AES192;
			break;
		case CIPHER_TYPE_AES256:
			*spu2_type = SPU2_HASH_TYPE_AES256;
			break;
		default:
			err = -EINVAL;
		}
		break;
	case HASH_ALG_SHA3_224:
		*spu2_type = SPU2_HASH_TYPE_SHA3_224;
		break;
	case HASH_ALG_SHA3_256:
		*spu2_type = SPU2_HASH_TYPE_SHA3_256;
		break;
	case HASH_ALG_SHA3_384:
		*spu2_type = SPU2_HASH_TYPE_SHA3_384;
		break;
	case HASH_ALG_SHA3_512:
		*spu2_type = SPU2_HASH_TYPE_SHA3_512;
		break;
	case HASH_ALG_LAST:
	default:
		err = -EINVAL;
		break;
	}

	if (err)
		flow_log("Invalid hash alg %d or type %d\n",
			 hash_alg, hash_type);
	return err;
}

/* Dump FMD ctrl0. The ctrl0 input is in host byte order */
static void spu2_dump_fmd_ctrl0(u64 ctrl0)
{
	enum spu2_cipher_type ciph_type;
	enum spu2_cipher_mode ciph_mode;
	enum spu2_hash_type hash_type;
	enum spu2_hash_mode hash_mode;
	char *ciph_name;
	char *ciph_mode_name;
	char *hash_name;
	char *hash_mode_name;
	u8 cfb;
	u8 proto;

	packet_log(" FMD CTRL0 %#16llx\n", ctrl0);
	if (ctrl0 & SPU2_CIPH_ENCRYPT_EN)
		packet_log("  encrypt\n");
	else
		packet_log("  decrypt\n");

	ciph_type = (ctrl0 & SPU2_CIPH_TYPE) >> SPU2_CIPH_TYPE_SHIFT;
	ciph_name = spu2_ciph_type_name(ciph_type);
	packet_log("  Cipher type: %s\n", ciph_name);

	if (ciph_type != SPU2_CIPHER_TYPE_NONE) {
		ciph_mode = (ctrl0 & SPU2_CIPH_MODE) >> SPU2_CIPH_MODE_SHIFT;
		ciph_mode_name = spu2_ciph_mode_name(ciph_mode);
		packet_log("  Cipher mode: %s\n", ciph_mode_name);
	}

	cfb = (ctrl0 & SPU2_CFB_MASK) >> SPU2_CFB_MASK_SHIFT;
	packet_log("  CFB %#x\n", cfb);

	proto = (ctrl0 & SPU2_PROTO_SEL) >> SPU2_PROTO_SEL_SHIFT;
	packet_log("  protocol %#x\n", proto);

	if (ctrl0 & SPU2_HASH_FIRST)
		packet_log("  hash first\n");
	else
		packet_log("  cipher first\n");

	if (ctrl0 & SPU2_CHK_TAG)
		packet_log("  check tag\n");

	hash_type = (ctrl0 & SPU2_HASH_TYPE) >> SPU2_HASH_TYPE_SHIFT;
	hash_name = spu2_hash_type_name(hash_type);
	packet_log("  Hash type: %s\n", hash_name);

	if (hash_type != SPU2_HASH_TYPE_NONE) {
		hash_mode = (ctrl0 & SPU2_HASH_MODE) >> SPU2_HASH_MODE_SHIFT;
		hash_mode_name = spu2_hash_mode_name(hash_mode);
		packet_log("  Hash mode: %s\n", hash_mode_name);
	}

	if (ctrl0 & SPU2_CIPH_PAD_EN) {
		packet_log("  Cipher pad: %#2llx\n",
			   (ctrl0 & SPU2_CIPH_PAD) >> SPU2_CIPH_PAD_SHIFT);
	}
}

/* Dump FMD ctrl1. The ctrl1 input is in host byte order */
static void spu2_dump_fmd_ctrl1(u64 ctrl1)
{
	u8 hash_key_len;
	u8 ciph_key_len;
	u8 ret_iv_len;
	u8 iv_offset;
	u8 iv_len;
	u8 hash_tag_len;
	u8 ret_md;

	packet_log(" FMD CTRL1 %#16llx\n", ctrl1);
	if (ctrl1 & SPU2_TAG_LOC)
		packet_log("  Tag after payload\n");

	packet_log("  Msg includes ");
	if (ctrl1 & SPU2_HAS_FR_DATA)
		packet_log("FD ");
	if (ctrl1 & SPU2_HAS_AAD1)
		packet_log("AAD1 ");
	if (ctrl1 & SPU2_HAS_NAAD)
		packet_log("NAAD ");
	if (ctrl1 & SPU2_HAS_AAD2)
		packet_log("AAD2 ");
	if (ctrl1 & SPU2_HAS_ESN)
		packet_log("ESN ");
	packet_log("\n");

	hash_key_len = (ctrl1 & SPU2_HASH_KEY_LEN) >> SPU2_HASH_KEY_LEN_SHIFT;
	packet_log("  Hash key len %u\n", hash_key_len);

	ciph_key_len = (ctrl1 & SPU2_CIPH_KEY_LEN) >> SPU2_CIPH_KEY_LEN_SHIFT;
	packet_log("  Cipher key len %u\n", ciph_key_len);

	if (ctrl1 & SPU2_GENIV)
		packet_log("  Generate IV\n");

	if (ctrl1 & SPU2_HASH_IV)
		packet_log("  IV included in hash\n");

	if (ctrl1 & SPU2_RET_IV)
		packet_log("  Return IV in output before payload\n");

	ret_iv_len = (ctrl1 & SPU2_RET_IV_LEN) >> SPU2_RET_IV_LEN_SHIFT;
	packet_log("  Length of returned IV %u bytes\n",
		   ret_iv_len ? ret_iv_len : 16);

	iv_offset = (ctrl1 & SPU2_IV_OFFSET) >> SPU2_IV_OFFSET_SHIFT;
	packet_log("  IV offset %u\n", iv_offset);

	iv_len = (ctrl1 & SPU2_IV_LEN) >> SPU2_IV_LEN_SHIFT;
	packet_log("  Input IV len %u bytes\n", iv_len);

	hash_tag_len = (ctrl1 & SPU2_HASH_TAG_LEN) >> SPU2_HASH_TAG_LEN_SHIFT;
	packet_log("  Hash tag length %u bytes\n", hash_tag_len);

	packet_log("  Return ");
	ret_md = (ctrl1 & SPU2_RETURN_MD) >> SPU2_RETURN_MD_SHIFT;
	if (ret_md)
		packet_log("FMD ");
	if (ret_md == SPU2_RET_FMD_OMD)
		packet_log("OMD ");
	else if (ret_md == SPU2_RET_FMD_OMD_IV)
		packet_log("OMD IV ");
	if (ctrl1 & SPU2_RETURN_FD)
		packet_log("FD ");
	if (ctrl1 & SPU2_RETURN_AAD1)
		packet_log("AAD1 ");
	if (ctrl1 & SPU2_RETURN_NAAD)
		packet_log("NAAD ");
	if (ctrl1 & SPU2_RETURN_AAD2)
		packet_log("AAD2 ");
	if (ctrl1 & SPU2_RETURN_PAY)
		packet_log("Payload");
	packet_log("\n");
}

/* Dump FMD ctrl2. The ctrl2 input is in host byte order */
static void spu2_dump_fmd_ctrl2(u64 ctrl2)
{
	packet_log(" FMD CTRL2 %#16llx\n", ctrl2);

	packet_log("  AAD1 offset %llu length %llu bytes\n",
		   ctrl2 & SPU2_AAD1_OFFSET,
		   (ctrl2 & SPU2_AAD1_LEN) >> SPU2_AAD1_LEN_SHIFT);
	packet_log("  AAD2 offset %llu\n",
		   (ctrl2 & SPU2_AAD2_OFFSET) >> SPU2_AAD2_OFFSET_SHIFT);
	packet_log("  Payload offset %llu\n",
		   (ctrl2 & SPU2_PL_OFFSET) >> SPU2_PL_OFFSET_SHIFT);
}

/* Dump FMD ctrl3. The ctrl3 input is in host byte order */
static void spu2_dump_fmd_ctrl3(u64 ctrl3)
{
	packet_log(" FMD CTRL3 %#16llx\n", ctrl3);

	packet_log("  Payload length %llu bytes\n", ctrl3 & SPU2_PL_LEN);
	packet_log("  TLS length %llu bytes\n",
		   (ctrl3 & SPU2_TLS_LEN) >> SPU2_TLS_LEN_SHIFT);
}

static void spu2_dump_fmd(struct SPU2_FMD *fmd)
{
	spu2_dump_fmd_ctrl0(le64_to_cpu(fmd->ctrl0));
	spu2_dump_fmd_ctrl1(le64_to_cpu(fmd->ctrl1));
	spu2_dump_fmd_ctrl2(le64_to_cpu(fmd->ctrl2));
	spu2_dump_fmd_ctrl3(le64_to_cpu(fmd->ctrl3));
}

static void spu2_dump_omd(u8 *omd, u16 hash_key_len, u16 ciph_key_len,
			  u16 hash_iv_len, u16 ciph_iv_len)
{
	u8 *ptr = omd;

	packet_log(" OMD:\n");

	if (hash_key_len) {
		packet_log("  Hash Key Length %u bytes\n", hash_key_len);
		packet_dump("  KEY: ", ptr, hash_key_len);
		ptr += hash_key_len;
	}

	if (ciph_key_len) {
		packet_log("  Cipher Key Length %u bytes\n", ciph_key_len);
		packet_dump("  KEY: ", ptr, ciph_key_len);
		ptr += ciph_key_len;
	}

	if (hash_iv_len) {
		packet_log("  Hash IV Length %u bytes\n", hash_iv_len);
		packet_dump("  hash IV: ", ptr, hash_iv_len);
		ptr += ciph_key_len;
	}

	if (ciph_iv_len) {
		packet_log("  Cipher IV Length %u bytes\n", ciph_iv_len);
		packet_dump("  cipher IV: ", ptr, ciph_iv_len);
	}
}

/* Dump a SPU2 header for debug */
void spu2_dump_msg_hdr(u8 *buf, unsigned int buf_len)
{
	struct SPU2_FMD *fmd = (struct SPU2_FMD *)buf;
	u8 *omd;
	u64 ctrl1;
	u16 hash_key_len;
	u16 ciph_key_len;
	u16 hash_iv_len;
	u16 ciph_iv_len;
	u16 omd_len;

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

	spu2_dump_fmd(fmd);
	omd = (u8 *)(fmd + 1);

	ctrl1 = le64_to_cpu(fmd->ctrl1);
	hash_key_len = (ctrl1 & SPU2_HASH_KEY_LEN) >> SPU2_HASH_KEY_LEN_SHIFT;
	ciph_key_len = (ctrl1 & SPU2_CIPH_KEY_LEN) >> SPU2_CIPH_KEY_LEN_SHIFT;
	hash_iv_len = 0;
	ciph_iv_len = (ctrl1 & SPU2_IV_LEN) >> SPU2_IV_LEN_SHIFT;
	spu2_dump_omd(omd, hash_key_len, ciph_key_len, hash_iv_len,
		      ciph_iv_len);

	/* Double check sanity */
	omd_len = hash_key_len + ciph_key_len + hash_iv_len + ciph_iv_len;
	if (FMD_SIZE + omd_len != buf_len) {
		packet_log
		    (" Packet parsed incorrectly. buf_len %u, sum of MD %zu\n",
		     buf_len, FMD_SIZE + omd_len);
	}
	packet_log("\n");
}

/**
 * spu2_fmd_init() - At setkey time, initialize the fixed meta data for
 * subsequent skcipher requests for this context.
 * @spu2_cipher_type:  Cipher algorithm
 * @spu2_mode:         Cipher mode
 * @cipher_key_len:    Length of cipher key, in bytes
 * @cipher_iv_len:     Length of cipher initialization vector, in bytes
 *
 * Return:  0 (success)
 */
static int spu2_fmd_init(struct SPU2_FMD *fmd,
			 enum spu2_cipher_type spu2_type,
			 enum spu2_cipher_mode spu2_mode,
			 u32 cipher_key_len, u32 cipher_iv_len)
{
	u64 ctrl0;
	u64 ctrl1;
	u64 ctrl2;
	u64 ctrl3;
	u32 aad1_offset;
	u32 aad2_offset;
	u16 aad1_len = 0;
	u64 payload_offset;

	ctrl0 = (spu2_type << SPU2_CIPH_TYPE_SHIFT) |
	    (spu2_mode << SPU2_CIPH_MODE_SHIFT);

	ctrl1 = (cipher_key_len << SPU2_CIPH_KEY_LEN_SHIFT) |
	    ((u64)cipher_iv_len << SPU2_IV_LEN_SHIFT) |
	    ((u64)SPU2_RET_FMD_ONLY << SPU2_RETURN_MD_SHIFT) | SPU2_RETURN_PAY;

	/*
	 * AAD1 offset is from start of FD. FD length is always 0 for this
	 * driver. So AAD1_offset is always 0.
	 */
	aad1_offset = 0;
	aad2_offset = aad1_offset;
	payload_offset = 0;
	ctrl2 = aad1_offset |
	    (aad1_len << SPU2_AAD1_LEN_SHIFT) |
	    (aad2_offset << SPU2_AAD2_OFFSET_SHIFT) |
	    (payload_offset << SPU2_PL_OFFSET_SHIFT);

	ctrl3 = 0;

	fmd->ctrl0 = cpu_to_le64(ctrl0);
	fmd->ctrl1 = cpu_to_le64(ctrl1);
	fmd->ctrl2 = cpu_to_le64(ctrl2);
	fmd->ctrl3 = cpu_to_le64(ctrl3);

	return 0;
}

/**
 * spu2_fmd_ctrl0_write() - Write ctrl0 field in fixed metadata (FMD) field of
 * SPU request packet.
 * @fmd:            Start of FMD field to be written
 * @is_inbound:     true if decrypting. false if encrypting.
 * @authFirst:      true if alg authenticates before encrypting
 * @protocol:       protocol selector
 * @cipher_type:    cipher algorithm
 * @cipher_mode:    cipher mode
 * @auth_type:      authentication type
 * @auth_mode:      authentication mode
 */
static void spu2_fmd_ctrl0_write(struct SPU2_FMD *fmd,
				 bool is_inbound, bool auth_first,
				 enum spu2_proto_sel protocol,
				 enum spu2_cipher_type cipher_type,
				 enum spu2_cipher_mode cipher_mode,
				 enum spu2_hash_type auth_type,
				 enum spu2_hash_mode auth_mode)
{
	u64 ctrl0 = 0;

	if ((cipher_type != SPU2_CIPHER_TYPE_NONE) && !is_inbound)
		ctrl0 |= SPU2_CIPH_ENCRYPT_EN;

	ctrl0 |= ((u64)cipher_type << SPU2_CIPH_TYPE_SHIFT) |
	    ((u64)cipher_mode << SPU2_CIPH_MODE_SHIFT);

	if (protocol)
		ctrl0 |= (u64)protocol << SPU2_PROTO_SEL_SHIFT;

	if (auth_first)
		ctrl0 |= SPU2_HASH_FIRST;

	if (is_inbound && (auth_type != SPU2_HASH_TYPE_NONE))
		ctrl0 |= SPU2_CHK_TAG;

	ctrl0 |= (((u64)auth_type << SPU2_HASH_TYPE_SHIFT) |
		  ((u64)auth_mode << SPU2_HASH_MODE_SHIFT));

	fmd->ctrl0 = cpu_to_le64(ctrl0);
}

/**
 * spu2_fmd_ctrl1_write() - Write ctrl1 field in fixed metadata (FMD) field of
 * SPU request packet.
 * @fmd:            Start of FMD field to be written
 * @assoc_size:     Length of additional associated data, in bytes
 * @auth_key_len:   Length of authentication key, in bytes
 * @cipher_key_len: Length of cipher key, in bytes
 * @gen_iv:         If true, hw generates IV and returns in response
 * @hash_iv:        IV participates in hash. Used for IPSEC and TLS.
 * @return_iv:      Return IV in output packet before payload
 * @ret_iv_len:     Length of IV returned from SPU, in bytes
 * @ret_iv_offset:  Offset into full IV of start of returned IV
 * @cipher_iv_len:  Length of input cipher IV, in bytes
 * @digest_size:    Length of digest (aka, hash tag or ICV), in bytes
 * @return_payload: Return payload in SPU response
 * @return_md : return metadata in SPU response
 *
 * Packet can have AAD2 w/o AAD1. For algorithms currently supported,
 * associated data goes in AAD2.
 */
static void spu2_fmd_ctrl1_write(struct SPU2_FMD *fmd, bool is_inbound,
				 u64 assoc_size,
				 u64 auth_key_len, u64 cipher_key_len,
				 bool gen_iv, bool hash_iv, bool return_iv,
				 u64 ret_iv_len, u64 ret_iv_offset,
				 u64 cipher_iv_len, u64 digest_size,
				 bool return_payload, bool return_md)
{
	u64 ctrl1 = 0;

	if (is_inbound && digest_size)
		ctrl1 |= SPU2_TAG_LOC;

	if (assoc_size) {
		ctrl1 |= SPU2_HAS_AAD2;
		ctrl1 |= SPU2_RETURN_AAD2;  /* need aad2 for gcm aes esp */
	}

	if (auth_key_len)
		ctrl1 |= ((auth_key_len << SPU2_HASH_KEY_LEN_SHIFT) &
			  SPU2_HASH_KEY_LEN);

	if (cipher_key_len)
		ctrl1 |= ((cipher_key_len << SPU2_CIPH_KEY_LEN_SHIFT) &
			  SPU2_CIPH_KEY_LEN);

	if (gen_iv)
		ctrl1 |= SPU2_GENIV;

	if (hash_iv)
		ctrl1 |= SPU2_HASH_IV;

	if (return_iv) {
		ctrl1 |= SPU2_RET_IV;
		ctrl1 |= ret_iv_len << SPU2_RET_IV_LEN_SHIFT;
		ctrl1 |= ret_iv_offset << SPU2_IV_OFFSET_SHIFT;
	}

	ctrl1 |= ((cipher_iv_len << SPU2_IV_LEN_SHIFT) & SPU2_IV_LEN);

	if (digest_size)
		ctrl1 |= ((digest_size << SPU2_HASH_TAG_LEN_SHIFT) &
			  SPU2_HASH_TAG_LEN);

	/* Let's ask for the output pkt to include FMD, but don't need to
	 * get keys and IVs back in OMD.
	 */
	if (return_md)
		ctrl1 |= ((u64)SPU2_RET_FMD_ONLY << SPU2_RETURN_MD_SHIFT);
	else
		ctrl1 |= ((u64)SPU2_RET_NO_MD << SPU2_RETURN_MD_SHIFT);

	/* Crypto API does not get assoc data back. So no need for AAD2. */

	if (return_payload)
		ctrl1 |= SPU2_RETURN_PAY;

	fmd->ctrl1 = cpu_to_le64(ctrl1);
}

/**
 * spu2_fmd_ctrl2_write() - Set the ctrl2 field in the fixed metadata field of
 * SPU2 header.
 * @fmd:            Start of FMD field to be written
 * @cipher_offset:  Number of bytes from Start of Packet (end of FD field) where
 *                  data to be encrypted or decrypted begins
 * @auth_key_len:   Length of authentication key, in bytes
 * @auth_iv_len:    Length of authentication initialization vector, in bytes
 * @cipher_key_len: Length of cipher key, in bytes
 * @cipher_iv_len:  Length of cipher IV, in bytes
 */
static void spu2_fmd_ctrl2_write(struct SPU2_FMD *fmd, u64 cipher_offset,
				 u64 auth_key_len, u64 auth_iv_len,
				 u64 cipher_key_len, u64 cipher_iv_len)
{
	u64 ctrl2;
	u64 aad1_offset;
	u64 aad2_offset;
	u16 aad1_len = 0;
	u64 payload_offset;

	/* AAD1 offset is from start of FD. FD length always 0. */
	aad1_offset = 0;

	aad2_offset = aad1_offset;
	payload_offset = cipher_offset;
	ctrl2 = aad1_offset |
	    (aad1_len << SPU2_AAD1_LEN_SHIFT) |
	    (aad2_offset << SPU2_AAD2_OFFSET_SHIFT) |
	    (payload_offset << SPU2_PL_OFFSET_SHIFT);

	fmd->ctrl2 = cpu_to_le64(ctrl2);
}

/**
 * spu2_fmd_ctrl3_write() - Set the ctrl3 field in FMD
 * @fmd:          Fixed meta data. First field in SPU2 msg header.
 * @payload_len:  Length of payload, in bytes
 */
static void spu2_fmd_ctrl3_write(struct SPU2_FMD *fmd, u64 payload_len)
{
	u64 ctrl3;

	ctrl3 = payload_len & SPU2_PL_LEN;

	fmd->ctrl3 = cpu_to_le64(ctrl3);
}

/**
 * spu2_ctx_max_payload() - Determine the maximum 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
 *
 * For SPU2, the hardware generally ignores the PayloadLen field in ctrl3 of
 * FMD and just keeps computing until it receives a DMA descriptor with the EOF
 * flag set. So we consider the max payload to be infinite. AES CCM is an
 * exception.
 *
 * Return: Max payload length in bytes
 */
u32 spu2_ctx_max_payload(enum spu_cipher_alg cipher_alg,
			 enum spu_cipher_mode cipher_mode,
			 unsigned int blocksize)
{
	if ((cipher_alg == CIPHER_ALG_AES) &&
	    (cipher_mode == CIPHER_MODE_CCM)) {
		u32 excess = SPU2_MAX_PAYLOAD % blocksize;

		return SPU2_MAX_PAYLOAD - excess;
	} else {
		return SPU_MAX_PAYLOAD_INF;
	}
}

/**
 * spu_payload_length() -  Given a SPU2 message header, extract the payload
 * length.
 * @spu_hdr:  Start of SPU message header (FMD)
 *
 * Return: payload length, in bytes
 */
u32 spu2_payload_length(u8 *spu_hdr)
{
	struct SPU2_FMD *fmd = (struct SPU2_FMD *)spu_hdr;
	u32 pl_len;
	u64 ctrl3;

	ctrl3 = le64_to_cpu(fmd->ctrl3);
	pl_len = ctrl3 & SPU2_PL_LEN;

	return pl_len;
}

/**
 * spu_response_hdr_len() - Determine the expected length of a SPU response
 * header.
 * @auth_key_len:  Length of authentication key, in bytes
 * @enc_key_len:   Length of encryption key, in bytes
 *
 * For SPU2, includes just FMD. OMD is never requested.
 *
 * Return: Length of FMD, in bytes
 */
u16 spu2_response_hdr_len(u16 auth_key_len, u16 enc_key_len, bool is_hash)
{
	return FMD_SIZE;
}

/**
 * spu_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 hash block, in bytes
 *
 * SPU2 hardware does all hash padding
 *
 * Return:  length of hash pad in bytes
 */
u16 spu2_hash_pad_len(enum hash_alg hash_alg, enum hash_mode hash_mode,
		      u32 chunksize, u16 hash_block_size)
{
	return 0;
}

/**
 * spu2_gcm_ccm_padlen() -  Determine the length of GCM/CCM padding for either
 * the AAD field or the data.
 *
 * Return:  0. Unlike SPU-M, SPU2 hardware does any GCM/CCM padding required.
 */
u32 spu2_gcm_ccm_pad_len(enum spu_cipher_mode cipher_mode,
			 unsigned int data_size)
{
	return 0;
}

/**
 * spu_assoc_resp_len() - Determine the size of the AAD2 buffer needed to catch
 * associated data in a SPU2 output packet.
 * @cipher_mode:   cipher mode
 * @assoc_len:     length of additional associated data, in bytes
 * @iv_len:        length of initialization vector, in bytes
 * @is_encrypt:    true if encrypting. false if decrypt.
 *
 * Return: Length of buffer to catch associated data in response
 */
u32 spu2_assoc_resp_len(enum spu_cipher_mode cipher_mode,
			unsigned int assoc_len, unsigned int iv_len,
			bool is_encrypt)
{
	u32 resp_len = assoc_len;

	if (is_encrypt)
		/* gcm aes esp has to write 8-byte IV in response */
		resp_len += iv_len;
	return resp_len;
}

/*
 * spu_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_ctr_len:   initialization vector length in bytes
 *
 * For SPU2, AEAD IV is included in OMD and does not need to be repeated
 * prior to the payload.
 *
 * Return: Length of AEAD IV in bytes
 */
u8 spu2_aead_ivlen(enum spu_cipher_mode cipher_mode, u16 iv_len)
{
	return 0;
}

/**
 * spu2_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.
 *
 * SPU2 always does a FULL hash operation
 */
enum hash_type spu2_hash_type(u32 src_sent)
{
	return HASH_TYPE_FULL;
}

/**
 * spu2_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)
 *
 */
u32 spu2_digest_size(u32 alg_digest_size, enum hash_alg alg,
		     enum hash_type htype)
{
	return alg_digest_size;
}

/**
 * spu_create_request() - Build a SPU2 request message header, includint FMD and
 * OMD.
 * @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.
 *
 * 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.
 */
u32 spu2_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 SPU2_FMD *fmd;
	u8 *ptr;
	unsigned int buf_len;
	int err;
	enum spu2_cipher_type spu2_ciph_type = SPU2_CIPHER_TYPE_NONE;
	enum spu2_cipher_mode spu2_ciph_mode;
	enum spu2_hash_type spu2_auth_type = SPU2_HASH_TYPE_NONE;
	enum spu2_hash_mode spu2_auth_mode;
	bool return_md = true;
	enum spu2_proto_sel proto = SPU2_PROTO_RESV;

	/* size of the payload */
	unsigned int payload_len =
	    hash_parms->prebuf_len + data_size + hash_parms->pad_len -
	    ((req_opts->is_aead && req_opts->is_inbound) ?
	     hash_parms->digestsize : 0);

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

	/* total size of the data following OMD (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 assoc_size = aead_parms->assoc_size;

	if (req_opts->is_aead &&
	    (cipher_parms->alg == CIPHER_ALG_AES) &&
	    (cipher_parms->mode == CIPHER_MODE_GCM))
		/*
		 * On SPU 2, aes gcm cipher first on encrypt, auth first on
		 * decrypt
		 */
		req_opts->auth_first = req_opts->is_inbound;

	/* and do opposite for ccm (auth 1st on encrypt) */
	if (req_opts->is_aead &&
	    (cipher_parms->alg == CIPHER_ALG_AES) &&
	    (cipher_parms->mode == CIPHER_MODE_CCM))
		req_opts->auth_first = !req_opts->is_inbound;

	flow_log("%s()\n", __func__);
	flow_log("  in:%u authFirst:%u\n",
		 req_opts->is_inbound, req_opts->auth_first);
	flow_log("  cipher alg:%u mode:%u type %u\n", cipher_parms->alg,
		 cipher_parms->mode, cipher_parms->type);
	flow_log("  is_esp: %s\n", req_opts->is_esp ? "yes" : "no");
	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", 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("  cipher_offset:%u payload_len:%u\n",
		 cipher_offset, payload_len);
	flow_log("  aead_iv: %u\n", aead_parms->iv_len);

	/* Convert to spu2 values for cipher alg, hash alg */
	err = spu2_cipher_xlate(cipher_parms->alg, cipher_parms->mode,
				cipher_parms->type,
				&spu2_ciph_type, &spu2_ciph_mode);

	/* If we are doing GCM hashing only - either via rfc4543 transform
	 * or because we happen to do GCM with AAD only and no payload - we
	 * need to configure hardware to use hash key rather than cipher key
	 * and put data into payload.  This is because unlike SPU-M, running
	 * GCM cipher with 0 size payload is not permitted.
	 */
	if ((req_opts->is_rfc4543) ||
	    ((spu2_ciph_mode == SPU2_CIPHER_MODE_GCM) &&
	    (payload_len == 0))) {
		/* Use hashing (only) and set up hash key */
		spu2_ciph_type = SPU2_CIPHER_TYPE_NONE;
		hash_parms->key_len = cipher_parms->key_len;
		memcpy(hash_parms->key_buf, cipher_parms->key_buf,
		       cipher_parms->key_len);
		cipher_parms->key_len = 0;

		if (req_opts->is_rfc4543)
			payload_len += assoc_size;
		else
			payload_len = assoc_size;
		cipher_offset = 0;
		assoc_size = 0;
	}

	if (err)
		return 0;

	flow_log("spu2 cipher type %s, cipher mode %s\n",
		 spu2_ciph_type_name(spu2_ciph_type),
		 spu2_ciph_mode_name(spu2_ciph_mode));

	err = spu2_hash_xlate(hash_parms->alg, hash_parms->mode,
			      hash_parms->type,
			      cipher_parms->type,
			      &spu2_auth_type, &spu2_auth_mode);
	if (err)
		return 0;

	flow_log("spu2 hash type %s, hash mode %s\n",
		 spu2_hash_type_name(spu2_auth_type),
		 spu2_hash_mode_name(spu2_auth_mode));

	fmd = (struct SPU2_FMD *)spu_hdr;

	spu2_fmd_ctrl0_write(fmd, req_opts->is_inbound, req_opts->auth_first,
			     proto, spu2_ciph_type, spu2_ciph_mode,
			     spu2_auth_type, spu2_auth_mode);

	spu2_fmd_ctrl1_write(fmd, req_opts->is_inbound, assoc_size,
			     hash_parms->key_len, cipher_parms->key_len,
			     false, false,
			     aead_parms->return_iv, aead_parms->ret_iv_len,
			     aead_parms->ret_iv_off,
			     cipher_parms->iv_len, hash_parms->digestsize,
			     !req_opts->bd_suppress, return_md);

	spu2_fmd_ctrl2_write(fmd, cipher_offset, hash_parms->key_len, 0,
			     cipher_parms->key_len, cipher_parms->iv_len);

	spu2_fmd_ctrl3_write(fmd, payload_len);

	ptr = (u8 *)(fmd + 1);
	buf_len = sizeof(struct SPU2_FMD);

	/* Write OMD */
	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;
	}
	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;
	}
	if (cipher_parms->iv_len) {
		memcpy(ptr, cipher_parms->iv_buf, cipher_parms->iv_len);
		ptr += cipher_parms->iv_len;
		buf_len += cipher_parms->iv_len;
	}

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

	return buf_len;
}

/**
 * spu_cipher_req_init() - Build an skcipher SPU2 request message header,
 * including FMD and OMD.
 * @spu_hdr:       Location of start of SPU request (FMD field)
 * @cipher_parms:  Parameters describing cipher request
 *
 * Called at setkey time to initialize a msg header that can be reused for all
 * subsequent skcipher requests. 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 total length of the SPU header (FMD and OMD) in bytes. 0 if an
 * error occurs.
 */
u16 spu2_cipher_req_init(u8 *spu_hdr, struct spu_cipher_parms *cipher_parms)
{
	struct SPU2_FMD *fmd;
	u8 *omd;
	enum spu2_cipher_type spu2_type = SPU2_CIPHER_TYPE_NONE;
	enum spu2_cipher_mode spu2_mode;
	int err;

	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);

	/* Convert to spu2 values */
	err = spu2_cipher_xlate(cipher_parms->alg, cipher_parms->mode,
				cipher_parms->type, &spu2_type, &spu2_mode);
	if (err)
		return 0;

	flow_log("spu2 cipher type %s, cipher mode %s\n",
		 spu2_ciph_type_name(spu2_type),
		 spu2_ciph_mode_name(spu2_mode));

	/* Construct the FMD header */
	fmd = (struct SPU2_FMD *)spu_hdr;
	err = spu2_fmd_init(fmd, spu2_type, spu2_mode, cipher_parms->key_len,
			    cipher_parms->iv_len);
	if (err)
		return 0;

	/* Write cipher key to OMD */
	omd = (u8 *)(fmd + 1);
	if (cipher_parms->key_buf && cipher_parms->key_len)
		memcpy(omd, cipher_parms->key_buf, cipher_parms->key_len);

	packet_dump("  SPU request header: ", spu_hdr,
		    FMD_SIZE + cipher_parms->key_len + cipher_parms->iv_len);

	return FMD_SIZE + cipher_parms->key_len + cipher_parms->iv_len;
}

/**
 * spu_cipher_req_finish() - Finish building a SPU request message header for a
 * block cipher request.
 * @spu_hdr:         Start of the request message header (MH field)
 * @spu_req_hdr_len: Length in bytes of the SPU request header
 * @isInbound:       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
 * spu_cipher_req_init().
 * spu_cipher_req_init() fills in the encryption key.
 */
void spu2_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 SPU2_FMD *fmd;
	u8 *omd;		/* start of optional metadata */
	u64 ctrl0;
	u64 ctrl3;

	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);
	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);

	fmd = (struct SPU2_FMD *)spu_hdr;
	omd = (u8 *)(fmd + 1);

	/*
	 * FMD ctrl0 was initialized at setkey time. update it to indicate
	 * whether we are encrypting or decrypting.
	 */
	ctrl0 = le64_to_cpu(fmd->ctrl0);
	if (is_inbound)
		ctrl0 &= ~SPU2_CIPH_ENCRYPT_EN;	/* decrypt */
	else
		ctrl0 |= SPU2_CIPH_ENCRYPT_EN;	/* encrypt */
	fmd->ctrl0 = cpu_to_le64(ctrl0);

	if (cipher_parms->alg && cipher_parms->iv_buf && cipher_parms->iv_len) {
		/* cipher iv provided so put it in here */
		memcpy(omd + cipher_parms->key_len, cipher_parms->iv_buf,
		       cipher_parms->iv_len);
	}

	ctrl3 = le64_to_cpu(fmd->ctrl3);
	data_size &= SPU2_PL_LEN;
	ctrl3 |= data_size;
	fmd->ctrl3 = cpu_to_le64(ctrl3);

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

/**
 * spu_request_pad() - Create pad bytes at the end of the data.
 * @pad_start:      Start of buffer where pad bytes are to be written
 * @gcm_padding:    Length of GCM 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 pad - for GCM 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 spu2_request_pad(u8 *pad_start, u32 gcm_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 */
	if (gcm_padding > 0) {
		flow_log("  GCM: padding to 16 byte alignment: %u bytes\n",
			 gcm_padding);
		memset(ptr, 0, gcm_padding);
		ptr += gcm_padding;
	}

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

		/* 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;
	}
}

/**
 * spu2_xts_tweak_in_payload() - Indicate that SPU2 does NOT place the XTS
 * tweak field in the packet payload (it uses IV instead)
 *
 * Return: 0
 */
u8 spu2_xts_tweak_in_payload(void)
{
	return 0;
}

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

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

/**
 * spu_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 spu2_status_process(u8 *statp)
{
	/* SPU2 status is 2 bytes by default - SPU_RX_STATUS_LEN */
	u16 status = le16_to_cpu(*(__le16 *)statp);

	if (status == 0)
		return 0;

	flow_log("rx status is %#x\n", status);
	if (status == SPU2_INVALID_ICV)
		return SPU_INVALID_ICV;

	return -EBADMSG;
}

/**
 * spu2_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 spu2_ccm_update_iv(unsigned int digestsize,
			struct spu_cipher_parms *cipher_parms,
			unsigned int assoclen, unsigned int chunksize,
			bool is_encrypt, bool is_esp)
{
	int L;  /* size of length field, in bytes */

	/*
	 * In RFC4309 mode, L is fixed at 4 bytes; otherwise, IV from
	 * testmgr contains (L-1) in bottom 3 bits of first byte,
	 * per RFC 3610.
	 */
	if (is_esp)
		L = CCM_ESP_L_VALUE;
	else
		L = ((cipher_parms->iv_buf[0] & CCM_B0_L_PRIME) >>
		      CCM_B0_L_PRIME_SHIFT) + 1;

	/* SPU2 doesn't want these length bytes nor the first byte... */
	cipher_parms->iv_len -= (1 + L);
	memmove(cipher_parms->iv_buf, &cipher_parms->iv_buf[1],
		cipher_parms->iv_len);
}

/**
 * spu2_wordalign_padlen() - SPU2 does not require padding.
 * @data_size: length of data field in bytes
 *
 * Return: length of status field padding, in bytes (always 0 on SPU2)
 */
u32 spu2_wordalign_padlen(u32 data_size)
{
	return 0;
}
