162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 2015-2016 Freescale Semiconductor Inc. 462306a36Sopenharmony_ci * Copyright 2017-2019 NXP 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include "compat.h" 862306a36Sopenharmony_ci#include "regs.h" 962306a36Sopenharmony_ci#include "caamalg_qi2.h" 1062306a36Sopenharmony_ci#include "dpseci_cmd.h" 1162306a36Sopenharmony_ci#include "desc_constr.h" 1262306a36Sopenharmony_ci#include "error.h" 1362306a36Sopenharmony_ci#include "sg_sw_sec4.h" 1462306a36Sopenharmony_ci#include "sg_sw_qm2.h" 1562306a36Sopenharmony_ci#include "key_gen.h" 1662306a36Sopenharmony_ci#include "caamalg_desc.h" 1762306a36Sopenharmony_ci#include "caamhash_desc.h" 1862306a36Sopenharmony_ci#include "dpseci-debugfs.h" 1962306a36Sopenharmony_ci#include <linux/dma-mapping.h> 2062306a36Sopenharmony_ci#include <linux/fsl/mc.h> 2162306a36Sopenharmony_ci#include <linux/kernel.h> 2262306a36Sopenharmony_ci#include <soc/fsl/dpaa2-io.h> 2362306a36Sopenharmony_ci#include <soc/fsl/dpaa2-fd.h> 2462306a36Sopenharmony_ci#include <crypto/xts.h> 2562306a36Sopenharmony_ci#include <asm/unaligned.h> 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#define CAAM_CRA_PRIORITY 2000 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* max key is sum of AES_MAX_KEY_SIZE, max split key size */ 3062306a36Sopenharmony_ci#define CAAM_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE + \ 3162306a36Sopenharmony_ci SHA512_DIGEST_SIZE * 2) 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* 3462306a36Sopenharmony_ci * This is a cache of buffers, from which the users of CAAM QI driver 3562306a36Sopenharmony_ci * can allocate short buffers. It's speedier than doing kmalloc on the hotpath. 3662306a36Sopenharmony_ci * NOTE: A more elegant solution would be to have some headroom in the frames 3762306a36Sopenharmony_ci * being processed. This can be added by the dpaa2-eth driver. This would 3862306a36Sopenharmony_ci * pose a problem for userspace application processing which cannot 3962306a36Sopenharmony_ci * know of this limitation. So for now, this will work. 4062306a36Sopenharmony_ci * NOTE: The memcache is SMP-safe. No need to handle spinlocks in-here 4162306a36Sopenharmony_ci */ 4262306a36Sopenharmony_cistatic struct kmem_cache *qi_cache; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_cistruct caam_alg_entry { 4562306a36Sopenharmony_ci struct device *dev; 4662306a36Sopenharmony_ci int class1_alg_type; 4762306a36Sopenharmony_ci int class2_alg_type; 4862306a36Sopenharmony_ci bool rfc3686; 4962306a36Sopenharmony_ci bool geniv; 5062306a36Sopenharmony_ci bool nodkp; 5162306a36Sopenharmony_ci}; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_cistruct caam_aead_alg { 5462306a36Sopenharmony_ci struct aead_alg aead; 5562306a36Sopenharmony_ci struct caam_alg_entry caam; 5662306a36Sopenharmony_ci bool registered; 5762306a36Sopenharmony_ci}; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistruct caam_skcipher_alg { 6062306a36Sopenharmony_ci struct skcipher_alg skcipher; 6162306a36Sopenharmony_ci struct caam_alg_entry caam; 6262306a36Sopenharmony_ci bool registered; 6362306a36Sopenharmony_ci}; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci/** 6662306a36Sopenharmony_ci * struct caam_ctx - per-session context 6762306a36Sopenharmony_ci * @flc: Flow Contexts array 6862306a36Sopenharmony_ci * @key: [authentication key], encryption key 6962306a36Sopenharmony_ci * @flc_dma: I/O virtual addresses of the Flow Contexts 7062306a36Sopenharmony_ci * @key_dma: I/O virtual address of the key 7162306a36Sopenharmony_ci * @dir: DMA direction for mapping key and Flow Contexts 7262306a36Sopenharmony_ci * @dev: dpseci device 7362306a36Sopenharmony_ci * @adata: authentication algorithm details 7462306a36Sopenharmony_ci * @cdata: encryption algorithm details 7562306a36Sopenharmony_ci * @authsize: authentication tag (a.k.a. ICV / MAC) size 7662306a36Sopenharmony_ci * @xts_key_fallback: true if fallback tfm needs to be used due 7762306a36Sopenharmony_ci * to unsupported xts key lengths 7862306a36Sopenharmony_ci * @fallback: xts fallback tfm 7962306a36Sopenharmony_ci */ 8062306a36Sopenharmony_cistruct caam_ctx { 8162306a36Sopenharmony_ci struct caam_flc flc[NUM_OP]; 8262306a36Sopenharmony_ci u8 key[CAAM_MAX_KEY_SIZE]; 8362306a36Sopenharmony_ci dma_addr_t flc_dma[NUM_OP]; 8462306a36Sopenharmony_ci dma_addr_t key_dma; 8562306a36Sopenharmony_ci enum dma_data_direction dir; 8662306a36Sopenharmony_ci struct device *dev; 8762306a36Sopenharmony_ci struct alginfo adata; 8862306a36Sopenharmony_ci struct alginfo cdata; 8962306a36Sopenharmony_ci unsigned int authsize; 9062306a36Sopenharmony_ci bool xts_key_fallback; 9162306a36Sopenharmony_ci struct crypto_skcipher *fallback; 9262306a36Sopenharmony_ci}; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistatic void *dpaa2_caam_iova_to_virt(struct dpaa2_caam_priv *priv, 9562306a36Sopenharmony_ci dma_addr_t iova_addr) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci phys_addr_t phys_addr; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci phys_addr = priv->domain ? iommu_iova_to_phys(priv->domain, iova_addr) : 10062306a36Sopenharmony_ci iova_addr; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci return phys_to_virt(phys_addr); 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/* 10662306a36Sopenharmony_ci * qi_cache_zalloc - Allocate buffers from CAAM-QI cache 10762306a36Sopenharmony_ci * 10862306a36Sopenharmony_ci * Allocate data on the hotpath. Instead of using kzalloc, one can use the 10962306a36Sopenharmony_ci * services of the CAAM QI memory cache (backed by kmem_cache). The buffers 11062306a36Sopenharmony_ci * will have a size of CAAM_QI_MEMCACHE_SIZE, which should be sufficient for 11162306a36Sopenharmony_ci * hosting 16 SG entries. 11262306a36Sopenharmony_ci * 11362306a36Sopenharmony_ci * @flags - flags that would be used for the equivalent kmalloc(..) call 11462306a36Sopenharmony_ci * 11562306a36Sopenharmony_ci * Returns a pointer to a retrieved buffer on success or NULL on failure. 11662306a36Sopenharmony_ci */ 11762306a36Sopenharmony_cistatic inline void *qi_cache_zalloc(gfp_t flags) 11862306a36Sopenharmony_ci{ 11962306a36Sopenharmony_ci return kmem_cache_zalloc(qi_cache, flags); 12062306a36Sopenharmony_ci} 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci/* 12362306a36Sopenharmony_ci * qi_cache_free - Frees buffers allocated from CAAM-QI cache 12462306a36Sopenharmony_ci * 12562306a36Sopenharmony_ci * @obj - buffer previously allocated by qi_cache_zalloc 12662306a36Sopenharmony_ci * 12762306a36Sopenharmony_ci * No checking is being done, the call is a passthrough call to 12862306a36Sopenharmony_ci * kmem_cache_free(...) 12962306a36Sopenharmony_ci */ 13062306a36Sopenharmony_cistatic inline void qi_cache_free(void *obj) 13162306a36Sopenharmony_ci{ 13262306a36Sopenharmony_ci kmem_cache_free(qi_cache, obj); 13362306a36Sopenharmony_ci} 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_cistatic struct caam_request *to_caam_req(struct crypto_async_request *areq) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci switch (crypto_tfm_alg_type(areq->tfm)) { 13862306a36Sopenharmony_ci case CRYPTO_ALG_TYPE_SKCIPHER: 13962306a36Sopenharmony_ci return skcipher_request_ctx_dma(skcipher_request_cast(areq)); 14062306a36Sopenharmony_ci case CRYPTO_ALG_TYPE_AEAD: 14162306a36Sopenharmony_ci return aead_request_ctx_dma( 14262306a36Sopenharmony_ci container_of(areq, struct aead_request, base)); 14362306a36Sopenharmony_ci case CRYPTO_ALG_TYPE_AHASH: 14462306a36Sopenharmony_ci return ahash_request_ctx_dma(ahash_request_cast(areq)); 14562306a36Sopenharmony_ci default: 14662306a36Sopenharmony_ci return ERR_PTR(-EINVAL); 14762306a36Sopenharmony_ci } 14862306a36Sopenharmony_ci} 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_cistatic void caam_unmap(struct device *dev, struct scatterlist *src, 15162306a36Sopenharmony_ci struct scatterlist *dst, int src_nents, 15262306a36Sopenharmony_ci int dst_nents, dma_addr_t iv_dma, int ivsize, 15362306a36Sopenharmony_ci enum dma_data_direction iv_dir, dma_addr_t qm_sg_dma, 15462306a36Sopenharmony_ci int qm_sg_bytes) 15562306a36Sopenharmony_ci{ 15662306a36Sopenharmony_ci if (dst != src) { 15762306a36Sopenharmony_ci if (src_nents) 15862306a36Sopenharmony_ci dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE); 15962306a36Sopenharmony_ci if (dst_nents) 16062306a36Sopenharmony_ci dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE); 16162306a36Sopenharmony_ci } else { 16262306a36Sopenharmony_ci dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL); 16362306a36Sopenharmony_ci } 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci if (iv_dma) 16662306a36Sopenharmony_ci dma_unmap_single(dev, iv_dma, ivsize, iv_dir); 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci if (qm_sg_bytes) 16962306a36Sopenharmony_ci dma_unmap_single(dev, qm_sg_dma, qm_sg_bytes, DMA_TO_DEVICE); 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cistatic int aead_set_sh_desc(struct crypto_aead *aead) 17362306a36Sopenharmony_ci{ 17462306a36Sopenharmony_ci struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead), 17562306a36Sopenharmony_ci typeof(*alg), aead); 17662306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 17762306a36Sopenharmony_ci unsigned int ivsize = crypto_aead_ivsize(aead); 17862306a36Sopenharmony_ci struct device *dev = ctx->dev; 17962306a36Sopenharmony_ci struct dpaa2_caam_priv *priv = dev_get_drvdata(dev); 18062306a36Sopenharmony_ci struct caam_flc *flc; 18162306a36Sopenharmony_ci u32 *desc; 18262306a36Sopenharmony_ci u32 ctx1_iv_off = 0; 18362306a36Sopenharmony_ci u32 *nonce = NULL; 18462306a36Sopenharmony_ci unsigned int data_len[2]; 18562306a36Sopenharmony_ci u32 inl_mask; 18662306a36Sopenharmony_ci const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) == 18762306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128); 18862306a36Sopenharmony_ci const bool is_rfc3686 = alg->caam.rfc3686; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci if (!ctx->cdata.keylen || !ctx->authsize) 19162306a36Sopenharmony_ci return 0; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci /* 19462306a36Sopenharmony_ci * AES-CTR needs to load IV in CONTEXT1 reg 19562306a36Sopenharmony_ci * at an offset of 128bits (16bytes) 19662306a36Sopenharmony_ci * CONTEXT1[255:128] = IV 19762306a36Sopenharmony_ci */ 19862306a36Sopenharmony_ci if (ctr_mode) 19962306a36Sopenharmony_ci ctx1_iv_off = 16; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci /* 20262306a36Sopenharmony_ci * RFC3686 specific: 20362306a36Sopenharmony_ci * CONTEXT1[255:128] = {NONCE, IV, COUNTER} 20462306a36Sopenharmony_ci */ 20562306a36Sopenharmony_ci if (is_rfc3686) { 20662306a36Sopenharmony_ci ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE; 20762306a36Sopenharmony_ci nonce = (u32 *)((void *)ctx->key + ctx->adata.keylen_pad + 20862306a36Sopenharmony_ci ctx->cdata.keylen - CTR_RFC3686_NONCE_SIZE); 20962306a36Sopenharmony_ci } 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci /* 21262306a36Sopenharmony_ci * In case |user key| > |derived key|, using DKP<imm,imm> would result 21362306a36Sopenharmony_ci * in invalid opcodes (last bytes of user key) in the resulting 21462306a36Sopenharmony_ci * descriptor. Use DKP<ptr,imm> instead => both virtual and dma key 21562306a36Sopenharmony_ci * addresses are needed. 21662306a36Sopenharmony_ci */ 21762306a36Sopenharmony_ci ctx->adata.key_virt = ctx->key; 21862306a36Sopenharmony_ci ctx->adata.key_dma = ctx->key_dma; 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad; 22162306a36Sopenharmony_ci ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci data_len[0] = ctx->adata.keylen_pad; 22462306a36Sopenharmony_ci data_len[1] = ctx->cdata.keylen; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci /* aead_encrypt shared descriptor */ 22762306a36Sopenharmony_ci if (desc_inline_query((alg->caam.geniv ? DESC_QI_AEAD_GIVENC_LEN : 22862306a36Sopenharmony_ci DESC_QI_AEAD_ENC_LEN) + 22962306a36Sopenharmony_ci (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0), 23062306a36Sopenharmony_ci DESC_JOB_IO_LEN, data_len, &inl_mask, 23162306a36Sopenharmony_ci ARRAY_SIZE(data_len)) < 0) 23262306a36Sopenharmony_ci return -EINVAL; 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci ctx->adata.key_inline = !!(inl_mask & 1); 23562306a36Sopenharmony_ci ctx->cdata.key_inline = !!(inl_mask & 2); 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci flc = &ctx->flc[ENCRYPT]; 23862306a36Sopenharmony_ci desc = flc->sh_desc; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci if (alg->caam.geniv) 24162306a36Sopenharmony_ci cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, 24262306a36Sopenharmony_ci ivsize, ctx->authsize, is_rfc3686, 24362306a36Sopenharmony_ci nonce, ctx1_iv_off, true, 24462306a36Sopenharmony_ci priv->sec_attr.era); 24562306a36Sopenharmony_ci else 24662306a36Sopenharmony_ci cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, 24762306a36Sopenharmony_ci ivsize, ctx->authsize, is_rfc3686, nonce, 24862306a36Sopenharmony_ci ctx1_iv_off, true, priv->sec_attr.era); 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 25162306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT], 25262306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 25362306a36Sopenharmony_ci ctx->dir); 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci /* aead_decrypt shared descriptor */ 25662306a36Sopenharmony_ci if (desc_inline_query(DESC_QI_AEAD_DEC_LEN + 25762306a36Sopenharmony_ci (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0), 25862306a36Sopenharmony_ci DESC_JOB_IO_LEN, data_len, &inl_mask, 25962306a36Sopenharmony_ci ARRAY_SIZE(data_len)) < 0) 26062306a36Sopenharmony_ci return -EINVAL; 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci ctx->adata.key_inline = !!(inl_mask & 1); 26362306a36Sopenharmony_ci ctx->cdata.key_inline = !!(inl_mask & 2); 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci flc = &ctx->flc[DECRYPT]; 26662306a36Sopenharmony_ci desc = flc->sh_desc; 26762306a36Sopenharmony_ci cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, 26862306a36Sopenharmony_ci ivsize, ctx->authsize, alg->caam.geniv, 26962306a36Sopenharmony_ci is_rfc3686, nonce, ctx1_iv_off, true, 27062306a36Sopenharmony_ci priv->sec_attr.era); 27162306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 27262306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT], 27362306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 27462306a36Sopenharmony_ci ctx->dir); 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci return 0; 27762306a36Sopenharmony_ci} 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_cistatic int aead_setauthsize(struct crypto_aead *authenc, unsigned int authsize) 28062306a36Sopenharmony_ci{ 28162306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(authenc); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci ctx->authsize = authsize; 28462306a36Sopenharmony_ci aead_set_sh_desc(authenc); 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci return 0; 28762306a36Sopenharmony_ci} 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_cistatic int aead_setkey(struct crypto_aead *aead, const u8 *key, 29062306a36Sopenharmony_ci unsigned int keylen) 29162306a36Sopenharmony_ci{ 29262306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 29362306a36Sopenharmony_ci struct device *dev = ctx->dev; 29462306a36Sopenharmony_ci struct crypto_authenc_keys keys; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci if (crypto_authenc_extractkeys(&keys, key, keylen) != 0) 29762306a36Sopenharmony_ci goto badkey; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci dev_dbg(dev, "keylen %d enckeylen %d authkeylen %d\n", 30062306a36Sopenharmony_ci keys.authkeylen + keys.enckeylen, keys.enckeylen, 30162306a36Sopenharmony_ci keys.authkeylen); 30262306a36Sopenharmony_ci print_hex_dump_debug("key in @" __stringify(__LINE__)": ", 30362306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci ctx->adata.keylen = keys.authkeylen; 30662306a36Sopenharmony_ci ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype & 30762306a36Sopenharmony_ci OP_ALG_ALGSEL_MASK); 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE) 31062306a36Sopenharmony_ci goto badkey; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci memcpy(ctx->key, keys.authkey, keys.authkeylen); 31362306a36Sopenharmony_ci memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen); 31462306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->key_dma, ctx->adata.keylen_pad + 31562306a36Sopenharmony_ci keys.enckeylen, ctx->dir); 31662306a36Sopenharmony_ci print_hex_dump_debug("ctx.key@" __stringify(__LINE__)": ", 31762306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, ctx->key, 31862306a36Sopenharmony_ci ctx->adata.keylen_pad + keys.enckeylen, 1); 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci ctx->cdata.keylen = keys.enckeylen; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci memzero_explicit(&keys, sizeof(keys)); 32362306a36Sopenharmony_ci return aead_set_sh_desc(aead); 32462306a36Sopenharmony_cibadkey: 32562306a36Sopenharmony_ci memzero_explicit(&keys, sizeof(keys)); 32662306a36Sopenharmony_ci return -EINVAL; 32762306a36Sopenharmony_ci} 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_cistatic int des3_aead_setkey(struct crypto_aead *aead, const u8 *key, 33062306a36Sopenharmony_ci unsigned int keylen) 33162306a36Sopenharmony_ci{ 33262306a36Sopenharmony_ci struct crypto_authenc_keys keys; 33362306a36Sopenharmony_ci int err; 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci err = crypto_authenc_extractkeys(&keys, key, keylen); 33662306a36Sopenharmony_ci if (unlikely(err)) 33762306a36Sopenharmony_ci goto out; 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci err = -EINVAL; 34062306a36Sopenharmony_ci if (keys.enckeylen != DES3_EDE_KEY_SIZE) 34162306a36Sopenharmony_ci goto out; 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci err = crypto_des3_ede_verify_key(crypto_aead_tfm(aead), keys.enckey) ?: 34462306a36Sopenharmony_ci aead_setkey(aead, key, keylen); 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ciout: 34762306a36Sopenharmony_ci memzero_explicit(&keys, sizeof(keys)); 34862306a36Sopenharmony_ci return err; 34962306a36Sopenharmony_ci} 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_cistatic struct aead_edesc *aead_edesc_alloc(struct aead_request *req, 35262306a36Sopenharmony_ci bool encrypt) 35362306a36Sopenharmony_ci{ 35462306a36Sopenharmony_ci struct crypto_aead *aead = crypto_aead_reqtfm(req); 35562306a36Sopenharmony_ci struct caam_request *req_ctx = aead_request_ctx_dma(req); 35662306a36Sopenharmony_ci struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; 35762306a36Sopenharmony_ci struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; 35862306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 35962306a36Sopenharmony_ci struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead), 36062306a36Sopenharmony_ci typeof(*alg), aead); 36162306a36Sopenharmony_ci struct device *dev = ctx->dev; 36262306a36Sopenharmony_ci gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 36362306a36Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 36462306a36Sopenharmony_ci int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0; 36562306a36Sopenharmony_ci int src_len, dst_len = 0; 36662306a36Sopenharmony_ci struct aead_edesc *edesc; 36762306a36Sopenharmony_ci dma_addr_t qm_sg_dma, iv_dma = 0; 36862306a36Sopenharmony_ci int ivsize = 0; 36962306a36Sopenharmony_ci unsigned int authsize = ctx->authsize; 37062306a36Sopenharmony_ci int qm_sg_index = 0, qm_sg_nents = 0, qm_sg_bytes; 37162306a36Sopenharmony_ci int in_len, out_len; 37262306a36Sopenharmony_ci struct dpaa2_sg_entry *sg_table; 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci /* allocate space for base edesc, link tables and IV */ 37562306a36Sopenharmony_ci edesc = qi_cache_zalloc(flags); 37662306a36Sopenharmony_ci if (unlikely(!edesc)) { 37762306a36Sopenharmony_ci dev_err(dev, "could not allocate extended descriptor\n"); 37862306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 37962306a36Sopenharmony_ci } 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci if (unlikely(req->dst != req->src)) { 38262306a36Sopenharmony_ci src_len = req->assoclen + req->cryptlen; 38362306a36Sopenharmony_ci dst_len = src_len + (encrypt ? authsize : (-authsize)); 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci src_nents = sg_nents_for_len(req->src, src_len); 38662306a36Sopenharmony_ci if (unlikely(src_nents < 0)) { 38762306a36Sopenharmony_ci dev_err(dev, "Insufficient bytes (%d) in src S/G\n", 38862306a36Sopenharmony_ci src_len); 38962306a36Sopenharmony_ci qi_cache_free(edesc); 39062306a36Sopenharmony_ci return ERR_PTR(src_nents); 39162306a36Sopenharmony_ci } 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci dst_nents = sg_nents_for_len(req->dst, dst_len); 39462306a36Sopenharmony_ci if (unlikely(dst_nents < 0)) { 39562306a36Sopenharmony_ci dev_err(dev, "Insufficient bytes (%d) in dst S/G\n", 39662306a36Sopenharmony_ci dst_len); 39762306a36Sopenharmony_ci qi_cache_free(edesc); 39862306a36Sopenharmony_ci return ERR_PTR(dst_nents); 39962306a36Sopenharmony_ci } 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci if (src_nents) { 40262306a36Sopenharmony_ci mapped_src_nents = dma_map_sg(dev, req->src, src_nents, 40362306a36Sopenharmony_ci DMA_TO_DEVICE); 40462306a36Sopenharmony_ci if (unlikely(!mapped_src_nents)) { 40562306a36Sopenharmony_ci dev_err(dev, "unable to map source\n"); 40662306a36Sopenharmony_ci qi_cache_free(edesc); 40762306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 40862306a36Sopenharmony_ci } 40962306a36Sopenharmony_ci } else { 41062306a36Sopenharmony_ci mapped_src_nents = 0; 41162306a36Sopenharmony_ci } 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci if (dst_nents) { 41462306a36Sopenharmony_ci mapped_dst_nents = dma_map_sg(dev, req->dst, dst_nents, 41562306a36Sopenharmony_ci DMA_FROM_DEVICE); 41662306a36Sopenharmony_ci if (unlikely(!mapped_dst_nents)) { 41762306a36Sopenharmony_ci dev_err(dev, "unable to map destination\n"); 41862306a36Sopenharmony_ci dma_unmap_sg(dev, req->src, src_nents, 41962306a36Sopenharmony_ci DMA_TO_DEVICE); 42062306a36Sopenharmony_ci qi_cache_free(edesc); 42162306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 42262306a36Sopenharmony_ci } 42362306a36Sopenharmony_ci } else { 42462306a36Sopenharmony_ci mapped_dst_nents = 0; 42562306a36Sopenharmony_ci } 42662306a36Sopenharmony_ci } else { 42762306a36Sopenharmony_ci src_len = req->assoclen + req->cryptlen + 42862306a36Sopenharmony_ci (encrypt ? authsize : 0); 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci src_nents = sg_nents_for_len(req->src, src_len); 43162306a36Sopenharmony_ci if (unlikely(src_nents < 0)) { 43262306a36Sopenharmony_ci dev_err(dev, "Insufficient bytes (%d) in src S/G\n", 43362306a36Sopenharmony_ci src_len); 43462306a36Sopenharmony_ci qi_cache_free(edesc); 43562306a36Sopenharmony_ci return ERR_PTR(src_nents); 43662306a36Sopenharmony_ci } 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci mapped_src_nents = dma_map_sg(dev, req->src, src_nents, 43962306a36Sopenharmony_ci DMA_BIDIRECTIONAL); 44062306a36Sopenharmony_ci if (unlikely(!mapped_src_nents)) { 44162306a36Sopenharmony_ci dev_err(dev, "unable to map source\n"); 44262306a36Sopenharmony_ci qi_cache_free(edesc); 44362306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 44462306a36Sopenharmony_ci } 44562306a36Sopenharmony_ci } 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci if ((alg->caam.rfc3686 && encrypt) || !alg->caam.geniv) 44862306a36Sopenharmony_ci ivsize = crypto_aead_ivsize(aead); 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci /* 45162306a36Sopenharmony_ci * Create S/G table: req->assoclen, [IV,] req->src [, req->dst]. 45262306a36Sopenharmony_ci * Input is not contiguous. 45362306a36Sopenharmony_ci * HW reads 4 S/G entries at a time; make sure the reads don't go beyond 45462306a36Sopenharmony_ci * the end of the table by allocating more S/G entries. Logic: 45562306a36Sopenharmony_ci * if (src != dst && output S/G) 45662306a36Sopenharmony_ci * pad output S/G, if needed 45762306a36Sopenharmony_ci * else if (src == dst && S/G) 45862306a36Sopenharmony_ci * overlapping S/Gs; pad one of them 45962306a36Sopenharmony_ci * else if (input S/G) ... 46062306a36Sopenharmony_ci * pad input S/G, if needed 46162306a36Sopenharmony_ci */ 46262306a36Sopenharmony_ci qm_sg_nents = 1 + !!ivsize + mapped_src_nents; 46362306a36Sopenharmony_ci if (mapped_dst_nents > 1) 46462306a36Sopenharmony_ci qm_sg_nents += pad_sg_nents(mapped_dst_nents); 46562306a36Sopenharmony_ci else if ((req->src == req->dst) && (mapped_src_nents > 1)) 46662306a36Sopenharmony_ci qm_sg_nents = max(pad_sg_nents(qm_sg_nents), 46762306a36Sopenharmony_ci 1 + !!ivsize + 46862306a36Sopenharmony_ci pad_sg_nents(mapped_src_nents)); 46962306a36Sopenharmony_ci else 47062306a36Sopenharmony_ci qm_sg_nents = pad_sg_nents(qm_sg_nents); 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci sg_table = &edesc->sgt[0]; 47362306a36Sopenharmony_ci qm_sg_bytes = qm_sg_nents * sizeof(*sg_table); 47462306a36Sopenharmony_ci if (unlikely(offsetof(struct aead_edesc, sgt) + qm_sg_bytes + ivsize > 47562306a36Sopenharmony_ci CAAM_QI_MEMCACHE_SIZE)) { 47662306a36Sopenharmony_ci dev_err(dev, "No space for %d S/G entries and/or %dB IV\n", 47762306a36Sopenharmony_ci qm_sg_nents, ivsize); 47862306a36Sopenharmony_ci caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0, 47962306a36Sopenharmony_ci 0, DMA_NONE, 0, 0); 48062306a36Sopenharmony_ci qi_cache_free(edesc); 48162306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 48262306a36Sopenharmony_ci } 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci if (ivsize) { 48562306a36Sopenharmony_ci u8 *iv = (u8 *)(sg_table + qm_sg_nents); 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci /* Make sure IV is located in a DMAable area */ 48862306a36Sopenharmony_ci memcpy(iv, req->iv, ivsize); 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci iv_dma = dma_map_single(dev, iv, ivsize, DMA_TO_DEVICE); 49162306a36Sopenharmony_ci if (dma_mapping_error(dev, iv_dma)) { 49262306a36Sopenharmony_ci dev_err(dev, "unable to map IV\n"); 49362306a36Sopenharmony_ci caam_unmap(dev, req->src, req->dst, src_nents, 49462306a36Sopenharmony_ci dst_nents, 0, 0, DMA_NONE, 0, 0); 49562306a36Sopenharmony_ci qi_cache_free(edesc); 49662306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 49762306a36Sopenharmony_ci } 49862306a36Sopenharmony_ci } 49962306a36Sopenharmony_ci 50062306a36Sopenharmony_ci edesc->src_nents = src_nents; 50162306a36Sopenharmony_ci edesc->dst_nents = dst_nents; 50262306a36Sopenharmony_ci edesc->iv_dma = iv_dma; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci if ((alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK) == 50562306a36Sopenharmony_ci OP_ALG_ALGSEL_CHACHA20 && ivsize != CHACHAPOLY_IV_SIZE) 50662306a36Sopenharmony_ci /* 50762306a36Sopenharmony_ci * The associated data comes already with the IV but we need 50862306a36Sopenharmony_ci * to skip it when we authenticate or encrypt... 50962306a36Sopenharmony_ci */ 51062306a36Sopenharmony_ci edesc->assoclen = cpu_to_caam32(req->assoclen - ivsize); 51162306a36Sopenharmony_ci else 51262306a36Sopenharmony_ci edesc->assoclen = cpu_to_caam32(req->assoclen); 51362306a36Sopenharmony_ci edesc->assoclen_dma = dma_map_single(dev, &edesc->assoclen, 4, 51462306a36Sopenharmony_ci DMA_TO_DEVICE); 51562306a36Sopenharmony_ci if (dma_mapping_error(dev, edesc->assoclen_dma)) { 51662306a36Sopenharmony_ci dev_err(dev, "unable to map assoclen\n"); 51762306a36Sopenharmony_ci caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 51862306a36Sopenharmony_ci iv_dma, ivsize, DMA_TO_DEVICE, 0, 0); 51962306a36Sopenharmony_ci qi_cache_free(edesc); 52062306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 52162306a36Sopenharmony_ci } 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci dma_to_qm_sg_one(sg_table, edesc->assoclen_dma, 4, 0); 52462306a36Sopenharmony_ci qm_sg_index++; 52562306a36Sopenharmony_ci if (ivsize) { 52662306a36Sopenharmony_ci dma_to_qm_sg_one(sg_table + qm_sg_index, iv_dma, ivsize, 0); 52762306a36Sopenharmony_ci qm_sg_index++; 52862306a36Sopenharmony_ci } 52962306a36Sopenharmony_ci sg_to_qm_sg_last(req->src, src_len, sg_table + qm_sg_index, 0); 53062306a36Sopenharmony_ci qm_sg_index += mapped_src_nents; 53162306a36Sopenharmony_ci 53262306a36Sopenharmony_ci if (mapped_dst_nents > 1) 53362306a36Sopenharmony_ci sg_to_qm_sg_last(req->dst, dst_len, sg_table + qm_sg_index, 0); 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci qm_sg_dma = dma_map_single(dev, sg_table, qm_sg_bytes, DMA_TO_DEVICE); 53662306a36Sopenharmony_ci if (dma_mapping_error(dev, qm_sg_dma)) { 53762306a36Sopenharmony_ci dev_err(dev, "unable to map S/G table\n"); 53862306a36Sopenharmony_ci dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE); 53962306a36Sopenharmony_ci caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 54062306a36Sopenharmony_ci iv_dma, ivsize, DMA_TO_DEVICE, 0, 0); 54162306a36Sopenharmony_ci qi_cache_free(edesc); 54262306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 54362306a36Sopenharmony_ci } 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci edesc->qm_sg_dma = qm_sg_dma; 54662306a36Sopenharmony_ci edesc->qm_sg_bytes = qm_sg_bytes; 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci out_len = req->assoclen + req->cryptlen + 54962306a36Sopenharmony_ci (encrypt ? ctx->authsize : (-ctx->authsize)); 55062306a36Sopenharmony_ci in_len = 4 + ivsize + req->assoclen + req->cryptlen; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); 55362306a36Sopenharmony_ci dpaa2_fl_set_final(in_fle, true); 55462306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); 55562306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, qm_sg_dma); 55662306a36Sopenharmony_ci dpaa2_fl_set_len(in_fle, in_len); 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci if (req->dst == req->src) { 55962306a36Sopenharmony_ci if (mapped_src_nents == 1) { 56062306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_single); 56162306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, sg_dma_address(req->src)); 56262306a36Sopenharmony_ci } else { 56362306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_sg); 56462306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, qm_sg_dma + 56562306a36Sopenharmony_ci (1 + !!ivsize) * sizeof(*sg_table)); 56662306a36Sopenharmony_ci } 56762306a36Sopenharmony_ci } else if (!mapped_dst_nents) { 56862306a36Sopenharmony_ci /* 56962306a36Sopenharmony_ci * crypto engine requires the output entry to be present when 57062306a36Sopenharmony_ci * "frame list" FD is used. 57162306a36Sopenharmony_ci * Since engine does not support FMT=2'b11 (unused entry type), 57262306a36Sopenharmony_ci * leaving out_fle zeroized is the best option. 57362306a36Sopenharmony_ci */ 57462306a36Sopenharmony_ci goto skip_out_fle; 57562306a36Sopenharmony_ci } else if (mapped_dst_nents == 1) { 57662306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_single); 57762306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, sg_dma_address(req->dst)); 57862306a36Sopenharmony_ci } else { 57962306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_sg); 58062306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, qm_sg_dma + qm_sg_index * 58162306a36Sopenharmony_ci sizeof(*sg_table)); 58262306a36Sopenharmony_ci } 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci dpaa2_fl_set_len(out_fle, out_len); 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ciskip_out_fle: 58762306a36Sopenharmony_ci return edesc; 58862306a36Sopenharmony_ci} 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_cistatic int chachapoly_set_sh_desc(struct crypto_aead *aead) 59162306a36Sopenharmony_ci{ 59262306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 59362306a36Sopenharmony_ci unsigned int ivsize = crypto_aead_ivsize(aead); 59462306a36Sopenharmony_ci struct device *dev = ctx->dev; 59562306a36Sopenharmony_ci struct caam_flc *flc; 59662306a36Sopenharmony_ci u32 *desc; 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ci if (!ctx->cdata.keylen || !ctx->authsize) 59962306a36Sopenharmony_ci return 0; 60062306a36Sopenharmony_ci 60162306a36Sopenharmony_ci flc = &ctx->flc[ENCRYPT]; 60262306a36Sopenharmony_ci desc = flc->sh_desc; 60362306a36Sopenharmony_ci cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize, 60462306a36Sopenharmony_ci ctx->authsize, true, true); 60562306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 60662306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT], 60762306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 60862306a36Sopenharmony_ci ctx->dir); 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_ci flc = &ctx->flc[DECRYPT]; 61162306a36Sopenharmony_ci desc = flc->sh_desc; 61262306a36Sopenharmony_ci cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize, 61362306a36Sopenharmony_ci ctx->authsize, false, true); 61462306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 61562306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT], 61662306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 61762306a36Sopenharmony_ci ctx->dir); 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ci return 0; 62062306a36Sopenharmony_ci} 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_cistatic int chachapoly_setauthsize(struct crypto_aead *aead, 62362306a36Sopenharmony_ci unsigned int authsize) 62462306a36Sopenharmony_ci{ 62562306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 62662306a36Sopenharmony_ci 62762306a36Sopenharmony_ci if (authsize != POLY1305_DIGEST_SIZE) 62862306a36Sopenharmony_ci return -EINVAL; 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci ctx->authsize = authsize; 63162306a36Sopenharmony_ci return chachapoly_set_sh_desc(aead); 63262306a36Sopenharmony_ci} 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_cistatic int chachapoly_setkey(struct crypto_aead *aead, const u8 *key, 63562306a36Sopenharmony_ci unsigned int keylen) 63662306a36Sopenharmony_ci{ 63762306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 63862306a36Sopenharmony_ci unsigned int ivsize = crypto_aead_ivsize(aead); 63962306a36Sopenharmony_ci unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize; 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci if (keylen != CHACHA_KEY_SIZE + saltlen) 64262306a36Sopenharmony_ci return -EINVAL; 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_ci memcpy(ctx->key, key, keylen); 64562306a36Sopenharmony_ci ctx->cdata.key_virt = ctx->key; 64662306a36Sopenharmony_ci ctx->cdata.keylen = keylen - saltlen; 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci return chachapoly_set_sh_desc(aead); 64962306a36Sopenharmony_ci} 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_cistatic int gcm_set_sh_desc(struct crypto_aead *aead) 65262306a36Sopenharmony_ci{ 65362306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 65462306a36Sopenharmony_ci struct device *dev = ctx->dev; 65562306a36Sopenharmony_ci unsigned int ivsize = crypto_aead_ivsize(aead); 65662306a36Sopenharmony_ci struct caam_flc *flc; 65762306a36Sopenharmony_ci u32 *desc; 65862306a36Sopenharmony_ci int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN - 65962306a36Sopenharmony_ci ctx->cdata.keylen; 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci if (!ctx->cdata.keylen || !ctx->authsize) 66262306a36Sopenharmony_ci return 0; 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci /* 66562306a36Sopenharmony_ci * AES GCM encrypt shared descriptor 66662306a36Sopenharmony_ci * Job Descriptor and Shared Descriptor 66762306a36Sopenharmony_ci * must fit into the 64-word Descriptor h/w Buffer 66862306a36Sopenharmony_ci */ 66962306a36Sopenharmony_ci if (rem_bytes >= DESC_QI_GCM_ENC_LEN) { 67062306a36Sopenharmony_ci ctx->cdata.key_inline = true; 67162306a36Sopenharmony_ci ctx->cdata.key_virt = ctx->key; 67262306a36Sopenharmony_ci } else { 67362306a36Sopenharmony_ci ctx->cdata.key_inline = false; 67462306a36Sopenharmony_ci ctx->cdata.key_dma = ctx->key_dma; 67562306a36Sopenharmony_ci } 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_ci flc = &ctx->flc[ENCRYPT]; 67862306a36Sopenharmony_ci desc = flc->sh_desc; 67962306a36Sopenharmony_ci cnstr_shdsc_gcm_encap(desc, &ctx->cdata, ivsize, ctx->authsize, true); 68062306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 68162306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT], 68262306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 68362306a36Sopenharmony_ci ctx->dir); 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci /* 68662306a36Sopenharmony_ci * Job Descriptor and Shared Descriptors 68762306a36Sopenharmony_ci * must all fit into the 64-word Descriptor h/w Buffer 68862306a36Sopenharmony_ci */ 68962306a36Sopenharmony_ci if (rem_bytes >= DESC_QI_GCM_DEC_LEN) { 69062306a36Sopenharmony_ci ctx->cdata.key_inline = true; 69162306a36Sopenharmony_ci ctx->cdata.key_virt = ctx->key; 69262306a36Sopenharmony_ci } else { 69362306a36Sopenharmony_ci ctx->cdata.key_inline = false; 69462306a36Sopenharmony_ci ctx->cdata.key_dma = ctx->key_dma; 69562306a36Sopenharmony_ci } 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_ci flc = &ctx->flc[DECRYPT]; 69862306a36Sopenharmony_ci desc = flc->sh_desc; 69962306a36Sopenharmony_ci cnstr_shdsc_gcm_decap(desc, &ctx->cdata, ivsize, ctx->authsize, true); 70062306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 70162306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT], 70262306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 70362306a36Sopenharmony_ci ctx->dir); 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_ci return 0; 70662306a36Sopenharmony_ci} 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_cistatic int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize) 70962306a36Sopenharmony_ci{ 71062306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(authenc); 71162306a36Sopenharmony_ci int err; 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci err = crypto_gcm_check_authsize(authsize); 71462306a36Sopenharmony_ci if (err) 71562306a36Sopenharmony_ci return err; 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci ctx->authsize = authsize; 71862306a36Sopenharmony_ci gcm_set_sh_desc(authenc); 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci return 0; 72162306a36Sopenharmony_ci} 72262306a36Sopenharmony_ci 72362306a36Sopenharmony_cistatic int gcm_setkey(struct crypto_aead *aead, 72462306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 72562306a36Sopenharmony_ci{ 72662306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 72762306a36Sopenharmony_ci struct device *dev = ctx->dev; 72862306a36Sopenharmony_ci int ret; 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_ci ret = aes_check_keylen(keylen); 73162306a36Sopenharmony_ci if (ret) 73262306a36Sopenharmony_ci return ret; 73362306a36Sopenharmony_ci print_hex_dump_debug("key in @" __stringify(__LINE__)": ", 73462306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci memcpy(ctx->key, key, keylen); 73762306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->key_dma, keylen, ctx->dir); 73862306a36Sopenharmony_ci ctx->cdata.keylen = keylen; 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_ci return gcm_set_sh_desc(aead); 74162306a36Sopenharmony_ci} 74262306a36Sopenharmony_ci 74362306a36Sopenharmony_cistatic int rfc4106_set_sh_desc(struct crypto_aead *aead) 74462306a36Sopenharmony_ci{ 74562306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 74662306a36Sopenharmony_ci struct device *dev = ctx->dev; 74762306a36Sopenharmony_ci unsigned int ivsize = crypto_aead_ivsize(aead); 74862306a36Sopenharmony_ci struct caam_flc *flc; 74962306a36Sopenharmony_ci u32 *desc; 75062306a36Sopenharmony_ci int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN - 75162306a36Sopenharmony_ci ctx->cdata.keylen; 75262306a36Sopenharmony_ci 75362306a36Sopenharmony_ci if (!ctx->cdata.keylen || !ctx->authsize) 75462306a36Sopenharmony_ci return 0; 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci ctx->cdata.key_virt = ctx->key; 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci /* 75962306a36Sopenharmony_ci * RFC4106 encrypt shared descriptor 76062306a36Sopenharmony_ci * Job Descriptor and Shared Descriptor 76162306a36Sopenharmony_ci * must fit into the 64-word Descriptor h/w Buffer 76262306a36Sopenharmony_ci */ 76362306a36Sopenharmony_ci if (rem_bytes >= DESC_QI_RFC4106_ENC_LEN) { 76462306a36Sopenharmony_ci ctx->cdata.key_inline = true; 76562306a36Sopenharmony_ci } else { 76662306a36Sopenharmony_ci ctx->cdata.key_inline = false; 76762306a36Sopenharmony_ci ctx->cdata.key_dma = ctx->key_dma; 76862306a36Sopenharmony_ci } 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_ci flc = &ctx->flc[ENCRYPT]; 77162306a36Sopenharmony_ci desc = flc->sh_desc; 77262306a36Sopenharmony_ci cnstr_shdsc_rfc4106_encap(desc, &ctx->cdata, ivsize, ctx->authsize, 77362306a36Sopenharmony_ci true); 77462306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 77562306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT], 77662306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 77762306a36Sopenharmony_ci ctx->dir); 77862306a36Sopenharmony_ci 77962306a36Sopenharmony_ci /* 78062306a36Sopenharmony_ci * Job Descriptor and Shared Descriptors 78162306a36Sopenharmony_ci * must all fit into the 64-word Descriptor h/w Buffer 78262306a36Sopenharmony_ci */ 78362306a36Sopenharmony_ci if (rem_bytes >= DESC_QI_RFC4106_DEC_LEN) { 78462306a36Sopenharmony_ci ctx->cdata.key_inline = true; 78562306a36Sopenharmony_ci } else { 78662306a36Sopenharmony_ci ctx->cdata.key_inline = false; 78762306a36Sopenharmony_ci ctx->cdata.key_dma = ctx->key_dma; 78862306a36Sopenharmony_ci } 78962306a36Sopenharmony_ci 79062306a36Sopenharmony_ci flc = &ctx->flc[DECRYPT]; 79162306a36Sopenharmony_ci desc = flc->sh_desc; 79262306a36Sopenharmony_ci cnstr_shdsc_rfc4106_decap(desc, &ctx->cdata, ivsize, ctx->authsize, 79362306a36Sopenharmony_ci true); 79462306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 79562306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT], 79662306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 79762306a36Sopenharmony_ci ctx->dir); 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_ci return 0; 80062306a36Sopenharmony_ci} 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_cistatic int rfc4106_setauthsize(struct crypto_aead *authenc, 80362306a36Sopenharmony_ci unsigned int authsize) 80462306a36Sopenharmony_ci{ 80562306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(authenc); 80662306a36Sopenharmony_ci int err; 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_ci err = crypto_rfc4106_check_authsize(authsize); 80962306a36Sopenharmony_ci if (err) 81062306a36Sopenharmony_ci return err; 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_ci ctx->authsize = authsize; 81362306a36Sopenharmony_ci rfc4106_set_sh_desc(authenc); 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ci return 0; 81662306a36Sopenharmony_ci} 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_cistatic int rfc4106_setkey(struct crypto_aead *aead, 81962306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 82062306a36Sopenharmony_ci{ 82162306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 82262306a36Sopenharmony_ci struct device *dev = ctx->dev; 82362306a36Sopenharmony_ci int ret; 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci ret = aes_check_keylen(keylen - 4); 82662306a36Sopenharmony_ci if (ret) 82762306a36Sopenharmony_ci return ret; 82862306a36Sopenharmony_ci 82962306a36Sopenharmony_ci print_hex_dump_debug("key in @" __stringify(__LINE__)": ", 83062306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci memcpy(ctx->key, key, keylen); 83362306a36Sopenharmony_ci /* 83462306a36Sopenharmony_ci * The last four bytes of the key material are used as the salt value 83562306a36Sopenharmony_ci * in the nonce. Update the AES key length. 83662306a36Sopenharmony_ci */ 83762306a36Sopenharmony_ci ctx->cdata.keylen = keylen - 4; 83862306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->key_dma, ctx->cdata.keylen, 83962306a36Sopenharmony_ci ctx->dir); 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci return rfc4106_set_sh_desc(aead); 84262306a36Sopenharmony_ci} 84362306a36Sopenharmony_ci 84462306a36Sopenharmony_cistatic int rfc4543_set_sh_desc(struct crypto_aead *aead) 84562306a36Sopenharmony_ci{ 84662306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 84762306a36Sopenharmony_ci struct device *dev = ctx->dev; 84862306a36Sopenharmony_ci unsigned int ivsize = crypto_aead_ivsize(aead); 84962306a36Sopenharmony_ci struct caam_flc *flc; 85062306a36Sopenharmony_ci u32 *desc; 85162306a36Sopenharmony_ci int rem_bytes = CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN - 85262306a36Sopenharmony_ci ctx->cdata.keylen; 85362306a36Sopenharmony_ci 85462306a36Sopenharmony_ci if (!ctx->cdata.keylen || !ctx->authsize) 85562306a36Sopenharmony_ci return 0; 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_ci ctx->cdata.key_virt = ctx->key; 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci /* 86062306a36Sopenharmony_ci * RFC4543 encrypt shared descriptor 86162306a36Sopenharmony_ci * Job Descriptor and Shared Descriptor 86262306a36Sopenharmony_ci * must fit into the 64-word Descriptor h/w Buffer 86362306a36Sopenharmony_ci */ 86462306a36Sopenharmony_ci if (rem_bytes >= DESC_QI_RFC4543_ENC_LEN) { 86562306a36Sopenharmony_ci ctx->cdata.key_inline = true; 86662306a36Sopenharmony_ci } else { 86762306a36Sopenharmony_ci ctx->cdata.key_inline = false; 86862306a36Sopenharmony_ci ctx->cdata.key_dma = ctx->key_dma; 86962306a36Sopenharmony_ci } 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci flc = &ctx->flc[ENCRYPT]; 87262306a36Sopenharmony_ci desc = flc->sh_desc; 87362306a36Sopenharmony_ci cnstr_shdsc_rfc4543_encap(desc, &ctx->cdata, ivsize, ctx->authsize, 87462306a36Sopenharmony_ci true); 87562306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 87662306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT], 87762306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 87862306a36Sopenharmony_ci ctx->dir); 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_ci /* 88162306a36Sopenharmony_ci * Job Descriptor and Shared Descriptors 88262306a36Sopenharmony_ci * must all fit into the 64-word Descriptor h/w Buffer 88362306a36Sopenharmony_ci */ 88462306a36Sopenharmony_ci if (rem_bytes >= DESC_QI_RFC4543_DEC_LEN) { 88562306a36Sopenharmony_ci ctx->cdata.key_inline = true; 88662306a36Sopenharmony_ci } else { 88762306a36Sopenharmony_ci ctx->cdata.key_inline = false; 88862306a36Sopenharmony_ci ctx->cdata.key_dma = ctx->key_dma; 88962306a36Sopenharmony_ci } 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci flc = &ctx->flc[DECRYPT]; 89262306a36Sopenharmony_ci desc = flc->sh_desc; 89362306a36Sopenharmony_ci cnstr_shdsc_rfc4543_decap(desc, &ctx->cdata, ivsize, ctx->authsize, 89462306a36Sopenharmony_ci true); 89562306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 89662306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT], 89762306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 89862306a36Sopenharmony_ci ctx->dir); 89962306a36Sopenharmony_ci 90062306a36Sopenharmony_ci return 0; 90162306a36Sopenharmony_ci} 90262306a36Sopenharmony_ci 90362306a36Sopenharmony_cistatic int rfc4543_setauthsize(struct crypto_aead *authenc, 90462306a36Sopenharmony_ci unsigned int authsize) 90562306a36Sopenharmony_ci{ 90662306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(authenc); 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci if (authsize != 16) 90962306a36Sopenharmony_ci return -EINVAL; 91062306a36Sopenharmony_ci 91162306a36Sopenharmony_ci ctx->authsize = authsize; 91262306a36Sopenharmony_ci rfc4543_set_sh_desc(authenc); 91362306a36Sopenharmony_ci 91462306a36Sopenharmony_ci return 0; 91562306a36Sopenharmony_ci} 91662306a36Sopenharmony_ci 91762306a36Sopenharmony_cistatic int rfc4543_setkey(struct crypto_aead *aead, 91862306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 91962306a36Sopenharmony_ci{ 92062306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 92162306a36Sopenharmony_ci struct device *dev = ctx->dev; 92262306a36Sopenharmony_ci int ret; 92362306a36Sopenharmony_ci 92462306a36Sopenharmony_ci ret = aes_check_keylen(keylen - 4); 92562306a36Sopenharmony_ci if (ret) 92662306a36Sopenharmony_ci return ret; 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci print_hex_dump_debug("key in @" __stringify(__LINE__)": ", 92962306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); 93062306a36Sopenharmony_ci 93162306a36Sopenharmony_ci memcpy(ctx->key, key, keylen); 93262306a36Sopenharmony_ci /* 93362306a36Sopenharmony_ci * The last four bytes of the key material are used as the salt value 93462306a36Sopenharmony_ci * in the nonce. Update the AES key length. 93562306a36Sopenharmony_ci */ 93662306a36Sopenharmony_ci ctx->cdata.keylen = keylen - 4; 93762306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->key_dma, ctx->cdata.keylen, 93862306a36Sopenharmony_ci ctx->dir); 93962306a36Sopenharmony_ci 94062306a36Sopenharmony_ci return rfc4543_set_sh_desc(aead); 94162306a36Sopenharmony_ci} 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_cistatic int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, 94462306a36Sopenharmony_ci unsigned int keylen, const u32 ctx1_iv_off) 94562306a36Sopenharmony_ci{ 94662306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher); 94762306a36Sopenharmony_ci struct caam_skcipher_alg *alg = 94862306a36Sopenharmony_ci container_of(crypto_skcipher_alg(skcipher), 94962306a36Sopenharmony_ci struct caam_skcipher_alg, skcipher); 95062306a36Sopenharmony_ci struct device *dev = ctx->dev; 95162306a36Sopenharmony_ci struct caam_flc *flc; 95262306a36Sopenharmony_ci unsigned int ivsize = crypto_skcipher_ivsize(skcipher); 95362306a36Sopenharmony_ci u32 *desc; 95462306a36Sopenharmony_ci const bool is_rfc3686 = alg->caam.rfc3686; 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_ci print_hex_dump_debug("key in @" __stringify(__LINE__)": ", 95762306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1); 95862306a36Sopenharmony_ci 95962306a36Sopenharmony_ci ctx->cdata.keylen = keylen; 96062306a36Sopenharmony_ci ctx->cdata.key_virt = key; 96162306a36Sopenharmony_ci ctx->cdata.key_inline = true; 96262306a36Sopenharmony_ci 96362306a36Sopenharmony_ci /* skcipher_encrypt shared descriptor */ 96462306a36Sopenharmony_ci flc = &ctx->flc[ENCRYPT]; 96562306a36Sopenharmony_ci desc = flc->sh_desc; 96662306a36Sopenharmony_ci cnstr_shdsc_skcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686, 96762306a36Sopenharmony_ci ctx1_iv_off); 96862306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 96962306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT], 97062306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 97162306a36Sopenharmony_ci ctx->dir); 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci /* skcipher_decrypt shared descriptor */ 97462306a36Sopenharmony_ci flc = &ctx->flc[DECRYPT]; 97562306a36Sopenharmony_ci desc = flc->sh_desc; 97662306a36Sopenharmony_ci cnstr_shdsc_skcipher_decap(desc, &ctx->cdata, ivsize, is_rfc3686, 97762306a36Sopenharmony_ci ctx1_iv_off); 97862306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 97962306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT], 98062306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 98162306a36Sopenharmony_ci ctx->dir); 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci return 0; 98462306a36Sopenharmony_ci} 98562306a36Sopenharmony_ci 98662306a36Sopenharmony_cistatic int aes_skcipher_setkey(struct crypto_skcipher *skcipher, 98762306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 98862306a36Sopenharmony_ci{ 98962306a36Sopenharmony_ci int err; 99062306a36Sopenharmony_ci 99162306a36Sopenharmony_ci err = aes_check_keylen(keylen); 99262306a36Sopenharmony_ci if (err) 99362306a36Sopenharmony_ci return err; 99462306a36Sopenharmony_ci 99562306a36Sopenharmony_ci return skcipher_setkey(skcipher, key, keylen, 0); 99662306a36Sopenharmony_ci} 99762306a36Sopenharmony_ci 99862306a36Sopenharmony_cistatic int rfc3686_skcipher_setkey(struct crypto_skcipher *skcipher, 99962306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 100062306a36Sopenharmony_ci{ 100162306a36Sopenharmony_ci u32 ctx1_iv_off; 100262306a36Sopenharmony_ci int err; 100362306a36Sopenharmony_ci 100462306a36Sopenharmony_ci /* 100562306a36Sopenharmony_ci * RFC3686 specific: 100662306a36Sopenharmony_ci * | CONTEXT1[255:128] = {NONCE, IV, COUNTER} 100762306a36Sopenharmony_ci * | *key = {KEY, NONCE} 100862306a36Sopenharmony_ci */ 100962306a36Sopenharmony_ci ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE; 101062306a36Sopenharmony_ci keylen -= CTR_RFC3686_NONCE_SIZE; 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_ci err = aes_check_keylen(keylen); 101362306a36Sopenharmony_ci if (err) 101462306a36Sopenharmony_ci return err; 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off); 101762306a36Sopenharmony_ci} 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_cistatic int ctr_skcipher_setkey(struct crypto_skcipher *skcipher, 102062306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 102162306a36Sopenharmony_ci{ 102262306a36Sopenharmony_ci u32 ctx1_iv_off; 102362306a36Sopenharmony_ci int err; 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_ci /* 102662306a36Sopenharmony_ci * AES-CTR needs to load IV in CONTEXT1 reg 102762306a36Sopenharmony_ci * at an offset of 128bits (16bytes) 102862306a36Sopenharmony_ci * CONTEXT1[255:128] = IV 102962306a36Sopenharmony_ci */ 103062306a36Sopenharmony_ci ctx1_iv_off = 16; 103162306a36Sopenharmony_ci 103262306a36Sopenharmony_ci err = aes_check_keylen(keylen); 103362306a36Sopenharmony_ci if (err) 103462306a36Sopenharmony_ci return err; 103562306a36Sopenharmony_ci 103662306a36Sopenharmony_ci return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off); 103762306a36Sopenharmony_ci} 103862306a36Sopenharmony_ci 103962306a36Sopenharmony_cistatic int chacha20_skcipher_setkey(struct crypto_skcipher *skcipher, 104062306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 104162306a36Sopenharmony_ci{ 104262306a36Sopenharmony_ci if (keylen != CHACHA_KEY_SIZE) 104362306a36Sopenharmony_ci return -EINVAL; 104462306a36Sopenharmony_ci 104562306a36Sopenharmony_ci return skcipher_setkey(skcipher, key, keylen, 0); 104662306a36Sopenharmony_ci} 104762306a36Sopenharmony_ci 104862306a36Sopenharmony_cistatic int des_skcipher_setkey(struct crypto_skcipher *skcipher, 104962306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 105062306a36Sopenharmony_ci{ 105162306a36Sopenharmony_ci return verify_skcipher_des_key(skcipher, key) ?: 105262306a36Sopenharmony_ci skcipher_setkey(skcipher, key, keylen, 0); 105362306a36Sopenharmony_ci} 105462306a36Sopenharmony_ci 105562306a36Sopenharmony_cistatic int des3_skcipher_setkey(struct crypto_skcipher *skcipher, 105662306a36Sopenharmony_ci const u8 *key, unsigned int keylen) 105762306a36Sopenharmony_ci{ 105862306a36Sopenharmony_ci return verify_skcipher_des3_key(skcipher, key) ?: 105962306a36Sopenharmony_ci skcipher_setkey(skcipher, key, keylen, 0); 106062306a36Sopenharmony_ci} 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_cistatic int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, 106362306a36Sopenharmony_ci unsigned int keylen) 106462306a36Sopenharmony_ci{ 106562306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher); 106662306a36Sopenharmony_ci struct device *dev = ctx->dev; 106762306a36Sopenharmony_ci struct dpaa2_caam_priv *priv = dev_get_drvdata(dev); 106862306a36Sopenharmony_ci struct caam_flc *flc; 106962306a36Sopenharmony_ci u32 *desc; 107062306a36Sopenharmony_ci int err; 107162306a36Sopenharmony_ci 107262306a36Sopenharmony_ci err = xts_verify_key(skcipher, key, keylen); 107362306a36Sopenharmony_ci if (err) { 107462306a36Sopenharmony_ci dev_dbg(dev, "key size mismatch\n"); 107562306a36Sopenharmony_ci return err; 107662306a36Sopenharmony_ci } 107762306a36Sopenharmony_ci 107862306a36Sopenharmony_ci if (keylen != 2 * AES_KEYSIZE_128 && keylen != 2 * AES_KEYSIZE_256) 107962306a36Sopenharmony_ci ctx->xts_key_fallback = true; 108062306a36Sopenharmony_ci 108162306a36Sopenharmony_ci if (priv->sec_attr.era <= 8 || ctx->xts_key_fallback) { 108262306a36Sopenharmony_ci err = crypto_skcipher_setkey(ctx->fallback, key, keylen); 108362306a36Sopenharmony_ci if (err) 108462306a36Sopenharmony_ci return err; 108562306a36Sopenharmony_ci } 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_ci ctx->cdata.keylen = keylen; 108862306a36Sopenharmony_ci ctx->cdata.key_virt = key; 108962306a36Sopenharmony_ci ctx->cdata.key_inline = true; 109062306a36Sopenharmony_ci 109162306a36Sopenharmony_ci /* xts_skcipher_encrypt shared descriptor */ 109262306a36Sopenharmony_ci flc = &ctx->flc[ENCRYPT]; 109362306a36Sopenharmony_ci desc = flc->sh_desc; 109462306a36Sopenharmony_ci cnstr_shdsc_xts_skcipher_encap(desc, &ctx->cdata); 109562306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 109662306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[ENCRYPT], 109762306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 109862306a36Sopenharmony_ci ctx->dir); 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_ci /* xts_skcipher_decrypt shared descriptor */ 110162306a36Sopenharmony_ci flc = &ctx->flc[DECRYPT]; 110262306a36Sopenharmony_ci desc = flc->sh_desc; 110362306a36Sopenharmony_ci cnstr_shdsc_xts_skcipher_decap(desc, &ctx->cdata); 110462306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 110562306a36Sopenharmony_ci dma_sync_single_for_device(dev, ctx->flc_dma[DECRYPT], 110662306a36Sopenharmony_ci sizeof(flc->flc) + desc_bytes(desc), 110762306a36Sopenharmony_ci ctx->dir); 110862306a36Sopenharmony_ci 110962306a36Sopenharmony_ci return 0; 111062306a36Sopenharmony_ci} 111162306a36Sopenharmony_ci 111262306a36Sopenharmony_cistatic struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req) 111362306a36Sopenharmony_ci{ 111462306a36Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 111562306a36Sopenharmony_ci struct caam_request *req_ctx = skcipher_request_ctx_dma(req); 111662306a36Sopenharmony_ci struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; 111762306a36Sopenharmony_ci struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; 111862306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher); 111962306a36Sopenharmony_ci struct device *dev = ctx->dev; 112062306a36Sopenharmony_ci gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 112162306a36Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 112262306a36Sopenharmony_ci int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0; 112362306a36Sopenharmony_ci struct skcipher_edesc *edesc; 112462306a36Sopenharmony_ci dma_addr_t iv_dma; 112562306a36Sopenharmony_ci u8 *iv; 112662306a36Sopenharmony_ci int ivsize = crypto_skcipher_ivsize(skcipher); 112762306a36Sopenharmony_ci int dst_sg_idx, qm_sg_ents, qm_sg_bytes; 112862306a36Sopenharmony_ci struct dpaa2_sg_entry *sg_table; 112962306a36Sopenharmony_ci 113062306a36Sopenharmony_ci src_nents = sg_nents_for_len(req->src, req->cryptlen); 113162306a36Sopenharmony_ci if (unlikely(src_nents < 0)) { 113262306a36Sopenharmony_ci dev_err(dev, "Insufficient bytes (%d) in src S/G\n", 113362306a36Sopenharmony_ci req->cryptlen); 113462306a36Sopenharmony_ci return ERR_PTR(src_nents); 113562306a36Sopenharmony_ci } 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_ci if (unlikely(req->dst != req->src)) { 113862306a36Sopenharmony_ci dst_nents = sg_nents_for_len(req->dst, req->cryptlen); 113962306a36Sopenharmony_ci if (unlikely(dst_nents < 0)) { 114062306a36Sopenharmony_ci dev_err(dev, "Insufficient bytes (%d) in dst S/G\n", 114162306a36Sopenharmony_ci req->cryptlen); 114262306a36Sopenharmony_ci return ERR_PTR(dst_nents); 114362306a36Sopenharmony_ci } 114462306a36Sopenharmony_ci 114562306a36Sopenharmony_ci mapped_src_nents = dma_map_sg(dev, req->src, src_nents, 114662306a36Sopenharmony_ci DMA_TO_DEVICE); 114762306a36Sopenharmony_ci if (unlikely(!mapped_src_nents)) { 114862306a36Sopenharmony_ci dev_err(dev, "unable to map source\n"); 114962306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 115062306a36Sopenharmony_ci } 115162306a36Sopenharmony_ci 115262306a36Sopenharmony_ci mapped_dst_nents = dma_map_sg(dev, req->dst, dst_nents, 115362306a36Sopenharmony_ci DMA_FROM_DEVICE); 115462306a36Sopenharmony_ci if (unlikely(!mapped_dst_nents)) { 115562306a36Sopenharmony_ci dev_err(dev, "unable to map destination\n"); 115662306a36Sopenharmony_ci dma_unmap_sg(dev, req->src, src_nents, DMA_TO_DEVICE); 115762306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 115862306a36Sopenharmony_ci } 115962306a36Sopenharmony_ci } else { 116062306a36Sopenharmony_ci mapped_src_nents = dma_map_sg(dev, req->src, src_nents, 116162306a36Sopenharmony_ci DMA_BIDIRECTIONAL); 116262306a36Sopenharmony_ci if (unlikely(!mapped_src_nents)) { 116362306a36Sopenharmony_ci dev_err(dev, "unable to map source\n"); 116462306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 116562306a36Sopenharmony_ci } 116662306a36Sopenharmony_ci } 116762306a36Sopenharmony_ci 116862306a36Sopenharmony_ci qm_sg_ents = 1 + mapped_src_nents; 116962306a36Sopenharmony_ci dst_sg_idx = qm_sg_ents; 117062306a36Sopenharmony_ci 117162306a36Sopenharmony_ci /* 117262306a36Sopenharmony_ci * Input, output HW S/G tables: [IV, src][dst, IV] 117362306a36Sopenharmony_ci * IV entries point to the same buffer 117462306a36Sopenharmony_ci * If src == dst, S/G entries are reused (S/G tables overlap) 117562306a36Sopenharmony_ci * 117662306a36Sopenharmony_ci * HW reads 4 S/G entries at a time; make sure the reads don't go beyond 117762306a36Sopenharmony_ci * the end of the table by allocating more S/G entries. 117862306a36Sopenharmony_ci */ 117962306a36Sopenharmony_ci if (req->src != req->dst) 118062306a36Sopenharmony_ci qm_sg_ents += pad_sg_nents(mapped_dst_nents + 1); 118162306a36Sopenharmony_ci else 118262306a36Sopenharmony_ci qm_sg_ents = 1 + pad_sg_nents(qm_sg_ents); 118362306a36Sopenharmony_ci 118462306a36Sopenharmony_ci qm_sg_bytes = qm_sg_ents * sizeof(struct dpaa2_sg_entry); 118562306a36Sopenharmony_ci if (unlikely(offsetof(struct skcipher_edesc, sgt) + qm_sg_bytes + 118662306a36Sopenharmony_ci ivsize > CAAM_QI_MEMCACHE_SIZE)) { 118762306a36Sopenharmony_ci dev_err(dev, "No space for %d S/G entries and/or %dB IV\n", 118862306a36Sopenharmony_ci qm_sg_ents, ivsize); 118962306a36Sopenharmony_ci caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0, 119062306a36Sopenharmony_ci 0, DMA_NONE, 0, 0); 119162306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 119262306a36Sopenharmony_ci } 119362306a36Sopenharmony_ci 119462306a36Sopenharmony_ci /* allocate space for base edesc, link tables and IV */ 119562306a36Sopenharmony_ci edesc = qi_cache_zalloc(flags); 119662306a36Sopenharmony_ci if (unlikely(!edesc)) { 119762306a36Sopenharmony_ci dev_err(dev, "could not allocate extended descriptor\n"); 119862306a36Sopenharmony_ci caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0, 119962306a36Sopenharmony_ci 0, DMA_NONE, 0, 0); 120062306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 120162306a36Sopenharmony_ci } 120262306a36Sopenharmony_ci 120362306a36Sopenharmony_ci /* Make sure IV is located in a DMAable area */ 120462306a36Sopenharmony_ci sg_table = &edesc->sgt[0]; 120562306a36Sopenharmony_ci iv = (u8 *)(sg_table + qm_sg_ents); 120662306a36Sopenharmony_ci memcpy(iv, req->iv, ivsize); 120762306a36Sopenharmony_ci 120862306a36Sopenharmony_ci iv_dma = dma_map_single(dev, iv, ivsize, DMA_BIDIRECTIONAL); 120962306a36Sopenharmony_ci if (dma_mapping_error(dev, iv_dma)) { 121062306a36Sopenharmony_ci dev_err(dev, "unable to map IV\n"); 121162306a36Sopenharmony_ci caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 0, 121262306a36Sopenharmony_ci 0, DMA_NONE, 0, 0); 121362306a36Sopenharmony_ci qi_cache_free(edesc); 121462306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 121562306a36Sopenharmony_ci } 121662306a36Sopenharmony_ci 121762306a36Sopenharmony_ci edesc->src_nents = src_nents; 121862306a36Sopenharmony_ci edesc->dst_nents = dst_nents; 121962306a36Sopenharmony_ci edesc->iv_dma = iv_dma; 122062306a36Sopenharmony_ci edesc->qm_sg_bytes = qm_sg_bytes; 122162306a36Sopenharmony_ci 122262306a36Sopenharmony_ci dma_to_qm_sg_one(sg_table, iv_dma, ivsize, 0); 122362306a36Sopenharmony_ci sg_to_qm_sg(req->src, req->cryptlen, sg_table + 1, 0); 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_ci if (req->src != req->dst) 122662306a36Sopenharmony_ci sg_to_qm_sg(req->dst, req->cryptlen, sg_table + dst_sg_idx, 0); 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_ci dma_to_qm_sg_one(sg_table + dst_sg_idx + mapped_dst_nents, iv_dma, 122962306a36Sopenharmony_ci ivsize, 0); 123062306a36Sopenharmony_ci 123162306a36Sopenharmony_ci edesc->qm_sg_dma = dma_map_single(dev, sg_table, edesc->qm_sg_bytes, 123262306a36Sopenharmony_ci DMA_TO_DEVICE); 123362306a36Sopenharmony_ci if (dma_mapping_error(dev, edesc->qm_sg_dma)) { 123462306a36Sopenharmony_ci dev_err(dev, "unable to map S/G table\n"); 123562306a36Sopenharmony_ci caam_unmap(dev, req->src, req->dst, src_nents, dst_nents, 123662306a36Sopenharmony_ci iv_dma, ivsize, DMA_BIDIRECTIONAL, 0, 0); 123762306a36Sopenharmony_ci qi_cache_free(edesc); 123862306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 123962306a36Sopenharmony_ci } 124062306a36Sopenharmony_ci 124162306a36Sopenharmony_ci memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); 124262306a36Sopenharmony_ci dpaa2_fl_set_final(in_fle, true); 124362306a36Sopenharmony_ci dpaa2_fl_set_len(in_fle, req->cryptlen + ivsize); 124462306a36Sopenharmony_ci dpaa2_fl_set_len(out_fle, req->cryptlen + ivsize); 124562306a36Sopenharmony_ci 124662306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); 124762306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); 124862306a36Sopenharmony_ci 124962306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_sg); 125062306a36Sopenharmony_ci 125162306a36Sopenharmony_ci if (req->src == req->dst) 125262306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, edesc->qm_sg_dma + 125362306a36Sopenharmony_ci sizeof(*sg_table)); 125462306a36Sopenharmony_ci else 125562306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, edesc->qm_sg_dma + dst_sg_idx * 125662306a36Sopenharmony_ci sizeof(*sg_table)); 125762306a36Sopenharmony_ci 125862306a36Sopenharmony_ci return edesc; 125962306a36Sopenharmony_ci} 126062306a36Sopenharmony_ci 126162306a36Sopenharmony_cistatic void aead_unmap(struct device *dev, struct aead_edesc *edesc, 126262306a36Sopenharmony_ci struct aead_request *req) 126362306a36Sopenharmony_ci{ 126462306a36Sopenharmony_ci struct crypto_aead *aead = crypto_aead_reqtfm(req); 126562306a36Sopenharmony_ci int ivsize = crypto_aead_ivsize(aead); 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_ci caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents, 126862306a36Sopenharmony_ci edesc->iv_dma, ivsize, DMA_TO_DEVICE, edesc->qm_sg_dma, 126962306a36Sopenharmony_ci edesc->qm_sg_bytes); 127062306a36Sopenharmony_ci dma_unmap_single(dev, edesc->assoclen_dma, 4, DMA_TO_DEVICE); 127162306a36Sopenharmony_ci} 127262306a36Sopenharmony_ci 127362306a36Sopenharmony_cistatic void skcipher_unmap(struct device *dev, struct skcipher_edesc *edesc, 127462306a36Sopenharmony_ci struct skcipher_request *req) 127562306a36Sopenharmony_ci{ 127662306a36Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 127762306a36Sopenharmony_ci int ivsize = crypto_skcipher_ivsize(skcipher); 127862306a36Sopenharmony_ci 127962306a36Sopenharmony_ci caam_unmap(dev, req->src, req->dst, edesc->src_nents, edesc->dst_nents, 128062306a36Sopenharmony_ci edesc->iv_dma, ivsize, DMA_BIDIRECTIONAL, edesc->qm_sg_dma, 128162306a36Sopenharmony_ci edesc->qm_sg_bytes); 128262306a36Sopenharmony_ci} 128362306a36Sopenharmony_ci 128462306a36Sopenharmony_cistatic void aead_encrypt_done(void *cbk_ctx, u32 status) 128562306a36Sopenharmony_ci{ 128662306a36Sopenharmony_ci struct crypto_async_request *areq = cbk_ctx; 128762306a36Sopenharmony_ci struct aead_request *req = container_of(areq, struct aead_request, 128862306a36Sopenharmony_ci base); 128962306a36Sopenharmony_ci struct caam_request *req_ctx = to_caam_req(areq); 129062306a36Sopenharmony_ci struct aead_edesc *edesc = req_ctx->edesc; 129162306a36Sopenharmony_ci struct crypto_aead *aead = crypto_aead_reqtfm(req); 129262306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 129362306a36Sopenharmony_ci int ecode = 0; 129462306a36Sopenharmony_ci 129562306a36Sopenharmony_ci dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status); 129662306a36Sopenharmony_ci 129762306a36Sopenharmony_ci if (unlikely(status)) 129862306a36Sopenharmony_ci ecode = caam_qi2_strstatus(ctx->dev, status); 129962306a36Sopenharmony_ci 130062306a36Sopenharmony_ci aead_unmap(ctx->dev, edesc, req); 130162306a36Sopenharmony_ci qi_cache_free(edesc); 130262306a36Sopenharmony_ci aead_request_complete(req, ecode); 130362306a36Sopenharmony_ci} 130462306a36Sopenharmony_ci 130562306a36Sopenharmony_cistatic void aead_decrypt_done(void *cbk_ctx, u32 status) 130662306a36Sopenharmony_ci{ 130762306a36Sopenharmony_ci struct crypto_async_request *areq = cbk_ctx; 130862306a36Sopenharmony_ci struct aead_request *req = container_of(areq, struct aead_request, 130962306a36Sopenharmony_ci base); 131062306a36Sopenharmony_ci struct caam_request *req_ctx = to_caam_req(areq); 131162306a36Sopenharmony_ci struct aead_edesc *edesc = req_ctx->edesc; 131262306a36Sopenharmony_ci struct crypto_aead *aead = crypto_aead_reqtfm(req); 131362306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 131462306a36Sopenharmony_ci int ecode = 0; 131562306a36Sopenharmony_ci 131662306a36Sopenharmony_ci dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status); 131762306a36Sopenharmony_ci 131862306a36Sopenharmony_ci if (unlikely(status)) 131962306a36Sopenharmony_ci ecode = caam_qi2_strstatus(ctx->dev, status); 132062306a36Sopenharmony_ci 132162306a36Sopenharmony_ci aead_unmap(ctx->dev, edesc, req); 132262306a36Sopenharmony_ci qi_cache_free(edesc); 132362306a36Sopenharmony_ci aead_request_complete(req, ecode); 132462306a36Sopenharmony_ci} 132562306a36Sopenharmony_ci 132662306a36Sopenharmony_cistatic int aead_encrypt(struct aead_request *req) 132762306a36Sopenharmony_ci{ 132862306a36Sopenharmony_ci struct aead_edesc *edesc; 132962306a36Sopenharmony_ci struct crypto_aead *aead = crypto_aead_reqtfm(req); 133062306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 133162306a36Sopenharmony_ci struct caam_request *caam_req = aead_request_ctx_dma(req); 133262306a36Sopenharmony_ci int ret; 133362306a36Sopenharmony_ci 133462306a36Sopenharmony_ci /* allocate extended descriptor */ 133562306a36Sopenharmony_ci edesc = aead_edesc_alloc(req, true); 133662306a36Sopenharmony_ci if (IS_ERR(edesc)) 133762306a36Sopenharmony_ci return PTR_ERR(edesc); 133862306a36Sopenharmony_ci 133962306a36Sopenharmony_ci caam_req->flc = &ctx->flc[ENCRYPT]; 134062306a36Sopenharmony_ci caam_req->flc_dma = ctx->flc_dma[ENCRYPT]; 134162306a36Sopenharmony_ci caam_req->cbk = aead_encrypt_done; 134262306a36Sopenharmony_ci caam_req->ctx = &req->base; 134362306a36Sopenharmony_ci caam_req->edesc = edesc; 134462306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, caam_req); 134562306a36Sopenharmony_ci if (ret != -EINPROGRESS && 134662306a36Sopenharmony_ci !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { 134762306a36Sopenharmony_ci aead_unmap(ctx->dev, edesc, req); 134862306a36Sopenharmony_ci qi_cache_free(edesc); 134962306a36Sopenharmony_ci } 135062306a36Sopenharmony_ci 135162306a36Sopenharmony_ci return ret; 135262306a36Sopenharmony_ci} 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_cistatic int aead_decrypt(struct aead_request *req) 135562306a36Sopenharmony_ci{ 135662306a36Sopenharmony_ci struct aead_edesc *edesc; 135762306a36Sopenharmony_ci struct crypto_aead *aead = crypto_aead_reqtfm(req); 135862306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_aead_ctx_dma(aead); 135962306a36Sopenharmony_ci struct caam_request *caam_req = aead_request_ctx_dma(req); 136062306a36Sopenharmony_ci int ret; 136162306a36Sopenharmony_ci 136262306a36Sopenharmony_ci /* allocate extended descriptor */ 136362306a36Sopenharmony_ci edesc = aead_edesc_alloc(req, false); 136462306a36Sopenharmony_ci if (IS_ERR(edesc)) 136562306a36Sopenharmony_ci return PTR_ERR(edesc); 136662306a36Sopenharmony_ci 136762306a36Sopenharmony_ci caam_req->flc = &ctx->flc[DECRYPT]; 136862306a36Sopenharmony_ci caam_req->flc_dma = ctx->flc_dma[DECRYPT]; 136962306a36Sopenharmony_ci caam_req->cbk = aead_decrypt_done; 137062306a36Sopenharmony_ci caam_req->ctx = &req->base; 137162306a36Sopenharmony_ci caam_req->edesc = edesc; 137262306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, caam_req); 137362306a36Sopenharmony_ci if (ret != -EINPROGRESS && 137462306a36Sopenharmony_ci !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { 137562306a36Sopenharmony_ci aead_unmap(ctx->dev, edesc, req); 137662306a36Sopenharmony_ci qi_cache_free(edesc); 137762306a36Sopenharmony_ci } 137862306a36Sopenharmony_ci 137962306a36Sopenharmony_ci return ret; 138062306a36Sopenharmony_ci} 138162306a36Sopenharmony_ci 138262306a36Sopenharmony_cistatic int ipsec_gcm_encrypt(struct aead_request *req) 138362306a36Sopenharmony_ci{ 138462306a36Sopenharmony_ci return crypto_ipsec_check_assoclen(req->assoclen) ? : aead_encrypt(req); 138562306a36Sopenharmony_ci} 138662306a36Sopenharmony_ci 138762306a36Sopenharmony_cistatic int ipsec_gcm_decrypt(struct aead_request *req) 138862306a36Sopenharmony_ci{ 138962306a36Sopenharmony_ci return crypto_ipsec_check_assoclen(req->assoclen) ? : aead_decrypt(req); 139062306a36Sopenharmony_ci} 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_cistatic void skcipher_encrypt_done(void *cbk_ctx, u32 status) 139362306a36Sopenharmony_ci{ 139462306a36Sopenharmony_ci struct crypto_async_request *areq = cbk_ctx; 139562306a36Sopenharmony_ci struct skcipher_request *req = skcipher_request_cast(areq); 139662306a36Sopenharmony_ci struct caam_request *req_ctx = to_caam_req(areq); 139762306a36Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 139862306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher); 139962306a36Sopenharmony_ci struct skcipher_edesc *edesc = req_ctx->edesc; 140062306a36Sopenharmony_ci int ecode = 0; 140162306a36Sopenharmony_ci int ivsize = crypto_skcipher_ivsize(skcipher); 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_ci dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status); 140462306a36Sopenharmony_ci 140562306a36Sopenharmony_ci if (unlikely(status)) 140662306a36Sopenharmony_ci ecode = caam_qi2_strstatus(ctx->dev, status); 140762306a36Sopenharmony_ci 140862306a36Sopenharmony_ci print_hex_dump_debug("dstiv @" __stringify(__LINE__)": ", 140962306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, req->iv, 141062306a36Sopenharmony_ci edesc->src_nents > 1 ? 100 : ivsize, 1); 141162306a36Sopenharmony_ci caam_dump_sg("dst @" __stringify(__LINE__)": ", 141262306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, req->dst, 141362306a36Sopenharmony_ci edesc->dst_nents > 1 ? 100 : req->cryptlen, 1); 141462306a36Sopenharmony_ci 141562306a36Sopenharmony_ci skcipher_unmap(ctx->dev, edesc, req); 141662306a36Sopenharmony_ci 141762306a36Sopenharmony_ci /* 141862306a36Sopenharmony_ci * The crypto API expects us to set the IV (req->iv) to the last 141962306a36Sopenharmony_ci * ciphertext block (CBC mode) or last counter (CTR mode). 142062306a36Sopenharmony_ci * This is used e.g. by the CTS mode. 142162306a36Sopenharmony_ci */ 142262306a36Sopenharmony_ci if (!ecode) 142362306a36Sopenharmony_ci memcpy(req->iv, (u8 *)&edesc->sgt[0] + edesc->qm_sg_bytes, 142462306a36Sopenharmony_ci ivsize); 142562306a36Sopenharmony_ci 142662306a36Sopenharmony_ci qi_cache_free(edesc); 142762306a36Sopenharmony_ci skcipher_request_complete(req, ecode); 142862306a36Sopenharmony_ci} 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_cistatic void skcipher_decrypt_done(void *cbk_ctx, u32 status) 143162306a36Sopenharmony_ci{ 143262306a36Sopenharmony_ci struct crypto_async_request *areq = cbk_ctx; 143362306a36Sopenharmony_ci struct skcipher_request *req = skcipher_request_cast(areq); 143462306a36Sopenharmony_ci struct caam_request *req_ctx = to_caam_req(areq); 143562306a36Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 143662306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher); 143762306a36Sopenharmony_ci struct skcipher_edesc *edesc = req_ctx->edesc; 143862306a36Sopenharmony_ci int ecode = 0; 143962306a36Sopenharmony_ci int ivsize = crypto_skcipher_ivsize(skcipher); 144062306a36Sopenharmony_ci 144162306a36Sopenharmony_ci dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status); 144262306a36Sopenharmony_ci 144362306a36Sopenharmony_ci if (unlikely(status)) 144462306a36Sopenharmony_ci ecode = caam_qi2_strstatus(ctx->dev, status); 144562306a36Sopenharmony_ci 144662306a36Sopenharmony_ci print_hex_dump_debug("dstiv @" __stringify(__LINE__)": ", 144762306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, req->iv, 144862306a36Sopenharmony_ci edesc->src_nents > 1 ? 100 : ivsize, 1); 144962306a36Sopenharmony_ci caam_dump_sg("dst @" __stringify(__LINE__)": ", 145062306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, req->dst, 145162306a36Sopenharmony_ci edesc->dst_nents > 1 ? 100 : req->cryptlen, 1); 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_ci skcipher_unmap(ctx->dev, edesc, req); 145462306a36Sopenharmony_ci 145562306a36Sopenharmony_ci /* 145662306a36Sopenharmony_ci * The crypto API expects us to set the IV (req->iv) to the last 145762306a36Sopenharmony_ci * ciphertext block (CBC mode) or last counter (CTR mode). 145862306a36Sopenharmony_ci * This is used e.g. by the CTS mode. 145962306a36Sopenharmony_ci */ 146062306a36Sopenharmony_ci if (!ecode) 146162306a36Sopenharmony_ci memcpy(req->iv, (u8 *)&edesc->sgt[0] + edesc->qm_sg_bytes, 146262306a36Sopenharmony_ci ivsize); 146362306a36Sopenharmony_ci 146462306a36Sopenharmony_ci qi_cache_free(edesc); 146562306a36Sopenharmony_ci skcipher_request_complete(req, ecode); 146662306a36Sopenharmony_ci} 146762306a36Sopenharmony_ci 146862306a36Sopenharmony_cistatic inline bool xts_skcipher_ivsize(struct skcipher_request *req) 146962306a36Sopenharmony_ci{ 147062306a36Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 147162306a36Sopenharmony_ci unsigned int ivsize = crypto_skcipher_ivsize(skcipher); 147262306a36Sopenharmony_ci 147362306a36Sopenharmony_ci return !!get_unaligned((u64 *)(req->iv + (ivsize / 2))); 147462306a36Sopenharmony_ci} 147562306a36Sopenharmony_ci 147662306a36Sopenharmony_cistatic int skcipher_encrypt(struct skcipher_request *req) 147762306a36Sopenharmony_ci{ 147862306a36Sopenharmony_ci struct skcipher_edesc *edesc; 147962306a36Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 148062306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher); 148162306a36Sopenharmony_ci struct caam_request *caam_req = skcipher_request_ctx_dma(req); 148262306a36Sopenharmony_ci struct dpaa2_caam_priv *priv = dev_get_drvdata(ctx->dev); 148362306a36Sopenharmony_ci int ret; 148462306a36Sopenharmony_ci 148562306a36Sopenharmony_ci /* 148662306a36Sopenharmony_ci * XTS is expected to return an error even for input length = 0 148762306a36Sopenharmony_ci * Note that the case input length < block size will be caught during 148862306a36Sopenharmony_ci * HW offloading and return an error. 148962306a36Sopenharmony_ci */ 149062306a36Sopenharmony_ci if (!req->cryptlen && !ctx->fallback) 149162306a36Sopenharmony_ci return 0; 149262306a36Sopenharmony_ci 149362306a36Sopenharmony_ci if (ctx->fallback && ((priv->sec_attr.era <= 8 && xts_skcipher_ivsize(req)) || 149462306a36Sopenharmony_ci ctx->xts_key_fallback)) { 149562306a36Sopenharmony_ci skcipher_request_set_tfm(&caam_req->fallback_req, ctx->fallback); 149662306a36Sopenharmony_ci skcipher_request_set_callback(&caam_req->fallback_req, 149762306a36Sopenharmony_ci req->base.flags, 149862306a36Sopenharmony_ci req->base.complete, 149962306a36Sopenharmony_ci req->base.data); 150062306a36Sopenharmony_ci skcipher_request_set_crypt(&caam_req->fallback_req, req->src, 150162306a36Sopenharmony_ci req->dst, req->cryptlen, req->iv); 150262306a36Sopenharmony_ci 150362306a36Sopenharmony_ci return crypto_skcipher_encrypt(&caam_req->fallback_req); 150462306a36Sopenharmony_ci } 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_ci /* allocate extended descriptor */ 150762306a36Sopenharmony_ci edesc = skcipher_edesc_alloc(req); 150862306a36Sopenharmony_ci if (IS_ERR(edesc)) 150962306a36Sopenharmony_ci return PTR_ERR(edesc); 151062306a36Sopenharmony_ci 151162306a36Sopenharmony_ci caam_req->flc = &ctx->flc[ENCRYPT]; 151262306a36Sopenharmony_ci caam_req->flc_dma = ctx->flc_dma[ENCRYPT]; 151362306a36Sopenharmony_ci caam_req->cbk = skcipher_encrypt_done; 151462306a36Sopenharmony_ci caam_req->ctx = &req->base; 151562306a36Sopenharmony_ci caam_req->edesc = edesc; 151662306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, caam_req); 151762306a36Sopenharmony_ci if (ret != -EINPROGRESS && 151862306a36Sopenharmony_ci !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { 151962306a36Sopenharmony_ci skcipher_unmap(ctx->dev, edesc, req); 152062306a36Sopenharmony_ci qi_cache_free(edesc); 152162306a36Sopenharmony_ci } 152262306a36Sopenharmony_ci 152362306a36Sopenharmony_ci return ret; 152462306a36Sopenharmony_ci} 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_cistatic int skcipher_decrypt(struct skcipher_request *req) 152762306a36Sopenharmony_ci{ 152862306a36Sopenharmony_ci struct skcipher_edesc *edesc; 152962306a36Sopenharmony_ci struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); 153062306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_skcipher_ctx_dma(skcipher); 153162306a36Sopenharmony_ci struct caam_request *caam_req = skcipher_request_ctx_dma(req); 153262306a36Sopenharmony_ci struct dpaa2_caam_priv *priv = dev_get_drvdata(ctx->dev); 153362306a36Sopenharmony_ci int ret; 153462306a36Sopenharmony_ci 153562306a36Sopenharmony_ci /* 153662306a36Sopenharmony_ci * XTS is expected to return an error even for input length = 0 153762306a36Sopenharmony_ci * Note that the case input length < block size will be caught during 153862306a36Sopenharmony_ci * HW offloading and return an error. 153962306a36Sopenharmony_ci */ 154062306a36Sopenharmony_ci if (!req->cryptlen && !ctx->fallback) 154162306a36Sopenharmony_ci return 0; 154262306a36Sopenharmony_ci 154362306a36Sopenharmony_ci if (ctx->fallback && ((priv->sec_attr.era <= 8 && xts_skcipher_ivsize(req)) || 154462306a36Sopenharmony_ci ctx->xts_key_fallback)) { 154562306a36Sopenharmony_ci skcipher_request_set_tfm(&caam_req->fallback_req, ctx->fallback); 154662306a36Sopenharmony_ci skcipher_request_set_callback(&caam_req->fallback_req, 154762306a36Sopenharmony_ci req->base.flags, 154862306a36Sopenharmony_ci req->base.complete, 154962306a36Sopenharmony_ci req->base.data); 155062306a36Sopenharmony_ci skcipher_request_set_crypt(&caam_req->fallback_req, req->src, 155162306a36Sopenharmony_ci req->dst, req->cryptlen, req->iv); 155262306a36Sopenharmony_ci 155362306a36Sopenharmony_ci return crypto_skcipher_decrypt(&caam_req->fallback_req); 155462306a36Sopenharmony_ci } 155562306a36Sopenharmony_ci 155662306a36Sopenharmony_ci /* allocate extended descriptor */ 155762306a36Sopenharmony_ci edesc = skcipher_edesc_alloc(req); 155862306a36Sopenharmony_ci if (IS_ERR(edesc)) 155962306a36Sopenharmony_ci return PTR_ERR(edesc); 156062306a36Sopenharmony_ci 156162306a36Sopenharmony_ci caam_req->flc = &ctx->flc[DECRYPT]; 156262306a36Sopenharmony_ci caam_req->flc_dma = ctx->flc_dma[DECRYPT]; 156362306a36Sopenharmony_ci caam_req->cbk = skcipher_decrypt_done; 156462306a36Sopenharmony_ci caam_req->ctx = &req->base; 156562306a36Sopenharmony_ci caam_req->edesc = edesc; 156662306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, caam_req); 156762306a36Sopenharmony_ci if (ret != -EINPROGRESS && 156862306a36Sopenharmony_ci !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { 156962306a36Sopenharmony_ci skcipher_unmap(ctx->dev, edesc, req); 157062306a36Sopenharmony_ci qi_cache_free(edesc); 157162306a36Sopenharmony_ci } 157262306a36Sopenharmony_ci 157362306a36Sopenharmony_ci return ret; 157462306a36Sopenharmony_ci} 157562306a36Sopenharmony_ci 157662306a36Sopenharmony_cistatic int caam_cra_init(struct caam_ctx *ctx, struct caam_alg_entry *caam, 157762306a36Sopenharmony_ci bool uses_dkp) 157862306a36Sopenharmony_ci{ 157962306a36Sopenharmony_ci dma_addr_t dma_addr; 158062306a36Sopenharmony_ci int i; 158162306a36Sopenharmony_ci 158262306a36Sopenharmony_ci /* copy descriptor header template value */ 158362306a36Sopenharmony_ci ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type; 158462306a36Sopenharmony_ci ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type; 158562306a36Sopenharmony_ci 158662306a36Sopenharmony_ci ctx->dev = caam->dev; 158762306a36Sopenharmony_ci ctx->dir = uses_dkp ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE; 158862306a36Sopenharmony_ci 158962306a36Sopenharmony_ci dma_addr = dma_map_single_attrs(ctx->dev, ctx->flc, 159062306a36Sopenharmony_ci offsetof(struct caam_ctx, flc_dma), 159162306a36Sopenharmony_ci ctx->dir, DMA_ATTR_SKIP_CPU_SYNC); 159262306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, dma_addr)) { 159362306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map key, shared descriptors\n"); 159462306a36Sopenharmony_ci return -ENOMEM; 159562306a36Sopenharmony_ci } 159662306a36Sopenharmony_ci 159762306a36Sopenharmony_ci for (i = 0; i < NUM_OP; i++) 159862306a36Sopenharmony_ci ctx->flc_dma[i] = dma_addr + i * sizeof(ctx->flc[i]); 159962306a36Sopenharmony_ci ctx->key_dma = dma_addr + NUM_OP * sizeof(ctx->flc[0]); 160062306a36Sopenharmony_ci 160162306a36Sopenharmony_ci return 0; 160262306a36Sopenharmony_ci} 160362306a36Sopenharmony_ci 160462306a36Sopenharmony_cistatic int caam_cra_init_skcipher(struct crypto_skcipher *tfm) 160562306a36Sopenharmony_ci{ 160662306a36Sopenharmony_ci struct skcipher_alg *alg = crypto_skcipher_alg(tfm); 160762306a36Sopenharmony_ci struct caam_skcipher_alg *caam_alg = 160862306a36Sopenharmony_ci container_of(alg, typeof(*caam_alg), skcipher); 160962306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_skcipher_ctx_dma(tfm); 161062306a36Sopenharmony_ci u32 alg_aai = caam_alg->caam.class1_alg_type & OP_ALG_AAI_MASK; 161162306a36Sopenharmony_ci int ret = 0; 161262306a36Sopenharmony_ci 161362306a36Sopenharmony_ci if (alg_aai == OP_ALG_AAI_XTS) { 161462306a36Sopenharmony_ci const char *tfm_name = crypto_tfm_alg_name(&tfm->base); 161562306a36Sopenharmony_ci struct crypto_skcipher *fallback; 161662306a36Sopenharmony_ci 161762306a36Sopenharmony_ci fallback = crypto_alloc_skcipher(tfm_name, 0, 161862306a36Sopenharmony_ci CRYPTO_ALG_NEED_FALLBACK); 161962306a36Sopenharmony_ci if (IS_ERR(fallback)) { 162062306a36Sopenharmony_ci dev_err(caam_alg->caam.dev, 162162306a36Sopenharmony_ci "Failed to allocate %s fallback: %ld\n", 162262306a36Sopenharmony_ci tfm_name, PTR_ERR(fallback)); 162362306a36Sopenharmony_ci return PTR_ERR(fallback); 162462306a36Sopenharmony_ci } 162562306a36Sopenharmony_ci 162662306a36Sopenharmony_ci ctx->fallback = fallback; 162762306a36Sopenharmony_ci crypto_skcipher_set_reqsize_dma( 162862306a36Sopenharmony_ci tfm, sizeof(struct caam_request) + 162962306a36Sopenharmony_ci crypto_skcipher_reqsize(fallback)); 163062306a36Sopenharmony_ci } else { 163162306a36Sopenharmony_ci crypto_skcipher_set_reqsize_dma(tfm, 163262306a36Sopenharmony_ci sizeof(struct caam_request)); 163362306a36Sopenharmony_ci } 163462306a36Sopenharmony_ci 163562306a36Sopenharmony_ci ret = caam_cra_init(ctx, &caam_alg->caam, false); 163662306a36Sopenharmony_ci if (ret && ctx->fallback) 163762306a36Sopenharmony_ci crypto_free_skcipher(ctx->fallback); 163862306a36Sopenharmony_ci 163962306a36Sopenharmony_ci return ret; 164062306a36Sopenharmony_ci} 164162306a36Sopenharmony_ci 164262306a36Sopenharmony_cistatic int caam_cra_init_aead(struct crypto_aead *tfm) 164362306a36Sopenharmony_ci{ 164462306a36Sopenharmony_ci struct aead_alg *alg = crypto_aead_alg(tfm); 164562306a36Sopenharmony_ci struct caam_aead_alg *caam_alg = container_of(alg, typeof(*caam_alg), 164662306a36Sopenharmony_ci aead); 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_ci crypto_aead_set_reqsize_dma(tfm, sizeof(struct caam_request)); 164962306a36Sopenharmony_ci return caam_cra_init(crypto_aead_ctx_dma(tfm), &caam_alg->caam, 165062306a36Sopenharmony_ci !caam_alg->caam.nodkp); 165162306a36Sopenharmony_ci} 165262306a36Sopenharmony_ci 165362306a36Sopenharmony_cistatic void caam_exit_common(struct caam_ctx *ctx) 165462306a36Sopenharmony_ci{ 165562306a36Sopenharmony_ci dma_unmap_single_attrs(ctx->dev, ctx->flc_dma[0], 165662306a36Sopenharmony_ci offsetof(struct caam_ctx, flc_dma), ctx->dir, 165762306a36Sopenharmony_ci DMA_ATTR_SKIP_CPU_SYNC); 165862306a36Sopenharmony_ci} 165962306a36Sopenharmony_ci 166062306a36Sopenharmony_cistatic void caam_cra_exit(struct crypto_skcipher *tfm) 166162306a36Sopenharmony_ci{ 166262306a36Sopenharmony_ci struct caam_ctx *ctx = crypto_skcipher_ctx_dma(tfm); 166362306a36Sopenharmony_ci 166462306a36Sopenharmony_ci if (ctx->fallback) 166562306a36Sopenharmony_ci crypto_free_skcipher(ctx->fallback); 166662306a36Sopenharmony_ci caam_exit_common(ctx); 166762306a36Sopenharmony_ci} 166862306a36Sopenharmony_ci 166962306a36Sopenharmony_cistatic void caam_cra_exit_aead(struct crypto_aead *tfm) 167062306a36Sopenharmony_ci{ 167162306a36Sopenharmony_ci caam_exit_common(crypto_aead_ctx_dma(tfm)); 167262306a36Sopenharmony_ci} 167362306a36Sopenharmony_ci 167462306a36Sopenharmony_cistatic struct caam_skcipher_alg driver_algs[] = { 167562306a36Sopenharmony_ci { 167662306a36Sopenharmony_ci .skcipher = { 167762306a36Sopenharmony_ci .base = { 167862306a36Sopenharmony_ci .cra_name = "cbc(aes)", 167962306a36Sopenharmony_ci .cra_driver_name = "cbc-aes-caam-qi2", 168062306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 168162306a36Sopenharmony_ci }, 168262306a36Sopenharmony_ci .setkey = aes_skcipher_setkey, 168362306a36Sopenharmony_ci .encrypt = skcipher_encrypt, 168462306a36Sopenharmony_ci .decrypt = skcipher_decrypt, 168562306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 168662306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 168762306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 168862306a36Sopenharmony_ci }, 168962306a36Sopenharmony_ci .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 169062306a36Sopenharmony_ci }, 169162306a36Sopenharmony_ci { 169262306a36Sopenharmony_ci .skcipher = { 169362306a36Sopenharmony_ci .base = { 169462306a36Sopenharmony_ci .cra_name = "cbc(des3_ede)", 169562306a36Sopenharmony_ci .cra_driver_name = "cbc-3des-caam-qi2", 169662306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 169762306a36Sopenharmony_ci }, 169862306a36Sopenharmony_ci .setkey = des3_skcipher_setkey, 169962306a36Sopenharmony_ci .encrypt = skcipher_encrypt, 170062306a36Sopenharmony_ci .decrypt = skcipher_decrypt, 170162306a36Sopenharmony_ci .min_keysize = DES3_EDE_KEY_SIZE, 170262306a36Sopenharmony_ci .max_keysize = DES3_EDE_KEY_SIZE, 170362306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 170462306a36Sopenharmony_ci }, 170562306a36Sopenharmony_ci .caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 170662306a36Sopenharmony_ci }, 170762306a36Sopenharmony_ci { 170862306a36Sopenharmony_ci .skcipher = { 170962306a36Sopenharmony_ci .base = { 171062306a36Sopenharmony_ci .cra_name = "cbc(des)", 171162306a36Sopenharmony_ci .cra_driver_name = "cbc-des-caam-qi2", 171262306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 171362306a36Sopenharmony_ci }, 171462306a36Sopenharmony_ci .setkey = des_skcipher_setkey, 171562306a36Sopenharmony_ci .encrypt = skcipher_encrypt, 171662306a36Sopenharmony_ci .decrypt = skcipher_decrypt, 171762306a36Sopenharmony_ci .min_keysize = DES_KEY_SIZE, 171862306a36Sopenharmony_ci .max_keysize = DES_KEY_SIZE, 171962306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 172062306a36Sopenharmony_ci }, 172162306a36Sopenharmony_ci .caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 172262306a36Sopenharmony_ci }, 172362306a36Sopenharmony_ci { 172462306a36Sopenharmony_ci .skcipher = { 172562306a36Sopenharmony_ci .base = { 172662306a36Sopenharmony_ci .cra_name = "ctr(aes)", 172762306a36Sopenharmony_ci .cra_driver_name = "ctr-aes-caam-qi2", 172862306a36Sopenharmony_ci .cra_blocksize = 1, 172962306a36Sopenharmony_ci }, 173062306a36Sopenharmony_ci .setkey = ctr_skcipher_setkey, 173162306a36Sopenharmony_ci .encrypt = skcipher_encrypt, 173262306a36Sopenharmony_ci .decrypt = skcipher_decrypt, 173362306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE, 173462306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE, 173562306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 173662306a36Sopenharmony_ci .chunksize = AES_BLOCK_SIZE, 173762306a36Sopenharmony_ci }, 173862306a36Sopenharmony_ci .caam.class1_alg_type = OP_ALG_ALGSEL_AES | 173962306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 174062306a36Sopenharmony_ci }, 174162306a36Sopenharmony_ci { 174262306a36Sopenharmony_ci .skcipher = { 174362306a36Sopenharmony_ci .base = { 174462306a36Sopenharmony_ci .cra_name = "rfc3686(ctr(aes))", 174562306a36Sopenharmony_ci .cra_driver_name = "rfc3686-ctr-aes-caam-qi2", 174662306a36Sopenharmony_ci .cra_blocksize = 1, 174762306a36Sopenharmony_ci }, 174862306a36Sopenharmony_ci .setkey = rfc3686_skcipher_setkey, 174962306a36Sopenharmony_ci .encrypt = skcipher_encrypt, 175062306a36Sopenharmony_ci .decrypt = skcipher_decrypt, 175162306a36Sopenharmony_ci .min_keysize = AES_MIN_KEY_SIZE + 175262306a36Sopenharmony_ci CTR_RFC3686_NONCE_SIZE, 175362306a36Sopenharmony_ci .max_keysize = AES_MAX_KEY_SIZE + 175462306a36Sopenharmony_ci CTR_RFC3686_NONCE_SIZE, 175562306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 175662306a36Sopenharmony_ci .chunksize = AES_BLOCK_SIZE, 175762306a36Sopenharmony_ci }, 175862306a36Sopenharmony_ci .caam = { 175962306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 176062306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 176162306a36Sopenharmony_ci .rfc3686 = true, 176262306a36Sopenharmony_ci }, 176362306a36Sopenharmony_ci }, 176462306a36Sopenharmony_ci { 176562306a36Sopenharmony_ci .skcipher = { 176662306a36Sopenharmony_ci .base = { 176762306a36Sopenharmony_ci .cra_name = "xts(aes)", 176862306a36Sopenharmony_ci .cra_driver_name = "xts-aes-caam-qi2", 176962306a36Sopenharmony_ci .cra_flags = CRYPTO_ALG_NEED_FALLBACK, 177062306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 177162306a36Sopenharmony_ci }, 177262306a36Sopenharmony_ci .setkey = xts_skcipher_setkey, 177362306a36Sopenharmony_ci .encrypt = skcipher_encrypt, 177462306a36Sopenharmony_ci .decrypt = skcipher_decrypt, 177562306a36Sopenharmony_ci .min_keysize = 2 * AES_MIN_KEY_SIZE, 177662306a36Sopenharmony_ci .max_keysize = 2 * AES_MAX_KEY_SIZE, 177762306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 177862306a36Sopenharmony_ci }, 177962306a36Sopenharmony_ci .caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS, 178062306a36Sopenharmony_ci }, 178162306a36Sopenharmony_ci { 178262306a36Sopenharmony_ci .skcipher = { 178362306a36Sopenharmony_ci .base = { 178462306a36Sopenharmony_ci .cra_name = "chacha20", 178562306a36Sopenharmony_ci .cra_driver_name = "chacha20-caam-qi2", 178662306a36Sopenharmony_ci .cra_blocksize = 1, 178762306a36Sopenharmony_ci }, 178862306a36Sopenharmony_ci .setkey = chacha20_skcipher_setkey, 178962306a36Sopenharmony_ci .encrypt = skcipher_encrypt, 179062306a36Sopenharmony_ci .decrypt = skcipher_decrypt, 179162306a36Sopenharmony_ci .min_keysize = CHACHA_KEY_SIZE, 179262306a36Sopenharmony_ci .max_keysize = CHACHA_KEY_SIZE, 179362306a36Sopenharmony_ci .ivsize = CHACHA_IV_SIZE, 179462306a36Sopenharmony_ci }, 179562306a36Sopenharmony_ci .caam.class1_alg_type = OP_ALG_ALGSEL_CHACHA20, 179662306a36Sopenharmony_ci }, 179762306a36Sopenharmony_ci}; 179862306a36Sopenharmony_ci 179962306a36Sopenharmony_cistatic struct caam_aead_alg driver_aeads[] = { 180062306a36Sopenharmony_ci { 180162306a36Sopenharmony_ci .aead = { 180262306a36Sopenharmony_ci .base = { 180362306a36Sopenharmony_ci .cra_name = "rfc4106(gcm(aes))", 180462306a36Sopenharmony_ci .cra_driver_name = "rfc4106-gcm-aes-caam-qi2", 180562306a36Sopenharmony_ci .cra_blocksize = 1, 180662306a36Sopenharmony_ci }, 180762306a36Sopenharmony_ci .setkey = rfc4106_setkey, 180862306a36Sopenharmony_ci .setauthsize = rfc4106_setauthsize, 180962306a36Sopenharmony_ci .encrypt = ipsec_gcm_encrypt, 181062306a36Sopenharmony_ci .decrypt = ipsec_gcm_decrypt, 181162306a36Sopenharmony_ci .ivsize = 8, 181262306a36Sopenharmony_ci .maxauthsize = AES_BLOCK_SIZE, 181362306a36Sopenharmony_ci }, 181462306a36Sopenharmony_ci .caam = { 181562306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, 181662306a36Sopenharmony_ci .nodkp = true, 181762306a36Sopenharmony_ci }, 181862306a36Sopenharmony_ci }, 181962306a36Sopenharmony_ci { 182062306a36Sopenharmony_ci .aead = { 182162306a36Sopenharmony_ci .base = { 182262306a36Sopenharmony_ci .cra_name = "rfc4543(gcm(aes))", 182362306a36Sopenharmony_ci .cra_driver_name = "rfc4543-gcm-aes-caam-qi2", 182462306a36Sopenharmony_ci .cra_blocksize = 1, 182562306a36Sopenharmony_ci }, 182662306a36Sopenharmony_ci .setkey = rfc4543_setkey, 182762306a36Sopenharmony_ci .setauthsize = rfc4543_setauthsize, 182862306a36Sopenharmony_ci .encrypt = ipsec_gcm_encrypt, 182962306a36Sopenharmony_ci .decrypt = ipsec_gcm_decrypt, 183062306a36Sopenharmony_ci .ivsize = 8, 183162306a36Sopenharmony_ci .maxauthsize = AES_BLOCK_SIZE, 183262306a36Sopenharmony_ci }, 183362306a36Sopenharmony_ci .caam = { 183462306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, 183562306a36Sopenharmony_ci .nodkp = true, 183662306a36Sopenharmony_ci }, 183762306a36Sopenharmony_ci }, 183862306a36Sopenharmony_ci /* Galois Counter Mode */ 183962306a36Sopenharmony_ci { 184062306a36Sopenharmony_ci .aead = { 184162306a36Sopenharmony_ci .base = { 184262306a36Sopenharmony_ci .cra_name = "gcm(aes)", 184362306a36Sopenharmony_ci .cra_driver_name = "gcm-aes-caam-qi2", 184462306a36Sopenharmony_ci .cra_blocksize = 1, 184562306a36Sopenharmony_ci }, 184662306a36Sopenharmony_ci .setkey = gcm_setkey, 184762306a36Sopenharmony_ci .setauthsize = gcm_setauthsize, 184862306a36Sopenharmony_ci .encrypt = aead_encrypt, 184962306a36Sopenharmony_ci .decrypt = aead_decrypt, 185062306a36Sopenharmony_ci .ivsize = 12, 185162306a36Sopenharmony_ci .maxauthsize = AES_BLOCK_SIZE, 185262306a36Sopenharmony_ci }, 185362306a36Sopenharmony_ci .caam = { 185462306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM, 185562306a36Sopenharmony_ci .nodkp = true, 185662306a36Sopenharmony_ci } 185762306a36Sopenharmony_ci }, 185862306a36Sopenharmony_ci /* single-pass ipsec_esp descriptor */ 185962306a36Sopenharmony_ci { 186062306a36Sopenharmony_ci .aead = { 186162306a36Sopenharmony_ci .base = { 186262306a36Sopenharmony_ci .cra_name = "authenc(hmac(md5),cbc(aes))", 186362306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-md5-" 186462306a36Sopenharmony_ci "cbc-aes-caam-qi2", 186562306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 186662306a36Sopenharmony_ci }, 186762306a36Sopenharmony_ci .setkey = aead_setkey, 186862306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 186962306a36Sopenharmony_ci .encrypt = aead_encrypt, 187062306a36Sopenharmony_ci .decrypt = aead_decrypt, 187162306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 187262306a36Sopenharmony_ci .maxauthsize = MD5_DIGEST_SIZE, 187362306a36Sopenharmony_ci }, 187462306a36Sopenharmony_ci .caam = { 187562306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 187662306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_MD5 | 187762306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 187862306a36Sopenharmony_ci } 187962306a36Sopenharmony_ci }, 188062306a36Sopenharmony_ci { 188162306a36Sopenharmony_ci .aead = { 188262306a36Sopenharmony_ci .base = { 188362306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(md5)," 188462306a36Sopenharmony_ci "cbc(aes)))", 188562306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-hmac-md5-" 188662306a36Sopenharmony_ci "cbc-aes-caam-qi2", 188762306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 188862306a36Sopenharmony_ci }, 188962306a36Sopenharmony_ci .setkey = aead_setkey, 189062306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 189162306a36Sopenharmony_ci .encrypt = aead_encrypt, 189262306a36Sopenharmony_ci .decrypt = aead_decrypt, 189362306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 189462306a36Sopenharmony_ci .maxauthsize = MD5_DIGEST_SIZE, 189562306a36Sopenharmony_ci }, 189662306a36Sopenharmony_ci .caam = { 189762306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 189862306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_MD5 | 189962306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 190062306a36Sopenharmony_ci .geniv = true, 190162306a36Sopenharmony_ci } 190262306a36Sopenharmony_ci }, 190362306a36Sopenharmony_ci { 190462306a36Sopenharmony_ci .aead = { 190562306a36Sopenharmony_ci .base = { 190662306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha1),cbc(aes))", 190762306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha1-" 190862306a36Sopenharmony_ci "cbc-aes-caam-qi2", 190962306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 191062306a36Sopenharmony_ci }, 191162306a36Sopenharmony_ci .setkey = aead_setkey, 191262306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 191362306a36Sopenharmony_ci .encrypt = aead_encrypt, 191462306a36Sopenharmony_ci .decrypt = aead_decrypt, 191562306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 191662306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 191762306a36Sopenharmony_ci }, 191862306a36Sopenharmony_ci .caam = { 191962306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 192062306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA1 | 192162306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 192262306a36Sopenharmony_ci } 192362306a36Sopenharmony_ci }, 192462306a36Sopenharmony_ci { 192562306a36Sopenharmony_ci .aead = { 192662306a36Sopenharmony_ci .base = { 192762306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha1)," 192862306a36Sopenharmony_ci "cbc(aes)))", 192962306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 193062306a36Sopenharmony_ci "hmac-sha1-cbc-aes-caam-qi2", 193162306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 193262306a36Sopenharmony_ci }, 193362306a36Sopenharmony_ci .setkey = aead_setkey, 193462306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 193562306a36Sopenharmony_ci .encrypt = aead_encrypt, 193662306a36Sopenharmony_ci .decrypt = aead_decrypt, 193762306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 193862306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 193962306a36Sopenharmony_ci }, 194062306a36Sopenharmony_ci .caam = { 194162306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 194262306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA1 | 194362306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 194462306a36Sopenharmony_ci .geniv = true, 194562306a36Sopenharmony_ci }, 194662306a36Sopenharmony_ci }, 194762306a36Sopenharmony_ci { 194862306a36Sopenharmony_ci .aead = { 194962306a36Sopenharmony_ci .base = { 195062306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha224),cbc(aes))", 195162306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha224-" 195262306a36Sopenharmony_ci "cbc-aes-caam-qi2", 195362306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 195462306a36Sopenharmony_ci }, 195562306a36Sopenharmony_ci .setkey = aead_setkey, 195662306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 195762306a36Sopenharmony_ci .encrypt = aead_encrypt, 195862306a36Sopenharmony_ci .decrypt = aead_decrypt, 195962306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 196062306a36Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 196162306a36Sopenharmony_ci }, 196262306a36Sopenharmony_ci .caam = { 196362306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 196462306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA224 | 196562306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 196662306a36Sopenharmony_ci } 196762306a36Sopenharmony_ci }, 196862306a36Sopenharmony_ci { 196962306a36Sopenharmony_ci .aead = { 197062306a36Sopenharmony_ci .base = { 197162306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha224)," 197262306a36Sopenharmony_ci "cbc(aes)))", 197362306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 197462306a36Sopenharmony_ci "hmac-sha224-cbc-aes-caam-qi2", 197562306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 197662306a36Sopenharmony_ci }, 197762306a36Sopenharmony_ci .setkey = aead_setkey, 197862306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 197962306a36Sopenharmony_ci .encrypt = aead_encrypt, 198062306a36Sopenharmony_ci .decrypt = aead_decrypt, 198162306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 198262306a36Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 198362306a36Sopenharmony_ci }, 198462306a36Sopenharmony_ci .caam = { 198562306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 198662306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA224 | 198762306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 198862306a36Sopenharmony_ci .geniv = true, 198962306a36Sopenharmony_ci } 199062306a36Sopenharmony_ci }, 199162306a36Sopenharmony_ci { 199262306a36Sopenharmony_ci .aead = { 199362306a36Sopenharmony_ci .base = { 199462306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha256),cbc(aes))", 199562306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha256-" 199662306a36Sopenharmony_ci "cbc-aes-caam-qi2", 199762306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 199862306a36Sopenharmony_ci }, 199962306a36Sopenharmony_ci .setkey = aead_setkey, 200062306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 200162306a36Sopenharmony_ci .encrypt = aead_encrypt, 200262306a36Sopenharmony_ci .decrypt = aead_decrypt, 200362306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 200462306a36Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 200562306a36Sopenharmony_ci }, 200662306a36Sopenharmony_ci .caam = { 200762306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 200862306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA256 | 200962306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 201062306a36Sopenharmony_ci } 201162306a36Sopenharmony_ci }, 201262306a36Sopenharmony_ci { 201362306a36Sopenharmony_ci .aead = { 201462306a36Sopenharmony_ci .base = { 201562306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha256)," 201662306a36Sopenharmony_ci "cbc(aes)))", 201762306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 201862306a36Sopenharmony_ci "hmac-sha256-cbc-aes-" 201962306a36Sopenharmony_ci "caam-qi2", 202062306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 202162306a36Sopenharmony_ci }, 202262306a36Sopenharmony_ci .setkey = aead_setkey, 202362306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 202462306a36Sopenharmony_ci .encrypt = aead_encrypt, 202562306a36Sopenharmony_ci .decrypt = aead_decrypt, 202662306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 202762306a36Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 202862306a36Sopenharmony_ci }, 202962306a36Sopenharmony_ci .caam = { 203062306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 203162306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA256 | 203262306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 203362306a36Sopenharmony_ci .geniv = true, 203462306a36Sopenharmony_ci } 203562306a36Sopenharmony_ci }, 203662306a36Sopenharmony_ci { 203762306a36Sopenharmony_ci .aead = { 203862306a36Sopenharmony_ci .base = { 203962306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha384),cbc(aes))", 204062306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha384-" 204162306a36Sopenharmony_ci "cbc-aes-caam-qi2", 204262306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 204362306a36Sopenharmony_ci }, 204462306a36Sopenharmony_ci .setkey = aead_setkey, 204562306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 204662306a36Sopenharmony_ci .encrypt = aead_encrypt, 204762306a36Sopenharmony_ci .decrypt = aead_decrypt, 204862306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 204962306a36Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 205062306a36Sopenharmony_ci }, 205162306a36Sopenharmony_ci .caam = { 205262306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 205362306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA384 | 205462306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 205562306a36Sopenharmony_ci } 205662306a36Sopenharmony_ci }, 205762306a36Sopenharmony_ci { 205862306a36Sopenharmony_ci .aead = { 205962306a36Sopenharmony_ci .base = { 206062306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha384)," 206162306a36Sopenharmony_ci "cbc(aes)))", 206262306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 206362306a36Sopenharmony_ci "hmac-sha384-cbc-aes-" 206462306a36Sopenharmony_ci "caam-qi2", 206562306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 206662306a36Sopenharmony_ci }, 206762306a36Sopenharmony_ci .setkey = aead_setkey, 206862306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 206962306a36Sopenharmony_ci .encrypt = aead_encrypt, 207062306a36Sopenharmony_ci .decrypt = aead_decrypt, 207162306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 207262306a36Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 207362306a36Sopenharmony_ci }, 207462306a36Sopenharmony_ci .caam = { 207562306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 207662306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA384 | 207762306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 207862306a36Sopenharmony_ci .geniv = true, 207962306a36Sopenharmony_ci } 208062306a36Sopenharmony_ci }, 208162306a36Sopenharmony_ci { 208262306a36Sopenharmony_ci .aead = { 208362306a36Sopenharmony_ci .base = { 208462306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha512),cbc(aes))", 208562306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha512-" 208662306a36Sopenharmony_ci "cbc-aes-caam-qi2", 208762306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 208862306a36Sopenharmony_ci }, 208962306a36Sopenharmony_ci .setkey = aead_setkey, 209062306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 209162306a36Sopenharmony_ci .encrypt = aead_encrypt, 209262306a36Sopenharmony_ci .decrypt = aead_decrypt, 209362306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 209462306a36Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 209562306a36Sopenharmony_ci }, 209662306a36Sopenharmony_ci .caam = { 209762306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 209862306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA512 | 209962306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 210062306a36Sopenharmony_ci } 210162306a36Sopenharmony_ci }, 210262306a36Sopenharmony_ci { 210362306a36Sopenharmony_ci .aead = { 210462306a36Sopenharmony_ci .base = { 210562306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha512)," 210662306a36Sopenharmony_ci "cbc(aes)))", 210762306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 210862306a36Sopenharmony_ci "hmac-sha512-cbc-aes-" 210962306a36Sopenharmony_ci "caam-qi2", 211062306a36Sopenharmony_ci .cra_blocksize = AES_BLOCK_SIZE, 211162306a36Sopenharmony_ci }, 211262306a36Sopenharmony_ci .setkey = aead_setkey, 211362306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 211462306a36Sopenharmony_ci .encrypt = aead_encrypt, 211562306a36Sopenharmony_ci .decrypt = aead_decrypt, 211662306a36Sopenharmony_ci .ivsize = AES_BLOCK_SIZE, 211762306a36Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 211862306a36Sopenharmony_ci }, 211962306a36Sopenharmony_ci .caam = { 212062306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, 212162306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA512 | 212262306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 212362306a36Sopenharmony_ci .geniv = true, 212462306a36Sopenharmony_ci } 212562306a36Sopenharmony_ci }, 212662306a36Sopenharmony_ci { 212762306a36Sopenharmony_ci .aead = { 212862306a36Sopenharmony_ci .base = { 212962306a36Sopenharmony_ci .cra_name = "authenc(hmac(md5),cbc(des3_ede))", 213062306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-md5-" 213162306a36Sopenharmony_ci "cbc-des3_ede-caam-qi2", 213262306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 213362306a36Sopenharmony_ci }, 213462306a36Sopenharmony_ci .setkey = des3_aead_setkey, 213562306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 213662306a36Sopenharmony_ci .encrypt = aead_encrypt, 213762306a36Sopenharmony_ci .decrypt = aead_decrypt, 213862306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 213962306a36Sopenharmony_ci .maxauthsize = MD5_DIGEST_SIZE, 214062306a36Sopenharmony_ci }, 214162306a36Sopenharmony_ci .caam = { 214262306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 214362306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_MD5 | 214462306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 214562306a36Sopenharmony_ci } 214662306a36Sopenharmony_ci }, 214762306a36Sopenharmony_ci { 214862306a36Sopenharmony_ci .aead = { 214962306a36Sopenharmony_ci .base = { 215062306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(md5)," 215162306a36Sopenharmony_ci "cbc(des3_ede)))", 215262306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-hmac-md5-" 215362306a36Sopenharmony_ci "cbc-des3_ede-caam-qi2", 215462306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 215562306a36Sopenharmony_ci }, 215662306a36Sopenharmony_ci .setkey = des3_aead_setkey, 215762306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 215862306a36Sopenharmony_ci .encrypt = aead_encrypt, 215962306a36Sopenharmony_ci .decrypt = aead_decrypt, 216062306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 216162306a36Sopenharmony_ci .maxauthsize = MD5_DIGEST_SIZE, 216262306a36Sopenharmony_ci }, 216362306a36Sopenharmony_ci .caam = { 216462306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 216562306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_MD5 | 216662306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 216762306a36Sopenharmony_ci .geniv = true, 216862306a36Sopenharmony_ci } 216962306a36Sopenharmony_ci }, 217062306a36Sopenharmony_ci { 217162306a36Sopenharmony_ci .aead = { 217262306a36Sopenharmony_ci .base = { 217362306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha1)," 217462306a36Sopenharmony_ci "cbc(des3_ede))", 217562306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha1-" 217662306a36Sopenharmony_ci "cbc-des3_ede-caam-qi2", 217762306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 217862306a36Sopenharmony_ci }, 217962306a36Sopenharmony_ci .setkey = des3_aead_setkey, 218062306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 218162306a36Sopenharmony_ci .encrypt = aead_encrypt, 218262306a36Sopenharmony_ci .decrypt = aead_decrypt, 218362306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 218462306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 218562306a36Sopenharmony_ci }, 218662306a36Sopenharmony_ci .caam = { 218762306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 218862306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA1 | 218962306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 219062306a36Sopenharmony_ci }, 219162306a36Sopenharmony_ci }, 219262306a36Sopenharmony_ci { 219362306a36Sopenharmony_ci .aead = { 219462306a36Sopenharmony_ci .base = { 219562306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha1)," 219662306a36Sopenharmony_ci "cbc(des3_ede)))", 219762306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 219862306a36Sopenharmony_ci "hmac-sha1-" 219962306a36Sopenharmony_ci "cbc-des3_ede-caam-qi2", 220062306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 220162306a36Sopenharmony_ci }, 220262306a36Sopenharmony_ci .setkey = des3_aead_setkey, 220362306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 220462306a36Sopenharmony_ci .encrypt = aead_encrypt, 220562306a36Sopenharmony_ci .decrypt = aead_decrypt, 220662306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 220762306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 220862306a36Sopenharmony_ci }, 220962306a36Sopenharmony_ci .caam = { 221062306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 221162306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA1 | 221262306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 221362306a36Sopenharmony_ci .geniv = true, 221462306a36Sopenharmony_ci } 221562306a36Sopenharmony_ci }, 221662306a36Sopenharmony_ci { 221762306a36Sopenharmony_ci .aead = { 221862306a36Sopenharmony_ci .base = { 221962306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha224)," 222062306a36Sopenharmony_ci "cbc(des3_ede))", 222162306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha224-" 222262306a36Sopenharmony_ci "cbc-des3_ede-caam-qi2", 222362306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 222462306a36Sopenharmony_ci }, 222562306a36Sopenharmony_ci .setkey = des3_aead_setkey, 222662306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 222762306a36Sopenharmony_ci .encrypt = aead_encrypt, 222862306a36Sopenharmony_ci .decrypt = aead_decrypt, 222962306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 223062306a36Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 223162306a36Sopenharmony_ci }, 223262306a36Sopenharmony_ci .caam = { 223362306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 223462306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA224 | 223562306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 223662306a36Sopenharmony_ci }, 223762306a36Sopenharmony_ci }, 223862306a36Sopenharmony_ci { 223962306a36Sopenharmony_ci .aead = { 224062306a36Sopenharmony_ci .base = { 224162306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha224)," 224262306a36Sopenharmony_ci "cbc(des3_ede)))", 224362306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 224462306a36Sopenharmony_ci "hmac-sha224-" 224562306a36Sopenharmony_ci "cbc-des3_ede-caam-qi2", 224662306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 224762306a36Sopenharmony_ci }, 224862306a36Sopenharmony_ci .setkey = des3_aead_setkey, 224962306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 225062306a36Sopenharmony_ci .encrypt = aead_encrypt, 225162306a36Sopenharmony_ci .decrypt = aead_decrypt, 225262306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 225362306a36Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 225462306a36Sopenharmony_ci }, 225562306a36Sopenharmony_ci .caam = { 225662306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 225762306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA224 | 225862306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 225962306a36Sopenharmony_ci .geniv = true, 226062306a36Sopenharmony_ci } 226162306a36Sopenharmony_ci }, 226262306a36Sopenharmony_ci { 226362306a36Sopenharmony_ci .aead = { 226462306a36Sopenharmony_ci .base = { 226562306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha256)," 226662306a36Sopenharmony_ci "cbc(des3_ede))", 226762306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha256-" 226862306a36Sopenharmony_ci "cbc-des3_ede-caam-qi2", 226962306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 227062306a36Sopenharmony_ci }, 227162306a36Sopenharmony_ci .setkey = des3_aead_setkey, 227262306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 227362306a36Sopenharmony_ci .encrypt = aead_encrypt, 227462306a36Sopenharmony_ci .decrypt = aead_decrypt, 227562306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 227662306a36Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 227762306a36Sopenharmony_ci }, 227862306a36Sopenharmony_ci .caam = { 227962306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 228062306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA256 | 228162306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 228262306a36Sopenharmony_ci }, 228362306a36Sopenharmony_ci }, 228462306a36Sopenharmony_ci { 228562306a36Sopenharmony_ci .aead = { 228662306a36Sopenharmony_ci .base = { 228762306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha256)," 228862306a36Sopenharmony_ci "cbc(des3_ede)))", 228962306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 229062306a36Sopenharmony_ci "hmac-sha256-" 229162306a36Sopenharmony_ci "cbc-des3_ede-caam-qi2", 229262306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 229362306a36Sopenharmony_ci }, 229462306a36Sopenharmony_ci .setkey = des3_aead_setkey, 229562306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 229662306a36Sopenharmony_ci .encrypt = aead_encrypt, 229762306a36Sopenharmony_ci .decrypt = aead_decrypt, 229862306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 229962306a36Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 230062306a36Sopenharmony_ci }, 230162306a36Sopenharmony_ci .caam = { 230262306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 230362306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA256 | 230462306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 230562306a36Sopenharmony_ci .geniv = true, 230662306a36Sopenharmony_ci } 230762306a36Sopenharmony_ci }, 230862306a36Sopenharmony_ci { 230962306a36Sopenharmony_ci .aead = { 231062306a36Sopenharmony_ci .base = { 231162306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha384)," 231262306a36Sopenharmony_ci "cbc(des3_ede))", 231362306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha384-" 231462306a36Sopenharmony_ci "cbc-des3_ede-caam-qi2", 231562306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 231662306a36Sopenharmony_ci }, 231762306a36Sopenharmony_ci .setkey = des3_aead_setkey, 231862306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 231962306a36Sopenharmony_ci .encrypt = aead_encrypt, 232062306a36Sopenharmony_ci .decrypt = aead_decrypt, 232162306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 232262306a36Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 232362306a36Sopenharmony_ci }, 232462306a36Sopenharmony_ci .caam = { 232562306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 232662306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA384 | 232762306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 232862306a36Sopenharmony_ci }, 232962306a36Sopenharmony_ci }, 233062306a36Sopenharmony_ci { 233162306a36Sopenharmony_ci .aead = { 233262306a36Sopenharmony_ci .base = { 233362306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha384)," 233462306a36Sopenharmony_ci "cbc(des3_ede)))", 233562306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 233662306a36Sopenharmony_ci "hmac-sha384-" 233762306a36Sopenharmony_ci "cbc-des3_ede-caam-qi2", 233862306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 233962306a36Sopenharmony_ci }, 234062306a36Sopenharmony_ci .setkey = des3_aead_setkey, 234162306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 234262306a36Sopenharmony_ci .encrypt = aead_encrypt, 234362306a36Sopenharmony_ci .decrypt = aead_decrypt, 234462306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 234562306a36Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 234662306a36Sopenharmony_ci }, 234762306a36Sopenharmony_ci .caam = { 234862306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 234962306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA384 | 235062306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 235162306a36Sopenharmony_ci .geniv = true, 235262306a36Sopenharmony_ci } 235362306a36Sopenharmony_ci }, 235462306a36Sopenharmony_ci { 235562306a36Sopenharmony_ci .aead = { 235662306a36Sopenharmony_ci .base = { 235762306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha512)," 235862306a36Sopenharmony_ci "cbc(des3_ede))", 235962306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha512-" 236062306a36Sopenharmony_ci "cbc-des3_ede-caam-qi2", 236162306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 236262306a36Sopenharmony_ci }, 236362306a36Sopenharmony_ci .setkey = des3_aead_setkey, 236462306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 236562306a36Sopenharmony_ci .encrypt = aead_encrypt, 236662306a36Sopenharmony_ci .decrypt = aead_decrypt, 236762306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 236862306a36Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 236962306a36Sopenharmony_ci }, 237062306a36Sopenharmony_ci .caam = { 237162306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 237262306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA512 | 237362306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 237462306a36Sopenharmony_ci }, 237562306a36Sopenharmony_ci }, 237662306a36Sopenharmony_ci { 237762306a36Sopenharmony_ci .aead = { 237862306a36Sopenharmony_ci .base = { 237962306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha512)," 238062306a36Sopenharmony_ci "cbc(des3_ede)))", 238162306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 238262306a36Sopenharmony_ci "hmac-sha512-" 238362306a36Sopenharmony_ci "cbc-des3_ede-caam-qi2", 238462306a36Sopenharmony_ci .cra_blocksize = DES3_EDE_BLOCK_SIZE, 238562306a36Sopenharmony_ci }, 238662306a36Sopenharmony_ci .setkey = des3_aead_setkey, 238762306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 238862306a36Sopenharmony_ci .encrypt = aead_encrypt, 238962306a36Sopenharmony_ci .decrypt = aead_decrypt, 239062306a36Sopenharmony_ci .ivsize = DES3_EDE_BLOCK_SIZE, 239162306a36Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 239262306a36Sopenharmony_ci }, 239362306a36Sopenharmony_ci .caam = { 239462306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, 239562306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA512 | 239662306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 239762306a36Sopenharmony_ci .geniv = true, 239862306a36Sopenharmony_ci } 239962306a36Sopenharmony_ci }, 240062306a36Sopenharmony_ci { 240162306a36Sopenharmony_ci .aead = { 240262306a36Sopenharmony_ci .base = { 240362306a36Sopenharmony_ci .cra_name = "authenc(hmac(md5),cbc(des))", 240462306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-md5-" 240562306a36Sopenharmony_ci "cbc-des-caam-qi2", 240662306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 240762306a36Sopenharmony_ci }, 240862306a36Sopenharmony_ci .setkey = aead_setkey, 240962306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 241062306a36Sopenharmony_ci .encrypt = aead_encrypt, 241162306a36Sopenharmony_ci .decrypt = aead_decrypt, 241262306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 241362306a36Sopenharmony_ci .maxauthsize = MD5_DIGEST_SIZE, 241462306a36Sopenharmony_ci }, 241562306a36Sopenharmony_ci .caam = { 241662306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 241762306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_MD5 | 241862306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 241962306a36Sopenharmony_ci }, 242062306a36Sopenharmony_ci }, 242162306a36Sopenharmony_ci { 242262306a36Sopenharmony_ci .aead = { 242362306a36Sopenharmony_ci .base = { 242462306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(md5)," 242562306a36Sopenharmony_ci "cbc(des)))", 242662306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-hmac-md5-" 242762306a36Sopenharmony_ci "cbc-des-caam-qi2", 242862306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 242962306a36Sopenharmony_ci }, 243062306a36Sopenharmony_ci .setkey = aead_setkey, 243162306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 243262306a36Sopenharmony_ci .encrypt = aead_encrypt, 243362306a36Sopenharmony_ci .decrypt = aead_decrypt, 243462306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 243562306a36Sopenharmony_ci .maxauthsize = MD5_DIGEST_SIZE, 243662306a36Sopenharmony_ci }, 243762306a36Sopenharmony_ci .caam = { 243862306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 243962306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_MD5 | 244062306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 244162306a36Sopenharmony_ci .geniv = true, 244262306a36Sopenharmony_ci } 244362306a36Sopenharmony_ci }, 244462306a36Sopenharmony_ci { 244562306a36Sopenharmony_ci .aead = { 244662306a36Sopenharmony_ci .base = { 244762306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha1),cbc(des))", 244862306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha1-" 244962306a36Sopenharmony_ci "cbc-des-caam-qi2", 245062306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 245162306a36Sopenharmony_ci }, 245262306a36Sopenharmony_ci .setkey = aead_setkey, 245362306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 245462306a36Sopenharmony_ci .encrypt = aead_encrypt, 245562306a36Sopenharmony_ci .decrypt = aead_decrypt, 245662306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 245762306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 245862306a36Sopenharmony_ci }, 245962306a36Sopenharmony_ci .caam = { 246062306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 246162306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA1 | 246262306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 246362306a36Sopenharmony_ci }, 246462306a36Sopenharmony_ci }, 246562306a36Sopenharmony_ci { 246662306a36Sopenharmony_ci .aead = { 246762306a36Sopenharmony_ci .base = { 246862306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha1)," 246962306a36Sopenharmony_ci "cbc(des)))", 247062306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 247162306a36Sopenharmony_ci "hmac-sha1-cbc-des-caam-qi2", 247262306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 247362306a36Sopenharmony_ci }, 247462306a36Sopenharmony_ci .setkey = aead_setkey, 247562306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 247662306a36Sopenharmony_ci .encrypt = aead_encrypt, 247762306a36Sopenharmony_ci .decrypt = aead_decrypt, 247862306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 247962306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 248062306a36Sopenharmony_ci }, 248162306a36Sopenharmony_ci .caam = { 248262306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 248362306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA1 | 248462306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 248562306a36Sopenharmony_ci .geniv = true, 248662306a36Sopenharmony_ci } 248762306a36Sopenharmony_ci }, 248862306a36Sopenharmony_ci { 248962306a36Sopenharmony_ci .aead = { 249062306a36Sopenharmony_ci .base = { 249162306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha224),cbc(des))", 249262306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha224-" 249362306a36Sopenharmony_ci "cbc-des-caam-qi2", 249462306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 249562306a36Sopenharmony_ci }, 249662306a36Sopenharmony_ci .setkey = aead_setkey, 249762306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 249862306a36Sopenharmony_ci .encrypt = aead_encrypt, 249962306a36Sopenharmony_ci .decrypt = aead_decrypt, 250062306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 250162306a36Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 250262306a36Sopenharmony_ci }, 250362306a36Sopenharmony_ci .caam = { 250462306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 250562306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA224 | 250662306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 250762306a36Sopenharmony_ci }, 250862306a36Sopenharmony_ci }, 250962306a36Sopenharmony_ci { 251062306a36Sopenharmony_ci .aead = { 251162306a36Sopenharmony_ci .base = { 251262306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha224)," 251362306a36Sopenharmony_ci "cbc(des)))", 251462306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 251562306a36Sopenharmony_ci "hmac-sha224-cbc-des-" 251662306a36Sopenharmony_ci "caam-qi2", 251762306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 251862306a36Sopenharmony_ci }, 251962306a36Sopenharmony_ci .setkey = aead_setkey, 252062306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 252162306a36Sopenharmony_ci .encrypt = aead_encrypt, 252262306a36Sopenharmony_ci .decrypt = aead_decrypt, 252362306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 252462306a36Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 252562306a36Sopenharmony_ci }, 252662306a36Sopenharmony_ci .caam = { 252762306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 252862306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA224 | 252962306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 253062306a36Sopenharmony_ci .geniv = true, 253162306a36Sopenharmony_ci } 253262306a36Sopenharmony_ci }, 253362306a36Sopenharmony_ci { 253462306a36Sopenharmony_ci .aead = { 253562306a36Sopenharmony_ci .base = { 253662306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha256),cbc(des))", 253762306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha256-" 253862306a36Sopenharmony_ci "cbc-des-caam-qi2", 253962306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 254062306a36Sopenharmony_ci }, 254162306a36Sopenharmony_ci .setkey = aead_setkey, 254262306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 254362306a36Sopenharmony_ci .encrypt = aead_encrypt, 254462306a36Sopenharmony_ci .decrypt = aead_decrypt, 254562306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 254662306a36Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 254762306a36Sopenharmony_ci }, 254862306a36Sopenharmony_ci .caam = { 254962306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 255062306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA256 | 255162306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 255262306a36Sopenharmony_ci }, 255362306a36Sopenharmony_ci }, 255462306a36Sopenharmony_ci { 255562306a36Sopenharmony_ci .aead = { 255662306a36Sopenharmony_ci .base = { 255762306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha256)," 255862306a36Sopenharmony_ci "cbc(des)))", 255962306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 256062306a36Sopenharmony_ci "hmac-sha256-cbc-des-" 256162306a36Sopenharmony_ci "caam-qi2", 256262306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 256362306a36Sopenharmony_ci }, 256462306a36Sopenharmony_ci .setkey = aead_setkey, 256562306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 256662306a36Sopenharmony_ci .encrypt = aead_encrypt, 256762306a36Sopenharmony_ci .decrypt = aead_decrypt, 256862306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 256962306a36Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 257062306a36Sopenharmony_ci }, 257162306a36Sopenharmony_ci .caam = { 257262306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 257362306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA256 | 257462306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 257562306a36Sopenharmony_ci .geniv = true, 257662306a36Sopenharmony_ci }, 257762306a36Sopenharmony_ci }, 257862306a36Sopenharmony_ci { 257962306a36Sopenharmony_ci .aead = { 258062306a36Sopenharmony_ci .base = { 258162306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha384),cbc(des))", 258262306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha384-" 258362306a36Sopenharmony_ci "cbc-des-caam-qi2", 258462306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 258562306a36Sopenharmony_ci }, 258662306a36Sopenharmony_ci .setkey = aead_setkey, 258762306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 258862306a36Sopenharmony_ci .encrypt = aead_encrypt, 258962306a36Sopenharmony_ci .decrypt = aead_decrypt, 259062306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 259162306a36Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 259262306a36Sopenharmony_ci }, 259362306a36Sopenharmony_ci .caam = { 259462306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 259562306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA384 | 259662306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 259762306a36Sopenharmony_ci }, 259862306a36Sopenharmony_ci }, 259962306a36Sopenharmony_ci { 260062306a36Sopenharmony_ci .aead = { 260162306a36Sopenharmony_ci .base = { 260262306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha384)," 260362306a36Sopenharmony_ci "cbc(des)))", 260462306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 260562306a36Sopenharmony_ci "hmac-sha384-cbc-des-" 260662306a36Sopenharmony_ci "caam-qi2", 260762306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 260862306a36Sopenharmony_ci }, 260962306a36Sopenharmony_ci .setkey = aead_setkey, 261062306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 261162306a36Sopenharmony_ci .encrypt = aead_encrypt, 261262306a36Sopenharmony_ci .decrypt = aead_decrypt, 261362306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 261462306a36Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 261562306a36Sopenharmony_ci }, 261662306a36Sopenharmony_ci .caam = { 261762306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 261862306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA384 | 261962306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 262062306a36Sopenharmony_ci .geniv = true, 262162306a36Sopenharmony_ci } 262262306a36Sopenharmony_ci }, 262362306a36Sopenharmony_ci { 262462306a36Sopenharmony_ci .aead = { 262562306a36Sopenharmony_ci .base = { 262662306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha512),cbc(des))", 262762306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha512-" 262862306a36Sopenharmony_ci "cbc-des-caam-qi2", 262962306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 263062306a36Sopenharmony_ci }, 263162306a36Sopenharmony_ci .setkey = aead_setkey, 263262306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 263362306a36Sopenharmony_ci .encrypt = aead_encrypt, 263462306a36Sopenharmony_ci .decrypt = aead_decrypt, 263562306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 263662306a36Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 263762306a36Sopenharmony_ci }, 263862306a36Sopenharmony_ci .caam = { 263962306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 264062306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA512 | 264162306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 264262306a36Sopenharmony_ci } 264362306a36Sopenharmony_ci }, 264462306a36Sopenharmony_ci { 264562306a36Sopenharmony_ci .aead = { 264662306a36Sopenharmony_ci .base = { 264762306a36Sopenharmony_ci .cra_name = "echainiv(authenc(hmac(sha512)," 264862306a36Sopenharmony_ci "cbc(des)))", 264962306a36Sopenharmony_ci .cra_driver_name = "echainiv-authenc-" 265062306a36Sopenharmony_ci "hmac-sha512-cbc-des-" 265162306a36Sopenharmony_ci "caam-qi2", 265262306a36Sopenharmony_ci .cra_blocksize = DES_BLOCK_SIZE, 265362306a36Sopenharmony_ci }, 265462306a36Sopenharmony_ci .setkey = aead_setkey, 265562306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 265662306a36Sopenharmony_ci .encrypt = aead_encrypt, 265762306a36Sopenharmony_ci .decrypt = aead_decrypt, 265862306a36Sopenharmony_ci .ivsize = DES_BLOCK_SIZE, 265962306a36Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 266062306a36Sopenharmony_ci }, 266162306a36Sopenharmony_ci .caam = { 266262306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, 266362306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA512 | 266462306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 266562306a36Sopenharmony_ci .geniv = true, 266662306a36Sopenharmony_ci } 266762306a36Sopenharmony_ci }, 266862306a36Sopenharmony_ci { 266962306a36Sopenharmony_ci .aead = { 267062306a36Sopenharmony_ci .base = { 267162306a36Sopenharmony_ci .cra_name = "authenc(hmac(md5)," 267262306a36Sopenharmony_ci "rfc3686(ctr(aes)))", 267362306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-md5-" 267462306a36Sopenharmony_ci "rfc3686-ctr-aes-caam-qi2", 267562306a36Sopenharmony_ci .cra_blocksize = 1, 267662306a36Sopenharmony_ci }, 267762306a36Sopenharmony_ci .setkey = aead_setkey, 267862306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 267962306a36Sopenharmony_ci .encrypt = aead_encrypt, 268062306a36Sopenharmony_ci .decrypt = aead_decrypt, 268162306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 268262306a36Sopenharmony_ci .maxauthsize = MD5_DIGEST_SIZE, 268362306a36Sopenharmony_ci }, 268462306a36Sopenharmony_ci .caam = { 268562306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 268662306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 268762306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_MD5 | 268862306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 268962306a36Sopenharmony_ci .rfc3686 = true, 269062306a36Sopenharmony_ci }, 269162306a36Sopenharmony_ci }, 269262306a36Sopenharmony_ci { 269362306a36Sopenharmony_ci .aead = { 269462306a36Sopenharmony_ci .base = { 269562306a36Sopenharmony_ci .cra_name = "seqiv(authenc(" 269662306a36Sopenharmony_ci "hmac(md5),rfc3686(ctr(aes))))", 269762306a36Sopenharmony_ci .cra_driver_name = "seqiv-authenc-hmac-md5-" 269862306a36Sopenharmony_ci "rfc3686-ctr-aes-caam-qi2", 269962306a36Sopenharmony_ci .cra_blocksize = 1, 270062306a36Sopenharmony_ci }, 270162306a36Sopenharmony_ci .setkey = aead_setkey, 270262306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 270362306a36Sopenharmony_ci .encrypt = aead_encrypt, 270462306a36Sopenharmony_ci .decrypt = aead_decrypt, 270562306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 270662306a36Sopenharmony_ci .maxauthsize = MD5_DIGEST_SIZE, 270762306a36Sopenharmony_ci }, 270862306a36Sopenharmony_ci .caam = { 270962306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 271062306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 271162306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_MD5 | 271262306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 271362306a36Sopenharmony_ci .rfc3686 = true, 271462306a36Sopenharmony_ci .geniv = true, 271562306a36Sopenharmony_ci }, 271662306a36Sopenharmony_ci }, 271762306a36Sopenharmony_ci { 271862306a36Sopenharmony_ci .aead = { 271962306a36Sopenharmony_ci .base = { 272062306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha1)," 272162306a36Sopenharmony_ci "rfc3686(ctr(aes)))", 272262306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha1-" 272362306a36Sopenharmony_ci "rfc3686-ctr-aes-caam-qi2", 272462306a36Sopenharmony_ci .cra_blocksize = 1, 272562306a36Sopenharmony_ci }, 272662306a36Sopenharmony_ci .setkey = aead_setkey, 272762306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 272862306a36Sopenharmony_ci .encrypt = aead_encrypt, 272962306a36Sopenharmony_ci .decrypt = aead_decrypt, 273062306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 273162306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 273262306a36Sopenharmony_ci }, 273362306a36Sopenharmony_ci .caam = { 273462306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 273562306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 273662306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA1 | 273762306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 273862306a36Sopenharmony_ci .rfc3686 = true, 273962306a36Sopenharmony_ci }, 274062306a36Sopenharmony_ci }, 274162306a36Sopenharmony_ci { 274262306a36Sopenharmony_ci .aead = { 274362306a36Sopenharmony_ci .base = { 274462306a36Sopenharmony_ci .cra_name = "seqiv(authenc(" 274562306a36Sopenharmony_ci "hmac(sha1),rfc3686(ctr(aes))))", 274662306a36Sopenharmony_ci .cra_driver_name = "seqiv-authenc-hmac-sha1-" 274762306a36Sopenharmony_ci "rfc3686-ctr-aes-caam-qi2", 274862306a36Sopenharmony_ci .cra_blocksize = 1, 274962306a36Sopenharmony_ci }, 275062306a36Sopenharmony_ci .setkey = aead_setkey, 275162306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 275262306a36Sopenharmony_ci .encrypt = aead_encrypt, 275362306a36Sopenharmony_ci .decrypt = aead_decrypt, 275462306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 275562306a36Sopenharmony_ci .maxauthsize = SHA1_DIGEST_SIZE, 275662306a36Sopenharmony_ci }, 275762306a36Sopenharmony_ci .caam = { 275862306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 275962306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 276062306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA1 | 276162306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 276262306a36Sopenharmony_ci .rfc3686 = true, 276362306a36Sopenharmony_ci .geniv = true, 276462306a36Sopenharmony_ci }, 276562306a36Sopenharmony_ci }, 276662306a36Sopenharmony_ci { 276762306a36Sopenharmony_ci .aead = { 276862306a36Sopenharmony_ci .base = { 276962306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha224)," 277062306a36Sopenharmony_ci "rfc3686(ctr(aes)))", 277162306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha224-" 277262306a36Sopenharmony_ci "rfc3686-ctr-aes-caam-qi2", 277362306a36Sopenharmony_ci .cra_blocksize = 1, 277462306a36Sopenharmony_ci }, 277562306a36Sopenharmony_ci .setkey = aead_setkey, 277662306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 277762306a36Sopenharmony_ci .encrypt = aead_encrypt, 277862306a36Sopenharmony_ci .decrypt = aead_decrypt, 277962306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 278062306a36Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 278162306a36Sopenharmony_ci }, 278262306a36Sopenharmony_ci .caam = { 278362306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 278462306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 278562306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA224 | 278662306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 278762306a36Sopenharmony_ci .rfc3686 = true, 278862306a36Sopenharmony_ci }, 278962306a36Sopenharmony_ci }, 279062306a36Sopenharmony_ci { 279162306a36Sopenharmony_ci .aead = { 279262306a36Sopenharmony_ci .base = { 279362306a36Sopenharmony_ci .cra_name = "seqiv(authenc(" 279462306a36Sopenharmony_ci "hmac(sha224),rfc3686(ctr(aes))))", 279562306a36Sopenharmony_ci .cra_driver_name = "seqiv-authenc-hmac-sha224-" 279662306a36Sopenharmony_ci "rfc3686-ctr-aes-caam-qi2", 279762306a36Sopenharmony_ci .cra_blocksize = 1, 279862306a36Sopenharmony_ci }, 279962306a36Sopenharmony_ci .setkey = aead_setkey, 280062306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 280162306a36Sopenharmony_ci .encrypt = aead_encrypt, 280262306a36Sopenharmony_ci .decrypt = aead_decrypt, 280362306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 280462306a36Sopenharmony_ci .maxauthsize = SHA224_DIGEST_SIZE, 280562306a36Sopenharmony_ci }, 280662306a36Sopenharmony_ci .caam = { 280762306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 280862306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 280962306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA224 | 281062306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 281162306a36Sopenharmony_ci .rfc3686 = true, 281262306a36Sopenharmony_ci .geniv = true, 281362306a36Sopenharmony_ci }, 281462306a36Sopenharmony_ci }, 281562306a36Sopenharmony_ci { 281662306a36Sopenharmony_ci .aead = { 281762306a36Sopenharmony_ci .base = { 281862306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha256)," 281962306a36Sopenharmony_ci "rfc3686(ctr(aes)))", 282062306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha256-" 282162306a36Sopenharmony_ci "rfc3686-ctr-aes-caam-qi2", 282262306a36Sopenharmony_ci .cra_blocksize = 1, 282362306a36Sopenharmony_ci }, 282462306a36Sopenharmony_ci .setkey = aead_setkey, 282562306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 282662306a36Sopenharmony_ci .encrypt = aead_encrypt, 282762306a36Sopenharmony_ci .decrypt = aead_decrypt, 282862306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 282962306a36Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 283062306a36Sopenharmony_ci }, 283162306a36Sopenharmony_ci .caam = { 283262306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 283362306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 283462306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA256 | 283562306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 283662306a36Sopenharmony_ci .rfc3686 = true, 283762306a36Sopenharmony_ci }, 283862306a36Sopenharmony_ci }, 283962306a36Sopenharmony_ci { 284062306a36Sopenharmony_ci .aead = { 284162306a36Sopenharmony_ci .base = { 284262306a36Sopenharmony_ci .cra_name = "seqiv(authenc(hmac(sha256)," 284362306a36Sopenharmony_ci "rfc3686(ctr(aes))))", 284462306a36Sopenharmony_ci .cra_driver_name = "seqiv-authenc-hmac-sha256-" 284562306a36Sopenharmony_ci "rfc3686-ctr-aes-caam-qi2", 284662306a36Sopenharmony_ci .cra_blocksize = 1, 284762306a36Sopenharmony_ci }, 284862306a36Sopenharmony_ci .setkey = aead_setkey, 284962306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 285062306a36Sopenharmony_ci .encrypt = aead_encrypt, 285162306a36Sopenharmony_ci .decrypt = aead_decrypt, 285262306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 285362306a36Sopenharmony_ci .maxauthsize = SHA256_DIGEST_SIZE, 285462306a36Sopenharmony_ci }, 285562306a36Sopenharmony_ci .caam = { 285662306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 285762306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 285862306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA256 | 285962306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 286062306a36Sopenharmony_ci .rfc3686 = true, 286162306a36Sopenharmony_ci .geniv = true, 286262306a36Sopenharmony_ci }, 286362306a36Sopenharmony_ci }, 286462306a36Sopenharmony_ci { 286562306a36Sopenharmony_ci .aead = { 286662306a36Sopenharmony_ci .base = { 286762306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha384)," 286862306a36Sopenharmony_ci "rfc3686(ctr(aes)))", 286962306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha384-" 287062306a36Sopenharmony_ci "rfc3686-ctr-aes-caam-qi2", 287162306a36Sopenharmony_ci .cra_blocksize = 1, 287262306a36Sopenharmony_ci }, 287362306a36Sopenharmony_ci .setkey = aead_setkey, 287462306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 287562306a36Sopenharmony_ci .encrypt = aead_encrypt, 287662306a36Sopenharmony_ci .decrypt = aead_decrypt, 287762306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 287862306a36Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 287962306a36Sopenharmony_ci }, 288062306a36Sopenharmony_ci .caam = { 288162306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 288262306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 288362306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA384 | 288462306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 288562306a36Sopenharmony_ci .rfc3686 = true, 288662306a36Sopenharmony_ci }, 288762306a36Sopenharmony_ci }, 288862306a36Sopenharmony_ci { 288962306a36Sopenharmony_ci .aead = { 289062306a36Sopenharmony_ci .base = { 289162306a36Sopenharmony_ci .cra_name = "seqiv(authenc(hmac(sha384)," 289262306a36Sopenharmony_ci "rfc3686(ctr(aes))))", 289362306a36Sopenharmony_ci .cra_driver_name = "seqiv-authenc-hmac-sha384-" 289462306a36Sopenharmony_ci "rfc3686-ctr-aes-caam-qi2", 289562306a36Sopenharmony_ci .cra_blocksize = 1, 289662306a36Sopenharmony_ci }, 289762306a36Sopenharmony_ci .setkey = aead_setkey, 289862306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 289962306a36Sopenharmony_ci .encrypt = aead_encrypt, 290062306a36Sopenharmony_ci .decrypt = aead_decrypt, 290162306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 290262306a36Sopenharmony_ci .maxauthsize = SHA384_DIGEST_SIZE, 290362306a36Sopenharmony_ci }, 290462306a36Sopenharmony_ci .caam = { 290562306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 290662306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 290762306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA384 | 290862306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 290962306a36Sopenharmony_ci .rfc3686 = true, 291062306a36Sopenharmony_ci .geniv = true, 291162306a36Sopenharmony_ci }, 291262306a36Sopenharmony_ci }, 291362306a36Sopenharmony_ci { 291462306a36Sopenharmony_ci .aead = { 291562306a36Sopenharmony_ci .base = { 291662306a36Sopenharmony_ci .cra_name = "rfc7539(chacha20,poly1305)", 291762306a36Sopenharmony_ci .cra_driver_name = "rfc7539-chacha20-poly1305-" 291862306a36Sopenharmony_ci "caam-qi2", 291962306a36Sopenharmony_ci .cra_blocksize = 1, 292062306a36Sopenharmony_ci }, 292162306a36Sopenharmony_ci .setkey = chachapoly_setkey, 292262306a36Sopenharmony_ci .setauthsize = chachapoly_setauthsize, 292362306a36Sopenharmony_ci .encrypt = aead_encrypt, 292462306a36Sopenharmony_ci .decrypt = aead_decrypt, 292562306a36Sopenharmony_ci .ivsize = CHACHAPOLY_IV_SIZE, 292662306a36Sopenharmony_ci .maxauthsize = POLY1305_DIGEST_SIZE, 292762306a36Sopenharmony_ci }, 292862306a36Sopenharmony_ci .caam = { 292962306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 | 293062306a36Sopenharmony_ci OP_ALG_AAI_AEAD, 293162306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_POLY1305 | 293262306a36Sopenharmony_ci OP_ALG_AAI_AEAD, 293362306a36Sopenharmony_ci .nodkp = true, 293462306a36Sopenharmony_ci }, 293562306a36Sopenharmony_ci }, 293662306a36Sopenharmony_ci { 293762306a36Sopenharmony_ci .aead = { 293862306a36Sopenharmony_ci .base = { 293962306a36Sopenharmony_ci .cra_name = "rfc7539esp(chacha20,poly1305)", 294062306a36Sopenharmony_ci .cra_driver_name = "rfc7539esp-chacha20-" 294162306a36Sopenharmony_ci "poly1305-caam-qi2", 294262306a36Sopenharmony_ci .cra_blocksize = 1, 294362306a36Sopenharmony_ci }, 294462306a36Sopenharmony_ci .setkey = chachapoly_setkey, 294562306a36Sopenharmony_ci .setauthsize = chachapoly_setauthsize, 294662306a36Sopenharmony_ci .encrypt = aead_encrypt, 294762306a36Sopenharmony_ci .decrypt = aead_decrypt, 294862306a36Sopenharmony_ci .ivsize = 8, 294962306a36Sopenharmony_ci .maxauthsize = POLY1305_DIGEST_SIZE, 295062306a36Sopenharmony_ci }, 295162306a36Sopenharmony_ci .caam = { 295262306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_CHACHA20 | 295362306a36Sopenharmony_ci OP_ALG_AAI_AEAD, 295462306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_POLY1305 | 295562306a36Sopenharmony_ci OP_ALG_AAI_AEAD, 295662306a36Sopenharmony_ci .nodkp = true, 295762306a36Sopenharmony_ci }, 295862306a36Sopenharmony_ci }, 295962306a36Sopenharmony_ci { 296062306a36Sopenharmony_ci .aead = { 296162306a36Sopenharmony_ci .base = { 296262306a36Sopenharmony_ci .cra_name = "authenc(hmac(sha512)," 296362306a36Sopenharmony_ci "rfc3686(ctr(aes)))", 296462306a36Sopenharmony_ci .cra_driver_name = "authenc-hmac-sha512-" 296562306a36Sopenharmony_ci "rfc3686-ctr-aes-caam-qi2", 296662306a36Sopenharmony_ci .cra_blocksize = 1, 296762306a36Sopenharmony_ci }, 296862306a36Sopenharmony_ci .setkey = aead_setkey, 296962306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 297062306a36Sopenharmony_ci .encrypt = aead_encrypt, 297162306a36Sopenharmony_ci .decrypt = aead_decrypt, 297262306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 297362306a36Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 297462306a36Sopenharmony_ci }, 297562306a36Sopenharmony_ci .caam = { 297662306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 297762306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 297862306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA512 | 297962306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 298062306a36Sopenharmony_ci .rfc3686 = true, 298162306a36Sopenharmony_ci }, 298262306a36Sopenharmony_ci }, 298362306a36Sopenharmony_ci { 298462306a36Sopenharmony_ci .aead = { 298562306a36Sopenharmony_ci .base = { 298662306a36Sopenharmony_ci .cra_name = "seqiv(authenc(hmac(sha512)," 298762306a36Sopenharmony_ci "rfc3686(ctr(aes))))", 298862306a36Sopenharmony_ci .cra_driver_name = "seqiv-authenc-hmac-sha512-" 298962306a36Sopenharmony_ci "rfc3686-ctr-aes-caam-qi2", 299062306a36Sopenharmony_ci .cra_blocksize = 1, 299162306a36Sopenharmony_ci }, 299262306a36Sopenharmony_ci .setkey = aead_setkey, 299362306a36Sopenharmony_ci .setauthsize = aead_setauthsize, 299462306a36Sopenharmony_ci .encrypt = aead_encrypt, 299562306a36Sopenharmony_ci .decrypt = aead_decrypt, 299662306a36Sopenharmony_ci .ivsize = CTR_RFC3686_IV_SIZE, 299762306a36Sopenharmony_ci .maxauthsize = SHA512_DIGEST_SIZE, 299862306a36Sopenharmony_ci }, 299962306a36Sopenharmony_ci .caam = { 300062306a36Sopenharmony_ci .class1_alg_type = OP_ALG_ALGSEL_AES | 300162306a36Sopenharmony_ci OP_ALG_AAI_CTR_MOD128, 300262306a36Sopenharmony_ci .class2_alg_type = OP_ALG_ALGSEL_SHA512 | 300362306a36Sopenharmony_ci OP_ALG_AAI_HMAC_PRECOMP, 300462306a36Sopenharmony_ci .rfc3686 = true, 300562306a36Sopenharmony_ci .geniv = true, 300662306a36Sopenharmony_ci }, 300762306a36Sopenharmony_ci }, 300862306a36Sopenharmony_ci}; 300962306a36Sopenharmony_ci 301062306a36Sopenharmony_cistatic void caam_skcipher_alg_init(struct caam_skcipher_alg *t_alg) 301162306a36Sopenharmony_ci{ 301262306a36Sopenharmony_ci struct skcipher_alg *alg = &t_alg->skcipher; 301362306a36Sopenharmony_ci 301462306a36Sopenharmony_ci alg->base.cra_module = THIS_MODULE; 301562306a36Sopenharmony_ci alg->base.cra_priority = CAAM_CRA_PRIORITY; 301662306a36Sopenharmony_ci alg->base.cra_ctxsize = sizeof(struct caam_ctx) + crypto_dma_padding(); 301762306a36Sopenharmony_ci alg->base.cra_flags |= (CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | 301862306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY); 301962306a36Sopenharmony_ci 302062306a36Sopenharmony_ci alg->init = caam_cra_init_skcipher; 302162306a36Sopenharmony_ci alg->exit = caam_cra_exit; 302262306a36Sopenharmony_ci} 302362306a36Sopenharmony_ci 302462306a36Sopenharmony_cistatic void caam_aead_alg_init(struct caam_aead_alg *t_alg) 302562306a36Sopenharmony_ci{ 302662306a36Sopenharmony_ci struct aead_alg *alg = &t_alg->aead; 302762306a36Sopenharmony_ci 302862306a36Sopenharmony_ci alg->base.cra_module = THIS_MODULE; 302962306a36Sopenharmony_ci alg->base.cra_priority = CAAM_CRA_PRIORITY; 303062306a36Sopenharmony_ci alg->base.cra_ctxsize = sizeof(struct caam_ctx) + crypto_dma_padding(); 303162306a36Sopenharmony_ci alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | 303262306a36Sopenharmony_ci CRYPTO_ALG_KERN_DRIVER_ONLY; 303362306a36Sopenharmony_ci 303462306a36Sopenharmony_ci alg->init = caam_cra_init_aead; 303562306a36Sopenharmony_ci alg->exit = caam_cra_exit_aead; 303662306a36Sopenharmony_ci} 303762306a36Sopenharmony_ci 303862306a36Sopenharmony_ci/* max hash key is max split key size */ 303962306a36Sopenharmony_ci#define CAAM_MAX_HASH_KEY_SIZE (SHA512_DIGEST_SIZE * 2) 304062306a36Sopenharmony_ci 304162306a36Sopenharmony_ci#define CAAM_MAX_HASH_BLOCK_SIZE SHA512_BLOCK_SIZE 304262306a36Sopenharmony_ci 304362306a36Sopenharmony_ci/* caam context sizes for hashes: running digest + 8 */ 304462306a36Sopenharmony_ci#define HASH_MSG_LEN 8 304562306a36Sopenharmony_ci#define MAX_CTX_LEN (HASH_MSG_LEN + SHA512_DIGEST_SIZE) 304662306a36Sopenharmony_ci 304762306a36Sopenharmony_cienum hash_optype { 304862306a36Sopenharmony_ci UPDATE = 0, 304962306a36Sopenharmony_ci UPDATE_FIRST, 305062306a36Sopenharmony_ci FINALIZE, 305162306a36Sopenharmony_ci DIGEST, 305262306a36Sopenharmony_ci HASH_NUM_OP 305362306a36Sopenharmony_ci}; 305462306a36Sopenharmony_ci 305562306a36Sopenharmony_ci/** 305662306a36Sopenharmony_ci * struct caam_hash_ctx - ahash per-session context 305762306a36Sopenharmony_ci * @flc: Flow Contexts array 305862306a36Sopenharmony_ci * @key: authentication key 305962306a36Sopenharmony_ci * @flc_dma: I/O virtual addresses of the Flow Contexts 306062306a36Sopenharmony_ci * @dev: dpseci device 306162306a36Sopenharmony_ci * @ctx_len: size of Context Register 306262306a36Sopenharmony_ci * @adata: hashing algorithm details 306362306a36Sopenharmony_ci */ 306462306a36Sopenharmony_cistruct caam_hash_ctx { 306562306a36Sopenharmony_ci struct caam_flc flc[HASH_NUM_OP]; 306662306a36Sopenharmony_ci u8 key[CAAM_MAX_HASH_BLOCK_SIZE] ____cacheline_aligned; 306762306a36Sopenharmony_ci dma_addr_t flc_dma[HASH_NUM_OP]; 306862306a36Sopenharmony_ci struct device *dev; 306962306a36Sopenharmony_ci int ctx_len; 307062306a36Sopenharmony_ci struct alginfo adata; 307162306a36Sopenharmony_ci}; 307262306a36Sopenharmony_ci 307362306a36Sopenharmony_ci/* ahash state */ 307462306a36Sopenharmony_cistruct caam_hash_state { 307562306a36Sopenharmony_ci struct caam_request caam_req; 307662306a36Sopenharmony_ci dma_addr_t buf_dma; 307762306a36Sopenharmony_ci dma_addr_t ctx_dma; 307862306a36Sopenharmony_ci int ctx_dma_len; 307962306a36Sopenharmony_ci u8 buf[CAAM_MAX_HASH_BLOCK_SIZE] ____cacheline_aligned; 308062306a36Sopenharmony_ci int buflen; 308162306a36Sopenharmony_ci int next_buflen; 308262306a36Sopenharmony_ci u8 caam_ctx[MAX_CTX_LEN] ____cacheline_aligned; 308362306a36Sopenharmony_ci int (*update)(struct ahash_request *req); 308462306a36Sopenharmony_ci int (*final)(struct ahash_request *req); 308562306a36Sopenharmony_ci int (*finup)(struct ahash_request *req); 308662306a36Sopenharmony_ci}; 308762306a36Sopenharmony_ci 308862306a36Sopenharmony_cistruct caam_export_state { 308962306a36Sopenharmony_ci u8 buf[CAAM_MAX_HASH_BLOCK_SIZE]; 309062306a36Sopenharmony_ci u8 caam_ctx[MAX_CTX_LEN]; 309162306a36Sopenharmony_ci int buflen; 309262306a36Sopenharmony_ci int (*update)(struct ahash_request *req); 309362306a36Sopenharmony_ci int (*final)(struct ahash_request *req); 309462306a36Sopenharmony_ci int (*finup)(struct ahash_request *req); 309562306a36Sopenharmony_ci}; 309662306a36Sopenharmony_ci 309762306a36Sopenharmony_ci/* Map current buffer in state (if length > 0) and put it in link table */ 309862306a36Sopenharmony_cistatic inline int buf_map_to_qm_sg(struct device *dev, 309962306a36Sopenharmony_ci struct dpaa2_sg_entry *qm_sg, 310062306a36Sopenharmony_ci struct caam_hash_state *state) 310162306a36Sopenharmony_ci{ 310262306a36Sopenharmony_ci int buflen = state->buflen; 310362306a36Sopenharmony_ci 310462306a36Sopenharmony_ci if (!buflen) 310562306a36Sopenharmony_ci return 0; 310662306a36Sopenharmony_ci 310762306a36Sopenharmony_ci state->buf_dma = dma_map_single(dev, state->buf, buflen, 310862306a36Sopenharmony_ci DMA_TO_DEVICE); 310962306a36Sopenharmony_ci if (dma_mapping_error(dev, state->buf_dma)) { 311062306a36Sopenharmony_ci dev_err(dev, "unable to map buf\n"); 311162306a36Sopenharmony_ci state->buf_dma = 0; 311262306a36Sopenharmony_ci return -ENOMEM; 311362306a36Sopenharmony_ci } 311462306a36Sopenharmony_ci 311562306a36Sopenharmony_ci dma_to_qm_sg_one(qm_sg, state->buf_dma, buflen, 0); 311662306a36Sopenharmony_ci 311762306a36Sopenharmony_ci return 0; 311862306a36Sopenharmony_ci} 311962306a36Sopenharmony_ci 312062306a36Sopenharmony_ci/* Map state->caam_ctx, and add it to link table */ 312162306a36Sopenharmony_cistatic inline int ctx_map_to_qm_sg(struct device *dev, 312262306a36Sopenharmony_ci struct caam_hash_state *state, int ctx_len, 312362306a36Sopenharmony_ci struct dpaa2_sg_entry *qm_sg, u32 flag) 312462306a36Sopenharmony_ci{ 312562306a36Sopenharmony_ci state->ctx_dma_len = ctx_len; 312662306a36Sopenharmony_ci state->ctx_dma = dma_map_single(dev, state->caam_ctx, ctx_len, flag); 312762306a36Sopenharmony_ci if (dma_mapping_error(dev, state->ctx_dma)) { 312862306a36Sopenharmony_ci dev_err(dev, "unable to map ctx\n"); 312962306a36Sopenharmony_ci state->ctx_dma = 0; 313062306a36Sopenharmony_ci return -ENOMEM; 313162306a36Sopenharmony_ci } 313262306a36Sopenharmony_ci 313362306a36Sopenharmony_ci dma_to_qm_sg_one(qm_sg, state->ctx_dma, ctx_len, 0); 313462306a36Sopenharmony_ci 313562306a36Sopenharmony_ci return 0; 313662306a36Sopenharmony_ci} 313762306a36Sopenharmony_ci 313862306a36Sopenharmony_cistatic int ahash_set_sh_desc(struct crypto_ahash *ahash) 313962306a36Sopenharmony_ci{ 314062306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 314162306a36Sopenharmony_ci int digestsize = crypto_ahash_digestsize(ahash); 314262306a36Sopenharmony_ci struct dpaa2_caam_priv *priv = dev_get_drvdata(ctx->dev); 314362306a36Sopenharmony_ci struct caam_flc *flc; 314462306a36Sopenharmony_ci u32 *desc; 314562306a36Sopenharmony_ci 314662306a36Sopenharmony_ci /* ahash_update shared descriptor */ 314762306a36Sopenharmony_ci flc = &ctx->flc[UPDATE]; 314862306a36Sopenharmony_ci desc = flc->sh_desc; 314962306a36Sopenharmony_ci cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_UPDATE, ctx->ctx_len, 315062306a36Sopenharmony_ci ctx->ctx_len, true, priv->sec_attr.era); 315162306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 315262306a36Sopenharmony_ci dma_sync_single_for_device(ctx->dev, ctx->flc_dma[UPDATE], 315362306a36Sopenharmony_ci desc_bytes(desc), DMA_BIDIRECTIONAL); 315462306a36Sopenharmony_ci print_hex_dump_debug("ahash update shdesc@" __stringify(__LINE__)": ", 315562306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 315662306a36Sopenharmony_ci 1); 315762306a36Sopenharmony_ci 315862306a36Sopenharmony_ci /* ahash_update_first shared descriptor */ 315962306a36Sopenharmony_ci flc = &ctx->flc[UPDATE_FIRST]; 316062306a36Sopenharmony_ci desc = flc->sh_desc; 316162306a36Sopenharmony_ci cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_INIT, ctx->ctx_len, 316262306a36Sopenharmony_ci ctx->ctx_len, false, priv->sec_attr.era); 316362306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 316462306a36Sopenharmony_ci dma_sync_single_for_device(ctx->dev, ctx->flc_dma[UPDATE_FIRST], 316562306a36Sopenharmony_ci desc_bytes(desc), DMA_BIDIRECTIONAL); 316662306a36Sopenharmony_ci print_hex_dump_debug("ahash update first shdesc@" __stringify(__LINE__)": ", 316762306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 316862306a36Sopenharmony_ci 1); 316962306a36Sopenharmony_ci 317062306a36Sopenharmony_ci /* ahash_final shared descriptor */ 317162306a36Sopenharmony_ci flc = &ctx->flc[FINALIZE]; 317262306a36Sopenharmony_ci desc = flc->sh_desc; 317362306a36Sopenharmony_ci cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_FINALIZE, digestsize, 317462306a36Sopenharmony_ci ctx->ctx_len, true, priv->sec_attr.era); 317562306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 317662306a36Sopenharmony_ci dma_sync_single_for_device(ctx->dev, ctx->flc_dma[FINALIZE], 317762306a36Sopenharmony_ci desc_bytes(desc), DMA_BIDIRECTIONAL); 317862306a36Sopenharmony_ci print_hex_dump_debug("ahash final shdesc@" __stringify(__LINE__)": ", 317962306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 318062306a36Sopenharmony_ci 1); 318162306a36Sopenharmony_ci 318262306a36Sopenharmony_ci /* ahash_digest shared descriptor */ 318362306a36Sopenharmony_ci flc = &ctx->flc[DIGEST]; 318462306a36Sopenharmony_ci desc = flc->sh_desc; 318562306a36Sopenharmony_ci cnstr_shdsc_ahash(desc, &ctx->adata, OP_ALG_AS_INITFINAL, digestsize, 318662306a36Sopenharmony_ci ctx->ctx_len, false, priv->sec_attr.era); 318762306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 318862306a36Sopenharmony_ci dma_sync_single_for_device(ctx->dev, ctx->flc_dma[DIGEST], 318962306a36Sopenharmony_ci desc_bytes(desc), DMA_BIDIRECTIONAL); 319062306a36Sopenharmony_ci print_hex_dump_debug("ahash digest shdesc@" __stringify(__LINE__)": ", 319162306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 319262306a36Sopenharmony_ci 1); 319362306a36Sopenharmony_ci 319462306a36Sopenharmony_ci return 0; 319562306a36Sopenharmony_ci} 319662306a36Sopenharmony_ci 319762306a36Sopenharmony_cistruct split_key_sh_result { 319862306a36Sopenharmony_ci struct completion completion; 319962306a36Sopenharmony_ci int err; 320062306a36Sopenharmony_ci struct device *dev; 320162306a36Sopenharmony_ci}; 320262306a36Sopenharmony_ci 320362306a36Sopenharmony_cistatic void split_key_sh_done(void *cbk_ctx, u32 err) 320462306a36Sopenharmony_ci{ 320562306a36Sopenharmony_ci struct split_key_sh_result *res = cbk_ctx; 320662306a36Sopenharmony_ci 320762306a36Sopenharmony_ci dev_dbg(res->dev, "%s %d: err 0x%x\n", __func__, __LINE__, err); 320862306a36Sopenharmony_ci 320962306a36Sopenharmony_ci res->err = err ? caam_qi2_strstatus(res->dev, err) : 0; 321062306a36Sopenharmony_ci complete(&res->completion); 321162306a36Sopenharmony_ci} 321262306a36Sopenharmony_ci 321362306a36Sopenharmony_ci/* Digest hash size if it is too large */ 321462306a36Sopenharmony_cistatic int hash_digest_key(struct caam_hash_ctx *ctx, u32 *keylen, u8 *key, 321562306a36Sopenharmony_ci u32 digestsize) 321662306a36Sopenharmony_ci{ 321762306a36Sopenharmony_ci struct caam_request *req_ctx; 321862306a36Sopenharmony_ci u32 *desc; 321962306a36Sopenharmony_ci struct split_key_sh_result result; 322062306a36Sopenharmony_ci dma_addr_t key_dma; 322162306a36Sopenharmony_ci struct caam_flc *flc; 322262306a36Sopenharmony_ci dma_addr_t flc_dma; 322362306a36Sopenharmony_ci int ret = -ENOMEM; 322462306a36Sopenharmony_ci struct dpaa2_fl_entry *in_fle, *out_fle; 322562306a36Sopenharmony_ci 322662306a36Sopenharmony_ci req_ctx = kzalloc(sizeof(*req_ctx), GFP_KERNEL); 322762306a36Sopenharmony_ci if (!req_ctx) 322862306a36Sopenharmony_ci return -ENOMEM; 322962306a36Sopenharmony_ci 323062306a36Sopenharmony_ci in_fle = &req_ctx->fd_flt[1]; 323162306a36Sopenharmony_ci out_fle = &req_ctx->fd_flt[0]; 323262306a36Sopenharmony_ci 323362306a36Sopenharmony_ci flc = kzalloc(sizeof(*flc), GFP_KERNEL); 323462306a36Sopenharmony_ci if (!flc) 323562306a36Sopenharmony_ci goto err_flc; 323662306a36Sopenharmony_ci 323762306a36Sopenharmony_ci key_dma = dma_map_single(ctx->dev, key, *keylen, DMA_BIDIRECTIONAL); 323862306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, key_dma)) { 323962306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map key memory\n"); 324062306a36Sopenharmony_ci goto err_key_dma; 324162306a36Sopenharmony_ci } 324262306a36Sopenharmony_ci 324362306a36Sopenharmony_ci desc = flc->sh_desc; 324462306a36Sopenharmony_ci 324562306a36Sopenharmony_ci init_sh_desc(desc, 0); 324662306a36Sopenharmony_ci 324762306a36Sopenharmony_ci /* descriptor to perform unkeyed hash on key_in */ 324862306a36Sopenharmony_ci append_operation(desc, ctx->adata.algtype | OP_ALG_ENCRYPT | 324962306a36Sopenharmony_ci OP_ALG_AS_INITFINAL); 325062306a36Sopenharmony_ci append_seq_fifo_load(desc, *keylen, FIFOLD_CLASS_CLASS2 | 325162306a36Sopenharmony_ci FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_MSG); 325262306a36Sopenharmony_ci append_seq_store(desc, digestsize, LDST_CLASS_2_CCB | 325362306a36Sopenharmony_ci LDST_SRCDST_BYTE_CONTEXT); 325462306a36Sopenharmony_ci 325562306a36Sopenharmony_ci flc->flc[1] = cpu_to_caam32(desc_len(desc)); /* SDL */ 325662306a36Sopenharmony_ci flc_dma = dma_map_single(ctx->dev, flc, sizeof(flc->flc) + 325762306a36Sopenharmony_ci desc_bytes(desc), DMA_TO_DEVICE); 325862306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, flc_dma)) { 325962306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map shared descriptor\n"); 326062306a36Sopenharmony_ci goto err_flc_dma; 326162306a36Sopenharmony_ci } 326262306a36Sopenharmony_ci 326362306a36Sopenharmony_ci dpaa2_fl_set_final(in_fle, true); 326462306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_single); 326562306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, key_dma); 326662306a36Sopenharmony_ci dpaa2_fl_set_len(in_fle, *keylen); 326762306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_single); 326862306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, key_dma); 326962306a36Sopenharmony_ci dpaa2_fl_set_len(out_fle, digestsize); 327062306a36Sopenharmony_ci 327162306a36Sopenharmony_ci print_hex_dump_debug("key_in@" __stringify(__LINE__)": ", 327262306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, key, *keylen, 1); 327362306a36Sopenharmony_ci print_hex_dump_debug("shdesc@" __stringify(__LINE__)": ", 327462306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 327562306a36Sopenharmony_ci 1); 327662306a36Sopenharmony_ci 327762306a36Sopenharmony_ci result.err = 0; 327862306a36Sopenharmony_ci init_completion(&result.completion); 327962306a36Sopenharmony_ci result.dev = ctx->dev; 328062306a36Sopenharmony_ci 328162306a36Sopenharmony_ci req_ctx->flc = flc; 328262306a36Sopenharmony_ci req_ctx->flc_dma = flc_dma; 328362306a36Sopenharmony_ci req_ctx->cbk = split_key_sh_done; 328462306a36Sopenharmony_ci req_ctx->ctx = &result; 328562306a36Sopenharmony_ci 328662306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, req_ctx); 328762306a36Sopenharmony_ci if (ret == -EINPROGRESS) { 328862306a36Sopenharmony_ci /* in progress */ 328962306a36Sopenharmony_ci wait_for_completion(&result.completion); 329062306a36Sopenharmony_ci ret = result.err; 329162306a36Sopenharmony_ci print_hex_dump_debug("digested key@" __stringify(__LINE__)": ", 329262306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, key, 329362306a36Sopenharmony_ci digestsize, 1); 329462306a36Sopenharmony_ci } 329562306a36Sopenharmony_ci 329662306a36Sopenharmony_ci dma_unmap_single(ctx->dev, flc_dma, sizeof(flc->flc) + desc_bytes(desc), 329762306a36Sopenharmony_ci DMA_TO_DEVICE); 329862306a36Sopenharmony_cierr_flc_dma: 329962306a36Sopenharmony_ci dma_unmap_single(ctx->dev, key_dma, *keylen, DMA_BIDIRECTIONAL); 330062306a36Sopenharmony_cierr_key_dma: 330162306a36Sopenharmony_ci kfree(flc); 330262306a36Sopenharmony_cierr_flc: 330362306a36Sopenharmony_ci kfree(req_ctx); 330462306a36Sopenharmony_ci 330562306a36Sopenharmony_ci *keylen = digestsize; 330662306a36Sopenharmony_ci 330762306a36Sopenharmony_ci return ret; 330862306a36Sopenharmony_ci} 330962306a36Sopenharmony_ci 331062306a36Sopenharmony_cistatic int ahash_setkey(struct crypto_ahash *ahash, const u8 *key, 331162306a36Sopenharmony_ci unsigned int keylen) 331262306a36Sopenharmony_ci{ 331362306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 331462306a36Sopenharmony_ci unsigned int blocksize = crypto_tfm_alg_blocksize(&ahash->base); 331562306a36Sopenharmony_ci unsigned int digestsize = crypto_ahash_digestsize(ahash); 331662306a36Sopenharmony_ci int ret; 331762306a36Sopenharmony_ci u8 *hashed_key = NULL; 331862306a36Sopenharmony_ci 331962306a36Sopenharmony_ci dev_dbg(ctx->dev, "keylen %d blocksize %d\n", keylen, blocksize); 332062306a36Sopenharmony_ci 332162306a36Sopenharmony_ci if (keylen > blocksize) { 332262306a36Sopenharmony_ci unsigned int aligned_len = 332362306a36Sopenharmony_ci ALIGN(keylen, dma_get_cache_alignment()); 332462306a36Sopenharmony_ci 332562306a36Sopenharmony_ci if (aligned_len < keylen) 332662306a36Sopenharmony_ci return -EOVERFLOW; 332762306a36Sopenharmony_ci 332862306a36Sopenharmony_ci hashed_key = kmemdup(key, aligned_len, GFP_KERNEL); 332962306a36Sopenharmony_ci if (!hashed_key) 333062306a36Sopenharmony_ci return -ENOMEM; 333162306a36Sopenharmony_ci ret = hash_digest_key(ctx, &keylen, hashed_key, digestsize); 333262306a36Sopenharmony_ci if (ret) 333362306a36Sopenharmony_ci goto bad_free_key; 333462306a36Sopenharmony_ci key = hashed_key; 333562306a36Sopenharmony_ci } 333662306a36Sopenharmony_ci 333762306a36Sopenharmony_ci ctx->adata.keylen = keylen; 333862306a36Sopenharmony_ci ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype & 333962306a36Sopenharmony_ci OP_ALG_ALGSEL_MASK); 334062306a36Sopenharmony_ci if (ctx->adata.keylen_pad > CAAM_MAX_HASH_KEY_SIZE) 334162306a36Sopenharmony_ci goto bad_free_key; 334262306a36Sopenharmony_ci 334362306a36Sopenharmony_ci ctx->adata.key_virt = key; 334462306a36Sopenharmony_ci ctx->adata.key_inline = true; 334562306a36Sopenharmony_ci 334662306a36Sopenharmony_ci /* 334762306a36Sopenharmony_ci * In case |user key| > |derived key|, using DKP<imm,imm> would result 334862306a36Sopenharmony_ci * in invalid opcodes (last bytes of user key) in the resulting 334962306a36Sopenharmony_ci * descriptor. Use DKP<ptr,imm> instead => both virtual and dma key 335062306a36Sopenharmony_ci * addresses are needed. 335162306a36Sopenharmony_ci */ 335262306a36Sopenharmony_ci if (keylen > ctx->adata.keylen_pad) { 335362306a36Sopenharmony_ci memcpy(ctx->key, key, keylen); 335462306a36Sopenharmony_ci dma_sync_single_for_device(ctx->dev, ctx->adata.key_dma, 335562306a36Sopenharmony_ci ctx->adata.keylen_pad, 335662306a36Sopenharmony_ci DMA_TO_DEVICE); 335762306a36Sopenharmony_ci } 335862306a36Sopenharmony_ci 335962306a36Sopenharmony_ci ret = ahash_set_sh_desc(ahash); 336062306a36Sopenharmony_ci kfree(hashed_key); 336162306a36Sopenharmony_ci return ret; 336262306a36Sopenharmony_cibad_free_key: 336362306a36Sopenharmony_ci kfree(hashed_key); 336462306a36Sopenharmony_ci return -EINVAL; 336562306a36Sopenharmony_ci} 336662306a36Sopenharmony_ci 336762306a36Sopenharmony_cistatic inline void ahash_unmap(struct device *dev, struct ahash_edesc *edesc, 336862306a36Sopenharmony_ci struct ahash_request *req) 336962306a36Sopenharmony_ci{ 337062306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 337162306a36Sopenharmony_ci 337262306a36Sopenharmony_ci if (edesc->src_nents) 337362306a36Sopenharmony_ci dma_unmap_sg(dev, req->src, edesc->src_nents, DMA_TO_DEVICE); 337462306a36Sopenharmony_ci 337562306a36Sopenharmony_ci if (edesc->qm_sg_bytes) 337662306a36Sopenharmony_ci dma_unmap_single(dev, edesc->qm_sg_dma, edesc->qm_sg_bytes, 337762306a36Sopenharmony_ci DMA_TO_DEVICE); 337862306a36Sopenharmony_ci 337962306a36Sopenharmony_ci if (state->buf_dma) { 338062306a36Sopenharmony_ci dma_unmap_single(dev, state->buf_dma, state->buflen, 338162306a36Sopenharmony_ci DMA_TO_DEVICE); 338262306a36Sopenharmony_ci state->buf_dma = 0; 338362306a36Sopenharmony_ci } 338462306a36Sopenharmony_ci} 338562306a36Sopenharmony_ci 338662306a36Sopenharmony_cistatic inline void ahash_unmap_ctx(struct device *dev, 338762306a36Sopenharmony_ci struct ahash_edesc *edesc, 338862306a36Sopenharmony_ci struct ahash_request *req, u32 flag) 338962306a36Sopenharmony_ci{ 339062306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 339162306a36Sopenharmony_ci 339262306a36Sopenharmony_ci if (state->ctx_dma) { 339362306a36Sopenharmony_ci dma_unmap_single(dev, state->ctx_dma, state->ctx_dma_len, flag); 339462306a36Sopenharmony_ci state->ctx_dma = 0; 339562306a36Sopenharmony_ci } 339662306a36Sopenharmony_ci ahash_unmap(dev, edesc, req); 339762306a36Sopenharmony_ci} 339862306a36Sopenharmony_ci 339962306a36Sopenharmony_cistatic void ahash_done(void *cbk_ctx, u32 status) 340062306a36Sopenharmony_ci{ 340162306a36Sopenharmony_ci struct crypto_async_request *areq = cbk_ctx; 340262306a36Sopenharmony_ci struct ahash_request *req = ahash_request_cast(areq); 340362306a36Sopenharmony_ci struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 340462306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 340562306a36Sopenharmony_ci struct ahash_edesc *edesc = state->caam_req.edesc; 340662306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 340762306a36Sopenharmony_ci int digestsize = crypto_ahash_digestsize(ahash); 340862306a36Sopenharmony_ci int ecode = 0; 340962306a36Sopenharmony_ci 341062306a36Sopenharmony_ci dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status); 341162306a36Sopenharmony_ci 341262306a36Sopenharmony_ci if (unlikely(status)) 341362306a36Sopenharmony_ci ecode = caam_qi2_strstatus(ctx->dev, status); 341462306a36Sopenharmony_ci 341562306a36Sopenharmony_ci ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE); 341662306a36Sopenharmony_ci memcpy(req->result, state->caam_ctx, digestsize); 341762306a36Sopenharmony_ci qi_cache_free(edesc); 341862306a36Sopenharmony_ci 341962306a36Sopenharmony_ci print_hex_dump_debug("ctx@" __stringify(__LINE__)": ", 342062306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx, 342162306a36Sopenharmony_ci ctx->ctx_len, 1); 342262306a36Sopenharmony_ci 342362306a36Sopenharmony_ci ahash_request_complete(req, ecode); 342462306a36Sopenharmony_ci} 342562306a36Sopenharmony_ci 342662306a36Sopenharmony_cistatic void ahash_done_bi(void *cbk_ctx, u32 status) 342762306a36Sopenharmony_ci{ 342862306a36Sopenharmony_ci struct crypto_async_request *areq = cbk_ctx; 342962306a36Sopenharmony_ci struct ahash_request *req = ahash_request_cast(areq); 343062306a36Sopenharmony_ci struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 343162306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 343262306a36Sopenharmony_ci struct ahash_edesc *edesc = state->caam_req.edesc; 343362306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 343462306a36Sopenharmony_ci int ecode = 0; 343562306a36Sopenharmony_ci 343662306a36Sopenharmony_ci dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status); 343762306a36Sopenharmony_ci 343862306a36Sopenharmony_ci if (unlikely(status)) 343962306a36Sopenharmony_ci ecode = caam_qi2_strstatus(ctx->dev, status); 344062306a36Sopenharmony_ci 344162306a36Sopenharmony_ci ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL); 344262306a36Sopenharmony_ci qi_cache_free(edesc); 344362306a36Sopenharmony_ci 344462306a36Sopenharmony_ci scatterwalk_map_and_copy(state->buf, req->src, 344562306a36Sopenharmony_ci req->nbytes - state->next_buflen, 344662306a36Sopenharmony_ci state->next_buflen, 0); 344762306a36Sopenharmony_ci state->buflen = state->next_buflen; 344862306a36Sopenharmony_ci 344962306a36Sopenharmony_ci print_hex_dump_debug("buf@" __stringify(__LINE__)": ", 345062306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, state->buf, 345162306a36Sopenharmony_ci state->buflen, 1); 345262306a36Sopenharmony_ci 345362306a36Sopenharmony_ci print_hex_dump_debug("ctx@" __stringify(__LINE__)": ", 345462306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx, 345562306a36Sopenharmony_ci ctx->ctx_len, 1); 345662306a36Sopenharmony_ci if (req->result) 345762306a36Sopenharmony_ci print_hex_dump_debug("result@" __stringify(__LINE__)": ", 345862306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, req->result, 345962306a36Sopenharmony_ci crypto_ahash_digestsize(ahash), 1); 346062306a36Sopenharmony_ci 346162306a36Sopenharmony_ci ahash_request_complete(req, ecode); 346262306a36Sopenharmony_ci} 346362306a36Sopenharmony_ci 346462306a36Sopenharmony_cistatic void ahash_done_ctx_src(void *cbk_ctx, u32 status) 346562306a36Sopenharmony_ci{ 346662306a36Sopenharmony_ci struct crypto_async_request *areq = cbk_ctx; 346762306a36Sopenharmony_ci struct ahash_request *req = ahash_request_cast(areq); 346862306a36Sopenharmony_ci struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 346962306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 347062306a36Sopenharmony_ci struct ahash_edesc *edesc = state->caam_req.edesc; 347162306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 347262306a36Sopenharmony_ci int digestsize = crypto_ahash_digestsize(ahash); 347362306a36Sopenharmony_ci int ecode = 0; 347462306a36Sopenharmony_ci 347562306a36Sopenharmony_ci dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status); 347662306a36Sopenharmony_ci 347762306a36Sopenharmony_ci if (unlikely(status)) 347862306a36Sopenharmony_ci ecode = caam_qi2_strstatus(ctx->dev, status); 347962306a36Sopenharmony_ci 348062306a36Sopenharmony_ci ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL); 348162306a36Sopenharmony_ci memcpy(req->result, state->caam_ctx, digestsize); 348262306a36Sopenharmony_ci qi_cache_free(edesc); 348362306a36Sopenharmony_ci 348462306a36Sopenharmony_ci print_hex_dump_debug("ctx@" __stringify(__LINE__)": ", 348562306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx, 348662306a36Sopenharmony_ci ctx->ctx_len, 1); 348762306a36Sopenharmony_ci 348862306a36Sopenharmony_ci ahash_request_complete(req, ecode); 348962306a36Sopenharmony_ci} 349062306a36Sopenharmony_ci 349162306a36Sopenharmony_cistatic void ahash_done_ctx_dst(void *cbk_ctx, u32 status) 349262306a36Sopenharmony_ci{ 349362306a36Sopenharmony_ci struct crypto_async_request *areq = cbk_ctx; 349462306a36Sopenharmony_ci struct ahash_request *req = ahash_request_cast(areq); 349562306a36Sopenharmony_ci struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 349662306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 349762306a36Sopenharmony_ci struct ahash_edesc *edesc = state->caam_req.edesc; 349862306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 349962306a36Sopenharmony_ci int ecode = 0; 350062306a36Sopenharmony_ci 350162306a36Sopenharmony_ci dev_dbg(ctx->dev, "%s %d: err 0x%x\n", __func__, __LINE__, status); 350262306a36Sopenharmony_ci 350362306a36Sopenharmony_ci if (unlikely(status)) 350462306a36Sopenharmony_ci ecode = caam_qi2_strstatus(ctx->dev, status); 350562306a36Sopenharmony_ci 350662306a36Sopenharmony_ci ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE); 350762306a36Sopenharmony_ci qi_cache_free(edesc); 350862306a36Sopenharmony_ci 350962306a36Sopenharmony_ci scatterwalk_map_and_copy(state->buf, req->src, 351062306a36Sopenharmony_ci req->nbytes - state->next_buflen, 351162306a36Sopenharmony_ci state->next_buflen, 0); 351262306a36Sopenharmony_ci state->buflen = state->next_buflen; 351362306a36Sopenharmony_ci 351462306a36Sopenharmony_ci print_hex_dump_debug("buf@" __stringify(__LINE__)": ", 351562306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, state->buf, 351662306a36Sopenharmony_ci state->buflen, 1); 351762306a36Sopenharmony_ci 351862306a36Sopenharmony_ci print_hex_dump_debug("ctx@" __stringify(__LINE__)": ", 351962306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, state->caam_ctx, 352062306a36Sopenharmony_ci ctx->ctx_len, 1); 352162306a36Sopenharmony_ci if (req->result) 352262306a36Sopenharmony_ci print_hex_dump_debug("result@" __stringify(__LINE__)": ", 352362306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, req->result, 352462306a36Sopenharmony_ci crypto_ahash_digestsize(ahash), 1); 352562306a36Sopenharmony_ci 352662306a36Sopenharmony_ci ahash_request_complete(req, ecode); 352762306a36Sopenharmony_ci} 352862306a36Sopenharmony_ci 352962306a36Sopenharmony_cistatic int ahash_update_ctx(struct ahash_request *req) 353062306a36Sopenharmony_ci{ 353162306a36Sopenharmony_ci struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 353262306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 353362306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 353462306a36Sopenharmony_ci struct caam_request *req_ctx = &state->caam_req; 353562306a36Sopenharmony_ci struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; 353662306a36Sopenharmony_ci struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; 353762306a36Sopenharmony_ci gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 353862306a36Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 353962306a36Sopenharmony_ci u8 *buf = state->buf; 354062306a36Sopenharmony_ci int *buflen = &state->buflen; 354162306a36Sopenharmony_ci int *next_buflen = &state->next_buflen; 354262306a36Sopenharmony_ci int in_len = *buflen + req->nbytes, to_hash; 354362306a36Sopenharmony_ci int src_nents, mapped_nents, qm_sg_bytes, qm_sg_src_index; 354462306a36Sopenharmony_ci struct ahash_edesc *edesc; 354562306a36Sopenharmony_ci int ret = 0; 354662306a36Sopenharmony_ci 354762306a36Sopenharmony_ci *next_buflen = in_len & (crypto_tfm_alg_blocksize(&ahash->base) - 1); 354862306a36Sopenharmony_ci to_hash = in_len - *next_buflen; 354962306a36Sopenharmony_ci 355062306a36Sopenharmony_ci if (to_hash) { 355162306a36Sopenharmony_ci struct dpaa2_sg_entry *sg_table; 355262306a36Sopenharmony_ci int src_len = req->nbytes - *next_buflen; 355362306a36Sopenharmony_ci 355462306a36Sopenharmony_ci src_nents = sg_nents_for_len(req->src, src_len); 355562306a36Sopenharmony_ci if (src_nents < 0) { 355662306a36Sopenharmony_ci dev_err(ctx->dev, "Invalid number of src SG.\n"); 355762306a36Sopenharmony_ci return src_nents; 355862306a36Sopenharmony_ci } 355962306a36Sopenharmony_ci 356062306a36Sopenharmony_ci if (src_nents) { 356162306a36Sopenharmony_ci mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents, 356262306a36Sopenharmony_ci DMA_TO_DEVICE); 356362306a36Sopenharmony_ci if (!mapped_nents) { 356462306a36Sopenharmony_ci dev_err(ctx->dev, "unable to DMA map source\n"); 356562306a36Sopenharmony_ci return -ENOMEM; 356662306a36Sopenharmony_ci } 356762306a36Sopenharmony_ci } else { 356862306a36Sopenharmony_ci mapped_nents = 0; 356962306a36Sopenharmony_ci } 357062306a36Sopenharmony_ci 357162306a36Sopenharmony_ci /* allocate space for base edesc and link tables */ 357262306a36Sopenharmony_ci edesc = qi_cache_zalloc(flags); 357362306a36Sopenharmony_ci if (!edesc) { 357462306a36Sopenharmony_ci dma_unmap_sg(ctx->dev, req->src, src_nents, 357562306a36Sopenharmony_ci DMA_TO_DEVICE); 357662306a36Sopenharmony_ci return -ENOMEM; 357762306a36Sopenharmony_ci } 357862306a36Sopenharmony_ci 357962306a36Sopenharmony_ci edesc->src_nents = src_nents; 358062306a36Sopenharmony_ci qm_sg_src_index = 1 + (*buflen ? 1 : 0); 358162306a36Sopenharmony_ci qm_sg_bytes = pad_sg_nents(qm_sg_src_index + mapped_nents) * 358262306a36Sopenharmony_ci sizeof(*sg_table); 358362306a36Sopenharmony_ci sg_table = &edesc->sgt[0]; 358462306a36Sopenharmony_ci 358562306a36Sopenharmony_ci ret = ctx_map_to_qm_sg(ctx->dev, state, ctx->ctx_len, sg_table, 358662306a36Sopenharmony_ci DMA_BIDIRECTIONAL); 358762306a36Sopenharmony_ci if (ret) 358862306a36Sopenharmony_ci goto unmap_ctx; 358962306a36Sopenharmony_ci 359062306a36Sopenharmony_ci ret = buf_map_to_qm_sg(ctx->dev, sg_table + 1, state); 359162306a36Sopenharmony_ci if (ret) 359262306a36Sopenharmony_ci goto unmap_ctx; 359362306a36Sopenharmony_ci 359462306a36Sopenharmony_ci if (mapped_nents) { 359562306a36Sopenharmony_ci sg_to_qm_sg_last(req->src, src_len, 359662306a36Sopenharmony_ci sg_table + qm_sg_src_index, 0); 359762306a36Sopenharmony_ci } else { 359862306a36Sopenharmony_ci dpaa2_sg_set_final(sg_table + qm_sg_src_index - 1, 359962306a36Sopenharmony_ci true); 360062306a36Sopenharmony_ci } 360162306a36Sopenharmony_ci 360262306a36Sopenharmony_ci edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, 360362306a36Sopenharmony_ci qm_sg_bytes, DMA_TO_DEVICE); 360462306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) { 360562306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map S/G table\n"); 360662306a36Sopenharmony_ci ret = -ENOMEM; 360762306a36Sopenharmony_ci goto unmap_ctx; 360862306a36Sopenharmony_ci } 360962306a36Sopenharmony_ci edesc->qm_sg_bytes = qm_sg_bytes; 361062306a36Sopenharmony_ci 361162306a36Sopenharmony_ci memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); 361262306a36Sopenharmony_ci dpaa2_fl_set_final(in_fle, true); 361362306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); 361462306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); 361562306a36Sopenharmony_ci dpaa2_fl_set_len(in_fle, ctx->ctx_len + to_hash); 361662306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_single); 361762306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, state->ctx_dma); 361862306a36Sopenharmony_ci dpaa2_fl_set_len(out_fle, ctx->ctx_len); 361962306a36Sopenharmony_ci 362062306a36Sopenharmony_ci req_ctx->flc = &ctx->flc[UPDATE]; 362162306a36Sopenharmony_ci req_ctx->flc_dma = ctx->flc_dma[UPDATE]; 362262306a36Sopenharmony_ci req_ctx->cbk = ahash_done_bi; 362362306a36Sopenharmony_ci req_ctx->ctx = &req->base; 362462306a36Sopenharmony_ci req_ctx->edesc = edesc; 362562306a36Sopenharmony_ci 362662306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, req_ctx); 362762306a36Sopenharmony_ci if (ret != -EINPROGRESS && 362862306a36Sopenharmony_ci !(ret == -EBUSY && 362962306a36Sopenharmony_ci req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) 363062306a36Sopenharmony_ci goto unmap_ctx; 363162306a36Sopenharmony_ci } else if (*next_buflen) { 363262306a36Sopenharmony_ci scatterwalk_map_and_copy(buf + *buflen, req->src, 0, 363362306a36Sopenharmony_ci req->nbytes, 0); 363462306a36Sopenharmony_ci *buflen = *next_buflen; 363562306a36Sopenharmony_ci 363662306a36Sopenharmony_ci print_hex_dump_debug("buf@" __stringify(__LINE__)": ", 363762306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, buf, 363862306a36Sopenharmony_ci *buflen, 1); 363962306a36Sopenharmony_ci } 364062306a36Sopenharmony_ci 364162306a36Sopenharmony_ci return ret; 364262306a36Sopenharmony_ciunmap_ctx: 364362306a36Sopenharmony_ci ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL); 364462306a36Sopenharmony_ci qi_cache_free(edesc); 364562306a36Sopenharmony_ci return ret; 364662306a36Sopenharmony_ci} 364762306a36Sopenharmony_ci 364862306a36Sopenharmony_cistatic int ahash_final_ctx(struct ahash_request *req) 364962306a36Sopenharmony_ci{ 365062306a36Sopenharmony_ci struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 365162306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 365262306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 365362306a36Sopenharmony_ci struct caam_request *req_ctx = &state->caam_req; 365462306a36Sopenharmony_ci struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; 365562306a36Sopenharmony_ci struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; 365662306a36Sopenharmony_ci gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 365762306a36Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 365862306a36Sopenharmony_ci int buflen = state->buflen; 365962306a36Sopenharmony_ci int qm_sg_bytes; 366062306a36Sopenharmony_ci int digestsize = crypto_ahash_digestsize(ahash); 366162306a36Sopenharmony_ci struct ahash_edesc *edesc; 366262306a36Sopenharmony_ci struct dpaa2_sg_entry *sg_table; 366362306a36Sopenharmony_ci int ret; 366462306a36Sopenharmony_ci 366562306a36Sopenharmony_ci /* allocate space for base edesc and link tables */ 366662306a36Sopenharmony_ci edesc = qi_cache_zalloc(flags); 366762306a36Sopenharmony_ci if (!edesc) 366862306a36Sopenharmony_ci return -ENOMEM; 366962306a36Sopenharmony_ci 367062306a36Sopenharmony_ci qm_sg_bytes = pad_sg_nents(1 + (buflen ? 1 : 0)) * sizeof(*sg_table); 367162306a36Sopenharmony_ci sg_table = &edesc->sgt[0]; 367262306a36Sopenharmony_ci 367362306a36Sopenharmony_ci ret = ctx_map_to_qm_sg(ctx->dev, state, ctx->ctx_len, sg_table, 367462306a36Sopenharmony_ci DMA_BIDIRECTIONAL); 367562306a36Sopenharmony_ci if (ret) 367662306a36Sopenharmony_ci goto unmap_ctx; 367762306a36Sopenharmony_ci 367862306a36Sopenharmony_ci ret = buf_map_to_qm_sg(ctx->dev, sg_table + 1, state); 367962306a36Sopenharmony_ci if (ret) 368062306a36Sopenharmony_ci goto unmap_ctx; 368162306a36Sopenharmony_ci 368262306a36Sopenharmony_ci dpaa2_sg_set_final(sg_table + (buflen ? 1 : 0), true); 368362306a36Sopenharmony_ci 368462306a36Sopenharmony_ci edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, qm_sg_bytes, 368562306a36Sopenharmony_ci DMA_TO_DEVICE); 368662306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) { 368762306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map S/G table\n"); 368862306a36Sopenharmony_ci ret = -ENOMEM; 368962306a36Sopenharmony_ci goto unmap_ctx; 369062306a36Sopenharmony_ci } 369162306a36Sopenharmony_ci edesc->qm_sg_bytes = qm_sg_bytes; 369262306a36Sopenharmony_ci 369362306a36Sopenharmony_ci memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); 369462306a36Sopenharmony_ci dpaa2_fl_set_final(in_fle, true); 369562306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); 369662306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); 369762306a36Sopenharmony_ci dpaa2_fl_set_len(in_fle, ctx->ctx_len + buflen); 369862306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_single); 369962306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, state->ctx_dma); 370062306a36Sopenharmony_ci dpaa2_fl_set_len(out_fle, digestsize); 370162306a36Sopenharmony_ci 370262306a36Sopenharmony_ci req_ctx->flc = &ctx->flc[FINALIZE]; 370362306a36Sopenharmony_ci req_ctx->flc_dma = ctx->flc_dma[FINALIZE]; 370462306a36Sopenharmony_ci req_ctx->cbk = ahash_done_ctx_src; 370562306a36Sopenharmony_ci req_ctx->ctx = &req->base; 370662306a36Sopenharmony_ci req_ctx->edesc = edesc; 370762306a36Sopenharmony_ci 370862306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, req_ctx); 370962306a36Sopenharmony_ci if (ret == -EINPROGRESS || 371062306a36Sopenharmony_ci (ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) 371162306a36Sopenharmony_ci return ret; 371262306a36Sopenharmony_ci 371362306a36Sopenharmony_ciunmap_ctx: 371462306a36Sopenharmony_ci ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL); 371562306a36Sopenharmony_ci qi_cache_free(edesc); 371662306a36Sopenharmony_ci return ret; 371762306a36Sopenharmony_ci} 371862306a36Sopenharmony_ci 371962306a36Sopenharmony_cistatic int ahash_finup_ctx(struct ahash_request *req) 372062306a36Sopenharmony_ci{ 372162306a36Sopenharmony_ci struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 372262306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 372362306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 372462306a36Sopenharmony_ci struct caam_request *req_ctx = &state->caam_req; 372562306a36Sopenharmony_ci struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; 372662306a36Sopenharmony_ci struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; 372762306a36Sopenharmony_ci gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 372862306a36Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 372962306a36Sopenharmony_ci int buflen = state->buflen; 373062306a36Sopenharmony_ci int qm_sg_bytes, qm_sg_src_index; 373162306a36Sopenharmony_ci int src_nents, mapped_nents; 373262306a36Sopenharmony_ci int digestsize = crypto_ahash_digestsize(ahash); 373362306a36Sopenharmony_ci struct ahash_edesc *edesc; 373462306a36Sopenharmony_ci struct dpaa2_sg_entry *sg_table; 373562306a36Sopenharmony_ci int ret; 373662306a36Sopenharmony_ci 373762306a36Sopenharmony_ci src_nents = sg_nents_for_len(req->src, req->nbytes); 373862306a36Sopenharmony_ci if (src_nents < 0) { 373962306a36Sopenharmony_ci dev_err(ctx->dev, "Invalid number of src SG.\n"); 374062306a36Sopenharmony_ci return src_nents; 374162306a36Sopenharmony_ci } 374262306a36Sopenharmony_ci 374362306a36Sopenharmony_ci if (src_nents) { 374462306a36Sopenharmony_ci mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents, 374562306a36Sopenharmony_ci DMA_TO_DEVICE); 374662306a36Sopenharmony_ci if (!mapped_nents) { 374762306a36Sopenharmony_ci dev_err(ctx->dev, "unable to DMA map source\n"); 374862306a36Sopenharmony_ci return -ENOMEM; 374962306a36Sopenharmony_ci } 375062306a36Sopenharmony_ci } else { 375162306a36Sopenharmony_ci mapped_nents = 0; 375262306a36Sopenharmony_ci } 375362306a36Sopenharmony_ci 375462306a36Sopenharmony_ci /* allocate space for base edesc and link tables */ 375562306a36Sopenharmony_ci edesc = qi_cache_zalloc(flags); 375662306a36Sopenharmony_ci if (!edesc) { 375762306a36Sopenharmony_ci dma_unmap_sg(ctx->dev, req->src, src_nents, DMA_TO_DEVICE); 375862306a36Sopenharmony_ci return -ENOMEM; 375962306a36Sopenharmony_ci } 376062306a36Sopenharmony_ci 376162306a36Sopenharmony_ci edesc->src_nents = src_nents; 376262306a36Sopenharmony_ci qm_sg_src_index = 1 + (buflen ? 1 : 0); 376362306a36Sopenharmony_ci qm_sg_bytes = pad_sg_nents(qm_sg_src_index + mapped_nents) * 376462306a36Sopenharmony_ci sizeof(*sg_table); 376562306a36Sopenharmony_ci sg_table = &edesc->sgt[0]; 376662306a36Sopenharmony_ci 376762306a36Sopenharmony_ci ret = ctx_map_to_qm_sg(ctx->dev, state, ctx->ctx_len, sg_table, 376862306a36Sopenharmony_ci DMA_BIDIRECTIONAL); 376962306a36Sopenharmony_ci if (ret) 377062306a36Sopenharmony_ci goto unmap_ctx; 377162306a36Sopenharmony_ci 377262306a36Sopenharmony_ci ret = buf_map_to_qm_sg(ctx->dev, sg_table + 1, state); 377362306a36Sopenharmony_ci if (ret) 377462306a36Sopenharmony_ci goto unmap_ctx; 377562306a36Sopenharmony_ci 377662306a36Sopenharmony_ci sg_to_qm_sg_last(req->src, req->nbytes, sg_table + qm_sg_src_index, 0); 377762306a36Sopenharmony_ci 377862306a36Sopenharmony_ci edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, qm_sg_bytes, 377962306a36Sopenharmony_ci DMA_TO_DEVICE); 378062306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) { 378162306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map S/G table\n"); 378262306a36Sopenharmony_ci ret = -ENOMEM; 378362306a36Sopenharmony_ci goto unmap_ctx; 378462306a36Sopenharmony_ci } 378562306a36Sopenharmony_ci edesc->qm_sg_bytes = qm_sg_bytes; 378662306a36Sopenharmony_ci 378762306a36Sopenharmony_ci memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); 378862306a36Sopenharmony_ci dpaa2_fl_set_final(in_fle, true); 378962306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); 379062306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); 379162306a36Sopenharmony_ci dpaa2_fl_set_len(in_fle, ctx->ctx_len + buflen + req->nbytes); 379262306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_single); 379362306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, state->ctx_dma); 379462306a36Sopenharmony_ci dpaa2_fl_set_len(out_fle, digestsize); 379562306a36Sopenharmony_ci 379662306a36Sopenharmony_ci req_ctx->flc = &ctx->flc[FINALIZE]; 379762306a36Sopenharmony_ci req_ctx->flc_dma = ctx->flc_dma[FINALIZE]; 379862306a36Sopenharmony_ci req_ctx->cbk = ahash_done_ctx_src; 379962306a36Sopenharmony_ci req_ctx->ctx = &req->base; 380062306a36Sopenharmony_ci req_ctx->edesc = edesc; 380162306a36Sopenharmony_ci 380262306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, req_ctx); 380362306a36Sopenharmony_ci if (ret == -EINPROGRESS || 380462306a36Sopenharmony_ci (ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) 380562306a36Sopenharmony_ci return ret; 380662306a36Sopenharmony_ci 380762306a36Sopenharmony_ciunmap_ctx: 380862306a36Sopenharmony_ci ahash_unmap_ctx(ctx->dev, edesc, req, DMA_BIDIRECTIONAL); 380962306a36Sopenharmony_ci qi_cache_free(edesc); 381062306a36Sopenharmony_ci return ret; 381162306a36Sopenharmony_ci} 381262306a36Sopenharmony_ci 381362306a36Sopenharmony_cistatic int ahash_digest(struct ahash_request *req) 381462306a36Sopenharmony_ci{ 381562306a36Sopenharmony_ci struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 381662306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 381762306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 381862306a36Sopenharmony_ci struct caam_request *req_ctx = &state->caam_req; 381962306a36Sopenharmony_ci struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; 382062306a36Sopenharmony_ci struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; 382162306a36Sopenharmony_ci gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 382262306a36Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 382362306a36Sopenharmony_ci int digestsize = crypto_ahash_digestsize(ahash); 382462306a36Sopenharmony_ci int src_nents, mapped_nents; 382562306a36Sopenharmony_ci struct ahash_edesc *edesc; 382662306a36Sopenharmony_ci int ret = -ENOMEM; 382762306a36Sopenharmony_ci 382862306a36Sopenharmony_ci state->buf_dma = 0; 382962306a36Sopenharmony_ci 383062306a36Sopenharmony_ci src_nents = sg_nents_for_len(req->src, req->nbytes); 383162306a36Sopenharmony_ci if (src_nents < 0) { 383262306a36Sopenharmony_ci dev_err(ctx->dev, "Invalid number of src SG.\n"); 383362306a36Sopenharmony_ci return src_nents; 383462306a36Sopenharmony_ci } 383562306a36Sopenharmony_ci 383662306a36Sopenharmony_ci if (src_nents) { 383762306a36Sopenharmony_ci mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents, 383862306a36Sopenharmony_ci DMA_TO_DEVICE); 383962306a36Sopenharmony_ci if (!mapped_nents) { 384062306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map source for DMA\n"); 384162306a36Sopenharmony_ci return ret; 384262306a36Sopenharmony_ci } 384362306a36Sopenharmony_ci } else { 384462306a36Sopenharmony_ci mapped_nents = 0; 384562306a36Sopenharmony_ci } 384662306a36Sopenharmony_ci 384762306a36Sopenharmony_ci /* allocate space for base edesc and link tables */ 384862306a36Sopenharmony_ci edesc = qi_cache_zalloc(flags); 384962306a36Sopenharmony_ci if (!edesc) { 385062306a36Sopenharmony_ci dma_unmap_sg(ctx->dev, req->src, src_nents, DMA_TO_DEVICE); 385162306a36Sopenharmony_ci return ret; 385262306a36Sopenharmony_ci } 385362306a36Sopenharmony_ci 385462306a36Sopenharmony_ci edesc->src_nents = src_nents; 385562306a36Sopenharmony_ci memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); 385662306a36Sopenharmony_ci 385762306a36Sopenharmony_ci if (mapped_nents > 1) { 385862306a36Sopenharmony_ci int qm_sg_bytes; 385962306a36Sopenharmony_ci struct dpaa2_sg_entry *sg_table = &edesc->sgt[0]; 386062306a36Sopenharmony_ci 386162306a36Sopenharmony_ci qm_sg_bytes = pad_sg_nents(mapped_nents) * sizeof(*sg_table); 386262306a36Sopenharmony_ci sg_to_qm_sg_last(req->src, req->nbytes, sg_table, 0); 386362306a36Sopenharmony_ci edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, 386462306a36Sopenharmony_ci qm_sg_bytes, DMA_TO_DEVICE); 386562306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) { 386662306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map S/G table\n"); 386762306a36Sopenharmony_ci goto unmap; 386862306a36Sopenharmony_ci } 386962306a36Sopenharmony_ci edesc->qm_sg_bytes = qm_sg_bytes; 387062306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); 387162306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); 387262306a36Sopenharmony_ci } else { 387362306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_single); 387462306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, sg_dma_address(req->src)); 387562306a36Sopenharmony_ci } 387662306a36Sopenharmony_ci 387762306a36Sopenharmony_ci state->ctx_dma_len = digestsize; 387862306a36Sopenharmony_ci state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, digestsize, 387962306a36Sopenharmony_ci DMA_FROM_DEVICE); 388062306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, state->ctx_dma)) { 388162306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map ctx\n"); 388262306a36Sopenharmony_ci state->ctx_dma = 0; 388362306a36Sopenharmony_ci goto unmap; 388462306a36Sopenharmony_ci } 388562306a36Sopenharmony_ci 388662306a36Sopenharmony_ci dpaa2_fl_set_final(in_fle, true); 388762306a36Sopenharmony_ci dpaa2_fl_set_len(in_fle, req->nbytes); 388862306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_single); 388962306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, state->ctx_dma); 389062306a36Sopenharmony_ci dpaa2_fl_set_len(out_fle, digestsize); 389162306a36Sopenharmony_ci 389262306a36Sopenharmony_ci req_ctx->flc = &ctx->flc[DIGEST]; 389362306a36Sopenharmony_ci req_ctx->flc_dma = ctx->flc_dma[DIGEST]; 389462306a36Sopenharmony_ci req_ctx->cbk = ahash_done; 389562306a36Sopenharmony_ci req_ctx->ctx = &req->base; 389662306a36Sopenharmony_ci req_ctx->edesc = edesc; 389762306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, req_ctx); 389862306a36Sopenharmony_ci if (ret == -EINPROGRESS || 389962306a36Sopenharmony_ci (ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) 390062306a36Sopenharmony_ci return ret; 390162306a36Sopenharmony_ci 390262306a36Sopenharmony_ciunmap: 390362306a36Sopenharmony_ci ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE); 390462306a36Sopenharmony_ci qi_cache_free(edesc); 390562306a36Sopenharmony_ci return ret; 390662306a36Sopenharmony_ci} 390762306a36Sopenharmony_ci 390862306a36Sopenharmony_cistatic int ahash_final_no_ctx(struct ahash_request *req) 390962306a36Sopenharmony_ci{ 391062306a36Sopenharmony_ci struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 391162306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 391262306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 391362306a36Sopenharmony_ci struct caam_request *req_ctx = &state->caam_req; 391462306a36Sopenharmony_ci struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; 391562306a36Sopenharmony_ci struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; 391662306a36Sopenharmony_ci gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 391762306a36Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 391862306a36Sopenharmony_ci u8 *buf = state->buf; 391962306a36Sopenharmony_ci int buflen = state->buflen; 392062306a36Sopenharmony_ci int digestsize = crypto_ahash_digestsize(ahash); 392162306a36Sopenharmony_ci struct ahash_edesc *edesc; 392262306a36Sopenharmony_ci int ret = -ENOMEM; 392362306a36Sopenharmony_ci 392462306a36Sopenharmony_ci /* allocate space for base edesc and link tables */ 392562306a36Sopenharmony_ci edesc = qi_cache_zalloc(flags); 392662306a36Sopenharmony_ci if (!edesc) 392762306a36Sopenharmony_ci return ret; 392862306a36Sopenharmony_ci 392962306a36Sopenharmony_ci if (buflen) { 393062306a36Sopenharmony_ci state->buf_dma = dma_map_single(ctx->dev, buf, buflen, 393162306a36Sopenharmony_ci DMA_TO_DEVICE); 393262306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, state->buf_dma)) { 393362306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map src\n"); 393462306a36Sopenharmony_ci goto unmap; 393562306a36Sopenharmony_ci } 393662306a36Sopenharmony_ci } 393762306a36Sopenharmony_ci 393862306a36Sopenharmony_ci state->ctx_dma_len = digestsize; 393962306a36Sopenharmony_ci state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, digestsize, 394062306a36Sopenharmony_ci DMA_FROM_DEVICE); 394162306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, state->ctx_dma)) { 394262306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map ctx\n"); 394362306a36Sopenharmony_ci state->ctx_dma = 0; 394462306a36Sopenharmony_ci goto unmap; 394562306a36Sopenharmony_ci } 394662306a36Sopenharmony_ci 394762306a36Sopenharmony_ci memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); 394862306a36Sopenharmony_ci dpaa2_fl_set_final(in_fle, true); 394962306a36Sopenharmony_ci /* 395062306a36Sopenharmony_ci * crypto engine requires the input entry to be present when 395162306a36Sopenharmony_ci * "frame list" FD is used. 395262306a36Sopenharmony_ci * Since engine does not support FMT=2'b11 (unused entry type), leaving 395362306a36Sopenharmony_ci * in_fle zeroized (except for "Final" flag) is the best option. 395462306a36Sopenharmony_ci */ 395562306a36Sopenharmony_ci if (buflen) { 395662306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_single); 395762306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, state->buf_dma); 395862306a36Sopenharmony_ci dpaa2_fl_set_len(in_fle, buflen); 395962306a36Sopenharmony_ci } 396062306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_single); 396162306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, state->ctx_dma); 396262306a36Sopenharmony_ci dpaa2_fl_set_len(out_fle, digestsize); 396362306a36Sopenharmony_ci 396462306a36Sopenharmony_ci req_ctx->flc = &ctx->flc[DIGEST]; 396562306a36Sopenharmony_ci req_ctx->flc_dma = ctx->flc_dma[DIGEST]; 396662306a36Sopenharmony_ci req_ctx->cbk = ahash_done; 396762306a36Sopenharmony_ci req_ctx->ctx = &req->base; 396862306a36Sopenharmony_ci req_ctx->edesc = edesc; 396962306a36Sopenharmony_ci 397062306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, req_ctx); 397162306a36Sopenharmony_ci if (ret == -EINPROGRESS || 397262306a36Sopenharmony_ci (ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) 397362306a36Sopenharmony_ci return ret; 397462306a36Sopenharmony_ci 397562306a36Sopenharmony_ciunmap: 397662306a36Sopenharmony_ci ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE); 397762306a36Sopenharmony_ci qi_cache_free(edesc); 397862306a36Sopenharmony_ci return ret; 397962306a36Sopenharmony_ci} 398062306a36Sopenharmony_ci 398162306a36Sopenharmony_cistatic int ahash_update_no_ctx(struct ahash_request *req) 398262306a36Sopenharmony_ci{ 398362306a36Sopenharmony_ci struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 398462306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 398562306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 398662306a36Sopenharmony_ci struct caam_request *req_ctx = &state->caam_req; 398762306a36Sopenharmony_ci struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; 398862306a36Sopenharmony_ci struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; 398962306a36Sopenharmony_ci gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 399062306a36Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 399162306a36Sopenharmony_ci u8 *buf = state->buf; 399262306a36Sopenharmony_ci int *buflen = &state->buflen; 399362306a36Sopenharmony_ci int *next_buflen = &state->next_buflen; 399462306a36Sopenharmony_ci int in_len = *buflen + req->nbytes, to_hash; 399562306a36Sopenharmony_ci int qm_sg_bytes, src_nents, mapped_nents; 399662306a36Sopenharmony_ci struct ahash_edesc *edesc; 399762306a36Sopenharmony_ci int ret = 0; 399862306a36Sopenharmony_ci 399962306a36Sopenharmony_ci *next_buflen = in_len & (crypto_tfm_alg_blocksize(&ahash->base) - 1); 400062306a36Sopenharmony_ci to_hash = in_len - *next_buflen; 400162306a36Sopenharmony_ci 400262306a36Sopenharmony_ci if (to_hash) { 400362306a36Sopenharmony_ci struct dpaa2_sg_entry *sg_table; 400462306a36Sopenharmony_ci int src_len = req->nbytes - *next_buflen; 400562306a36Sopenharmony_ci 400662306a36Sopenharmony_ci src_nents = sg_nents_for_len(req->src, src_len); 400762306a36Sopenharmony_ci if (src_nents < 0) { 400862306a36Sopenharmony_ci dev_err(ctx->dev, "Invalid number of src SG.\n"); 400962306a36Sopenharmony_ci return src_nents; 401062306a36Sopenharmony_ci } 401162306a36Sopenharmony_ci 401262306a36Sopenharmony_ci if (src_nents) { 401362306a36Sopenharmony_ci mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents, 401462306a36Sopenharmony_ci DMA_TO_DEVICE); 401562306a36Sopenharmony_ci if (!mapped_nents) { 401662306a36Sopenharmony_ci dev_err(ctx->dev, "unable to DMA map source\n"); 401762306a36Sopenharmony_ci return -ENOMEM; 401862306a36Sopenharmony_ci } 401962306a36Sopenharmony_ci } else { 402062306a36Sopenharmony_ci mapped_nents = 0; 402162306a36Sopenharmony_ci } 402262306a36Sopenharmony_ci 402362306a36Sopenharmony_ci /* allocate space for base edesc and link tables */ 402462306a36Sopenharmony_ci edesc = qi_cache_zalloc(flags); 402562306a36Sopenharmony_ci if (!edesc) { 402662306a36Sopenharmony_ci dma_unmap_sg(ctx->dev, req->src, src_nents, 402762306a36Sopenharmony_ci DMA_TO_DEVICE); 402862306a36Sopenharmony_ci return -ENOMEM; 402962306a36Sopenharmony_ci } 403062306a36Sopenharmony_ci 403162306a36Sopenharmony_ci edesc->src_nents = src_nents; 403262306a36Sopenharmony_ci qm_sg_bytes = pad_sg_nents(1 + mapped_nents) * 403362306a36Sopenharmony_ci sizeof(*sg_table); 403462306a36Sopenharmony_ci sg_table = &edesc->sgt[0]; 403562306a36Sopenharmony_ci 403662306a36Sopenharmony_ci ret = buf_map_to_qm_sg(ctx->dev, sg_table, state); 403762306a36Sopenharmony_ci if (ret) 403862306a36Sopenharmony_ci goto unmap_ctx; 403962306a36Sopenharmony_ci 404062306a36Sopenharmony_ci sg_to_qm_sg_last(req->src, src_len, sg_table + 1, 0); 404162306a36Sopenharmony_ci 404262306a36Sopenharmony_ci edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, 404362306a36Sopenharmony_ci qm_sg_bytes, DMA_TO_DEVICE); 404462306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) { 404562306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map S/G table\n"); 404662306a36Sopenharmony_ci ret = -ENOMEM; 404762306a36Sopenharmony_ci goto unmap_ctx; 404862306a36Sopenharmony_ci } 404962306a36Sopenharmony_ci edesc->qm_sg_bytes = qm_sg_bytes; 405062306a36Sopenharmony_ci 405162306a36Sopenharmony_ci state->ctx_dma_len = ctx->ctx_len; 405262306a36Sopenharmony_ci state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, 405362306a36Sopenharmony_ci ctx->ctx_len, DMA_FROM_DEVICE); 405462306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, state->ctx_dma)) { 405562306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map ctx\n"); 405662306a36Sopenharmony_ci state->ctx_dma = 0; 405762306a36Sopenharmony_ci ret = -ENOMEM; 405862306a36Sopenharmony_ci goto unmap_ctx; 405962306a36Sopenharmony_ci } 406062306a36Sopenharmony_ci 406162306a36Sopenharmony_ci memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); 406262306a36Sopenharmony_ci dpaa2_fl_set_final(in_fle, true); 406362306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); 406462306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); 406562306a36Sopenharmony_ci dpaa2_fl_set_len(in_fle, to_hash); 406662306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_single); 406762306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, state->ctx_dma); 406862306a36Sopenharmony_ci dpaa2_fl_set_len(out_fle, ctx->ctx_len); 406962306a36Sopenharmony_ci 407062306a36Sopenharmony_ci req_ctx->flc = &ctx->flc[UPDATE_FIRST]; 407162306a36Sopenharmony_ci req_ctx->flc_dma = ctx->flc_dma[UPDATE_FIRST]; 407262306a36Sopenharmony_ci req_ctx->cbk = ahash_done_ctx_dst; 407362306a36Sopenharmony_ci req_ctx->ctx = &req->base; 407462306a36Sopenharmony_ci req_ctx->edesc = edesc; 407562306a36Sopenharmony_ci 407662306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, req_ctx); 407762306a36Sopenharmony_ci if (ret != -EINPROGRESS && 407862306a36Sopenharmony_ci !(ret == -EBUSY && 407962306a36Sopenharmony_ci req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) 408062306a36Sopenharmony_ci goto unmap_ctx; 408162306a36Sopenharmony_ci 408262306a36Sopenharmony_ci state->update = ahash_update_ctx; 408362306a36Sopenharmony_ci state->finup = ahash_finup_ctx; 408462306a36Sopenharmony_ci state->final = ahash_final_ctx; 408562306a36Sopenharmony_ci } else if (*next_buflen) { 408662306a36Sopenharmony_ci scatterwalk_map_and_copy(buf + *buflen, req->src, 0, 408762306a36Sopenharmony_ci req->nbytes, 0); 408862306a36Sopenharmony_ci *buflen = *next_buflen; 408962306a36Sopenharmony_ci 409062306a36Sopenharmony_ci print_hex_dump_debug("buf@" __stringify(__LINE__)": ", 409162306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, buf, 409262306a36Sopenharmony_ci *buflen, 1); 409362306a36Sopenharmony_ci } 409462306a36Sopenharmony_ci 409562306a36Sopenharmony_ci return ret; 409662306a36Sopenharmony_ciunmap_ctx: 409762306a36Sopenharmony_ci ahash_unmap_ctx(ctx->dev, edesc, req, DMA_TO_DEVICE); 409862306a36Sopenharmony_ci qi_cache_free(edesc); 409962306a36Sopenharmony_ci return ret; 410062306a36Sopenharmony_ci} 410162306a36Sopenharmony_ci 410262306a36Sopenharmony_cistatic int ahash_finup_no_ctx(struct ahash_request *req) 410362306a36Sopenharmony_ci{ 410462306a36Sopenharmony_ci struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 410562306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 410662306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 410762306a36Sopenharmony_ci struct caam_request *req_ctx = &state->caam_req; 410862306a36Sopenharmony_ci struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; 410962306a36Sopenharmony_ci struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; 411062306a36Sopenharmony_ci gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 411162306a36Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 411262306a36Sopenharmony_ci int buflen = state->buflen; 411362306a36Sopenharmony_ci int qm_sg_bytes, src_nents, mapped_nents; 411462306a36Sopenharmony_ci int digestsize = crypto_ahash_digestsize(ahash); 411562306a36Sopenharmony_ci struct ahash_edesc *edesc; 411662306a36Sopenharmony_ci struct dpaa2_sg_entry *sg_table; 411762306a36Sopenharmony_ci int ret = -ENOMEM; 411862306a36Sopenharmony_ci 411962306a36Sopenharmony_ci src_nents = sg_nents_for_len(req->src, req->nbytes); 412062306a36Sopenharmony_ci if (src_nents < 0) { 412162306a36Sopenharmony_ci dev_err(ctx->dev, "Invalid number of src SG.\n"); 412262306a36Sopenharmony_ci return src_nents; 412362306a36Sopenharmony_ci } 412462306a36Sopenharmony_ci 412562306a36Sopenharmony_ci if (src_nents) { 412662306a36Sopenharmony_ci mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents, 412762306a36Sopenharmony_ci DMA_TO_DEVICE); 412862306a36Sopenharmony_ci if (!mapped_nents) { 412962306a36Sopenharmony_ci dev_err(ctx->dev, "unable to DMA map source\n"); 413062306a36Sopenharmony_ci return ret; 413162306a36Sopenharmony_ci } 413262306a36Sopenharmony_ci } else { 413362306a36Sopenharmony_ci mapped_nents = 0; 413462306a36Sopenharmony_ci } 413562306a36Sopenharmony_ci 413662306a36Sopenharmony_ci /* allocate space for base edesc and link tables */ 413762306a36Sopenharmony_ci edesc = qi_cache_zalloc(flags); 413862306a36Sopenharmony_ci if (!edesc) { 413962306a36Sopenharmony_ci dma_unmap_sg(ctx->dev, req->src, src_nents, DMA_TO_DEVICE); 414062306a36Sopenharmony_ci return ret; 414162306a36Sopenharmony_ci } 414262306a36Sopenharmony_ci 414362306a36Sopenharmony_ci edesc->src_nents = src_nents; 414462306a36Sopenharmony_ci qm_sg_bytes = pad_sg_nents(2 + mapped_nents) * sizeof(*sg_table); 414562306a36Sopenharmony_ci sg_table = &edesc->sgt[0]; 414662306a36Sopenharmony_ci 414762306a36Sopenharmony_ci ret = buf_map_to_qm_sg(ctx->dev, sg_table, state); 414862306a36Sopenharmony_ci if (ret) 414962306a36Sopenharmony_ci goto unmap; 415062306a36Sopenharmony_ci 415162306a36Sopenharmony_ci sg_to_qm_sg_last(req->src, req->nbytes, sg_table + 1, 0); 415262306a36Sopenharmony_ci 415362306a36Sopenharmony_ci edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, qm_sg_bytes, 415462306a36Sopenharmony_ci DMA_TO_DEVICE); 415562306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) { 415662306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map S/G table\n"); 415762306a36Sopenharmony_ci ret = -ENOMEM; 415862306a36Sopenharmony_ci goto unmap; 415962306a36Sopenharmony_ci } 416062306a36Sopenharmony_ci edesc->qm_sg_bytes = qm_sg_bytes; 416162306a36Sopenharmony_ci 416262306a36Sopenharmony_ci state->ctx_dma_len = digestsize; 416362306a36Sopenharmony_ci state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, digestsize, 416462306a36Sopenharmony_ci DMA_FROM_DEVICE); 416562306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, state->ctx_dma)) { 416662306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map ctx\n"); 416762306a36Sopenharmony_ci state->ctx_dma = 0; 416862306a36Sopenharmony_ci ret = -ENOMEM; 416962306a36Sopenharmony_ci goto unmap; 417062306a36Sopenharmony_ci } 417162306a36Sopenharmony_ci 417262306a36Sopenharmony_ci memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); 417362306a36Sopenharmony_ci dpaa2_fl_set_final(in_fle, true); 417462306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); 417562306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); 417662306a36Sopenharmony_ci dpaa2_fl_set_len(in_fle, buflen + req->nbytes); 417762306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_single); 417862306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, state->ctx_dma); 417962306a36Sopenharmony_ci dpaa2_fl_set_len(out_fle, digestsize); 418062306a36Sopenharmony_ci 418162306a36Sopenharmony_ci req_ctx->flc = &ctx->flc[DIGEST]; 418262306a36Sopenharmony_ci req_ctx->flc_dma = ctx->flc_dma[DIGEST]; 418362306a36Sopenharmony_ci req_ctx->cbk = ahash_done; 418462306a36Sopenharmony_ci req_ctx->ctx = &req->base; 418562306a36Sopenharmony_ci req_ctx->edesc = edesc; 418662306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, req_ctx); 418762306a36Sopenharmony_ci if (ret != -EINPROGRESS && 418862306a36Sopenharmony_ci !(ret == -EBUSY && req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) 418962306a36Sopenharmony_ci goto unmap; 419062306a36Sopenharmony_ci 419162306a36Sopenharmony_ci return ret; 419262306a36Sopenharmony_ciunmap: 419362306a36Sopenharmony_ci ahash_unmap_ctx(ctx->dev, edesc, req, DMA_FROM_DEVICE); 419462306a36Sopenharmony_ci qi_cache_free(edesc); 419562306a36Sopenharmony_ci return ret; 419662306a36Sopenharmony_ci} 419762306a36Sopenharmony_ci 419862306a36Sopenharmony_cistatic int ahash_update_first(struct ahash_request *req) 419962306a36Sopenharmony_ci{ 420062306a36Sopenharmony_ci struct crypto_ahash *ahash = crypto_ahash_reqtfm(req); 420162306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_ahash_ctx_dma(ahash); 420262306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 420362306a36Sopenharmony_ci struct caam_request *req_ctx = &state->caam_req; 420462306a36Sopenharmony_ci struct dpaa2_fl_entry *in_fle = &req_ctx->fd_flt[1]; 420562306a36Sopenharmony_ci struct dpaa2_fl_entry *out_fle = &req_ctx->fd_flt[0]; 420662306a36Sopenharmony_ci gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 420762306a36Sopenharmony_ci GFP_KERNEL : GFP_ATOMIC; 420862306a36Sopenharmony_ci u8 *buf = state->buf; 420962306a36Sopenharmony_ci int *buflen = &state->buflen; 421062306a36Sopenharmony_ci int *next_buflen = &state->next_buflen; 421162306a36Sopenharmony_ci int to_hash; 421262306a36Sopenharmony_ci int src_nents, mapped_nents; 421362306a36Sopenharmony_ci struct ahash_edesc *edesc; 421462306a36Sopenharmony_ci int ret = 0; 421562306a36Sopenharmony_ci 421662306a36Sopenharmony_ci *next_buflen = req->nbytes & (crypto_tfm_alg_blocksize(&ahash->base) - 421762306a36Sopenharmony_ci 1); 421862306a36Sopenharmony_ci to_hash = req->nbytes - *next_buflen; 421962306a36Sopenharmony_ci 422062306a36Sopenharmony_ci if (to_hash) { 422162306a36Sopenharmony_ci struct dpaa2_sg_entry *sg_table; 422262306a36Sopenharmony_ci int src_len = req->nbytes - *next_buflen; 422362306a36Sopenharmony_ci 422462306a36Sopenharmony_ci src_nents = sg_nents_for_len(req->src, src_len); 422562306a36Sopenharmony_ci if (src_nents < 0) { 422662306a36Sopenharmony_ci dev_err(ctx->dev, "Invalid number of src SG.\n"); 422762306a36Sopenharmony_ci return src_nents; 422862306a36Sopenharmony_ci } 422962306a36Sopenharmony_ci 423062306a36Sopenharmony_ci if (src_nents) { 423162306a36Sopenharmony_ci mapped_nents = dma_map_sg(ctx->dev, req->src, src_nents, 423262306a36Sopenharmony_ci DMA_TO_DEVICE); 423362306a36Sopenharmony_ci if (!mapped_nents) { 423462306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map source for DMA\n"); 423562306a36Sopenharmony_ci return -ENOMEM; 423662306a36Sopenharmony_ci } 423762306a36Sopenharmony_ci } else { 423862306a36Sopenharmony_ci mapped_nents = 0; 423962306a36Sopenharmony_ci } 424062306a36Sopenharmony_ci 424162306a36Sopenharmony_ci /* allocate space for base edesc and link tables */ 424262306a36Sopenharmony_ci edesc = qi_cache_zalloc(flags); 424362306a36Sopenharmony_ci if (!edesc) { 424462306a36Sopenharmony_ci dma_unmap_sg(ctx->dev, req->src, src_nents, 424562306a36Sopenharmony_ci DMA_TO_DEVICE); 424662306a36Sopenharmony_ci return -ENOMEM; 424762306a36Sopenharmony_ci } 424862306a36Sopenharmony_ci 424962306a36Sopenharmony_ci edesc->src_nents = src_nents; 425062306a36Sopenharmony_ci sg_table = &edesc->sgt[0]; 425162306a36Sopenharmony_ci 425262306a36Sopenharmony_ci memset(&req_ctx->fd_flt, 0, sizeof(req_ctx->fd_flt)); 425362306a36Sopenharmony_ci dpaa2_fl_set_final(in_fle, true); 425462306a36Sopenharmony_ci dpaa2_fl_set_len(in_fle, to_hash); 425562306a36Sopenharmony_ci 425662306a36Sopenharmony_ci if (mapped_nents > 1) { 425762306a36Sopenharmony_ci int qm_sg_bytes; 425862306a36Sopenharmony_ci 425962306a36Sopenharmony_ci sg_to_qm_sg_last(req->src, src_len, sg_table, 0); 426062306a36Sopenharmony_ci qm_sg_bytes = pad_sg_nents(mapped_nents) * 426162306a36Sopenharmony_ci sizeof(*sg_table); 426262306a36Sopenharmony_ci edesc->qm_sg_dma = dma_map_single(ctx->dev, sg_table, 426362306a36Sopenharmony_ci qm_sg_bytes, 426462306a36Sopenharmony_ci DMA_TO_DEVICE); 426562306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, edesc->qm_sg_dma)) { 426662306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map S/G table\n"); 426762306a36Sopenharmony_ci ret = -ENOMEM; 426862306a36Sopenharmony_ci goto unmap_ctx; 426962306a36Sopenharmony_ci } 427062306a36Sopenharmony_ci edesc->qm_sg_bytes = qm_sg_bytes; 427162306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_sg); 427262306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, edesc->qm_sg_dma); 427362306a36Sopenharmony_ci } else { 427462306a36Sopenharmony_ci dpaa2_fl_set_format(in_fle, dpaa2_fl_single); 427562306a36Sopenharmony_ci dpaa2_fl_set_addr(in_fle, sg_dma_address(req->src)); 427662306a36Sopenharmony_ci } 427762306a36Sopenharmony_ci 427862306a36Sopenharmony_ci state->ctx_dma_len = ctx->ctx_len; 427962306a36Sopenharmony_ci state->ctx_dma = dma_map_single(ctx->dev, state->caam_ctx, 428062306a36Sopenharmony_ci ctx->ctx_len, DMA_FROM_DEVICE); 428162306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, state->ctx_dma)) { 428262306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map ctx\n"); 428362306a36Sopenharmony_ci state->ctx_dma = 0; 428462306a36Sopenharmony_ci ret = -ENOMEM; 428562306a36Sopenharmony_ci goto unmap_ctx; 428662306a36Sopenharmony_ci } 428762306a36Sopenharmony_ci 428862306a36Sopenharmony_ci dpaa2_fl_set_format(out_fle, dpaa2_fl_single); 428962306a36Sopenharmony_ci dpaa2_fl_set_addr(out_fle, state->ctx_dma); 429062306a36Sopenharmony_ci dpaa2_fl_set_len(out_fle, ctx->ctx_len); 429162306a36Sopenharmony_ci 429262306a36Sopenharmony_ci req_ctx->flc = &ctx->flc[UPDATE_FIRST]; 429362306a36Sopenharmony_ci req_ctx->flc_dma = ctx->flc_dma[UPDATE_FIRST]; 429462306a36Sopenharmony_ci req_ctx->cbk = ahash_done_ctx_dst; 429562306a36Sopenharmony_ci req_ctx->ctx = &req->base; 429662306a36Sopenharmony_ci req_ctx->edesc = edesc; 429762306a36Sopenharmony_ci 429862306a36Sopenharmony_ci ret = dpaa2_caam_enqueue(ctx->dev, req_ctx); 429962306a36Sopenharmony_ci if (ret != -EINPROGRESS && 430062306a36Sopenharmony_ci !(ret == -EBUSY && req->base.flags & 430162306a36Sopenharmony_ci CRYPTO_TFM_REQ_MAY_BACKLOG)) 430262306a36Sopenharmony_ci goto unmap_ctx; 430362306a36Sopenharmony_ci 430462306a36Sopenharmony_ci state->update = ahash_update_ctx; 430562306a36Sopenharmony_ci state->finup = ahash_finup_ctx; 430662306a36Sopenharmony_ci state->final = ahash_final_ctx; 430762306a36Sopenharmony_ci } else if (*next_buflen) { 430862306a36Sopenharmony_ci state->update = ahash_update_no_ctx; 430962306a36Sopenharmony_ci state->finup = ahash_finup_no_ctx; 431062306a36Sopenharmony_ci state->final = ahash_final_no_ctx; 431162306a36Sopenharmony_ci scatterwalk_map_and_copy(buf, req->src, 0, 431262306a36Sopenharmony_ci req->nbytes, 0); 431362306a36Sopenharmony_ci *buflen = *next_buflen; 431462306a36Sopenharmony_ci 431562306a36Sopenharmony_ci print_hex_dump_debug("buf@" __stringify(__LINE__)": ", 431662306a36Sopenharmony_ci DUMP_PREFIX_ADDRESS, 16, 4, buf, 431762306a36Sopenharmony_ci *buflen, 1); 431862306a36Sopenharmony_ci } 431962306a36Sopenharmony_ci 432062306a36Sopenharmony_ci return ret; 432162306a36Sopenharmony_ciunmap_ctx: 432262306a36Sopenharmony_ci ahash_unmap_ctx(ctx->dev, edesc, req, DMA_TO_DEVICE); 432362306a36Sopenharmony_ci qi_cache_free(edesc); 432462306a36Sopenharmony_ci return ret; 432562306a36Sopenharmony_ci} 432662306a36Sopenharmony_ci 432762306a36Sopenharmony_cistatic int ahash_finup_first(struct ahash_request *req) 432862306a36Sopenharmony_ci{ 432962306a36Sopenharmony_ci return ahash_digest(req); 433062306a36Sopenharmony_ci} 433162306a36Sopenharmony_ci 433262306a36Sopenharmony_cistatic int ahash_init(struct ahash_request *req) 433362306a36Sopenharmony_ci{ 433462306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 433562306a36Sopenharmony_ci 433662306a36Sopenharmony_ci state->update = ahash_update_first; 433762306a36Sopenharmony_ci state->finup = ahash_finup_first; 433862306a36Sopenharmony_ci state->final = ahash_final_no_ctx; 433962306a36Sopenharmony_ci 434062306a36Sopenharmony_ci state->ctx_dma = 0; 434162306a36Sopenharmony_ci state->ctx_dma_len = 0; 434262306a36Sopenharmony_ci state->buf_dma = 0; 434362306a36Sopenharmony_ci state->buflen = 0; 434462306a36Sopenharmony_ci state->next_buflen = 0; 434562306a36Sopenharmony_ci 434662306a36Sopenharmony_ci return 0; 434762306a36Sopenharmony_ci} 434862306a36Sopenharmony_ci 434962306a36Sopenharmony_cistatic int ahash_update(struct ahash_request *req) 435062306a36Sopenharmony_ci{ 435162306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 435262306a36Sopenharmony_ci 435362306a36Sopenharmony_ci return state->update(req); 435462306a36Sopenharmony_ci} 435562306a36Sopenharmony_ci 435662306a36Sopenharmony_cistatic int ahash_finup(struct ahash_request *req) 435762306a36Sopenharmony_ci{ 435862306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 435962306a36Sopenharmony_ci 436062306a36Sopenharmony_ci return state->finup(req); 436162306a36Sopenharmony_ci} 436262306a36Sopenharmony_ci 436362306a36Sopenharmony_cistatic int ahash_final(struct ahash_request *req) 436462306a36Sopenharmony_ci{ 436562306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 436662306a36Sopenharmony_ci 436762306a36Sopenharmony_ci return state->final(req); 436862306a36Sopenharmony_ci} 436962306a36Sopenharmony_ci 437062306a36Sopenharmony_cistatic int ahash_export(struct ahash_request *req, void *out) 437162306a36Sopenharmony_ci{ 437262306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 437362306a36Sopenharmony_ci struct caam_export_state *export = out; 437462306a36Sopenharmony_ci u8 *buf = state->buf; 437562306a36Sopenharmony_ci int len = state->buflen; 437662306a36Sopenharmony_ci 437762306a36Sopenharmony_ci memcpy(export->buf, buf, len); 437862306a36Sopenharmony_ci memcpy(export->caam_ctx, state->caam_ctx, sizeof(export->caam_ctx)); 437962306a36Sopenharmony_ci export->buflen = len; 438062306a36Sopenharmony_ci export->update = state->update; 438162306a36Sopenharmony_ci export->final = state->final; 438262306a36Sopenharmony_ci export->finup = state->finup; 438362306a36Sopenharmony_ci 438462306a36Sopenharmony_ci return 0; 438562306a36Sopenharmony_ci} 438662306a36Sopenharmony_ci 438762306a36Sopenharmony_cistatic int ahash_import(struct ahash_request *req, const void *in) 438862306a36Sopenharmony_ci{ 438962306a36Sopenharmony_ci struct caam_hash_state *state = ahash_request_ctx_dma(req); 439062306a36Sopenharmony_ci const struct caam_export_state *export = in; 439162306a36Sopenharmony_ci 439262306a36Sopenharmony_ci memset(state, 0, sizeof(*state)); 439362306a36Sopenharmony_ci memcpy(state->buf, export->buf, export->buflen); 439462306a36Sopenharmony_ci memcpy(state->caam_ctx, export->caam_ctx, sizeof(state->caam_ctx)); 439562306a36Sopenharmony_ci state->buflen = export->buflen; 439662306a36Sopenharmony_ci state->update = export->update; 439762306a36Sopenharmony_ci state->final = export->final; 439862306a36Sopenharmony_ci state->finup = export->finup; 439962306a36Sopenharmony_ci 440062306a36Sopenharmony_ci return 0; 440162306a36Sopenharmony_ci} 440262306a36Sopenharmony_ci 440362306a36Sopenharmony_cistruct caam_hash_template { 440462306a36Sopenharmony_ci char name[CRYPTO_MAX_ALG_NAME]; 440562306a36Sopenharmony_ci char driver_name[CRYPTO_MAX_ALG_NAME]; 440662306a36Sopenharmony_ci char hmac_name[CRYPTO_MAX_ALG_NAME]; 440762306a36Sopenharmony_ci char hmac_driver_name[CRYPTO_MAX_ALG_NAME]; 440862306a36Sopenharmony_ci unsigned int blocksize; 440962306a36Sopenharmony_ci struct ahash_alg template_ahash; 441062306a36Sopenharmony_ci u32 alg_type; 441162306a36Sopenharmony_ci}; 441262306a36Sopenharmony_ci 441362306a36Sopenharmony_ci/* ahash descriptors */ 441462306a36Sopenharmony_cistatic struct caam_hash_template driver_hash[] = { 441562306a36Sopenharmony_ci { 441662306a36Sopenharmony_ci .name = "sha1", 441762306a36Sopenharmony_ci .driver_name = "sha1-caam-qi2", 441862306a36Sopenharmony_ci .hmac_name = "hmac(sha1)", 441962306a36Sopenharmony_ci .hmac_driver_name = "hmac-sha1-caam-qi2", 442062306a36Sopenharmony_ci .blocksize = SHA1_BLOCK_SIZE, 442162306a36Sopenharmony_ci .template_ahash = { 442262306a36Sopenharmony_ci .init = ahash_init, 442362306a36Sopenharmony_ci .update = ahash_update, 442462306a36Sopenharmony_ci .final = ahash_final, 442562306a36Sopenharmony_ci .finup = ahash_finup, 442662306a36Sopenharmony_ci .digest = ahash_digest, 442762306a36Sopenharmony_ci .export = ahash_export, 442862306a36Sopenharmony_ci .import = ahash_import, 442962306a36Sopenharmony_ci .setkey = ahash_setkey, 443062306a36Sopenharmony_ci .halg = { 443162306a36Sopenharmony_ci .digestsize = SHA1_DIGEST_SIZE, 443262306a36Sopenharmony_ci .statesize = sizeof(struct caam_export_state), 443362306a36Sopenharmony_ci }, 443462306a36Sopenharmony_ci }, 443562306a36Sopenharmony_ci .alg_type = OP_ALG_ALGSEL_SHA1, 443662306a36Sopenharmony_ci }, { 443762306a36Sopenharmony_ci .name = "sha224", 443862306a36Sopenharmony_ci .driver_name = "sha224-caam-qi2", 443962306a36Sopenharmony_ci .hmac_name = "hmac(sha224)", 444062306a36Sopenharmony_ci .hmac_driver_name = "hmac-sha224-caam-qi2", 444162306a36Sopenharmony_ci .blocksize = SHA224_BLOCK_SIZE, 444262306a36Sopenharmony_ci .template_ahash = { 444362306a36Sopenharmony_ci .init = ahash_init, 444462306a36Sopenharmony_ci .update = ahash_update, 444562306a36Sopenharmony_ci .final = ahash_final, 444662306a36Sopenharmony_ci .finup = ahash_finup, 444762306a36Sopenharmony_ci .digest = ahash_digest, 444862306a36Sopenharmony_ci .export = ahash_export, 444962306a36Sopenharmony_ci .import = ahash_import, 445062306a36Sopenharmony_ci .setkey = ahash_setkey, 445162306a36Sopenharmony_ci .halg = { 445262306a36Sopenharmony_ci .digestsize = SHA224_DIGEST_SIZE, 445362306a36Sopenharmony_ci .statesize = sizeof(struct caam_export_state), 445462306a36Sopenharmony_ci }, 445562306a36Sopenharmony_ci }, 445662306a36Sopenharmony_ci .alg_type = OP_ALG_ALGSEL_SHA224, 445762306a36Sopenharmony_ci }, { 445862306a36Sopenharmony_ci .name = "sha256", 445962306a36Sopenharmony_ci .driver_name = "sha256-caam-qi2", 446062306a36Sopenharmony_ci .hmac_name = "hmac(sha256)", 446162306a36Sopenharmony_ci .hmac_driver_name = "hmac-sha256-caam-qi2", 446262306a36Sopenharmony_ci .blocksize = SHA256_BLOCK_SIZE, 446362306a36Sopenharmony_ci .template_ahash = { 446462306a36Sopenharmony_ci .init = ahash_init, 446562306a36Sopenharmony_ci .update = ahash_update, 446662306a36Sopenharmony_ci .final = ahash_final, 446762306a36Sopenharmony_ci .finup = ahash_finup, 446862306a36Sopenharmony_ci .digest = ahash_digest, 446962306a36Sopenharmony_ci .export = ahash_export, 447062306a36Sopenharmony_ci .import = ahash_import, 447162306a36Sopenharmony_ci .setkey = ahash_setkey, 447262306a36Sopenharmony_ci .halg = { 447362306a36Sopenharmony_ci .digestsize = SHA256_DIGEST_SIZE, 447462306a36Sopenharmony_ci .statesize = sizeof(struct caam_export_state), 447562306a36Sopenharmony_ci }, 447662306a36Sopenharmony_ci }, 447762306a36Sopenharmony_ci .alg_type = OP_ALG_ALGSEL_SHA256, 447862306a36Sopenharmony_ci }, { 447962306a36Sopenharmony_ci .name = "sha384", 448062306a36Sopenharmony_ci .driver_name = "sha384-caam-qi2", 448162306a36Sopenharmony_ci .hmac_name = "hmac(sha384)", 448262306a36Sopenharmony_ci .hmac_driver_name = "hmac-sha384-caam-qi2", 448362306a36Sopenharmony_ci .blocksize = SHA384_BLOCK_SIZE, 448462306a36Sopenharmony_ci .template_ahash = { 448562306a36Sopenharmony_ci .init = ahash_init, 448662306a36Sopenharmony_ci .update = ahash_update, 448762306a36Sopenharmony_ci .final = ahash_final, 448862306a36Sopenharmony_ci .finup = ahash_finup, 448962306a36Sopenharmony_ci .digest = ahash_digest, 449062306a36Sopenharmony_ci .export = ahash_export, 449162306a36Sopenharmony_ci .import = ahash_import, 449262306a36Sopenharmony_ci .setkey = ahash_setkey, 449362306a36Sopenharmony_ci .halg = { 449462306a36Sopenharmony_ci .digestsize = SHA384_DIGEST_SIZE, 449562306a36Sopenharmony_ci .statesize = sizeof(struct caam_export_state), 449662306a36Sopenharmony_ci }, 449762306a36Sopenharmony_ci }, 449862306a36Sopenharmony_ci .alg_type = OP_ALG_ALGSEL_SHA384, 449962306a36Sopenharmony_ci }, { 450062306a36Sopenharmony_ci .name = "sha512", 450162306a36Sopenharmony_ci .driver_name = "sha512-caam-qi2", 450262306a36Sopenharmony_ci .hmac_name = "hmac(sha512)", 450362306a36Sopenharmony_ci .hmac_driver_name = "hmac-sha512-caam-qi2", 450462306a36Sopenharmony_ci .blocksize = SHA512_BLOCK_SIZE, 450562306a36Sopenharmony_ci .template_ahash = { 450662306a36Sopenharmony_ci .init = ahash_init, 450762306a36Sopenharmony_ci .update = ahash_update, 450862306a36Sopenharmony_ci .final = ahash_final, 450962306a36Sopenharmony_ci .finup = ahash_finup, 451062306a36Sopenharmony_ci .digest = ahash_digest, 451162306a36Sopenharmony_ci .export = ahash_export, 451262306a36Sopenharmony_ci .import = ahash_import, 451362306a36Sopenharmony_ci .setkey = ahash_setkey, 451462306a36Sopenharmony_ci .halg = { 451562306a36Sopenharmony_ci .digestsize = SHA512_DIGEST_SIZE, 451662306a36Sopenharmony_ci .statesize = sizeof(struct caam_export_state), 451762306a36Sopenharmony_ci }, 451862306a36Sopenharmony_ci }, 451962306a36Sopenharmony_ci .alg_type = OP_ALG_ALGSEL_SHA512, 452062306a36Sopenharmony_ci }, { 452162306a36Sopenharmony_ci .name = "md5", 452262306a36Sopenharmony_ci .driver_name = "md5-caam-qi2", 452362306a36Sopenharmony_ci .hmac_name = "hmac(md5)", 452462306a36Sopenharmony_ci .hmac_driver_name = "hmac-md5-caam-qi2", 452562306a36Sopenharmony_ci .blocksize = MD5_BLOCK_WORDS * 4, 452662306a36Sopenharmony_ci .template_ahash = { 452762306a36Sopenharmony_ci .init = ahash_init, 452862306a36Sopenharmony_ci .update = ahash_update, 452962306a36Sopenharmony_ci .final = ahash_final, 453062306a36Sopenharmony_ci .finup = ahash_finup, 453162306a36Sopenharmony_ci .digest = ahash_digest, 453262306a36Sopenharmony_ci .export = ahash_export, 453362306a36Sopenharmony_ci .import = ahash_import, 453462306a36Sopenharmony_ci .setkey = ahash_setkey, 453562306a36Sopenharmony_ci .halg = { 453662306a36Sopenharmony_ci .digestsize = MD5_DIGEST_SIZE, 453762306a36Sopenharmony_ci .statesize = sizeof(struct caam_export_state), 453862306a36Sopenharmony_ci }, 453962306a36Sopenharmony_ci }, 454062306a36Sopenharmony_ci .alg_type = OP_ALG_ALGSEL_MD5, 454162306a36Sopenharmony_ci } 454262306a36Sopenharmony_ci}; 454362306a36Sopenharmony_ci 454462306a36Sopenharmony_cistruct caam_hash_alg { 454562306a36Sopenharmony_ci struct list_head entry; 454662306a36Sopenharmony_ci struct device *dev; 454762306a36Sopenharmony_ci int alg_type; 454862306a36Sopenharmony_ci struct ahash_alg ahash_alg; 454962306a36Sopenharmony_ci}; 455062306a36Sopenharmony_ci 455162306a36Sopenharmony_cistatic int caam_hash_cra_init(struct crypto_tfm *tfm) 455262306a36Sopenharmony_ci{ 455362306a36Sopenharmony_ci struct crypto_ahash *ahash = __crypto_ahash_cast(tfm); 455462306a36Sopenharmony_ci struct crypto_alg *base = tfm->__crt_alg; 455562306a36Sopenharmony_ci struct hash_alg_common *halg = 455662306a36Sopenharmony_ci container_of(base, struct hash_alg_common, base); 455762306a36Sopenharmony_ci struct ahash_alg *alg = 455862306a36Sopenharmony_ci container_of(halg, struct ahash_alg, halg); 455962306a36Sopenharmony_ci struct caam_hash_alg *caam_hash = 456062306a36Sopenharmony_ci container_of(alg, struct caam_hash_alg, ahash_alg); 456162306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_tfm_ctx_dma(tfm); 456262306a36Sopenharmony_ci /* Sizes for MDHA running digests: MD5, SHA1, 224, 256, 384, 512 */ 456362306a36Sopenharmony_ci static const u8 runninglen[] = { HASH_MSG_LEN + MD5_DIGEST_SIZE, 456462306a36Sopenharmony_ci HASH_MSG_LEN + SHA1_DIGEST_SIZE, 456562306a36Sopenharmony_ci HASH_MSG_LEN + 32, 456662306a36Sopenharmony_ci HASH_MSG_LEN + SHA256_DIGEST_SIZE, 456762306a36Sopenharmony_ci HASH_MSG_LEN + 64, 456862306a36Sopenharmony_ci HASH_MSG_LEN + SHA512_DIGEST_SIZE }; 456962306a36Sopenharmony_ci dma_addr_t dma_addr; 457062306a36Sopenharmony_ci int i; 457162306a36Sopenharmony_ci 457262306a36Sopenharmony_ci ctx->dev = caam_hash->dev; 457362306a36Sopenharmony_ci 457462306a36Sopenharmony_ci if (alg->setkey) { 457562306a36Sopenharmony_ci ctx->adata.key_dma = dma_map_single_attrs(ctx->dev, ctx->key, 457662306a36Sopenharmony_ci ARRAY_SIZE(ctx->key), 457762306a36Sopenharmony_ci DMA_TO_DEVICE, 457862306a36Sopenharmony_ci DMA_ATTR_SKIP_CPU_SYNC); 457962306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, ctx->adata.key_dma)) { 458062306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map key\n"); 458162306a36Sopenharmony_ci return -ENOMEM; 458262306a36Sopenharmony_ci } 458362306a36Sopenharmony_ci } 458462306a36Sopenharmony_ci 458562306a36Sopenharmony_ci dma_addr = dma_map_single_attrs(ctx->dev, ctx->flc, sizeof(ctx->flc), 458662306a36Sopenharmony_ci DMA_BIDIRECTIONAL, 458762306a36Sopenharmony_ci DMA_ATTR_SKIP_CPU_SYNC); 458862306a36Sopenharmony_ci if (dma_mapping_error(ctx->dev, dma_addr)) { 458962306a36Sopenharmony_ci dev_err(ctx->dev, "unable to map shared descriptors\n"); 459062306a36Sopenharmony_ci if (ctx->adata.key_dma) 459162306a36Sopenharmony_ci dma_unmap_single_attrs(ctx->dev, ctx->adata.key_dma, 459262306a36Sopenharmony_ci ARRAY_SIZE(ctx->key), 459362306a36Sopenharmony_ci DMA_TO_DEVICE, 459462306a36Sopenharmony_ci DMA_ATTR_SKIP_CPU_SYNC); 459562306a36Sopenharmony_ci return -ENOMEM; 459662306a36Sopenharmony_ci } 459762306a36Sopenharmony_ci 459862306a36Sopenharmony_ci for (i = 0; i < HASH_NUM_OP; i++) 459962306a36Sopenharmony_ci ctx->flc_dma[i] = dma_addr + i * sizeof(ctx->flc[i]); 460062306a36Sopenharmony_ci 460162306a36Sopenharmony_ci /* copy descriptor header template value */ 460262306a36Sopenharmony_ci ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam_hash->alg_type; 460362306a36Sopenharmony_ci 460462306a36Sopenharmony_ci ctx->ctx_len = runninglen[(ctx->adata.algtype & 460562306a36Sopenharmony_ci OP_ALG_ALGSEL_SUBMASK) >> 460662306a36Sopenharmony_ci OP_ALG_ALGSEL_SHIFT]; 460762306a36Sopenharmony_ci 460862306a36Sopenharmony_ci crypto_ahash_set_reqsize_dma(ahash, sizeof(struct caam_hash_state)); 460962306a36Sopenharmony_ci 461062306a36Sopenharmony_ci /* 461162306a36Sopenharmony_ci * For keyed hash algorithms shared descriptors 461262306a36Sopenharmony_ci * will be created later in setkey() callback 461362306a36Sopenharmony_ci */ 461462306a36Sopenharmony_ci return alg->setkey ? 0 : ahash_set_sh_desc(ahash); 461562306a36Sopenharmony_ci} 461662306a36Sopenharmony_ci 461762306a36Sopenharmony_cistatic void caam_hash_cra_exit(struct crypto_tfm *tfm) 461862306a36Sopenharmony_ci{ 461962306a36Sopenharmony_ci struct caam_hash_ctx *ctx = crypto_tfm_ctx_dma(tfm); 462062306a36Sopenharmony_ci 462162306a36Sopenharmony_ci dma_unmap_single_attrs(ctx->dev, ctx->flc_dma[0], sizeof(ctx->flc), 462262306a36Sopenharmony_ci DMA_BIDIRECTIONAL, DMA_ATTR_SKIP_CPU_SYNC); 462362306a36Sopenharmony_ci if (ctx->adata.key_dma) 462462306a36Sopenharmony_ci dma_unmap_single_attrs(ctx->dev, ctx->adata.key_dma, 462562306a36Sopenharmony_ci ARRAY_SIZE(ctx->key), DMA_TO_DEVICE, 462662306a36Sopenharmony_ci DMA_ATTR_SKIP_CPU_SYNC); 462762306a36Sopenharmony_ci} 462862306a36Sopenharmony_ci 462962306a36Sopenharmony_cistatic struct caam_hash_alg *caam_hash_alloc(struct device *dev, 463062306a36Sopenharmony_ci struct caam_hash_template *template, bool keyed) 463162306a36Sopenharmony_ci{ 463262306a36Sopenharmony_ci struct caam_hash_alg *t_alg; 463362306a36Sopenharmony_ci struct ahash_alg *halg; 463462306a36Sopenharmony_ci struct crypto_alg *alg; 463562306a36Sopenharmony_ci 463662306a36Sopenharmony_ci t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL); 463762306a36Sopenharmony_ci if (!t_alg) 463862306a36Sopenharmony_ci return ERR_PTR(-ENOMEM); 463962306a36Sopenharmony_ci 464062306a36Sopenharmony_ci t_alg->ahash_alg = template->template_ahash; 464162306a36Sopenharmony_ci halg = &t_alg->ahash_alg; 464262306a36Sopenharmony_ci alg = &halg->halg.base; 464362306a36Sopenharmony_ci 464462306a36Sopenharmony_ci if (keyed) { 464562306a36Sopenharmony_ci snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", 464662306a36Sopenharmony_ci template->hmac_name); 464762306a36Sopenharmony_ci snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", 464862306a36Sopenharmony_ci template->hmac_driver_name); 464962306a36Sopenharmony_ci } else { 465062306a36Sopenharmony_ci snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", 465162306a36Sopenharmony_ci template->name); 465262306a36Sopenharmony_ci snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s", 465362306a36Sopenharmony_ci template->driver_name); 465462306a36Sopenharmony_ci t_alg->ahash_alg.setkey = NULL; 465562306a36Sopenharmony_ci } 465662306a36Sopenharmony_ci alg->cra_module = THIS_MODULE; 465762306a36Sopenharmony_ci alg->cra_init = caam_hash_cra_init; 465862306a36Sopenharmony_ci alg->cra_exit = caam_hash_cra_exit; 465962306a36Sopenharmony_ci alg->cra_ctxsize = sizeof(struct caam_hash_ctx) + crypto_dma_padding(); 466062306a36Sopenharmony_ci alg->cra_priority = CAAM_CRA_PRIORITY; 466162306a36Sopenharmony_ci alg->cra_blocksize = template->blocksize; 466262306a36Sopenharmony_ci alg->cra_alignmask = 0; 466362306a36Sopenharmony_ci alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY; 466462306a36Sopenharmony_ci 466562306a36Sopenharmony_ci t_alg->alg_type = template->alg_type; 466662306a36Sopenharmony_ci t_alg->dev = dev; 466762306a36Sopenharmony_ci 466862306a36Sopenharmony_ci return t_alg; 466962306a36Sopenharmony_ci} 467062306a36Sopenharmony_ci 467162306a36Sopenharmony_cistatic void dpaa2_caam_fqdan_cb(struct dpaa2_io_notification_ctx *nctx) 467262306a36Sopenharmony_ci{ 467362306a36Sopenharmony_ci struct dpaa2_caam_priv_per_cpu *ppriv; 467462306a36Sopenharmony_ci 467562306a36Sopenharmony_ci ppriv = container_of(nctx, struct dpaa2_caam_priv_per_cpu, nctx); 467662306a36Sopenharmony_ci napi_schedule_irqoff(&ppriv->napi); 467762306a36Sopenharmony_ci} 467862306a36Sopenharmony_ci 467962306a36Sopenharmony_cistatic int __cold dpaa2_dpseci_dpio_setup(struct dpaa2_caam_priv *priv) 468062306a36Sopenharmony_ci{ 468162306a36Sopenharmony_ci struct device *dev = priv->dev; 468262306a36Sopenharmony_ci struct dpaa2_io_notification_ctx *nctx; 468362306a36Sopenharmony_ci struct dpaa2_caam_priv_per_cpu *ppriv; 468462306a36Sopenharmony_ci int err, i = 0, cpu; 468562306a36Sopenharmony_ci 468662306a36Sopenharmony_ci for_each_online_cpu(cpu) { 468762306a36Sopenharmony_ci ppriv = per_cpu_ptr(priv->ppriv, cpu); 468862306a36Sopenharmony_ci ppriv->priv = priv; 468962306a36Sopenharmony_ci nctx = &ppriv->nctx; 469062306a36Sopenharmony_ci nctx->is_cdan = 0; 469162306a36Sopenharmony_ci nctx->id = ppriv->rsp_fqid; 469262306a36Sopenharmony_ci nctx->desired_cpu = cpu; 469362306a36Sopenharmony_ci nctx->cb = dpaa2_caam_fqdan_cb; 469462306a36Sopenharmony_ci 469562306a36Sopenharmony_ci /* Register notification callbacks */ 469662306a36Sopenharmony_ci ppriv->dpio = dpaa2_io_service_select(cpu); 469762306a36Sopenharmony_ci err = dpaa2_io_service_register(ppriv->dpio, nctx, dev); 469862306a36Sopenharmony_ci if (unlikely(err)) { 469962306a36Sopenharmony_ci dev_dbg(dev, "No affine DPIO for cpu %d\n", cpu); 470062306a36Sopenharmony_ci nctx->cb = NULL; 470162306a36Sopenharmony_ci /* 470262306a36Sopenharmony_ci * If no affine DPIO for this core, there's probably 470362306a36Sopenharmony_ci * none available for next cores either. Signal we want 470462306a36Sopenharmony_ci * to retry later, in case the DPIO devices weren't 470562306a36Sopenharmony_ci * probed yet. 470662306a36Sopenharmony_ci */ 470762306a36Sopenharmony_ci err = -EPROBE_DEFER; 470862306a36Sopenharmony_ci goto err; 470962306a36Sopenharmony_ci } 471062306a36Sopenharmony_ci 471162306a36Sopenharmony_ci ppriv->store = dpaa2_io_store_create(DPAA2_CAAM_STORE_SIZE, 471262306a36Sopenharmony_ci dev); 471362306a36Sopenharmony_ci if (unlikely(!ppriv->store)) { 471462306a36Sopenharmony_ci dev_err(dev, "dpaa2_io_store_create() failed\n"); 471562306a36Sopenharmony_ci err = -ENOMEM; 471662306a36Sopenharmony_ci goto err; 471762306a36Sopenharmony_ci } 471862306a36Sopenharmony_ci 471962306a36Sopenharmony_ci if (++i == priv->num_pairs) 472062306a36Sopenharmony_ci break; 472162306a36Sopenharmony_ci } 472262306a36Sopenharmony_ci 472362306a36Sopenharmony_ci return 0; 472462306a36Sopenharmony_ci 472562306a36Sopenharmony_cierr: 472662306a36Sopenharmony_ci for_each_online_cpu(cpu) { 472762306a36Sopenharmony_ci ppriv = per_cpu_ptr(priv->ppriv, cpu); 472862306a36Sopenharmony_ci if (!ppriv->nctx.cb) 472962306a36Sopenharmony_ci break; 473062306a36Sopenharmony_ci dpaa2_io_service_deregister(ppriv->dpio, &ppriv->nctx, dev); 473162306a36Sopenharmony_ci } 473262306a36Sopenharmony_ci 473362306a36Sopenharmony_ci for_each_online_cpu(cpu) { 473462306a36Sopenharmony_ci ppriv = per_cpu_ptr(priv->ppriv, cpu); 473562306a36Sopenharmony_ci if (!ppriv->store) 473662306a36Sopenharmony_ci break; 473762306a36Sopenharmony_ci dpaa2_io_store_destroy(ppriv->store); 473862306a36Sopenharmony_ci } 473962306a36Sopenharmony_ci 474062306a36Sopenharmony_ci return err; 474162306a36Sopenharmony_ci} 474262306a36Sopenharmony_ci 474362306a36Sopenharmony_cistatic void __cold dpaa2_dpseci_dpio_free(struct dpaa2_caam_priv *priv) 474462306a36Sopenharmony_ci{ 474562306a36Sopenharmony_ci struct dpaa2_caam_priv_per_cpu *ppriv; 474662306a36Sopenharmony_ci int i = 0, cpu; 474762306a36Sopenharmony_ci 474862306a36Sopenharmony_ci for_each_online_cpu(cpu) { 474962306a36Sopenharmony_ci ppriv = per_cpu_ptr(priv->ppriv, cpu); 475062306a36Sopenharmony_ci dpaa2_io_service_deregister(ppriv->dpio, &ppriv->nctx, 475162306a36Sopenharmony_ci priv->dev); 475262306a36Sopenharmony_ci dpaa2_io_store_destroy(ppriv->store); 475362306a36Sopenharmony_ci 475462306a36Sopenharmony_ci if (++i == priv->num_pairs) 475562306a36Sopenharmony_ci return; 475662306a36Sopenharmony_ci } 475762306a36Sopenharmony_ci} 475862306a36Sopenharmony_ci 475962306a36Sopenharmony_cistatic int dpaa2_dpseci_bind(struct dpaa2_caam_priv *priv) 476062306a36Sopenharmony_ci{ 476162306a36Sopenharmony_ci struct dpseci_rx_queue_cfg rx_queue_cfg; 476262306a36Sopenharmony_ci struct device *dev = priv->dev; 476362306a36Sopenharmony_ci struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev); 476462306a36Sopenharmony_ci struct dpaa2_caam_priv_per_cpu *ppriv; 476562306a36Sopenharmony_ci int err = 0, i = 0, cpu; 476662306a36Sopenharmony_ci 476762306a36Sopenharmony_ci /* Configure Rx queues */ 476862306a36Sopenharmony_ci for_each_online_cpu(cpu) { 476962306a36Sopenharmony_ci ppriv = per_cpu_ptr(priv->ppriv, cpu); 477062306a36Sopenharmony_ci 477162306a36Sopenharmony_ci rx_queue_cfg.options = DPSECI_QUEUE_OPT_DEST | 477262306a36Sopenharmony_ci DPSECI_QUEUE_OPT_USER_CTX; 477362306a36Sopenharmony_ci rx_queue_cfg.order_preservation_en = 0; 477462306a36Sopenharmony_ci rx_queue_cfg.dest_cfg.dest_type = DPSECI_DEST_DPIO; 477562306a36Sopenharmony_ci rx_queue_cfg.dest_cfg.dest_id = ppriv->nctx.dpio_id; 477662306a36Sopenharmony_ci /* 477762306a36Sopenharmony_ci * Rx priority (WQ) doesn't really matter, since we use 477862306a36Sopenharmony_ci * pull mode, i.e. volatile dequeues from specific FQs 477962306a36Sopenharmony_ci */ 478062306a36Sopenharmony_ci rx_queue_cfg.dest_cfg.priority = 0; 478162306a36Sopenharmony_ci rx_queue_cfg.user_ctx = ppriv->nctx.qman64; 478262306a36Sopenharmony_ci 478362306a36Sopenharmony_ci err = dpseci_set_rx_queue(priv->mc_io, 0, ls_dev->mc_handle, i, 478462306a36Sopenharmony_ci &rx_queue_cfg); 478562306a36Sopenharmony_ci if (err) { 478662306a36Sopenharmony_ci dev_err(dev, "dpseci_set_rx_queue() failed with err %d\n", 478762306a36Sopenharmony_ci err); 478862306a36Sopenharmony_ci return err; 478962306a36Sopenharmony_ci } 479062306a36Sopenharmony_ci 479162306a36Sopenharmony_ci if (++i == priv->num_pairs) 479262306a36Sopenharmony_ci break; 479362306a36Sopenharmony_ci } 479462306a36Sopenharmony_ci 479562306a36Sopenharmony_ci return err; 479662306a36Sopenharmony_ci} 479762306a36Sopenharmony_ci 479862306a36Sopenharmony_cistatic void dpaa2_dpseci_congestion_free(struct dpaa2_caam_priv *priv) 479962306a36Sopenharmony_ci{ 480062306a36Sopenharmony_ci struct device *dev = priv->dev; 480162306a36Sopenharmony_ci 480262306a36Sopenharmony_ci if (!priv->cscn_mem) 480362306a36Sopenharmony_ci return; 480462306a36Sopenharmony_ci 480562306a36Sopenharmony_ci dma_unmap_single(dev, priv->cscn_dma, DPAA2_CSCN_SIZE, DMA_FROM_DEVICE); 480662306a36Sopenharmony_ci kfree(priv->cscn_mem); 480762306a36Sopenharmony_ci} 480862306a36Sopenharmony_ci 480962306a36Sopenharmony_cistatic void dpaa2_dpseci_free(struct dpaa2_caam_priv *priv) 481062306a36Sopenharmony_ci{ 481162306a36Sopenharmony_ci struct device *dev = priv->dev; 481262306a36Sopenharmony_ci struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev); 481362306a36Sopenharmony_ci int err; 481462306a36Sopenharmony_ci 481562306a36Sopenharmony_ci if (DPSECI_VER(priv->major_ver, priv->minor_ver) > DPSECI_VER(5, 3)) { 481662306a36Sopenharmony_ci err = dpseci_reset(priv->mc_io, 0, ls_dev->mc_handle); 481762306a36Sopenharmony_ci if (err) 481862306a36Sopenharmony_ci dev_err(dev, "dpseci_reset() failed\n"); 481962306a36Sopenharmony_ci } 482062306a36Sopenharmony_ci 482162306a36Sopenharmony_ci dpaa2_dpseci_congestion_free(priv); 482262306a36Sopenharmony_ci dpseci_close(priv->mc_io, 0, ls_dev->mc_handle); 482362306a36Sopenharmony_ci} 482462306a36Sopenharmony_ci 482562306a36Sopenharmony_cistatic void dpaa2_caam_process_fd(struct dpaa2_caam_priv *priv, 482662306a36Sopenharmony_ci const struct dpaa2_fd *fd) 482762306a36Sopenharmony_ci{ 482862306a36Sopenharmony_ci struct caam_request *req; 482962306a36Sopenharmony_ci u32 fd_err; 483062306a36Sopenharmony_ci 483162306a36Sopenharmony_ci if (dpaa2_fd_get_format(fd) != dpaa2_fd_list) { 483262306a36Sopenharmony_ci dev_err(priv->dev, "Only Frame List FD format is supported!\n"); 483362306a36Sopenharmony_ci return; 483462306a36Sopenharmony_ci } 483562306a36Sopenharmony_ci 483662306a36Sopenharmony_ci fd_err = dpaa2_fd_get_ctrl(fd) & FD_CTRL_ERR_MASK; 483762306a36Sopenharmony_ci if (unlikely(fd_err)) 483862306a36Sopenharmony_ci dev_err_ratelimited(priv->dev, "FD error: %08x\n", fd_err); 483962306a36Sopenharmony_ci 484062306a36Sopenharmony_ci /* 484162306a36Sopenharmony_ci * FD[ADDR] is guaranteed to be valid, irrespective of errors reported 484262306a36Sopenharmony_ci * in FD[ERR] or FD[FRC]. 484362306a36Sopenharmony_ci */ 484462306a36Sopenharmony_ci req = dpaa2_caam_iova_to_virt(priv, dpaa2_fd_get_addr(fd)); 484562306a36Sopenharmony_ci dma_unmap_single(priv->dev, req->fd_flt_dma, sizeof(req->fd_flt), 484662306a36Sopenharmony_ci DMA_BIDIRECTIONAL); 484762306a36Sopenharmony_ci req->cbk(req->ctx, dpaa2_fd_get_frc(fd)); 484862306a36Sopenharmony_ci} 484962306a36Sopenharmony_ci 485062306a36Sopenharmony_cistatic int dpaa2_caam_pull_fq(struct dpaa2_caam_priv_per_cpu *ppriv) 485162306a36Sopenharmony_ci{ 485262306a36Sopenharmony_ci int err; 485362306a36Sopenharmony_ci 485462306a36Sopenharmony_ci /* Retry while portal is busy */ 485562306a36Sopenharmony_ci do { 485662306a36Sopenharmony_ci err = dpaa2_io_service_pull_fq(ppriv->dpio, ppriv->rsp_fqid, 485762306a36Sopenharmony_ci ppriv->store); 485862306a36Sopenharmony_ci } while (err == -EBUSY); 485962306a36Sopenharmony_ci 486062306a36Sopenharmony_ci if (unlikely(err)) 486162306a36Sopenharmony_ci dev_err(ppriv->priv->dev, "dpaa2_io_service_pull err %d", err); 486262306a36Sopenharmony_ci 486362306a36Sopenharmony_ci return err; 486462306a36Sopenharmony_ci} 486562306a36Sopenharmony_ci 486662306a36Sopenharmony_cistatic int dpaa2_caam_store_consume(struct dpaa2_caam_priv_per_cpu *ppriv) 486762306a36Sopenharmony_ci{ 486862306a36Sopenharmony_ci struct dpaa2_dq *dq; 486962306a36Sopenharmony_ci int cleaned = 0, is_last; 487062306a36Sopenharmony_ci 487162306a36Sopenharmony_ci do { 487262306a36Sopenharmony_ci dq = dpaa2_io_store_next(ppriv->store, &is_last); 487362306a36Sopenharmony_ci if (unlikely(!dq)) { 487462306a36Sopenharmony_ci if (unlikely(!is_last)) { 487562306a36Sopenharmony_ci dev_dbg(ppriv->priv->dev, 487662306a36Sopenharmony_ci "FQ %d returned no valid frames\n", 487762306a36Sopenharmony_ci ppriv->rsp_fqid); 487862306a36Sopenharmony_ci /* 487962306a36Sopenharmony_ci * MUST retry until we get some sort of 488062306a36Sopenharmony_ci * valid response token (be it "empty dequeue" 488162306a36Sopenharmony_ci * or a valid frame). 488262306a36Sopenharmony_ci */ 488362306a36Sopenharmony_ci continue; 488462306a36Sopenharmony_ci } 488562306a36Sopenharmony_ci break; 488662306a36Sopenharmony_ci } 488762306a36Sopenharmony_ci 488862306a36Sopenharmony_ci /* Process FD */ 488962306a36Sopenharmony_ci dpaa2_caam_process_fd(ppriv->priv, dpaa2_dq_fd(dq)); 489062306a36Sopenharmony_ci cleaned++; 489162306a36Sopenharmony_ci } while (!is_last); 489262306a36Sopenharmony_ci 489362306a36Sopenharmony_ci return cleaned; 489462306a36Sopenharmony_ci} 489562306a36Sopenharmony_ci 489662306a36Sopenharmony_cistatic int dpaa2_dpseci_poll(struct napi_struct *napi, int budget) 489762306a36Sopenharmony_ci{ 489862306a36Sopenharmony_ci struct dpaa2_caam_priv_per_cpu *ppriv; 489962306a36Sopenharmony_ci struct dpaa2_caam_priv *priv; 490062306a36Sopenharmony_ci int err, cleaned = 0, store_cleaned; 490162306a36Sopenharmony_ci 490262306a36Sopenharmony_ci ppriv = container_of(napi, struct dpaa2_caam_priv_per_cpu, napi); 490362306a36Sopenharmony_ci priv = ppriv->priv; 490462306a36Sopenharmony_ci 490562306a36Sopenharmony_ci if (unlikely(dpaa2_caam_pull_fq(ppriv))) 490662306a36Sopenharmony_ci return 0; 490762306a36Sopenharmony_ci 490862306a36Sopenharmony_ci do { 490962306a36Sopenharmony_ci store_cleaned = dpaa2_caam_store_consume(ppriv); 491062306a36Sopenharmony_ci cleaned += store_cleaned; 491162306a36Sopenharmony_ci 491262306a36Sopenharmony_ci if (store_cleaned == 0 || 491362306a36Sopenharmony_ci cleaned > budget - DPAA2_CAAM_STORE_SIZE) 491462306a36Sopenharmony_ci break; 491562306a36Sopenharmony_ci 491662306a36Sopenharmony_ci /* Try to dequeue some more */ 491762306a36Sopenharmony_ci err = dpaa2_caam_pull_fq(ppriv); 491862306a36Sopenharmony_ci if (unlikely(err)) 491962306a36Sopenharmony_ci break; 492062306a36Sopenharmony_ci } while (1); 492162306a36Sopenharmony_ci 492262306a36Sopenharmony_ci if (cleaned < budget) { 492362306a36Sopenharmony_ci napi_complete_done(napi, cleaned); 492462306a36Sopenharmony_ci err = dpaa2_io_service_rearm(ppriv->dpio, &ppriv->nctx); 492562306a36Sopenharmony_ci if (unlikely(err)) 492662306a36Sopenharmony_ci dev_err(priv->dev, "Notification rearm failed: %d\n", 492762306a36Sopenharmony_ci err); 492862306a36Sopenharmony_ci } 492962306a36Sopenharmony_ci 493062306a36Sopenharmony_ci return cleaned; 493162306a36Sopenharmony_ci} 493262306a36Sopenharmony_ci 493362306a36Sopenharmony_cistatic int dpaa2_dpseci_congestion_setup(struct dpaa2_caam_priv *priv, 493462306a36Sopenharmony_ci u16 token) 493562306a36Sopenharmony_ci{ 493662306a36Sopenharmony_ci struct dpseci_congestion_notification_cfg cong_notif_cfg = { 0 }; 493762306a36Sopenharmony_ci struct device *dev = priv->dev; 493862306a36Sopenharmony_ci unsigned int alignmask; 493962306a36Sopenharmony_ci int err; 494062306a36Sopenharmony_ci 494162306a36Sopenharmony_ci /* 494262306a36Sopenharmony_ci * Congestion group feature supported starting with DPSECI API v5.1 494362306a36Sopenharmony_ci * and only when object has been created with this capability. 494462306a36Sopenharmony_ci */ 494562306a36Sopenharmony_ci if ((DPSECI_VER(priv->major_ver, priv->minor_ver) < DPSECI_VER(5, 1)) || 494662306a36Sopenharmony_ci !(priv->dpseci_attr.options & DPSECI_OPT_HAS_CG)) 494762306a36Sopenharmony_ci return 0; 494862306a36Sopenharmony_ci 494962306a36Sopenharmony_ci alignmask = DPAA2_CSCN_ALIGN - 1; 495062306a36Sopenharmony_ci alignmask |= dma_get_cache_alignment() - 1; 495162306a36Sopenharmony_ci priv->cscn_mem = kzalloc(ALIGN(DPAA2_CSCN_SIZE, alignmask + 1), 495262306a36Sopenharmony_ci GFP_KERNEL); 495362306a36Sopenharmony_ci if (!priv->cscn_mem) 495462306a36Sopenharmony_ci return -ENOMEM; 495562306a36Sopenharmony_ci 495662306a36Sopenharmony_ci priv->cscn_dma = dma_map_single(dev, priv->cscn_mem, 495762306a36Sopenharmony_ci DPAA2_CSCN_SIZE, DMA_FROM_DEVICE); 495862306a36Sopenharmony_ci if (dma_mapping_error(dev, priv->cscn_dma)) { 495962306a36Sopenharmony_ci dev_err(dev, "Error mapping CSCN memory area\n"); 496062306a36Sopenharmony_ci err = -ENOMEM; 496162306a36Sopenharmony_ci goto err_dma_map; 496262306a36Sopenharmony_ci } 496362306a36Sopenharmony_ci 496462306a36Sopenharmony_ci cong_notif_cfg.units = DPSECI_CONGESTION_UNIT_BYTES; 496562306a36Sopenharmony_ci cong_notif_cfg.threshold_entry = DPAA2_SEC_CONG_ENTRY_THRESH; 496662306a36Sopenharmony_ci cong_notif_cfg.threshold_exit = DPAA2_SEC_CONG_EXIT_THRESH; 496762306a36Sopenharmony_ci cong_notif_cfg.message_ctx = (uintptr_t)priv; 496862306a36Sopenharmony_ci cong_notif_cfg.message_iova = priv->cscn_dma; 496962306a36Sopenharmony_ci cong_notif_cfg.notification_mode = DPSECI_CGN_MODE_WRITE_MEM_ON_ENTER | 497062306a36Sopenharmony_ci DPSECI_CGN_MODE_WRITE_MEM_ON_EXIT | 497162306a36Sopenharmony_ci DPSECI_CGN_MODE_COHERENT_WRITE; 497262306a36Sopenharmony_ci 497362306a36Sopenharmony_ci err = dpseci_set_congestion_notification(priv->mc_io, 0, token, 497462306a36Sopenharmony_ci &cong_notif_cfg); 497562306a36Sopenharmony_ci if (err) { 497662306a36Sopenharmony_ci dev_err(dev, "dpseci_set_congestion_notification failed\n"); 497762306a36Sopenharmony_ci goto err_set_cong; 497862306a36Sopenharmony_ci } 497962306a36Sopenharmony_ci 498062306a36Sopenharmony_ci return 0; 498162306a36Sopenharmony_ci 498262306a36Sopenharmony_cierr_set_cong: 498362306a36Sopenharmony_ci dma_unmap_single(dev, priv->cscn_dma, DPAA2_CSCN_SIZE, DMA_FROM_DEVICE); 498462306a36Sopenharmony_cierr_dma_map: 498562306a36Sopenharmony_ci kfree(priv->cscn_mem); 498662306a36Sopenharmony_ci 498762306a36Sopenharmony_ci return err; 498862306a36Sopenharmony_ci} 498962306a36Sopenharmony_ci 499062306a36Sopenharmony_cistatic int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev) 499162306a36Sopenharmony_ci{ 499262306a36Sopenharmony_ci struct device *dev = &ls_dev->dev; 499362306a36Sopenharmony_ci struct dpaa2_caam_priv *priv; 499462306a36Sopenharmony_ci struct dpaa2_caam_priv_per_cpu *ppriv; 499562306a36Sopenharmony_ci int err, cpu; 499662306a36Sopenharmony_ci u8 i; 499762306a36Sopenharmony_ci 499862306a36Sopenharmony_ci priv = dev_get_drvdata(dev); 499962306a36Sopenharmony_ci 500062306a36Sopenharmony_ci priv->dev = dev; 500162306a36Sopenharmony_ci priv->dpsec_id = ls_dev->obj_desc.id; 500262306a36Sopenharmony_ci 500362306a36Sopenharmony_ci /* Get a handle for the DPSECI this interface is associate with */ 500462306a36Sopenharmony_ci err = dpseci_open(priv->mc_io, 0, priv->dpsec_id, &ls_dev->mc_handle); 500562306a36Sopenharmony_ci if (err) { 500662306a36Sopenharmony_ci dev_err(dev, "dpseci_open() failed: %d\n", err); 500762306a36Sopenharmony_ci goto err_open; 500862306a36Sopenharmony_ci } 500962306a36Sopenharmony_ci 501062306a36Sopenharmony_ci err = dpseci_get_api_version(priv->mc_io, 0, &priv->major_ver, 501162306a36Sopenharmony_ci &priv->minor_ver); 501262306a36Sopenharmony_ci if (err) { 501362306a36Sopenharmony_ci dev_err(dev, "dpseci_get_api_version() failed\n"); 501462306a36Sopenharmony_ci goto err_get_vers; 501562306a36Sopenharmony_ci } 501662306a36Sopenharmony_ci 501762306a36Sopenharmony_ci dev_info(dev, "dpseci v%d.%d\n", priv->major_ver, priv->minor_ver); 501862306a36Sopenharmony_ci 501962306a36Sopenharmony_ci if (DPSECI_VER(priv->major_ver, priv->minor_ver) > DPSECI_VER(5, 3)) { 502062306a36Sopenharmony_ci err = dpseci_reset(priv->mc_io, 0, ls_dev->mc_handle); 502162306a36Sopenharmony_ci if (err) { 502262306a36Sopenharmony_ci dev_err(dev, "dpseci_reset() failed\n"); 502362306a36Sopenharmony_ci goto err_get_vers; 502462306a36Sopenharmony_ci } 502562306a36Sopenharmony_ci } 502662306a36Sopenharmony_ci 502762306a36Sopenharmony_ci err = dpseci_get_attributes(priv->mc_io, 0, ls_dev->mc_handle, 502862306a36Sopenharmony_ci &priv->dpseci_attr); 502962306a36Sopenharmony_ci if (err) { 503062306a36Sopenharmony_ci dev_err(dev, "dpseci_get_attributes() failed\n"); 503162306a36Sopenharmony_ci goto err_get_vers; 503262306a36Sopenharmony_ci } 503362306a36Sopenharmony_ci 503462306a36Sopenharmony_ci err = dpseci_get_sec_attr(priv->mc_io, 0, ls_dev->mc_handle, 503562306a36Sopenharmony_ci &priv->sec_attr); 503662306a36Sopenharmony_ci if (err) { 503762306a36Sopenharmony_ci dev_err(dev, "dpseci_get_sec_attr() failed\n"); 503862306a36Sopenharmony_ci goto err_get_vers; 503962306a36Sopenharmony_ci } 504062306a36Sopenharmony_ci 504162306a36Sopenharmony_ci err = dpaa2_dpseci_congestion_setup(priv, ls_dev->mc_handle); 504262306a36Sopenharmony_ci if (err) { 504362306a36Sopenharmony_ci dev_err(dev, "setup_congestion() failed\n"); 504462306a36Sopenharmony_ci goto err_get_vers; 504562306a36Sopenharmony_ci } 504662306a36Sopenharmony_ci 504762306a36Sopenharmony_ci priv->num_pairs = min(priv->dpseci_attr.num_rx_queues, 504862306a36Sopenharmony_ci priv->dpseci_attr.num_tx_queues); 504962306a36Sopenharmony_ci if (priv->num_pairs > num_online_cpus()) { 505062306a36Sopenharmony_ci dev_warn(dev, "%d queues won't be used\n", 505162306a36Sopenharmony_ci priv->num_pairs - num_online_cpus()); 505262306a36Sopenharmony_ci priv->num_pairs = num_online_cpus(); 505362306a36Sopenharmony_ci } 505462306a36Sopenharmony_ci 505562306a36Sopenharmony_ci for (i = 0; i < priv->dpseci_attr.num_rx_queues; i++) { 505662306a36Sopenharmony_ci err = dpseci_get_rx_queue(priv->mc_io, 0, ls_dev->mc_handle, i, 505762306a36Sopenharmony_ci &priv->rx_queue_attr[i]); 505862306a36Sopenharmony_ci if (err) { 505962306a36Sopenharmony_ci dev_err(dev, "dpseci_get_rx_queue() failed\n"); 506062306a36Sopenharmony_ci goto err_get_rx_queue; 506162306a36Sopenharmony_ci } 506262306a36Sopenharmony_ci } 506362306a36Sopenharmony_ci 506462306a36Sopenharmony_ci for (i = 0; i < priv->dpseci_attr.num_tx_queues; i++) { 506562306a36Sopenharmony_ci err = dpseci_get_tx_queue(priv->mc_io, 0, ls_dev->mc_handle, i, 506662306a36Sopenharmony_ci &priv->tx_queue_attr[i]); 506762306a36Sopenharmony_ci if (err) { 506862306a36Sopenharmony_ci dev_err(dev, "dpseci_get_tx_queue() failed\n"); 506962306a36Sopenharmony_ci goto err_get_rx_queue; 507062306a36Sopenharmony_ci } 507162306a36Sopenharmony_ci } 507262306a36Sopenharmony_ci 507362306a36Sopenharmony_ci i = 0; 507462306a36Sopenharmony_ci for_each_online_cpu(cpu) { 507562306a36Sopenharmony_ci u8 j; 507662306a36Sopenharmony_ci 507762306a36Sopenharmony_ci j = i % priv->num_pairs; 507862306a36Sopenharmony_ci 507962306a36Sopenharmony_ci ppriv = per_cpu_ptr(priv->ppriv, cpu); 508062306a36Sopenharmony_ci ppriv->req_fqid = priv->tx_queue_attr[j].fqid; 508162306a36Sopenharmony_ci 508262306a36Sopenharmony_ci /* 508362306a36Sopenharmony_ci * Allow all cores to enqueue, while only some of them 508462306a36Sopenharmony_ci * will take part in dequeuing. 508562306a36Sopenharmony_ci */ 508662306a36Sopenharmony_ci if (++i > priv->num_pairs) 508762306a36Sopenharmony_ci continue; 508862306a36Sopenharmony_ci 508962306a36Sopenharmony_ci ppriv->rsp_fqid = priv->rx_queue_attr[j].fqid; 509062306a36Sopenharmony_ci ppriv->prio = j; 509162306a36Sopenharmony_ci 509262306a36Sopenharmony_ci dev_dbg(dev, "pair %d: rx queue %d, tx queue %d\n", j, 509362306a36Sopenharmony_ci priv->rx_queue_attr[j].fqid, 509462306a36Sopenharmony_ci priv->tx_queue_attr[j].fqid); 509562306a36Sopenharmony_ci 509662306a36Sopenharmony_ci ppriv->net_dev.dev = *dev; 509762306a36Sopenharmony_ci INIT_LIST_HEAD(&ppriv->net_dev.napi_list); 509862306a36Sopenharmony_ci netif_napi_add_tx_weight(&ppriv->net_dev, &ppriv->napi, 509962306a36Sopenharmony_ci dpaa2_dpseci_poll, 510062306a36Sopenharmony_ci DPAA2_CAAM_NAPI_WEIGHT); 510162306a36Sopenharmony_ci } 510262306a36Sopenharmony_ci 510362306a36Sopenharmony_ci return 0; 510462306a36Sopenharmony_ci 510562306a36Sopenharmony_cierr_get_rx_queue: 510662306a36Sopenharmony_ci dpaa2_dpseci_congestion_free(priv); 510762306a36Sopenharmony_cierr_get_vers: 510862306a36Sopenharmony_ci dpseci_close(priv->mc_io, 0, ls_dev->mc_handle); 510962306a36Sopenharmony_cierr_open: 511062306a36Sopenharmony_ci return err; 511162306a36Sopenharmony_ci} 511262306a36Sopenharmony_ci 511362306a36Sopenharmony_cistatic int dpaa2_dpseci_enable(struct dpaa2_caam_priv *priv) 511462306a36Sopenharmony_ci{ 511562306a36Sopenharmony_ci struct device *dev = priv->dev; 511662306a36Sopenharmony_ci struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev); 511762306a36Sopenharmony_ci struct dpaa2_caam_priv_per_cpu *ppriv; 511862306a36Sopenharmony_ci int i; 511962306a36Sopenharmony_ci 512062306a36Sopenharmony_ci for (i = 0; i < priv->num_pairs; i++) { 512162306a36Sopenharmony_ci ppriv = per_cpu_ptr(priv->ppriv, i); 512262306a36Sopenharmony_ci napi_enable(&ppriv->napi); 512362306a36Sopenharmony_ci } 512462306a36Sopenharmony_ci 512562306a36Sopenharmony_ci return dpseci_enable(priv->mc_io, 0, ls_dev->mc_handle); 512662306a36Sopenharmony_ci} 512762306a36Sopenharmony_ci 512862306a36Sopenharmony_cistatic int __cold dpaa2_dpseci_disable(struct dpaa2_caam_priv *priv) 512962306a36Sopenharmony_ci{ 513062306a36Sopenharmony_ci struct device *dev = priv->dev; 513162306a36Sopenharmony_ci struct dpaa2_caam_priv_per_cpu *ppriv; 513262306a36Sopenharmony_ci struct fsl_mc_device *ls_dev = to_fsl_mc_device(dev); 513362306a36Sopenharmony_ci int i, err = 0, enabled; 513462306a36Sopenharmony_ci 513562306a36Sopenharmony_ci err = dpseci_disable(priv->mc_io, 0, ls_dev->mc_handle); 513662306a36Sopenharmony_ci if (err) { 513762306a36Sopenharmony_ci dev_err(dev, "dpseci_disable() failed\n"); 513862306a36Sopenharmony_ci return err; 513962306a36Sopenharmony_ci } 514062306a36Sopenharmony_ci 514162306a36Sopenharmony_ci err = dpseci_is_enabled(priv->mc_io, 0, ls_dev->mc_handle, &enabled); 514262306a36Sopenharmony_ci if (err) { 514362306a36Sopenharmony_ci dev_err(dev, "dpseci_is_enabled() failed\n"); 514462306a36Sopenharmony_ci return err; 514562306a36Sopenharmony_ci } 514662306a36Sopenharmony_ci 514762306a36Sopenharmony_ci dev_dbg(dev, "disable: %s\n", enabled ? "false" : "true"); 514862306a36Sopenharmony_ci 514962306a36Sopenharmony_ci for (i = 0; i < priv->num_pairs; i++) { 515062306a36Sopenharmony_ci ppriv = per_cpu_ptr(priv->ppriv, i); 515162306a36Sopenharmony_ci napi_disable(&ppriv->napi); 515262306a36Sopenharmony_ci netif_napi_del(&ppriv->napi); 515362306a36Sopenharmony_ci } 515462306a36Sopenharmony_ci 515562306a36Sopenharmony_ci return 0; 515662306a36Sopenharmony_ci} 515762306a36Sopenharmony_ci 515862306a36Sopenharmony_cistatic struct list_head hash_list; 515962306a36Sopenharmony_ci 516062306a36Sopenharmony_cistatic int dpaa2_caam_probe(struct fsl_mc_device *dpseci_dev) 516162306a36Sopenharmony_ci{ 516262306a36Sopenharmony_ci struct device *dev; 516362306a36Sopenharmony_ci struct dpaa2_caam_priv *priv; 516462306a36Sopenharmony_ci int i, err = 0; 516562306a36Sopenharmony_ci bool registered = false; 516662306a36Sopenharmony_ci 516762306a36Sopenharmony_ci /* 516862306a36Sopenharmony_ci * There is no way to get CAAM endianness - there is no direct register 516962306a36Sopenharmony_ci * space access and MC f/w does not provide this attribute. 517062306a36Sopenharmony_ci * All DPAA2-based SoCs have little endian CAAM, thus hard-code this 517162306a36Sopenharmony_ci * property. 517262306a36Sopenharmony_ci */ 517362306a36Sopenharmony_ci caam_little_end = true; 517462306a36Sopenharmony_ci 517562306a36Sopenharmony_ci caam_imx = false; 517662306a36Sopenharmony_ci 517762306a36Sopenharmony_ci dev = &dpseci_dev->dev; 517862306a36Sopenharmony_ci 517962306a36Sopenharmony_ci priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 518062306a36Sopenharmony_ci if (!priv) 518162306a36Sopenharmony_ci return -ENOMEM; 518262306a36Sopenharmony_ci 518362306a36Sopenharmony_ci dev_set_drvdata(dev, priv); 518462306a36Sopenharmony_ci 518562306a36Sopenharmony_ci priv->domain = iommu_get_domain_for_dev(dev); 518662306a36Sopenharmony_ci 518762306a36Sopenharmony_ci qi_cache = kmem_cache_create("dpaa2_caamqicache", CAAM_QI_MEMCACHE_SIZE, 518862306a36Sopenharmony_ci 0, 0, NULL); 518962306a36Sopenharmony_ci if (!qi_cache) { 519062306a36Sopenharmony_ci dev_err(dev, "Can't allocate SEC cache\n"); 519162306a36Sopenharmony_ci return -ENOMEM; 519262306a36Sopenharmony_ci } 519362306a36Sopenharmony_ci 519462306a36Sopenharmony_ci err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(49)); 519562306a36Sopenharmony_ci if (err) { 519662306a36Sopenharmony_ci dev_err(dev, "dma_set_mask_and_coherent() failed\n"); 519762306a36Sopenharmony_ci goto err_dma_mask; 519862306a36Sopenharmony_ci } 519962306a36Sopenharmony_ci 520062306a36Sopenharmony_ci /* Obtain a MC portal */ 520162306a36Sopenharmony_ci err = fsl_mc_portal_allocate(dpseci_dev, 0, &priv->mc_io); 520262306a36Sopenharmony_ci if (err) { 520362306a36Sopenharmony_ci if (err == -ENXIO) 520462306a36Sopenharmony_ci err = -EPROBE_DEFER; 520562306a36Sopenharmony_ci else 520662306a36Sopenharmony_ci dev_err(dev, "MC portal allocation failed\n"); 520762306a36Sopenharmony_ci 520862306a36Sopenharmony_ci goto err_dma_mask; 520962306a36Sopenharmony_ci } 521062306a36Sopenharmony_ci 521162306a36Sopenharmony_ci priv->ppriv = alloc_percpu(*priv->ppriv); 521262306a36Sopenharmony_ci if (!priv->ppriv) { 521362306a36Sopenharmony_ci dev_err(dev, "alloc_percpu() failed\n"); 521462306a36Sopenharmony_ci err = -ENOMEM; 521562306a36Sopenharmony_ci goto err_alloc_ppriv; 521662306a36Sopenharmony_ci } 521762306a36Sopenharmony_ci 521862306a36Sopenharmony_ci /* DPSECI initialization */ 521962306a36Sopenharmony_ci err = dpaa2_dpseci_setup(dpseci_dev); 522062306a36Sopenharmony_ci if (err) { 522162306a36Sopenharmony_ci dev_err(dev, "dpaa2_dpseci_setup() failed\n"); 522262306a36Sopenharmony_ci goto err_dpseci_setup; 522362306a36Sopenharmony_ci } 522462306a36Sopenharmony_ci 522562306a36Sopenharmony_ci /* DPIO */ 522662306a36Sopenharmony_ci err = dpaa2_dpseci_dpio_setup(priv); 522762306a36Sopenharmony_ci if (err) { 522862306a36Sopenharmony_ci dev_err_probe(dev, err, "dpaa2_dpseci_dpio_setup() failed\n"); 522962306a36Sopenharmony_ci goto err_dpio_setup; 523062306a36Sopenharmony_ci } 523162306a36Sopenharmony_ci 523262306a36Sopenharmony_ci /* DPSECI binding to DPIO */ 523362306a36Sopenharmony_ci err = dpaa2_dpseci_bind(priv); 523462306a36Sopenharmony_ci if (err) { 523562306a36Sopenharmony_ci dev_err(dev, "dpaa2_dpseci_bind() failed\n"); 523662306a36Sopenharmony_ci goto err_bind; 523762306a36Sopenharmony_ci } 523862306a36Sopenharmony_ci 523962306a36Sopenharmony_ci /* DPSECI enable */ 524062306a36Sopenharmony_ci err = dpaa2_dpseci_enable(priv); 524162306a36Sopenharmony_ci if (err) { 524262306a36Sopenharmony_ci dev_err(dev, "dpaa2_dpseci_enable() failed\n"); 524362306a36Sopenharmony_ci goto err_bind; 524462306a36Sopenharmony_ci } 524562306a36Sopenharmony_ci 524662306a36Sopenharmony_ci dpaa2_dpseci_debugfs_init(priv); 524762306a36Sopenharmony_ci 524862306a36Sopenharmony_ci /* register crypto algorithms the device supports */ 524962306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { 525062306a36Sopenharmony_ci struct caam_skcipher_alg *t_alg = driver_algs + i; 525162306a36Sopenharmony_ci u32 alg_sel = t_alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK; 525262306a36Sopenharmony_ci 525362306a36Sopenharmony_ci /* Skip DES algorithms if not supported by device */ 525462306a36Sopenharmony_ci if (!priv->sec_attr.des_acc_num && 525562306a36Sopenharmony_ci (alg_sel == OP_ALG_ALGSEL_3DES || 525662306a36Sopenharmony_ci alg_sel == OP_ALG_ALGSEL_DES)) 525762306a36Sopenharmony_ci continue; 525862306a36Sopenharmony_ci 525962306a36Sopenharmony_ci /* Skip AES algorithms if not supported by device */ 526062306a36Sopenharmony_ci if (!priv->sec_attr.aes_acc_num && 526162306a36Sopenharmony_ci alg_sel == OP_ALG_ALGSEL_AES) 526262306a36Sopenharmony_ci continue; 526362306a36Sopenharmony_ci 526462306a36Sopenharmony_ci /* Skip CHACHA20 algorithms if not supported by device */ 526562306a36Sopenharmony_ci if (alg_sel == OP_ALG_ALGSEL_CHACHA20 && 526662306a36Sopenharmony_ci !priv->sec_attr.ccha_acc_num) 526762306a36Sopenharmony_ci continue; 526862306a36Sopenharmony_ci 526962306a36Sopenharmony_ci t_alg->caam.dev = dev; 527062306a36Sopenharmony_ci caam_skcipher_alg_init(t_alg); 527162306a36Sopenharmony_ci 527262306a36Sopenharmony_ci err = crypto_register_skcipher(&t_alg->skcipher); 527362306a36Sopenharmony_ci if (err) { 527462306a36Sopenharmony_ci dev_warn(dev, "%s alg registration failed: %d\n", 527562306a36Sopenharmony_ci t_alg->skcipher.base.cra_driver_name, err); 527662306a36Sopenharmony_ci continue; 527762306a36Sopenharmony_ci } 527862306a36Sopenharmony_ci 527962306a36Sopenharmony_ci t_alg->registered = true; 528062306a36Sopenharmony_ci registered = true; 528162306a36Sopenharmony_ci } 528262306a36Sopenharmony_ci 528362306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) { 528462306a36Sopenharmony_ci struct caam_aead_alg *t_alg = driver_aeads + i; 528562306a36Sopenharmony_ci u32 c1_alg_sel = t_alg->caam.class1_alg_type & 528662306a36Sopenharmony_ci OP_ALG_ALGSEL_MASK; 528762306a36Sopenharmony_ci u32 c2_alg_sel = t_alg->caam.class2_alg_type & 528862306a36Sopenharmony_ci OP_ALG_ALGSEL_MASK; 528962306a36Sopenharmony_ci 529062306a36Sopenharmony_ci /* Skip DES algorithms if not supported by device */ 529162306a36Sopenharmony_ci if (!priv->sec_attr.des_acc_num && 529262306a36Sopenharmony_ci (c1_alg_sel == OP_ALG_ALGSEL_3DES || 529362306a36Sopenharmony_ci c1_alg_sel == OP_ALG_ALGSEL_DES)) 529462306a36Sopenharmony_ci continue; 529562306a36Sopenharmony_ci 529662306a36Sopenharmony_ci /* Skip AES algorithms if not supported by device */ 529762306a36Sopenharmony_ci if (!priv->sec_attr.aes_acc_num && 529862306a36Sopenharmony_ci c1_alg_sel == OP_ALG_ALGSEL_AES) 529962306a36Sopenharmony_ci continue; 530062306a36Sopenharmony_ci 530162306a36Sopenharmony_ci /* Skip CHACHA20 algorithms if not supported by device */ 530262306a36Sopenharmony_ci if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 && 530362306a36Sopenharmony_ci !priv->sec_attr.ccha_acc_num) 530462306a36Sopenharmony_ci continue; 530562306a36Sopenharmony_ci 530662306a36Sopenharmony_ci /* Skip POLY1305 algorithms if not supported by device */ 530762306a36Sopenharmony_ci if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 && 530862306a36Sopenharmony_ci !priv->sec_attr.ptha_acc_num) 530962306a36Sopenharmony_ci continue; 531062306a36Sopenharmony_ci 531162306a36Sopenharmony_ci /* 531262306a36Sopenharmony_ci * Skip algorithms requiring message digests 531362306a36Sopenharmony_ci * if MD not supported by device. 531462306a36Sopenharmony_ci */ 531562306a36Sopenharmony_ci if ((c2_alg_sel & ~OP_ALG_ALGSEL_SUBMASK) == 0x40 && 531662306a36Sopenharmony_ci !priv->sec_attr.md_acc_num) 531762306a36Sopenharmony_ci continue; 531862306a36Sopenharmony_ci 531962306a36Sopenharmony_ci t_alg->caam.dev = dev; 532062306a36Sopenharmony_ci caam_aead_alg_init(t_alg); 532162306a36Sopenharmony_ci 532262306a36Sopenharmony_ci err = crypto_register_aead(&t_alg->aead); 532362306a36Sopenharmony_ci if (err) { 532462306a36Sopenharmony_ci dev_warn(dev, "%s alg registration failed: %d\n", 532562306a36Sopenharmony_ci t_alg->aead.base.cra_driver_name, err); 532662306a36Sopenharmony_ci continue; 532762306a36Sopenharmony_ci } 532862306a36Sopenharmony_ci 532962306a36Sopenharmony_ci t_alg->registered = true; 533062306a36Sopenharmony_ci registered = true; 533162306a36Sopenharmony_ci } 533262306a36Sopenharmony_ci if (registered) 533362306a36Sopenharmony_ci dev_info(dev, "algorithms registered in /proc/crypto\n"); 533462306a36Sopenharmony_ci 533562306a36Sopenharmony_ci /* register hash algorithms the device supports */ 533662306a36Sopenharmony_ci INIT_LIST_HEAD(&hash_list); 533762306a36Sopenharmony_ci 533862306a36Sopenharmony_ci /* 533962306a36Sopenharmony_ci * Skip registration of any hashing algorithms if MD block 534062306a36Sopenharmony_ci * is not present. 534162306a36Sopenharmony_ci */ 534262306a36Sopenharmony_ci if (!priv->sec_attr.md_acc_num) 534362306a36Sopenharmony_ci return 0; 534462306a36Sopenharmony_ci 534562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(driver_hash); i++) { 534662306a36Sopenharmony_ci struct caam_hash_alg *t_alg; 534762306a36Sopenharmony_ci struct caam_hash_template *alg = driver_hash + i; 534862306a36Sopenharmony_ci 534962306a36Sopenharmony_ci /* register hmac version */ 535062306a36Sopenharmony_ci t_alg = caam_hash_alloc(dev, alg, true); 535162306a36Sopenharmony_ci if (IS_ERR(t_alg)) { 535262306a36Sopenharmony_ci err = PTR_ERR(t_alg); 535362306a36Sopenharmony_ci dev_warn(dev, "%s hash alg allocation failed: %d\n", 535462306a36Sopenharmony_ci alg->hmac_driver_name, err); 535562306a36Sopenharmony_ci continue; 535662306a36Sopenharmony_ci } 535762306a36Sopenharmony_ci 535862306a36Sopenharmony_ci err = crypto_register_ahash(&t_alg->ahash_alg); 535962306a36Sopenharmony_ci if (err) { 536062306a36Sopenharmony_ci dev_warn(dev, "%s alg registration failed: %d\n", 536162306a36Sopenharmony_ci t_alg->ahash_alg.halg.base.cra_driver_name, 536262306a36Sopenharmony_ci err); 536362306a36Sopenharmony_ci kfree(t_alg); 536462306a36Sopenharmony_ci } else { 536562306a36Sopenharmony_ci list_add_tail(&t_alg->entry, &hash_list); 536662306a36Sopenharmony_ci } 536762306a36Sopenharmony_ci 536862306a36Sopenharmony_ci /* register unkeyed version */ 536962306a36Sopenharmony_ci t_alg = caam_hash_alloc(dev, alg, false); 537062306a36Sopenharmony_ci if (IS_ERR(t_alg)) { 537162306a36Sopenharmony_ci err = PTR_ERR(t_alg); 537262306a36Sopenharmony_ci dev_warn(dev, "%s alg allocation failed: %d\n", 537362306a36Sopenharmony_ci alg->driver_name, err); 537462306a36Sopenharmony_ci continue; 537562306a36Sopenharmony_ci } 537662306a36Sopenharmony_ci 537762306a36Sopenharmony_ci err = crypto_register_ahash(&t_alg->ahash_alg); 537862306a36Sopenharmony_ci if (err) { 537962306a36Sopenharmony_ci dev_warn(dev, "%s alg registration failed: %d\n", 538062306a36Sopenharmony_ci t_alg->ahash_alg.halg.base.cra_driver_name, 538162306a36Sopenharmony_ci err); 538262306a36Sopenharmony_ci kfree(t_alg); 538362306a36Sopenharmony_ci } else { 538462306a36Sopenharmony_ci list_add_tail(&t_alg->entry, &hash_list); 538562306a36Sopenharmony_ci } 538662306a36Sopenharmony_ci } 538762306a36Sopenharmony_ci if (!list_empty(&hash_list)) 538862306a36Sopenharmony_ci dev_info(dev, "hash algorithms registered in /proc/crypto\n"); 538962306a36Sopenharmony_ci 539062306a36Sopenharmony_ci return err; 539162306a36Sopenharmony_ci 539262306a36Sopenharmony_cierr_bind: 539362306a36Sopenharmony_ci dpaa2_dpseci_dpio_free(priv); 539462306a36Sopenharmony_cierr_dpio_setup: 539562306a36Sopenharmony_ci dpaa2_dpseci_free(priv); 539662306a36Sopenharmony_cierr_dpseci_setup: 539762306a36Sopenharmony_ci free_percpu(priv->ppriv); 539862306a36Sopenharmony_cierr_alloc_ppriv: 539962306a36Sopenharmony_ci fsl_mc_portal_free(priv->mc_io); 540062306a36Sopenharmony_cierr_dma_mask: 540162306a36Sopenharmony_ci kmem_cache_destroy(qi_cache); 540262306a36Sopenharmony_ci 540362306a36Sopenharmony_ci return err; 540462306a36Sopenharmony_ci} 540562306a36Sopenharmony_ci 540662306a36Sopenharmony_cistatic void __cold dpaa2_caam_remove(struct fsl_mc_device *ls_dev) 540762306a36Sopenharmony_ci{ 540862306a36Sopenharmony_ci struct device *dev; 540962306a36Sopenharmony_ci struct dpaa2_caam_priv *priv; 541062306a36Sopenharmony_ci int i; 541162306a36Sopenharmony_ci 541262306a36Sopenharmony_ci dev = &ls_dev->dev; 541362306a36Sopenharmony_ci priv = dev_get_drvdata(dev); 541462306a36Sopenharmony_ci 541562306a36Sopenharmony_ci dpaa2_dpseci_debugfs_exit(priv); 541662306a36Sopenharmony_ci 541762306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) { 541862306a36Sopenharmony_ci struct caam_aead_alg *t_alg = driver_aeads + i; 541962306a36Sopenharmony_ci 542062306a36Sopenharmony_ci if (t_alg->registered) 542162306a36Sopenharmony_ci crypto_unregister_aead(&t_alg->aead); 542262306a36Sopenharmony_ci } 542362306a36Sopenharmony_ci 542462306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { 542562306a36Sopenharmony_ci struct caam_skcipher_alg *t_alg = driver_algs + i; 542662306a36Sopenharmony_ci 542762306a36Sopenharmony_ci if (t_alg->registered) 542862306a36Sopenharmony_ci crypto_unregister_skcipher(&t_alg->skcipher); 542962306a36Sopenharmony_ci } 543062306a36Sopenharmony_ci 543162306a36Sopenharmony_ci if (hash_list.next) { 543262306a36Sopenharmony_ci struct caam_hash_alg *t_hash_alg, *p; 543362306a36Sopenharmony_ci 543462306a36Sopenharmony_ci list_for_each_entry_safe(t_hash_alg, p, &hash_list, entry) { 543562306a36Sopenharmony_ci crypto_unregister_ahash(&t_hash_alg->ahash_alg); 543662306a36Sopenharmony_ci list_del(&t_hash_alg->entry); 543762306a36Sopenharmony_ci kfree(t_hash_alg); 543862306a36Sopenharmony_ci } 543962306a36Sopenharmony_ci } 544062306a36Sopenharmony_ci 544162306a36Sopenharmony_ci dpaa2_dpseci_disable(priv); 544262306a36Sopenharmony_ci dpaa2_dpseci_dpio_free(priv); 544362306a36Sopenharmony_ci dpaa2_dpseci_free(priv); 544462306a36Sopenharmony_ci free_percpu(priv->ppriv); 544562306a36Sopenharmony_ci fsl_mc_portal_free(priv->mc_io); 544662306a36Sopenharmony_ci kmem_cache_destroy(qi_cache); 544762306a36Sopenharmony_ci} 544862306a36Sopenharmony_ci 544962306a36Sopenharmony_ciint dpaa2_caam_enqueue(struct device *dev, struct caam_request *req) 545062306a36Sopenharmony_ci{ 545162306a36Sopenharmony_ci struct dpaa2_fd fd; 545262306a36Sopenharmony_ci struct dpaa2_caam_priv *priv = dev_get_drvdata(dev); 545362306a36Sopenharmony_ci struct dpaa2_caam_priv_per_cpu *ppriv; 545462306a36Sopenharmony_ci int err = 0, i; 545562306a36Sopenharmony_ci 545662306a36Sopenharmony_ci if (IS_ERR(req)) 545762306a36Sopenharmony_ci return PTR_ERR(req); 545862306a36Sopenharmony_ci 545962306a36Sopenharmony_ci if (priv->cscn_mem) { 546062306a36Sopenharmony_ci dma_sync_single_for_cpu(priv->dev, priv->cscn_dma, 546162306a36Sopenharmony_ci DPAA2_CSCN_SIZE, 546262306a36Sopenharmony_ci DMA_FROM_DEVICE); 546362306a36Sopenharmony_ci if (unlikely(dpaa2_cscn_state_congested(priv->cscn_mem))) { 546462306a36Sopenharmony_ci dev_dbg_ratelimited(dev, "Dropping request\n"); 546562306a36Sopenharmony_ci return -EBUSY; 546662306a36Sopenharmony_ci } 546762306a36Sopenharmony_ci } 546862306a36Sopenharmony_ci 546962306a36Sopenharmony_ci dpaa2_fl_set_flc(&req->fd_flt[1], req->flc_dma); 547062306a36Sopenharmony_ci 547162306a36Sopenharmony_ci req->fd_flt_dma = dma_map_single(dev, req->fd_flt, sizeof(req->fd_flt), 547262306a36Sopenharmony_ci DMA_BIDIRECTIONAL); 547362306a36Sopenharmony_ci if (dma_mapping_error(dev, req->fd_flt_dma)) { 547462306a36Sopenharmony_ci dev_err(dev, "DMA mapping error for QI enqueue request\n"); 547562306a36Sopenharmony_ci goto err_out; 547662306a36Sopenharmony_ci } 547762306a36Sopenharmony_ci 547862306a36Sopenharmony_ci memset(&fd, 0, sizeof(fd)); 547962306a36Sopenharmony_ci dpaa2_fd_set_format(&fd, dpaa2_fd_list); 548062306a36Sopenharmony_ci dpaa2_fd_set_addr(&fd, req->fd_flt_dma); 548162306a36Sopenharmony_ci dpaa2_fd_set_len(&fd, dpaa2_fl_get_len(&req->fd_flt[1])); 548262306a36Sopenharmony_ci dpaa2_fd_set_flc(&fd, req->flc_dma); 548362306a36Sopenharmony_ci 548462306a36Sopenharmony_ci ppriv = raw_cpu_ptr(priv->ppriv); 548562306a36Sopenharmony_ci for (i = 0; i < (priv->dpseci_attr.num_tx_queues << 1); i++) { 548662306a36Sopenharmony_ci err = dpaa2_io_service_enqueue_fq(ppriv->dpio, ppriv->req_fqid, 548762306a36Sopenharmony_ci &fd); 548862306a36Sopenharmony_ci if (err != -EBUSY) 548962306a36Sopenharmony_ci break; 549062306a36Sopenharmony_ci 549162306a36Sopenharmony_ci cpu_relax(); 549262306a36Sopenharmony_ci } 549362306a36Sopenharmony_ci 549462306a36Sopenharmony_ci if (unlikely(err)) { 549562306a36Sopenharmony_ci dev_err_ratelimited(dev, "Error enqueuing frame: %d\n", err); 549662306a36Sopenharmony_ci goto err_out; 549762306a36Sopenharmony_ci } 549862306a36Sopenharmony_ci 549962306a36Sopenharmony_ci return -EINPROGRESS; 550062306a36Sopenharmony_ci 550162306a36Sopenharmony_cierr_out: 550262306a36Sopenharmony_ci dma_unmap_single(dev, req->fd_flt_dma, sizeof(req->fd_flt), 550362306a36Sopenharmony_ci DMA_BIDIRECTIONAL); 550462306a36Sopenharmony_ci return -EIO; 550562306a36Sopenharmony_ci} 550662306a36Sopenharmony_ciEXPORT_SYMBOL(dpaa2_caam_enqueue); 550762306a36Sopenharmony_ci 550862306a36Sopenharmony_cistatic const struct fsl_mc_device_id dpaa2_caam_match_id_table[] = { 550962306a36Sopenharmony_ci { 551062306a36Sopenharmony_ci .vendor = FSL_MC_VENDOR_FREESCALE, 551162306a36Sopenharmony_ci .obj_type = "dpseci", 551262306a36Sopenharmony_ci }, 551362306a36Sopenharmony_ci { .vendor = 0x0 } 551462306a36Sopenharmony_ci}; 551562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(fslmc, dpaa2_caam_match_id_table); 551662306a36Sopenharmony_ci 551762306a36Sopenharmony_cistatic struct fsl_mc_driver dpaa2_caam_driver = { 551862306a36Sopenharmony_ci .driver = { 551962306a36Sopenharmony_ci .name = KBUILD_MODNAME, 552062306a36Sopenharmony_ci .owner = THIS_MODULE, 552162306a36Sopenharmony_ci }, 552262306a36Sopenharmony_ci .probe = dpaa2_caam_probe, 552362306a36Sopenharmony_ci .remove = dpaa2_caam_remove, 552462306a36Sopenharmony_ci .match_id_table = dpaa2_caam_match_id_table 552562306a36Sopenharmony_ci}; 552662306a36Sopenharmony_ci 552762306a36Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 552862306a36Sopenharmony_ciMODULE_AUTHOR("Freescale Semiconductor, Inc"); 552962306a36Sopenharmony_ciMODULE_DESCRIPTION("Freescale DPAA2 CAAM Driver"); 553062306a36Sopenharmony_ci 553162306a36Sopenharmony_cimodule_fsl_mc_driver(dpaa2_caam_driver); 5532