diff options
| author | Herbert Xu <herbert@gondor.apana.org.au> | 2024-09-04 07:09:51 +0800 |
|---|---|---|
| committer | Herbert Xu <herbert@gondor.apana.org.au> | 2024-09-04 07:09:51 +0800 |
| commit | b8fc70ab7b5f3afbc4fb0587782633d7fcf1e069 (patch) | |
| tree | 6a76c35f787b1481155c2f490f502335aab9bdfd /drivers/crypto | |
| parent | be9c336852056e2c34369de79fd938dc21a2d5cf (diff) | |
| download | linux-b8fc70ab7b5f3afbc4fb0587782633d7fcf1e069.tar.gz linux-b8fc70ab7b5f3afbc4fb0587782633d7fcf1e069.tar.bz2 linux-b8fc70ab7b5f3afbc4fb0587782633d7fcf1e069.zip | |
Revert "crypto: spacc - Add SPAcc Skcipher support"
This reverts the following commits:
87a3fcf5fec5fb59ec8f23d12a56bcf2b2ee6db7
58bf99100a6dfcc53ba4ab547f1394bb6873b2ac
3b1c9df662915a18a86f1a88364ee70875ed3b44
8bc1bfa02e37d63632f0cb65543e3e71acdccafb
c32f08d024e275059474b3c11c1fc2bc7f2de990
f036dd566453176d4eafb9701ebd69e7e59d6707
c76c9ec333432088a1c6f52650c149530fc5df5d
5d22d37aa8b93efaad797faf80db40ea59453481
b63483b37e813299445d2719488acab2b3f20544
2d6213bd592b4731b53ece3492f9d1d18e97eb5e
fc61c658c94cb7405ca6946d8f2a2b71cef49845
cb67c924b2a7b561bd7f4f2bd66766337c1007b7
06af76b46c78f4729fe2f9712a74502c90d87554
9f1a7ab4d31ef30fbf8adb0985300049469f2270
8ebb14deef0f374f7ca0d34a1ad720ba0a7b79f3
c8981d9230d808e62c65349d0b255c7f4b9087d6
They were submitted with no device tree bindings.
Reported-by: Rob Herring <robh@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto')
| -rw-r--r-- | drivers/crypto/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/crypto/Makefile | 1 | ||||
| -rw-r--r-- | drivers/crypto/dwc-spacc/Kconfig | 95 | ||||
| -rw-r--r-- | drivers/crypto/dwc-spacc/Makefile | 16 | ||||
| -rwxr-xr-x | drivers/crypto/dwc-spacc/spacc_aead.c | 1243 | ||||
| -rw-r--r-- | drivers/crypto/dwc-spacc/spacc_ahash.c | 914 | ||||
| -rw-r--r-- | drivers/crypto/dwc-spacc/spacc_core.c | 2513 | ||||
| -rw-r--r-- | drivers/crypto/dwc-spacc/spacc_core.h | 824 | ||||
| -rw-r--r-- | drivers/crypto/dwc-spacc/spacc_device.c | 338 | ||||
| -rw-r--r-- | drivers/crypto/dwc-spacc/spacc_device.h | 231 | ||||
| -rw-r--r-- | drivers/crypto/dwc-spacc/spacc_hal.c | 367 | ||||
| -rw-r--r-- | drivers/crypto/dwc-spacc/spacc_hal.h | 114 | ||||
| -rw-r--r-- | drivers/crypto/dwc-spacc/spacc_interrupt.c | 316 | ||||
| -rw-r--r-- | drivers/crypto/dwc-spacc/spacc_manager.c | 653 | ||||
| -rw-r--r-- | drivers/crypto/dwc-spacc/spacc_skcipher.c | 717 |
15 files changed, 0 insertions, 8343 deletions
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 009cbd0e1993..94f23c6fc93b 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -696,7 +696,6 @@ config CRYPTO_DEV_BCM_SPU ahash, and aead algorithms with the kernel cryptographic API. source "drivers/crypto/stm32/Kconfig" -source "drivers/crypto/dwc-spacc/Kconfig" config CRYPTO_DEV_SAFEXCEL tristate "Inside Secure's SafeXcel cryptographic engine driver" diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index a937e8f5849b..ad4ccef67d12 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -48,7 +48,6 @@ obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/ obj-$(CONFIG_CRYPTO_DEV_SAFEXCEL) += inside-secure/ obj-$(CONFIG_CRYPTO_DEV_ARTPEC6) += axis/ obj-y += xilinx/ -obj-y += dwc-spacc/ obj-y += hisilicon/ obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/ obj-y += intel/ diff --git a/drivers/crypto/dwc-spacc/Kconfig b/drivers/crypto/dwc-spacc/Kconfig deleted file mode 100644 index 9eb41a295f9d..000000000000 --- a/drivers/crypto/dwc-spacc/Kconfig +++ /dev/null @@ -1,95 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only - -config CRYPTO_DEV_SPACC - tristate "Support for dw_spacc Security protocol accelerators" - depends on HAS_DMA - default m - - help - This enables support for the HASH/CRYP/AEAD hw accelerator which can be found - on dw_spacc IP. - -config CRYPTO_DEV_SPACC_CIPHER - bool "Enable CIPHER functionality" - depends on CRYPTO_DEV_SPACC - default y - select CRYPTO_SKCIPHER - select CRYPTO_LIB_DES - select CRYPTO_AES - select CRYPTO_CBC - select CRYPTO_ECB - select CRYPTO_CTR - select CRYPTO_XTS - select CRYPTO_CTS - select CRYPTO_OFB - select CRYPTO_CFB - select CRYPTO_SM4_GENERIC - select CRYPTO_CHACHA20 - - help - Say y to enable Cipher functionality of SPACC. - -config CRYPTO_DEV_SPACC_HASH - bool "Enable HASH functionality" - depends on CRYPTO_DEV_SPACC - default y - select CRYPTO_HASH - select CRYPTO_SHA1 - select CRYPTO_MD5 - select CRYPTO_SHA256 - select CRYPTO_SHA512 - select CRYPTO_HMAC - select CRYPTO_SM3 - select CRYPTO_CMAC - select CRYPTO_MICHAEL_MIC - select CRYPTO_XCBC - select CRYPTO_AES - select CRYPTO_SM4_GENERIC - - help - Say y to enable Hash functionality of SPACC. - -config CRYPTO_DEV_SPACC_AEAD - bool "Enable AEAD functionality" - depends on CRYPTO_DEV_SPACC - default y - select CRYPTO_AEAD - select CRYPTO_AUTHENC - select CRYPTO_AES - select CRYPTO_SM4_GENERIC - select CRYPTO_CHACHAPOLY1305 - select CRYPTO_GCM - select CRYPTO_CCM - - help - Say y to enable AEAD functionality of SPACC. - -config CRYPTO_DEV_SPACC_AUTODETECT - bool "Enable Autodetect functionality" - depends on CRYPTO_DEV_SPACC - default y - help - Say y to enable Autodetect functionality - -config CRYPTO_DEV_SPACC_DEBUG_TRACE_IO - bool "Enable Trace MMIO reads/writes stats" - depends on CRYPTO_DEV_SPACC - default n - help - Say y to enable Trace MMIO reads/writes stats. - To Debug and trace IO register read/write opration - -config CRYPTO_DEV_SPACC_DEBUG_TRACE_DDT - bool "Enable Trace DDT entries stats" - default n - depends on CRYPTO_DEV_SPACC - help - Say y to enable Enable Trace DDT entries stats. - To Debug and trace DDT opration - -config CRYPTO_DEV_SPACC_SECURE_MODE - bool "Enable Spacc secure mode stats" - default n - depends on CRYPTO_DEV_SPACC - help - Say y to enable Spacc secure modes stats. diff --git a/drivers/crypto/dwc-spacc/Makefile b/drivers/crypto/dwc-spacc/Makefile deleted file mode 100644 index bf46c8e13a31..000000000000 --- a/drivers/crypto/dwc-spacc/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_CRYPTO_DEV_SPACC) += snps-spacc.o -snps-spacc-objs = spacc_hal.o spacc_core.o \ -spacc_manager.o spacc_interrupt.o spacc_device.o - -ifeq ($(CONFIG_CRYPTO_DEV_SPACC_HASH),y) -snps-spacc-objs += spacc_ahash.o -endif - -ifeq ($(CONFIG_CRYPTO_DEV_SPACC_CIPHER),y) -snps-spacc-objs += spacc_skcipher.o -endif - -ifeq ($(CONFIG_CRYPTO_DEV_SPACC_AEAD),y) -snps-spacc-objs += spacc_aead.o -endif diff --git a/drivers/crypto/dwc-spacc/spacc_aead.c b/drivers/crypto/dwc-spacc/spacc_aead.c deleted file mode 100755 index 7f6c48881eab..000000000000 --- a/drivers/crypto/dwc-spacc/spacc_aead.c +++ /dev/null @@ -1,1243 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -#include <crypto/aes.h> -#include <crypto/sm4.h> -#include <crypto/gcm.h> -#include <crypto/aead.h> -#include <crypto/authenc.h> -#include <crypto/scatterwalk.h> -#include <crypto/internal/aead.h> -#include <linux/platform_device.h> - -#include "spacc_device.h" -#include "spacc_core.h" - -static LIST_HEAD(spacc_aead_alg_list); -static DEFINE_MUTEX(spacc_aead_alg_mutex); - -#define SPACC_B0_SIZE 16 -#define SET_IV_IN_SRCBUF 0x80000000 -#define SET_IV_IN_CONTEXT 0x0 -#define AAD_BUF_SIZE 4096 -#define ADATA_BUF_SIZE (AAD_BUF_SIZE + SPACC_B0_SIZE +\ - SPACC_MAX_IV_SIZE) - -struct spacc_iv_buf { - unsigned char iv[SPACC_MAX_IV_SIZE]; - unsigned char spacc_adata[ADATA_BUF_SIZE]; - struct scatterlist sg[2], spacc_adata_sg[2]; - struct scatterlist *spacc_ptextsg, temp_aad[2]; -}; - -static struct kmem_cache *spacc_iv_pool; - -static struct mode_tab possible_aeads[] = { - { MODE_TAB_AEAD("rfc7539(chacha20,poly1305)", - CRYPTO_MODE_CHACHA20_POLY1305, CRYPTO_MODE_NULL, - 16, 12, 1), .keylen = { 16, 24, 32 } - }, - { MODE_TAB_AEAD("gcm(aes)", - CRYPTO_MODE_AES_GCM, CRYPTO_MODE_NULL, - 16, 12, 1), .keylen = { 16, 24, 32 } - }, - { MODE_TAB_AEAD("gcm(sm4)", - CRYPTO_MODE_SM4_GCM, CRYPTO_MODE_NULL, - 16, 12, 1), .keylen = { 16 } - }, - { MODE_TAB_AEAD("ccm(aes)", - CRYPTO_MODE_AES_CCM, CRYPTO_MODE_NULL, - 16, 16, 1), .keylen = { 16, 24, 32 } - }, - { MODE_TAB_AEAD("ccm(sm4)", - CRYPTO_MODE_SM4_CCM, CRYPTO_MODE_NULL, - 16, 16, 1), .keylen = { 16, 24, 32 } - }, -}; - -static void spacc_init_aead_alg(struct crypto_alg *calg, - const struct mode_tab *mode) -{ - strscpy(calg->cra_name, mode->name, sizeof(mode->name) - 1); - calg->cra_name[sizeof(mode->name) - 1] = '\0'; - - strscpy(calg->cra_driver_name, "spacc-"); - strcat(calg->cra_driver_name, mode->name); - calg->cra_driver_name[sizeof(calg->cra_driver_name) - 1] = '\0'; - - calg->cra_blocksize = mode->blocklen; -} - -static int ccm_16byte_aligned_len(int in_len) -{ - int len; - int computed_mod; - - if (in_len > 0) { - computed_mod = in_len % 16; - if (computed_mod) - len = in_len - computed_mod + 16; - else - len = in_len; - } else { - len = in_len; - } - - return len; -} - -/* taken from crypto/ccm.c */ -static int spacc_aead_format_adata(u8 *adata, unsigned int a) -{ - int len = 0; - - /* add control info for associated data - * RFC 3610 and NIST Special Publication 800-38C - */ - if (a < 65280) { - *(__be16 *)adata = cpu_to_be16(a); - len = 2; - } else { - *(__be16 *)adata = cpu_to_be16(0xfffe); - *(__be32 *)&adata[2] = cpu_to_be32(a); - len = 6; - } - - return len; -} - - -/* taken from crypto/ccm.c */ -static int spacc_aead_set_msg_len(u8 *block, unsigned int msglen, int csize) -{ - __be32 data; - - memset(block, 0, csize); - block += csize; - - if (csize >= 4) - csize = 4; - else if (msglen > (unsigned int)(1 << (8 * csize))) - return -EOVERFLOW; - - data = cpu_to_be32(msglen); - memcpy(block - csize, (u8 *)&data + 4 - csize, csize); - - return 0; -} - -static int spacc_aead_init_dma(struct device *dev, struct aead_request *req, - u64 seq, uint32_t icvlen, int encrypt, int *alen) -{ - struct crypto_aead *reqtfm = crypto_aead_reqtfm(req); - struct spacc_crypto_ctx *tctx = crypto_aead_ctx(reqtfm); - struct spacc_crypto_reqctx *ctx = aead_request_ctx(req); - - gfp_t mflags = GFP_ATOMIC; - struct spacc_iv_buf *iv; - int ccm_aad_16b_len = 0; - int rc, B0len; - int payload_len, spacc_adata_sg_buf_len; - unsigned int ivsize = crypto_aead_ivsize(reqtfm); - - /* always have 1 byte of IV */ - if (!ivsize) - ivsize = 1; - - if (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) - mflags = GFP_KERNEL; - - ctx->iv_buf = kmem_cache_alloc(spacc_iv_pool, mflags); - if (!ctx->iv_buf) - return -ENOMEM; - iv = ctx->iv_buf; - - sg_init_table(iv->sg, ARRAY_SIZE(iv->sg)); - sg_init_table(iv->spacc_adata_sg, ARRAY_SIZE(iv->spacc_adata_sg)); - - B0len = 0; - ctx->aead_nents = 0; - - memset(iv->iv, 0, SPACC_MAX_IV_SIZE); - memset(iv->spacc_adata, 0, ADATA_BUF_SIZE); - - /* copy the IV out for AAD */ - memcpy(iv->iv, req->iv, ivsize); - memset(iv->spacc_adata, 0, 144); - - /* now we need to figure out the cipher IV which may or - * may not be "req->iv" depending on the mode we are in - */ - if (tctx->mode & SPACC_MANGLE_IV_FLAG) { - switch (tctx->mode & 0x7F00) { - case SPACC_MANGLE_IV_RFC3686: - case SPACC_MANGLE_IV_RFC4106: - case SPACC_MANGLE_IV_RFC4543: - { - unsigned char *p = iv->spacc_adata; - /* we're in RFC3686 mode so the last - * 4 bytes of the key are the SALT - */ - memcpy(p, tctx->csalt, 4); - memcpy(p + 4, req->iv, ivsize); - - p[12] = 0; - p[13] = 0; - p[14] = 0; - p[15] = 1; - } - break; - case SPACC_MANGLE_IV_RFC4309: - { - unsigned char *p = iv->spacc_adata; - int L, M; - u32 lm = req->cryptlen; - - /* CCM mode */ - /* p[0..15] is the CTR IV */ - /* p[16..31] is the CBC-MAC B0 block*/ - B0len = SPACC_B0_SIZE; - /* IPsec requires L=4*/ - L = 4; - M = tctx->auth_size; - - /* CTR block */ - p[0] = L - 1; - memcpy(p + 1, tctx->csalt, 3); - memcpy(p + 4, req->iv, ivsize); - p[12] = 0; - p[13] = 0; - p[14] = 0; - p[15] = 1; - - /* store B0 block at p[16..31] */ - p[16] = (1 << 6) | (((M - 2) >> 1) << 3) - | (L - 1); - memcpy(p + 1 + 16, tctx->csalt, 3); - memcpy(p + 4 + 16, req->iv, ivsize); - - /* now store length */ - p[16 + 12 + 0] = (lm >> 24) & 0xFF; - p[16 + 12 + 1] = (lm >> 16) & 0xFF; - p[16 + 12 + 2] = (lm >> 8) & 0xFF; - p[16 + 12 + 3] = (lm) & 0xFF; - - /*now store the pre-formatted AAD */ - p[32] = (req->assoclen >> 8) & 0xFF; - p[33] = (req->assoclen) & 0xFF; - /* we added 2 byte header to the AAD */ - B0len += 2; - } - break; - } - } else if (tctx->mode == CRYPTO_MODE_AES_CCM || - tctx->mode == CRYPTO_MODE_SM4_CCM) { - unsigned char *p = iv->spacc_adata; - u8 *orig_iv = req->iv; - int L, M; - - u32 lm = (encrypt) ? - req->cryptlen : - req->cryptlen - tctx->auth_size; - - memset(iv->spacc_adata, 0, 144); - iv->spacc_ptextsg = req->src; - /* CCM mode */ - /* p[0..15] is the CTR IV */ - /* p[16..31] is the CBC-MAC B0 block*/ - B0len = SPACC_B0_SIZE; - - /* IPsec requires L=4 */ - L = req->iv[0] + 1; - M = tctx->auth_size; - - /* Note: rfc 3610 and NIST 800-38C require counter of - * zero to encrypt auth tag. - */ - memset(orig_iv + 15 - orig_iv[0], 0, orig_iv[0] + 1); - - /* CTR block */ - memcpy(p, req->iv, ivsize); - memcpy(p + 16, req->iv, ivsize); - - /* Taken from ccm.c - * Note: rfc 3610 and NIST 800-38C require counter of - * zero to encrypt auth tag. - */ - - /* Store B0 block at p[16..31] */ - p[16] |= (8 * ((M - 2) / 2)); - - /* set adata if assoclen > 0 */ - if (req->assoclen) - p[16] |= 64; - - /* now store length, this is L size starts from 16-L - * to 16 of B0 - */ - spacc_aead_set_msg_len(p + 16 + 16 - L, lm, L); - - if (req->assoclen) { - - /* store pre-formatted AAD: - * AAD_LEN + AAD + PAD - */ - *alen = spacc_aead_format_adata(&p[32], req->assoclen); - - ccm_aad_16b_len = - ccm_16byte_aligned_len(req->assoclen + *alen); - - /* Adding the rest of AAD from req->src */ - scatterwalk_map_and_copy(p + 32 + *alen, - req->src, 0, - req->assoclen, 0); - - /* Copy AAD to req->dst */ - scatterwalk_map_and_copy(p + 32 + *alen, req->dst, - 0, req->assoclen, 1); - - iv->spacc_ptextsg = scatterwalk_ffwd(iv->temp_aad, - req->src, req->assoclen); - } - /* default is to copy the iv over since the - * cipher and protocol IV are the same - */ - memcpy(iv->spacc_adata, req->iv, ivsize); - } - - /* this is part of the AAD */ - sg_set_buf(iv->sg, iv->iv, ivsize); - - /* GCM and CCM don't include the IV in the AAD */ - switch (tctx->mode) { - case CRYPTO_MODE_AES_GCM_RFC4106: - case CRYPTO_MODE_AES_GCM: - case CRYPTO_MODE_SM4_GCM_RFC8998: - case CRYPTO_MODE_CHACHA20_POLY1305: - case CRYPTO_MODE_NULL: - - payload_len = req->cryptlen + icvlen + req->assoclen; - spacc_adata_sg_buf_len = SPACC_MAX_IV_SIZE + B0len; - - /* this is the actual IV getting fed to the core - * (via IV IMPORT) - */ - - sg_set_buf(iv->spacc_adata_sg, iv->spacc_adata, - spacc_adata_sg_buf_len); - - sg_chain(iv->spacc_adata_sg, - sg_nents_for_len(iv->spacc_adata_sg, - spacc_adata_sg_buf_len) + 1, req->src); - - rc = spacc_sg_to_ddt(dev, iv->spacc_adata_sg, - spacc_adata_sg_buf_len + payload_len, - &ctx->src, DMA_TO_DEVICE); - - if (rc < 0) - goto err_free_iv; - ctx->aead_nents = rc; - break; - case CRYPTO_MODE_AES_CCM: - case CRYPTO_MODE_AES_CCM_RFC4309: - case CRYPTO_MODE_SM4_CCM: - - - if (encrypt) - payload_len = - ccm_16byte_aligned_len(req->cryptlen + icvlen); - else - payload_len = - ccm_16byte_aligned_len(req->cryptlen); - - spacc_adata_sg_buf_len = SPACC_MAX_IV_SIZE + B0len + - ccm_aad_16b_len; - - /* this is the actual IV getting fed to the core (via IV IMPORT) - * This has CTR IV + B0 + AAD(B1, B2, ...) - */ - sg_set_buf(iv->spacc_adata_sg, iv->spacc_adata, - spacc_adata_sg_buf_len); - sg_chain(iv->spacc_adata_sg, - sg_nents_for_len(iv->spacc_adata_sg, - spacc_adata_sg_buf_len) + 1, - iv->spacc_ptextsg); - - rc = spacc_sg_to_ddt(dev, iv->spacc_adata_sg, - spacc_adata_sg_buf_len + payload_len, - &ctx->src, DMA_TO_DEVICE); - if (rc < 0) - goto err_free_iv; - ctx->aead_nents = rc; - break; - default: - - /* this is the actual IV getting fed to the core (via IV IMPORT) - * This has CTR IV + B0 + AAD(B1, B2, ...) - */ - payload_len = req->cryptlen + icvlen + req->assoclen; - spacc_adata_sg_buf_len = SPACC_MAX_IV_SIZE + B0len; - sg_set_buf(iv->spacc_adata_sg, iv->spacc_adata, - spacc_adata_sg_buf_len); - - sg_chain(iv->spacc_adata_sg, - sg_nents_for_len(iv->spacc_adata_sg, - spacc_adata_sg_buf_len) + 1, - req->src); - - rc = spacc_sg_to_ddt(dev, iv->spacc_adata_sg, - spacc_adata_sg_buf_len + payload_len, - &ctx->src, DMA_TO_DEVICE); - - if (rc < 0) - goto err_free_iv; - ctx->aead_nents = rc; - } - - /* Putting in req->dst is good since it won't overwrite anything - * even in case of CCM this is fine condition - */ - if (req->dst != req->src) { - switch (tctx->mode) { - case CRYPTO_MODE_AES_CCM: - case CRYPTO_MODE_AES_CCM_RFC4309: - case CRYPTO_MODE_SM4_CCM: - /* If req->dst buffer len is not-positive, - * then skip setting up of DMA - */ - if (req->dst->length <= 0) { - ctx->dst_nents = 0; - return 0; - } - - if (encrypt) - payload_len = req->cryptlen + icvlen + - req->assoclen; - else - payload_len = req->cryptlen - tctx->auth_size + - req->assoclen; - - /* For corner cases where PTlen=AADlen=0, we set default - * to 16 - */ - rc = spacc_sg_to_ddt(dev, req->dst, - payload_len > 0 ? payload_len : 16, - &ctx->dst, DMA_FROM_DEVICE); - if (rc < 0) - goto err_free_src; - ctx->dst_nents = rc; - break; - default: - - /* If req->dst buffer len is not-positive, - * then skip setting up of DMA - */ - if (req->dst->length <= 0) { - ctx->dst_nents = 0; - return 0; - } - - if (encrypt) - payload_len = SPACC_MAX_IV_SIZE + req->cryptlen - + icvlen + req->assoclen; - else { - payload_len = req->cryptlen - tctx->auth_size + - req->assoclen; - if (payload_len <= 0) - return -EBADMSG; - } - - - rc = spacc_sg_to_ddt(dev, req->dst, - payload_len > 0 ? payload_len : 16, - &ctx->dst, DMA_FROM_DEVICE); - if (rc < 0) - goto err_free_src; - ctx->dst_nents = rc; - } - } - - return 0; - -err_free_src: - if (ctx->aead_nents) { - dma_unmap_sg(dev, iv->spacc_adata_sg, ctx->aead_nents, - DMA_TO_DEVICE); - - pdu_ddt_free(&ctx->src); - } - -err_free_iv: - kmem_cache_free(spacc_iv_pool, ctx->iv_buf); - - return rc; -} - -static void spacc_aead_cleanup_dma(struct device *dev, struct aead_request *req) -{ - struct spacc_crypto_reqctx *ctx = aead_request_ctx(req); - struct spacc_iv_buf *iv = ctx->iv_buf; - - if (req->src != req->dst && ctx->dst_nents > 0) { - dma_unmap_sg(dev, req->dst, ctx->dst_nents, - DMA_FROM_DEVICE); - pdu_ddt_free(&ctx->dst); - } - - if (ctx->aead_nents) { - dma_unmap_sg(dev, iv->spacc_adata_sg, ctx->aead_nents, - DMA_TO_DEVICE); - - pdu_ddt_free(&ctx->src); - } - - kmem_cache_free(spacc_iv_pool, ctx->iv_buf); -} - -static bool spacc_check_keylen(const struct spacc_alg *salg, - unsigned int keylen) -{ - unsigned int i, mask = salg->keylen_mask; - - if (mask > (1ul << ARRAY_SIZE(salg->mode->keylen)) - 1) - return false; - - for (i = 0; mask; i++, mask >>= 1) { - if (mask & 1 && salg->mode->keylen[i] == keylen) - return true; - } - - return false; -} - -static void spacc_aead_cb(void *spacc, void *tfm) -{ - struct aead_cb_data *cb = tfm; - int err = -1; - u32 status_reg = readl(cb->spacc->regmap + SPACC_REG_STATUS); - u32 status_ret = (status_reg >> 24) & 0x3; - - dma_sync_sg_for_cpu(cb->tctx->dev, cb->req->dst, - cb->ctx->dst_nents, DMA_FROM_DEVICE); - - /* ICV mismatch send bad msg */ - if (status_ret == 0x1) { - err = -EBADMSG; - goto REQ_DST_CP_SKIP; - } - err = cb->spacc->job[cb->new_handle].job_err; - -REQ_DST_CP_SKIP: - spacc_aead_cleanup_dma(cb->tctx->dev, cb->req); - spacc_close(cb->spacc, cb->new_handle); - - /* call complete */ - aead_request_complete(cb->req, err); -} - -static int spacc_aead_setkey(struct crypto_aead *tfm, const u8 *key, - unsigned int keylen) -{ - struct spacc_crypto_ctx *ctx = crypto_aead_ctx(tfm); - const struct spacc_alg *salg = spacc_tfm_aead(&tfm->base); - struct crypto_authenc_keys authenc_keys; - struct spacc_priv *priv; - unsigned int authkeylen, enckeylen; - const unsigned char *authkey, *enckey; - unsigned char xcbc[64]; - int singlekey = 0; - int err; - - /* are keylens valid? */ - ctx->ctx_valid = false; - - switch (ctx->mode & 0xFF) { - case CRYPTO_MODE_SM4_GCM: - case CRYPTO_MODE_SM4_CCM: - case CRYPTO_MODE_NULL: - case CRYPTO_MODE_AES_GCM: - case CRYPTO_MODE_AES_CCM: - case CRYPTO_MODE_CHACHA20_POLY1305: - authkey = key; - authkeylen = 0; - enckey = key; - enckeylen = keylen; - ctx->keylen = keylen; - singlekey = 1; - goto skipover; - } - - err = crypto_authenc_extractkeys(&authenc_keys, key, keylen); - if (err) - return err; - - authkeylen = authenc_keys.authkeylen; - authkey = authenc_keys.authkey; - enckeylen = authenc_keys.enckeylen; - enckey = authenc_keys.enckey; - -skipover: - /* detect RFC3686/4106 and trim from enckeylen(and copy salt..) */ - if (ctx->mode & SPACC_MANGLE_IV_FLAG) { - switch (ctx->mode & 0x7F00) { - case SPACC_MANGLE_IV_RFC3686: - case SPACC_MANGLE_IV_RFC4106: - case SPACC_MANGLE_IV_RFC4543: - memcpy(ctx->csalt, enckey + enckeylen - 4, 4); - enckeylen -= 4; - break; - case SPACC_MANGLE_IV_RFC4309: - memcpy(ctx->csalt, enckey + enckeylen - 3, 3); - enckeylen -= 3; - break; - } - } - - if (!singlekey) { - if (authkeylen > salg->mode->hashlen) { - dev_warn(ctx->dev, "Auth key size of %u is not valid\n", - authkeylen); - return -EINVAL; - } - } - - if (!spacc_check_keylen(salg, enckeylen)) { - dev_warn(ctx->dev, "Enc key size of %u is not valid\n", - enckeylen); - return -EINVAL; - } - - /* if we're already open close the handle since - * the size may have changed - */ - if (ctx->handle != -1) { - priv = dev_get_drvdata(ctx->dev); - spacc_close(&priv->spacc, ctx->handle); - put_device(ctx->dev); - ctx->handle = -1; - } - - /* Open a handle and - * search all devices for an open handle - */ - priv = NULL; - priv = dev_get_drvdata(salg->dev[0]); - - /* increase reference */ - ctx->dev = get_device(salg->dev[0]); - - /* check if its a valid mode ... */ - if (spacc_isenabled(&priv->spacc, salg->mode->aead.ciph & 0xFF, - enckeylen) && - spacc_isenabled(&priv->spacc, - salg->mode->aead.hash & 0xFF, authkeylen)) { - /* try to open spacc handle */ - ctx->handle = spacc_open(&priv->spacc, - salg->mode->aead.ciph & 0xFF, - salg->mode->aead.hash & 0xFF, - -1, 0, spacc_aead_cb, tfm); - } - - if (ctx->handle < 0) { - put_device(salg->dev[0]); - pr_debug("Failed to open SPAcc context\n"); - return -EIO; - } - - /* setup XCBC key */ - if (salg->mode->aead.hash == CRYPTO_MODE_MAC_XCBC) { - err = spacc_compute_xcbc_key(&priv->spacc, - salg->mode->aead.hash, - ctx->handle, authkey, - authkeylen, xcbc); - if (err < 0) { - dev_warn(ctx->dev, "Failed to compute XCBC key: %d\n", - err); - return -EIO; - } - authkey = xcbc; - authkeylen = 48; - } - - /* handle zero key/zero len DEC condition for SM4/AES GCM mode */ - ctx->zero_key = 0; - if (!key[0]) { - int i, val = 0; - - for (i = 0; i < keylen ; i++) - val += key[i]; - - if (val == 0) - ctx->zero_key = 1; - } - - err = spacc_write_context(&priv->spacc, ctx->handle, - SPACC_CRYPTO_OPERATION, enckey, - enckeylen, NULL, 0); - - if (err) { - dev_warn(ctx->dev, - "Could not write ciphering context: %d\n", err); - return -EIO; - } - - if (!singlekey) { - err = spacc_write_context(&priv->spacc, ctx->handle, - SPACC_HASH_OPERATION, authkey, - authkeylen, NULL, 0); - if (err) { - dev_warn(ctx->dev, - "Could not write hashing context: %d\n", err); - return -EIO; - } - } - - /* set expand key */ - spacc_set_key_exp(&priv->spacc, ctx->handle); - ctx->ctx_valid = true; - - memset(xcbc, 0, sizeof(xcbc)); - - /* copy key to ctx for fallback */ - memcpy(ctx->key, key, keylen); - - return 0; -} - -static int spacc_aead_setauthsize(struct crypto_aead *tfm, - unsigned int authsize) -{ - struct spacc_crypto_ctx *ctx = crypto_aead_ctx(tfm); - - ctx->auth_size = authsize; - - /* taken from crypto/ccm.c */ - switch (ctx->mode) { - case CRYPTO_MODE_SM4_GCM: - case CRYPTO_MODE_AES_GCM: - switch (authsize) { - case 4: - case 8: - case 12: - case 13: - case 14: - case 15: - case 16: - break; - default: - return -EINVAL; - } - break; - - case CRYPTO_MODE_AES_CCM: - case CRYPTO_MODE_SM4_CCM: - switch (authsize) { - case 4: - case 6: - case 8: - case 10: - case 12: - case 14: - case 16: - break; - default: - return -EINVAL; - } - break; - - case CRYPTO_MODE_CHACHA20_POLY1305: - switch (authsize) { - case 16: - break; - default: - return -EINVAL; - } - break; - } - - return 0; -} - -static int spacc_aead_fallback(struct aead_request *req, - struct spacc_crypto_ctx *ctx, int encrypt) -{ - int ret; - struct aead_request *subreq = aead_request_ctx(req); - struct crypto_aead *reqtfm = crypto_aead_reqtfm(req); - struct aead_alg *alg = crypto_aead_alg(reqtfm); - const char *aead_name = alg->base.cra_name; - - ctx->fb.aead = crypto_alloc_aead(aead_name, 0, - CRYPTO_ALG_NEED_FALLBACK | - CRYPTO_ALG_ASYNC); - if (IS_ERR(ctx->fb.aead)) { - pr_err("Spacc aead fallback tfm is NULL!\n"); - return PTR_ERR(ctx->fb.aead); - } - - subreq = aead_request_alloc(ctx->fb.aead, GFP_KERNEL); - if (!subreq) - return -ENOMEM; - - crypto_aead_setkey(ctx->fb.aead, ctx->key, ctx->keylen); - crypto_aead_setauthsize(ctx->fb.aead, ctx->auth_size); - - aead_request_set_tfm(subreq, ctx->fb.aead); - aead_request_set_callback(subreq, req->base.flags, - req->base.complete, req->base.data); - aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, - req->iv); - aead_request_set_ad(subreq, req->assoclen); - - if (encrypt) - ret = crypto_aead_encrypt(subreq); - else - ret = crypto_aead_decrypt(subreq); - - aead_request_free(subreq); - crypto_free_aead(ctx->fb.aead); - ctx->fb.aead = NULL; - - return ret; -} - -static int spacc_aead_process(struct aead_request *req, u64 seq, int encrypt) -{ - int rc; - int B0len; - int alen; - u32 dstoff; - int icvremove; - int ivaadsize; - int ptaadsize = 0; - int iv_to_context; - int spacc_proc_len; - u32 spacc_icv_offset = 0; - int spacc_pre_aad_size; - int ccm_aad_16b_len; - struct crypto_aead *reqtfm = crypto_aead_reqtfm(req); - int ivsize = crypto_aead_ivsize(reqtfm); - struct spacc_crypto_ctx *tctx = crypto_aead_ctx(reqtfm); - struct spacc_crypto_reqctx *ctx = aead_request_ctx(req); - struct spacc_priv *priv = dev_get_drvdata(tctx->dev); - - ctx->encrypt_op = encrypt; - alen = 0; - ccm_aad_16b_len = 0; - - if (tctx->handle < 0 || !tctx->ctx_valid || (req->cryptlen + - req->assoclen) > priv->max_msg_len) - return -EINVAL; - - /* IV is programmed to context by default */ - iv_to_context = SET_IV_IN_CONTEXT; - - if (encrypt) { - switch (tctx->mode & 0xFF) { - case CRYPTO_MODE_AES_GCM: - case CRYPTO_MODE_SM4_GCM: - case CRYPTO_MODE_CHACHA20_POLY1305: - /* For cryptlen = 0 */ - if (req->cryptlen + req->assoclen == 0) - return spacc_aead_fallback(req, tctx, encrypt); - break; - case CRYPTO_MODE_AES_CCM: - case CRYPTO_MODE_SM4_CCM: - - if (req->cryptlen + req->assoclen == 0) - return spacc_aead_fallback(req, tctx, encrypt); - - /* verify that msglen can in fact be represented - * in L bytes - */ - /* 2 <= L <= 8, so 1 <= L' <= 7. */ - if (req->iv[0] < 1 || req->iv[0] > 7) - return -EINVAL; - - break; - default: - pr_debug("Unsupported algo"); - return -EINVAL; - } - } else { - /* Handle the decryption */ - switch (tctx->mode & 0xFF) { - case CRYPTO_MODE_AES_GCM: - case CRYPTO_MODE_SM4_GCM: - case CRYPTO_MODE_CHACHA20_POLY1305: - /* For assoclen = 0 */ - if (req->assoclen == 0 && - (req->cryptlen - tctx->auth_size == 0)) - return spacc_aead_fallback(req, tctx, encrypt); - break; - case CRYPTO_MODE_AES_CCM: - case CRYPTO_MODE_SM4_CCM: - - if (req->assoclen == 0 && - (req->cryptlen - tctx->auth_size == 0)) - return spacc_aead_fallback(req, tctx, encrypt); - /* 2 <= L <= 8, so 1 |
