Path: blob/master/drivers/crypto/inside-secure/safexcel_cipher.c
26285 views
// SPDX-License-Identifier: GPL-2.01/*2* Copyright (C) 2017 Marvell3*4* Antoine Tenart <[email protected]>5*/67#include <linux/unaligned.h>8#include <linux/device.h>9#include <linux/dma-mapping.h>10#include <linux/dmapool.h>11#include <crypto/aead.h>12#include <crypto/aes.h>13#include <crypto/authenc.h>14#include <crypto/chacha.h>15#include <crypto/ctr.h>16#include <crypto/internal/des.h>17#include <crypto/gcm.h>18#include <crypto/ghash.h>19#include <crypto/poly1305.h>20#include <crypto/sha1.h>21#include <crypto/sha2.h>22#include <crypto/sm3.h>23#include <crypto/sm4.h>24#include <crypto/xts.h>25#include <crypto/skcipher.h>26#include <crypto/internal/aead.h>27#include <crypto/internal/skcipher.h>2829#include "safexcel.h"3031enum safexcel_cipher_direction {32SAFEXCEL_ENCRYPT,33SAFEXCEL_DECRYPT,34};3536enum safexcel_cipher_alg {37SAFEXCEL_DES,38SAFEXCEL_3DES,39SAFEXCEL_AES,40SAFEXCEL_CHACHA20,41SAFEXCEL_SM4,42};4344struct safexcel_cipher_ctx {45struct safexcel_context base;46struct safexcel_crypto_priv *priv;4748u32 mode;49enum safexcel_cipher_alg alg;50u8 aead; /* !=0=AEAD, 2=IPSec ESP AEAD, 3=IPsec ESP GMAC */51u8 xcm; /* 0=authenc, 1=GCM, 2 reserved for CCM */52u8 aadskip;53u8 blocksz;54u32 ivmask;55u32 ctrinit;5657__le32 key[16];58u32 nonce;59unsigned int key_len, xts;6061/* All the below is AEAD specific */62u32 hash_alg;63u32 state_sz;6465struct crypto_aead *fback;66};6768struct safexcel_cipher_req {69enum safexcel_cipher_direction direction;70/* Number of result descriptors associated to the request */71unsigned int rdescs;72bool needs_inv;73int nr_src, nr_dst;74};7576static int safexcel_skcipher_iv(struct safexcel_cipher_ctx *ctx, u8 *iv,77struct safexcel_command_desc *cdesc)78{79if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) {80cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;81/* 32 bit nonce */82cdesc->control_data.token[0] = ctx->nonce;83/* 64 bit IV part */84memcpy(&cdesc->control_data.token[1], iv, 8);85/* 32 bit counter, start at 0 or 1 (big endian!) */86cdesc->control_data.token[3] =87(__force u32)cpu_to_be32(ctx->ctrinit);88return 4;89}90if (ctx->alg == SAFEXCEL_CHACHA20) {91cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;92/* 96 bit nonce part */93memcpy(&cdesc->control_data.token[0], &iv[4], 12);94/* 32 bit counter */95cdesc->control_data.token[3] = *(u32 *)iv;96return 4;97}9899cdesc->control_data.options |= ctx->ivmask;100memcpy(cdesc->control_data.token, iv, ctx->blocksz);101return ctx->blocksz / sizeof(u32);102}103104static void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv,105struct safexcel_command_desc *cdesc,106struct safexcel_token *atoken,107u32 length)108{109struct safexcel_token *token;110int ivlen;111112ivlen = safexcel_skcipher_iv(ctx, iv, cdesc);113if (ivlen == 4) {114/* No space in cdesc, instruction moves to atoken */115cdesc->additional_cdata_size = 1;116token = atoken;117} else {118/* Everything fits in cdesc */119token = (struct safexcel_token *)(cdesc->control_data.token + 2);120/* Need to pad with NOP */121eip197_noop_token(&token[1]);122}123124token->opcode = EIP197_TOKEN_OPCODE_DIRECTION;125token->packet_length = length;126token->stat = EIP197_TOKEN_STAT_LAST_PACKET |127EIP197_TOKEN_STAT_LAST_HASH;128token->instructions = EIP197_TOKEN_INS_LAST |129EIP197_TOKEN_INS_TYPE_CRYPTO |130EIP197_TOKEN_INS_TYPE_OUTPUT;131}132133static void safexcel_aead_iv(struct safexcel_cipher_ctx *ctx, u8 *iv,134struct safexcel_command_desc *cdesc)135{136if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD ||137ctx->aead & EIP197_AEAD_TYPE_IPSEC_ESP) { /* _ESP and _ESP_GMAC */138/* 32 bit nonce */139cdesc->control_data.token[0] = ctx->nonce;140/* 64 bit IV part */141memcpy(&cdesc->control_data.token[1], iv, 8);142/* 32 bit counter, start at 0 or 1 (big endian!) */143cdesc->control_data.token[3] =144(__force u32)cpu_to_be32(ctx->ctrinit);145return;146}147if (ctx->xcm == EIP197_XCM_MODE_GCM || ctx->alg == SAFEXCEL_CHACHA20) {148/* 96 bit IV part */149memcpy(&cdesc->control_data.token[0], iv, 12);150/* 32 bit counter, start at 0 or 1 (big endian!) */151cdesc->control_data.token[3] =152(__force u32)cpu_to_be32(ctx->ctrinit);153return;154}155/* CBC */156memcpy(cdesc->control_data.token, iv, ctx->blocksz);157}158159static void safexcel_aead_token(struct safexcel_cipher_ctx *ctx, u8 *iv,160struct safexcel_command_desc *cdesc,161struct safexcel_token *atoken,162enum safexcel_cipher_direction direction,163u32 cryptlen, u32 assoclen, u32 digestsize)164{165struct safexcel_token *aadref;166int atoksize = 2; /* Start with minimum size */167int assocadj = assoclen - ctx->aadskip, aadalign;168169/* Always 4 dwords of embedded IV for AEAD modes */170cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;171172if (direction == SAFEXCEL_DECRYPT)173cryptlen -= digestsize;174175if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM)) {176/* Construct IV block B0 for the CBC-MAC */177u8 *final_iv = (u8 *)cdesc->control_data.token;178u8 *cbcmaciv = (u8 *)&atoken[1];179__le32 *aadlen = (__le32 *)&atoken[5];180181if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {182/* Length + nonce */183cdesc->control_data.token[0] = ctx->nonce;184/* Fixup flags byte */185*(__le32 *)cbcmaciv =186cpu_to_le32(ctx->nonce |187((assocadj > 0) << 6) |188((digestsize - 2) << 2));189/* 64 bit IV part */190memcpy(&cdesc->control_data.token[1], iv, 8);191memcpy(cbcmaciv + 4, iv, 8);192/* Start counter at 0 */193cdesc->control_data.token[3] = 0;194/* Message length */195*(__be32 *)(cbcmaciv + 12) = cpu_to_be32(cryptlen);196} else {197/* Variable length IV part */198memcpy(final_iv, iv, 15 - iv[0]);199memcpy(cbcmaciv, iv, 15 - iv[0]);200/* Start variable length counter at 0 */201memset(final_iv + 15 - iv[0], 0, iv[0] + 1);202memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1);203/* fixup flags byte */204cbcmaciv[0] |= ((assocadj > 0) << 6) |205((digestsize - 2) << 2);206/* insert lower 2 bytes of message length */207cbcmaciv[14] = cryptlen >> 8;208cbcmaciv[15] = cryptlen & 255;209}210211atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;212atoken->packet_length = AES_BLOCK_SIZE +213((assocadj > 0) << 1);214atoken->stat = 0;215atoken->instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN |216EIP197_TOKEN_INS_TYPE_HASH;217218if (likely(assocadj)) {219*aadlen = cpu_to_le32((assocadj >> 8) |220(assocadj & 255) << 8);221atoken += 6;222atoksize += 7;223} else {224atoken += 5;225atoksize += 6;226}227228/* Process AAD data */229aadref = atoken;230atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;231atoken->packet_length = assocadj;232atoken->stat = 0;233atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;234atoken++;235236/* For CCM only, align AAD data towards hash engine */237atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;238aadalign = (assocadj + 2) & 15;239atoken->packet_length = assocadj && aadalign ?24016 - aadalign :2410;242if (likely(cryptlen)) {243atoken->stat = 0;244atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;245} else {246atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;247atoken->instructions = EIP197_TOKEN_INS_LAST |248EIP197_TOKEN_INS_TYPE_HASH;249}250} else {251safexcel_aead_iv(ctx, iv, cdesc);252253/* Process AAD data */254aadref = atoken;255atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;256atoken->packet_length = assocadj;257atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;258atoken->instructions = EIP197_TOKEN_INS_LAST |259EIP197_TOKEN_INS_TYPE_HASH;260}261atoken++;262263if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {264/* For ESP mode (and not GMAC), skip over the IV */265atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;266atoken->packet_length = EIP197_AEAD_IPSEC_IV_SIZE;267atoken->stat = 0;268atoken->instructions = 0;269atoken++;270atoksize++;271} else if (unlikely(ctx->alg == SAFEXCEL_CHACHA20 &&272direction == SAFEXCEL_DECRYPT)) {273/* Poly-chacha decryption needs a dummy NOP here ... */274atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;275atoken->packet_length = 16; /* According to Op Manual */276atoken->stat = 0;277atoken->instructions = 0;278atoken++;279atoksize++;280}281282if (ctx->xcm) {283/* For GCM and CCM, obtain enc(Y0) */284atoken->opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES;285atoken->packet_length = 0;286atoken->stat = 0;287atoken->instructions = AES_BLOCK_SIZE;288atoken++;289290atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;291atoken->packet_length = AES_BLOCK_SIZE;292atoken->stat = 0;293atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |294EIP197_TOKEN_INS_TYPE_CRYPTO;295atoken++;296atoksize += 2;297}298299if (likely(cryptlen || ctx->alg == SAFEXCEL_CHACHA20)) {300/* Fixup stat field for AAD direction instruction */301aadref->stat = 0;302303/* Process crypto data */304atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;305atoken->packet_length = cryptlen;306307if (unlikely(ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) {308/* Fixup instruction field for AAD dir instruction */309aadref->instructions = EIP197_TOKEN_INS_TYPE_HASH;310311/* Do not send to crypt engine in case of GMAC */312atoken->instructions = EIP197_TOKEN_INS_LAST |313EIP197_TOKEN_INS_TYPE_HASH |314EIP197_TOKEN_INS_TYPE_OUTPUT;315} else {316atoken->instructions = EIP197_TOKEN_INS_LAST |317EIP197_TOKEN_INS_TYPE_CRYPTO |318EIP197_TOKEN_INS_TYPE_HASH |319EIP197_TOKEN_INS_TYPE_OUTPUT;320}321322cryptlen &= 15;323if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM && cryptlen)) {324atoken->stat = 0;325/* For CCM only, pad crypto data to the hash engine */326atoken++;327atoksize++;328atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;329atoken->packet_length = 16 - cryptlen;330atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;331atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;332} else {333atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;334}335atoken++;336atoksize++;337}338339if (direction == SAFEXCEL_ENCRYPT) {340/* Append ICV */341atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;342atoken->packet_length = digestsize;343atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |344EIP197_TOKEN_STAT_LAST_PACKET;345atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |346EIP197_TOKEN_INS_INSERT_HASH_DIGEST;347} else {348/* Extract ICV */349atoken->opcode = EIP197_TOKEN_OPCODE_RETRIEVE;350atoken->packet_length = digestsize;351atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |352EIP197_TOKEN_STAT_LAST_PACKET;353atoken->instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST;354atoken++;355atoksize++;356357/* Verify ICV */358atoken->opcode = EIP197_TOKEN_OPCODE_VERIFY;359atoken->packet_length = digestsize |360EIP197_TOKEN_HASH_RESULT_VERIFY;361atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |362EIP197_TOKEN_STAT_LAST_PACKET;363atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT;364}365366/* Fixup length of the token in the command descriptor */367cdesc->additional_cdata_size = atoksize;368}369370static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm,371const u8 *key, unsigned int len)372{373struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);374struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);375struct safexcel_crypto_priv *priv = ctx->base.priv;376struct crypto_aes_ctx aes;377int ret, i;378379ret = aes_expandkey(&aes, key, len);380if (ret)381return ret;382383if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {384for (i = 0; i < len / sizeof(u32); i++) {385if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {386ctx->base.needs_inv = true;387break;388}389}390}391392for (i = 0; i < len / sizeof(u32); i++)393ctx->key[i] = cpu_to_le32(aes.key_enc[i]);394395ctx->key_len = len;396397memzero_explicit(&aes, sizeof(aes));398return 0;399}400401static int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key,402unsigned int len)403{404struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);405struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);406struct safexcel_crypto_priv *priv = ctx->base.priv;407struct crypto_authenc_keys keys;408struct crypto_aes_ctx aes;409int err = -EINVAL, i;410const char *alg;411412if (unlikely(crypto_authenc_extractkeys(&keys, key, len)))413goto badkey;414415if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) {416/* Must have at least space for the nonce here */417if (unlikely(keys.enckeylen < CTR_RFC3686_NONCE_SIZE))418goto badkey;419/* last 4 bytes of key are the nonce! */420ctx->nonce = *(u32 *)(keys.enckey + keys.enckeylen -421CTR_RFC3686_NONCE_SIZE);422/* exclude the nonce here */423keys.enckeylen -= CTR_RFC3686_NONCE_SIZE;424}425426/* Encryption key */427switch (ctx->alg) {428case SAFEXCEL_DES:429err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen);430if (unlikely(err))431goto badkey;432break;433case SAFEXCEL_3DES:434err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen);435if (unlikely(err))436goto badkey;437break;438case SAFEXCEL_AES:439err = aes_expandkey(&aes, keys.enckey, keys.enckeylen);440if (unlikely(err))441goto badkey;442break;443case SAFEXCEL_SM4:444if (unlikely(keys.enckeylen != SM4_KEY_SIZE))445goto badkey;446break;447default:448dev_err(priv->dev, "aead: unsupported cipher algorithm\n");449goto badkey;450}451452if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {453for (i = 0; i < keys.enckeylen / sizeof(u32); i++) {454if (le32_to_cpu(ctx->key[i]) !=455((u32 *)keys.enckey)[i]) {456ctx->base.needs_inv = true;457break;458}459}460}461462/* Auth key */463switch (ctx->hash_alg) {464case CONTEXT_CONTROL_CRYPTO_ALG_SHA1:465alg = "safexcel-sha1";466break;467case CONTEXT_CONTROL_CRYPTO_ALG_SHA224:468alg = "safexcel-sha224";469break;470case CONTEXT_CONTROL_CRYPTO_ALG_SHA256:471alg = "safexcel-sha256";472break;473case CONTEXT_CONTROL_CRYPTO_ALG_SHA384:474alg = "safexcel-sha384";475break;476case CONTEXT_CONTROL_CRYPTO_ALG_SHA512:477alg = "safexcel-sha512";478break;479case CONTEXT_CONTROL_CRYPTO_ALG_SM3:480alg = "safexcel-sm3";481break;482default:483dev_err(priv->dev, "aead: unsupported hash algorithm\n");484goto badkey;485}486487if (safexcel_hmac_setkey(&ctx->base, keys.authkey, keys.authkeylen,488alg, ctx->state_sz))489goto badkey;490491/* Now copy the keys into the context */492for (i = 0; i < keys.enckeylen / sizeof(u32); i++)493ctx->key[i] = cpu_to_le32(((u32 *)keys.enckey)[i]);494ctx->key_len = keys.enckeylen;495496memzero_explicit(&keys, sizeof(keys));497return 0;498499badkey:500memzero_explicit(&keys, sizeof(keys));501return err;502}503504static int safexcel_context_control(struct safexcel_cipher_ctx *ctx,505struct crypto_async_request *async,506struct safexcel_cipher_req *sreq,507struct safexcel_command_desc *cdesc)508{509struct safexcel_crypto_priv *priv = ctx->base.priv;510int ctrl_size = ctx->key_len / sizeof(u32);511512cdesc->control_data.control1 = ctx->mode;513514if (ctx->aead) {515/* Take in account the ipad+opad digests */516if (ctx->xcm) {517ctrl_size += ctx->state_sz / sizeof(u32);518cdesc->control_data.control0 =519CONTEXT_CONTROL_KEY_EN |520CONTEXT_CONTROL_DIGEST_XCM |521ctx->hash_alg |522CONTEXT_CONTROL_SIZE(ctrl_size);523} else if (ctx->alg == SAFEXCEL_CHACHA20) {524/* Chacha20-Poly1305 */525cdesc->control_data.control0 =526CONTEXT_CONTROL_KEY_EN |527CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 |528(sreq->direction == SAFEXCEL_ENCRYPT ?529CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT :530CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN) |531ctx->hash_alg |532CONTEXT_CONTROL_SIZE(ctrl_size);533return 0;534} else {535ctrl_size += ctx->state_sz / sizeof(u32) * 2;536cdesc->control_data.control0 =537CONTEXT_CONTROL_KEY_EN |538CONTEXT_CONTROL_DIGEST_HMAC |539ctx->hash_alg |540CONTEXT_CONTROL_SIZE(ctrl_size);541}542543if (sreq->direction == SAFEXCEL_ENCRYPT &&544(ctx->xcm == EIP197_XCM_MODE_CCM ||545ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC))546cdesc->control_data.control0 |=547CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT;548else if (sreq->direction == SAFEXCEL_ENCRYPT)549cdesc->control_data.control0 |=550CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT;551else if (ctx->xcm == EIP197_XCM_MODE_CCM)552cdesc->control_data.control0 |=553CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN;554else555cdesc->control_data.control0 |=556CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN;557} else {558if (sreq->direction == SAFEXCEL_ENCRYPT)559cdesc->control_data.control0 =560CONTEXT_CONTROL_TYPE_CRYPTO_OUT |561CONTEXT_CONTROL_KEY_EN |562CONTEXT_CONTROL_SIZE(ctrl_size);563else564cdesc->control_data.control0 =565CONTEXT_CONTROL_TYPE_CRYPTO_IN |566CONTEXT_CONTROL_KEY_EN |567CONTEXT_CONTROL_SIZE(ctrl_size);568}569570if (ctx->alg == SAFEXCEL_DES) {571cdesc->control_data.control0 |=572CONTEXT_CONTROL_CRYPTO_ALG_DES;573} else if (ctx->alg == SAFEXCEL_3DES) {574cdesc->control_data.control0 |=575CONTEXT_CONTROL_CRYPTO_ALG_3DES;576} else if (ctx->alg == SAFEXCEL_AES) {577switch (ctx->key_len >> ctx->xts) {578case AES_KEYSIZE_128:579cdesc->control_data.control0 |=580CONTEXT_CONTROL_CRYPTO_ALG_AES128;581break;582case AES_KEYSIZE_192:583cdesc->control_data.control0 |=584CONTEXT_CONTROL_CRYPTO_ALG_AES192;585break;586case AES_KEYSIZE_256:587cdesc->control_data.control0 |=588CONTEXT_CONTROL_CRYPTO_ALG_AES256;589break;590default:591dev_err(priv->dev, "aes keysize not supported: %u\n",592ctx->key_len >> ctx->xts);593return -EINVAL;594}595} else if (ctx->alg == SAFEXCEL_CHACHA20) {596cdesc->control_data.control0 |=597CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20;598} else if (ctx->alg == SAFEXCEL_SM4) {599cdesc->control_data.control0 |=600CONTEXT_CONTROL_CRYPTO_ALG_SM4;601}602603return 0;604}605606static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring,607struct crypto_async_request *async,608struct scatterlist *src,609struct scatterlist *dst,610unsigned int cryptlen,611struct safexcel_cipher_req *sreq,612bool *should_complete, int *ret)613{614struct skcipher_request *areq = skcipher_request_cast(async);615struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq);616struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(skcipher);617struct safexcel_result_desc *rdesc;618int ndesc = 0;619620*ret = 0;621622if (unlikely(!sreq->rdescs))623return 0;624625while (sreq->rdescs--) {626rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr);627if (IS_ERR(rdesc)) {628dev_err(priv->dev,629"cipher: result: could not retrieve the result descriptor\n");630*ret = PTR_ERR(rdesc);631break;632}633634if (likely(!*ret))635*ret = safexcel_rdesc_check_errors(priv, rdesc);636637ndesc++;638}639640safexcel_complete(priv, ring);641642if (src == dst) {643if (sreq->nr_src > 0)644dma_unmap_sg(priv->dev, src, sreq->nr_src,645DMA_BIDIRECTIONAL);646} else {647if (sreq->nr_src > 0)648dma_unmap_sg(priv->dev, src, sreq->nr_src,649DMA_TO_DEVICE);650if (sreq->nr_dst > 0)651dma_unmap_sg(priv->dev, dst, sreq->nr_dst,652DMA_FROM_DEVICE);653}654655/*656* Update IV in req from last crypto output word for CBC modes657*/658if ((!ctx->aead) && (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) &&659(sreq->direction == SAFEXCEL_ENCRYPT)) {660/* For encrypt take the last output word */661sg_pcopy_to_buffer(dst, sreq->nr_dst, areq->iv,662crypto_skcipher_ivsize(skcipher),663(cryptlen -664crypto_skcipher_ivsize(skcipher)));665}666667*should_complete = true;668669return ndesc;670}671672static int safexcel_send_req(struct crypto_async_request *base, int ring,673struct safexcel_cipher_req *sreq,674struct scatterlist *src, struct scatterlist *dst,675unsigned int cryptlen, unsigned int assoclen,676unsigned int digestsize, u8 *iv, int *commands,677int *results)678{679struct skcipher_request *areq = skcipher_request_cast(base);680struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq);681struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);682struct safexcel_crypto_priv *priv = ctx->base.priv;683struct safexcel_command_desc *cdesc;684struct safexcel_command_desc *first_cdesc = NULL;685struct safexcel_result_desc *rdesc, *first_rdesc = NULL;686struct scatterlist *sg;687unsigned int totlen;688unsigned int totlen_src = cryptlen + assoclen;689unsigned int totlen_dst = totlen_src;690struct safexcel_token *atoken;691int n_cdesc = 0, n_rdesc = 0;692int queued, i, ret = 0;693bool first = true;694695sreq->nr_src = sg_nents_for_len(src, totlen_src);696697if (ctx->aead) {698/*699* AEAD has auth tag appended to output for encrypt and700* removed from the output for decrypt!701*/702if (sreq->direction == SAFEXCEL_DECRYPT)703totlen_dst -= digestsize;704else705totlen_dst += digestsize;706707memcpy(ctx->base.ctxr->data + ctx->key_len / sizeof(u32),708&ctx->base.ipad, ctx->state_sz);709if (!ctx->xcm)710memcpy(ctx->base.ctxr->data + (ctx->key_len +711ctx->state_sz) / sizeof(u32), &ctx->base.opad,712ctx->state_sz);713} else if ((ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) &&714(sreq->direction == SAFEXCEL_DECRYPT)) {715/*716* Save IV from last crypto input word for CBC modes in decrypt717* direction. Need to do this first in case of inplace operation718* as it will be overwritten.719*/720sg_pcopy_to_buffer(src, sreq->nr_src, areq->iv,721crypto_skcipher_ivsize(skcipher),722(totlen_src -723crypto_skcipher_ivsize(skcipher)));724}725726sreq->nr_dst = sg_nents_for_len(dst, totlen_dst);727728/*729* Remember actual input length, source buffer length may be730* updated in case of inline operation below.731*/732totlen = totlen_src;733queued = totlen_src;734735if (src == dst) {736sreq->nr_src = max(sreq->nr_src, sreq->nr_dst);737sreq->nr_dst = sreq->nr_src;738if (unlikely((totlen_src || totlen_dst) &&739(sreq->nr_src <= 0))) {740dev_err(priv->dev, "In-place buffer not large enough (need %d bytes)!",741max(totlen_src, totlen_dst));742return -EINVAL;743}744if (sreq->nr_src > 0 &&745!dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL))746return -EIO;747} else {748if (unlikely(totlen_src && (sreq->nr_src <= 0))) {749dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!",750totlen_src);751return -EINVAL;752}753754if (sreq->nr_src > 0 &&755!dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE))756return -EIO;757758if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) {759dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!",760totlen_dst);761ret = -EINVAL;762goto unmap;763}764765if (sreq->nr_dst > 0 &&766!dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE)) {767ret = -EIO;768goto unmap;769}770}771772memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len);773774if (!totlen) {775/*776* The EIP97 cannot deal with zero length input packets!777* So stuff a dummy command descriptor indicating a 1 byte778* (dummy) input packet, using the context record as source.779*/780first_cdesc = safexcel_add_cdesc(priv, ring,7811, 1, ctx->base.ctxr_dma,7821, 1, ctx->base.ctxr_dma,783&atoken);784if (IS_ERR(first_cdesc)) {785/* No space left in the command descriptor ring */786ret = PTR_ERR(first_cdesc);787goto cdesc_rollback;788}789n_cdesc = 1;790goto skip_cdesc;791}792793/* command descriptors */794for_each_sg(src, sg, sreq->nr_src, i) {795int len = sg_dma_len(sg);796797/* Do not overflow the request */798if (queued < len)799len = queued;800801cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc,802!(queued - len),803sg_dma_address(sg), len, totlen,804ctx->base.ctxr_dma, &atoken);805if (IS_ERR(cdesc)) {806/* No space left in the command descriptor ring */807ret = PTR_ERR(cdesc);808goto cdesc_rollback;809}810811if (!n_cdesc)812first_cdesc = cdesc;813814n_cdesc++;815queued -= len;816if (!queued)817break;818}819skip_cdesc:820/* Add context control words and token to first command descriptor */821safexcel_context_control(ctx, base, sreq, first_cdesc);822if (ctx->aead)823safexcel_aead_token(ctx, iv, first_cdesc, atoken,824sreq->direction, cryptlen,825assoclen, digestsize);826else827safexcel_skcipher_token(ctx, iv, first_cdesc, atoken,828cryptlen);829830/* result descriptors */831for_each_sg(dst, sg, sreq->nr_dst, i) {832bool last = (i == sreq->nr_dst - 1);833u32 len = sg_dma_len(sg);834835/* only allow the part of the buffer we know we need */836if (len > totlen_dst)837len = totlen_dst;838if (unlikely(!len))839break;840totlen_dst -= len;841842/* skip over AAD space in buffer - not written */843if (assoclen) {844if (assoclen >= len) {845assoclen -= len;846continue;847}848rdesc = safexcel_add_rdesc(priv, ring, first, last,849sg_dma_address(sg) +850assoclen,851len - assoclen);852assoclen = 0;853} else {854rdesc = safexcel_add_rdesc(priv, ring, first, last,855sg_dma_address(sg),856len);857}858if (IS_ERR(rdesc)) {859/* No space left in the result descriptor ring */860ret = PTR_ERR(rdesc);861goto rdesc_rollback;862}863if (first) {864first_rdesc = rdesc;865first = false;866}867n_rdesc++;868}869870if (unlikely(first)) {871/*872* Special case: AEAD decrypt with only AAD data.873* In this case there is NO output data from the engine,874* but the engine still needs a result descriptor!875* Create a dummy one just for catching the result token.876*/877rdesc = safexcel_add_rdesc(priv, ring, true, true, 0, 0);878if (IS_ERR(rdesc)) {879/* No space left in the result descriptor ring */880ret = PTR_ERR(rdesc);881goto rdesc_rollback;882}883first_rdesc = rdesc;884n_rdesc = 1;885}886887safexcel_rdr_req_set(priv, ring, first_rdesc, base);888889*commands = n_cdesc;890*results = n_rdesc;891return 0;892893rdesc_rollback:894for (i = 0; i < n_rdesc; i++)895safexcel_ring_rollback_wptr(priv, &priv->ring[ring].rdr);896cdesc_rollback:897for (i = 0; i < n_cdesc; i++)898safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr);899unmap:900if (src == dst) {901if (sreq->nr_src > 0)902dma_unmap_sg(priv->dev, src, sreq->nr_src,903DMA_BIDIRECTIONAL);904} else {905if (sreq->nr_src > 0)906dma_unmap_sg(priv->dev, src, sreq->nr_src,907DMA_TO_DEVICE);908if (sreq->nr_dst > 0)909dma_unmap_sg(priv->dev, dst, sreq->nr_dst,910DMA_FROM_DEVICE);911}912913return ret;914}915916static int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv,917int ring,918struct crypto_async_request *base,919struct safexcel_cipher_req *sreq,920bool *should_complete, int *ret)921{922struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);923struct safexcel_result_desc *rdesc;924int ndesc = 0, enq_ret;925926*ret = 0;927928if (unlikely(!sreq->rdescs))929return 0;930931while (sreq->rdescs--) {932rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr);933if (IS_ERR(rdesc)) {934dev_err(priv->dev,935"cipher: invalidate: could not retrieve the result descriptor\n");936*ret = PTR_ERR(rdesc);937break;938}939940if (likely(!*ret))941*ret = safexcel_rdesc_check_errors(priv, rdesc);942943ndesc++;944}945946safexcel_complete(priv, ring);947948if (ctx->base.exit_inv) {949dma_pool_free(priv->context_pool, ctx->base.ctxr,950ctx->base.ctxr_dma);951952*should_complete = true;953954return ndesc;955}956957ring = safexcel_select_ring(priv);958ctx->base.ring = ring;959960spin_lock_bh(&priv->ring[ring].queue_lock);961enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, base);962spin_unlock_bh(&priv->ring[ring].queue_lock);963964if (enq_ret != -EINPROGRESS)965*ret = enq_ret;966967queue_work(priv->ring[ring].workqueue,968&priv->ring[ring].work_data.work);969970*should_complete = false;971972return ndesc;973}974975static int safexcel_skcipher_handle_result(struct safexcel_crypto_priv *priv,976int ring,977struct crypto_async_request *async,978bool *should_complete, int *ret)979{980struct skcipher_request *req = skcipher_request_cast(async);981struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);982int err;983984if (sreq->needs_inv) {985sreq->needs_inv = false;986err = safexcel_handle_inv_result(priv, ring, async, sreq,987should_complete, ret);988} else {989err = safexcel_handle_req_result(priv, ring, async, req->src,990req->dst, req->cryptlen, sreq,991should_complete, ret);992}993994return err;995}996997static int safexcel_aead_handle_result(struct safexcel_crypto_priv *priv,998int ring,999struct crypto_async_request *async,1000bool *should_complete, int *ret)1001{1002struct aead_request *req = aead_request_cast(async);1003struct crypto_aead *tfm = crypto_aead_reqtfm(req);1004struct safexcel_cipher_req *sreq = aead_request_ctx(req);1005int err;10061007if (sreq->needs_inv) {1008sreq->needs_inv = false;1009err = safexcel_handle_inv_result(priv, ring, async, sreq,1010should_complete, ret);1011} else {1012err = safexcel_handle_req_result(priv, ring, async, req->src,1013req->dst,1014req->cryptlen + crypto_aead_authsize(tfm),1015sreq, should_complete, ret);1016}10171018return err;1019}10201021static int safexcel_cipher_send_inv(struct crypto_async_request *base,1022int ring, int *commands, int *results)1023{1024struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);1025struct safexcel_crypto_priv *priv = ctx->base.priv;1026int ret;10271028ret = safexcel_invalidate_cache(base, priv, ctx->base.ctxr_dma, ring);1029if (unlikely(ret))1030return ret;10311032*commands = 1;1033*results = 1;10341035return 0;1036}10371038static int safexcel_skcipher_send(struct crypto_async_request *async, int ring,1039int *commands, int *results)1040{1041struct skcipher_request *req = skcipher_request_cast(async);1042struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);1043struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);1044struct safexcel_crypto_priv *priv = ctx->base.priv;1045int ret;10461047BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv);10481049if (sreq->needs_inv) {1050ret = safexcel_cipher_send_inv(async, ring, commands, results);1051} else {1052struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);1053u8 input_iv[AES_BLOCK_SIZE];10541055/*1056* Save input IV in case of CBC decrypt mode1057* Will be overwritten with output IV prior to use!1058*/1059memcpy(input_iv, req->iv, crypto_skcipher_ivsize(skcipher));10601061ret = safexcel_send_req(async, ring, sreq, req->src,1062req->dst, req->cryptlen, 0, 0, input_iv,1063commands, results);1064}10651066sreq->rdescs = *results;1067return ret;1068}10691070static int safexcel_aead_send(struct crypto_async_request *async, int ring,1071int *commands, int *results)1072{1073struct aead_request *req = aead_request_cast(async);1074struct crypto_aead *tfm = crypto_aead_reqtfm(req);1075struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);1076struct safexcel_cipher_req *sreq = aead_request_ctx(req);1077struct safexcel_crypto_priv *priv = ctx->base.priv;1078int ret;10791080BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv);10811082if (sreq->needs_inv)1083ret = safexcel_cipher_send_inv(async, ring, commands, results);1084else1085ret = safexcel_send_req(async, ring, sreq, req->src, req->dst,1086req->cryptlen, req->assoclen,1087crypto_aead_authsize(tfm), req->iv,1088commands, results);1089sreq->rdescs = *results;1090return ret;1091}10921093static int safexcel_cipher_exit_inv(struct crypto_tfm *tfm,1094struct crypto_async_request *base,1095struct safexcel_cipher_req *sreq,1096struct crypto_wait *result)1097{1098struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1099struct safexcel_crypto_priv *priv = ctx->base.priv;1100int ring = ctx->base.ring;1101int err;11021103ctx = crypto_tfm_ctx(base->tfm);1104ctx->base.exit_inv = true;1105sreq->needs_inv = true;11061107spin_lock_bh(&priv->ring[ring].queue_lock);1108crypto_enqueue_request(&priv->ring[ring].queue, base);1109spin_unlock_bh(&priv->ring[ring].queue_lock);11101111queue_work(priv->ring[ring].workqueue,1112&priv->ring[ring].work_data.work);11131114err = crypto_wait_req(-EINPROGRESS, result);11151116if (err) {1117dev_warn(priv->dev,1118"cipher: sync: invalidate: completion error %d\n",1119err);1120return err;1121}11221123return 0;1124}11251126static int safexcel_skcipher_exit_inv(struct crypto_tfm *tfm)1127{1128EIP197_REQUEST_ON_STACK(req, skcipher, EIP197_SKCIPHER_REQ_SIZE);1129struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);1130DECLARE_CRYPTO_WAIT(result);11311132memset(req, 0, sizeof(struct skcipher_request));11331134skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,1135crypto_req_done, &result);1136skcipher_request_set_tfm(req, __crypto_skcipher_cast(tfm));11371138return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result);1139}11401141static int safexcel_aead_exit_inv(struct crypto_tfm *tfm)1142{1143EIP197_REQUEST_ON_STACK(req, aead, EIP197_AEAD_REQ_SIZE);1144struct safexcel_cipher_req *sreq = aead_request_ctx(req);1145DECLARE_CRYPTO_WAIT(result);11461147memset(req, 0, sizeof(struct aead_request));11481149aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,1150crypto_req_done, &result);1151aead_request_set_tfm(req, __crypto_aead_cast(tfm));11521153return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result);1154}11551156static int safexcel_queue_req(struct crypto_async_request *base,1157struct safexcel_cipher_req *sreq,1158enum safexcel_cipher_direction dir)1159{1160struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);1161struct safexcel_crypto_priv *priv = ctx->base.priv;1162int ret, ring;11631164sreq->needs_inv = false;1165sreq->direction = dir;11661167if (ctx->base.ctxr) {1168if (priv->flags & EIP197_TRC_CACHE && ctx->base.needs_inv) {1169sreq->needs_inv = true;1170ctx->base.needs_inv = false;1171}1172} else {1173ctx->base.ring = safexcel_select_ring(priv);1174ctx->base.ctxr = dma_pool_zalloc(priv->context_pool,1175EIP197_GFP_FLAGS(*base),1176&ctx->base.ctxr_dma);1177if (!ctx->base.ctxr)1178return -ENOMEM;1179}11801181ring = ctx->base.ring;11821183spin_lock_bh(&priv->ring[ring].queue_lock);1184ret = crypto_enqueue_request(&priv->ring[ring].queue, base);1185spin_unlock_bh(&priv->ring[ring].queue_lock);11861187queue_work(priv->ring[ring].workqueue,1188&priv->ring[ring].work_data.work);11891190return ret;1191}11921193static int safexcel_encrypt(struct skcipher_request *req)1194{1195return safexcel_queue_req(&req->base, skcipher_request_ctx(req),1196SAFEXCEL_ENCRYPT);1197}11981199static int safexcel_decrypt(struct skcipher_request *req)1200{1201return safexcel_queue_req(&req->base, skcipher_request_ctx(req),1202SAFEXCEL_DECRYPT);1203}12041205static int safexcel_skcipher_cra_init(struct crypto_tfm *tfm)1206{1207struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1208struct safexcel_alg_template *tmpl =1209container_of(tfm->__crt_alg, struct safexcel_alg_template,1210alg.skcipher.base);12111212crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm),1213sizeof(struct safexcel_cipher_req));12141215ctx->base.priv = tmpl->priv;12161217ctx->base.send = safexcel_skcipher_send;1218ctx->base.handle_result = safexcel_skcipher_handle_result;1219ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD;1220ctx->ctrinit = 1;1221return 0;1222}12231224static int safexcel_cipher_cra_exit(struct crypto_tfm *tfm)1225{1226struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);12271228memzero_explicit(ctx->key, sizeof(ctx->key));12291230/* context not allocated, skip invalidation */1231if (!ctx->base.ctxr)1232return -ENOMEM;12331234memzero_explicit(ctx->base.ctxr->data, sizeof(ctx->base.ctxr->data));1235return 0;1236}12371238static void safexcel_skcipher_cra_exit(struct crypto_tfm *tfm)1239{1240struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1241struct safexcel_crypto_priv *priv = ctx->base.priv;1242int ret;12431244if (safexcel_cipher_cra_exit(tfm))1245return;12461247if (priv->flags & EIP197_TRC_CACHE) {1248ret = safexcel_skcipher_exit_inv(tfm);1249if (ret)1250dev_warn(priv->dev, "skcipher: invalidation error %d\n",1251ret);1252} else {1253dma_pool_free(priv->context_pool, ctx->base.ctxr,1254ctx->base.ctxr_dma);1255}1256}12571258static void safexcel_aead_cra_exit(struct crypto_tfm *tfm)1259{1260struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1261struct safexcel_crypto_priv *priv = ctx->base.priv;1262int ret;12631264if (safexcel_cipher_cra_exit(tfm))1265return;12661267if (priv->flags & EIP197_TRC_CACHE) {1268ret = safexcel_aead_exit_inv(tfm);1269if (ret)1270dev_warn(priv->dev, "aead: invalidation error %d\n",1271ret);1272} else {1273dma_pool_free(priv->context_pool, ctx->base.ctxr,1274ctx->base.ctxr_dma);1275}1276}12771278static int safexcel_skcipher_aes_ecb_cra_init(struct crypto_tfm *tfm)1279{1280struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);12811282safexcel_skcipher_cra_init(tfm);1283ctx->alg = SAFEXCEL_AES;1284ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;1285ctx->blocksz = 0;1286ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1287return 0;1288}12891290struct safexcel_alg_template safexcel_alg_ecb_aes = {1291.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1292.algo_mask = SAFEXCEL_ALG_AES,1293.alg.skcipher = {1294.setkey = safexcel_skcipher_aes_setkey,1295.encrypt = safexcel_encrypt,1296.decrypt = safexcel_decrypt,1297.min_keysize = AES_MIN_KEY_SIZE,1298.max_keysize = AES_MAX_KEY_SIZE,1299.base = {1300.cra_name = "ecb(aes)",1301.cra_driver_name = "safexcel-ecb-aes",1302.cra_priority = SAFEXCEL_CRA_PRIORITY,1303.cra_flags = CRYPTO_ALG_ASYNC |1304CRYPTO_ALG_ALLOCATES_MEMORY |1305CRYPTO_ALG_KERN_DRIVER_ONLY,1306.cra_blocksize = AES_BLOCK_SIZE,1307.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1308.cra_alignmask = 0,1309.cra_init = safexcel_skcipher_aes_ecb_cra_init,1310.cra_exit = safexcel_skcipher_cra_exit,1311.cra_module = THIS_MODULE,1312},1313},1314};13151316static int safexcel_skcipher_aes_cbc_cra_init(struct crypto_tfm *tfm)1317{1318struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);13191320safexcel_skcipher_cra_init(tfm);1321ctx->alg = SAFEXCEL_AES;1322ctx->blocksz = AES_BLOCK_SIZE;1323ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;1324return 0;1325}13261327struct safexcel_alg_template safexcel_alg_cbc_aes = {1328.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1329.algo_mask = SAFEXCEL_ALG_AES,1330.alg.skcipher = {1331.setkey = safexcel_skcipher_aes_setkey,1332.encrypt = safexcel_encrypt,1333.decrypt = safexcel_decrypt,1334.min_keysize = AES_MIN_KEY_SIZE,1335.max_keysize = AES_MAX_KEY_SIZE,1336.ivsize = AES_BLOCK_SIZE,1337.base = {1338.cra_name = "cbc(aes)",1339.cra_driver_name = "safexcel-cbc-aes",1340.cra_priority = SAFEXCEL_CRA_PRIORITY,1341.cra_flags = CRYPTO_ALG_ASYNC |1342CRYPTO_ALG_ALLOCATES_MEMORY |1343CRYPTO_ALG_KERN_DRIVER_ONLY,1344.cra_blocksize = AES_BLOCK_SIZE,1345.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1346.cra_alignmask = 0,1347.cra_init = safexcel_skcipher_aes_cbc_cra_init,1348.cra_exit = safexcel_skcipher_cra_exit,1349.cra_module = THIS_MODULE,1350},1351},1352};13531354static int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm,1355const u8 *key, unsigned int len)1356{1357struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);1358struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1359struct safexcel_crypto_priv *priv = ctx->base.priv;1360struct crypto_aes_ctx aes;1361int ret, i;1362unsigned int keylen;13631364/* last 4 bytes of key are the nonce! */1365ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);1366/* exclude the nonce here */1367keylen = len - CTR_RFC3686_NONCE_SIZE;1368ret = aes_expandkey(&aes, key, keylen);1369if (ret)1370return ret;13711372if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {1373for (i = 0; i < keylen / sizeof(u32); i++) {1374if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {1375ctx->base.needs_inv = true;1376break;1377}1378}1379}13801381for (i = 0; i < keylen / sizeof(u32); i++)1382ctx->key[i] = cpu_to_le32(aes.key_enc[i]);13831384ctx->key_len = keylen;13851386memzero_explicit(&aes, sizeof(aes));1387return 0;1388}13891390static int safexcel_skcipher_aes_ctr_cra_init(struct crypto_tfm *tfm)1391{1392struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);13931394safexcel_skcipher_cra_init(tfm);1395ctx->alg = SAFEXCEL_AES;1396ctx->blocksz = AES_BLOCK_SIZE;1397ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;1398return 0;1399}14001401struct safexcel_alg_template safexcel_alg_ctr_aes = {1402.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1403.algo_mask = SAFEXCEL_ALG_AES,1404.alg.skcipher = {1405.setkey = safexcel_skcipher_aesctr_setkey,1406.encrypt = safexcel_encrypt,1407.decrypt = safexcel_decrypt,1408/* Add nonce size */1409.min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,1410.max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,1411.ivsize = CTR_RFC3686_IV_SIZE,1412.base = {1413.cra_name = "rfc3686(ctr(aes))",1414.cra_driver_name = "safexcel-ctr-aes",1415.cra_priority = SAFEXCEL_CRA_PRIORITY,1416.cra_flags = CRYPTO_ALG_ASYNC |1417CRYPTO_ALG_ALLOCATES_MEMORY |1418CRYPTO_ALG_KERN_DRIVER_ONLY,1419.cra_blocksize = 1,1420.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1421.cra_alignmask = 0,1422.cra_init = safexcel_skcipher_aes_ctr_cra_init,1423.cra_exit = safexcel_skcipher_cra_exit,1424.cra_module = THIS_MODULE,1425},1426},1427};14281429static int safexcel_des_setkey(struct crypto_skcipher *ctfm, const u8 *key,1430unsigned int len)1431{1432struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);1433struct safexcel_crypto_priv *priv = ctx->base.priv;1434int ret;14351436ret = verify_skcipher_des_key(ctfm, key);1437if (ret)1438return ret;14391440/* if context exits and key changed, need to invalidate it */1441if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)1442if (memcmp(ctx->key, key, len))1443ctx->base.needs_inv = true;14441445memcpy(ctx->key, key, len);1446ctx->key_len = len;14471448return 0;1449}14501451static int safexcel_skcipher_des_cbc_cra_init(struct crypto_tfm *tfm)1452{1453struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);14541455safexcel_skcipher_cra_init(tfm);1456ctx->alg = SAFEXCEL_DES;1457ctx->blocksz = DES_BLOCK_SIZE;1458ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1459ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;1460return 0;1461}14621463struct safexcel_alg_template safexcel_alg_cbc_des = {1464.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1465.algo_mask = SAFEXCEL_ALG_DES,1466.alg.skcipher = {1467.setkey = safexcel_des_setkey,1468.encrypt = safexcel_encrypt,1469.decrypt = safexcel_decrypt,1470.min_keysize = DES_KEY_SIZE,1471.max_keysize = DES_KEY_SIZE,1472.ivsize = DES_BLOCK_SIZE,1473.base = {1474.cra_name = "cbc(des)",1475.cra_driver_name = "safexcel-cbc-des",1476.cra_priority = SAFEXCEL_CRA_PRIORITY,1477.cra_flags = CRYPTO_ALG_ASYNC |1478CRYPTO_ALG_ALLOCATES_MEMORY |1479CRYPTO_ALG_KERN_DRIVER_ONLY,1480.cra_blocksize = DES_BLOCK_SIZE,1481.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1482.cra_alignmask = 0,1483.cra_init = safexcel_skcipher_des_cbc_cra_init,1484.cra_exit = safexcel_skcipher_cra_exit,1485.cra_module = THIS_MODULE,1486},1487},1488};14891490static int safexcel_skcipher_des_ecb_cra_init(struct crypto_tfm *tfm)1491{1492struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);14931494safexcel_skcipher_cra_init(tfm);1495ctx->alg = SAFEXCEL_DES;1496ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;1497ctx->blocksz = 0;1498ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1499return 0;1500}15011502struct safexcel_alg_template safexcel_alg_ecb_des = {1503.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1504.algo_mask = SAFEXCEL_ALG_DES,1505.alg.skcipher = {1506.setkey = safexcel_des_setkey,1507.encrypt = safexcel_encrypt,1508.decrypt = safexcel_decrypt,1509.min_keysize = DES_KEY_SIZE,1510.max_keysize = DES_KEY_SIZE,1511.base = {1512.cra_name = "ecb(des)",1513.cra_driver_name = "safexcel-ecb-des",1514.cra_priority = SAFEXCEL_CRA_PRIORITY,1515.cra_flags = CRYPTO_ALG_ASYNC |1516CRYPTO_ALG_ALLOCATES_MEMORY |1517CRYPTO_ALG_KERN_DRIVER_ONLY,1518.cra_blocksize = DES_BLOCK_SIZE,1519.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1520.cra_alignmask = 0,1521.cra_init = safexcel_skcipher_des_ecb_cra_init,1522.cra_exit = safexcel_skcipher_cra_exit,1523.cra_module = THIS_MODULE,1524},1525},1526};15271528static int safexcel_des3_ede_setkey(struct crypto_skcipher *ctfm,1529const u8 *key, unsigned int len)1530{1531struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);1532struct safexcel_crypto_priv *priv = ctx->base.priv;1533int err;15341535err = verify_skcipher_des3_key(ctfm, key);1536if (err)1537return err;15381539/* if context exits and key changed, need to invalidate it */1540if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)1541if (memcmp(ctx->key, key, len))1542ctx->base.needs_inv = true;15431544memcpy(ctx->key, key, len);1545ctx->key_len = len;15461547return 0;1548}15491550static int safexcel_skcipher_des3_cbc_cra_init(struct crypto_tfm *tfm)1551{1552struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);15531554safexcel_skcipher_cra_init(tfm);1555ctx->alg = SAFEXCEL_3DES;1556ctx->blocksz = DES3_EDE_BLOCK_SIZE;1557ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1558ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;1559return 0;1560}15611562struct safexcel_alg_template safexcel_alg_cbc_des3_ede = {1563.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1564.algo_mask = SAFEXCEL_ALG_DES,1565.alg.skcipher = {1566.setkey = safexcel_des3_ede_setkey,1567.encrypt = safexcel_encrypt,1568.decrypt = safexcel_decrypt,1569.min_keysize = DES3_EDE_KEY_SIZE,1570.max_keysize = DES3_EDE_KEY_SIZE,1571.ivsize = DES3_EDE_BLOCK_SIZE,1572.base = {1573.cra_name = "cbc(des3_ede)",1574.cra_driver_name = "safexcel-cbc-des3_ede",1575.cra_priority = SAFEXCEL_CRA_PRIORITY,1576.cra_flags = CRYPTO_ALG_ASYNC |1577CRYPTO_ALG_ALLOCATES_MEMORY |1578CRYPTO_ALG_KERN_DRIVER_ONLY,1579.cra_blocksize = DES3_EDE_BLOCK_SIZE,1580.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1581.cra_alignmask = 0,1582.cra_init = safexcel_skcipher_des3_cbc_cra_init,1583.cra_exit = safexcel_skcipher_cra_exit,1584.cra_module = THIS_MODULE,1585},1586},1587};15881589static int safexcel_skcipher_des3_ecb_cra_init(struct crypto_tfm *tfm)1590{1591struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);15921593safexcel_skcipher_cra_init(tfm);1594ctx->alg = SAFEXCEL_3DES;1595ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;1596ctx->blocksz = 0;1597ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1598return 0;1599}16001601struct safexcel_alg_template safexcel_alg_ecb_des3_ede = {1602.type = SAFEXCEL_ALG_TYPE_SKCIPHER,1603.algo_mask = SAFEXCEL_ALG_DES,1604.alg.skcipher = {1605.setkey = safexcel_des3_ede_setkey,1606.encrypt = safexcel_encrypt,1607.decrypt = safexcel_decrypt,1608.min_keysize = DES3_EDE_KEY_SIZE,1609.max_keysize = DES3_EDE_KEY_SIZE,1610.base = {1611.cra_name = "ecb(des3_ede)",1612.cra_driver_name = "safexcel-ecb-des3_ede",1613.cra_priority = SAFEXCEL_CRA_PRIORITY,1614.cra_flags = CRYPTO_ALG_ASYNC |1615CRYPTO_ALG_ALLOCATES_MEMORY |1616CRYPTO_ALG_KERN_DRIVER_ONLY,1617.cra_blocksize = DES3_EDE_BLOCK_SIZE,1618.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1619.cra_alignmask = 0,1620.cra_init = safexcel_skcipher_des3_ecb_cra_init,1621.cra_exit = safexcel_skcipher_cra_exit,1622.cra_module = THIS_MODULE,1623},1624},1625};16261627static int safexcel_aead_encrypt(struct aead_request *req)1628{1629struct safexcel_cipher_req *creq = aead_request_ctx(req);16301631return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);1632}16331634static int safexcel_aead_decrypt(struct aead_request *req)1635{1636struct safexcel_cipher_req *creq = aead_request_ctx(req);16371638return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);1639}16401641static int safexcel_aead_cra_init(struct crypto_tfm *tfm)1642{1643struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);1644struct safexcel_alg_template *tmpl =1645container_of(tfm->__crt_alg, struct safexcel_alg_template,1646alg.aead.base);16471648crypto_aead_set_reqsize(__crypto_aead_cast(tfm),1649sizeof(struct safexcel_cipher_req));16501651ctx->base.priv = tmpl->priv;16521653ctx->alg = SAFEXCEL_AES; /* default */1654ctx->blocksz = AES_BLOCK_SIZE;1655ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD;1656ctx->ctrinit = 1;1657ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; /* default */1658ctx->aead = true;1659ctx->base.send = safexcel_aead_send;1660ctx->base.handle_result = safexcel_aead_handle_result;1661return 0;1662}16631664static int safexcel_aead_sha1_cra_init(struct crypto_tfm *tfm)1665{1666struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);16671668safexcel_aead_cra_init(tfm);1669ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;1670ctx->state_sz = SHA1_DIGEST_SIZE;1671return 0;1672}16731674struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_aes = {1675.type = SAFEXCEL_ALG_TYPE_AEAD,1676.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1,1677.alg.aead = {1678.setkey = safexcel_aead_setkey,1679.encrypt = safexcel_aead_encrypt,1680.decrypt = safexcel_aead_decrypt,1681.ivsize = AES_BLOCK_SIZE,1682.maxauthsize = SHA1_DIGEST_SIZE,1683.base = {1684.cra_name = "authenc(hmac(sha1),cbc(aes))",1685.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-aes",1686.cra_priority = SAFEXCEL_CRA_PRIORITY,1687.cra_flags = CRYPTO_ALG_ASYNC |1688CRYPTO_ALG_ALLOCATES_MEMORY |1689CRYPTO_ALG_KERN_DRIVER_ONLY,1690.cra_blocksize = AES_BLOCK_SIZE,1691.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1692.cra_alignmask = 0,1693.cra_init = safexcel_aead_sha1_cra_init,1694.cra_exit = safexcel_aead_cra_exit,1695.cra_module = THIS_MODULE,1696},1697},1698};16991700static int safexcel_aead_sha256_cra_init(struct crypto_tfm *tfm)1701{1702struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);17031704safexcel_aead_cra_init(tfm);1705ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256;1706ctx->state_sz = SHA256_DIGEST_SIZE;1707return 0;1708}17091710struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_aes = {1711.type = SAFEXCEL_ALG_TYPE_AEAD,1712.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,1713.alg.aead = {1714.setkey = safexcel_aead_setkey,1715.encrypt = safexcel_aead_encrypt,1716.decrypt = safexcel_aead_decrypt,1717.ivsize = AES_BLOCK_SIZE,1718.maxauthsize = SHA256_DIGEST_SIZE,1719.base = {1720.cra_name = "authenc(hmac(sha256),cbc(aes))",1721.cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-aes",1722.cra_priority = SAFEXCEL_CRA_PRIORITY,1723.cra_flags = CRYPTO_ALG_ASYNC |1724CRYPTO_ALG_ALLOCATES_MEMORY |1725CRYPTO_ALG_KERN_DRIVER_ONLY,1726.cra_blocksize = AES_BLOCK_SIZE,1727.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1728.cra_alignmask = 0,1729.cra_init = safexcel_aead_sha256_cra_init,1730.cra_exit = safexcel_aead_cra_exit,1731.cra_module = THIS_MODULE,1732},1733},1734};17351736static int safexcel_aead_sha224_cra_init(struct crypto_tfm *tfm)1737{1738struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);17391740safexcel_aead_cra_init(tfm);1741ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224;1742ctx->state_sz = SHA256_DIGEST_SIZE;1743return 0;1744}17451746struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_aes = {1747.type = SAFEXCEL_ALG_TYPE_AEAD,1748.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,1749.alg.aead = {1750.setkey = safexcel_aead_setkey,1751.encrypt = safexcel_aead_encrypt,1752.decrypt = safexcel_aead_decrypt,1753.ivsize = AES_BLOCK_SIZE,1754.maxauthsize = SHA224_DIGEST_SIZE,1755.base = {1756.cra_name = "authenc(hmac(sha224),cbc(aes))",1757.cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-aes",1758.cra_priority = SAFEXCEL_CRA_PRIORITY,1759.cra_flags = CRYPTO_ALG_ASYNC |1760CRYPTO_ALG_ALLOCATES_MEMORY |1761CRYPTO_ALG_KERN_DRIVER_ONLY,1762.cra_blocksize = AES_BLOCK_SIZE,1763.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1764.cra_alignmask = 0,1765.cra_init = safexcel_aead_sha224_cra_init,1766.cra_exit = safexcel_aead_cra_exit,1767.cra_module = THIS_MODULE,1768},1769},1770};17711772static int safexcel_aead_sha512_cra_init(struct crypto_tfm *tfm)1773{1774struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);17751776safexcel_aead_cra_init(tfm);1777ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512;1778ctx->state_sz = SHA512_DIGEST_SIZE;1779return 0;1780}17811782struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_aes = {1783.type = SAFEXCEL_ALG_TYPE_AEAD,1784.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,1785.alg.aead = {1786.setkey = safexcel_aead_setkey,1787.encrypt = safexcel_aead_encrypt,1788.decrypt = safexcel_aead_decrypt,1789.ivsize = AES_BLOCK_SIZE,1790.maxauthsize = SHA512_DIGEST_SIZE,1791.base = {1792.cra_name = "authenc(hmac(sha512),cbc(aes))",1793.cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-aes",1794.cra_priority = SAFEXCEL_CRA_PRIORITY,1795.cra_flags = CRYPTO_ALG_ASYNC |1796CRYPTO_ALG_ALLOCATES_MEMORY |1797CRYPTO_ALG_KERN_DRIVER_ONLY,1798.cra_blocksize = AES_BLOCK_SIZE,1799.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1800.cra_alignmask = 0,1801.cra_init = safexcel_aead_sha512_cra_init,1802.cra_exit = safexcel_aead_cra_exit,1803.cra_module = THIS_MODULE,1804},1805},1806};18071808static int safexcel_aead_sha384_cra_init(struct crypto_tfm *tfm)1809{1810struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);18111812safexcel_aead_cra_init(tfm);1813ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384;1814ctx->state_sz = SHA512_DIGEST_SIZE;1815return 0;1816}18171818struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_aes = {1819.type = SAFEXCEL_ALG_TYPE_AEAD,1820.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,1821.alg.aead = {1822.setkey = safexcel_aead_setkey,1823.encrypt = safexcel_aead_encrypt,1824.decrypt = safexcel_aead_decrypt,1825.ivsize = AES_BLOCK_SIZE,1826.maxauthsize = SHA384_DIGEST_SIZE,1827.base = {1828.cra_name = "authenc(hmac(sha384),cbc(aes))",1829.cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-aes",1830.cra_priority = SAFEXCEL_CRA_PRIORITY,1831.cra_flags = CRYPTO_ALG_ASYNC |1832CRYPTO_ALG_ALLOCATES_MEMORY |1833CRYPTO_ALG_KERN_DRIVER_ONLY,1834.cra_blocksize = AES_BLOCK_SIZE,1835.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1836.cra_alignmask = 0,1837.cra_init = safexcel_aead_sha384_cra_init,1838.cra_exit = safexcel_aead_cra_exit,1839.cra_module = THIS_MODULE,1840},1841},1842};18431844static int safexcel_aead_sha1_des3_cra_init(struct crypto_tfm *tfm)1845{1846struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);18471848safexcel_aead_sha1_cra_init(tfm);1849ctx->alg = SAFEXCEL_3DES; /* override default */1850ctx->blocksz = DES3_EDE_BLOCK_SIZE;1851ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1852return 0;1853}18541855struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des3_ede = {1856.type = SAFEXCEL_ALG_TYPE_AEAD,1857.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1,1858.alg.aead = {1859.setkey = safexcel_aead_setkey,1860.encrypt = safexcel_aead_encrypt,1861.decrypt = safexcel_aead_decrypt,1862.ivsize = DES3_EDE_BLOCK_SIZE,1863.maxauthsize = SHA1_DIGEST_SIZE,1864.base = {1865.cra_name = "authenc(hmac(sha1),cbc(des3_ede))",1866.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des3_ede",1867.cra_priority = SAFEXCEL_CRA_PRIORITY,1868.cra_flags = CRYPTO_ALG_ASYNC |1869CRYPTO_ALG_ALLOCATES_MEMORY |1870CRYPTO_ALG_KERN_DRIVER_ONLY,1871.cra_blocksize = DES3_EDE_BLOCK_SIZE,1872.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1873.cra_alignmask = 0,1874.cra_init = safexcel_aead_sha1_des3_cra_init,1875.cra_exit = safexcel_aead_cra_exit,1876.cra_module = THIS_MODULE,1877},1878},1879};18801881static int safexcel_aead_sha256_des3_cra_init(struct crypto_tfm *tfm)1882{1883struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);18841885safexcel_aead_sha256_cra_init(tfm);1886ctx->alg = SAFEXCEL_3DES; /* override default */1887ctx->blocksz = DES3_EDE_BLOCK_SIZE;1888ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1889return 0;1890}18911892struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede = {1893.type = SAFEXCEL_ALG_TYPE_AEAD,1894.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,1895.alg.aead = {1896.setkey = safexcel_aead_setkey,1897.encrypt = safexcel_aead_encrypt,1898.decrypt = safexcel_aead_decrypt,1899.ivsize = DES3_EDE_BLOCK_SIZE,1900.maxauthsize = SHA256_DIGEST_SIZE,1901.base = {1902.cra_name = "authenc(hmac(sha256),cbc(des3_ede))",1903.cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des3_ede",1904.cra_priority = SAFEXCEL_CRA_PRIORITY,1905.cra_flags = CRYPTO_ALG_ASYNC |1906CRYPTO_ALG_ALLOCATES_MEMORY |1907CRYPTO_ALG_KERN_DRIVER_ONLY,1908.cra_blocksize = DES3_EDE_BLOCK_SIZE,1909.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1910.cra_alignmask = 0,1911.cra_init = safexcel_aead_sha256_des3_cra_init,1912.cra_exit = safexcel_aead_cra_exit,1913.cra_module = THIS_MODULE,1914},1915},1916};19171918static int safexcel_aead_sha224_des3_cra_init(struct crypto_tfm *tfm)1919{1920struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);19211922safexcel_aead_sha224_cra_init(tfm);1923ctx->alg = SAFEXCEL_3DES; /* override default */1924ctx->blocksz = DES3_EDE_BLOCK_SIZE;1925ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1926return 0;1927}19281929struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede = {1930.type = SAFEXCEL_ALG_TYPE_AEAD,1931.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,1932.alg.aead = {1933.setkey = safexcel_aead_setkey,1934.encrypt = safexcel_aead_encrypt,1935.decrypt = safexcel_aead_decrypt,1936.ivsize = DES3_EDE_BLOCK_SIZE,1937.maxauthsize = SHA224_DIGEST_SIZE,1938.base = {1939.cra_name = "authenc(hmac(sha224),cbc(des3_ede))",1940.cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des3_ede",1941.cra_priority = SAFEXCEL_CRA_PRIORITY,1942.cra_flags = CRYPTO_ALG_ASYNC |1943CRYPTO_ALG_ALLOCATES_MEMORY |1944CRYPTO_ALG_KERN_DRIVER_ONLY,1945.cra_blocksize = DES3_EDE_BLOCK_SIZE,1946.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1947.cra_alignmask = 0,1948.cra_init = safexcel_aead_sha224_des3_cra_init,1949.cra_exit = safexcel_aead_cra_exit,1950.cra_module = THIS_MODULE,1951},1952},1953};19541955static int safexcel_aead_sha512_des3_cra_init(struct crypto_tfm *tfm)1956{1957struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);19581959safexcel_aead_sha512_cra_init(tfm);1960ctx->alg = SAFEXCEL_3DES; /* override default */1961ctx->blocksz = DES3_EDE_BLOCK_SIZE;1962ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;1963return 0;1964}19651966struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede = {1967.type = SAFEXCEL_ALG_TYPE_AEAD,1968.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,1969.alg.aead = {1970.setkey = safexcel_aead_setkey,1971.encrypt = safexcel_aead_encrypt,1972.decrypt = safexcel_aead_decrypt,1973.ivsize = DES3_EDE_BLOCK_SIZE,1974.maxauthsize = SHA512_DIGEST_SIZE,1975.base = {1976.cra_name = "authenc(hmac(sha512),cbc(des3_ede))",1977.cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des3_ede",1978.cra_priority = SAFEXCEL_CRA_PRIORITY,1979.cra_flags = CRYPTO_ALG_ASYNC |1980CRYPTO_ALG_ALLOCATES_MEMORY |1981CRYPTO_ALG_KERN_DRIVER_ONLY,1982.cra_blocksize = DES3_EDE_BLOCK_SIZE,1983.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),1984.cra_alignmask = 0,1985.cra_init = safexcel_aead_sha512_des3_cra_init,1986.cra_exit = safexcel_aead_cra_exit,1987.cra_module = THIS_MODULE,1988},1989},1990};19911992static int safexcel_aead_sha384_des3_cra_init(struct crypto_tfm *tfm)1993{1994struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);19951996safexcel_aead_sha384_cra_init(tfm);1997ctx->alg = SAFEXCEL_3DES; /* override default */1998ctx->blocksz = DES3_EDE_BLOCK_SIZE;1999ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;2000return 0;2001}20022003struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede = {2004.type = SAFEXCEL_ALG_TYPE_AEAD,2005.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,2006.alg.aead = {2007.setkey = safexcel_aead_setkey,2008.encrypt = safexcel_aead_encrypt,2009.decrypt = safexcel_aead_decrypt,2010.ivsize = DES3_EDE_BLOCK_SIZE,2011.maxauthsize = SHA384_DIGEST_SIZE,2012.base = {2013.cra_name = "authenc(hmac(sha384),cbc(des3_ede))",2014.cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des3_ede",2015.cra_priority = SAFEXCEL_CRA_PRIORITY,2016.cra_flags = CRYPTO_ALG_ASYNC |2017CRYPTO_ALG_ALLOCATES_MEMORY |2018CRYPTO_ALG_KERN_DRIVER_ONLY,2019.cra_blocksize = DES3_EDE_BLOCK_SIZE,2020.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2021.cra_alignmask = 0,2022.cra_init = safexcel_aead_sha384_des3_cra_init,2023.cra_exit = safexcel_aead_cra_exit,2024.cra_module = THIS_MODULE,2025},2026},2027};20282029static int safexcel_aead_sha1_des_cra_init(struct crypto_tfm *tfm)2030{2031struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);20322033safexcel_aead_sha1_cra_init(tfm);2034ctx->alg = SAFEXCEL_DES; /* override default */2035ctx->blocksz = DES_BLOCK_SIZE;2036ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;2037return 0;2038}20392040struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des = {2041.type = SAFEXCEL_ALG_TYPE_AEAD,2042.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1,2043.alg.aead = {2044.setkey = safexcel_aead_setkey,2045.encrypt = safexcel_aead_encrypt,2046.decrypt = safexcel_aead_decrypt,2047.ivsize = DES_BLOCK_SIZE,2048.maxauthsize = SHA1_DIGEST_SIZE,2049.base = {2050.cra_name = "authenc(hmac(sha1),cbc(des))",2051.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des",2052.cra_priority = SAFEXCEL_CRA_PRIORITY,2053.cra_flags = CRYPTO_ALG_ASYNC |2054CRYPTO_ALG_ALLOCATES_MEMORY |2055CRYPTO_ALG_KERN_DRIVER_ONLY,2056.cra_blocksize = DES_BLOCK_SIZE,2057.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2058.cra_alignmask = 0,2059.cra_init = safexcel_aead_sha1_des_cra_init,2060.cra_exit = safexcel_aead_cra_exit,2061.cra_module = THIS_MODULE,2062},2063},2064};20652066static int safexcel_aead_sha256_des_cra_init(struct crypto_tfm *tfm)2067{2068struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);20692070safexcel_aead_sha256_cra_init(tfm);2071ctx->alg = SAFEXCEL_DES; /* override default */2072ctx->blocksz = DES_BLOCK_SIZE;2073ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;2074return 0;2075}20762077struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des = {2078.type = SAFEXCEL_ALG_TYPE_AEAD,2079.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,2080.alg.aead = {2081.setkey = safexcel_aead_setkey,2082.encrypt = safexcel_aead_encrypt,2083.decrypt = safexcel_aead_decrypt,2084.ivsize = DES_BLOCK_SIZE,2085.maxauthsize = SHA256_DIGEST_SIZE,2086.base = {2087.cra_name = "authenc(hmac(sha256),cbc(des))",2088.cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des",2089.cra_priority = SAFEXCEL_CRA_PRIORITY,2090.cra_flags = CRYPTO_ALG_ASYNC |2091CRYPTO_ALG_ALLOCATES_MEMORY |2092CRYPTO_ALG_KERN_DRIVER_ONLY,2093.cra_blocksize = DES_BLOCK_SIZE,2094.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2095.cra_alignmask = 0,2096.cra_init = safexcel_aead_sha256_des_cra_init,2097.cra_exit = safexcel_aead_cra_exit,2098.cra_module = THIS_MODULE,2099},2100},2101};21022103static int safexcel_aead_sha224_des_cra_init(struct crypto_tfm *tfm)2104{2105struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);21062107safexcel_aead_sha224_cra_init(tfm);2108ctx->alg = SAFEXCEL_DES; /* override default */2109ctx->blocksz = DES_BLOCK_SIZE;2110ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;2111return 0;2112}21132114struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des = {2115.type = SAFEXCEL_ALG_TYPE_AEAD,2116.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,2117.alg.aead = {2118.setkey = safexcel_aead_setkey,2119.encrypt = safexcel_aead_encrypt,2120.decrypt = safexcel_aead_decrypt,2121.ivsize = DES_BLOCK_SIZE,2122.maxauthsize = SHA224_DIGEST_SIZE,2123.base = {2124.cra_name = "authenc(hmac(sha224),cbc(des))",2125.cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des",2126.cra_priority = SAFEXCEL_CRA_PRIORITY,2127.cra_flags = CRYPTO_ALG_ASYNC |2128CRYPTO_ALG_ALLOCATES_MEMORY |2129CRYPTO_ALG_KERN_DRIVER_ONLY,2130.cra_blocksize = DES_BLOCK_SIZE,2131.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2132.cra_alignmask = 0,2133.cra_init = safexcel_aead_sha224_des_cra_init,2134.cra_exit = safexcel_aead_cra_exit,2135.cra_module = THIS_MODULE,2136},2137},2138};21392140static int safexcel_aead_sha512_des_cra_init(struct crypto_tfm *tfm)2141{2142struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);21432144safexcel_aead_sha512_cra_init(tfm);2145ctx->alg = SAFEXCEL_DES; /* override default */2146ctx->blocksz = DES_BLOCK_SIZE;2147ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;2148return 0;2149}21502151struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des = {2152.type = SAFEXCEL_ALG_TYPE_AEAD,2153.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,2154.alg.aead = {2155.setkey = safexcel_aead_setkey,2156.encrypt = safexcel_aead_encrypt,2157.decrypt = safexcel_aead_decrypt,2158.ivsize = DES_BLOCK_SIZE,2159.maxauthsize = SHA512_DIGEST_SIZE,2160.base = {2161.cra_name = "authenc(hmac(sha512),cbc(des))",2162.cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des",2163.cra_priority = SAFEXCEL_CRA_PRIORITY,2164.cra_flags = CRYPTO_ALG_ASYNC |2165CRYPTO_ALG_ALLOCATES_MEMORY |2166CRYPTO_ALG_KERN_DRIVER_ONLY,2167.cra_blocksize = DES_BLOCK_SIZE,2168.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2169.cra_alignmask = 0,2170.cra_init = safexcel_aead_sha512_des_cra_init,2171.cra_exit = safexcel_aead_cra_exit,2172.cra_module = THIS_MODULE,2173},2174},2175};21762177static int safexcel_aead_sha384_des_cra_init(struct crypto_tfm *tfm)2178{2179struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);21802181safexcel_aead_sha384_cra_init(tfm);2182ctx->alg = SAFEXCEL_DES; /* override default */2183ctx->blocksz = DES_BLOCK_SIZE;2184ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;2185return 0;2186}21872188struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des = {2189.type = SAFEXCEL_ALG_TYPE_AEAD,2190.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,2191.alg.aead = {2192.setkey = safexcel_aead_setkey,2193.encrypt = safexcel_aead_encrypt,2194.decrypt = safexcel_aead_decrypt,2195.ivsize = DES_BLOCK_SIZE,2196.maxauthsize = SHA384_DIGEST_SIZE,2197.base = {2198.cra_name = "authenc(hmac(sha384),cbc(des))",2199.cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des",2200.cra_priority = SAFEXCEL_CRA_PRIORITY,2201.cra_flags = CRYPTO_ALG_ASYNC |2202CRYPTO_ALG_ALLOCATES_MEMORY |2203CRYPTO_ALG_KERN_DRIVER_ONLY,2204.cra_blocksize = DES_BLOCK_SIZE,2205.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2206.cra_alignmask = 0,2207.cra_init = safexcel_aead_sha384_des_cra_init,2208.cra_exit = safexcel_aead_cra_exit,2209.cra_module = THIS_MODULE,2210},2211},2212};22132214static int safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm *tfm)2215{2216struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);22172218safexcel_aead_sha1_cra_init(tfm);2219ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */2220return 0;2221}22222223struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_aes = {2224.type = SAFEXCEL_ALG_TYPE_AEAD,2225.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1,2226.alg.aead = {2227.setkey = safexcel_aead_setkey,2228.encrypt = safexcel_aead_encrypt,2229.decrypt = safexcel_aead_decrypt,2230.ivsize = CTR_RFC3686_IV_SIZE,2231.maxauthsize = SHA1_DIGEST_SIZE,2232.base = {2233.cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))",2234.cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-aes",2235.cra_priority = SAFEXCEL_CRA_PRIORITY,2236.cra_flags = CRYPTO_ALG_ASYNC |2237CRYPTO_ALG_ALLOCATES_MEMORY |2238CRYPTO_ALG_KERN_DRIVER_ONLY,2239.cra_blocksize = 1,2240.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2241.cra_alignmask = 0,2242.cra_init = safexcel_aead_sha1_ctr_cra_init,2243.cra_exit = safexcel_aead_cra_exit,2244.cra_module = THIS_MODULE,2245},2246},2247};22482249static int safexcel_aead_sha256_ctr_cra_init(struct crypto_tfm *tfm)2250{2251struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);22522253safexcel_aead_sha256_cra_init(tfm);2254ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */2255return 0;2256}22572258struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes = {2259.type = SAFEXCEL_ALG_TYPE_AEAD,2260.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,2261.alg.aead = {2262.setkey = safexcel_aead_setkey,2263.encrypt = safexcel_aead_encrypt,2264.decrypt = safexcel_aead_decrypt,2265.ivsize = CTR_RFC3686_IV_SIZE,2266.maxauthsize = SHA256_DIGEST_SIZE,2267.base = {2268.cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))",2269.cra_driver_name = "safexcel-authenc-hmac-sha256-ctr-aes",2270.cra_priority = SAFEXCEL_CRA_PRIORITY,2271.cra_flags = CRYPTO_ALG_ASYNC |2272CRYPTO_ALG_ALLOCATES_MEMORY |2273CRYPTO_ALG_KERN_DRIVER_ONLY,2274.cra_blocksize = 1,2275.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2276.cra_alignmask = 0,2277.cra_init = safexcel_aead_sha256_ctr_cra_init,2278.cra_exit = safexcel_aead_cra_exit,2279.cra_module = THIS_MODULE,2280},2281},2282};22832284static int safexcel_aead_sha224_ctr_cra_init(struct crypto_tfm *tfm)2285{2286struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);22872288safexcel_aead_sha224_cra_init(tfm);2289ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */2290return 0;2291}22922293struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_ctr_aes = {2294.type = SAFEXCEL_ALG_TYPE_AEAD,2295.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,2296.alg.aead = {2297.setkey = safexcel_aead_setkey,2298.encrypt = safexcel_aead_encrypt,2299.decrypt = safexcel_aead_decrypt,2300.ivsize = CTR_RFC3686_IV_SIZE,2301.maxauthsize = SHA224_DIGEST_SIZE,2302.base = {2303.cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))",2304.cra_driver_name = "safexcel-authenc-hmac-sha224-ctr-aes",2305.cra_priority = SAFEXCEL_CRA_PRIORITY,2306.cra_flags = CRYPTO_ALG_ASYNC |2307CRYPTO_ALG_ALLOCATES_MEMORY |2308CRYPTO_ALG_KERN_DRIVER_ONLY,2309.cra_blocksize = 1,2310.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2311.cra_alignmask = 0,2312.cra_init = safexcel_aead_sha224_ctr_cra_init,2313.cra_exit = safexcel_aead_cra_exit,2314.cra_module = THIS_MODULE,2315},2316},2317};23182319static int safexcel_aead_sha512_ctr_cra_init(struct crypto_tfm *tfm)2320{2321struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);23222323safexcel_aead_sha512_cra_init(tfm);2324ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */2325return 0;2326}23272328struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes = {2329.type = SAFEXCEL_ALG_TYPE_AEAD,2330.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,2331.alg.aead = {2332.setkey = safexcel_aead_setkey,2333.encrypt = safexcel_aead_encrypt,2334.decrypt = safexcel_aead_decrypt,2335.ivsize = CTR_RFC3686_IV_SIZE,2336.maxauthsize = SHA512_DIGEST_SIZE,2337.base = {2338.cra_name = "authenc(hmac(sha512),rfc3686(ctr(aes)))",2339.cra_driver_name = "safexcel-authenc-hmac-sha512-ctr-aes",2340.cra_priority = SAFEXCEL_CRA_PRIORITY,2341.cra_flags = CRYPTO_ALG_ASYNC |2342CRYPTO_ALG_ALLOCATES_MEMORY |2343CRYPTO_ALG_KERN_DRIVER_ONLY,2344.cra_blocksize = 1,2345.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2346.cra_alignmask = 0,2347.cra_init = safexcel_aead_sha512_ctr_cra_init,2348.cra_exit = safexcel_aead_cra_exit,2349.cra_module = THIS_MODULE,2350},2351},2352};23532354static int safexcel_aead_sha384_ctr_cra_init(struct crypto_tfm *tfm)2355{2356struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);23572358safexcel_aead_sha384_cra_init(tfm);2359ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */2360return 0;2361}23622363struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes = {2364.type = SAFEXCEL_ALG_TYPE_AEAD,2365.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,2366.alg.aead = {2367.setkey = safexcel_aead_setkey,2368.encrypt = safexcel_aead_encrypt,2369.decrypt = safexcel_aead_decrypt,2370.ivsize = CTR_RFC3686_IV_SIZE,2371.maxauthsize = SHA384_DIGEST_SIZE,2372.base = {2373.cra_name = "authenc(hmac(sha384),rfc3686(ctr(aes)))",2374.cra_driver_name = "safexcel-authenc-hmac-sha384-ctr-aes",2375.cra_priority = SAFEXCEL_CRA_PRIORITY,2376.cra_flags = CRYPTO_ALG_ASYNC |2377CRYPTO_ALG_ALLOCATES_MEMORY |2378CRYPTO_ALG_KERN_DRIVER_ONLY,2379.cra_blocksize = 1,2380.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2381.cra_alignmask = 0,2382.cra_init = safexcel_aead_sha384_ctr_cra_init,2383.cra_exit = safexcel_aead_cra_exit,2384.cra_module = THIS_MODULE,2385},2386},2387};23882389static int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm,2390const u8 *key, unsigned int len)2391{2392struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);2393struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2394struct safexcel_crypto_priv *priv = ctx->base.priv;2395struct crypto_aes_ctx aes;2396int ret, i;2397unsigned int keylen;23982399/* Check for illegal XTS keys */2400ret = xts_verify_key(ctfm, key, len);2401if (ret)2402return ret;24032404/* Only half of the key data is cipher key */2405keylen = (len >> 1);2406ret = aes_expandkey(&aes, key, keylen);2407if (ret)2408return ret;24092410if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {2411for (i = 0; i < keylen / sizeof(u32); i++) {2412if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {2413ctx->base.needs_inv = true;2414break;2415}2416}2417}24182419for (i = 0; i < keylen / sizeof(u32); i++)2420ctx->key[i] = cpu_to_le32(aes.key_enc[i]);24212422/* The other half is the tweak key */2423ret = aes_expandkey(&aes, (u8 *)(key + keylen), keylen);2424if (ret)2425return ret;24262427if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {2428for (i = 0; i < keylen / sizeof(u32); i++) {2429if (le32_to_cpu(ctx->key[i + keylen / sizeof(u32)]) !=2430aes.key_enc[i]) {2431ctx->base.needs_inv = true;2432break;2433}2434}2435}24362437for (i = 0; i < keylen / sizeof(u32); i++)2438ctx->key[i + keylen / sizeof(u32)] =2439cpu_to_le32(aes.key_enc[i]);24402441ctx->key_len = keylen << 1;24422443memzero_explicit(&aes, sizeof(aes));2444return 0;2445}24462447static int safexcel_skcipher_aes_xts_cra_init(struct crypto_tfm *tfm)2448{2449struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);24502451safexcel_skcipher_cra_init(tfm);2452ctx->alg = SAFEXCEL_AES;2453ctx->blocksz = AES_BLOCK_SIZE;2454ctx->xts = 1;2455ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS;2456return 0;2457}24582459static int safexcel_encrypt_xts(struct skcipher_request *req)2460{2461if (req->cryptlen < XTS_BLOCK_SIZE)2462return -EINVAL;2463return safexcel_queue_req(&req->base, skcipher_request_ctx(req),2464SAFEXCEL_ENCRYPT);2465}24662467static int safexcel_decrypt_xts(struct skcipher_request *req)2468{2469if (req->cryptlen < XTS_BLOCK_SIZE)2470return -EINVAL;2471return safexcel_queue_req(&req->base, skcipher_request_ctx(req),2472SAFEXCEL_DECRYPT);2473}24742475struct safexcel_alg_template safexcel_alg_xts_aes = {2476.type = SAFEXCEL_ALG_TYPE_SKCIPHER,2477.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XTS,2478.alg.skcipher = {2479.setkey = safexcel_skcipher_aesxts_setkey,2480.encrypt = safexcel_encrypt_xts,2481.decrypt = safexcel_decrypt_xts,2482/* XTS actually uses 2 AES keys glued together */2483.min_keysize = AES_MIN_KEY_SIZE * 2,2484.max_keysize = AES_MAX_KEY_SIZE * 2,2485.ivsize = XTS_BLOCK_SIZE,2486.base = {2487.cra_name = "xts(aes)",2488.cra_driver_name = "safexcel-xts-aes",2489.cra_priority = SAFEXCEL_CRA_PRIORITY,2490.cra_flags = CRYPTO_ALG_ASYNC |2491CRYPTO_ALG_ALLOCATES_MEMORY |2492CRYPTO_ALG_KERN_DRIVER_ONLY,2493.cra_blocksize = XTS_BLOCK_SIZE,2494.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2495.cra_alignmask = 0,2496.cra_init = safexcel_skcipher_aes_xts_cra_init,2497.cra_exit = safexcel_skcipher_cra_exit,2498.cra_module = THIS_MODULE,2499},2500},2501};25022503static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key,2504unsigned int len)2505{2506struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);2507struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2508struct safexcel_crypto_priv *priv = ctx->base.priv;2509struct crypto_aes_ctx aes;2510u32 hashkey[AES_BLOCK_SIZE >> 2];2511int ret, i;25122513ret = aes_expandkey(&aes, key, len);2514if (ret) {2515memzero_explicit(&aes, sizeof(aes));2516return ret;2517}25182519if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {2520for (i = 0; i < len / sizeof(u32); i++) {2521if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {2522ctx->base.needs_inv = true;2523break;2524}2525}2526}25272528for (i = 0; i < len / sizeof(u32); i++)2529ctx->key[i] = cpu_to_le32(aes.key_enc[i]);25302531ctx->key_len = len;25322533/* Compute hash key by encrypting zeroes with cipher key */2534memset(hashkey, 0, AES_BLOCK_SIZE);2535aes_encrypt(&aes, (u8 *)hashkey, (u8 *)hashkey);25362537if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {2538for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) {2539if (be32_to_cpu(ctx->base.ipad.be[i]) != hashkey[i]) {2540ctx->base.needs_inv = true;2541break;2542}2543}2544}25452546for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++)2547ctx->base.ipad.be[i] = cpu_to_be32(hashkey[i]);25482549memzero_explicit(hashkey, AES_BLOCK_SIZE);2550memzero_explicit(&aes, sizeof(aes));2551return 0;2552}25532554static int safexcel_aead_gcm_cra_init(struct crypto_tfm *tfm)2555{2556struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);25572558safexcel_aead_cra_init(tfm);2559ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_GHASH;2560ctx->state_sz = GHASH_BLOCK_SIZE;2561ctx->xcm = EIP197_XCM_MODE_GCM;2562ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */25632564return 0;2565}25662567static void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm)2568{2569safexcel_aead_cra_exit(tfm);2570}25712572static int safexcel_aead_gcm_setauthsize(struct crypto_aead *tfm,2573unsigned int authsize)2574{2575return crypto_gcm_check_authsize(authsize);2576}25772578struct safexcel_alg_template safexcel_alg_gcm = {2579.type = SAFEXCEL_ALG_TYPE_AEAD,2580.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,2581.alg.aead = {2582.setkey = safexcel_aead_gcm_setkey,2583.setauthsize = safexcel_aead_gcm_setauthsize,2584.encrypt = safexcel_aead_encrypt,2585.decrypt = safexcel_aead_decrypt,2586.ivsize = GCM_AES_IV_SIZE,2587.maxauthsize = GHASH_DIGEST_SIZE,2588.base = {2589.cra_name = "gcm(aes)",2590.cra_driver_name = "safexcel-gcm-aes",2591.cra_priority = SAFEXCEL_CRA_PRIORITY,2592.cra_flags = CRYPTO_ALG_ASYNC |2593CRYPTO_ALG_ALLOCATES_MEMORY |2594CRYPTO_ALG_KERN_DRIVER_ONLY,2595.cra_blocksize = 1,2596.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2597.cra_alignmask = 0,2598.cra_init = safexcel_aead_gcm_cra_init,2599.cra_exit = safexcel_aead_gcm_cra_exit,2600.cra_module = THIS_MODULE,2601},2602},2603};26042605static int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key,2606unsigned int len)2607{2608struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);2609struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2610struct safexcel_crypto_priv *priv = ctx->base.priv;2611struct crypto_aes_ctx aes;2612int ret, i;26132614ret = aes_expandkey(&aes, key, len);2615if (ret) {2616memzero_explicit(&aes, sizeof(aes));2617return ret;2618}26192620if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {2621for (i = 0; i < len / sizeof(u32); i++) {2622if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {2623ctx->base.needs_inv = true;2624break;2625}2626}2627}26282629for (i = 0; i < len / sizeof(u32); i++) {2630ctx->key[i] = cpu_to_le32(aes.key_enc[i]);2631ctx->base.ipad.be[i + 2 * AES_BLOCK_SIZE / sizeof(u32)] =2632cpu_to_be32(aes.key_enc[i]);2633}26342635ctx->key_len = len;2636ctx->state_sz = 2 * AES_BLOCK_SIZE + len;26372638if (len == AES_KEYSIZE_192)2639ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192;2640else if (len == AES_KEYSIZE_256)2641ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256;2642else2643ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128;26442645memzero_explicit(&aes, sizeof(aes));2646return 0;2647}26482649static int safexcel_aead_ccm_cra_init(struct crypto_tfm *tfm)2650{2651struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);26522653safexcel_aead_cra_init(tfm);2654ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128;2655ctx->state_sz = 3 * AES_BLOCK_SIZE;2656ctx->xcm = EIP197_XCM_MODE_CCM;2657ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */2658ctx->ctrinit = 0;2659return 0;2660}26612662static int safexcel_aead_ccm_setauthsize(struct crypto_aead *tfm,2663unsigned int authsize)2664{2665/* Borrowed from crypto/ccm.c */2666switch (authsize) {2667case 4:2668case 6:2669case 8:2670case 10:2671case 12:2672case 14:2673case 16:2674break;2675default:2676return -EINVAL;2677}26782679return 0;2680}26812682static int safexcel_ccm_encrypt(struct aead_request *req)2683{2684struct safexcel_cipher_req *creq = aead_request_ctx(req);26852686if (req->iv[0] < 1 || req->iv[0] > 7)2687return -EINVAL;26882689return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);2690}26912692static int safexcel_ccm_decrypt(struct aead_request *req)2693{2694struct safexcel_cipher_req *creq = aead_request_ctx(req);26952696if (req->iv[0] < 1 || req->iv[0] > 7)2697return -EINVAL;26982699return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);2700}27012702struct safexcel_alg_template safexcel_alg_ccm = {2703.type = SAFEXCEL_ALG_TYPE_AEAD,2704.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL,2705.alg.aead = {2706.setkey = safexcel_aead_ccm_setkey,2707.setauthsize = safexcel_aead_ccm_setauthsize,2708.encrypt = safexcel_ccm_encrypt,2709.decrypt = safexcel_ccm_decrypt,2710.ivsize = AES_BLOCK_SIZE,2711.maxauthsize = AES_BLOCK_SIZE,2712.base = {2713.cra_name = "ccm(aes)",2714.cra_driver_name = "safexcel-ccm-aes",2715.cra_priority = SAFEXCEL_CRA_PRIORITY,2716.cra_flags = CRYPTO_ALG_ASYNC |2717CRYPTO_ALG_ALLOCATES_MEMORY |2718CRYPTO_ALG_KERN_DRIVER_ONLY,2719.cra_blocksize = 1,2720.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2721.cra_alignmask = 0,2722.cra_init = safexcel_aead_ccm_cra_init,2723.cra_exit = safexcel_aead_cra_exit,2724.cra_module = THIS_MODULE,2725},2726},2727};27282729static void safexcel_chacha20_setkey(struct safexcel_cipher_ctx *ctx,2730const u8 *key)2731{2732struct safexcel_crypto_priv *priv = ctx->base.priv;27332734if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)2735if (memcmp(ctx->key, key, CHACHA_KEY_SIZE))2736ctx->base.needs_inv = true;27372738memcpy(ctx->key, key, CHACHA_KEY_SIZE);2739ctx->key_len = CHACHA_KEY_SIZE;2740}27412742static int safexcel_skcipher_chacha20_setkey(struct crypto_skcipher *ctfm,2743const u8 *key, unsigned int len)2744{2745struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);27462747if (len != CHACHA_KEY_SIZE)2748return -EINVAL;27492750safexcel_chacha20_setkey(ctx, key);27512752return 0;2753}27542755static int safexcel_skcipher_chacha20_cra_init(struct crypto_tfm *tfm)2756{2757struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);27582759safexcel_skcipher_cra_init(tfm);2760ctx->alg = SAFEXCEL_CHACHA20;2761ctx->ctrinit = 0;2762ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32;2763return 0;2764}27652766struct safexcel_alg_template safexcel_alg_chacha20 = {2767.type = SAFEXCEL_ALG_TYPE_SKCIPHER,2768.algo_mask = SAFEXCEL_ALG_CHACHA20,2769.alg.skcipher = {2770.setkey = safexcel_skcipher_chacha20_setkey,2771.encrypt = safexcel_encrypt,2772.decrypt = safexcel_decrypt,2773.min_keysize = CHACHA_KEY_SIZE,2774.max_keysize = CHACHA_KEY_SIZE,2775.ivsize = CHACHA_IV_SIZE,2776.base = {2777.cra_name = "chacha20",2778.cra_driver_name = "safexcel-chacha20",2779.cra_priority = SAFEXCEL_CRA_PRIORITY,2780.cra_flags = CRYPTO_ALG_ASYNC |2781CRYPTO_ALG_ALLOCATES_MEMORY |2782CRYPTO_ALG_KERN_DRIVER_ONLY,2783.cra_blocksize = 1,2784.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2785.cra_alignmask = 0,2786.cra_init = safexcel_skcipher_chacha20_cra_init,2787.cra_exit = safexcel_skcipher_cra_exit,2788.cra_module = THIS_MODULE,2789},2790},2791};27922793static int safexcel_aead_chachapoly_setkey(struct crypto_aead *ctfm,2794const u8 *key, unsigned int len)2795{2796struct safexcel_cipher_ctx *ctx = crypto_aead_ctx(ctfm);27972798if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP &&2799len > EIP197_AEAD_IPSEC_NONCE_SIZE) {2800/* ESP variant has nonce appended to key */2801len -= EIP197_AEAD_IPSEC_NONCE_SIZE;2802ctx->nonce = *(u32 *)(key + len);2803}2804if (len != CHACHA_KEY_SIZE)2805return -EINVAL;28062807safexcel_chacha20_setkey(ctx, key);28082809return 0;2810}28112812static int safexcel_aead_chachapoly_setauthsize(struct crypto_aead *tfm,2813unsigned int authsize)2814{2815if (authsize != POLY1305_DIGEST_SIZE)2816return -EINVAL;2817return 0;2818}28192820static int safexcel_aead_chachapoly_crypt(struct aead_request *req,2821enum safexcel_cipher_direction dir)2822{2823struct safexcel_cipher_req *creq = aead_request_ctx(req);2824struct crypto_aead *aead = crypto_aead_reqtfm(req);2825struct crypto_tfm *tfm = crypto_aead_tfm(aead);2826struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2827struct aead_request *subreq = aead_request_ctx(req);2828u32 key[CHACHA_KEY_SIZE / sizeof(u32) + 1];2829int ret = 0;28302831/*2832* Instead of wasting time detecting umpteen silly corner cases,2833* just dump all "small" requests to the fallback implementation.2834* HW would not be faster on such small requests anyway.2835*/2836if (likely((ctx->aead != EIP197_AEAD_TYPE_IPSEC_ESP ||2837req->assoclen >= EIP197_AEAD_IPSEC_IV_SIZE) &&2838req->cryptlen > POLY1305_DIGEST_SIZE)) {2839return safexcel_queue_req(&req->base, creq, dir);2840}28412842/* HW cannot do full (AAD+payload) zero length, use fallback */2843memcpy(key, ctx->key, CHACHA_KEY_SIZE);2844if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {2845/* ESP variant has nonce appended to the key */2846key[CHACHA_KEY_SIZE / sizeof(u32)] = ctx->nonce;2847ret = crypto_aead_setkey(ctx->fback, (u8 *)key,2848CHACHA_KEY_SIZE +2849EIP197_AEAD_IPSEC_NONCE_SIZE);2850} else {2851ret = crypto_aead_setkey(ctx->fback, (u8 *)key,2852CHACHA_KEY_SIZE);2853}2854if (ret) {2855crypto_aead_clear_flags(aead, CRYPTO_TFM_REQ_MASK);2856crypto_aead_set_flags(aead, crypto_aead_get_flags(ctx->fback) &2857CRYPTO_TFM_REQ_MASK);2858return ret;2859}28602861aead_request_set_tfm(subreq, ctx->fback);2862aead_request_set_callback(subreq, req->base.flags, req->base.complete,2863req->base.data);2864aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,2865req->iv);2866aead_request_set_ad(subreq, req->assoclen);28672868return (dir == SAFEXCEL_ENCRYPT) ?2869crypto_aead_encrypt(subreq) :2870crypto_aead_decrypt(subreq);2871}28722873static int safexcel_aead_chachapoly_encrypt(struct aead_request *req)2874{2875return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_ENCRYPT);2876}28772878static int safexcel_aead_chachapoly_decrypt(struct aead_request *req)2879{2880return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_DECRYPT);2881}28822883static int safexcel_aead_fallback_cra_init(struct crypto_tfm *tfm)2884{2885struct crypto_aead *aead = __crypto_aead_cast(tfm);2886struct aead_alg *alg = crypto_aead_alg(aead);2887struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);28882889safexcel_aead_cra_init(tfm);28902891/* Allocate fallback implementation */2892ctx->fback = crypto_alloc_aead(alg->base.cra_name, 0,2893CRYPTO_ALG_ASYNC |2894CRYPTO_ALG_NEED_FALLBACK);2895if (IS_ERR(ctx->fback))2896return PTR_ERR(ctx->fback);28972898crypto_aead_set_reqsize(aead, max(sizeof(struct safexcel_cipher_req),2899sizeof(struct aead_request) +2900crypto_aead_reqsize(ctx->fback)));29012902return 0;2903}29042905static int safexcel_aead_chachapoly_cra_init(struct crypto_tfm *tfm)2906{2907struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);29082909safexcel_aead_fallback_cra_init(tfm);2910ctx->alg = SAFEXCEL_CHACHA20;2911ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32 |2912CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK;2913ctx->ctrinit = 0;2914ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_POLY1305;2915ctx->state_sz = 0; /* Precomputed by HW */2916return 0;2917}29182919static void safexcel_aead_fallback_cra_exit(struct crypto_tfm *tfm)2920{2921struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);29222923crypto_free_aead(ctx->fback);2924safexcel_aead_cra_exit(tfm);2925}29262927struct safexcel_alg_template safexcel_alg_chachapoly = {2928.type = SAFEXCEL_ALG_TYPE_AEAD,2929.algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305,2930.alg.aead = {2931.setkey = safexcel_aead_chachapoly_setkey,2932.setauthsize = safexcel_aead_chachapoly_setauthsize,2933.encrypt = safexcel_aead_chachapoly_encrypt,2934.decrypt = safexcel_aead_chachapoly_decrypt,2935.ivsize = CHACHAPOLY_IV_SIZE,2936.maxauthsize = POLY1305_DIGEST_SIZE,2937.base = {2938.cra_name = "rfc7539(chacha20,poly1305)",2939.cra_driver_name = "safexcel-chacha20-poly1305",2940/* +1 to put it above HW chacha + SW poly */2941.cra_priority = SAFEXCEL_CRA_PRIORITY + 1,2942.cra_flags = CRYPTO_ALG_ASYNC |2943CRYPTO_ALG_ALLOCATES_MEMORY |2944CRYPTO_ALG_KERN_DRIVER_ONLY |2945CRYPTO_ALG_NEED_FALLBACK,2946.cra_blocksize = 1,2947.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2948.cra_alignmask = 0,2949.cra_init = safexcel_aead_chachapoly_cra_init,2950.cra_exit = safexcel_aead_fallback_cra_exit,2951.cra_module = THIS_MODULE,2952},2953},2954};29552956static int safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm *tfm)2957{2958struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);2959int ret;29602961ret = safexcel_aead_chachapoly_cra_init(tfm);2962ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP;2963ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;2964return ret;2965}29662967struct safexcel_alg_template safexcel_alg_chachapoly_esp = {2968.type = SAFEXCEL_ALG_TYPE_AEAD,2969.algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305,2970.alg.aead = {2971.setkey = safexcel_aead_chachapoly_setkey,2972.setauthsize = safexcel_aead_chachapoly_setauthsize,2973.encrypt = safexcel_aead_chachapoly_encrypt,2974.decrypt = safexcel_aead_chachapoly_decrypt,2975.ivsize = CHACHAPOLY_IV_SIZE - EIP197_AEAD_IPSEC_NONCE_SIZE,2976.maxauthsize = POLY1305_DIGEST_SIZE,2977.base = {2978.cra_name = "rfc7539esp(chacha20,poly1305)",2979.cra_driver_name = "safexcel-chacha20-poly1305-esp",2980/* +1 to put it above HW chacha + SW poly */2981.cra_priority = SAFEXCEL_CRA_PRIORITY + 1,2982.cra_flags = CRYPTO_ALG_ASYNC |2983CRYPTO_ALG_ALLOCATES_MEMORY |2984CRYPTO_ALG_KERN_DRIVER_ONLY |2985CRYPTO_ALG_NEED_FALLBACK,2986.cra_blocksize = 1,2987.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),2988.cra_alignmask = 0,2989.cra_init = safexcel_aead_chachapolyesp_cra_init,2990.cra_exit = safexcel_aead_fallback_cra_exit,2991.cra_module = THIS_MODULE,2992},2993},2994};29952996static int safexcel_skcipher_sm4_setkey(struct crypto_skcipher *ctfm,2997const u8 *key, unsigned int len)2998{2999struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);3000struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3001struct safexcel_crypto_priv *priv = ctx->base.priv;30023003if (len != SM4_KEY_SIZE)3004return -EINVAL;30053006if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)3007if (memcmp(ctx->key, key, SM4_KEY_SIZE))3008ctx->base.needs_inv = true;30093010memcpy(ctx->key, key, SM4_KEY_SIZE);3011ctx->key_len = SM4_KEY_SIZE;30123013return 0;3014}30153016static int safexcel_sm4_blk_encrypt(struct skcipher_request *req)3017{3018/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */3019if (req->cryptlen & (SM4_BLOCK_SIZE - 1))3020return -EINVAL;3021else3022return safexcel_queue_req(&req->base, skcipher_request_ctx(req),3023SAFEXCEL_ENCRYPT);3024}30253026static int safexcel_sm4_blk_decrypt(struct skcipher_request *req)3027{3028/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */3029if (req->cryptlen & (SM4_BLOCK_SIZE - 1))3030return -EINVAL;3031else3032return safexcel_queue_req(&req->base, skcipher_request_ctx(req),3033SAFEXCEL_DECRYPT);3034}30353036static int safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm *tfm)3037{3038struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);30393040safexcel_skcipher_cra_init(tfm);3041ctx->alg = SAFEXCEL_SM4;3042ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;3043ctx->blocksz = 0;3044ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;3045return 0;3046}30473048struct safexcel_alg_template safexcel_alg_ecb_sm4 = {3049.type = SAFEXCEL_ALG_TYPE_SKCIPHER,3050.algo_mask = SAFEXCEL_ALG_SM4,3051.alg.skcipher = {3052.setkey = safexcel_skcipher_sm4_setkey,3053.encrypt = safexcel_sm4_blk_encrypt,3054.decrypt = safexcel_sm4_blk_decrypt,3055.min_keysize = SM4_KEY_SIZE,3056.max_keysize = SM4_KEY_SIZE,3057.base = {3058.cra_name = "ecb(sm4)",3059.cra_driver_name = "safexcel-ecb-sm4",3060.cra_priority = SAFEXCEL_CRA_PRIORITY,3061.cra_flags = CRYPTO_ALG_ASYNC |3062CRYPTO_ALG_ALLOCATES_MEMORY |3063CRYPTO_ALG_KERN_DRIVER_ONLY,3064.cra_blocksize = SM4_BLOCK_SIZE,3065.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3066.cra_alignmask = 0,3067.cra_init = safexcel_skcipher_sm4_ecb_cra_init,3068.cra_exit = safexcel_skcipher_cra_exit,3069.cra_module = THIS_MODULE,3070},3071},3072};30733074static int safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm *tfm)3075{3076struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);30773078safexcel_skcipher_cra_init(tfm);3079ctx->alg = SAFEXCEL_SM4;3080ctx->blocksz = SM4_BLOCK_SIZE;3081ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;3082return 0;3083}30843085struct safexcel_alg_template safexcel_alg_cbc_sm4 = {3086.type = SAFEXCEL_ALG_TYPE_SKCIPHER,3087.algo_mask = SAFEXCEL_ALG_SM4,3088.alg.skcipher = {3089.setkey = safexcel_skcipher_sm4_setkey,3090.encrypt = safexcel_sm4_blk_encrypt,3091.decrypt = safexcel_sm4_blk_decrypt,3092.min_keysize = SM4_KEY_SIZE,3093.max_keysize = SM4_KEY_SIZE,3094.ivsize = SM4_BLOCK_SIZE,3095.base = {3096.cra_name = "cbc(sm4)",3097.cra_driver_name = "safexcel-cbc-sm4",3098.cra_priority = SAFEXCEL_CRA_PRIORITY,3099.cra_flags = CRYPTO_ALG_ASYNC |3100CRYPTO_ALG_ALLOCATES_MEMORY |3101CRYPTO_ALG_KERN_DRIVER_ONLY,3102.cra_blocksize = SM4_BLOCK_SIZE,3103.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3104.cra_alignmask = 0,3105.cra_init = safexcel_skcipher_sm4_cbc_cra_init,3106.cra_exit = safexcel_skcipher_cra_exit,3107.cra_module = THIS_MODULE,3108},3109},3110};31113112static int safexcel_skcipher_sm4ctr_setkey(struct crypto_skcipher *ctfm,3113const u8 *key, unsigned int len)3114{3115struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);3116struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);31173118/* last 4 bytes of key are the nonce! */3119ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);3120/* exclude the nonce here */3121len -= CTR_RFC3686_NONCE_SIZE;31223123return safexcel_skcipher_sm4_setkey(ctfm, key, len);3124}31253126static int safexcel_skcipher_sm4_ctr_cra_init(struct crypto_tfm *tfm)3127{3128struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);31293130safexcel_skcipher_cra_init(tfm);3131ctx->alg = SAFEXCEL_SM4;3132ctx->blocksz = SM4_BLOCK_SIZE;3133ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;3134return 0;3135}31363137struct safexcel_alg_template safexcel_alg_ctr_sm4 = {3138.type = SAFEXCEL_ALG_TYPE_SKCIPHER,3139.algo_mask = SAFEXCEL_ALG_SM4,3140.alg.skcipher = {3141.setkey = safexcel_skcipher_sm4ctr_setkey,3142.encrypt = safexcel_encrypt,3143.decrypt = safexcel_decrypt,3144/* Add nonce size */3145.min_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,3146.max_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,3147.ivsize = CTR_RFC3686_IV_SIZE,3148.base = {3149.cra_name = "rfc3686(ctr(sm4))",3150.cra_driver_name = "safexcel-ctr-sm4",3151.cra_priority = SAFEXCEL_CRA_PRIORITY,3152.cra_flags = CRYPTO_ALG_ASYNC |3153CRYPTO_ALG_ALLOCATES_MEMORY |3154CRYPTO_ALG_KERN_DRIVER_ONLY,3155.cra_blocksize = 1,3156.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3157.cra_alignmask = 0,3158.cra_init = safexcel_skcipher_sm4_ctr_cra_init,3159.cra_exit = safexcel_skcipher_cra_exit,3160.cra_module = THIS_MODULE,3161},3162},3163};31643165static int safexcel_aead_sm4_blk_encrypt(struct aead_request *req)3166{3167/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */3168if (req->cryptlen & (SM4_BLOCK_SIZE - 1))3169return -EINVAL;31703171return safexcel_queue_req(&req->base, aead_request_ctx(req),3172SAFEXCEL_ENCRYPT);3173}31743175static int safexcel_aead_sm4_blk_decrypt(struct aead_request *req)3176{3177struct crypto_aead *tfm = crypto_aead_reqtfm(req);31783179/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */3180if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1))3181return -EINVAL;31823183return safexcel_queue_req(&req->base, aead_request_ctx(req),3184SAFEXCEL_DECRYPT);3185}31863187static int safexcel_aead_sm4cbc_sha1_cra_init(struct crypto_tfm *tfm)3188{3189struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);31903191safexcel_aead_cra_init(tfm);3192ctx->alg = SAFEXCEL_SM4;3193ctx->blocksz = SM4_BLOCK_SIZE;3194ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;3195ctx->state_sz = SHA1_DIGEST_SIZE;3196return 0;3197}31983199struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4 = {3200.type = SAFEXCEL_ALG_TYPE_AEAD,3201.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1,3202.alg.aead = {3203.setkey = safexcel_aead_setkey,3204.encrypt = safexcel_aead_sm4_blk_encrypt,3205.decrypt = safexcel_aead_sm4_blk_decrypt,3206.ivsize = SM4_BLOCK_SIZE,3207.maxauthsize = SHA1_DIGEST_SIZE,3208.base = {3209.cra_name = "authenc(hmac(sha1),cbc(sm4))",3210.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-sm4",3211.cra_priority = SAFEXCEL_CRA_PRIORITY,3212.cra_flags = CRYPTO_ALG_ASYNC |3213CRYPTO_ALG_ALLOCATES_MEMORY |3214CRYPTO_ALG_KERN_DRIVER_ONLY,3215.cra_blocksize = SM4_BLOCK_SIZE,3216.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3217.cra_alignmask = 0,3218.cra_init = safexcel_aead_sm4cbc_sha1_cra_init,3219.cra_exit = safexcel_aead_cra_exit,3220.cra_module = THIS_MODULE,3221},3222},3223};32243225static int safexcel_aead_fallback_setkey(struct crypto_aead *ctfm,3226const u8 *key, unsigned int len)3227{3228struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);3229struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);32303231/* Keep fallback cipher synchronized */3232return crypto_aead_setkey(ctx->fback, (u8 *)key, len) ?:3233safexcel_aead_setkey(ctfm, key, len);3234}32353236static int safexcel_aead_fallback_setauthsize(struct crypto_aead *ctfm,3237unsigned int authsize)3238{3239struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);3240struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);32413242/* Keep fallback cipher synchronized */3243return crypto_aead_setauthsize(ctx->fback, authsize);3244}32453246static int safexcel_aead_fallback_crypt(struct aead_request *req,3247enum safexcel_cipher_direction dir)3248{3249struct crypto_aead *aead = crypto_aead_reqtfm(req);3250struct crypto_tfm *tfm = crypto_aead_tfm(aead);3251struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3252struct aead_request *subreq = aead_request_ctx(req);32533254aead_request_set_tfm(subreq, ctx->fback);3255aead_request_set_callback(subreq, req->base.flags, req->base.complete,3256req->base.data);3257aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,3258req->iv);3259aead_request_set_ad(subreq, req->assoclen);32603261return (dir == SAFEXCEL_ENCRYPT) ?3262crypto_aead_encrypt(subreq) :3263crypto_aead_decrypt(subreq);3264}32653266static int safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request *req)3267{3268struct safexcel_cipher_req *creq = aead_request_ctx(req);32693270/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */3271if (req->cryptlen & (SM4_BLOCK_SIZE - 1))3272return -EINVAL;3273else if (req->cryptlen || req->assoclen) /* If input length > 0 only */3274return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);32753276/* HW cannot do full (AAD+payload) zero length, use fallback */3277return safexcel_aead_fallback_crypt(req, SAFEXCEL_ENCRYPT);3278}32793280static int safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request *req)3281{3282struct safexcel_cipher_req *creq = aead_request_ctx(req);3283struct crypto_aead *tfm = crypto_aead_reqtfm(req);32843285/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */3286if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1))3287return -EINVAL;3288else if (req->cryptlen > crypto_aead_authsize(tfm) || req->assoclen)3289/* If input length > 0 only */3290return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);32913292/* HW cannot do full (AAD+payload) zero length, use fallback */3293return safexcel_aead_fallback_crypt(req, SAFEXCEL_DECRYPT);3294}32953296static int safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm *tfm)3297{3298struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);32993300safexcel_aead_fallback_cra_init(tfm);3301ctx->alg = SAFEXCEL_SM4;3302ctx->blocksz = SM4_BLOCK_SIZE;3303ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3;3304ctx->state_sz = SM3_DIGEST_SIZE;3305return 0;3306}33073308struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4 = {3309.type = SAFEXCEL_ALG_TYPE_AEAD,3310.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3,3311.alg.aead = {3312.setkey = safexcel_aead_fallback_setkey,3313.setauthsize = safexcel_aead_fallback_setauthsize,3314.encrypt = safexcel_aead_sm4cbc_sm3_encrypt,3315.decrypt = safexcel_aead_sm4cbc_sm3_decrypt,3316.ivsize = SM4_BLOCK_SIZE,3317.maxauthsize = SM3_DIGEST_SIZE,3318.base = {3319.cra_name = "authenc(hmac(sm3),cbc(sm4))",3320.cra_driver_name = "safexcel-authenc-hmac-sm3-cbc-sm4",3321.cra_priority = SAFEXCEL_CRA_PRIORITY,3322.cra_flags = CRYPTO_ALG_ASYNC |3323CRYPTO_ALG_ALLOCATES_MEMORY |3324CRYPTO_ALG_KERN_DRIVER_ONLY |3325CRYPTO_ALG_NEED_FALLBACK,3326.cra_blocksize = SM4_BLOCK_SIZE,3327.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3328.cra_alignmask = 0,3329.cra_init = safexcel_aead_sm4cbc_sm3_cra_init,3330.cra_exit = safexcel_aead_fallback_cra_exit,3331.cra_module = THIS_MODULE,3332},3333},3334};33353336static int safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm *tfm)3337{3338struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);33393340safexcel_aead_sm4cbc_sha1_cra_init(tfm);3341ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;3342return 0;3343}33443345struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4 = {3346.type = SAFEXCEL_ALG_TYPE_AEAD,3347.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1,3348.alg.aead = {3349.setkey = safexcel_aead_setkey,3350.encrypt = safexcel_aead_encrypt,3351.decrypt = safexcel_aead_decrypt,3352.ivsize = CTR_RFC3686_IV_SIZE,3353.maxauthsize = SHA1_DIGEST_SIZE,3354.base = {3355.cra_name = "authenc(hmac(sha1),rfc3686(ctr(sm4)))",3356.cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-sm4",3357.cra_priority = SAFEXCEL_CRA_PRIORITY,3358.cra_flags = CRYPTO_ALG_ASYNC |3359CRYPTO_ALG_ALLOCATES_MEMORY |3360CRYPTO_ALG_KERN_DRIVER_ONLY,3361.cra_blocksize = 1,3362.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3363.cra_alignmask = 0,3364.cra_init = safexcel_aead_sm4ctr_sha1_cra_init,3365.cra_exit = safexcel_aead_cra_exit,3366.cra_module = THIS_MODULE,3367},3368},3369};33703371static int safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm *tfm)3372{3373struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);33743375safexcel_aead_sm4cbc_sm3_cra_init(tfm);3376ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;3377return 0;3378}33793380struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4 = {3381.type = SAFEXCEL_ALG_TYPE_AEAD,3382.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3,3383.alg.aead = {3384.setkey = safexcel_aead_setkey,3385.encrypt = safexcel_aead_encrypt,3386.decrypt = safexcel_aead_decrypt,3387.ivsize = CTR_RFC3686_IV_SIZE,3388.maxauthsize = SM3_DIGEST_SIZE,3389.base = {3390.cra_name = "authenc(hmac(sm3),rfc3686(ctr(sm4)))",3391.cra_driver_name = "safexcel-authenc-hmac-sm3-ctr-sm4",3392.cra_priority = SAFEXCEL_CRA_PRIORITY,3393.cra_flags = CRYPTO_ALG_ASYNC |3394CRYPTO_ALG_ALLOCATES_MEMORY |3395CRYPTO_ALG_KERN_DRIVER_ONLY,3396.cra_blocksize = 1,3397.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3398.cra_alignmask = 0,3399.cra_init = safexcel_aead_sm4ctr_sm3_cra_init,3400.cra_exit = safexcel_aead_cra_exit,3401.cra_module = THIS_MODULE,3402},3403},3404};34053406static int safexcel_rfc4106_gcm_setkey(struct crypto_aead *ctfm, const u8 *key,3407unsigned int len)3408{3409struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);3410struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);34113412/* last 4 bytes of key are the nonce! */3413ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);34143415len -= CTR_RFC3686_NONCE_SIZE;3416return safexcel_aead_gcm_setkey(ctfm, key, len);3417}34183419static int safexcel_rfc4106_gcm_setauthsize(struct crypto_aead *tfm,3420unsigned int authsize)3421{3422return crypto_rfc4106_check_authsize(authsize);3423}34243425static int safexcel_rfc4106_encrypt(struct aead_request *req)3426{3427return crypto_ipsec_check_assoclen(req->assoclen) ?:3428safexcel_aead_encrypt(req);3429}34303431static int safexcel_rfc4106_decrypt(struct aead_request *req)3432{3433return crypto_ipsec_check_assoclen(req->assoclen) ?:3434safexcel_aead_decrypt(req);3435}34363437static int safexcel_rfc4106_gcm_cra_init(struct crypto_tfm *tfm)3438{3439struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3440int ret;34413442ret = safexcel_aead_gcm_cra_init(tfm);3443ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP;3444ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;3445return ret;3446}34473448struct safexcel_alg_template safexcel_alg_rfc4106_gcm = {3449.type = SAFEXCEL_ALG_TYPE_AEAD,3450.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,3451.alg.aead = {3452.setkey = safexcel_rfc4106_gcm_setkey,3453.setauthsize = safexcel_rfc4106_gcm_setauthsize,3454.encrypt = safexcel_rfc4106_encrypt,3455.decrypt = safexcel_rfc4106_decrypt,3456.ivsize = GCM_RFC4106_IV_SIZE,3457.maxauthsize = GHASH_DIGEST_SIZE,3458.base = {3459.cra_name = "rfc4106(gcm(aes))",3460.cra_driver_name = "safexcel-rfc4106-gcm-aes",3461.cra_priority = SAFEXCEL_CRA_PRIORITY,3462.cra_flags = CRYPTO_ALG_ASYNC |3463CRYPTO_ALG_ALLOCATES_MEMORY |3464CRYPTO_ALG_KERN_DRIVER_ONLY,3465.cra_blocksize = 1,3466.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3467.cra_alignmask = 0,3468.cra_init = safexcel_rfc4106_gcm_cra_init,3469.cra_exit = safexcel_aead_gcm_cra_exit,3470},3471},3472};34733474static int safexcel_rfc4543_gcm_setauthsize(struct crypto_aead *tfm,3475unsigned int authsize)3476{3477if (authsize != GHASH_DIGEST_SIZE)3478return -EINVAL;34793480return 0;3481}34823483static int safexcel_rfc4543_gcm_cra_init(struct crypto_tfm *tfm)3484{3485struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3486int ret;34873488ret = safexcel_aead_gcm_cra_init(tfm);3489ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP_GMAC;3490return ret;3491}34923493struct safexcel_alg_template safexcel_alg_rfc4543_gcm = {3494.type = SAFEXCEL_ALG_TYPE_AEAD,3495.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,3496.alg.aead = {3497.setkey = safexcel_rfc4106_gcm_setkey,3498.setauthsize = safexcel_rfc4543_gcm_setauthsize,3499.encrypt = safexcel_rfc4106_encrypt,3500.decrypt = safexcel_rfc4106_decrypt,3501.ivsize = GCM_RFC4543_IV_SIZE,3502.maxauthsize = GHASH_DIGEST_SIZE,3503.base = {3504.cra_name = "rfc4543(gcm(aes))",3505.cra_driver_name = "safexcel-rfc4543-gcm-aes",3506.cra_priority = SAFEXCEL_CRA_PRIORITY,3507.cra_flags = CRYPTO_ALG_ASYNC |3508CRYPTO_ALG_ALLOCATES_MEMORY |3509CRYPTO_ALG_KERN_DRIVER_ONLY,3510.cra_blocksize = 1,3511.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3512.cra_alignmask = 0,3513.cra_init = safexcel_rfc4543_gcm_cra_init,3514.cra_exit = safexcel_aead_gcm_cra_exit,3515},3516},3517};35183519static int safexcel_rfc4309_ccm_setkey(struct crypto_aead *ctfm, const u8 *key,3520unsigned int len)3521{3522struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);3523struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);35243525/* First byte of the nonce = L = always 3 for RFC4309 (4 byte ctr) */3526*(u8 *)&ctx->nonce = EIP197_AEAD_IPSEC_COUNTER_SIZE - 1;3527/* last 3 bytes of key are the nonce! */3528memcpy((u8 *)&ctx->nonce + 1, key + len -3529EIP197_AEAD_IPSEC_CCM_NONCE_SIZE,3530EIP197_AEAD_IPSEC_CCM_NONCE_SIZE);35313532len -= EIP197_AEAD_IPSEC_CCM_NONCE_SIZE;3533return safexcel_aead_ccm_setkey(ctfm, key, len);3534}35353536static int safexcel_rfc4309_ccm_setauthsize(struct crypto_aead *tfm,3537unsigned int authsize)3538{3539/* Borrowed from crypto/ccm.c */3540switch (authsize) {3541case 8:3542case 12:3543case 16:3544break;3545default:3546return -EINVAL;3547}35483549return 0;3550}35513552static int safexcel_rfc4309_ccm_encrypt(struct aead_request *req)3553{3554struct safexcel_cipher_req *creq = aead_request_ctx(req);35553556/* Borrowed from crypto/ccm.c */3557if (req->assoclen != 16 && req->assoclen != 20)3558return -EINVAL;35593560return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);3561}35623563static int safexcel_rfc4309_ccm_decrypt(struct aead_request *req)3564{3565struct safexcel_cipher_req *creq = aead_request_ctx(req);35663567/* Borrowed from crypto/ccm.c */3568if (req->assoclen != 16 && req->assoclen != 20)3569return -EINVAL;35703571return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);3572}35733574static int safexcel_rfc4309_ccm_cra_init(struct crypto_tfm *tfm)3575{3576struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);3577int ret;35783579ret = safexcel_aead_ccm_cra_init(tfm);3580ctx->aead = EIP197_AEAD_TYPE_IPSEC_ESP;3581ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;3582return ret;3583}35843585struct safexcel_alg_template safexcel_alg_rfc4309_ccm = {3586.type = SAFEXCEL_ALG_TYPE_AEAD,3587.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL,3588.alg.aead = {3589.setkey = safexcel_rfc4309_ccm_setkey,3590.setauthsize = safexcel_rfc4309_ccm_setauthsize,3591.encrypt = safexcel_rfc4309_ccm_encrypt,3592.decrypt = safexcel_rfc4309_ccm_decrypt,3593.ivsize = EIP197_AEAD_IPSEC_IV_SIZE,3594.maxauthsize = AES_BLOCK_SIZE,3595.base = {3596.cra_name = "rfc4309(ccm(aes))",3597.cra_driver_name = "safexcel-rfc4309-ccm-aes",3598.cra_priority = SAFEXCEL_CRA_PRIORITY,3599.cra_flags = CRYPTO_ALG_ASYNC |3600CRYPTO_ALG_ALLOCATES_MEMORY |3601CRYPTO_ALG_KERN_DRIVER_ONLY,3602.cra_blocksize = 1,3603.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),3604.cra_alignmask = 0,3605.cra_init = safexcel_rfc4309_ccm_cra_init,3606.cra_exit = safexcel_aead_cra_exit,3607.cra_module = THIS_MODULE,3608},3609},3610};361136123613