brintos

brintos / linux-shallow public Read only

0
0
Text · 103.3 KiB · 919e5a2 Raw
3612 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (C) 2017 Marvell4 *5 * Antoine Tenart <antoine.tenart@free-electrons.com>6 */7 8#include <linux/unaligned.h>9#include <linux/device.h>10#include <linux/dma-mapping.h>11#include <linux/dmapool.h>12#include <crypto/aead.h>13#include <crypto/aes.h>14#include <crypto/authenc.h>15#include <crypto/chacha.h>16#include <crypto/ctr.h>17#include <crypto/internal/des.h>18#include <crypto/gcm.h>19#include <crypto/ghash.h>20#include <crypto/poly1305.h>21#include <crypto/sha1.h>22#include <crypto/sha2.h>23#include <crypto/sm3.h>24#include <crypto/sm4.h>25#include <crypto/xts.h>26#include <crypto/skcipher.h>27#include <crypto/internal/aead.h>28#include <crypto/internal/skcipher.h>29 30#include "safexcel.h"31 32enum safexcel_cipher_direction {33	SAFEXCEL_ENCRYPT,34	SAFEXCEL_DECRYPT,35};36 37enum safexcel_cipher_alg {38	SAFEXCEL_DES,39	SAFEXCEL_3DES,40	SAFEXCEL_AES,41	SAFEXCEL_CHACHA20,42	SAFEXCEL_SM4,43};44 45struct safexcel_cipher_ctx {46	struct safexcel_context base;47	struct safexcel_crypto_priv *priv;48 49	u32 mode;50	enum safexcel_cipher_alg alg;51	u8 aead; /* !=0=AEAD, 2=IPSec ESP AEAD, 3=IPsec ESP GMAC */52	u8 xcm;  /* 0=authenc, 1=GCM, 2 reserved for CCM */53	u8 aadskip;54	u8 blocksz;55	u32 ivmask;56	u32 ctrinit;57 58	__le32 key[16];59	u32 nonce;60	unsigned int key_len, xts;61 62	/* All the below is AEAD specific */63	u32 hash_alg;64	u32 state_sz;65 66	struct crypto_aead *fback;67};68 69struct safexcel_cipher_req {70	enum safexcel_cipher_direction direction;71	/* Number of result descriptors associated to the request */72	unsigned int rdescs;73	bool needs_inv;74	int  nr_src, nr_dst;75};76 77static int safexcel_skcipher_iv(struct safexcel_cipher_ctx *ctx, u8 *iv,78				struct safexcel_command_desc *cdesc)79{80	if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) {81		cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;82		/* 32 bit nonce */83		cdesc->control_data.token[0] = ctx->nonce;84		/* 64 bit IV part */85		memcpy(&cdesc->control_data.token[1], iv, 8);86		/* 32 bit counter, start at 0 or 1 (big endian!) */87		cdesc->control_data.token[3] =88			(__force u32)cpu_to_be32(ctx->ctrinit);89		return 4;90	}91	if (ctx->alg == SAFEXCEL_CHACHA20) {92		cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;93		/* 96 bit nonce part */94		memcpy(&cdesc->control_data.token[0], &iv[4], 12);95		/* 32 bit counter */96		cdesc->control_data.token[3] = *(u32 *)iv;97		return 4;98	}99 100	cdesc->control_data.options |= ctx->ivmask;101	memcpy(cdesc->control_data.token, iv, ctx->blocksz);102	return ctx->blocksz / sizeof(u32);103}104 105static void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv,106				    struct safexcel_command_desc *cdesc,107				    struct safexcel_token *atoken,108				    u32 length)109{110	struct safexcel_token *token;111	int ivlen;112 113	ivlen = safexcel_skcipher_iv(ctx, iv, cdesc);114	if (ivlen == 4) {115		/* No space in cdesc, instruction moves to atoken */116		cdesc->additional_cdata_size = 1;117		token = atoken;118	} else {119		/* Everything fits in cdesc */120		token = (struct safexcel_token *)(cdesc->control_data.token + 2);121		/* Need to pad with NOP */122		eip197_noop_token(&token[1]);123	}124 125	token->opcode = EIP197_TOKEN_OPCODE_DIRECTION;126	token->packet_length = length;127	token->stat = EIP197_TOKEN_STAT_LAST_PACKET |128		      EIP197_TOKEN_STAT_LAST_HASH;129	token->instructions = EIP197_TOKEN_INS_LAST |130			      EIP197_TOKEN_INS_TYPE_CRYPTO |131			      EIP197_TOKEN_INS_TYPE_OUTPUT;132}133 134static void safexcel_aead_iv(struct safexcel_cipher_ctx *ctx, u8 *iv,135			     struct safexcel_command_desc *cdesc)136{137	if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD ||138	    ctx->aead & EIP197_AEAD_TYPE_IPSEC_ESP) { /* _ESP and _ESP_GMAC */139		/* 32 bit nonce */140		cdesc->control_data.token[0] = ctx->nonce;141		/* 64 bit IV part */142		memcpy(&cdesc->control_data.token[1], iv, 8);143		/* 32 bit counter, start at 0 or 1 (big endian!) */144		cdesc->control_data.token[3] =145			(__force u32)cpu_to_be32(ctx->ctrinit);146		return;147	}148	if (ctx->xcm == EIP197_XCM_MODE_GCM || ctx->alg == SAFEXCEL_CHACHA20) {149		/* 96 bit IV part */150		memcpy(&cdesc->control_data.token[0], iv, 12);151		/* 32 bit counter, start at 0 or 1 (big endian!) */152		cdesc->control_data.token[3] =153			(__force u32)cpu_to_be32(ctx->ctrinit);154		return;155	}156	/* CBC */157	memcpy(cdesc->control_data.token, iv, ctx->blocksz);158}159 160static void safexcel_aead_token(struct safexcel_cipher_ctx *ctx, u8 *iv,161				struct safexcel_command_desc *cdesc,162				struct safexcel_token *atoken,163				enum safexcel_cipher_direction direction,164				u32 cryptlen, u32 assoclen, u32 digestsize)165{166	struct safexcel_token *aadref;167	int atoksize = 2; /* Start with minimum size */168	int assocadj = assoclen - ctx->aadskip, aadalign;169 170	/* Always 4 dwords of embedded IV  for AEAD modes */171	cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;172 173	if (direction == SAFEXCEL_DECRYPT)174		cryptlen -= digestsize;175 176	if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM)) {177		/* Construct IV block B0 for the CBC-MAC */178		u8 *final_iv = (u8 *)cdesc->control_data.token;179		u8 *cbcmaciv = (u8 *)&atoken[1];180		__le32 *aadlen = (__le32 *)&atoken[5];181 182		if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {183			/* Length + nonce */184			cdesc->control_data.token[0] = ctx->nonce;185			/* Fixup flags byte */186			*(__le32 *)cbcmaciv =187				cpu_to_le32(ctx->nonce |188					    ((assocadj > 0) << 6) |189					    ((digestsize - 2) << 2));190			/* 64 bit IV part */191			memcpy(&cdesc->control_data.token[1], iv, 8);192			memcpy(cbcmaciv + 4, iv, 8);193			/* Start counter at 0 */194			cdesc->control_data.token[3] = 0;195			/* Message length */196			*(__be32 *)(cbcmaciv + 12) = cpu_to_be32(cryptlen);197		} else {198			/* Variable length IV part */199			memcpy(final_iv, iv, 15 - iv[0]);200			memcpy(cbcmaciv, iv, 15 - iv[0]);201			/* Start variable length counter at 0 */202			memset(final_iv + 15 - iv[0], 0, iv[0] + 1);203			memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1);204			/* fixup flags byte */205			cbcmaciv[0] |= ((assocadj > 0) << 6) |206				       ((digestsize - 2) << 2);207			/* insert lower 2 bytes of message length */208			cbcmaciv[14] = cryptlen >> 8;209			cbcmaciv[15] = cryptlen & 255;210		}211 212		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;213		atoken->packet_length = AES_BLOCK_SIZE +214					((assocadj > 0) << 1);215		atoken->stat = 0;216		atoken->instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN |217				       EIP197_TOKEN_INS_TYPE_HASH;218 219		if (likely(assocadj)) {220			*aadlen = cpu_to_le32((assocadj >> 8) |221					      (assocadj & 255) << 8);222			atoken += 6;223			atoksize += 7;224		} else {225			atoken += 5;226			atoksize += 6;227		}228 229		/* Process AAD data */230		aadref = atoken;231		atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;232		atoken->packet_length = assocadj;233		atoken->stat = 0;234		atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;235		atoken++;236 237		/* For CCM only, align AAD data towards hash engine */238		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;239		aadalign = (assocadj + 2) & 15;240		atoken->packet_length = assocadj && aadalign ?241						16 - aadalign :242						0;243		if (likely(cryptlen)) {244			atoken->stat = 0;245			atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;246		} else {247			atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;248			atoken->instructions = EIP197_TOKEN_INS_LAST |249					       EIP197_TOKEN_INS_TYPE_HASH;250		}251	} else {252		safexcel_aead_iv(ctx, iv, cdesc);253 254		/* Process AAD data */255		aadref = atoken;256		atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;257		atoken->packet_length = assocadj;258		atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;259		atoken->instructions = EIP197_TOKEN_INS_LAST |260				       EIP197_TOKEN_INS_TYPE_HASH;261	}262	atoken++;263 264	if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {265		/* For ESP mode (and not GMAC), skip over the IV */266		atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;267		atoken->packet_length = EIP197_AEAD_IPSEC_IV_SIZE;268		atoken->stat = 0;269		atoken->instructions = 0;270		atoken++;271		atoksize++;272	} else if (unlikely(ctx->alg == SAFEXCEL_CHACHA20 &&273			    direction == SAFEXCEL_DECRYPT)) {274		/* Poly-chacha decryption needs a dummy NOP here ... */275		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;276		atoken->packet_length = 16; /* According to Op Manual */277		atoken->stat = 0;278		atoken->instructions = 0;279		atoken++;280		atoksize++;281	}282 283	if  (ctx->xcm) {284		/* For GCM and CCM, obtain enc(Y0) */285		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES;286		atoken->packet_length = 0;287		atoken->stat = 0;288		atoken->instructions = AES_BLOCK_SIZE;289		atoken++;290 291		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;292		atoken->packet_length = AES_BLOCK_SIZE;293		atoken->stat = 0;294		atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |295				       EIP197_TOKEN_INS_TYPE_CRYPTO;296		atoken++;297		atoksize += 2;298	}299 300	if (likely(cryptlen || ctx->alg == SAFEXCEL_CHACHA20)) {301		/* Fixup stat field for AAD direction instruction */302		aadref->stat = 0;303 304		/* Process crypto data */305		atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;306		atoken->packet_length = cryptlen;307 308		if (unlikely(ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) {309			/* Fixup instruction field for AAD dir instruction */310			aadref->instructions = EIP197_TOKEN_INS_TYPE_HASH;311 312			/* Do not send to crypt engine in case of GMAC */313			atoken->instructions = EIP197_TOKEN_INS_LAST |314					       EIP197_TOKEN_INS_TYPE_HASH |315					       EIP197_TOKEN_INS_TYPE_OUTPUT;316		} else {317			atoken->instructions = EIP197_TOKEN_INS_LAST |318					       EIP197_TOKEN_INS_TYPE_CRYPTO |319					       EIP197_TOKEN_INS_TYPE_HASH |320					       EIP197_TOKEN_INS_TYPE_OUTPUT;321		}322 323		cryptlen &= 15;324		if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM && cryptlen)) {325			atoken->stat = 0;326			/* For CCM only, pad crypto data to the hash engine */327			atoken++;328			atoksize++;329			atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;330			atoken->packet_length = 16 - cryptlen;331			atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;332			atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;333		} else {334			atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;335		}336		atoken++;337		atoksize++;338	}339 340	if (direction == SAFEXCEL_ENCRYPT) {341		/* Append ICV */342		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;343		atoken->packet_length = digestsize;344		atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |345			       EIP197_TOKEN_STAT_LAST_PACKET;346		atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |347				       EIP197_TOKEN_INS_INSERT_HASH_DIGEST;348	} else {349		/* Extract ICV */350		atoken->opcode = EIP197_TOKEN_OPCODE_RETRIEVE;351		atoken->packet_length = digestsize;352		atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |353			       EIP197_TOKEN_STAT_LAST_PACKET;354		atoken->instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST;355		atoken++;356		atoksize++;357 358		/* Verify ICV */359		atoken->opcode = EIP197_TOKEN_OPCODE_VERIFY;360		atoken->packet_length = digestsize |361					EIP197_TOKEN_HASH_RESULT_VERIFY;362		atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |363			       EIP197_TOKEN_STAT_LAST_PACKET;364		atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT;365	}366 367	/* Fixup length of the token in the command descriptor */368	cdesc->additional_cdata_size = atoksize;369}370 371static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm,372					const u8 *key, unsigned int len)373{374	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);375	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);376	struct safexcel_crypto_priv *priv = ctx->base.priv;377	struct crypto_aes_ctx aes;378	int ret, i;379 380	ret = aes_expandkey(&aes, key, len);381	if (ret)382		return ret;383 384	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {385		for (i = 0; i < len / sizeof(u32); i++) {386			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {387				ctx->base.needs_inv = true;388				break;389			}390		}391	}392 393	for (i = 0; i < len / sizeof(u32); i++)394		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);395 396	ctx->key_len = len;397 398	memzero_explicit(&aes, sizeof(aes));399	return 0;400}401 402static int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key,403				unsigned int len)404{405	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);406	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);407	struct safexcel_crypto_priv *priv = ctx->base.priv;408	struct crypto_authenc_keys keys;409	struct crypto_aes_ctx aes;410	int err = -EINVAL, i;411	const char *alg;412 413	if (unlikely(crypto_authenc_extractkeys(&keys, key, len)))414		goto badkey;415 416	if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) {417		/* Must have at least space for the nonce here */418		if (unlikely(keys.enckeylen < CTR_RFC3686_NONCE_SIZE))419			goto badkey;420		/* last 4 bytes of key are the nonce! */421		ctx->nonce = *(u32 *)(keys.enckey + keys.enckeylen -422				      CTR_RFC3686_NONCE_SIZE);423		/* exclude the nonce here */424		keys.enckeylen -= CTR_RFC3686_NONCE_SIZE;425	}426 427	/* Encryption key */428	switch (ctx->alg) {429	case SAFEXCEL_DES:430		err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen);431		if (unlikely(err))432			goto badkey;433		break;434	case SAFEXCEL_3DES:435		err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen);436		if (unlikely(err))437			goto badkey;438		break;439	case SAFEXCEL_AES:440		err = aes_expandkey(&aes, keys.enckey, keys.enckeylen);441		if (unlikely(err))442			goto badkey;443		break;444	case SAFEXCEL_SM4:445		if (unlikely(keys.enckeylen != SM4_KEY_SIZE))446			goto badkey;447		break;448	default:449		dev_err(priv->dev, "aead: unsupported cipher algorithm\n");450		goto badkey;451	}452 453	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {454		for (i = 0; i < keys.enckeylen / sizeof(u32); i++) {455			if (le32_to_cpu(ctx->key[i]) !=456			    ((u32 *)keys.enckey)[i]) {457				ctx->base.needs_inv = true;458				break;459			}460		}461	}462 463	/* Auth key */464	switch (ctx->hash_alg) {465	case CONTEXT_CONTROL_CRYPTO_ALG_SHA1:466		alg = "safexcel-sha1";467		break;468	case CONTEXT_CONTROL_CRYPTO_ALG_SHA224:469		alg = "safexcel-sha224";470		break;471	case CONTEXT_CONTROL_CRYPTO_ALG_SHA256:472		alg = "safexcel-sha256";473		break;474	case CONTEXT_CONTROL_CRYPTO_ALG_SHA384:475		alg = "safexcel-sha384";476		break;477	case CONTEXT_CONTROL_CRYPTO_ALG_SHA512:478		alg = "safexcel-sha512";479		break;480	case CONTEXT_CONTROL_CRYPTO_ALG_SM3:481		alg = "safexcel-sm3";482		break;483	default:484		dev_err(priv->dev, "aead: unsupported hash algorithm\n");485		goto badkey;486	}487 488	if (safexcel_hmac_setkey(&ctx->base, keys.authkey, keys.authkeylen,489				 alg, ctx->state_sz))490		goto badkey;491 492	/* Now copy the keys into the context */493	for (i = 0; i < keys.enckeylen / sizeof(u32); i++)494		ctx->key[i] = cpu_to_le32(((u32 *)keys.enckey)[i]);495	ctx->key_len = keys.enckeylen;496 497	memzero_explicit(&keys, sizeof(keys));498	return 0;499 500badkey:501	memzero_explicit(&keys, sizeof(keys));502	return err;503}504 505static int safexcel_context_control(struct safexcel_cipher_ctx *ctx,506				    struct crypto_async_request *async,507				    struct safexcel_cipher_req *sreq,508				    struct safexcel_command_desc *cdesc)509{510	struct safexcel_crypto_priv *priv = ctx->base.priv;511	int ctrl_size = ctx->key_len / sizeof(u32);512 513	cdesc->control_data.control1 = ctx->mode;514 515	if (ctx->aead) {516		/* Take in account the ipad+opad digests */517		if (ctx->xcm) {518			ctrl_size += ctx->state_sz / sizeof(u32);519			cdesc->control_data.control0 =520				CONTEXT_CONTROL_KEY_EN |521				CONTEXT_CONTROL_DIGEST_XCM |522				ctx->hash_alg |523				CONTEXT_CONTROL_SIZE(ctrl_size);524		} else if (ctx->alg == SAFEXCEL_CHACHA20) {525			/* Chacha20-Poly1305 */526			cdesc->control_data.control0 =527				CONTEXT_CONTROL_KEY_EN |528				CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 |529				(sreq->direction == SAFEXCEL_ENCRYPT ?530					CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT :531					CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN) |532				ctx->hash_alg |533				CONTEXT_CONTROL_SIZE(ctrl_size);534			return 0;535		} else {536			ctrl_size += ctx->state_sz / sizeof(u32) * 2;537			cdesc->control_data.control0 =538				CONTEXT_CONTROL_KEY_EN |539				CONTEXT_CONTROL_DIGEST_HMAC |540				ctx->hash_alg |541				CONTEXT_CONTROL_SIZE(ctrl_size);542		}543 544		if (sreq->direction == SAFEXCEL_ENCRYPT &&545		    (ctx->xcm == EIP197_XCM_MODE_CCM ||546		     ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC))547			cdesc->control_data.control0 |=548				CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT;549		else if (sreq->direction == SAFEXCEL_ENCRYPT)550			cdesc->control_data.control0 |=551				CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT;552		else if (ctx->xcm == EIP197_XCM_MODE_CCM)553			cdesc->control_data.control0 |=554				CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN;555		else556			cdesc->control_data.control0 |=557				CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN;558	} else {559		if (sreq->direction == SAFEXCEL_ENCRYPT)560			cdesc->control_data.control0 =561				CONTEXT_CONTROL_TYPE_CRYPTO_OUT |562				CONTEXT_CONTROL_KEY_EN |563				CONTEXT_CONTROL_SIZE(ctrl_size);564		else565			cdesc->control_data.control0 =566				CONTEXT_CONTROL_TYPE_CRYPTO_IN |567				CONTEXT_CONTROL_KEY_EN |568				CONTEXT_CONTROL_SIZE(ctrl_size);569	}570 571	if (ctx->alg == SAFEXCEL_DES) {572		cdesc->control_data.control0 |=573			CONTEXT_CONTROL_CRYPTO_ALG_DES;574	} else if (ctx->alg == SAFEXCEL_3DES) {575		cdesc->control_data.control0 |=576			CONTEXT_CONTROL_CRYPTO_ALG_3DES;577	} else if (ctx->alg == SAFEXCEL_AES) {578		switch (ctx->key_len >> ctx->xts) {579		case AES_KEYSIZE_128:580			cdesc->control_data.control0 |=581				CONTEXT_CONTROL_CRYPTO_ALG_AES128;582			break;583		case AES_KEYSIZE_192:584			cdesc->control_data.control0 |=585				CONTEXT_CONTROL_CRYPTO_ALG_AES192;586			break;587		case AES_KEYSIZE_256:588			cdesc->control_data.control0 |=589				CONTEXT_CONTROL_CRYPTO_ALG_AES256;590			break;591		default:592			dev_err(priv->dev, "aes keysize not supported: %u\n",593				ctx->key_len >> ctx->xts);594			return -EINVAL;595		}596	} else if (ctx->alg == SAFEXCEL_CHACHA20) {597		cdesc->control_data.control0 |=598			CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20;599	} else if (ctx->alg == SAFEXCEL_SM4) {600		cdesc->control_data.control0 |=601			CONTEXT_CONTROL_CRYPTO_ALG_SM4;602	}603 604	return 0;605}606 607static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring,608				      struct crypto_async_request *async,609				      struct scatterlist *src,610				      struct scatterlist *dst,611				      unsigned int cryptlen,612				      struct safexcel_cipher_req *sreq,613				      bool *should_complete, int *ret)614{615	struct skcipher_request *areq = skcipher_request_cast(async);616	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq);617	struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(skcipher);618	struct safexcel_result_desc *rdesc;619	int ndesc = 0;620 621	*ret = 0;622 623	if (unlikely(!sreq->rdescs))624		return 0;625 626	while (sreq->rdescs--) {627		rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr);628		if (IS_ERR(rdesc)) {629			dev_err(priv->dev,630				"cipher: result: could not retrieve the result descriptor\n");631			*ret = PTR_ERR(rdesc);632			break;633		}634 635		if (likely(!*ret))636			*ret = safexcel_rdesc_check_errors(priv, rdesc);637 638		ndesc++;639	}640 641	safexcel_complete(priv, ring);642 643	if (src == dst) {644		if (sreq->nr_src > 0)645			dma_unmap_sg(priv->dev, src, sreq->nr_src,646				     DMA_BIDIRECTIONAL);647	} else {648		if (sreq->nr_src > 0)649			dma_unmap_sg(priv->dev, src, sreq->nr_src,650				     DMA_TO_DEVICE);651		if (sreq->nr_dst > 0)652			dma_unmap_sg(priv->dev, dst, sreq->nr_dst,653				     DMA_FROM_DEVICE);654	}655 656	/*657	 * Update IV in req from last crypto output word for CBC modes658	 */659	if ((!ctx->aead) && (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) &&660	    (sreq->direction == SAFEXCEL_ENCRYPT)) {661		/* For encrypt take the last output word */662		sg_pcopy_to_buffer(dst, sreq->nr_dst, areq->iv,663				   crypto_skcipher_ivsize(skcipher),664				   (cryptlen -665				    crypto_skcipher_ivsize(skcipher)));666	}667 668	*should_complete = true;669 670	return ndesc;671}672 673static int safexcel_send_req(struct crypto_async_request *base, int ring,674			     struct safexcel_cipher_req *sreq,675			     struct scatterlist *src, struct scatterlist *dst,676			     unsigned int cryptlen, unsigned int assoclen,677			     unsigned int digestsize, u8 *iv, int *commands,678			     int *results)679{680	struct skcipher_request *areq = skcipher_request_cast(base);681	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq);682	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);683	struct safexcel_crypto_priv *priv = ctx->base.priv;684	struct safexcel_command_desc *cdesc;685	struct safexcel_command_desc *first_cdesc = NULL;686	struct safexcel_result_desc *rdesc, *first_rdesc = NULL;687	struct scatterlist *sg;688	unsigned int totlen;689	unsigned int totlen_src = cryptlen + assoclen;690	unsigned int totlen_dst = totlen_src;691	struct safexcel_token *atoken;692	int n_cdesc = 0, n_rdesc = 0;693	int queued, i, ret = 0;694	bool first = true;695 696	sreq->nr_src = sg_nents_for_len(src, totlen_src);697 698	if (ctx->aead) {699		/*700		 * AEAD has auth tag appended to output for encrypt and701		 * removed from the output for decrypt!702		 */703		if (sreq->direction == SAFEXCEL_DECRYPT)704			totlen_dst -= digestsize;705		else706			totlen_dst += digestsize;707 708		memcpy(ctx->base.ctxr->data + ctx->key_len / sizeof(u32),709		       &ctx->base.ipad, ctx->state_sz);710		if (!ctx->xcm)711			memcpy(ctx->base.ctxr->data + (ctx->key_len +712			       ctx->state_sz) / sizeof(u32), &ctx->base.opad,713			       ctx->state_sz);714	} else if ((ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) &&715		   (sreq->direction == SAFEXCEL_DECRYPT)) {716		/*717		 * Save IV from last crypto input word for CBC modes in decrypt718		 * direction. Need to do this first in case of inplace operation719		 * as it will be overwritten.720		 */721		sg_pcopy_to_buffer(src, sreq->nr_src, areq->iv,722				   crypto_skcipher_ivsize(skcipher),723				   (totlen_src -724				    crypto_skcipher_ivsize(skcipher)));725	}726 727	sreq->nr_dst = sg_nents_for_len(dst, totlen_dst);728 729	/*730	 * Remember actual input length, source buffer length may be731	 * updated in case of inline operation below.732	 */733	totlen = totlen_src;734	queued = totlen_src;735 736	if (src == dst) {737		sreq->nr_src = max(sreq->nr_src, sreq->nr_dst);738		sreq->nr_dst = sreq->nr_src;739		if (unlikely((totlen_src || totlen_dst) &&740		    (sreq->nr_src <= 0))) {741			dev_err(priv->dev, "In-place buffer not large enough (need %d bytes)!",742				max(totlen_src, totlen_dst));743			return -EINVAL;744		}745		if (sreq->nr_src > 0 &&746		    !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL))747			return -EIO;748	} else {749		if (unlikely(totlen_src && (sreq->nr_src <= 0))) {750			dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!",751				totlen_src);752			return -EINVAL;753		}754 755		if (sreq->nr_src > 0 &&756		    !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE))757			return -EIO;758 759		if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) {760			dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!",761				totlen_dst);762			ret = -EINVAL;763			goto unmap;764		}765 766		if (sreq->nr_dst > 0 &&767		    !dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE)) {768			ret = -EIO;769			goto unmap;770		}771	}772 773	memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len);774 775	if (!totlen) {776		/*777		 * The EIP97 cannot deal with zero length input packets!778		 * So stuff a dummy command descriptor indicating a 1 byte779		 * (dummy) input packet, using the context record as source.780		 */781		first_cdesc = safexcel_add_cdesc(priv, ring,782						 1, 1, ctx->base.ctxr_dma,783						 1, 1, ctx->base.ctxr_dma,784						 &atoken);785		if (IS_ERR(first_cdesc)) {786			/* No space left in the command descriptor ring */787			ret = PTR_ERR(first_cdesc);788			goto cdesc_rollback;789		}790		n_cdesc = 1;791		goto skip_cdesc;792	}793 794	/* command descriptors */795	for_each_sg(src, sg, sreq->nr_src, i) {796		int len = sg_dma_len(sg);797 798		/* Do not overflow the request */799		if (queued < len)800			len = queued;801 802		cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc,803					   !(queued - len),804					   sg_dma_address(sg), len, totlen,805					   ctx->base.ctxr_dma, &atoken);806		if (IS_ERR(cdesc)) {807			/* No space left in the command descriptor ring */808			ret = PTR_ERR(cdesc);809			goto cdesc_rollback;810		}811 812		if (!n_cdesc)813			first_cdesc = cdesc;814 815		n_cdesc++;816		queued -= len;817		if (!queued)818			break;819	}820skip_cdesc:821	/* Add context control words and token to first command descriptor */822	safexcel_context_control(ctx, base, sreq, first_cdesc);823	if (ctx->aead)824		safexcel_aead_token(ctx, iv, first_cdesc, atoken,825				    sreq->direction, cryptlen,826				    assoclen, digestsize);827	else828		safexcel_skcipher_token(ctx, iv, first_cdesc, atoken,829					cryptlen);830 831	/* result descriptors */832	for_each_sg(dst, sg, sreq->nr_dst, i) {833		bool last = (i == sreq->nr_dst - 1);834		u32 len = sg_dma_len(sg);835 836		/* only allow the part of the buffer we know we need */837		if (len > totlen_dst)838			len = totlen_dst;839		if (unlikely(!len))840			break;841		totlen_dst -= len;842 843		/* skip over AAD space in buffer - not written */844		if (assoclen) {845			if (assoclen >= len) {846				assoclen -= len;847				continue;848			}849			rdesc = safexcel_add_rdesc(priv, ring, first, last,850						   sg_dma_address(sg) +851						   assoclen,852						   len - assoclen);853			assoclen = 0;854		} else {855			rdesc = safexcel_add_rdesc(priv, ring, first, last,856						   sg_dma_address(sg),857						   len);858		}859		if (IS_ERR(rdesc)) {860			/* No space left in the result descriptor ring */861			ret = PTR_ERR(rdesc);862			goto rdesc_rollback;863		}864		if (first) {865			first_rdesc = rdesc;866			first = false;867		}868		n_rdesc++;869	}870 871	if (unlikely(first)) {872		/*873		 * Special case: AEAD decrypt with only AAD data.874		 * In this case there is NO output data from the engine,875		 * but the engine still needs a result descriptor!876		 * Create a dummy one just for catching the result token.877		 */878		rdesc = safexcel_add_rdesc(priv, ring, true, true, 0, 0);879		if (IS_ERR(rdesc)) {880			/* No space left in the result descriptor ring */881			ret = PTR_ERR(rdesc);882			goto rdesc_rollback;883		}884		first_rdesc = rdesc;885		n_rdesc = 1;886	}887 888	safexcel_rdr_req_set(priv, ring, first_rdesc, base);889 890	*commands = n_cdesc;891	*results = n_rdesc;892	return 0;893 894rdesc_rollback:895	for (i = 0; i < n_rdesc; i++)896		safexcel_ring_rollback_wptr(priv, &priv->ring[ring].rdr);897cdesc_rollback:898	for (i = 0; i < n_cdesc; i++)899		safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr);900unmap:901	if (src == dst) {902		if (sreq->nr_src > 0)903			dma_unmap_sg(priv->dev, src, sreq->nr_src,904				     DMA_BIDIRECTIONAL);905	} else {906		if (sreq->nr_src > 0)907			dma_unmap_sg(priv->dev, src, sreq->nr_src,908				     DMA_TO_DEVICE);909		if (sreq->nr_dst > 0)910			dma_unmap_sg(priv->dev, dst, sreq->nr_dst,911				     DMA_FROM_DEVICE);912	}913 914	return ret;915}916 917static int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv,918				      int ring,919				      struct crypto_async_request *base,920				      struct safexcel_cipher_req *sreq,921				      bool *should_complete, int *ret)922{923	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);924	struct safexcel_result_desc *rdesc;925	int ndesc = 0, enq_ret;926 927	*ret = 0;928 929	if (unlikely(!sreq->rdescs))930		return 0;931 932	while (sreq->rdescs--) {933		rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr);934		if (IS_ERR(rdesc)) {935			dev_err(priv->dev,936				"cipher: invalidate: could not retrieve the result descriptor\n");937			*ret = PTR_ERR(rdesc);938			break;939		}940 941		if (likely(!*ret))942			*ret = safexcel_rdesc_check_errors(priv, rdesc);943 944		ndesc++;945	}946 947	safexcel_complete(priv, ring);948 949	if (ctx->base.exit_inv) {950		dma_pool_free(priv->context_pool, ctx->base.ctxr,951			      ctx->base.ctxr_dma);952 953		*should_complete = true;954 955		return ndesc;956	}957 958	ring = safexcel_select_ring(priv);959	ctx->base.ring = ring;960 961	spin_lock_bh(&priv->ring[ring].queue_lock);962	enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, base);963	spin_unlock_bh(&priv->ring[ring].queue_lock);964 965	if (enq_ret != -EINPROGRESS)966		*ret = enq_ret;967 968	queue_work(priv->ring[ring].workqueue,969		   &priv->ring[ring].work_data.work);970 971	*should_complete = false;972 973	return ndesc;974}975 976static int safexcel_skcipher_handle_result(struct safexcel_crypto_priv *priv,977					   int ring,978					   struct crypto_async_request *async,979					   bool *should_complete, int *ret)980{981	struct skcipher_request *req = skcipher_request_cast(async);982	struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);983	int err;984 985	if (sreq->needs_inv) {986		sreq->needs_inv = false;987		err = safexcel_handle_inv_result(priv, ring, async, sreq,988						 should_complete, ret);989	} else {990		err = safexcel_handle_req_result(priv, ring, async, req->src,991						 req->dst, req->cryptlen, sreq,992						 should_complete, ret);993	}994 995	return err;996}997 998static int safexcel_aead_handle_result(struct safexcel_crypto_priv *priv,999				       int ring,1000				       struct crypto_async_request *async,1001				       bool *should_complete, int *ret)1002{1003	struct aead_request *req = aead_request_cast(async);1004	struct crypto_aead *tfm = crypto_aead_reqtfm(req);1005	struct safexcel_cipher_req *sreq = aead_request_ctx(req);1006	int err;1007 1008	if (sreq->needs_inv) {1009		sreq->needs_inv = false;1010		err = safexcel_handle_inv_result(priv, ring, async, sreq,1011						 should_complete, ret);1012	} else {1013		err = safexcel_handle_req_result(priv, ring, async, req->src,1014						 req->dst,1015						 req->cryptlen + crypto_aead_authsize(tfm),1016						 sreq, should_complete, ret);1017	}1018 1019	return err;1020}1021 1022static int safexcel_cipher_send_inv(struct crypto_async_request *base,1023				    int ring, int *commands, int *results)1024{1025	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);1026	struct safexcel_crypto_priv *priv = ctx->base.priv;1027	int ret;1028 1029	ret = safexcel_invalidate_cache(base, priv, ctx->base.ctxr_dma, ring);1030	if (unlikely(ret))1031		return ret;1032 1033	*commands = 1;1034	*results = 1;1035 1036	return 0;1037}1038 1039static int safexcel_skcipher_send(struct crypto_async_request *async, int ring,1040				  int *commands, int *results)1041{1042	struct skcipher_request *req = skcipher_request_cast(async);1043	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);1044	struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);1045	struct safexcel_crypto_priv *priv = ctx->base.priv;1046	int ret;1047 1048	BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv);1049 1050	if (sreq->needs_inv) {1051		ret = safexcel_cipher_send_inv(async, ring, commands, results);1052	} else {1053		struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);1054		u8 input_iv[AES_BLOCK_SIZE];1055 1056		/*1057		 * Save input IV in case of CBC decrypt mode1058		 * Will be overwritten with output IV prior to use!1059		 */1060		memcpy(input_iv, req->iv, crypto_skcipher_ivsize(skcipher));1061 1062		ret = safexcel_send_req(async, ring, sreq, req->src,1063					req->dst, req->cryptlen, 0, 0, input_iv,1064					commands, results);1065	}1066 1067	sreq->rdescs = *results;1068	return ret;1069}1070 1071static int safexcel_aead_send(struct crypto_async_request *async, int ring,1072			      int *commands, int *results)1073{1074	struct aead_request *req = aead_request_cast(async);1075	struct crypto_aead *tfm = crypto_aead_reqtfm(req);1076	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);1077	struct safexcel_cipher_req *sreq = aead_request_ctx(req);1078	struct safexcel_crypto_priv *priv = ctx->base.priv;1079	int ret;1080 1081	BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv);1082 1083	if (sreq->needs_inv)1084		ret = safexcel_cipher_send_inv(async, ring, commands, results);1085	else1086		ret = safexcel_send_req(async, ring, sreq, req->src, req->dst,1087					req->cryptlen, req->assoclen,1088					crypto_aead_authsize(tfm), req->iv,1089					commands, results);1090	sreq->rdescs = *results;1091	return ret;1092}1093 1094static int safexcel_cipher_exit_inv(struct crypto_tfm *tfm,1095				    struct crypto_async_request *base,1096				    struct safexcel_cipher_req *sreq,1097				    struct crypto_wait *result)1098{1099	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1100	struct safexcel_crypto_priv *priv = ctx->base.priv;1101	int ring = ctx->base.ring;1102	int err;1103 1104	ctx = crypto_tfm_ctx(base->tfm);1105	ctx->base.exit_inv = true;1106	sreq->needs_inv = true;1107 1108	spin_lock_bh(&priv->ring[ring].queue_lock);1109	crypto_enqueue_request(&priv->ring[ring].queue, base);1110	spin_unlock_bh(&priv->ring[ring].queue_lock);1111 1112	queue_work(priv->ring[ring].workqueue,1113		   &priv->ring[ring].work_data.work);1114 1115	err = crypto_wait_req(-EINPROGRESS, result);1116 1117	if (err) {1118		dev_warn(priv->dev,1119			"cipher: sync: invalidate: completion error %d\n",1120			 err);1121		return err;1122	}1123 1124	return 0;1125}1126 1127static int safexcel_skcipher_exit_inv(struct crypto_tfm *tfm)1128{1129	EIP197_REQUEST_ON_STACK(req, skcipher, EIP197_SKCIPHER_REQ_SIZE);1130	struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);1131	DECLARE_CRYPTO_WAIT(result);1132 1133	memset(req, 0, sizeof(struct skcipher_request));1134 1135	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,1136				      crypto_req_done, &result);1137	skcipher_request_set_tfm(req, __crypto_skcipher_cast(tfm));1138 1139	return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result);1140}1141 1142static int safexcel_aead_exit_inv(struct crypto_tfm *tfm)1143{1144	EIP197_REQUEST_ON_STACK(req, aead, EIP197_AEAD_REQ_SIZE);1145	struct safexcel_cipher_req *sreq = aead_request_ctx(req);1146	DECLARE_CRYPTO_WAIT(result);1147 1148	memset(req, 0, sizeof(struct aead_request));1149 1150	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,1151				  crypto_req_done, &result);1152	aead_request_set_tfm(req, __crypto_aead_cast(tfm));1153 1154	return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result);1155}1156 1157static int safexcel_queue_req(struct crypto_async_request *base,1158			struct safexcel_cipher_req *sreq,1159			enum safexcel_cipher_direction dir)1160{1161	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);1162	struct safexcel_crypto_priv *priv = ctx->base.priv;1163	int ret, ring;1164 1165	sreq->needs_inv = false;1166	sreq->direction = dir;1167 1168	if (ctx->base.ctxr) {1169		if (priv->flags & EIP197_TRC_CACHE && ctx->base.needs_inv) {1170			sreq->needs_inv = true;1171			ctx->base.needs_inv = false;1172		}1173	} else {1174		ctx->base.ring = safexcel_select_ring(priv);1175		ctx->base.ctxr = dma_pool_zalloc(priv->context_pool,1176						 EIP197_GFP_FLAGS(*base),1177						 &ctx->base.ctxr_dma);1178		if (!ctx->base.ctxr)1179			return -ENOMEM;1180	}1181 1182	ring = ctx->base.ring;1183 1184	spin_lock_bh(&priv->ring[ring].queue_lock);1185	ret = crypto_enqueue_request(&priv->ring[ring].queue, base);1186	spin_unlock_bh(&priv->ring[ring].queue_lock);1187 1188	queue_work(priv->ring[ring].workqueue,1189		   &priv->ring[ring].work_data.work);1190 1191	return ret;1192}1193 1194static int safexcel_encrypt(struct skcipher_request *req)1195{1196	return safexcel_queue_req(&req->base, skcipher_request_ctx(req),1197			SAFEXCEL_ENCRYPT);1198}1199 1200static int safexcel_decrypt(struct skcipher_request *req)1201{1202	return safexcel_queue_req(&req->base, skcipher_request_ctx(req),1203			SAFEXCEL_DECRYPT);1204}1205 1206static int safexcel_skcipher_cra_init(struct crypto_tfm *tfm)1207{1208	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1209	struct safexcel_alg_template *tmpl =1210		container_of(tfm->__crt_alg, struct safexcel_alg_template,1211			     alg.skcipher.base);1212 1213	crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm),1214				    sizeof(struct safexcel_cipher_req));1215 1216	ctx->base.priv = tmpl->priv;1217 1218	ctx->base.send = safexcel_skcipher_send;1219	ctx->base.handle_result = safexcel_skcipher_handle_result;1220	ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD;1221	ctx->ctrinit = 1;1222	return 0;1223}1224 1225static int safexcel_cipher_cra_exit(struct crypto_tfm *tfm)1226{1227	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1228 1229	memzero_explicit(ctx->key, sizeof(ctx->key));1230 1231	/* context not allocated, skip invalidation */1232	if (!ctx->base.ctxr)1233		return -ENOMEM;1234 1235	memzero_explicit(ctx->base.ctxr->data, sizeof(ctx->base.ctxr->data));1236	return 0;1237}1238 1239static void safexcel_skcipher_cra_exit(struct crypto_tfm *tfm)1240{1241	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1242	struct safexcel_crypto_priv *priv = ctx->base.priv;1243	int ret;1244 1245	if (safexcel_cipher_cra_exit(tfm))1246		return;1247 1248	if (priv->flags & EIP197_TRC_CACHE) {1249		ret = safexcel_skcipher_exit_inv(tfm);1250		if (ret)1251			dev_warn(priv->dev, "skcipher: invalidation error %d\n",1252				 ret);1253	} else {1254		dma_pool_free(priv->context_pool, ctx->base.ctxr,1255			      ctx->base.ctxr_dma);1256	}1257}1258 1259static void safexcel_aead_cra_exit(struct crypto_tfm *tfm)1260{1261	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1262	struct safexcel_crypto_priv *priv = ctx->base.priv;1263	int ret;1264 1265	if (safexcel_cipher_cra_exit(tfm))1266		return;1267 1268	if (priv->flags & EIP197_TRC_CACHE) {1269		ret = safexcel_aead_exit_inv(tfm);1270		if (ret)1271			dev_warn(priv->dev, "aead: invalidation error %d\n",1272				 ret);1273	} else {1274		dma_pool_free(priv->context_pool, ctx->base.ctxr,1275			      ctx->base.ctxr_dma);1276	}1277}1278 1279static int safexcel_skcipher_aes_ecb_cra_init(struct crypto_tfm *tfm)1280{1281	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1282 1283	safexcel_skcipher_cra_init(tfm);1284	ctx->alg  = SAFEXCEL_AES;1285	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;1286	ctx->blocksz = 0;1287	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1288	return 0;1289}1290 1291struct safexcel_alg_template safexcel_alg_ecb_aes = {1292	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1293	.algo_mask = SAFEXCEL_ALG_AES,1294	.alg.skcipher = {1295		.setkey = safexcel_skcipher_aes_setkey,1296		.encrypt = safexcel_encrypt,1297		.decrypt = safexcel_decrypt,1298		.min_keysize = AES_MIN_KEY_SIZE,1299		.max_keysize = AES_MAX_KEY_SIZE,1300		.base = {1301			.cra_name = "ecb(aes)",1302			.cra_driver_name = "safexcel-ecb-aes",1303			.cra_priority = SAFEXCEL_CRA_PRIORITY,1304			.cra_flags = CRYPTO_ALG_ASYNC |1305				     CRYPTO_ALG_ALLOCATES_MEMORY |1306				     CRYPTO_ALG_KERN_DRIVER_ONLY,1307			.cra_blocksize = AES_BLOCK_SIZE,1308			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1309			.cra_alignmask = 0,1310			.cra_init = safexcel_skcipher_aes_ecb_cra_init,1311			.cra_exit = safexcel_skcipher_cra_exit,1312			.cra_module = THIS_MODULE,1313		},1314	},1315};1316 1317static int safexcel_skcipher_aes_cbc_cra_init(struct crypto_tfm *tfm)1318{1319	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1320 1321	safexcel_skcipher_cra_init(tfm);1322	ctx->alg  = SAFEXCEL_AES;1323	ctx->blocksz = AES_BLOCK_SIZE;1324	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;1325	return 0;1326}1327 1328struct safexcel_alg_template safexcel_alg_cbc_aes = {1329	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1330	.algo_mask = SAFEXCEL_ALG_AES,1331	.alg.skcipher = {1332		.setkey = safexcel_skcipher_aes_setkey,1333		.encrypt = safexcel_encrypt,1334		.decrypt = safexcel_decrypt,1335		.min_keysize = AES_MIN_KEY_SIZE,1336		.max_keysize = AES_MAX_KEY_SIZE,1337		.ivsize = AES_BLOCK_SIZE,1338		.base = {1339			.cra_name = "cbc(aes)",1340			.cra_driver_name = "safexcel-cbc-aes",1341			.cra_priority = SAFEXCEL_CRA_PRIORITY,1342			.cra_flags = CRYPTO_ALG_ASYNC |1343				     CRYPTO_ALG_ALLOCATES_MEMORY |1344				     CRYPTO_ALG_KERN_DRIVER_ONLY,1345			.cra_blocksize = AES_BLOCK_SIZE,1346			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1347			.cra_alignmask = 0,1348			.cra_init = safexcel_skcipher_aes_cbc_cra_init,1349			.cra_exit = safexcel_skcipher_cra_exit,1350			.cra_module = THIS_MODULE,1351		},1352	},1353};1354 1355static int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm,1356					   const u8 *key, unsigned int len)1357{1358	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);1359	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1360	struct safexcel_crypto_priv *priv = ctx->base.priv;1361	struct crypto_aes_ctx aes;1362	int ret, i;1363	unsigned int keylen;1364 1365	/* last 4 bytes of key are the nonce! */1366	ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);1367	/* exclude the nonce here */1368	keylen = len - CTR_RFC3686_NONCE_SIZE;1369	ret = aes_expandkey(&aes, key, keylen);1370	if (ret)1371		return ret;1372 1373	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {1374		for (i = 0; i < keylen / sizeof(u32); i++) {1375			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {1376				ctx->base.needs_inv = true;1377				break;1378			}1379		}1380	}1381 1382	for (i = 0; i < keylen / sizeof(u32); i++)1383		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);1384 1385	ctx->key_len = keylen;1386 1387	memzero_explicit(&aes, sizeof(aes));1388	return 0;1389}1390 1391static int safexcel_skcipher_aes_ctr_cra_init(struct crypto_tfm *tfm)1392{1393	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1394 1395	safexcel_skcipher_cra_init(tfm);1396	ctx->alg  = SAFEXCEL_AES;1397	ctx->blocksz = AES_BLOCK_SIZE;1398	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;1399	return 0;1400}1401 1402struct safexcel_alg_template safexcel_alg_ctr_aes = {1403	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1404	.algo_mask = SAFEXCEL_ALG_AES,1405	.alg.skcipher = {1406		.setkey = safexcel_skcipher_aesctr_setkey,1407		.encrypt = safexcel_encrypt,1408		.decrypt = safexcel_decrypt,1409		/* Add nonce size */1410		.min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,1411		.max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,1412		.ivsize = CTR_RFC3686_IV_SIZE,1413		.base = {1414			.cra_name = "rfc3686(ctr(aes))",1415			.cra_driver_name = "safexcel-ctr-aes",1416			.cra_priority = SAFEXCEL_CRA_PRIORITY,1417			.cra_flags = CRYPTO_ALG_ASYNC |1418				     CRYPTO_ALG_ALLOCATES_MEMORY |1419				     CRYPTO_ALG_KERN_DRIVER_ONLY,1420			.cra_blocksize = 1,1421			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1422			.cra_alignmask = 0,1423			.cra_init = safexcel_skcipher_aes_ctr_cra_init,1424			.cra_exit = safexcel_skcipher_cra_exit,1425			.cra_module = THIS_MODULE,1426		},1427	},1428};1429 1430static int safexcel_des_setkey(struct crypto_skcipher *ctfm, const u8 *key,1431			       unsigned int len)1432{1433	struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);1434	struct safexcel_crypto_priv *priv = ctx->base.priv;1435	int ret;1436 1437	ret = verify_skcipher_des_key(ctfm, key);1438	if (ret)1439		return ret;1440 1441	/* if context exits and key changed, need to invalidate it */1442	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)1443		if (memcmp(ctx->key, key, len))1444			ctx->base.needs_inv = true;1445 1446	memcpy(ctx->key, key, len);1447	ctx->key_len = len;1448 1449	return 0;1450}1451 1452static int safexcel_skcipher_des_cbc_cra_init(struct crypto_tfm *tfm)1453{1454	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1455 1456	safexcel_skcipher_cra_init(tfm);1457	ctx->alg  = SAFEXCEL_DES;1458	ctx->blocksz = DES_BLOCK_SIZE;1459	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1460	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;1461	return 0;1462}1463 1464struct safexcel_alg_template safexcel_alg_cbc_des = {1465	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1466	.algo_mask = SAFEXCEL_ALG_DES,1467	.alg.skcipher = {1468		.setkey = safexcel_des_setkey,1469		.encrypt = safexcel_encrypt,1470		.decrypt = safexcel_decrypt,1471		.min_keysize = DES_KEY_SIZE,1472		.max_keysize = DES_KEY_SIZE,1473		.ivsize = DES_BLOCK_SIZE,1474		.base = {1475			.cra_name = "cbc(des)",1476			.cra_driver_name = "safexcel-cbc-des",1477			.cra_priority = SAFEXCEL_CRA_PRIORITY,1478			.cra_flags = CRYPTO_ALG_ASYNC |1479				     CRYPTO_ALG_ALLOCATES_MEMORY |1480				     CRYPTO_ALG_KERN_DRIVER_ONLY,1481			.cra_blocksize = DES_BLOCK_SIZE,1482			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1483			.cra_alignmask = 0,1484			.cra_init = safexcel_skcipher_des_cbc_cra_init,1485			.cra_exit = safexcel_skcipher_cra_exit,1486			.cra_module = THIS_MODULE,1487		},1488	},1489};1490 1491static int safexcel_skcipher_des_ecb_cra_init(struct crypto_tfm *tfm)1492{1493	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1494 1495	safexcel_skcipher_cra_init(tfm);1496	ctx->alg  = SAFEXCEL_DES;1497	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;1498	ctx->blocksz = 0;1499	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1500	return 0;1501}1502 1503struct safexcel_alg_template safexcel_alg_ecb_des = {1504	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1505	.algo_mask = SAFEXCEL_ALG_DES,1506	.alg.skcipher = {1507		.setkey = safexcel_des_setkey,1508		.encrypt = safexcel_encrypt,1509		.decrypt = safexcel_decrypt,1510		.min_keysize = DES_KEY_SIZE,1511		.max_keysize = DES_KEY_SIZE,1512		.base = {1513			.cra_name = "ecb(des)",1514			.cra_driver_name = "safexcel-ecb-des",1515			.cra_priority = SAFEXCEL_CRA_PRIORITY,1516			.cra_flags = CRYPTO_ALG_ASYNC |1517				     CRYPTO_ALG_ALLOCATES_MEMORY |1518				     CRYPTO_ALG_KERN_DRIVER_ONLY,1519			.cra_blocksize = DES_BLOCK_SIZE,1520			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1521			.cra_alignmask = 0,1522			.cra_init = safexcel_skcipher_des_ecb_cra_init,1523			.cra_exit = safexcel_skcipher_cra_exit,1524			.cra_module = THIS_MODULE,1525		},1526	},1527};1528 1529static int safexcel_des3_ede_setkey(struct crypto_skcipher *ctfm,1530				   const u8 *key, unsigned int len)1531{1532	struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);1533	struct safexcel_crypto_priv *priv = ctx->base.priv;1534	int err;1535 1536	err = verify_skcipher_des3_key(ctfm, key);1537	if (err)1538		return err;1539 1540	/* if context exits and key changed, need to invalidate it */1541	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)1542		if (memcmp(ctx->key, key, len))1543			ctx->base.needs_inv = true;1544 1545	memcpy(ctx->key, key, len);1546	ctx->key_len = len;1547 1548	return 0;1549}1550 1551static int safexcel_skcipher_des3_cbc_cra_init(struct crypto_tfm *tfm)1552{1553	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1554 1555	safexcel_skcipher_cra_init(tfm);1556	ctx->alg  = SAFEXCEL_3DES;1557	ctx->blocksz = DES3_EDE_BLOCK_SIZE;1558	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1559	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;1560	return 0;1561}1562 1563struct safexcel_alg_template safexcel_alg_cbc_des3_ede = {1564	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1565	.algo_mask = SAFEXCEL_ALG_DES,1566	.alg.skcipher = {1567		.setkey = safexcel_des3_ede_setkey,1568		.encrypt = safexcel_encrypt,1569		.decrypt = safexcel_decrypt,1570		.min_keysize = DES3_EDE_KEY_SIZE,1571		.max_keysize = DES3_EDE_KEY_SIZE,1572		.ivsize = DES3_EDE_BLOCK_SIZE,1573		.base = {1574			.cra_name = "cbc(des3_ede)",1575			.cra_driver_name = "safexcel-cbc-des3_ede",1576			.cra_priority = SAFEXCEL_CRA_PRIORITY,1577			.cra_flags = CRYPTO_ALG_ASYNC |1578				     CRYPTO_ALG_ALLOCATES_MEMORY |1579				     CRYPTO_ALG_KERN_DRIVER_ONLY,1580			.cra_blocksize = DES3_EDE_BLOCK_SIZE,1581			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1582			.cra_alignmask = 0,1583			.cra_init = safexcel_skcipher_des3_cbc_cra_init,1584			.cra_exit = safexcel_skcipher_cra_exit,1585			.cra_module = THIS_MODULE,1586		},1587	},1588};1589 1590static int safexcel_skcipher_des3_ecb_cra_init(struct crypto_tfm *tfm)1591{1592	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1593 1594	safexcel_skcipher_cra_init(tfm);1595	ctx->alg  = SAFEXCEL_3DES;1596	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;1597	ctx->blocksz = 0;1598	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1599	return 0;1600}1601 1602struct safexcel_alg_template safexcel_alg_ecb_des3_ede = {1603	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1604	.algo_mask = SAFEXCEL_ALG_DES,1605	.alg.skcipher = {1606		.setkey = safexcel_des3_ede_setkey,1607		.encrypt = safexcel_encrypt,1608		.decrypt = safexcel_decrypt,1609		.min_keysize = DES3_EDE_KEY_SIZE,1610		.max_keysize = DES3_EDE_KEY_SIZE,1611		.base = {1612			.cra_name = "ecb(des3_ede)",1613			.cra_driver_name = "safexcel-ecb-des3_ede",1614			.cra_priority = SAFEXCEL_CRA_PRIORITY,1615			.cra_flags = CRYPTO_ALG_ASYNC |1616				     CRYPTO_ALG_ALLOCATES_MEMORY |1617				     CRYPTO_ALG_KERN_DRIVER_ONLY,1618			.cra_blocksize = DES3_EDE_BLOCK_SIZE,1619			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1620			.cra_alignmask = 0,1621			.cra_init = safexcel_skcipher_des3_ecb_cra_init,1622			.cra_exit = safexcel_skcipher_cra_exit,1623			.cra_module = THIS_MODULE,1624		},1625	},1626};1627 1628static int safexcel_aead_encrypt(struct aead_request *req)1629{1630	struct safexcel_cipher_req *creq = aead_request_ctx(req);1631 1632	return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);1633}1634 1635static int safexcel_aead_decrypt(struct aead_request *req)1636{1637	struct safexcel_cipher_req *creq = aead_request_ctx(req);1638 1639	return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);1640}1641 1642static int safexcel_aead_cra_init(struct crypto_tfm *tfm)1643{1644	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1645	struct safexcel_alg_template *tmpl =1646		container_of(tfm->__crt_alg, struct safexcel_alg_template,1647			     alg.aead.base);1648 1649	crypto_aead_set_reqsize(__crypto_aead_cast(tfm),1650				sizeof(struct safexcel_cipher_req));1651 1652	ctx->base.priv = tmpl->priv;1653 1654	ctx->alg  = SAFEXCEL_AES; /* default */1655	ctx->blocksz = AES_BLOCK_SIZE;1656	ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD;1657	ctx->ctrinit = 1;1658	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; /* default */1659	ctx->aead = true;1660	ctx->base.send = safexcel_aead_send;1661	ctx->base.handle_result = safexcel_aead_handle_result;1662	return 0;1663}1664 1665static int safexcel_aead_sha1_cra_init(struct crypto_tfm *tfm)1666{1667	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1668 1669	safexcel_aead_cra_init(tfm);1670	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;1671	ctx->state_sz = SHA1_DIGEST_SIZE;1672	return 0;1673}1674 1675struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_aes = {1676	.type = SAFEXCEL_ALG_TYPE_AEAD,1677	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1,1678	.alg.aead = {1679		.setkey = safexcel_aead_setkey,1680		.encrypt = safexcel_aead_encrypt,1681		.decrypt = safexcel_aead_decrypt,1682		.ivsize = AES_BLOCK_SIZE,1683		.maxauthsize = SHA1_DIGEST_SIZE,1684		.base = {1685			.cra_name = "authenc(hmac(sha1),cbc(aes))",1686			.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-aes",1687			.cra_priority = SAFEXCEL_CRA_PRIORITY,1688			.cra_flags = CRYPTO_ALG_ASYNC |1689				     CRYPTO_ALG_ALLOCATES_MEMORY |1690				     CRYPTO_ALG_KERN_DRIVER_ONLY,1691			.cra_blocksize = AES_BLOCK_SIZE,1692			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1693			.cra_alignmask = 0,1694			.cra_init = safexcel_aead_sha1_cra_init,1695			.cra_exit = safexcel_aead_cra_exit,1696			.cra_module = THIS_MODULE,1697		},1698	},1699};1700 1701static int safexcel_aead_sha256_cra_init(struct crypto_tfm *tfm)1702{1703	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1704 1705	safexcel_aead_cra_init(tfm);1706	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256;1707	ctx->state_sz = SHA256_DIGEST_SIZE;1708	return 0;1709}1710 1711struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_aes = {1712	.type = SAFEXCEL_ALG_TYPE_AEAD,1713	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,1714	.alg.aead = {1715		.setkey = safexcel_aead_setkey,1716		.encrypt = safexcel_aead_encrypt,1717		.decrypt = safexcel_aead_decrypt,1718		.ivsize = AES_BLOCK_SIZE,1719		.maxauthsize = SHA256_DIGEST_SIZE,1720		.base = {1721			.cra_name = "authenc(hmac(sha256),cbc(aes))",1722			.cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-aes",1723			.cra_priority = SAFEXCEL_CRA_PRIORITY,1724			.cra_flags = CRYPTO_ALG_ASYNC |1725				     CRYPTO_ALG_ALLOCATES_MEMORY |1726				     CRYPTO_ALG_KERN_DRIVER_ONLY,1727			.cra_blocksize = AES_BLOCK_SIZE,1728			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1729			.cra_alignmask = 0,1730			.cra_init = safexcel_aead_sha256_cra_init,1731			.cra_exit = safexcel_aead_cra_exit,1732			.cra_module = THIS_MODULE,1733		},1734	},1735};1736 1737static int safexcel_aead_sha224_cra_init(struct crypto_tfm *tfm)1738{1739	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1740 1741	safexcel_aead_cra_init(tfm);1742	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224;1743	ctx->state_sz = SHA256_DIGEST_SIZE;1744	return 0;1745}1746 1747struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_aes = {1748	.type = SAFEXCEL_ALG_TYPE_AEAD,1749	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,1750	.alg.aead = {1751		.setkey = safexcel_aead_setkey,1752		.encrypt = safexcel_aead_encrypt,1753		.decrypt = safexcel_aead_decrypt,1754		.ivsize = AES_BLOCK_SIZE,1755		.maxauthsize = SHA224_DIGEST_SIZE,1756		.base = {1757			.cra_name = "authenc(hmac(sha224),cbc(aes))",1758			.cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-aes",1759			.cra_priority = SAFEXCEL_CRA_PRIORITY,1760			.cra_flags = CRYPTO_ALG_ASYNC |1761				     CRYPTO_ALG_ALLOCATES_MEMORY |1762				     CRYPTO_ALG_KERN_DRIVER_ONLY,1763			.cra_blocksize = AES_BLOCK_SIZE,1764			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1765			.cra_alignmask = 0,1766			.cra_init = safexcel_aead_sha224_cra_init,1767			.cra_exit = safexcel_aead_cra_exit,1768			.cra_module = THIS_MODULE,1769		},1770	},1771};1772 1773static int safexcel_aead_sha512_cra_init(struct crypto_tfm *tfm)1774{1775	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1776 1777	safexcel_aead_cra_init(tfm);1778	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512;1779	ctx->state_sz = SHA512_DIGEST_SIZE;1780	return 0;1781}1782 1783struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_aes = {1784	.type = SAFEXCEL_ALG_TYPE_AEAD,1785	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,1786	.alg.aead = {1787		.setkey = safexcel_aead_setkey,1788		.encrypt = safexcel_aead_encrypt,1789		.decrypt = safexcel_aead_decrypt,1790		.ivsize = AES_BLOCK_SIZE,1791		.maxauthsize = SHA512_DIGEST_SIZE,1792		.base = {1793			.cra_name = "authenc(hmac(sha512),cbc(aes))",1794			.cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-aes",1795			.cra_priority = SAFEXCEL_CRA_PRIORITY,1796			.cra_flags = CRYPTO_ALG_ASYNC |1797				     CRYPTO_ALG_ALLOCATES_MEMORY |1798				     CRYPTO_ALG_KERN_DRIVER_ONLY,1799			.cra_blocksize = AES_BLOCK_SIZE,1800			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1801			.cra_alignmask = 0,1802			.cra_init = safexcel_aead_sha512_cra_init,1803			.cra_exit = safexcel_aead_cra_exit,1804			.cra_module = THIS_MODULE,1805		},1806	},1807};1808 1809static int safexcel_aead_sha384_cra_init(struct crypto_tfm *tfm)1810{1811	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1812 1813	safexcel_aead_cra_init(tfm);1814	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384;1815	ctx->state_sz = SHA512_DIGEST_SIZE;1816	return 0;1817}1818 1819struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_aes = {1820	.type = SAFEXCEL_ALG_TYPE_AEAD,1821	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,1822	.alg.aead = {1823		.setkey = safexcel_aead_setkey,1824		.encrypt = safexcel_aead_encrypt,1825		.decrypt = safexcel_aead_decrypt,1826		.ivsize = AES_BLOCK_SIZE,1827		.maxauthsize = SHA384_DIGEST_SIZE,1828		.base = {1829			.cra_name = "authenc(hmac(sha384),cbc(aes))",1830			.cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-aes",1831			.cra_priority = SAFEXCEL_CRA_PRIORITY,1832			.cra_flags = CRYPTO_ALG_ASYNC |1833				     CRYPTO_ALG_ALLOCATES_MEMORY |1834				     CRYPTO_ALG_KERN_DRIVER_ONLY,1835			.cra_blocksize = AES_BLOCK_SIZE,1836			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1837			.cra_alignmask = 0,1838			.cra_init = safexcel_aead_sha384_cra_init,1839			.cra_exit = safexcel_aead_cra_exit,1840			.cra_module = THIS_MODULE,1841		},1842	},1843};1844 1845static int safexcel_aead_sha1_des3_cra_init(struct crypto_tfm *tfm)1846{1847	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1848 1849	safexcel_aead_sha1_cra_init(tfm);1850	ctx->alg = SAFEXCEL_3DES; /* override default */1851	ctx->blocksz = DES3_EDE_BLOCK_SIZE;1852	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1853	return 0;1854}1855 1856struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des3_ede = {1857	.type = SAFEXCEL_ALG_TYPE_AEAD,1858	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1,1859	.alg.aead = {1860		.setkey = safexcel_aead_setkey,1861		.encrypt = safexcel_aead_encrypt,1862		.decrypt = safexcel_aead_decrypt,1863		.ivsize = DES3_EDE_BLOCK_SIZE,1864		.maxauthsize = SHA1_DIGEST_SIZE,1865		.base = {1866			.cra_name = "authenc(hmac(sha1),cbc(des3_ede))",1867			.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des3_ede",1868			.cra_priority = SAFEXCEL_CRA_PRIORITY,1869			.cra_flags = CRYPTO_ALG_ASYNC |1870				     CRYPTO_ALG_ALLOCATES_MEMORY |1871				     CRYPTO_ALG_KERN_DRIVER_ONLY,1872			.cra_blocksize = DES3_EDE_BLOCK_SIZE,1873			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1874			.cra_alignmask = 0,1875			.cra_init = safexcel_aead_sha1_des3_cra_init,1876			.cra_exit = safexcel_aead_cra_exit,1877			.cra_module = THIS_MODULE,1878		},1879	},1880};1881 1882static int safexcel_aead_sha256_des3_cra_init(struct crypto_tfm *tfm)1883{1884	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1885 1886	safexcel_aead_sha256_cra_init(tfm);1887	ctx->alg = SAFEXCEL_3DES; /* override default */1888	ctx->blocksz = DES3_EDE_BLOCK_SIZE;1889	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1890	return 0;1891}1892 1893struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede = {1894	.type = SAFEXCEL_ALG_TYPE_AEAD,1895	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,1896	.alg.aead = {1897		.setkey = safexcel_aead_setkey,1898		.encrypt = safexcel_aead_encrypt,1899		.decrypt = safexcel_aead_decrypt,1900		.ivsize = DES3_EDE_BLOCK_SIZE,1901		.maxauthsize = SHA256_DIGEST_SIZE,1902		.base = {1903			.cra_name = "authenc(hmac(sha256),cbc(des3_ede))",1904			.cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des3_ede",1905			.cra_priority = SAFEXCEL_CRA_PRIORITY,1906			.cra_flags = CRYPTO_ALG_ASYNC |1907				     CRYPTO_ALG_ALLOCATES_MEMORY |1908				     CRYPTO_ALG_KERN_DRIVER_ONLY,1909			.cra_blocksize = DES3_EDE_BLOCK_SIZE,1910			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1911			.cra_alignmask = 0,1912			.cra_init = safexcel_aead_sha256_des3_cra_init,1913			.cra_exit = safexcel_aead_cra_exit,1914			.cra_module = THIS_MODULE,1915		},1916	},1917};1918 1919static int safexcel_aead_sha224_des3_cra_init(struct crypto_tfm *tfm)1920{1921	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1922 1923	safexcel_aead_sha224_cra_init(tfm);1924	ctx->alg = SAFEXCEL_3DES; /* override default */1925	ctx->blocksz = DES3_EDE_BLOCK_SIZE;1926	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1927	return 0;1928}1929 1930struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede = {1931	.type = SAFEXCEL_ALG_TYPE_AEAD,1932	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,1933	.alg.aead = {1934		.setkey = safexcel_aead_setkey,1935		.encrypt = safexcel_aead_encrypt,1936		.decrypt = safexcel_aead_decrypt,1937		.ivsize = DES3_EDE_BLOCK_SIZE,1938		.maxauthsize = SHA224_DIGEST_SIZE,1939		.base = {1940			.cra_name = "authenc(hmac(sha224),cbc(des3_ede))",1941			.cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des3_ede",1942			.cra_priority = SAFEXCEL_CRA_PRIORITY,1943			.cra_flags = CRYPTO_ALG_ASYNC |1944				     CRYPTO_ALG_ALLOCATES_MEMORY |1945				     CRYPTO_ALG_KERN_DRIVER_ONLY,1946			.cra_blocksize = DES3_EDE_BLOCK_SIZE,1947			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1948			.cra_alignmask = 0,1949			.cra_init = safexcel_aead_sha224_des3_cra_init,1950			.cra_exit = safexcel_aead_cra_exit,1951			.cra_module = THIS_MODULE,1952		},1953	},1954};1955 1956static int safexcel_aead_sha512_des3_cra_init(struct crypto_tfm *tfm)1957{1958	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1959 1960	safexcel_aead_sha512_cra_init(tfm);1961	ctx->alg = SAFEXCEL_3DES; /* override default */1962	ctx->blocksz = DES3_EDE_BLOCK_SIZE;1963	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1964	return 0;1965}1966 1967struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede = {1968	.type = SAFEXCEL_ALG_TYPE_AEAD,1969	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,1970	.alg.aead = {1971		.setkey = safexcel_aead_setkey,1972		.encrypt = safexcel_aead_encrypt,1973		.decrypt = safexcel_aead_decrypt,1974		.ivsize = DES3_EDE_BLOCK_SIZE,1975		.maxauthsize = SHA512_DIGEST_SIZE,1976		.base = {1977			.cra_name = "authenc(hmac(sha512),cbc(des3_ede))",1978			.cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des3_ede",1979			.cra_priority = SAFEXCEL_CRA_PRIORITY,1980			.cra_flags = CRYPTO_ALG_ASYNC |1981				     CRYPTO_ALG_ALLOCATES_MEMORY |1982				     CRYPTO_ALG_KERN_DRIVER_ONLY,1983			.cra_blocksize = DES3_EDE_BLOCK_SIZE,1984			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1985			.cra_alignmask = 0,1986			.cra_init = safexcel_aead_sha512_des3_cra_init,1987			.cra_exit = safexcel_aead_cra_exit,1988			.cra_module = THIS_MODULE,1989		},1990	},1991};1992 1993static int safexcel_aead_sha384_des3_cra_init(struct crypto_tfm *tfm)1994{1995	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1996 1997	safexcel_aead_sha384_cra_init(tfm);1998	ctx->alg = SAFEXCEL_3DES; /* override default */1999	ctx->blocksz = DES3_EDE_BLOCK_SIZE;2000	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;2001	return 0;2002}2003 2004struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede = {2005	.type = SAFEXCEL_ALG_TYPE_AEAD,2006	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,2007	.alg.aead = {2008		.setkey = safexcel_aead_setkey,2009		.encrypt = safexcel_aead_encrypt,2010		.decrypt = safexcel_aead_decrypt,2011		.ivsize = DES3_EDE_BLOCK_SIZE,2012		.maxauthsize = SHA384_DIGEST_SIZE,2013		.base = {2014			.cra_name = "authenc(hmac(sha384),cbc(des3_ede))",2015			.cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des3_ede",2016			.cra_priority = SAFEXCEL_CRA_PRIORITY,2017			.cra_flags = CRYPTO_ALG_ASYNC |2018				     CRYPTO_ALG_ALLOCATES_MEMORY |2019				     CRYPTO_ALG_KERN_DRIVER_ONLY,2020			.cra_blocksize = DES3_EDE_BLOCK_SIZE,2021			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2022			.cra_alignmask = 0,2023			.cra_init = safexcel_aead_sha384_des3_cra_init,2024			.cra_exit = safexcel_aead_cra_exit,2025			.cra_module = THIS_MODULE,2026		},2027	},2028};2029 2030static int safexcel_aead_sha1_des_cra_init(struct crypto_tfm *tfm)2031{2032	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2033 2034	safexcel_aead_sha1_cra_init(tfm);2035	ctx->alg = SAFEXCEL_DES; /* override default */2036	ctx->blocksz = DES_BLOCK_SIZE;2037	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;2038	return 0;2039}2040 2041struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des = {2042	.type = SAFEXCEL_ALG_TYPE_AEAD,2043	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1,2044	.alg.aead = {2045		.setkey = safexcel_aead_setkey,2046		.encrypt = safexcel_aead_encrypt,2047		.decrypt = safexcel_aead_decrypt,2048		.ivsize = DES_BLOCK_SIZE,2049		.maxauthsize = SHA1_DIGEST_SIZE,2050		.base = {2051			.cra_name = "authenc(hmac(sha1),cbc(des))",2052			.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des",2053			.cra_priority = SAFEXCEL_CRA_PRIORITY,2054			.cra_flags = CRYPTO_ALG_ASYNC |2055				     CRYPTO_ALG_ALLOCATES_MEMORY |2056				     CRYPTO_ALG_KERN_DRIVER_ONLY,2057			.cra_blocksize = DES_BLOCK_SIZE,2058			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2059			.cra_alignmask = 0,2060			.cra_init = safexcel_aead_sha1_des_cra_init,2061			.cra_exit = safexcel_aead_cra_exit,2062			.cra_module = THIS_MODULE,2063		},2064	},2065};2066 2067static int safexcel_aead_sha256_des_cra_init(struct crypto_tfm *tfm)2068{2069	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2070 2071	safexcel_aead_sha256_cra_init(tfm);2072	ctx->alg = SAFEXCEL_DES; /* override default */2073	ctx->blocksz = DES_BLOCK_SIZE;2074	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;2075	return 0;2076}2077 2078struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des = {2079	.type = SAFEXCEL_ALG_TYPE_AEAD,2080	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,2081	.alg.aead = {2082		.setkey = safexcel_aead_setkey,2083		.encrypt = safexcel_aead_encrypt,2084		.decrypt = safexcel_aead_decrypt,2085		.ivsize = DES_BLOCK_SIZE,2086		.maxauthsize = SHA256_DIGEST_SIZE,2087		.base = {2088			.cra_name = "authenc(hmac(sha256),cbc(des))",2089			.cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des",2090			.cra_priority = SAFEXCEL_CRA_PRIORITY,2091			.cra_flags = CRYPTO_ALG_ASYNC |2092				     CRYPTO_ALG_ALLOCATES_MEMORY |2093				     CRYPTO_ALG_KERN_DRIVER_ONLY,2094			.cra_blocksize = DES_BLOCK_SIZE,2095			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2096			.cra_alignmask = 0,2097			.cra_init = safexcel_aead_sha256_des_cra_init,2098			.cra_exit = safexcel_aead_cra_exit,2099			.cra_module = THIS_MODULE,2100		},2101	},2102};2103 2104static int safexcel_aead_sha224_des_cra_init(struct crypto_tfm *tfm)2105{2106	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2107 2108	safexcel_aead_sha224_cra_init(tfm);2109	ctx->alg = SAFEXCEL_DES; /* override default */2110	ctx->blocksz = DES_BLOCK_SIZE;2111	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;2112	return 0;2113}2114 2115struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des = {2116	.type = SAFEXCEL_ALG_TYPE_AEAD,2117	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,2118	.alg.aead = {2119		.setkey = safexcel_aead_setkey,2120		.encrypt = safexcel_aead_encrypt,2121		.decrypt = safexcel_aead_decrypt,2122		.ivsize = DES_BLOCK_SIZE,2123		.maxauthsize = SHA224_DIGEST_SIZE,2124		.base = {2125			.cra_name = "authenc(hmac(sha224),cbc(des))",2126			.cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des",2127			.cra_priority = SAFEXCEL_CRA_PRIORITY,2128			.cra_flags = CRYPTO_ALG_ASYNC |2129				     CRYPTO_ALG_ALLOCATES_MEMORY |2130				     CRYPTO_ALG_KERN_DRIVER_ONLY,2131			.cra_blocksize = DES_BLOCK_SIZE,2132			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2133			.cra_alignmask = 0,2134			.cra_init = safexcel_aead_sha224_des_cra_init,2135			.cra_exit = safexcel_aead_cra_exit,2136			.cra_module = THIS_MODULE,2137		},2138	},2139};2140 2141static int safexcel_aead_sha512_des_cra_init(struct crypto_tfm *tfm)2142{2143	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2144 2145	safexcel_aead_sha512_cra_init(tfm);2146	ctx->alg = SAFEXCEL_DES; /* override default */2147	ctx->blocksz = DES_BLOCK_SIZE;2148	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;2149	return 0;2150}2151 2152struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des = {2153	.type = SAFEXCEL_ALG_TYPE_AEAD,2154	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,2155	.alg.aead = {2156		.setkey = safexcel_aead_setkey,2157		.encrypt = safexcel_aead_encrypt,2158		.decrypt = safexcel_aead_decrypt,2159		.ivsize = DES_BLOCK_SIZE,2160		.maxauthsize = SHA512_DIGEST_SIZE,2161		.base = {2162			.cra_name = "authenc(hmac(sha512),cbc(des))",2163			.cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des",2164			.cra_priority = SAFEXCEL_CRA_PRIORITY,2165			.cra_flags = CRYPTO_ALG_ASYNC |2166				     CRYPTO_ALG_ALLOCATES_MEMORY |2167				     CRYPTO_ALG_KERN_DRIVER_ONLY,2168			.cra_blocksize = DES_BLOCK_SIZE,2169			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2170			.cra_alignmask = 0,2171			.cra_init = safexcel_aead_sha512_des_cra_init,2172			.cra_exit = safexcel_aead_cra_exit,2173			.cra_module = THIS_MODULE,2174		},2175	},2176};2177 2178static int safexcel_aead_sha384_des_cra_init(struct crypto_tfm *tfm)2179{2180	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2181 2182	safexcel_aead_sha384_cra_init(tfm);2183	ctx->alg = SAFEXCEL_DES; /* override default */2184	ctx->blocksz = DES_BLOCK_SIZE;2185	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;2186	return 0;2187}2188 2189struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des = {2190	.type = SAFEXCEL_ALG_TYPE_AEAD,2191	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,2192	.alg.aead = {2193		.setkey = safexcel_aead_setkey,2194		.encrypt = safexcel_aead_encrypt,2195		.decrypt = safexcel_aead_decrypt,2196		.ivsize = DES_BLOCK_SIZE,2197		.maxauthsize = SHA384_DIGEST_SIZE,2198		.base = {2199			.cra_name = "authenc(hmac(sha384),cbc(des))",2200			.cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des",2201			.cra_priority = SAFEXCEL_CRA_PRIORITY,2202			.cra_flags = CRYPTO_ALG_ASYNC |2203				     CRYPTO_ALG_ALLOCATES_MEMORY |2204				     CRYPTO_ALG_KERN_DRIVER_ONLY,2205			.cra_blocksize = DES_BLOCK_SIZE,2206			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2207			.cra_alignmask = 0,2208			.cra_init = safexcel_aead_sha384_des_cra_init,2209			.cra_exit = safexcel_aead_cra_exit,2210			.cra_module = THIS_MODULE,2211		},2212	},2213};2214 2215static int safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm *tfm)2216{2217	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2218 2219	safexcel_aead_sha1_cra_init(tfm);2220	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */2221	return 0;2222}2223 2224struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_aes = {2225	.type = SAFEXCEL_ALG_TYPE_AEAD,2226	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1,2227	.alg.aead = {2228		.setkey = safexcel_aead_setkey,2229		.encrypt = safexcel_aead_encrypt,2230		.decrypt = safexcel_aead_decrypt,2231		.ivsize = CTR_RFC3686_IV_SIZE,2232		.maxauthsize = SHA1_DIGEST_SIZE,2233		.base = {2234			.cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))",2235			.cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-aes",2236			.cra_priority = SAFEXCEL_CRA_PRIORITY,2237			.cra_flags = CRYPTO_ALG_ASYNC |2238				     CRYPTO_ALG_ALLOCATES_MEMORY |2239				     CRYPTO_ALG_KERN_DRIVER_ONLY,2240			.cra_blocksize = 1,2241			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2242			.cra_alignmask = 0,2243			.cra_init = safexcel_aead_sha1_ctr_cra_init,2244			.cra_exit = safexcel_aead_cra_exit,2245			.cra_module = THIS_MODULE,2246		},2247	},2248};2249 2250static int safexcel_aead_sha256_ctr_cra_init(struct crypto_tfm *tfm)2251{2252	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2253 2254	safexcel_aead_sha256_cra_init(tfm);2255	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */2256	return 0;2257}2258 2259struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes = {2260	.type = SAFEXCEL_ALG_TYPE_AEAD,2261	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,2262	.alg.aead = {2263		.setkey = safexcel_aead_setkey,2264		.encrypt = safexcel_aead_encrypt,2265		.decrypt = safexcel_aead_decrypt,2266		.ivsize = CTR_RFC3686_IV_SIZE,2267		.maxauthsize = SHA256_DIGEST_SIZE,2268		.base = {2269			.cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))",2270			.cra_driver_name = "safexcel-authenc-hmac-sha256-ctr-aes",2271			.cra_priority = SAFEXCEL_CRA_PRIORITY,2272			.cra_flags = CRYPTO_ALG_ASYNC |2273				     CRYPTO_ALG_ALLOCATES_MEMORY |2274				     CRYPTO_ALG_KERN_DRIVER_ONLY,2275			.cra_blocksize = 1,2276			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2277			.cra_alignmask = 0,2278			.cra_init = safexcel_aead_sha256_ctr_cra_init,2279			.cra_exit = safexcel_aead_cra_exit,2280			.cra_module = THIS_MODULE,2281		},2282	},2283};2284 2285static int safexcel_aead_sha224_ctr_cra_init(struct crypto_tfm *tfm)2286{2287	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2288 2289	safexcel_aead_sha224_cra_init(tfm);2290	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */2291	return 0;2292}2293 2294struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_ctr_aes = {2295	.type = SAFEXCEL_ALG_TYPE_AEAD,2296	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,2297	.alg.aead = {2298		.setkey = safexcel_aead_setkey,2299		.encrypt = safexcel_aead_encrypt,2300		.decrypt = safexcel_aead_decrypt,2301		.ivsize = CTR_RFC3686_IV_SIZE,2302		.maxauthsize = SHA224_DIGEST_SIZE,2303		.base = {2304			.cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))",2305			.cra_driver_name = "safexcel-authenc-hmac-sha224-ctr-aes",2306			.cra_priority = SAFEXCEL_CRA_PRIORITY,2307			.cra_flags = CRYPTO_ALG_ASYNC |2308				     CRYPTO_ALG_ALLOCATES_MEMORY |2309				     CRYPTO_ALG_KERN_DRIVER_ONLY,2310			.cra_blocksize = 1,2311			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2312			.cra_alignmask = 0,2313			.cra_init = safexcel_aead_sha224_ctr_cra_init,2314			.cra_exit = safexcel_aead_cra_exit,2315			.cra_module = THIS_MODULE,2316		},2317	},2318};2319 2320static int safexcel_aead_sha512_ctr_cra_init(struct crypto_tfm *tfm)2321{2322	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2323 2324	safexcel_aead_sha512_cra_init(tfm);2325	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */2326	return 0;2327}2328 2329struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes = {2330	.type = SAFEXCEL_ALG_TYPE_AEAD,2331	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,2332	.alg.aead = {2333		.setkey = safexcel_aead_setkey,2334		.encrypt = safexcel_aead_encrypt,2335		.decrypt = safexcel_aead_decrypt,2336		.ivsize = CTR_RFC3686_IV_SIZE,2337		.maxauthsize = SHA512_DIGEST_SIZE,2338		.base = {2339			.cra_name = "authenc(hmac(sha512),rfc3686(ctr(aes)))",2340			.cra_driver_name = "safexcel-authenc-hmac-sha512-ctr-aes",2341			.cra_priority = SAFEXCEL_CRA_PRIORITY,2342			.cra_flags = CRYPTO_ALG_ASYNC |2343				     CRYPTO_ALG_ALLOCATES_MEMORY |2344				     CRYPTO_ALG_KERN_DRIVER_ONLY,2345			.cra_blocksize = 1,2346			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2347			.cra_alignmask = 0,2348			.cra_init = safexcel_aead_sha512_ctr_cra_init,2349			.cra_exit = safexcel_aead_cra_exit,2350			.cra_module = THIS_MODULE,2351		},2352	},2353};2354 2355static int safexcel_aead_sha384_ctr_cra_init(struct crypto_tfm *tfm)2356{2357	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2358 2359	safexcel_aead_sha384_cra_init(tfm);2360	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */2361	return 0;2362}2363 2364struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes = {2365	.type = SAFEXCEL_ALG_TYPE_AEAD,2366	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,2367	.alg.aead = {2368		.setkey = safexcel_aead_setkey,2369		.encrypt = safexcel_aead_encrypt,2370		.decrypt = safexcel_aead_decrypt,2371		.ivsize = CTR_RFC3686_IV_SIZE,2372		.maxauthsize = SHA384_DIGEST_SIZE,2373		.base = {2374			.cra_name = "authenc(hmac(sha384),rfc3686(ctr(aes)))",2375			.cra_driver_name = "safexcel-authenc-hmac-sha384-ctr-aes",2376			.cra_priority = SAFEXCEL_CRA_PRIORITY,2377			.cra_flags = CRYPTO_ALG_ASYNC |2378				     CRYPTO_ALG_ALLOCATES_MEMORY |2379				     CRYPTO_ALG_KERN_DRIVER_ONLY,2380			.cra_blocksize = 1,2381			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2382			.cra_alignmask = 0,2383			.cra_init = safexcel_aead_sha384_ctr_cra_init,2384			.cra_exit = safexcel_aead_cra_exit,2385			.cra_module = THIS_MODULE,2386		},2387	},2388};2389 2390static int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm,2391					   const u8 *key, unsigned int len)2392{2393	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);2394	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2395	struct safexcel_crypto_priv *priv = ctx->base.priv;2396	struct crypto_aes_ctx aes;2397	int ret, i;2398	unsigned int keylen;2399 2400	/* Check for illegal XTS keys */2401	ret = xts_verify_key(ctfm, key, len);2402	if (ret)2403		return ret;2404 2405	/* Only half of the key data is cipher key */2406	keylen = (len >> 1);2407	ret = aes_expandkey(&aes, key, keylen);2408	if (ret)2409		return ret;2410 2411	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {2412		for (i = 0; i < keylen / sizeof(u32); i++) {2413			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {2414				ctx->base.needs_inv = true;2415				break;2416			}2417		}2418	}2419 2420	for (i = 0; i < keylen / sizeof(u32); i++)2421		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);2422 2423	/* The other half is the tweak key */2424	ret = aes_expandkey(&aes, (u8 *)(key + keylen), keylen);2425	if (ret)2426		return ret;2427 2428	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {2429		for (i = 0; i < keylen / sizeof(u32); i++) {2430			if (le32_to_cpu(ctx->key[i + keylen / sizeof(u32)]) !=2431			    aes.key_enc[i]) {2432				ctx->base.needs_inv = true;2433				break;2434			}2435		}2436	}2437 2438	for (i = 0; i < keylen / sizeof(u32); i++)2439		ctx->key[i + keylen / sizeof(u32)] =2440			cpu_to_le32(aes.key_enc[i]);2441 2442	ctx->key_len = keylen << 1;2443 2444	memzero_explicit(&aes, sizeof(aes));2445	return 0;2446}2447 2448static int safexcel_skcipher_aes_xts_cra_init(struct crypto_tfm *tfm)2449{2450	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2451 2452	safexcel_skcipher_cra_init(tfm);2453	ctx->alg  = SAFEXCEL_AES;2454	ctx->blocksz = AES_BLOCK_SIZE;2455	ctx->xts  = 1;2456	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS;2457	return 0;2458}2459 2460static int safexcel_encrypt_xts(struct skcipher_request *req)2461{2462	if (req->cryptlen < XTS_BLOCK_SIZE)2463		return -EINVAL;2464	return safexcel_queue_req(&req->base, skcipher_request_ctx(req),2465				  SAFEXCEL_ENCRYPT);2466}2467 2468static int safexcel_decrypt_xts(struct skcipher_request *req)2469{2470	if (req->cryptlen < XTS_BLOCK_SIZE)2471		return -EINVAL;2472	return safexcel_queue_req(&req->base, skcipher_request_ctx(req),2473				  SAFEXCEL_DECRYPT);2474}2475 2476struct safexcel_alg_template safexcel_alg_xts_aes = {2477	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,2478	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XTS,2479	.alg.skcipher = {2480		.setkey = safexcel_skcipher_aesxts_setkey,2481		.encrypt = safexcel_encrypt_xts,2482		.decrypt = safexcel_decrypt_xts,2483		/* XTS actually uses 2 AES keys glued together */2484		.min_keysize = AES_MIN_KEY_SIZE * 2,2485		.max_keysize = AES_MAX_KEY_SIZE * 2,2486		.ivsize = XTS_BLOCK_SIZE,2487		.base = {2488			.cra_name = "xts(aes)",2489			.cra_driver_name = "safexcel-xts-aes",2490			.cra_priority = SAFEXCEL_CRA_PRIORITY,2491			.cra_flags = CRYPTO_ALG_ASYNC |2492				     CRYPTO_ALG_ALLOCATES_MEMORY |2493				     CRYPTO_ALG_KERN_DRIVER_ONLY,2494			.cra_blocksize = XTS_BLOCK_SIZE,2495			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2496			.cra_alignmask = 0,2497			.cra_init = safexcel_skcipher_aes_xts_cra_init,2498			.cra_exit = safexcel_skcipher_cra_exit,2499			.cra_module = THIS_MODULE,2500		},2501	},2502};2503 2504static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key,2505				    unsigned int len)2506{2507	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);2508	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2509	struct safexcel_crypto_priv *priv = ctx->base.priv;2510	struct crypto_aes_ctx aes;2511	u32 hashkey[AES_BLOCK_SIZE >> 2];2512	int ret, i;2513 2514	ret = aes_expandkey(&aes, key, len);2515	if (ret) {2516		memzero_explicit(&aes, sizeof(aes));2517		return ret;2518	}2519 2520	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {2521		for (i = 0; i < len / sizeof(u32); i++) {2522			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {2523				ctx->base.needs_inv = true;2524				break;2525			}2526		}2527	}2528 2529	for (i = 0; i < len / sizeof(u32); i++)2530		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);2531 2532	ctx->key_len = len;2533 2534	/* Compute hash key by encrypting zeroes with cipher key */2535	memset(hashkey, 0, AES_BLOCK_SIZE);2536	aes_encrypt(&aes, (u8 *)hashkey, (u8 *)hashkey);2537 2538	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {2539		for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) {2540			if (be32_to_cpu(ctx->base.ipad.be[i]) != hashkey[i]) {2541				ctx->base.needs_inv = true;2542				break;2543			}2544		}2545	}2546 2547	for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++)2548		ctx->base.ipad.be[i] = cpu_to_be32(hashkey[i]);2549 2550	memzero_explicit(hashkey, AES_BLOCK_SIZE);2551	memzero_explicit(&aes, sizeof(aes));2552	return 0;2553}2554 2555static int safexcel_aead_gcm_cra_init(struct crypto_tfm *tfm)2556{2557	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2558 2559	safexcel_aead_cra_init(tfm);2560	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_GHASH;2561	ctx->state_sz = GHASH_BLOCK_SIZE;2562	ctx->xcm = EIP197_XCM_MODE_GCM;2563	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */2564 2565	return 0;2566}2567 2568static void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm)2569{2570	safexcel_aead_cra_exit(tfm);2571}2572 2573static int safexcel_aead_gcm_setauthsize(struct crypto_aead *tfm,2574					 unsigned int authsize)2575{2576	return crypto_gcm_check_authsize(authsize);2577}2578 2579struct safexcel_alg_template safexcel_alg_gcm = {2580	.type = SAFEXCEL_ALG_TYPE_AEAD,2581	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,2582	.alg.aead = {2583		.setkey = safexcel_aead_gcm_setkey,2584		.setauthsize = safexcel_aead_gcm_setauthsize,2585		.encrypt = safexcel_aead_encrypt,2586		.decrypt = safexcel_aead_decrypt,2587		.ivsize = GCM_AES_IV_SIZE,2588		.maxauthsize = GHASH_DIGEST_SIZE,2589		.base = {2590			.cra_name = "gcm(aes)",2591			.cra_driver_name = "safexcel-gcm-aes",2592			.cra_priority = SAFEXCEL_CRA_PRIORITY,2593			.cra_flags = CRYPTO_ALG_ASYNC |2594				     CRYPTO_ALG_ALLOCATES_MEMORY |2595				     CRYPTO_ALG_KERN_DRIVER_ONLY,2596			.cra_blocksize = 1,2597			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2598			.cra_alignmask = 0,2599			.cra_init = safexcel_aead_gcm_cra_init,2600			.cra_exit = safexcel_aead_gcm_cra_exit,2601			.cra_module = THIS_MODULE,2602		},2603	},2604};2605 2606static int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key,2607				    unsigned int len)2608{2609	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);2610	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2611	struct safexcel_crypto_priv *priv = ctx->base.priv;2612	struct crypto_aes_ctx aes;2613	int ret, i;2614 2615	ret = aes_expandkey(&aes, key, len);2616	if (ret) {2617		memzero_explicit(&aes, sizeof(aes));2618		return ret;2619	}2620 2621	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {2622		for (i = 0; i < len / sizeof(u32); i++) {2623			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {2624				ctx->base.needs_inv = true;2625				break;2626			}2627		}2628	}2629 2630	for (i = 0; i < len / sizeof(u32); i++) {2631		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);2632		ctx->base.ipad.be[i + 2 * AES_BLOCK_SIZE / sizeof(u32)] =2633			cpu_to_be32(aes.key_enc[i]);2634	}2635 2636	ctx->key_len = len;2637	ctx->state_sz = 2 * AES_BLOCK_SIZE + len;2638 2639	if (len == AES_KEYSIZE_192)2640		ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192;2641	else if (len == AES_KEYSIZE_256)2642		ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256;2643	else2644		ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128;2645 2646	memzero_explicit(&aes, sizeof(aes));2647	return 0;2648}2649 2650static int safexcel_aead_ccm_cra_init(struct crypto_tfm *tfm)2651{2652	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2653 2654	safexcel_aead_cra_init(tfm);2655	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128;2656	ctx->state_sz = 3 * AES_BLOCK_SIZE;2657	ctx->xcm = EIP197_XCM_MODE_CCM;2658	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */2659	ctx->ctrinit = 0;2660	return 0;2661}2662 2663static int safexcel_aead_ccm_setauthsize(struct crypto_aead *tfm,2664					 unsigned int authsize)2665{2666	/* Borrowed from crypto/ccm.c */2667	switch (authsize) {2668	case 4:2669	case 6:2670	case 8:2671	case 10:2672	case 12:2673	case 14:2674	case 16:2675		break;2676	default:2677		return -EINVAL;2678	}2679 2680	return 0;2681}2682 2683static int safexcel_ccm_encrypt(struct aead_request *req)2684{2685	struct safexcel_cipher_req *creq = aead_request_ctx(req);2686 2687	if (req->iv[0] < 1 || req->iv[0] > 7)2688		return -EINVAL;2689 2690	return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);2691}2692 2693static int safexcel_ccm_decrypt(struct aead_request *req)2694{2695	struct safexcel_cipher_req *creq = aead_request_ctx(req);2696 2697	if (req->iv[0] < 1 || req->iv[0] > 7)2698		return -EINVAL;2699 2700	return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);2701}2702 2703struct safexcel_alg_template safexcel_alg_ccm = {2704	.type = SAFEXCEL_ALG_TYPE_AEAD,2705	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL,2706	.alg.aead = {2707		.setkey = safexcel_aead_ccm_setkey,2708		.setauthsize = safexcel_aead_ccm_setauthsize,2709		.encrypt = safexcel_ccm_encrypt,2710		.decrypt = safexcel_ccm_decrypt,2711		.ivsize = AES_BLOCK_SIZE,2712		.maxauthsize = AES_BLOCK_SIZE,2713		.base = {2714			.cra_name = "ccm(aes)",2715			.cra_driver_name = "safexcel-ccm-aes",2716			.cra_priority = SAFEXCEL_CRA_PRIORITY,2717			.cra_flags = CRYPTO_ALG_ASYNC |2718				     CRYPTO_ALG_ALLOCATES_MEMORY |2719				     CRYPTO_ALG_KERN_DRIVER_ONLY,2720			.cra_blocksize = 1,2721			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2722			.cra_alignmask = 0,2723			.cra_init = safexcel_aead_ccm_cra_init,2724			.cra_exit = safexcel_aead_cra_exit,2725			.cra_module = THIS_MODULE,2726		},2727	},2728};2729 2730static void safexcel_chacha20_setkey(struct safexcel_cipher_ctx *ctx,2731				     const u8 *key)2732{2733	struct safexcel_crypto_priv *priv = ctx->base.priv;2734 2735	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)2736		if (memcmp(ctx->key, key, CHACHA_KEY_SIZE))2737			ctx->base.needs_inv = true;2738 2739	memcpy(ctx->key, key, CHACHA_KEY_SIZE);2740	ctx->key_len = CHACHA_KEY_SIZE;2741}2742 2743static int safexcel_skcipher_chacha20_setkey(struct crypto_skcipher *ctfm,2744					     const u8 *key, unsigned int len)2745{2746	struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);2747 2748	if (len != CHACHA_KEY_SIZE)2749		return -EINVAL;2750 2751	safexcel_chacha20_setkey(ctx, key);2752 2753	return 0;2754}2755 2756static int safexcel_skcipher_chacha20_cra_init(struct crypto_tfm *tfm)2757{2758	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2759 2760	safexcel_skcipher_cra_init(tfm);2761	ctx->alg  = SAFEXCEL_CHACHA20;2762	ctx->ctrinit = 0;2763	ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32;2764	return 0;2765}2766 2767struct safexcel_alg_template safexcel_alg_chacha20 = {2768	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,2769	.algo_mask = SAFEXCEL_ALG_CHACHA20,2770	.alg.skcipher = {2771		.setkey = safexcel_skcipher_chacha20_setkey,2772		.encrypt = safexcel_encrypt,2773		.decrypt = safexcel_decrypt,2774		.min_keysize = CHACHA_KEY_SIZE,2775		.max_keysize = CHACHA_KEY_SIZE,2776		.ivsize = CHACHA_IV_SIZE,2777		.base = {2778			.cra_name = "chacha20",2779			.cra_driver_name = "safexcel-chacha20",2780			.cra_priority = SAFEXCEL_CRA_PRIORITY,2781			.cra_flags = CRYPTO_ALG_ASYNC |2782				     CRYPTO_ALG_ALLOCATES_MEMORY |2783				     CRYPTO_ALG_KERN_DRIVER_ONLY,2784			.cra_blocksize = 1,2785			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2786			.cra_alignmask = 0,2787			.cra_init = safexcel_skcipher_chacha20_cra_init,2788			.cra_exit = safexcel_skcipher_cra_exit,2789			.cra_module = THIS_MODULE,2790		},2791	},2792};2793 2794static int safexcel_aead_chachapoly_setkey(struct crypto_aead *ctfm,2795				    const u8 *key, unsigned int len)2796{2797	struct safexcel_cipher_ctx *ctx = crypto_aead_ctx(ctfm);2798 2799	if (ctx->aead  == EIP197_AEAD_TYPE_IPSEC_ESP &&2800	    len > EIP197_AEAD_IPSEC_NONCE_SIZE) {2801		/* ESP variant has nonce appended to key */2802		len -= EIP197_AEAD_IPSEC_NONCE_SIZE;2803		ctx->nonce = *(u32 *)(key + len);2804	}2805	if (len != CHACHA_KEY_SIZE)2806		return -EINVAL;2807 2808	safexcel_chacha20_setkey(ctx, key);2809 2810	return 0;2811}2812 2813static int safexcel_aead_chachapoly_setauthsize(struct crypto_aead *tfm,2814					 unsigned int authsize)2815{2816	if (authsize != POLY1305_DIGEST_SIZE)2817		return -EINVAL;2818	return 0;2819}2820 2821static int safexcel_aead_chachapoly_crypt(struct aead_request *req,2822					  enum safexcel_cipher_direction dir)2823{2824	struct safexcel_cipher_req *creq = aead_request_ctx(req);2825	struct crypto_aead *aead = crypto_aead_reqtfm(req);2826	struct crypto_tfm *tfm = crypto_aead_tfm(aead);2827	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2828	struct aead_request *subreq = aead_request_ctx(req);2829	u32 key[CHACHA_KEY_SIZE / sizeof(u32) + 1];2830	int ret = 0;2831 2832	/*2833	 * Instead of wasting time detecting umpteen silly corner cases,2834	 * just dump all "small" requests to the fallback implementation.2835	 * HW would not be faster on such small requests anyway.2836	 */2837	if (likely((ctx->aead != EIP197_AEAD_TYPE_IPSEC_ESP ||2838		    req->assoclen >= EIP197_AEAD_IPSEC_IV_SIZE) &&2839		   req->cryptlen > POLY1305_DIGEST_SIZE)) {2840		return safexcel_queue_req(&req->base, creq, dir);2841	}2842 2843	/* HW cannot do full (AAD+payload) zero length, use fallback */2844	memcpy(key, ctx->key, CHACHA_KEY_SIZE);2845	if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {2846		/* ESP variant has nonce appended to the key */2847		key[CHACHA_KEY_SIZE / sizeof(u32)] = ctx->nonce;2848		ret = crypto_aead_setkey(ctx->fback, (u8 *)key,2849					 CHACHA_KEY_SIZE +2850					 EIP197_AEAD_IPSEC_NONCE_SIZE);2851	} else {2852		ret = crypto_aead_setkey(ctx->fback, (u8 *)key,2853					 CHACHA_KEY_SIZE);2854	}2855	if (ret) {2856		crypto_aead_clear_flags(aead, CRYPTO_TFM_REQ_MASK);2857		crypto_aead_set_flags(aead, crypto_aead_get_flags(ctx->fback) &2858					    CRYPTO_TFM_REQ_MASK);2859		return ret;2860	}2861 2862	aead_request_set_tfm(subreq, ctx->fback);2863	aead_request_set_callback(subreq, req->base.flags, req->base.complete,2864				  req->base.data);2865	aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,2866			       req->iv);2867	aead_request_set_ad(subreq, req->assoclen);2868 2869	return (dir ==  SAFEXCEL_ENCRYPT) ?2870		crypto_aead_encrypt(subreq) :2871		crypto_aead_decrypt(subreq);2872}2873 2874static int safexcel_aead_chachapoly_encrypt(struct aead_request *req)2875{2876	return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_ENCRYPT);2877}2878 2879static int safexcel_aead_chachapoly_decrypt(struct aead_request *req)2880{2881	return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_DECRYPT);2882}2883 2884static int safexcel_aead_fallback_cra_init(struct crypto_tfm *tfm)2885{2886	struct crypto_aead *aead = __crypto_aead_cast(tfm);2887	struct aead_alg *alg = crypto_aead_alg(aead);2888	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2889 2890	safexcel_aead_cra_init(tfm);2891 2892	/* Allocate fallback implementation */2893	ctx->fback = crypto_alloc_aead(alg->base.cra_name, 0,2894				       CRYPTO_ALG_ASYNC |2895				       CRYPTO_ALG_NEED_FALLBACK);2896	if (IS_ERR(ctx->fback))2897		return PTR_ERR(ctx->fback);2898 2899	crypto_aead_set_reqsize(aead, max(sizeof(struct safexcel_cipher_req),2900					  sizeof(struct aead_request) +2901					  crypto_aead_reqsize(ctx->fback)));2902 2903	return 0;2904}2905 2906static int safexcel_aead_chachapoly_cra_init(struct crypto_tfm *tfm)2907{2908	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2909 2910	safexcel_aead_fallback_cra_init(tfm);2911	ctx->alg  = SAFEXCEL_CHACHA20;2912	ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32 |2913		    CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK;2914	ctx->ctrinit = 0;2915	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_POLY1305;2916	ctx->state_sz = 0; /* Precomputed by HW */2917	return 0;2918}2919 2920static void safexcel_aead_fallback_cra_exit(struct crypto_tfm *tfm)2921{2922	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2923 2924	crypto_free_aead(ctx->fback);2925	safexcel_aead_cra_exit(tfm);2926}2927 2928struct safexcel_alg_template safexcel_alg_chachapoly = {2929	.type = SAFEXCEL_ALG_TYPE_AEAD,2930	.algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305,2931	.alg.aead = {2932		.setkey = safexcel_aead_chachapoly_setkey,2933		.setauthsize = safexcel_aead_chachapoly_setauthsize,2934		.encrypt = safexcel_aead_chachapoly_encrypt,2935		.decrypt = safexcel_aead_chachapoly_decrypt,2936		.ivsize = CHACHAPOLY_IV_SIZE,2937		.maxauthsize = POLY1305_DIGEST_SIZE,2938		.base = {2939			.cra_name = "rfc7539(chacha20,poly1305)",2940			.cra_driver_name = "safexcel-chacha20-poly1305",2941			/* +1 to put it above HW chacha + SW poly */2942			.cra_priority = SAFEXCEL_CRA_PRIORITY + 1,2943			.cra_flags = CRYPTO_ALG_ASYNC |2944				     CRYPTO_ALG_ALLOCATES_MEMORY |2945				     CRYPTO_ALG_KERN_DRIVER_ONLY |2946				     CRYPTO_ALG_NEED_FALLBACK,2947			.cra_blocksize = 1,2948			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2949			.cra_alignmask = 0,2950			.cra_init = safexcel_aead_chachapoly_cra_init,2951			.cra_exit = safexcel_aead_fallback_cra_exit,2952			.cra_module = THIS_MODULE,2953		},2954	},2955};2956 2957static int safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm *tfm)2958{2959	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2960	int ret;2961 2962	ret = safexcel_aead_chachapoly_cra_init(tfm);2963	ctx->aead  = EIP197_AEAD_TYPE_IPSEC_ESP;2964	ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;2965	return ret;2966}2967 2968struct safexcel_alg_template safexcel_alg_chachapoly_esp = {2969	.type = SAFEXCEL_ALG_TYPE_AEAD,2970	.algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305,2971	.alg.aead = {2972		.setkey = safexcel_aead_chachapoly_setkey,2973		.setauthsize = safexcel_aead_chachapoly_setauthsize,2974		.encrypt = safexcel_aead_chachapoly_encrypt,2975		.decrypt = safexcel_aead_chachapoly_decrypt,2976		.ivsize = CHACHAPOLY_IV_SIZE - EIP197_AEAD_IPSEC_NONCE_SIZE,2977		.maxauthsize = POLY1305_DIGEST_SIZE,2978		.base = {2979			.cra_name = "rfc7539esp(chacha20,poly1305)",2980			.cra_driver_name = "safexcel-chacha20-poly1305-esp",2981			/* +1 to put it above HW chacha + SW poly */2982			.cra_priority = SAFEXCEL_CRA_PRIORITY + 1,2983			.cra_flags = CRYPTO_ALG_ASYNC |2984				     CRYPTO_ALG_ALLOCATES_MEMORY |2985				     CRYPTO_ALG_KERN_DRIVER_ONLY |2986				     CRYPTO_ALG_NEED_FALLBACK,2987			.cra_blocksize = 1,2988			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2989			.cra_alignmask = 0,2990			.cra_init = safexcel_aead_chachapolyesp_cra_init,2991			.cra_exit = safexcel_aead_fallback_cra_exit,2992			.cra_module = THIS_MODULE,2993		},2994	},2995};2996 2997static int safexcel_skcipher_sm4_setkey(struct crypto_skcipher *ctfm,2998					const u8 *key, unsigned int len)2999{3000	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);3001	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3002	struct safexcel_crypto_priv *priv = ctx->base.priv;3003 3004	if (len != SM4_KEY_SIZE)3005		return -EINVAL;3006 3007	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)3008		if (memcmp(ctx->key, key, SM4_KEY_SIZE))3009			ctx->base.needs_inv = true;3010 3011	memcpy(ctx->key, key, SM4_KEY_SIZE);3012	ctx->key_len = SM4_KEY_SIZE;3013 3014	return 0;3015}3016 3017static int safexcel_sm4_blk_encrypt(struct skcipher_request *req)3018{3019	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */3020	if (req->cryptlen & (SM4_BLOCK_SIZE - 1))3021		return -EINVAL;3022	else3023		return safexcel_queue_req(&req->base, skcipher_request_ctx(req),3024					  SAFEXCEL_ENCRYPT);3025}3026 3027static int safexcel_sm4_blk_decrypt(struct skcipher_request *req)3028{3029	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */3030	if (req->cryptlen & (SM4_BLOCK_SIZE - 1))3031		return -EINVAL;3032	else3033		return safexcel_queue_req(&req->base, skcipher_request_ctx(req),3034					  SAFEXCEL_DECRYPT);3035}3036 3037static int safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm *tfm)3038{3039	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3040 3041	safexcel_skcipher_cra_init(tfm);3042	ctx->alg  = SAFEXCEL_SM4;3043	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;3044	ctx->blocksz = 0;3045	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;3046	return 0;3047}3048 3049struct safexcel_alg_template safexcel_alg_ecb_sm4 = {3050	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,3051	.algo_mask = SAFEXCEL_ALG_SM4,3052	.alg.skcipher = {3053		.setkey = safexcel_skcipher_sm4_setkey,3054		.encrypt = safexcel_sm4_blk_encrypt,3055		.decrypt = safexcel_sm4_blk_decrypt,3056		.min_keysize = SM4_KEY_SIZE,3057		.max_keysize = SM4_KEY_SIZE,3058		.base = {3059			.cra_name = "ecb(sm4)",3060			.cra_driver_name = "safexcel-ecb-sm4",3061			.cra_priority = SAFEXCEL_CRA_PRIORITY,3062			.cra_flags = CRYPTO_ALG_ASYNC |3063				     CRYPTO_ALG_ALLOCATES_MEMORY |3064				     CRYPTO_ALG_KERN_DRIVER_ONLY,3065			.cra_blocksize = SM4_BLOCK_SIZE,3066			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3067			.cra_alignmask = 0,3068			.cra_init = safexcel_skcipher_sm4_ecb_cra_init,3069			.cra_exit = safexcel_skcipher_cra_exit,3070			.cra_module = THIS_MODULE,3071		},3072	},3073};3074 3075static int safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm *tfm)3076{3077	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3078 3079	safexcel_skcipher_cra_init(tfm);3080	ctx->alg  = SAFEXCEL_SM4;3081	ctx->blocksz = SM4_BLOCK_SIZE;3082	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;3083	return 0;3084}3085 3086struct safexcel_alg_template safexcel_alg_cbc_sm4 = {3087	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,3088	.algo_mask = SAFEXCEL_ALG_SM4,3089	.alg.skcipher = {3090		.setkey = safexcel_skcipher_sm4_setkey,3091		.encrypt = safexcel_sm4_blk_encrypt,3092		.decrypt = safexcel_sm4_blk_decrypt,3093		.min_keysize = SM4_KEY_SIZE,3094		.max_keysize = SM4_KEY_SIZE,3095		.ivsize = SM4_BLOCK_SIZE,3096		.base = {3097			.cra_name = "cbc(sm4)",3098			.cra_driver_name = "safexcel-cbc-sm4",3099			.cra_priority = SAFEXCEL_CRA_PRIORITY,3100			.cra_flags = CRYPTO_ALG_ASYNC |3101				     CRYPTO_ALG_ALLOCATES_MEMORY |3102				     CRYPTO_ALG_KERN_DRIVER_ONLY,3103			.cra_blocksize = SM4_BLOCK_SIZE,3104			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3105			.cra_alignmask = 0,3106			.cra_init = safexcel_skcipher_sm4_cbc_cra_init,3107			.cra_exit = safexcel_skcipher_cra_exit,3108			.cra_module = THIS_MODULE,3109		},3110	},3111};3112 3113static int safexcel_skcipher_sm4ctr_setkey(struct crypto_skcipher *ctfm,3114					   const u8 *key, unsigned int len)3115{3116	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);3117	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3118 3119	/* last 4 bytes of key are the nonce! */3120	ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);3121	/* exclude the nonce here */3122	len -= CTR_RFC3686_NONCE_SIZE;3123 3124	return safexcel_skcipher_sm4_setkey(ctfm, key, len);3125}3126 3127static int safexcel_skcipher_sm4_ctr_cra_init(struct crypto_tfm *tfm)3128{3129	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3130 3131	safexcel_skcipher_cra_init(tfm);3132	ctx->alg  = SAFEXCEL_SM4;3133	ctx->blocksz = SM4_BLOCK_SIZE;3134	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;3135	return 0;3136}3137 3138struct safexcel_alg_template safexcel_alg_ctr_sm4 = {3139	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,3140	.algo_mask = SAFEXCEL_ALG_SM4,3141	.alg.skcipher = {3142		.setkey = safexcel_skcipher_sm4ctr_setkey,3143		.encrypt = safexcel_encrypt,3144		.decrypt = safexcel_decrypt,3145		/* Add nonce size */3146		.min_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,3147		.max_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,3148		.ivsize = CTR_RFC3686_IV_SIZE,3149		.base = {3150			.cra_name = "rfc3686(ctr(sm4))",3151			.cra_driver_name = "safexcel-ctr-sm4",3152			.cra_priority = SAFEXCEL_CRA_PRIORITY,3153			.cra_flags = CRYPTO_ALG_ASYNC |3154				     CRYPTO_ALG_ALLOCATES_MEMORY |3155				     CRYPTO_ALG_KERN_DRIVER_ONLY,3156			.cra_blocksize = 1,3157			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3158			.cra_alignmask = 0,3159			.cra_init = safexcel_skcipher_sm4_ctr_cra_init,3160			.cra_exit = safexcel_skcipher_cra_exit,3161			.cra_module = THIS_MODULE,3162		},3163	},3164};3165 3166static int safexcel_aead_sm4_blk_encrypt(struct aead_request *req)3167{3168	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */3169	if (req->cryptlen & (SM4_BLOCK_SIZE - 1))3170		return -EINVAL;3171 3172	return safexcel_queue_req(&req->base, aead_request_ctx(req),3173				  SAFEXCEL_ENCRYPT);3174}3175 3176static int safexcel_aead_sm4_blk_decrypt(struct aead_request *req)3177{3178	struct crypto_aead *tfm = crypto_aead_reqtfm(req);3179 3180	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */3181	if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1))3182		return -EINVAL;3183 3184	return safexcel_queue_req(&req->base, aead_request_ctx(req),3185				  SAFEXCEL_DECRYPT);3186}3187 3188static int safexcel_aead_sm4cbc_sha1_cra_init(struct crypto_tfm *tfm)3189{3190	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3191 3192	safexcel_aead_cra_init(tfm);3193	ctx->alg = SAFEXCEL_SM4;3194	ctx->blocksz = SM4_BLOCK_SIZE;3195	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;3196	ctx->state_sz = SHA1_DIGEST_SIZE;3197	return 0;3198}3199 3200struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4 = {3201	.type = SAFEXCEL_ALG_TYPE_AEAD,3202	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1,3203	.alg.aead = {3204		.setkey = safexcel_aead_setkey,3205		.encrypt = safexcel_aead_sm4_blk_encrypt,3206		.decrypt = safexcel_aead_sm4_blk_decrypt,3207		.ivsize = SM4_BLOCK_SIZE,3208		.maxauthsize = SHA1_DIGEST_SIZE,3209		.base = {3210			.cra_name = "authenc(hmac(sha1),cbc(sm4))",3211			.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-sm4",3212			.cra_priority = SAFEXCEL_CRA_PRIORITY,3213			.cra_flags = CRYPTO_ALG_ASYNC |3214				     CRYPTO_ALG_ALLOCATES_MEMORY |3215				     CRYPTO_ALG_KERN_DRIVER_ONLY,3216			.cra_blocksize = SM4_BLOCK_SIZE,3217			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3218			.cra_alignmask = 0,3219			.cra_init = safexcel_aead_sm4cbc_sha1_cra_init,3220			.cra_exit = safexcel_aead_cra_exit,3221			.cra_module = THIS_MODULE,3222		},3223	},3224};3225 3226static int safexcel_aead_fallback_setkey(struct crypto_aead *ctfm,3227					 const u8 *key, unsigned int len)3228{3229	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);3230	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3231 3232	/* Keep fallback cipher synchronized */3233	return crypto_aead_setkey(ctx->fback, (u8 *)key, len) ?:3234	       safexcel_aead_setkey(ctfm, key, len);3235}3236 3237static int safexcel_aead_fallback_setauthsize(struct crypto_aead *ctfm,3238					      unsigned int authsize)3239{3240	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);3241	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3242 3243	/* Keep fallback cipher synchronized */3244	return crypto_aead_setauthsize(ctx->fback, authsize);3245}3246 3247static int safexcel_aead_fallback_crypt(struct aead_request *req,3248					enum safexcel_cipher_direction dir)3249{3250	struct crypto_aead *aead = crypto_aead_reqtfm(req);3251	struct crypto_tfm *tfm = crypto_aead_tfm(aead);3252	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3253	struct aead_request *subreq = aead_request_ctx(req);3254 3255	aead_request_set_tfm(subreq, ctx->fback);3256	aead_request_set_callback(subreq, req->base.flags, req->base.complete,3257				  req->base.data);3258	aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,3259			       req->iv);3260	aead_request_set_ad(subreq, req->assoclen);3261 3262	return (dir ==  SAFEXCEL_ENCRYPT) ?3263		crypto_aead_encrypt(subreq) :3264		crypto_aead_decrypt(subreq);3265}3266 3267static int safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request *req)3268{3269	struct safexcel_cipher_req *creq = aead_request_ctx(req);3270 3271	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */3272	if (req->cryptlen & (SM4_BLOCK_SIZE - 1))3273		return -EINVAL;3274	else if (req->cryptlen || req->assoclen) /* If input length > 0 only */3275		return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);3276 3277	/* HW cannot do full (AAD+payload) zero length, use fallback */3278	return safexcel_aead_fallback_crypt(req, SAFEXCEL_ENCRYPT);3279}3280 3281static int safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request *req)3282{3283	struct safexcel_cipher_req *creq = aead_request_ctx(req);3284	struct crypto_aead *tfm = crypto_aead_reqtfm(req);3285 3286	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */3287	if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1))3288		return -EINVAL;3289	else if (req->cryptlen > crypto_aead_authsize(tfm) || req->assoclen)3290		/* If input length > 0 only */3291		return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);3292 3293	/* HW cannot do full (AAD+payload) zero length, use fallback */3294	return safexcel_aead_fallback_crypt(req, SAFEXCEL_DECRYPT);3295}3296 3297static int safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm *tfm)3298{3299	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3300 3301	safexcel_aead_fallback_cra_init(tfm);3302	ctx->alg = SAFEXCEL_SM4;3303	ctx->blocksz = SM4_BLOCK_SIZE;3304	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3;3305	ctx->state_sz = SM3_DIGEST_SIZE;3306	return 0;3307}3308 3309struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4 = {3310	.type = SAFEXCEL_ALG_TYPE_AEAD,3311	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3,3312	.alg.aead = {3313		.setkey = safexcel_aead_fallback_setkey,3314		.setauthsize = safexcel_aead_fallback_setauthsize,3315		.encrypt = safexcel_aead_sm4cbc_sm3_encrypt,3316		.decrypt = safexcel_aead_sm4cbc_sm3_decrypt,3317		.ivsize = SM4_BLOCK_SIZE,3318		.maxauthsize = SM3_DIGEST_SIZE,3319		.base = {3320			.cra_name = "authenc(hmac(sm3),cbc(sm4))",3321			.cra_driver_name = "safexcel-authenc-hmac-sm3-cbc-sm4",3322			.cra_priority = SAFEXCEL_CRA_PRIORITY,3323			.cra_flags = CRYPTO_ALG_ASYNC |3324				     CRYPTO_ALG_ALLOCATES_MEMORY |3325				     CRYPTO_ALG_KERN_DRIVER_ONLY |3326				     CRYPTO_ALG_NEED_FALLBACK,3327			.cra_blocksize = SM4_BLOCK_SIZE,3328			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3329			.cra_alignmask = 0,3330			.cra_init = safexcel_aead_sm4cbc_sm3_cra_init,3331			.cra_exit = safexcel_aead_fallback_cra_exit,3332			.cra_module = THIS_MODULE,3333		},3334	},3335};3336 3337static int safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm *tfm)3338{3339	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3340 3341	safexcel_aead_sm4cbc_sha1_cra_init(tfm);3342	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;3343	return 0;3344}3345 3346struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4 = {3347	.type = SAFEXCEL_ALG_TYPE_AEAD,3348	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1,3349	.alg.aead = {3350		.setkey = safexcel_aead_setkey,3351		.encrypt = safexcel_aead_encrypt,3352		.decrypt = safexcel_aead_decrypt,3353		.ivsize = CTR_RFC3686_IV_SIZE,3354		.maxauthsize = SHA1_DIGEST_SIZE,3355		.base = {3356			.cra_name = "authenc(hmac(sha1),rfc3686(ctr(sm4)))",3357			.cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-sm4",3358			.cra_priority = SAFEXCEL_CRA_PRIORITY,3359			.cra_flags = CRYPTO_ALG_ASYNC |3360				     CRYPTO_ALG_ALLOCATES_MEMORY |3361				     CRYPTO_ALG_KERN_DRIVER_ONLY,3362			.cra_blocksize = 1,3363			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3364			.cra_alignmask = 0,3365			.cra_init = safexcel_aead_sm4ctr_sha1_cra_init,3366			.cra_exit = safexcel_aead_cra_exit,3367			.cra_module = THIS_MODULE,3368		},3369	},3370};3371 3372static int safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm *tfm)3373{3374	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3375 3376	safexcel_aead_sm4cbc_sm3_cra_init(tfm);3377	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;3378	return 0;3379}3380 3381struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4 = {3382	.type = SAFEXCEL_ALG_TYPE_AEAD,3383	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3,3384	.alg.aead = {3385		.setkey = safexcel_aead_setkey,3386		.encrypt = safexcel_aead_encrypt,3387		.decrypt = safexcel_aead_decrypt,3388		.ivsize = CTR_RFC3686_IV_SIZE,3389		.maxauthsize = SM3_DIGEST_SIZE,3390		.base = {3391			.cra_name = "authenc(hmac(sm3),rfc3686(ctr(sm4)))",3392			.cra_driver_name = "safexcel-authenc-hmac-sm3-ctr-sm4",3393			.cra_priority = SAFEXCEL_CRA_PRIORITY,3394			.cra_flags = CRYPTO_ALG_ASYNC |3395				     CRYPTO_ALG_ALLOCATES_MEMORY |3396				     CRYPTO_ALG_KERN_DRIVER_ONLY,3397			.cra_blocksize = 1,3398			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3399			.cra_alignmask = 0,3400			.cra_init = safexcel_aead_sm4ctr_sm3_cra_init,3401			.cra_exit = safexcel_aead_cra_exit,3402			.cra_module = THIS_MODULE,3403		},3404	},3405};3406 3407static int safexcel_rfc4106_gcm_setkey(struct crypto_aead *ctfm, const u8 *key,3408				       unsigned int len)3409{3410	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);3411	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3412 3413	/* last 4 bytes of key are the nonce! */3414	ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);3415 3416	len -= CTR_RFC3686_NONCE_SIZE;3417	return safexcel_aead_gcm_setkey(ctfm, key, len);3418}3419 3420static int safexcel_rfc4106_gcm_setauthsize(struct crypto_aead *tfm,3421					    unsigned int authsize)3422{3423	return crypto_rfc4106_check_authsize(authsize);3424}3425 3426static int safexcel_rfc4106_encrypt(struct aead_request *req)3427{3428	return crypto_ipsec_check_assoclen(req->assoclen) ?:3429	       safexcel_aead_encrypt(req);3430}3431 3432static int safexcel_rfc4106_decrypt(struct aead_request *req)3433{3434	return crypto_ipsec_check_assoclen(req->assoclen) ?:3435	       safexcel_aead_decrypt(req);3436}3437 3438static int safexcel_rfc4106_gcm_cra_init(struct crypto_tfm *tfm)3439{3440	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3441	int ret;3442 3443	ret = safexcel_aead_gcm_cra_init(tfm);3444	ctx->aead  = EIP197_AEAD_TYPE_IPSEC_ESP;3445	ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;3446	return ret;3447}3448 3449struct safexcel_alg_template safexcel_alg_rfc4106_gcm = {3450	.type = SAFEXCEL_ALG_TYPE_AEAD,3451	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,3452	.alg.aead = {3453		.setkey = safexcel_rfc4106_gcm_setkey,3454		.setauthsize = safexcel_rfc4106_gcm_setauthsize,3455		.encrypt = safexcel_rfc4106_encrypt,3456		.decrypt = safexcel_rfc4106_decrypt,3457		.ivsize = GCM_RFC4106_IV_SIZE,3458		.maxauthsize = GHASH_DIGEST_SIZE,3459		.base = {3460			.cra_name = "rfc4106(gcm(aes))",3461			.cra_driver_name = "safexcel-rfc4106-gcm-aes",3462			.cra_priority = SAFEXCEL_CRA_PRIORITY,3463			.cra_flags = CRYPTO_ALG_ASYNC |3464				     CRYPTO_ALG_ALLOCATES_MEMORY |3465				     CRYPTO_ALG_KERN_DRIVER_ONLY,3466			.cra_blocksize = 1,3467			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3468			.cra_alignmask = 0,3469			.cra_init = safexcel_rfc4106_gcm_cra_init,3470			.cra_exit = safexcel_aead_gcm_cra_exit,3471		},3472	},3473};3474 3475static int safexcel_rfc4543_gcm_setauthsize(struct crypto_aead *tfm,3476					    unsigned int authsize)3477{3478	if (authsize != GHASH_DIGEST_SIZE)3479		return -EINVAL;3480 3481	return 0;3482}3483 3484static int safexcel_rfc4543_gcm_cra_init(struct crypto_tfm *tfm)3485{3486	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3487	int ret;3488 3489	ret = safexcel_aead_gcm_cra_init(tfm);3490	ctx->aead  = EIP197_AEAD_TYPE_IPSEC_ESP_GMAC;3491	return ret;3492}3493 3494struct safexcel_alg_template safexcel_alg_rfc4543_gcm = {3495	.type = SAFEXCEL_ALG_TYPE_AEAD,3496	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,3497	.alg.aead = {3498		.setkey = safexcel_rfc4106_gcm_setkey,3499		.setauthsize = safexcel_rfc4543_gcm_setauthsize,3500		.encrypt = safexcel_rfc4106_encrypt,3501		.decrypt = safexcel_rfc4106_decrypt,3502		.ivsize = GCM_RFC4543_IV_SIZE,3503		.maxauthsize = GHASH_DIGEST_SIZE,3504		.base = {3505			.cra_name = "rfc4543(gcm(aes))",3506			.cra_driver_name = "safexcel-rfc4543-gcm-aes",3507			.cra_priority = SAFEXCEL_CRA_PRIORITY,3508			.cra_flags = CRYPTO_ALG_ASYNC |3509				     CRYPTO_ALG_ALLOCATES_MEMORY |3510				     CRYPTO_ALG_KERN_DRIVER_ONLY,3511			.cra_blocksize = 1,3512			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3513			.cra_alignmask = 0,3514			.cra_init = safexcel_rfc4543_gcm_cra_init,3515			.cra_exit = safexcel_aead_gcm_cra_exit,3516		},3517	},3518};3519 3520static int safexcel_rfc4309_ccm_setkey(struct crypto_aead *ctfm, const u8 *key,3521				       unsigned int len)3522{3523	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);3524	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3525 3526	/* First byte of the nonce = L = always 3 for RFC4309 (4 byte ctr) */3527	*(u8 *)&ctx->nonce = EIP197_AEAD_IPSEC_COUNTER_SIZE - 1;3528	/* last 3 bytes of key are the nonce! */3529	memcpy((u8 *)&ctx->nonce + 1, key + len -3530	       EIP197_AEAD_IPSEC_CCM_NONCE_SIZE,3531	       EIP197_AEAD_IPSEC_CCM_NONCE_SIZE);3532 3533	len -= EIP197_AEAD_IPSEC_CCM_NONCE_SIZE;3534	return safexcel_aead_ccm_setkey(ctfm, key, len);3535}3536 3537static int safexcel_rfc4309_ccm_setauthsize(struct crypto_aead *tfm,3538					    unsigned int authsize)3539{3540	/* Borrowed from crypto/ccm.c */3541	switch (authsize) {3542	case 8:3543	case 12:3544	case 16:3545		break;3546	default:3547		return -EINVAL;3548	}3549 3550	return 0;3551}3552 3553static int safexcel_rfc4309_ccm_encrypt(struct aead_request *req)3554{3555	struct safexcel_cipher_req *creq = aead_request_ctx(req);3556 3557	/* Borrowed from crypto/ccm.c */3558	if (req->assoclen != 16 && req->assoclen != 20)3559		return -EINVAL;3560 3561	return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);3562}3563 3564static int safexcel_rfc4309_ccm_decrypt(struct aead_request *req)3565{3566	struct safexcel_cipher_req *creq = aead_request_ctx(req);3567 3568	/* Borrowed from crypto/ccm.c */3569	if (req->assoclen != 16 && req->assoclen != 20)3570		return -EINVAL;3571 3572	return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);3573}3574 3575static int safexcel_rfc4309_ccm_cra_init(struct crypto_tfm *tfm)3576{3577	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3578	int ret;3579 3580	ret = safexcel_aead_ccm_cra_init(tfm);3581	ctx->aead  = EIP197_AEAD_TYPE_IPSEC_ESP;3582	ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;3583	return ret;3584}3585 3586struct safexcel_alg_template safexcel_alg_rfc4309_ccm = {3587	.type = SAFEXCEL_ALG_TYPE_AEAD,3588	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL,3589	.alg.aead = {3590		.setkey = safexcel_rfc4309_ccm_setkey,3591		.setauthsize = safexcel_rfc4309_ccm_setauthsize,3592		.encrypt = safexcel_rfc4309_ccm_encrypt,3593		.decrypt = safexcel_rfc4309_ccm_decrypt,3594		.ivsize = EIP197_AEAD_IPSEC_IV_SIZE,3595		.maxauthsize = AES_BLOCK_SIZE,3596		.base = {3597			.cra_name = "rfc4309(ccm(aes))",3598			.cra_driver_name = "safexcel-rfc4309-ccm-aes",3599			.cra_priority = SAFEXCEL_CRA_PRIORITY,3600			.cra_flags = CRYPTO_ALG_ASYNC |3601				     CRYPTO_ALG_ALLOCATES_MEMORY |3602				     CRYPTO_ALG_KERN_DRIVER_ONLY,3603			.cra_blocksize = 1,3604			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3605			.cra_alignmask = 0,3606			.cra_init = safexcel_rfc4309_ccm_cra_init,3607			.cra_exit = safexcel_aead_cra_exit,3608			.cra_module = THIS_MODULE,3609		},3610	},3611};3612