crypto: spacc - Add SPAcc Crypto Driver
Subsystems (2)
v27 cover crypto: spacc - Add SPAcc Crypto Driver
Add the driver for SPAcc(Security Protocol Accelerator), which is a crypto acceleration IP from Synopsys. The SPAcc supports multiple ciphers, hashes and AEAD algorithms with various modes. The driver currently supports below
hash:
- cmac(sm4)
- xcbc(sm4)
- hmac(md5)
- md5
- hmac(sha1)
- sha1
- sha224
- sha256
- sha384
- sha512
- hmac(sha224)
- hmac(sha256)
- hmac(sha384)
- hmac(sha512)
- sha3-224
- sha3-256
- sha3-384
- sha3-512
changelog:
v1->v2 changes:
- Added local_bh_disable() and local_bh_enable() for the below calls. a. for ciphers skcipher_request_complete()
b. for aead aead_request_complete()
c. for hash ahash_request_complete()
- dt-bindings updates
a. removed snps,vspacc-priority and made it into config option b. renamed snps,spacc-wdtimer to snps,spacc-internal-counter c. Added description to all properties
- Updated corresponding dt-binding changes to code
v2->v3 changes:
- cra_init and cra_exit replaced with init_tfm and exit_tfm for hashes.
- removed mutex_lock/unlock for spacc_skcipher_fallback call
- dt-bindings updates
a. updated SOC related information
b. renamed compatible string as per SOC
- Updated corresponding dt-binding changes to code
v3->v4 changes:
- removed snps,vspacc-id from the dt-bindings
- removed mutex_lock from ciphers
- replaced magic numbers with macros
- removed sw_fb variable from struct mode_tab and associated code from the hashes
- polling code is replaced by wait_event_interruptible
v4->v5 changes:
- Updated to register with the crypto-engine
- Used semaphore to manage SPAcc device hardware context pool
- This patchset supports Hashes only
- Dropping the support for Ciphers and AEADs in this patchset
- Added Reviewed-by tag on the Device tree patch since it was reviewed on v4 patch by Krzysztof Kozlowski and Rob Herring (Arm)
v5->v6 changes:
- Removed CRYPTO_DEV_SPACC_CIPHER and CRYPTO_DEV_SPACC_AEAD Kconfig options, since the cipher and aead support is not part of this patchset
- Dropped spacc_skcipher.o and spacc_aead.o from Makefile to fix build errors reported by kernel test robot
- Added Reported-by and Closes tags as suggested
v6->v7 changes:
- Fixed build error reported by Kernel test robot
- Added Reported-by and Closes tags as suggested
v7->v8 changes:
- Fixed misleading comment: Clarified that only HMAC key pre-processing is done in software, while the actual HMAC operation is performed by hardware
- Simplified do_shash() function signature by removing unused parameters
- Updated all do_shash() call sites to use new simplified signature
- Fixed commit message formatting by adding "crypto: spacc - <subject>" to all patches
- used __free() for scope based resource management
v8->v9 changes:
- Updated the software fallback implementation to use HASH_FBREQ_ON_STACK
- Corrected dynamic allocation of statesize and reqsize in init_tfm
- Fixed synchronization issues in the digest request
v9->v10 changes:
- Fixed unused variable warning
v10->v11 changes:
- Removed the redundant crypto_alloc_ahash in the init_tfm function
- Removed the redundant crypto_free_ahash in exit_tfm function
- Removed the redundant crypto_ahash_setkey call in setkey function
v11->v12 changes:
- Removed do_shash() and switched to lib/crypto API in spacc_hash_setkey
- Dropped support for SM3 algorithm
- Improved multi-device safety by encapsulating handling within priv
- Added memzero_explicit() in sensitive paths
- Minor code cleanups and style fixes
- Algorithm registration cleanups
v12->v13 changes:
- Removed all the sleep function from setkey function
- Added shash implemntation for aes algorthims
v13->v14 changes:
-Added fixes based on the reports by Sashiko
-Removed the spacc_is_mode_keysize_supported call from do_one_request
v14->v15 changes:
-Added fixes based on the reports by Sashiko on 19/jun/2026 -Fixed styling in the Kconfig
v15->v16 changes:
-Added fixes based on the reports by Sashiko
v16->v17 changes:
-Added fixes based on the reports by Sashiko
v17->v18 changes:
-Added fixes based on the reports by Sashiko
v18->v19 changes:
-Added fixes based on the reports by Sashiko
v19->v20 changes:
-Added fixes based on the reports by Sashiko
v20->v21 changes:
-Added fixes based on the reports by Sashiko
v21->v22 changes:
-Added fixes based on the reports by Sashiko
v22->v23 changes:
-Added fixes based on the reports by Sashiko
v23->v24 changes:
-Added fixes based on the reports by Sashiko
v24->v25 changes:
-Added fixes based on the reports by Sashiko
v25->v26 changes:
-Added fixes based on the reports by Sashiko -Removed the additional fallback
-Added the CRYPTO_AHASH_ALG_BLOCK_ONLY flag to the cra_flags -Minor code cleanups and style fixes
v26->v27 changes:
-Added fixes based on the reports by Sashiko
Pavitrakumar Managutte (4):
dt-bindings: crypto: Document support for SPAcc
crypto: spacc - Add SPAcc ahash support
crypto: spacc - add spacc autodetect support
crypto: spacc - Add SPAcc Kconfig and Makefile
.../bindings/crypto/snps,dwc-spacc.yaml | 50 + drivers/crypto/Kconfig | 1 + drivers/crypto/Makefile | 1 + drivers/crypto/dwc-spacc/Kconfig | 64 + drivers/crypto/dwc-spacc/Makefile | 7 + drivers/crypto/dwc-spacc/spacc_ahash.c | 857 ++++++ drivers/crypto/dwc-spacc/spacc_core.c | 2529 +++++++++++++++++ drivers/crypto/dwc-spacc/spacc_core.h | 863 ++++++ drivers/crypto/dwc-spacc/spacc_device.c | 324 +++ drivers/crypto/dwc-spacc/spacc_device.h | 181 ++ drivers/crypto/dwc-spacc/spacc_hal.c | 349 +++ drivers/crypto/dwc-spacc/spacc_hal.h | 113 + drivers/crypto/dwc-spacc/spacc_interrupt.c | 360 +++ drivers/crypto/dwc-spacc/spacc_manager.c | 657 +++++ 14 files changed, 6356 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/snps,dwc-spacc.yaml create mode 100644 drivers/crypto/dwc-spacc/Kconfig create mode 100644 drivers/crypto/dwc-spacc/Makefile create mode 100644 drivers/crypto/dwc-spacc/spacc_ahash.c create mode 100644 drivers/crypto/dwc-spacc/spacc_core.c create mode 100644 drivers/crypto/dwc-spacc/spacc_core.h create mode 100644 drivers/crypto/dwc-spacc/spacc_device.c create mode 100644 drivers/crypto/dwc-spacc/spacc_device.h create mode 100644 drivers/crypto/dwc-spacc/spacc_hal.c create mode 100644 drivers/crypto/dwc-spacc/spacc_hal.h create mode 100644 drivers/crypto/dwc-spacc/spacc_interrupt.c create mode 100644 drivers/crypto/dwc-spacc/spacc_manager.c
base-commit: 178aff4cf425b3fc51ff09c571fa1bfbc1eb8ea4 --
2.25.1
PATCH v27 1/4 dt-bindings: crypto: Document support for SPAcc
Add DT bindings related to the SPAcc driver for Documentation. DWC Synopsys Security Protocol Accelerator(SPAcc) Hardware Crypto Engine is a crypto IP designed by Synopsys.
--- .../bindings/crypto/snps,dwc-spacc.yaml | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/snps,dwc-spacc.yaml
Documentation/devicetree/bindings/crypto/snps,dwc-spacc.yaml new file +50 -0
@@ -0,0 +1,50 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/crypto/snps,dwc-spacc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synopsys DesignWare Security Protocol Accelerator (SPAcc) Crypto Engine + +maintainers: + - Ross Bannerman <[email protected]> + +description: | + The Synopsys DWC Security Protocol Accelerator (SPAcc) is a + semiconductor IP designed to accelerate cryptographic operations, + such as encryption, decryption, and hashing. + + In this configuration, the SPAcc IP is instantiated within the Synopsys + NSIMOSCI virtual SoC platform, a SystemC simulation environment used for + software development and testing. The device is accessed as a memory-mapped + peripheral and generates interrupts to the ARC interrupt controller. + +properties: + compatible: + items: + - const: snps,nsimosci-hs-spacc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + crypto@40000000 { + compatible = "snps,nsimosci-hs-spacc"; + reg = <0x40000000 0x40000>; + interrupts = <28>; + clocks = <&clock>; + };
--
2.25.1
PATCH v27 2/4 crypto: spacc - Add SPAcc ahash support
In reply to Pavitrakumar ManagutteAdd ahash support to SPAcc driver.
Below are the hash algos supported:
- cmac(sm4)
- xcbc(sm4)
- hmac(md5)
- md5
- hmac(sha1)
- sha1
- sha224
- sha256
- sha384
- sha512
- hmac(sha224)
- hmac(sha256)
- hmac(sha384)
- hmac(sha512)
- sha3-224
- sha3-256
- sha3-384
- sha3-512
--- drivers/crypto/dwc-spacc/spacc_ahash.c | 857 +++++++++++++ drivers/crypto/dwc-spacc/spacc_core.c | 1337 ++++++++++++++++++++ drivers/crypto/dwc-spacc/spacc_core.h | 863 +++++++++++++ drivers/crypto/dwc-spacc/spacc_device.c | 324 +++++ drivers/crypto/dwc-spacc/spacc_device.h | 181 +++ drivers/crypto/dwc-spacc/spacc_hal.c | 349 +++++ drivers/crypto/dwc-spacc/spacc_hal.h | 113 ++ drivers/crypto/dwc-spacc/spacc_interrupt.c | 360 ++++++ drivers/crypto/dwc-spacc/spacc_manager.c | 657 ++++++++++ 9 files changed, 5041 insertions(+) create mode 100644 drivers/crypto/dwc-spacc/spacc_ahash.c create mode 100644 drivers/crypto/dwc-spacc/spacc_core.c create mode 100644 drivers/crypto/dwc-spacc/spacc_core.h create mode 100644 drivers/crypto/dwc-spacc/spacc_device.c create mode 100644 drivers/crypto/dwc-spacc/spacc_device.h create mode 100644 drivers/crypto/dwc-spacc/spacc_hal.c create mode 100644 drivers/crypto/dwc-spacc/spacc_hal.h create mode 100644 drivers/crypto/dwc-spacc/spacc_interrupt.c create mode 100644 drivers/crypto/dwc-spacc/spacc_manager.c
drivers/crypto/dwc-spacc/spacc_ahash.c new file +857 -0
@@ -0,0 +1,857 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/dmapool.h> +#include <crypto/sha1.h> +#include <crypto/sm4.h> +#include <crypto/sha2.h> +#include <crypto/sha3.h> +#include <crypto/md5.h> +#include <linux/dma-mapping.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <linux/scatterlist.h> +#include <crypto/scatterwalk.h> +#include <crypto/internal/hash.h> +#include <crypto/engine.h> +#include <linux/delay.h> +#include <linux/atomic.h> + +#include "spacc_device.h" +#include "spacc_core.h" + +#define PPP_BUF_SIZE 128 + +static struct mode_tab possible_hashes[] = { + {MODE_TAB_HASH ("cmac(sm4)" ,MAC_SM4_CMAC ,16 ,16 ) }, + { .keylen[0 ] =32 |MODE_TAB_HASH_XCBC ,MODE_TAB_HASH ("xcbc(sm4)" , +MAC_SM4_XCBC ,16 ,16 ) }, + + {MODE_TAB_HASH ("hmac(md5)" ,HMAC_MD5 ,MD5_DIGEST_SIZE , +MD5_HMAC_BLOCK_SIZE ) }, + {MODE_TAB_HASH ("md5" ,HASH_MD5 ,MD5_DIGEST_SIZE , +MD5_HMAC_BLOCK_SIZE ) }, + + {MODE_TAB_HASH ("hmac(sha1)" ,HMAC_SHA1 ,SHA1_DIGEST_SIZE , +SHA1_BLOCK_SIZE ) }, + {MODE_TAB_HASH ("sha1" ,HASH_SHA1 ,SHA1_DIGEST_SIZE , +SHA1_BLOCK_SIZE ) }, + + {MODE_TAB_HASH ("sha224" ,HASH_SHA224 ,SHA224_DIGEST_SIZE , +SHA224_BLOCK_SIZE ) }, + {MODE_TAB_HASH ("sha256" ,HASH_SHA256 ,SHA256_DIGEST_SIZE , +SHA256_BLOCK_SIZE ) }, + {MODE_TAB_HASH ("sha384" ,HASH_SHA384 ,SHA384_DIGEST_SIZE , +SHA384_BLOCK_SIZE ) }, + {MODE_TAB_HASH ("sha512" ,HASH_SHA512 ,SHA512_DIGEST_SIZE , +SHA512_BLOCK_SIZE ) }, + + {MODE_TAB_HASH ("hmac(sha512)" ,HMAC_SHA512 ,SHA512_DIGEST_SIZE , +SHA512_BLOCK_SIZE ) }, + {MODE_TAB_HASH ("hmac(sha224)" ,HMAC_SHA224 ,SHA224_DIGEST_SIZE , +SHA224_BLOCK_SIZE ) }, + {MODE_TAB_HASH ("hmac(sha256)" ,HMAC_SHA256 ,SHA256_DIGEST_SIZE , +SHA256_BLOCK_SIZE ) }, + {MODE_TAB_HASH ("hmac(sha384)" ,HMAC_SHA384 ,SHA384_DIGEST_SIZE , +SHA384_BLOCK_SIZE ) }, + + {MODE_TAB_HASH ("sha3-224" ,HASH_SHA3_224 ,SHA3_224_DIGEST_SIZE , +SHA3_224_BLOCK_SIZE ) }, + {MODE_TAB_HASH ("sha3-256" ,HASH_SHA3_256 ,SHA3_256_DIGEST_SIZE , +SHA3_256_BLOCK_SIZE ) }, + {MODE_TAB_HASH ("sha3-384" ,HASH_SHA3_384 ,SHA3_384_DIGEST_SIZE , +SHA3_384_BLOCK_SIZE ) }, + {MODE_TAB_HASH ("sha3-512" ,HASH_SHA3_512 ,SHA3_512_DIGEST_SIZE , +SHA3_512_BLOCK_SIZE ) }, +}; + +static void spacc_hash_cleanup_dma_dst (struct ahash_request *req) +{ +struct spacc_crypto_reqctx *ctx =ahash_request_ctx (req); + +pdu_ddt_free (&ctx->dst); +} + +static void spacc_hash_cleanup_dma_src (struct spacc_crypto_ctx *tctx, +struct ahash_request *req) +{ +struct spacc_crypto_reqctx *ctx =ahash_request_ctx (req); + +if (tctx->tmp_sgl && tctx->tmp_sgl[0 ].length !=0 ) { +dma_unmap_sg (tctx->dev, tctx->tmp_sgl, ctx->src_nents, +DMA_TO_DEVICE ); + tctx->tmp_sgl[0 ].length =0 ; + }else { +dma_unmap_sg (tctx->dev, req->src, ctx->src_nents, +DMA_TO_DEVICE ); + } + +pdu_ddt_free (&ctx->src); +} + +static int spacc_init_calg (struct crypto_alg *calg, +const struct mode_tab *mode) +{ +if (strscpy (calg->cra_name, mode->name) <0 ) +return -ENAMETOOLONG ; + +if (snprintf (calg->cra_driver_name,CRYPTO_MAX_ALG_NAME , +"spacc-%s" , mode->name) >=CRYPTO_MAX_ALG_NAME ) +return -ENAMETOOLONG ; + + calg->cra_blocksize = mode->blocklen; + +return 0 ; +} + +static int spacc_ctx_clone_handle (struct ahash_request *req) +{ +struct crypto_ahash *tfm =crypto_ahash_reqtfm (req); +struct spacc_crypto_ctx *tctx =crypto_ahash_ctx (tfm); +struct spacc_crypto_reqctx *ctx =ahash_request_ctx (req); +struct spacc_priv *priv =dev_get_drvdata (tctx->dev); + +if (tctx->handle <0 ) +return -EINVAL ; + +if (!priv) +return -ENODEV ; + + ctx->acb.new_handle =spacc_clone_handle (&priv->spacc, tctx->handle, + &ctx->acb); + +if (ctx->acb.new_handle <0 ) +return -ENOMEM ; + + ctx->acb.tctx = tctx; + ctx->acb.ctx = ctx; + ctx->acb.req = req; + ctx->acb.spacc = &priv->spacc; + +return 0 ; +} + +static int spacc_hash_init_dma (struct device *dev,struct ahash_request *req) +{ +int rc =-1 ; +struct crypto_ahash *tfm =crypto_ahash_reqtfm (req); +struct spacc_crypto_ctx *tctx =crypto_ahash_ctx (tfm); +struct spacc_crypto_reqctx *ctx =ahash_request_ctx (req); +struct spacc_priv *priv =dev_get_drvdata (dev); + +/* +* do_one_request runs in a sleepable context, +* so GFP_KERNEL is always safe here. +*/ +gfp_t mflags =GFP_KERNEL ; + + ctx->acb.new_handle =-1 ; + ctx->digest_buf =dma_pool_alloc (priv->hash_pool, mflags, + &ctx->digest_dma); + +if (!ctx->digest_buf) +return -ENOMEM ; + + rc =pdu_ddt_init (dev, &ctx->dst,1 |0x80000000 ); +if (rc <0 ) { +dev_err (dev,"ERR: PDU DDT init error\n" ); + rc = -EIO ; + goto err_free_digest; + } + +pdu_ddt_add (dev, &ctx->dst, ctx->digest_dma,SPACC_MAX_DIGEST_SIZE ); + +if (ctx->total_nents >0 && ctx->single_shot) { +/* single shot */ + rc =spacc_ctx_clone_handle (req); +if (rc <0 ) + goto err_free_dst; + +if (req->nbytes) { + rc =spacc_sg_to_ddt (dev, req->src, req->nbytes, + &ctx->src,DMA_TO_DEVICE ); + }else { +memset (tctx->tmp_buffer,'\0' ,PPP_BUF_SIZE ); +sg_set_buf (&tctx->tmp_sgl[0 ], tctx->tmp_buffer, +PPP_BUF_SIZE ); + rc =spacc_sg_to_ddt (dev, &tctx->tmp_sgl[0 ], + tctx->tmp_sgl[0 ].length, + &ctx->src,DMA_TO_DEVICE ); + } + }else if (ctx->total_nents ==0 && req->nbytes ==0 ) { + rc =spacc_ctx_clone_handle (req); +if (rc <0 ) + goto err_free_dst; + +/* zero length case */ +memset (tctx->tmp_buffer,'\0' ,PPP_BUF_SIZE ); +sg_set_buf (&tctx->tmp_sgl[0 ], tctx->tmp_buffer,PPP_BUF_SIZE ); + rc =spacc_sg_to_ddt (dev, &tctx->tmp_sgl[0 ], + tctx->tmp_sgl[0 ].length, + &ctx->src,DMA_TO_DEVICE ); + }else { +/* +* ctx->total_nents == 0 with req->nbytes > 0: an empty +* scatterlist can't supply the bytes the request claims to +* have. Fail explicitly instead of silently falling through +* with a stale `rc`. +*/ +dev_err (dev,"ERR: empty src sg with nbytes=%u\n" , req->nbytes); + rc = -EINVAL ; + goto err_free_dst; + } + +if (rc <0 ) + goto err_free_dst; + + ctx->src_nents = rc; +return rc; + +err_free_dst: +/* +* If the handle was already cloned (semaphore count and job slot +* taken) before this failure, release it. +*/ +if (ctx->acb.new_handle >=0 ) { +spacc_close (&priv->spacc, ctx->acb.new_handle); + ctx->acb.new_handle =-1 ; + } +pdu_ddt_free (&ctx->dst); + +err_free_digest: +dma_pool_free (priv->hash_pool, ctx->digest_buf, ctx->digest_dma); + +return rc; +} + +static void spacc_free_mems (struct spacc_crypto_reqctx *ctx, +struct spacc_crypto_ctx *tctx, +struct ahash_request *req) +{ +spacc_hash_cleanup_dma_dst (req); +spacc_hash_cleanup_dma_src (tctx, req); + +if (ctx->single_shot) { +kfree (tctx->tmp_sgl); + tctx->tmp_sgl =NULL ; + + ctx->single_shot =0 ; +if (ctx->total_nents) + ctx->total_nents =0 ; + } +} + +static void spacc_digest_cb (void *spacc,void *tfm) +{ +int err; +int dig_sz; +struct ahash_cb_data *cb = tfm; +struct spacc_device *device = spacc; + struct spacc_priv *priv = container_of(device, struct spacc_priv, + spacc); + + dig_sz =crypto_ahash_digestsize (crypto_ahash_reqtfm (cb->req)); + + err = cb->spacc->job[cb->new_handle].job_err; + +if (!err) +memcpy (cb->req->result, cb->ctx->digest_buf, dig_sz); + +dma_pool_free (priv->hash_pool, cb->ctx->digest_buf, + cb->ctx->digest_dma); + +spacc_free_mems (cb->ctx, cb->tctx, cb->req); +spacc_close (cb->spacc, cb->new_handle); + +local_bh_disable (); +crypto_finalize_hash_request (priv->engine, cb->req, err); +local_bh_enable (); + +/* +* This decrement must run exactly once for every enqueued job (it +* balances the atomic_inc in spacc_hash_do_one_request and releases +* the drain in spacc_crypto_remove). +*/ +if (atomic_dec_and_test (&priv->dma_ref_cnt)) +wake_up (&priv->drain_wq); +} + +static int spacc_hash_commit_key (struct crypto_ahash *tfm, +struct spacc_priv *priv, +const u8 *key,unsigned int keylen, +const u8 *keybuf,unsigned int klen) +{ +struct spacc_crypto_ctx *tctx =crypto_ahash_ctx (tfm); +struct crypto_ahash *fb; +int ret; + +guard (mutex)(&tctx->lock); + + fb =crypto_ahash_fb (tfm); +if (fb) { + ret =crypto_ahash_setkey (fb, key, keylen); +if (ret) +return ret; + } + +memcpy (tctx->ipad, keybuf, klen); + tctx->keylen = klen; + +/* Invalidate any cached HW context - key has changed. */ +if (tctx->handle >=0 ) { +spacc_close (&priv->spacc, tctx->handle); + tctx->handle =-1 ; + } + + tctx->ctx_valid = false; +return 0 ; +} + +static int spacc_hash_setkey (struct crypto_ahash *tfm,const u8 *key, +unsigned int keylen) +{ +unsigned int block_size; +unsigned int digest_size; +const struct spacc_alg *salg =spacc_tfm_ahash (&tfm->base); +struct spacc_crypto_ctx *tctx =crypto_ahash_ctx (tfm); +struct spacc_priv *priv =dev_get_drvdata (salg->dev); +u8 keybuf[sizeof (tctx->ipad)]; +unsigned int klen; +int ret =0 ; + +if (!priv) +return -ENODEV ; + + block_size =crypto_tfm_alg_blocksize (&tfm->base); + digest_size =crypto_ahash_digestsize (tfm); + +/* +* We are using hardware for HMAC operations. The software fallback is +* only for key pre-processing in case of HMACs. +* This was meant for hashes but it also works for cmac/xcbc. +*/ +if (keylen > block_size) { +dev_dbg (salg->dev,"Exceeds keylen: %u\n" , keylen); +dev_dbg (salg->dev,"Req. keylen hashing %s\n" , + salg->calg->cra_name); + +switch (salg->mode->id) { +case CRYPTO_MODE_HMAC_SHA224 : +sha224 (key, keylen, keybuf); +break ; + +case CRYPTO_MODE_HMAC_SHA256 : +sha256 (key, keylen, keybuf); +break ; + +case CRYPTO_MODE_HMAC_SHA384 : +sha384 (key, keylen, keybuf); +break ; + +case CRYPTO_MODE_HMAC_SHA512 : +sha512 (key, keylen, keybuf); +break ; + +case CRYPTO_MODE_HMAC_MD5 : +md5 (key, keylen, keybuf); +break ; + +case CRYPTO_MODE_HMAC_SHA1 : +sha1 (key, keylen, keybuf); +break ; +default : + ret = -EINVAL ; + goto out; + } + + klen = digest_size; +dev_dbg (salg->dev,"updated keylen: %u\n" , keylen); + }else { +/* +* CMAC/XCBC skip the hashing path above, and via AF_ALG the +* key length is fully user-controlled. tctx->ipad is a fixed +* 128-byte buffer, so reject anything that would not fit +* before copying to prevent a heap buffer overflow. +*/ +if (keylen >sizeof (keybuf)) { + ret = -EINVAL ; + goto out; + } + +/* +* Enforcing valid block-cipher key sizes supported by SPAcc: +* - AES-CMAC accepts 16/24/32, +* - SM4-CMAC/XCBC/SM4-XCBC only 16. +*/ +memcpy (keybuf, key, keylen); + klen = keylen; + +/* +* An empty HMAC key is the same as an all-zero key, because +* HMAC pads the key with zeros. Program one zero byte so a +* key is always written to the hardware context. +*/ +if (!klen) { + keybuf[0 ] =0 ; + klen =1 ; + } + } + +if (!spacc_is_mode_keysize_supported (&priv->spacc, salg->mode->id, + klen,1 )) { +dev_dbg (salg->dev,"keylen %u not supported for mode %d\n" , + klen, salg->mode->id); + ret = -EINVAL ; + goto out; + } + + ret =spacc_hash_commit_key (tfm, priv, key, keylen, keybuf, klen); + +out: +memzero_explicit (keybuf,sizeof (keybuf)); +return ret; +} + +static int spacc_hash_try_hw (struct spacc_crypto_ctx *tctx, +struct spacc_priv *priv, +const struct spacc_alg *salg, +struct crypto_ahash *reqtfm, +struct ahash_request *req) +{ +int rc; + +guard (mutex)(&tctx->lock); + +if (tctx->handle <0 || !tctx->ctx_valid) { +/* +* spacc_open() acquires ctx_sem which may sleep; +* do_one_request runs in the crypto_engine workqueue +* which is a sleepable context, so this is safe. +*/ + tctx->handle =spacc_open (&priv->spacc, +CRYPTO_MODE_NULL , salg->mode->id, +-1 ,0 , spacc_digest_cb, reqtfm); +if (tctx->handle <0 ) { +dev_dbg (salg->dev,"context open failed, fallback\n" ); +return tctx->handle; + } + + rc =spacc_set_operation (&priv->spacc, tctx->handle, +OP_ENCRYPT ,ICV_HASH ,IP_ICV_OFFSET ,0 ,0 ,0 ); +if (rc <0 ) { +spacc_close (&priv->spacc, tctx->handle); + tctx->handle =-1 ; +return rc; + } + +if (tctx->keylen >0 ) { +u32 mode_id = salg->mode->id; + +if (mode_id ==CRYPTO_MODE_MAC_SM4_XCBC ) { + rc =spacc_compute_xcbc_key (&priv->spacc, + mode_id, + tctx->handle, + tctx->ipad, + tctx->keylen, + tctx->ipad); +if (rc <0 ) { +spacc_close (&priv->spacc, tctx->handle); + tctx->handle =-1 ; +return rc; + } + + rc =spacc_write_context (&priv->spacc, + tctx->handle, +SPACC_HASH_OPERATION , + tctx->ipad, +32 + tctx->keylen, +NULL ,0 ); + }else { + rc =spacc_write_context (&priv->spacc, + tctx->handle, +SPACC_HASH_OPERATION , + tctx->ipad, + tctx->keylen, +NULL ,0 ); + } + +if (rc <0 ) { +spacc_close (&priv->spacc, tctx->handle); + tctx->handle =-1 ; +return rc; + } + } + +memzero_explicit (tctx->ipad,sizeof (tctx->ipad)); + tctx->ctx_valid = true; + } + + rc =spacc_hash_init_dma (tctx->dev, req); +if (rc <0 ) { +dev_dbg (salg->dev,"DMA init failed (%d), falling back\n" , rc); +return rc; + } + +return 0 ; +} + +/* Crypto engine hash operation */ +static int spacc_hash_do_one_request (struct crypto_engine *engine,void *areq) +{ +int rc =0 ; +struct ahash_request *req =ahash_request_cast (areq); +struct crypto_ahash *reqtfm =crypto_ahash_reqtfm (req); +struct spacc_crypto_ctx *tctx =crypto_ahash_ctx (reqtfm); +struct spacc_crypto_reqctx *ctx =ahash_request_ctx (req); +const struct spacc_alg *salg =spacc_tfm_ahash (&reqtfm->base); + +/* +* Derive priv from the algorithm's stable device, not tctx->dev -- +* the latter is mutated by setkey() concurrently with this +* function and is not safe to read outside tctx->lock. +*/ +struct spacc_priv *priv =dev_get_drvdata (salg->dev); + + ctx->single_shot =1 ; + ctx->total_nents =sg_nents (req->src); +if (req->nbytes > priv->max_msg_len) + goto fallback; + + tctx->tmp_sgl =kmalloc_array (2 ,sizeof (*tctx->tmp_sgl),GFP_KERNEL ); +if (!tctx->tmp_sgl) + goto fallback; + +sg_init_table (tctx->tmp_sgl,2 ); + tctx->tmp_sgl[0 ].length =0 ; + +if (spacc_hash_try_hw (tctx, priv, salg, reqtfm, req) <0 ) + goto fallback; + +atomic_inc (&priv->dma_ref_cnt); + + rc =spacc_packet_enqueue_ddt (&priv->spacc, ctx->acb.new_handle, + &ctx->src, &ctx->dst, req->nbytes, +0 , req->nbytes,0 ,0 ,0 , false); +if (rc <0 ) { + +spacc_free_mems (ctx, tctx, req); +dma_pool_free (priv->hash_pool, ctx->digest_buf, + ctx->digest_dma); +pdu_ddt_free (&ctx->dst); + +if (ctx->acb.new_handle >=0 ) { +spacc_close (&priv->spacc, ctx->acb.new_handle); + ctx->acb.new_handle =-1 ; + } + +if (rc == -EBUSY ) +dev_dbg (salg->dev,"HW full, failing request\n" ); + +local_bh_disable (); +crypto_finalize_hash_request (priv->engine, req, rc); +local_bh_enable (); + +if (atomic_dec_and_test (&priv->dma_ref_cnt)) +wake_up (&priv->drain_wq); + +return 0 ; + } + +return 0 ; + +fallback: +kfree (tctx->tmp_sgl); + tctx->tmp_sgl =NULL ; + +HASH_FBREQ_ON_STACK (fbreq, req); + rc =crypto_ahash_digest (fbreq); +HASH_REQUEST_ZERO (fbreq); + +local_bh_disable (); +crypto_finalize_hash_request (engine, req, rc); +local_bh_enable (); + +return 0 ; +} + +static int spacc_hash_init_tfm (struct crypto_ahash *tfm) +{ +const struct spacc_alg *salg =container_of (crypto_ahash_alg (tfm), + struct spacc_alg, + alg.hash.base); +struct spacc_crypto_ctx *tctx =crypto_ahash_ctx (tfm); + + tctx->handle =-1 ; + tctx->ctx_valid = false; + tctx->dev =get_device (salg->dev); +mutex_init (&tctx->lock); + +return 0 ; +} + +static void spacc_hash_exit_tfm (struct crypto_ahash *tfm) +{ +struct spacc_crypto_ctx *tctx =crypto_ahash_ctx (tfm); +struct spacc_priv *priv =dev_get_drvdata (tctx->dev); + +if (priv && tctx->handle >=0 ) +spacc_close (&priv->spacc, tctx->handle); + +put_device (tctx->dev); +mutex_destroy (&tctx->lock); +} + +static int spacc_hash_init (struct ahash_request *req) +{ +int rc; +struct spacc_crypto_reqctx *ctx =ahash_request_ctx (req); + +memset (ctx->state_buffer,0 ,sizeof (ctx->state_buffer)); + +HASH_FBREQ_ON_STACK (fbreq, req); + rc =crypto_ahash_init (fbreq); +if (!rc) + rc =crypto_ahash_export (fbreq, ctx->state_buffer); +HASH_REQUEST_ZERO (fbreq); + +return rc; +} + +static int spacc_hash_update (struct ahash_request *req) +{ +int rc; +struct spacc_crypto_reqctx *ctx =ahash_request_ctx (req); + +if (!req->nbytes) +return 0 ; + +HASH_FBREQ_ON_STACK (fbreq, req); + + rc =crypto_ahash_import (fbreq, ctx->state_buffer); +if (!rc) + rc =crypto_ahash_update (fbreq); +if (!rc) + rc =crypto_ahash_export (fbreq, ctx->state_buffer); + +HASH_REQUEST_ZERO (fbreq); + +return rc; +} + +static int spacc_hash_final (struct ahash_request *req) +{ +int rc; +struct spacc_crypto_reqctx *ctx =ahash_request_ctx (req); + +HASH_FBREQ_ON_STACK (fbreq, req); + rc =crypto_ahash_import (fbreq, ctx->state_buffer); +if (!rc) + rc =crypto_ahash_final (fbreq); +HASH_REQUEST_ZERO (fbreq); + +return rc; +} + +static int spacc_hash_digest (struct ahash_request *req) +{ +struct crypto_ahash *reqtfm =crypto_ahash_reqtfm (req); +struct spacc_crypto_ctx *tctx =crypto_ahash_ctx (reqtfm); +struct spacc_priv *priv =dev_get_drvdata (tctx->dev); +unsigned long flags; +bool removing; + +if (!priv || !priv->engine) +return -ENODEV ; + +spin_lock_irqsave (&priv->spacc.lock, flags); + removing = priv->removing; +spin_unlock_irqrestore (&priv->spacc.lock, flags); + +if (removing) +return -ENODEV ; + +return crypto_transfer_hash_request_to_engine (priv->engine, req); +} + +static int spacc_hash_finup (struct ahash_request *req) +{ +int rc; +struct spacc_crypto_reqctx *ctx =ahash_request_ctx (req); + +HASH_FBREQ_ON_STACK (fbreq, req); + rc =crypto_ahash_import (fbreq, ctx->state_buffer); +if (!rc) + rc =crypto_ahash_finup (fbreq); +HASH_REQUEST_ZERO (fbreq); + +return rc; +} + +static int spacc_hash_export (struct ahash_request *req,void *out) +{ +struct spacc_crypto_reqctx *ctx =ahash_request_ctx (req); + +memcpy (out, ctx->state_buffer,HASH_MAX_STATESIZE ); +return 0 ; +} + +static int spacc_hash_import (struct ahash_request *req,const void *in) +{ +struct spacc_crypto_reqctx *ctx =ahash_request_ctx (req); + +memcpy (ctx->state_buffer, in,HASH_MAX_STATESIZE ); +return 0 ; +} + +static void spacc_hash_alg_destroy (struct crypto_alg *alg) +{ + struct spacc_alg *salg = container_of(alg, struct spacc_alg, + alg.hash.base.halg.base); + +kfree (salg); +} + +static const struct ahash_engine_alg spacc_hash_template = { + .base = { + .init = spacc_hash_init, + .update = spacc_hash_update, + .final = spacc_hash_final, + .finup = spacc_hash_finup, + .digest = spacc_hash_digest, + .setkey = spacc_hash_setkey, + .export = spacc_hash_export, + .import = spacc_hash_import, + .init_tfm = spacc_hash_init_tfm, + .exit_tfm = spacc_hash_exit_tfm, + + .halg.base = { + .cra_priority =300 , + .cra_module =THIS_MODULE , + .cra_ctxsize =sizeof (struct spacc_crypto_ctx ), + .cra_reqsize =sizeof (struct spacc_crypto_reqctx ), + .cra_destroy = spacc_hash_alg_destroy, + .cra_flags =CRYPTO_ALG_TYPE_AHASH | +CRYPTO_ALG_ASYNC | +CRYPTO_AHASH_ALG_BLOCK_ONLY + }, + }, + .op = { + .do_one_request = spacc_hash_do_one_request, + }, +}; + +/* Keyed algorithms need a setkey(); plain digests must not have one. */ +static bool spacc_mode_is_keyed (int id) +{ +switch (id) { +case CRYPTO_MODE_HMAC_MD5 : +case CRYPTO_MODE_HMAC_SHA1 : +case CRYPTO_MODE_HMAC_SHA224 : +case CRYPTO_MODE_HMAC_SHA256 : +case CRYPTO_MODE_HMAC_SHA384 : +case CRYPTO_MODE_HMAC_SHA512 : +case CRYPTO_MODE_MAC_SM4_CMAC : +case CRYPTO_MODE_MAC_SM4_XCBC : +return true; +default : +return false; + } +} + +static int spacc_register_hash (struct spacc_alg *salg) +{ +int rc =0 ; +struct spacc_priv *priv =dev_get_drvdata (salg->dev); + + salg->calg = &salg->alg.hash.base.halg.base; + salg->alg.hash = spacc_hash_template; + +/* Unkeyed digests must not advertise a setkey. */ +if (!spacc_mode_is_keyed (salg->mode->id)) + salg->alg.hash.base.setkey =NULL ; + + rc =spacc_init_calg (salg->calg, salg->mode); +if (rc) +return rc; + + salg->alg.hash.base.halg.digestsize = salg->mode->hashlen; + salg->alg.hash.base.halg.statesize =HASH_MAX_STATESIZE ; + + rc =crypto_engine_register_ahash (&salg->alg.hash); +if (rc <0 ) +return rc; + +guard (mutex)(&priv->hash_alg_mutex); +list_add (&salg->list, &priv->hash_alg_list); + +return 0 ; +} + +int spacc_probe_hashes (struct platform_device *spacc_pdev) +{ +int rc =0 ; +unsigned int index; +int registered =0 ; +struct spacc_alg *salg; +struct spacc_priv *priv =dev_get_drvdata (&spacc_pdev->dev); +const char *name =NULL ; + +INIT_LIST_HEAD (&priv->hash_alg_list); +mutex_init (&priv->hash_alg_mutex); + +/* Create per-device DMA pool */ + priv->hash_pool =dma_pool_create ("spacc-digest" , &spacc_pdev->dev, +SPACC_MAX_DIGEST_SIZE , +SPACC_DMA_ALIGN ,SPACC_DMA_BOUNDARY ); + +if (!priv->hash_pool) +return -ENOMEM ; + +for (index =0 ; index <ARRAY_SIZE (possible_hashes); index++) { + name = possible_hashes[index].name; + +if (!crypto_has_ahash (name,0 ,0 )) +continue ; + +if (spacc_is_mode_keysize_supported (&priv->spacc, + possible_hashes[index].id &0xFF , + possible_hashes[index].hashlen,1 )) { + salg =kmalloc_obj (*salg,GFP_KERNEL ); +if (!salg) { + rc = -ENOMEM ; + goto err_unregister; + } + + salg->mode = &possible_hashes[index]; + salg->dev = &spacc_pdev->dev; + + rc =spacc_register_hash (salg); +if (rc <0 ) +continue ; + + registered++; + } + } + +return registered; + +err_unregister: +spacc_unregister_hash_algs (priv); +return rc; +} + +int spacc_unregister_hash_algs (struct spacc_priv *priv) +{ +struct spacc_alg *salg, *tmp; + +if (!priv) +return 0 ; + +guard (mutex)(&priv->hash_alg_mutex); + +list_for_each_entry_safe (salg, tmp, &priv->hash_alg_list, list) { +list_del (&salg->list); +crypto_engine_unregister_ahash (&salg->alg.hash); + } + +return 0 ; +}
drivers/crypto/dwc-spacc/spacc_core.c new file +1337 -0
1,337 lines not on this page · raw message
drivers/crypto/dwc-spacc/spacc_core.h new file +863 -0
806 lines not on this page · raw message
drivers/crypto/dwc-spacc/spacc_device.c new file +324 -0
324 lines not on this page · raw message
drivers/crypto/dwc-spacc/spacc_device.h new file +181 -0
181 lines not on this page · raw message
drivers/crypto/dwc-spacc/spacc_hal.c new file +349 -0
349 lines not on this page · raw message
drivers/crypto/dwc-spacc/spacc_hal.h new file +113 -0
113 lines not on this page · raw message
drivers/crypto/dwc-spacc/spacc_interrupt.c new file +360 -0
360 lines not on this page · raw message
drivers/crypto/dwc-spacc/spacc_manager.c new file +657 -0
657 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
--
2.25.1
Part of the diff is not shown here. View the raw message.
[email protected]
AI reviewRe: [PATCH v27 2/4] crypto: spacc - Add SPAcc ahash support
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider: - [High] crypto: spacc: statesize overflow and broken BLOCK_ONLY in spacc_register_hash() - [High] crypto…
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] crypto: spacc: statesize overflow and broken BLOCK_ONLY in spacc_register_hash()
- [High] crypto: spacc: teardown race and use-after-free in spacc_crypto_remove()
- [High] crypto: spacc - unsplit >64KB or boundary-crossing SG entries in spacc_sg_to_ddt()
- [High] crypto: spacc - hardirq livelock in spacc_process_irq() in IRQ mode
- [Medium] crypto: spacc: sleeping lock in spacc_hash_setkey() and persistent hw handle
- [Medium] crypto: spacc - unlocked IRQ state and register setup in spacc_init_device() --
commit 39aecabd458071b66bf2f10317714fe1849c6141
Author: Pavitrakumar Managutte <[email protected]>
crypto: spacc - Add SPAcc ahash support
This commit adds core SPAcc driver infrastructure and ahash algorithm support for MD5, SHA-1, SHA-2, SHA-3, HMAC, and SM4 CMAC/XCBC.
Quoted 5 lines
drivers/crypto/dwc-spacc/spacc_ahash.c new file +0
-0
[ ... ]
Quoted 10 lines
drivers/crypto/dwc-spacc/spacc_ahash.c new file +10
-0+static int spacc_hash_commit_key (struct crypto_ahash *tfm, +struct spacc_priv *priv, +const u8 *key,unsigned int keylen, +const u8 *keybuf,unsigned int klen) +{ +struct spacc_crypto_ctx *tctx =crypto_ahash_ctx (tfm); +struct crypto_ahash *fb; +int ret; + +guard (mutex)(&tctx->lock);
[ ... ]
Quoted 19 lines
drivers/crypto/dwc-spacc/spacc_ahash.c new file +19
-0+static int spacc_hash_try_hw (struct spacc_crypto_ctx *tctx, +struct spacc_priv *priv, +const struct spacc_alg *salg, +struct crypto_ahash *reqtfm, +struct ahash_request *req) +{ +int rc; + +guard (mutex)(&tctx->lock); + +if (tctx->handle <0 || !tctx->ctx_valid) { +/* +* spacc_open() acquires ctx_sem which may sleep; +* do_one_request runs in the crypto_engine workqueue +* which is a sleepable context, so this is safe. +*/ + tctx->handle =spacc_open (&priv->spacc, +CRYPTO_MODE_NULL , salg->mode->id, +-1 ,0 , spacc_digest_cb, reqtfm);
[ ... ]
drivers/crypto/dwc-spacc/spacc_ahash.c line 486
Quoted 3 lines
drivers/crypto/dwc-spacc/spacc_ahash.c new file +3
-0+memzero_explicit (tctx->ipad,sizeof (tctx->ipad)); + tctx->ctx_valid = true; + }
[Severity: Medium]
As reported by Herbert Xu on v12 [1], crypto_ahash_setkey() should not sleep, and hardware handles can be allocated and released per request in spacc_hash_do_one_request().
In spacc_hash_setkey() -> spacc_hash_commit_key(), acquiring tctx->lock still sleeps if crypto_ahash_setkey() is called from atomic context.
Additionally, spacc_hash_try_hw() opens a persistent tctx->handle on the transform context, zeroes tctx->ipad, and clones a second job slot (ctx->acb.new_handle) via spacc_hash_init_dma() -> spacc_ctx_clone_handle(). When the request completes, spacc_digest_cb() only closes cb->new_handle, leaving tctx->handle and its scarce hardware context slot pinned across idle transforms until spacc_hash_exit_tfm() or a subsequent setkey.
Could tctx->ipad be retained across requests and the hardware handle opened and closed per request inside spacc_hash_do_one_request() / spacc_digest_cb() so that setkey does not need a sleeping lock or persistent context?
[ ... ]
Quoted 28 lines
drivers/crypto/dwc-spacc/spacc_ahash.c new file +28
-0+static const struct ahash_engine_alg spacc_hash_template = { + .base = { + .init = spacc_hash_init, + .update = spacc_hash_update, + .final = spacc_hash_final, + .finup = spacc_hash_finup, + .digest = spacc_hash_digest, + .setkey = spacc_hash_setkey, + .export = spacc_hash_export, + .import = spacc_hash_import, + .init_tfm = spacc_hash_init_tfm, + .exit_tfm = spacc_hash_exit_tfm, + + .halg.base = { + .cra_priority =300 , + .cra_module =THIS_MODULE , + .cra_ctxsize =sizeof (struct spacc_crypto_ctx ), + .cra_reqsize =sizeof (struct spacc_crypto_reqctx ), + .cra_destroy = spacc_hash_alg_destroy, + .cra_flags =CRYPTO_ALG_TYPE_AHASH | +CRYPTO_ALG_ASYNC | +CRYPTO_AHASH_ALG_BLOCK_ONLY + }, + }, + .op = { + .do_one_request = spacc_hash_do_one_request, + }, +};
[ ... ]
Quoted 10 lines
drivers/crypto/dwc-spacc/spacc_ahash.c new file +10
-0+static int spacc_register_hash (struct spacc_alg *salg) +{ +int rc =0 ; +struct spacc_priv *priv =dev_get_drvdata (salg->dev); + + salg->calg = &salg->alg.hash.base.halg.base; + salg->alg.hash = spacc_hash_template; + +/* Unkeyed digests must not advertise a setkey. */ +if (!spacc_mode_is_keyed (salg->mode->id))
drivers/crypto/dwc-spacc/spacc_ahash.c line 779
Quoted 10 lines
drivers/crypto/dwc-spacc/spacc_ahash.c new file +10
-0+ salg->alg.hash.base.setkey =NULL ; + + rc =spacc_init_calg (salg->calg, salg->mode); +if (rc) +return rc; + + salg->alg.hash.base.halg.digestsize = salg->mode->hashlen; + salg->alg.hash.base.halg.statesize =HASH_MAX_STATESIZE ; + + rc =crypto_engine_register_ahash (&salg->alg.hash);
[Severity: High]
As reported by Sashiko on v26 [2], does setting CRYPTO_AHASH_ALG_BLOCK_ONLY on spacc_hash_template combined with halg.statesize = HASH_MAX_STATESIZE in spacc_register_hash() break state export/import and virtual-address requests?
In spacc_ahash.c, spacc_hash_init(), spacc_hash_update(), spacc_hash_final(), spacc_hash_finup(), spacc_hash_export(), and spacc_hash_import() delegate full-state operations to the software fallback (fbreq) rather than implementing block-only core state operations (for instance, spacc_hash_update() delegates to crypto_ahash_update(fbreq) and returns 0 rather than returning the leftover partial-block byte count expected by CRYPTO_AHASH_ALG_BLOCK_ONLY).
When spacc_register_hash() calls crypto_engine_register_ahash() -> crypto_register_ahash() -> ahash_prepare_alg() with CRYPTO_AHASH_ALG_BLOCK_ONLY set, ahash_prepare_alg() adds cra_blocksize + 1 to alg->halg.statesize:
crypto_ahash_statesize(tfm) = HASH_MAX_STATESIZE + cra_blocksize + 1
This exceeds HASH_MAX_STATESIZE for every registered SPAcc algorithm, which causes:
1. ahash_do_req_chain() to reject all virtual-address requests (CRYPTO_AHASH_REQ_VIRT, including testmgr virtual-address tests and crypto/hmac.c wrapping unkeyed SPAcc hashes) with -ENOSYS because crypto_ahash_statesize(tfm) > HASH_MAX_STATESIZE.
2. crypto_ahash_export() to write cra_blocksize + 1 bytes at
out + HASH_MAX_STATESIZE after spacc_hash_export() copies HASH_MAX_STATESIZE bytes, overflowing any HASH_MAX_STATESIZE-sized export buffer.
Should CRYPTO_AHASH_ALG_BLOCK_ONLY be dropped from spacc_hash_template since incremental hashing is handled entirely by the software fallback?
Quoted 5 lines
drivers/crypto/dwc-spacc/spacc_core.c new file +0
-0
[ ... ]
Quoted 22 lines
drivers/crypto/dwc-spacc/spacc_core.c new file +22
-0+int spacc_sg_to_ddt (struct device *dev,struct scatterlist *sg, +int nbytes,struct pdu_ddt *ddt,int dma_direction) +{ +int i; +int nents; +int rc =0 ; +int orig_nents; +struct scatterlist *sg_entry; + +/* Count the SG entries needed to cover the requested length. */ + orig_nents =sg_nents_for_len (sg, nbytes); +if (orig_nents <=0 ) +return orig_nents; + + nents =dma_map_sg (dev, sg, orig_nents, dma_direction); +if (nents <=0 ) +return -ENOMEM ; + + rc =pdu_ddt_init (dev, ddt, nents |0x80000000 ); +if (rc <0 ) { +dma_unmap_sg (dev, sg, orig_nents, dma_direction); +return -EIO ;
drivers/crypto/dwc-spacc/spacc_core.c line 235
Quoted 10 lines
drivers/crypto/dwc-spacc/spacc_core.c new file +10
-0+ } + +/* Populate the descriptor table with the DMA-mapped SG entries. */ +for_each_sg (sg, sg_entry, nents, i) { +pdu_ddt_add (dev, ddt,sg_dma_address (sg_entry), +sg_dma_len (sg_entry)); + } + +return orig_nents; +}
[Severity: High]
What happens in spacc_sg_to_ddt() when an input scatterlist entry is larger than 64KB (SPACC_DMA_BOUNDARY) or straddles a 64KB DMA address boundary?
In spacc_init_device(), the driver notes that each DDT fragment must be <= 64KB and must not straddle a 64KB boundary, and sets priv->max_msg_len to priv->spacc.config.max_msg_size (up to 512KB) while relying on dma_set_max_seg_size() and dma_set_seg_boundary().
However, dma_map_sg() maps entries in-place into the caller-supplied sg array of orig_nents elements; while those DMA parameters prevent an IOMMU from merging adjacent SG entries across a 64KB boundary, dma_map_sg() cannot split a single scatterlist entry that is already > 64KB (such as a high-order folio or kmalloc buffer) or that crosses a 64KB boundary on a dma-direct system.
Since spacc_sg_to_ddt() passes each mapped sg_entry directly to pdu_ddt_add(), won't such requests violate the hardware's 64KB DDT fragment limit and trigger SPACC_MEMERR or DMA-API debug warnings?
Quoted 5 lines
drivers/crypto/dwc-spacc/spacc_device.c new file +0
-0
[ ... ]
Quoted 9 lines
drivers/crypto/dwc-spacc/spacc_device.c new file +9
-0+ irq_ret =devm_request_irq (&pdev->dev, irq_num, spacc_irq_handler, +IRQF_SHARED ,dev_name (&pdev->dev), + &pdev->dev); +if (irq_ret) { +dev_err (&pdev->dev,"Failed to request IRQ : %d\n" , irq_ret); + err = irq_ret; + goto free_spacc_workq; + } +
drivers/crypto/dwc-spacc/spacc_device.c line 166
Quoted 10 lines
drivers/crypto/dwc-spacc/spacc_device.c new file +10
-0+ priv->spacc.irq_cb_stat = spacc_stat_process; + priv->spacc.irq_cb_cmdx = spacc_cmd_process; + oldmode = priv->spacc.op_mode; + priv->spacc.op_mode =SPACC_OP_MODE_IRQ ; + +/* Enable STAT and CMD interrupts */ +spacc_irq_stat_enable (&priv->spacc,1 ); +spacc_irq_cmdx_enable (&priv->spacc,0 ,1 ); +spacc_irq_stat_wd_disable (&priv->spacc); +spacc_irq_glbl_enable (&priv->spacc);
[Severity: Medium]
As reported by Sashiko on v26 [2], in spacc_init_device(), after devm_request_irq() registers spacc_irq_handler() with IRQF_SHARED, can a shared interrupt (or an immediate CMD0 interrupt once SPACC_IRQ_EN_CMD(0) is enabled) race with this unlocked initialization block?
spacc_process_irq() runs under priv->spacc.lock, reads spacc->op_mode and spacc->irq_cb_*, and performs read-modify-write updates on SPACC_REG_IRQ_CTRL and SPACC_REG_IRQ_EN, whereas spacc_init_device() updates irq_cb_stat, irq_cb_cmdx, op_mode, SPACC_REG_IRQ_CTRL, and SPACC_REG_IRQ_EN here without holding priv->spacc.lock (unlike the second IRQ configuration block further down in spacc_init_device()).
[ ... ]
Quoted 31 lines
drivers/crypto/dwc-spacc/spacc_device.c new file +31
-0+static void spacc_crypto_remove (struct platform_device *pdev) +{ +struct spacc_priv *priv =platform_get_drvdata (pdev); +unsigned long flags; + +/* +* Set before anything else: sysfs unbind (unlike rmmod) has no +* built-in wait for existing tfms to be freed, so a request can +* reach spacc_hash_digest() at any point during this function. +* This flag, checked under the same lock there, blocks any new +* submission attempt from this point on. +*/ +spin_lock_irqsave (&priv->spacc.lock, flags); + priv->removing = true; +spin_unlock_irqrestore (&priv->spacc.lock, flags); + +/* Stop the crypto API from handing out any new tfms. */ +spacc_unregister_algs (priv); + +wait_event (priv->drain_wq, !atomic_read (&priv->dma_ref_cnt)); + +if (priv->engine) +crypto_engine_exit (priv->engine); + +/* Nothing can dispatch new work past this point. */ +spin_lock_irqsave (&priv->spacc.lock, flags); +spacc_irq_glbl_disable (&priv->spacc); +spin_unlock_irqrestore (&priv->spacc.lock, flags); + +devm_free_irq (&pdev->dev, priv->irq, &pdev->dev); +
drivers/crypto/dwc-spacc/spacc_device.c line 283
Quoted 10 lines
drivers/crypto/dwc-spacc/spacc_device.c new file +10
-0+if (priv->spacc_wq) +destroy_workqueue (priv->spacc_wq); + +/* No job can still reference this pool past the drain above. */ +dma_pool_destroy (priv->hash_pool); + priv->hash_pool =NULL ; + +spacc_remove (pdev); +platform_set_drvdata (pdev,NULL ); +}
[Severity: High]
As reported by Sashiko on v26 [2], can spacc_crypto_remove() race with in-flight requests and surviving transforms during sysfs unbind, leading to a use-after-free of priv, priv->engine, spacc->job, and spacc->ctx?
First, in spacc_hash_digest(), priv->removing is checked under priv->spacc.lock, and the lock is dropped before calling crypto_transfer_hash_request_to_engine(priv->engine, req):
spin_lock_irqsave(&priv->spacc.lock, flags); removing = priv->removing; spin_unlock_irqrestore(&priv->spacc.lock, flags); if (removing) return -ENODEV; return crypto_transfer_hash_request_to_engine(priv->engine, req);
Meanwhile, priv->dma_ref_cnt is not incremented until the crypto_engine worker runs spacc_hash_do_one_request() and finishes spacc_hash_try_hw(). Because spacc_crypto_remove() waits on drain_wq before calling crypto_engine_exit(priv->engine), any request that has passed the priv->removing check in spacc_hash_digest(), is queued in priv->engine, or is inside spacc_hash_try_hw() has not incremented dma_ref_cnt yet, allowing wait_event(priv->drain_wq, ...) to return prematurely.
Second, on sysfs unbind, existing crypto_ahash transforms remain alive after spacc_crypto_remove() returns. While spacc_hash_init_tfm() calls get_device(salg->dev), that only pins the struct device kobject and does not prevent devres from freeing devm_kzalloc()-allocated priv when spacc_crypto_remove() finishes. In addition, spacc_remove(pdev) frees spacc->ctx and spacc->job before platform_set_drvdata(pdev, NULL) is called, and concurrent calls to spacc_hash_exit_tfm(), spacc_hash_setkey(), or spacc_hash_digest() read dev_get_drvdata(tctx->dev) without synchronization against teardown.
Quoted 5 lines
drivers/crypto/dwc-spacc/spacc_interrupt.c new file +0
-0
[ ... ]
Quoted 28 lines
drivers/crypto/dwc-spacc/spacc_interrupt.c new file +28
-0+/* clear interrupt pin and run registered callback */ +if (irq_status &SPACC_IRQ_STAT_STAT ) { + handled |=SPACC_IRQ_STAT_STAT ; +SPACC_IRQ_STAT_CLEAR_STAT (spacc); +if (spacc->op_mode ==SPACC_OP_MODE_IRQ && + spacc->wd_cnt_limit) { +spacc_irq_cmdx_disable (spacc,0 ); +spacc_irq_stat_enable (spacc, + spacc->config.ideal_stat_level); +spacc_irq_stat_wd_enable (spacc); + spacc->wdcnt =0 ; + spacc->op_mode =SPACC_OP_MODE_WD ; + spacc->wd_cnt_limit = false; + }else if (spacc->op_mode ==SPACC_OP_MODE_IRQ ) { + spacc->config.fifo_cnt <<=2 ; + spacc->config.fifo_cnt =min (spacc->config.fifo_cnt, + spacc->config.stat_fifo_depth); + +/* update fifo count to allow more stats to pile up */ +spacc_irq_stat_enable (spacc, spacc->config.fifo_cnt); + + +/* re-enable CMD0 empty interrupt */ +spacc_irq_cmdx_enable (spacc,0 ,0 ); + } +if (spacc->irq_cb_stat) + spacc->irq_cb_stat (spacc); + }
[ ... ]
Quoted 11 lines
drivers/crypto/dwc-spacc/spacc_interrupt.c new file +11
-0+if (spacc->op_mode ==SPACC_OP_MODE_IRQ ) { + cmd_max = (spacc->config.is_qos ?SPACC_CMDX_MAX_QOS : +SPACC_CMDX_MAX ); +for (x =0 ; x < cmd_max; x++) { +if (irq_status &SPACC_IRQ_STAT_CMDX (x)) { + handled |=SPACC_IRQ_STAT_CMDX (x); + spacc->config.fifo_cnt =1 ; + +/* disable CMD0 interrupt since STAT=1 */ +spacc_irq_cmdx_disable (spacc, x); + spacc_irq_stat_enable(spacc,
drivers/crypto/dwc-spacc/spacc_interrupt.c line 262
Quoted 10 lines
drivers/crypto/dwc-spacc/spacc_interrupt.c new file +10
-0+ spacc->config.fifo_cnt); + +SPACC_IRQ_STAT_CLEAR_CMDX (spacc, x); + +/* run registered callback */ +if (spacc->irq_cb_cmdx) + spacc->irq_cb_cmdx (spacc, x); + } + } + }
[Severity: High]
Won't spacc_process_irq() livelock in hardirq context when operating in SPACC_OP_MODE_IRQ?
In spacc_device.c, spacc_stat_process() and spacc_cmd_process() defer popping the STATUS FIFO to priv->pop_jobs on the priv->spacc_wq workqueue rather than draining the FIFO in the interrupt handler.
When a job completes in SPACC_OP_MODE_IRQ (STATUS FIFO count is 1, CMD0 FIFO is empty), the SPACC_IRQ_STAT_STAT branch raises spacc->config.fifo_cnt, calls spacc_irq_stat_enable(spacc, spacc->config.fifo_cnt), and enables the CMD0 empty interrupt via spacc_irq_cmdx_enable(spacc, 0, 0).
Because CMD0 is currently empty, enabling CMD0 IRQ with threshold 0 immediately asserts SPACC_IRQ_STAT_CMDX(0) before the workqueue can run. The next hardirq enters the SPACC_IRQ_STAT_CMDX(0) branch, disables CMD0 IRQ, and lowers the STAT threshold back to 1 via spacc_irq_stat_enable(spacc, 1). Because the completed job is still unpopped in the STATUS FIFO, lowering the STAT threshold to 1 immediately re-asserts SPACC_IRQ_STAT_STAT, which re-enables CMD0 IRQ and traps the CPU in an infinite interrupt loop.
[1] https://lore.kernel.org/r/[email protected]
[2] https://lore.kernel.org/r/[email protected]
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
PATCH v27 3/4 crypto: spacc - add spacc autodetect support
In reply to Pavitrakumar ManagutteSPAcc is configurable and it supports the below modes:
1. AUTODETECT configuration - Autodetects the supported algos.
2. Static configuration - The algo support is defined statically.
--- drivers/crypto/dwc-spacc/spacc_core.c | 1192 +++++++++++++++++++++++++ 1 file changed, 1192 insertions(+)
drivers/crypto/dwc-spacc/spacc_core.c +1192 -0
@@ -201,6 +201,922 @@ static const unsigned char template[] = { [CRYPTO_MODE_MAC_SM4_CMAC] = 130, }; +#if IS_ENABLED (CONFIG_CRYPTO_DEV_SPACC_AUTODETECT ) +static const struct { +unsigned int min_version; +struct { +int outlen; +unsigned char data[64 ]; + } test[7 ]; +} testdata[CRYPTO_MODE_LAST ] = { + [CRYPTO_MODE_NULL ] = { + .min_version =0x65 , + .test[0 ].outlen =0 + }, + + [CRYPTO_MODE_AES_ECB ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0xc6 ,0xa1 ,0x3b ,0x37 , +0x87 ,0x8f ,0x5b ,0x82 ,0x6f ,0x4f ,0x81 ,0x62 ,0xa1 , +0xc8 ,0xd8 ,0x79 , }, + .test[3 ].outlen =16 , .test[3 ].data = {0x91 ,0x62 ,0x51 ,0x82 , +0x1c ,0x73 ,0xa5 ,0x22 ,0xc3 ,0x96 ,0xd6 ,0x27 ,0x38 , +0x01 ,0x96 ,0x07 , }, + .test[4 ].outlen =16 , .test[4 ].data = {0xf2 ,0x90 ,0x00 ,0xb6 , +0x2a ,0x49 ,0x9f ,0xd0 ,0xa9 ,0xf3 ,0x9a ,0x6a ,0xdd , +0x2e ,0x77 ,0x80 , }, + }, + + [CRYPTO_MODE_AES_CBC ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x0a ,0x94 ,0x0b ,0xb5 , +0x41 ,0x6e ,0xf0 ,0x45 ,0xf1 ,0xc3 ,0x94 ,0x58 ,0xc6 , +0x53 ,0xea ,0x5a , }, + .test[3 ].outlen =16 , .test[3 ].data = {0x00 ,0x60 ,0xbf ,0xfe , +0x46 ,0x83 ,0x4b ,0xb8 ,0xda ,0x5c ,0xf9 ,0xa6 ,0x1f , +0xf2 ,0x20 ,0xae , }, + .test[4 ].outlen =16 , .test[4 ].data = {0x5a ,0x6e ,0x04 ,0x57 , +0x08 ,0xfb ,0x71 ,0x96 ,0xf0 ,0x2e ,0x55 ,0x3d ,0x02 , +0xc3 ,0xa6 ,0x92 , }, + }, + + [CRYPTO_MODE_AES_CTR ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x0a ,0x94 ,0x0b ,0xb5 , +0x41 ,0x6e ,0xf0 ,0x45 ,0xf1 ,0xc3 ,0x94 ,0x58 ,0xc6 , +0x53 ,0xea ,0x5a , }, + .test[3 ].outlen =16 , .test[3 ].data = {0x00 ,0x60 ,0xbf ,0xfe , +0x46 ,0x83 ,0x4b ,0xb8 ,0xda ,0x5c ,0xf9 ,0xa6 ,0x1f , +0xf2 ,0x20 ,0xae , }, + .test[4 ].outlen =16 , .test[4 ].data = {0x5a ,0x6e ,0x04 ,0x57 , +0x08 ,0xfb ,0x71 ,0x96 ,0xf0 ,0x2e ,0x55 ,0x3d ,0x02 , +0xc3 ,0xa6 ,0x92 , }, + }, + + [CRYPTO_MODE_AES_CCM ] = { + .min_version =0x65 , + .test[2 ].outlen =32 , .test[2 ].data = {0x02 ,0x63 ,0xec ,0x94 , +0x66 ,0x18 ,0x72 ,0x96 ,0x9a ,0xda ,0xfd ,0x0f ,0x4b , +0xa4 ,0x0f ,0xdc ,0xa5 ,0x09 ,0x92 ,0x93 ,0xb6 ,0xb4 , +0x38 ,0x34 ,0x63 ,0x72 ,0x50 ,0x4c ,0xfc ,0x8a ,0x63 , +0x02 , }, + .test[3 ].outlen =32 , .test[3 ].data = {0x29 ,0xf7 ,0x63 ,0xe8 , +0xa1 ,0x75 ,0xc6 ,0xbf ,0xa5 ,0x54 ,0x94 ,0x89 ,0x12 , +0x84 ,0x45 ,0xf5 ,0x9b ,0x27 ,0xeb ,0xb1 ,0xa4 ,0x65 , +0x93 ,0x6e ,0x5a ,0xc0 ,0xa2 ,0xa3 ,0xe2 ,0x6c ,0x46 , +0x29 , }, + .test[4 ].outlen =32 , .test[4 ].data = {0x60 ,0xf3 ,0x10 ,0xd5 , +0xc3 ,0x85 ,0x58 ,0x5d ,0x55 ,0x16 ,0xfb ,0x51 ,0x72 , +0xe5 ,0x20 ,0xcf ,0x8e ,0x87 ,0x6d ,0x72 ,0xc8 ,0x44 , +0xbe ,0x6d ,0xa2 ,0xd6 ,0xf4 ,0xba ,0xec ,0xb4 ,0xec , +0x39 , }, + }, + + [CRYPTO_MODE_AES_GCM ] = { + .min_version =0x65 , + .test[2 ].outlen =32 , .test[2 ].data = {0x93 ,0x6c ,0xa7 ,0xce , +0x66 ,0x1b ,0xf7 ,0x54 ,0x4b ,0xd2 ,0x61 ,0x8a ,0x36 , +0xa3 ,0x70 ,0x08 ,0xc0 ,0xd7 ,0xd0 ,0x77 ,0xc5 ,0x64 , +0x76 ,0xdb ,0x48 ,0x4a ,0x53 ,0xe3 ,0x6c ,0x93 ,0x34 , +0x0f , }, + .test[3 ].outlen =32 , .test[3 ].data = {0xe6 ,0xf9 ,0x22 ,0x9b , +0x99 ,0xb9 ,0xc9 ,0x0e ,0xd0 ,0x33 ,0xdc ,0x82 ,0xff , +0xa9 ,0xdc ,0x70 ,0x4c ,0xcd ,0xc4 ,0x1b ,0xa3 ,0x5a , +0x87 ,0x5d ,0xd8 ,0xef ,0xb6 ,0x48 ,0xbb ,0x0c ,0x92 , +0x60 , }, + .test[4 ].outlen =32 , .test[4 ].data = {0x47 ,0x02 ,0xd6 ,0x1b , +0xc5 ,0xe5 ,0xc2 ,0x1b ,0x8d ,0x41 ,0x97 ,0x8b ,0xb1 , +0xe9 ,0x78 ,0x6d ,0x48 ,0x6f ,0x78 ,0x81 ,0xc7 ,0x98 , +0xcc ,0xf5 ,0x28 ,0xf1 ,0x01 ,0x7c ,0xe8 ,0xf6 ,0x09 , +0x78 , }, + }, + + [CRYPTO_MODE_AES_F8 ] = { + .min_version =0x65 , + .test[0 ].outlen =0 + }, + + [CRYPTO_MODE_AES_XTS ] = { + .min_version =0x65 , + .test[2 ].outlen =32 , .test[2 ].data = {0xa0 ,0x1a ,0x6f ,0x09 , +0xfa ,0xef ,0xd2 ,0x72 ,0xc3 ,0x9b ,0xad ,0x35 ,0x52 , +0xfc ,0xa1 ,0xcb ,0x33 ,0x69 ,0x51 ,0xc5 ,0x23 ,0xbe , +0xac ,0xa5 ,0x4a ,0xf2 ,0xfc ,0x77 ,0x71 ,0x6f ,0x9a , +0x86 , }, + .test[4 ].outlen =32 , .test[4 ].data = {0x05 ,0x45 ,0x91 ,0x86 , +0xf2 ,0x2d ,0x97 ,0x93 ,0xf3 ,0xa0 ,0xbb ,0x29 ,0xc7 , +0x9c ,0xc1 ,0x4c ,0x3b ,0x8f ,0xdd ,0x9d ,0xda ,0xc7 , +0xb5 ,0xaa ,0xc2 ,0x7c ,0x2e ,0x71 ,0xce ,0x7f ,0xce , +0x0e , }, + }, + + [CRYPTO_MODE_AES_CFB ] = { + .min_version =0x65 , + .test[0 ].outlen =0 + }, + + [CRYPTO_MODE_AES_OFB ] = { + .min_version =0x65 , + .test[0 ].outlen =0 + }, + + [CRYPTO_MODE_AES_CS1 ] = { + .min_version =0x65 , + .test[2 ].outlen =31 , .test[2 ].data = {0x0a ,0x94 ,0x0b ,0xb5 , +0x41 ,0x6e ,0xf0 ,0x45 ,0xf1 ,0xc3 ,0x94 ,0x58 ,0xc6 , +0x53 ,0xea ,0xae ,0xe7 ,0x1e ,0xa5 ,0x41 ,0xd7 ,0xae , +0x4b ,0xeb ,0x60 ,0xbe ,0xcc ,0x59 ,0x3f ,0xb6 ,0x63 , + }, + .test[3 ].outlen =31 , .test[3 ].data = {0x00 ,0x60 ,0xbf ,0xfe , +0x46 ,0x83 ,0x4b ,0xb8 ,0xda ,0x5c ,0xf9 ,0xa6 ,0x1f , +0xf2 ,0x20 ,0x2e ,0x84 ,0xcb ,0x12 ,0xa3 ,0x59 ,0x17 , +0xb0 ,0x9e ,0x25 ,0xa2 ,0xa2 ,0x3d ,0xf1 ,0x9f ,0xdc , + }, + .test[4 ].outlen =31 , .test[4 ].data = {0x5a ,0x6e ,0x04 ,0x57 , +0x08 ,0xfb ,0x71 ,0x96 ,0xf0 ,0x2e ,0x55 ,0x3d ,0x02 , +0xc3 ,0xa6 ,0xcd ,0xfc ,0x25 ,0x35 ,0x31 ,0x0b ,0xf5 , +0x6b ,0x2e ,0xb7 ,0x8a ,0xa2 ,0x5a ,0xdd ,0x77 ,0x51 , + }, + }, + + [CRYPTO_MODE_AES_CS2 ] = { + .min_version =0x65 , + .test[2 ].outlen =31 , .test[2 ].data = {0xae ,0xe7 ,0x1e ,0xa5 , +0x41 ,0xd7 ,0xae ,0x4b ,0xeb ,0x60 ,0xbe ,0xcc ,0x59 , +0x3f ,0xb6 ,0x63 ,0x0a ,0x94 ,0x0b ,0xb5 ,0x41 ,0x6e , +0xf0 ,0x45 ,0xf1 ,0xc3 ,0x94 ,0x58 ,0xc6 ,0x53 ,0xea , + }, + .test[3 ].outlen =31 , .test[3 ].data = {0x2e ,0x84 ,0xcb ,0x12 , +0xa3 ,0x59 ,0x17 ,0xb0 ,0x9e ,0x25 ,0xa2 ,0xa2 ,0x3d , +0xf1 ,0x9f ,0xdc ,0x00 ,0x60 ,0xbf ,0xfe ,0x46 ,0x83 , +0x4b ,0xb8 ,0xda ,0x5c ,0xf9 ,0xa6 ,0x1f ,0xf2 ,0x20 , + }, + .test[4 ].outlen =31 , .test[4 ].data = {0xcd ,0xfc ,0x25 ,0x35 , +0x31 ,0x0b ,0xf5 ,0x6b ,0x2e ,0xb7 ,0x8a ,0xa2 ,0x5a , +0xdd ,0x77 ,0x51 ,0x5a ,0x6e ,0x04 ,0x57 ,0x08 ,0xfb , +0x71 ,0x96 ,0xf0 ,0x2e ,0x55 ,0x3d ,0x02 ,0xc3 ,0xa6 , + }, + }, + + [CRYPTO_MODE_AES_CS3 ] = { + .min_version =0x65 , + .test[2 ].outlen =31 , .test[2 ].data = {0xae ,0xe7 ,0x1e ,0xa5 , +0x41 ,0xd7 ,0xae ,0x4b ,0xeb ,0x60 ,0xbe ,0xcc ,0x59 , +0x3f ,0xb6 ,0x63 ,0x0a ,0x94 ,0x0b ,0xb5 ,0x41 ,0x6e , +0xf0 ,0x45 ,0xf1 ,0xc3 ,0x94 ,0x58 ,0xc6 ,0x53 ,0xea , + }, + .test[3 ].outlen =31 , .test[3 ].data = {0x2e ,0x84 ,0xcb ,0x12 , +0xa3 ,0x59 ,0x17 ,0xb0 ,0x9e ,0x25 ,0xa2 ,0xa2 ,0x3d , +0xf1 ,0x9f ,0xdc ,0x00 ,0x60 ,0xbf ,0xfe ,0x46 ,0x83 , +0x4b ,0xb8 ,0xda ,0x5c ,0xf9 ,0xa6 ,0x1f ,0xf2 ,0x20 , + }, + .test[4 ].outlen =31 , .test[4 ].data = {0xcd ,0xfc ,0x25 ,0x35 , +0x31 ,0x0b ,0xf5 ,0x6b ,0x2e ,0xb7 ,0x8a ,0xa2 ,0x5a , +0xdd ,0x77 ,0x51 ,0x5a ,0x6e ,0x04 ,0x57 ,0x08 ,0xfb , +0x71 ,0x96 ,0xf0 ,0x2e ,0x55 ,0x3d ,0x02 ,0xc3 ,0xa6 , + }, + }, + + [CRYPTO_MODE_MULTI2_ECB ] = { + .min_version =0x65 , + .test[0 ].outlen =0 + }, + + [CRYPTO_MODE_MULTI2_CBC ] = { + .min_version =0x65 , + .test[0 ].outlen =0 + }, + + [CRYPTO_MODE_MULTI2_OFB ] = { + .min_version =0x65 , + .test[0 ].outlen =0 + }, + + [CRYPTO_MODE_MULTI2_CFB ] = { + .min_version =0x65 , + .test[0 ].outlen =0 + }, + + [CRYPTO_MODE_3DES_CBC ] = { + .min_version =0x65 , + .test[3 ].outlen =16 , .test[3 ].data = {0x58 ,0xed ,0x24 ,0x8f , +0x77 ,0xf6 ,0xb1 ,0x9e ,0x47 ,0xd9 ,0xb7 ,0x4a ,0x4f , +0x5a ,0xe6 ,0x6d , } + }, + + [CRYPTO_MODE_3DES_ECB ] = { + .min_version =0x65 , + .test[3 ].outlen =16 , .test[3 ].data = {0x89 ,0x4b ,0xc3 ,0x08 , +0x54 ,0x26 ,0xa4 ,0x41 ,0x89 ,0x4b ,0xc3 ,0x08 ,0x54 , +0x26 ,0xa4 ,0x41 , } + }, + + [CRYPTO_MODE_DES_CBC ] = { + .min_version =0x65 , + .test[1 ].outlen =16 , .test[1 ].data = {0xe1 ,0xb2 ,0x46 ,0xe5 , +0xa7 ,0xc7 ,0x4c ,0xbc ,0xd5 ,0xf0 ,0x8e ,0x25 ,0x3b , +0xfa ,0x23 ,0x80 , } + }, + + [CRYPTO_MODE_DES_ECB ] = { + .min_version =0x65 , + .test[1 ].outlen =16 , .test[1 ].data = {0xa5 ,0x17 ,0x3a , +0xd5 ,0x95 ,0x7b ,0x43 ,0x70 ,0xa5 ,0x17 ,0x3a ,0xd5 , +0x95 ,0x7b ,0x43 ,0x70 , } + }, + + [CRYPTO_MODE_KASUMI_ECB ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x04 ,0x7d ,0x5d , +0x2c ,0x8c ,0x2e ,0x91 ,0xb3 ,0x04 ,0x7d ,0x5d ,0x2c , +0x8c ,0x2e ,0x91 ,0xb3 , } + }, + + [CRYPTO_MODE_KASUMI_F8 ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0xfc ,0xf7 ,0x45 , +0xee ,0x1d ,0xbb ,0xa4 ,0x57 ,0xa7 ,0x45 ,0xdc ,0x6b , +0x2a ,0x1b ,0x50 ,0x88 , } + }, + + [CRYPTO_MODE_SNOW3G_UEA2 ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x95 ,0xd3 ,0xc8 , +0x13 ,0xc0 ,0x20 ,0x24 ,0xa3 ,0x76 ,0x24 ,0xd1 ,0x98 , +0xb6 ,0x67 ,0x4d ,0x4c , } + }, + + [CRYPTO_MODE_ZUC_UEA3 ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0xda ,0xdf ,0xb6 , +0xa2 ,0xac ,0x9d ,0xba ,0xfe ,0x18 ,0x9c ,0x0c ,0x75 , +0x79 ,0xc6 ,0xe0 ,0x4e , } + }, + + [CRYPTO_MODE_CHACHA20_STREAM ] = { + .min_version =0x65 , + .test[4 ].outlen =16 , .test[4 ].data = {0x55 ,0xdf ,0x91 , +0xe9 ,0x27 ,0x01 ,0x37 ,0x69 ,0xdb ,0x38 ,0xd4 ,0x28 , +0x01 ,0x79 ,0x76 ,0x64 } + }, + + [CRYPTO_MODE_CHACHA20_POLY1305 ] = { + .min_version =0x65 , + .test[4 ].outlen =16 , .test[4 ].data = {0x89 ,0xfb ,0x08 , +0x00 ,0x29 ,0x17 ,0xa5 ,0x40 ,0xb7 ,0x83 ,0x3f ,0xf3 , +0x98 ,0x1d ,0x0e ,0x63 } + }, + + [CRYPTO_MODE_SM4_ECB ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x1e ,0x96 ,0x34 , +0xb7 ,0x70 ,0xf9 ,0xae ,0xba ,0xa9 ,0x34 ,0x4f ,0x5a , +0xff ,0x9f ,0x82 ,0xa3 } + }, + + [CRYPTO_MODE_SM4_CBC ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x8f ,0x78 ,0x76 , +0x3e ,0xe0 ,0x60 ,0x13 ,0xe0 ,0xb7 ,0x62 ,0x2c ,0x42 , +0x8f ,0xd0 ,0x52 ,0x8d } + }, + + [CRYPTO_MODE_SM4_CFB ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x8f ,0x78 ,0x76 , +0x3e ,0xe0 ,0x60 ,0x13 ,0xe0 ,0xb7 ,0x62 ,0x2c ,0x42 , +0x8f ,0xd0 ,0x52 ,0x8d } + }, + + [CRYPTO_MODE_SM4_OFB ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x8f ,0x78 ,0x76 ,0x3e , +0xe0 ,0x60 ,0x13 ,0xe0 ,0xb7 ,0x62 ,0x2c ,0x42 ,0x8f , +0xd0 ,0x52 ,0x8d } + }, + + [CRYPTO_MODE_SM4_CTR ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x8f ,0x78 ,0x76 ,0x3e , +0xe0 ,0x60 ,0x13 ,0xe0 ,0xb7 ,0x62 ,0x2c ,0x42 ,0x8f , +0xd0 ,0x52 ,0x8d } + }, + + [CRYPTO_MODE_SM4_CCM ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x8e ,0x25 ,0x5a , +0x13 ,0xc7 ,0x43 ,0x4d ,0x95 ,0xef ,0x14 ,0x15 ,0x11 , +0xd0 ,0xb9 ,0x60 ,0x5b } + }, + + [CRYPTO_MODE_SM4_GCM ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x97 ,0x46 ,0xde , +0xfb ,0xc9 ,0x6a ,0x85 ,0x00 ,0xff ,0x9c ,0x74 ,0x4d , +0xd1 ,0xbb ,0xf9 ,0x66 } + }, + + [CRYPTO_MODE_SM4_F8 ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x77 ,0x30 ,0xff , +0x70 ,0x46 ,0xbc ,0xf4 ,0xe3 ,0x11 ,0xf6 ,0x27 ,0xe2 , +0xff ,0xd7 ,0xc4 ,0x2e } + }, + + [CRYPTO_MODE_SM4_XTS ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x05 ,0x3f ,0xb6 , +0xe9 ,0xb1 ,0xff ,0x09 ,0x4f ,0x9d ,0x69 ,0x4d ,0xc2 , +0xb6 ,0xa1 ,0x15 ,0xde } + }, + + [CRYPTO_MODE_SM4_CS1 ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0x8f ,0x78 ,0x76 , +0x3e ,0xe0 ,0x60 ,0x13 ,0xe0 ,0xb7 ,0x62 ,0x2c ,0x42 , +0x8f ,0xd0 ,0x52 ,0xa0 } + }, + + [CRYPTO_MODE_SM4_CS2 ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0xa0 ,0x1c ,0xfe , +0x91 ,0xaa ,0x7e ,0xf1 ,0x75 ,0x6a ,0xe8 ,0xbc ,0xe1 , +0x55 ,0x08 ,0xda ,0x71 } + }, + + [CRYPTO_MODE_SM4_CS3 ] = { + .min_version =0x65 , + .test[2 ].outlen =16 , .test[2 ].data = {0xa0 ,0x1c ,0xfe , +0x91 ,0xaa ,0x7e ,0xf1 ,0x75 ,0x6a ,0xe8 ,0xbc ,0xe1 , +0x55 ,0x08 ,0xda ,0x71 } + }, + +/* +* Hashes ... note they use the 2nd keysize +* array so the indices mean different sizes!!! +*/ + + [CRYPTO_MODE_HASH_MD5 ] = { + .min_version =0x65 , + .test[1 ].outlen =16 , .test[1 ].data = {0x70 ,0xbc ,0x8f ,0x4b , +0x72 ,0xa8 ,0x69 ,0x21 ,0x46 ,0x8b ,0xf8 ,0xe8 ,0x44 , +0x1d ,0xce ,0x51 , } + }, + + [CRYPTO_MODE_HMAC_MD5 ] = { + .min_version =0x65 , + .test[1 ].outlen =16 , .test[1 ].data = {0xb6 ,0x39 ,0xc8 ,0x73 , +0x16 ,0x38 ,0x61 ,0x8b ,0x70 ,0x79 ,0x72 ,0xaa ,0x6e , +0x96 ,0xcf ,0x90 , }, + .test[4 ].outlen =16 , .test[4 ].data = {0xb7 ,0x79 ,0x68 ,0xea , +0x17 ,0x32 ,0x1e ,0x32 ,0x13 ,0x90 ,0x6c ,0x2e ,0x9f , +0xd5 ,0xc8 ,0xb3 , }, + .test[5 ].outlen =16 , .test[5 ].data = {0x80 ,0x3e ,0x0a ,0x2f , +0x8a ,0xd8 ,0x31 ,0x8f ,0x8e ,0x12 ,0x28 ,0x86 ,0x22 , +0x59 ,0x6b ,0x05 , }, + .test[6 ].outlen =16 , .test[6 ].data = {0x48 ,0x8d ,0xca ,0xb3 , +0x65 ,0xf0 ,0x64 ,0x5f ,0xca ,0x8e ,0x22 ,0xf5 ,0x05 , +0xd7 ,0xa0 ,0x1c , }, + }, + + [CRYPTO_MODE_HASH_SHA1 ] = { + .min_version =0x65 , + .test[1 ].outlen =20 , .test[1 ].data = {0xde ,0x8a ,0x84 ,0x7b , +0xff ,0x8c ,0x34 ,0x3d ,0x69 ,0xb8 ,0x53 ,0xa2 ,0x15 , +0xe6 ,0xee ,0x77 ,0x5e ,0xf2 ,0xef ,0x96 , } + }, + + [CRYPTO_MODE_HMAC_SHA1 ] = { + .min_version =0x65 , + .test[1 ].outlen =20 , .test[1 ].data = {0xf8 ,0x54 ,0x60 ,0x50 , +0x49 ,0x56 ,0xd1 ,0xcd ,0x55 ,0x5c ,0x5d ,0xcd ,0x24 , +0x33 ,0xbf ,0xdc ,0x5c ,0x99 ,0x54 ,0xc8 , }, + .test[4 ].outlen =20 , .test[4 ].data = {0x66 ,0x3f ,0x3a ,0x3c , +0x08 ,0xb6 ,0x87 ,0xb2 ,0xd3 ,0x0c ,0x5a ,0xa7 ,0xcc , +0x5c ,0xc3 ,0x99 ,0xb2 ,0xb4 ,0x58 ,0x55 , }, + .test[5 ].outlen =20 , .test[5 ].data = {0x9a ,0x28 ,0x54 ,0x2f , +0xaf ,0xa7 ,0x0b ,0x37 ,0xbe ,0x2d ,0x3e ,0xd9 ,0xd4 , +0x70 ,0xbc ,0xdc ,0x0b ,0x54 ,0x20 ,0x06 , }, + .test[6 ].outlen =20 , .test[6 ].data = {0x1d ,0x8e ,0x20 ,0xcd , +0x5e ,0x6b ,0x4e ,0x32 ,0x64 ,0x8e ,0x99 ,0xfb ,0xa3 , +0x7e ,0x74 ,0xb4 ,0x9c ,0x0c ,0x00 ,0x9d , }, + }, + + [CRYPTO_MODE_HASH_SHA224 ] = { + .min_version =0x65 , + .test[1 ].outlen =28 , .test[1 ].data = {0xb3 ,0x38 ,0xc7 ,0x6b , +0xcf ,0xfa ,0x1a ,0x0b ,0x3e ,0xad ,0x8d ,0xe5 ,0x8d , +0xfb ,0xff ,0x47 ,0xb6 ,0x3a ,0xb1 ,0x15 ,0x0e ,0x10 , +0xd8 ,0xf1 ,0x7f ,0x2b ,0xaf ,0xdf , } + }, + + [CRYPTO_MODE_HMAC_SHA224 ] = { + .min_version =0x65 , + .test[1 ].outlen =28 , .test[1 ].data = {0xf3 ,0xb4 ,0x33 ,0x78 , +0x53 ,0x4c ,0x0c ,0x4a ,0x1e ,0x31 ,0xc2 ,0xce ,0xda , +0xc8 ,0xfe ,0x74 ,0x4a ,0xd2 ,0x9b ,0x7c ,0x1d ,0x2f , +0x5e ,0xa1 ,0xaa ,0x31 ,0xb9 ,0xf5 , }, + .test[4 ].outlen =28 , .test[4 ].data = {0x4b ,0x6b ,0x3f ,0x9a , +0x66 ,0x47 ,0x45 ,0xe2 ,0x60 ,0xc9 ,0x53 ,0x86 ,0x7a , +0x34 ,0x65 ,0x7d ,0xe2 ,0x24 ,0x06 ,0xcc ,0xf9 ,0x17 , +0x20 ,0x5d ,0xc2 ,0xb6 ,0x97 ,0x9a , }, + .test[5 ].outlen =28 , .test[5 ].data = {0x90 ,0xb0 ,0x6e ,0xee , +0x21 ,0x57 ,0x38 ,0xc7 ,0x65 ,0xbb ,0x9a ,0xf5 ,0xb4 , +0x31 ,0x0a ,0x0e ,0xe5 ,0x64 ,0xc4 ,0x49 ,0x9d ,0xbd , +0xe9 ,0xf7 ,0xac ,0x9f ,0xf8 ,0x05 , }, + .test[6 ].outlen =28 , .test[6 ].data = {0x5a ,0x1f ,0x21 ,0xaf , +0xd5 ,0x8a ,0x54 ,0x5e ,0x74 ,0xd7 ,0x21 ,0x76 ,0x25 , +0x06 ,0x70 ,0x81 ,0x3e ,0x51 ,0xef ,0x38 ,0xdc ,0x78 , +0x97 ,0x54 ,0xe6 ,0xb3 ,0xa4 ,0x3e , }, + }, + + [CRYPTO_MODE_HASH_SHA256 ] = { + .min_version =0x65 , + .test[1 ].outlen =32 , .test[1 ].data = {0x66 ,0x68 ,0x7a ,0xad , +0xf8 ,0x62 ,0xbd ,0x77 ,0x6c ,0x8f ,0xc1 ,0x8b ,0x8e , +0x9f ,0x8e ,0x20 ,0x08 ,0x97 ,0x14 ,0x85 ,0x6e ,0xe2 , +0x33 ,0xb3 ,0x90 ,0x2a ,0x59 ,0x1d ,0x0d ,0x5f ,0x29 , +0x25 , } + }, + + [CRYPTO_MODE_HMAC_SHA256 ] = { + .min_version =0x65 , + .test[1 ].outlen =32 , .test[1 ].data = {0x75 ,0x40 ,0x84 ,0x49 , +0x54 ,0x0a ,0xf9 ,0x80 ,0x99 ,0xeb ,0x93 ,0x6b ,0xf6 , +0xd3 ,0xff ,0x41 ,0x05 ,0x47 ,0xcc ,0x82 ,0x62 ,0x76 , +0x32 ,0xf3 ,0x43 ,0x74 ,0x70 ,0x54 ,0xe2 ,0x3b ,0xc0 , +0x90 , }, + .test[4 ].outlen =32 , .test[4 ].data = {0x41 ,0x6c ,0x53 ,0x92 , +0xb9 ,0xf3 ,0x6d ,0xf1 ,0x88 ,0xe9 ,0x0e ,0xb1 ,0x4d , +0x17 ,0xbf ,0x0d ,0xa1 ,0x90 ,0xbf ,0xdb ,0x7f ,0x1f , +0x49 ,0x56 ,0xe6 ,0xe5 ,0x66 ,0xa5 ,0x69 ,0xc8 ,0xb1 , +0x5c , }, + .test[5 ].outlen =32 , .test[5 ].data = {0x49 ,0x1f ,0x58 ,0x3b , +0x05 ,0xe2 ,0x3a ,0x72 ,0x1d ,0x11 ,0x6d ,0xc1 ,0x08 , +0xa0 ,0x3f ,0x30 ,0x37 ,0x98 ,0x36 ,0x8a ,0x49 ,0x4c , +0x21 ,0x1d ,0x56 ,0xa5 ,0x2a ,0xf3 ,0x68 ,0x28 ,0xb7 , +0x69 , }, + .test[6 ].outlen =32 , .test[6 ].data = {0x76 ,0xf8 ,0x88 ,0xed , +0x39 ,0xed ,0xf8 ,0xe0 ,0x31 ,0x68 ,0x3a ,0x33 ,0xcf , +0xaf ,0x20 ,0x62 ,0x96 ,0xdc ,0x06 ,0xf9 ,0xa9 ,0xb1 , +0xfe ,0x88 ,0x25 ,0xef ,0x96 ,0x69 ,0xa0 ,0x66 ,0x1e , +0x53 , }, + }, + + [CRYPTO_MODE_HASH_SHA384 ] = { + .min_version =0x65 , + .test[1 ].outlen =48 , .test[1 ].data = {0xa3 ,0x8f ,0xff ,0x4b , +0xa2 ,0x6c ,0x15 ,0xe4 ,0xac ,0x9c ,0xde ,0x8c ,0x03 , +0x10 ,0x3a ,0xc8 ,0x90 ,0x80 ,0xfd ,0x47 ,0x54 ,0x5f , +0xde ,0x94 ,0x46 ,0xc8 ,0xf1 ,0x92 ,0x72 ,0x9e ,0xab , +0x7b ,0xd0 ,0x3a ,0x4d ,0x5c ,0x31 ,0x87 ,0xf7 ,0x5f , +0xe2 ,0xa7 ,0x1b ,0x0e ,0xe5 ,0x0a ,0x4a ,0x40 , } + }, + + [CRYPTO_MODE_HMAC_SHA384 ] = { + .min_version =0x65 , + .test[1 ].outlen =48 , .test[1 ].data = {0x6c ,0xd8 ,0x89 ,0xa0 , +0xca ,0x54 ,0xa6 ,0x1d ,0x24 ,0xc4 ,0x1d ,0xa1 ,0x77 , +0x50 ,0xd6 ,0xf2 ,0xf3 ,0x43 ,0x23 ,0x0d ,0xb1 ,0xf5 , +0xf7 ,0xfc ,0xc0 ,0x8c ,0xf6 ,0xdf ,0x3c ,0x61 ,0xfc , +0x8a ,0xb9 ,0xda ,0x12 ,0x75 ,0x97 ,0xac ,0x51 ,0x88 , +0x59 ,0x19 ,0x44 ,0x13 ,0xc0 ,0x78 ,0xa5 ,0xa8 , }, + .test[4 ].outlen =48 , .test[4 ].data = {0x0c ,0x91 ,0x36 ,0x46 , +0xd9 ,0x17 ,0x81 ,0x46 ,0x1d ,0x42 ,0xb1 ,0x00 ,0xaa , +0xfa ,0x26 ,0x92 ,0x9f ,0x05 ,0xc0 ,0x91 ,0x8e ,0x20 , +0xd7 ,0x75 ,0x9d ,0xd2 ,0xc8 ,0x9b ,0x02 ,0x18 ,0x20 , +0x1f ,0xdd ,0xa3 ,0x32 ,0xe3 ,0x1e ,0xa4 ,0x2b ,0xc3 , +0xc8 ,0xb9 ,0xb1 ,0x53 ,0x4e ,0x6a ,0x49 ,0xd2 , }, + .test[5 ].outlen =48 , .test[5 ].data = {0x84 ,0x78 ,0xd2 ,0xf1 , +0x44 ,0x95 ,0x6a ,0x22 ,0x2d ,0x08 ,0x19 ,0xe8 ,0xea , +0x61 ,0xb4 ,0x86 ,0xe8 ,0xc6 ,0xb0 ,0x40 ,0x51 ,0x28 , +0x22 ,0x54 ,0x48 ,0xc0 ,0x70 ,0x09 ,0x81 ,0xf9 ,0xf5 , +0x47 ,0x9e ,0xb3 ,0x2c ,0x69 ,0x19 ,0xd5 ,0x8d ,0x03 , +0x5d ,0x24 ,0xca ,0x90 ,0xa6 ,0x9d ,0x80 ,0x2a , }, + .test[6 ].outlen =48 , .test[6 ].data = {0x0e ,0x68 ,0x17 ,0x31 , +0x01 ,0xa8 ,0x28 ,0x0a ,0x4e ,0x47 ,0x22 ,0xa6 ,0x89 , +0xf0 ,0xc6 ,0xcd ,0x4e ,0x8c ,0x19 ,0x4c ,0x44 ,0x3d , +0xb5 ,0xa5 ,0xf9 ,0xfe ,0xea ,0xc7 ,0x84 ,0x0b ,0x57 , +0x0d ,0xd4 ,0xe4 ,0x8a ,0x3f ,0x68 ,0x31 ,0x20 ,0xd9 , +0x1f ,0xc4 ,0xa3 ,0x76 ,0xcf ,0xdd ,0x07 ,0xa6 , }, + }, + + [CRYPTO_MODE_HASH_SHA512 ] = { + .min_version =0x65 , + .test[1 ].outlen =64 , .test[1 ].data = {0x50 ,0x46 ,0xad ,0xc1 , +0xdb ,0xa8 ,0x38 ,0x86 ,0x7b ,0x2b ,0xbb ,0xfd ,0xd0 , +0xc3 ,0x42 ,0x3e ,0x58 ,0xb5 ,0x79 ,0x70 ,0xb5 ,0x26 , +0x7a ,0x90 ,0xf5 ,0x79 ,0x60 ,0x92 ,0x4a ,0x87 ,0xf1 , +0x96 ,0x0a ,0x6a ,0x85 ,0xea ,0xa6 ,0x42 ,0xda ,0xc8 , +0x35 ,0x42 ,0x4b ,0x5d ,0x7c ,0x8d ,0x63 ,0x7c ,0x00 , +0x40 ,0x8c ,0x7a ,0x73 ,0xda ,0x67 ,0x2b ,0x7f ,0x49 , +0x85 ,0x21 ,0x42 ,0x0b ,0x6d ,0xd3 , } + }, + + [CRYPTO_MODE_HMAC_SHA512 ] = { + .min_version =0x65 , + .test[1 ].outlen =64 , .test[1 ].data = {0xec ,0xfd ,0x83 ,0x74 , +0xc8 ,0xa9 ,0x2f ,0xd7 ,0x71 ,0x94 ,0xd1 ,0x1e ,0xe7 , +0x0f ,0x0f ,0x5e ,0x11 ,0x29 ,0x58 ,0xb8 ,0x36 ,0xc6 , +0x39 ,0xbc ,0xd6 ,0x88 ,0x6e ,0xdb ,0xc8 ,0x06 ,0x09 , +0x30 ,0x27 ,0xaa ,0x69 ,0xb9 ,0x2a ,0xd4 ,0x67 ,0x06 , +0x5c ,0x82 ,0x8e ,0x90 ,0xe9 ,0x3e ,0x55 ,0x88 ,0x7d , +0xb2 ,0x2b ,0x48 ,0xa2 ,0x28 ,0x92 ,0x6c ,0x0f ,0xf1 , +0x57 ,0xb5 ,0xd0 ,0x06 ,0x1d ,0xf3 , }, + .test[4 ].outlen =64 , .test[4 ].data = {0x47 ,0x88 ,0x91 ,0xe9 , +0x12 ,0x3e ,0xfd ,0xdc ,0x26 ,0x29 ,0x08 ,0xd6 ,0x30 , +0x8f ,0xcc ,0xb6 ,0x93 ,0x30 ,0x58 ,0x69 ,0x4e ,0x81 , +0xee ,0x9d ,0xb6 ,0x0f ,0xc5 ,0x54 ,0xe6 ,0x7c ,0x84 , +0xc5 ,0xbc ,0x89 ,0x99 ,0xf0 ,0xf3 ,0x7f ,0x6f ,0x3f , +0xf5 ,0x04 ,0x2c ,0xdf ,0x76 ,0x72 ,0x6a ,0xbe ,0x28 , +0x3b ,0xb8 ,0x05 ,0xb3 ,0x47 ,0x45 ,0xf5 ,0x7f ,0xb1 , +0x21 ,0x2d ,0xe0 ,0x8d ,0x1e ,0x29 , }, + .test[5 ].outlen =64 , .test[5 ].data = {0x7e ,0x55 ,0xda ,0x88 , +0x28 ,0xc1 ,0x6e ,0x9a ,0x6a ,0x99 ,0xa0 ,0x37 ,0x68 , +0xf0 ,0x28 ,0x5e ,0xe2 ,0xbe ,0x00 ,0xac ,0x76 ,0x89 , +0x76 ,0xcc ,0x5d ,0x98 ,0x1b ,0x32 ,0x1a ,0x14 ,0xc4 , +0x2e ,0x9c ,0xe4 ,0xf3 ,0x3f ,0x5f ,0xa0 ,0xae ,0x95 , +0x16 ,0x0b ,0x14 ,0xf5 ,0xf5 ,0x45 ,0x29 ,0xd8 ,0xc9 , +0x43 ,0xf2 ,0xa9 ,0xbc ,0xdc ,0x03 ,0x81 ,0x0d ,0x36 , +0x2f ,0xb1 ,0x22 ,0xe8 ,0x13 ,0xf8 , }, + .test[6 ].outlen =64 , .test[6 ].data = {0x5d ,0xc4 ,0x80 ,0x90 , +0x6b ,0x00 ,0x17 ,0x04 ,0x34 ,0x63 ,0x93 ,0xf1 ,0xad , +0x9a ,0x3e ,0x13 ,0x37 ,0x6b ,0x86 ,0xd7 ,0xc4 ,0x2b , +0x22 ,0x9c ,0x2e ,0xf2 ,0x1d ,0xde ,0x35 ,0x39 ,0x03 , +0x3f ,0x2b ,0x3a ,0xc3 ,0x49 ,0xb3 ,0x32 ,0x86 ,0x63 , +0x6b ,0x0f ,0x27 ,0x95 ,0x97 ,0xe5 ,0xe7 ,0x2b ,0x9b , +0x80 ,0xea ,0x94 ,0x4d ,0x84 ,0x2e ,0x39 ,0x44 ,0x8f , +0x56 ,0xe3 ,0xcd ,0xa7 ,0x12 ,0x3e , }, + }, + + [CRYPTO_MODE_HASH_SHA512_224 ] = { + .min_version =0x65 , + .test[1 ].outlen =28 , .test[1 ].data = {0x9e ,0x7d ,0x60 ,0x80 , +0xde ,0xf4 ,0xe1 ,0xcc ,0xf4 ,0xae ,0xaa ,0xc6 ,0xf7 , +0xfa ,0xd0 ,0x08 ,0xd0 ,0x60 ,0xa6 ,0xcf ,0x87 ,0x06 , +0x20 ,0x38 ,0xd6 ,0x16 ,0x67 ,0x74 , } + }, + + [CRYPTO_MODE_HMAC_SHA512_224 ] = { + .min_version =0x65 , + .test[1 ].outlen =28 , .test[1 ].data = {0xff ,0xfb ,0x43 ,0x27 , +0xdd ,0x2e ,0x39 ,0xa0 ,0x18 ,0xa8 ,0xaf ,0xde ,0x84 , +0x0b ,0x5d ,0x0f ,0x3d ,0xdc ,0xc6 ,0x17 ,0xd1 ,0xb6 , +0x2f ,0x8c ,0xf8 ,0x7e ,0x34 ,0x34 , }, + .test[4 ].outlen =28 , .test[4 ].data = {0x00 ,0x19 ,0xe2 ,0x2d , +0x44 ,0x80 ,0x2d ,0xd8 ,0x1c ,0x57 ,0xf5 ,0x57 ,0x92 , +0x08 ,0x13 ,0xe7 ,0x9d ,0xbb ,0x2b ,0xc2 ,0x8d ,0x77 , +0xc1 ,0xff ,0x71 ,0x4c ,0xf0 ,0xa9 , }, + .test[5 ].outlen =28 , .test[5 ].data = {0x6a ,0xc4 ,0xa8 ,0x73 , +0x21 ,0x54 ,0xb2 ,0x82 ,0xee ,0x89 ,0x8d ,0x45 ,0xd4 , +0xe3 ,0x76 ,0x3e ,0x04 ,0x03 ,0xc9 ,0x71 ,0xee ,0x01 , +0x25 ,0xd2 ,0x7b ,0xa1 ,0x20 ,0xc4 , }, + .test[6 ].outlen =28 , .test[6 ].data = {0x0f ,0x98 ,0x15 ,0x9b , +0x11 ,0xca ,0x60 ,0xc7 ,0x82 ,0x39 ,0x1a ,0x50 ,0x8c , +0xe4 ,0x79 ,0xfa ,0xa8 ,0x0e ,0xc7 ,0x12 ,0xfd ,0x8c , +0x9c ,0x99 ,0x7a ,0xe8 ,0x7e ,0x92 , }, + }, + + [CRYPTO_MODE_HASH_SHA512_256 ] = { + .min_version =0x65 , + .test[1 ].outlen =32 , .test[1 ].data = {0xaf ,0x13 ,0xc0 ,0x48 , +0x99 ,0x12 ,0x24 ,0xa5 ,0xe4 ,0xc6 ,0x64 ,0x44 ,0x6b , +0x68 ,0x8a ,0xaf ,0x48 ,0xfb ,0x54 ,0x56 ,0xdb ,0x36 , +0x29 ,0x60 ,0x1b ,0x00 ,0xec ,0x16 ,0x0c ,0x74 ,0xe5 , +0x54 , } + }, + + [CRYPTO_MODE_HMAC_SHA512_256 ] = { + .min_version =0x65 , + .test[1 ].outlen =32 , .test[1 ].data = {0x3a ,0x2c ,0xd0 ,0x2b , +0xfa ,0xa6 ,0x72 ,0xe4 ,0xf1 ,0xab ,0x0a ,0x3e ,0x70 , +0xe4 ,0x88 ,0x1a ,0x92 ,0xe1 ,0x3b ,0x64 ,0x5a ,0x9b , +0xed ,0xb3 ,0x97 ,0xc0 ,0x17 ,0x1f ,0xd4 ,0x05 ,0xf1 , +0x72 , }, + .test[4 ].outlen =32 , .test[4 ].data = {0x6f ,0x2d ,0xae ,0xc6 , +0xe4 ,0xa6 ,0x5b ,0x52 ,0x0f ,0x26 ,0x16 ,0xf6 ,0xa9 , +0xc1 ,0x23 ,0xc2 ,0xb3 ,0x67 ,0xfc ,0x69 ,0xac ,0x73 , +0x87 ,0xa2 ,0x5b ,0x6c ,0x44 ,0xad ,0xc5 ,0x26 ,0x2b , +0x10 , }, + .test[5 ].outlen =32 , .test[5 ].data = {0x63 ,0xe7 ,0xb8 ,0xd1 , +0x76 ,0x33 ,0x56 ,0x29 ,0xba ,0x99 ,0x86 ,0x42 ,0x0d , +0x4f ,0xf7 ,0x54 ,0x8c ,0xb9 ,0x39 ,0xf2 ,0x72 ,0x1d , +0x0e ,0x9d ,0x80 ,0x67 ,0xd9 ,0xab ,0x15 ,0xb0 ,0x68 , +0x18 , }, + .test[6 ].outlen =32 , .test[6 ].data = {0x64 ,0x78 ,0x56 ,0xd7 , +0xaf ,0x5b ,0x56 ,0x08 ,0xf1 ,0x44 ,0xf7 ,0x4f ,0xa1 , +0xa1 ,0x13 ,0x79 ,0x6c ,0xb1 ,0x31 ,0x11 ,0xf3 ,0x75 , +0xf4 ,0x8c ,0xb4 ,0x9f ,0xbf ,0xb1 ,0x60 ,0x38 ,0x3d , +0x28 , }, + }, + + [CRYPTO_MODE_MAC_XCBC ] = { + .min_version =0x65 , + .test[1 ].outlen =16 , .test[1 ].data = {0x35 ,0xd9 ,0xdc ,0xdb , +0x82 ,0x9f ,0xec ,0x33 ,0x52 ,0xe7 ,0xbf ,0x10 ,0xb8 , +0x4b ,0xe4 ,0xa5 , }, + .test[3 ].outlen =16 , .test[3 ].data = {0x39 ,0x6f ,0x99 ,0xb5 , +0x43 ,0x33 ,0x67 ,0x4e ,0xd4 ,0x45 ,0x8f ,0x80 ,0x77 , +0xe4 ,0xd4 ,0x14 , }, + .test[4 ].outlen =16 , .test[4 ].data = {0x73 ,0xd4 ,0x7c ,0x38 , +0x37 ,0x4f ,0x73 ,0xd0 ,0x78 ,0xa8 ,0xc6 ,0xec ,0x05 , +0x67 ,0xca ,0x5e , }, + }, + + [CRYPTO_MODE_MAC_CMAC ] = { + .min_version =0x65 , + .test[1 ].outlen =16 , .test[1 ].data = {0x15 ,0xbe ,0x1b ,0xfd , +0x8c ,0xbb ,0xaf ,0x8b ,0x51 ,0x9a ,0x64 ,0x3b ,0x1b , +0x46 ,0xc1 ,0x8f , }, + .test[3 ].outlen =16 , .test[3 ].data = {0x4e ,0x02 ,0xd6 ,0xec , +0x92 ,0x75 ,0x88 ,0xb4 ,0x3e ,0x83 ,0xa7 ,0xac ,0x32 , +0xb6 ,0x2b ,0xdb , }, + .test[4 ].outlen =16 , .test[4 ].data = {0xa7 ,0x37 ,0x01 ,0xbe , +0xe8 ,0xce ,0xed ,0x44 ,0x49 ,0x4a ,0xbb ,0xf6 ,0x9e , +0xd9 ,0x31 ,0x3e , }, + }, + + [CRYPTO_MODE_MAC_KASUMI_F9 ] = { + .min_version =0x65 , + .test[1 ].outlen =4 , .test[1 ].data = {0x5b ,0x26 ,0x81 ,0x06 } + }, + + [CRYPTO_MODE_MAC_SNOW3G_UIA2 ] = { + .min_version =0x65 , + .test[1 ].outlen =4 , .test[1 ].data = {0x08 ,0xed ,0x2c ,0x76 , } + }, + + [CRYPTO_MODE_MAC_ZUC_UIA3 ] = { + .min_version =0x65 , + .test[1 ].outlen =4 , .test[1 ].data = {0x6a ,0x2b ,0x4c ,0x3a , } + }, + + [CRYPTO_MODE_MAC_POLY1305 ] = { + .min_version =0x65 , + .test[4 ].outlen =16 , .test[4 ].data = {0xef ,0x91 ,0x06 ,0x4e , +0xce ,0x99 ,0x9c ,0x4e ,0xfd ,0x05 ,0x6a ,0x8c ,0xe6 , +0x18 ,0x23 ,0xad } + }, + + [CRYPTO_MODE_SSLMAC_MD5 ] = { + .min_version =0x65 , + .test[1 ].outlen =16 , .test[1 ].data = {0x0e ,0xf4 ,0xca ,0x32 , +0x32 ,0x40 ,0x1d ,0x1b ,0xaa ,0xfd ,0x6d ,0xa8 ,0x01 , +0x79 ,0xed ,0xcd , }, + }, + + [CRYPTO_MODE_SSLMAC_SHA1 ] = { + .min_version =0x65 , + .test[2 ].outlen =20 , .test[2 ].data = {0x05 ,0x9d ,0x99 ,0xb4 , +0xf3 ,0x03 ,0x1e ,0xc5 ,0x24 ,0xbf ,0xec ,0xdf ,0x64 , +0x8e ,0x37 ,0x2e ,0xf0 ,0xef ,0x93 ,0xa0 , }, + }, + + [CRYPTO_MODE_HASH_CRC32 ] = { + .min_version =0x65 , + .test[0 ].outlen =0 + }, + + [CRYPTO_MODE_MAC_MICHAEL ] = { + .min_version =0x65 , + .test[0 ].outlen =8 , .test[0 ].data = {0x16 ,0xfb ,0xa0 , +0x0e ,0xe2 ,0xab ,0x6c ,0x97 , } + }, + + [CRYPTO_MODE_HASH_SHA3_224 ] = { + .min_version =0x65 , + .test[1 ].outlen =28 , .test[1 ].data = {0x73 ,0xe0 ,0x87 , +0xae ,0x12 ,0x71 ,0xb2 ,0xc5 ,0xf6 ,0x85 ,0x46 ,0xc9 , +0x3a ,0xb4 ,0x25 ,0x14 ,0xa6 ,0x9e ,0xef ,0x25 ,0x2b , +0xfd ,0xd1 ,0x37 ,0x55 ,0x74 ,0x8a ,0x00 , } + }, + + [CRYPTO_MODE_HASH_SHA3_256 ] = { + .min_version =0x65 , + .test[1 ].outlen =32 , .test[1 ].data = {0x9e ,0x62 ,0x91 ,0x97 , +0x0c ,0xb4 ,0x4d ,0xd9 ,0x40 ,0x08 ,0xc7 ,0x9b ,0xca , +0xf9 ,0xd8 ,0x6f ,0x18 ,0xb4 ,0xb4 ,0x9b ,0xa5 ,0xb2 , +0xa0 ,0x47 ,0x81 ,0xdb ,0x71 ,0x99 ,0xed ,0x3b ,0x9e , +0x4e , } + }, + + [CRYPTO_MODE_HASH_SHA3_384 ] = { + .min_version =0x65 , + .test[1 ].outlen =48 , .test[1 ].data = {0x4b ,0xda ,0xab , +0xf7 ,0x88 ,0xd3 ,0xad ,0x1a ,0xd8 ,0x3d ,0x6d ,0x93 , +0xc7 ,0xe4 ,0x49 ,0x37 ,0xc2 ,0xe6 ,0x49 ,0x6a ,0xf2 , +0x3b ,0xe3 ,0x35 ,0x4d ,0x75 ,0x69 ,0x87 ,0xf4 ,0x51 , +0x60 ,0xfc ,0x40 ,0x23 ,0xbd ,0xa9 ,0x5e ,0xcd ,0xcb , +0x3c ,0x7e ,0x31 ,0xa6 ,0x2f ,0x72 ,0x6d ,0x70 ,0x2c , + } + }, + + [CRYPTO_MODE_HASH_SHA3_512 ] = { + .min_version =0x65 , + .test[1 ].outlen =64 , .test[1 ].data = {0xad ,0x56 ,0xc3 ,0x5c , +0xab ,0x50 ,0x63 ,0xb9 ,0xe7 ,0xea ,0x56 ,0x83 ,0x14 , +0xec ,0x81 ,0xc4 ,0x0b ,0xa5 ,0x77 ,0xaa ,0xe6 ,0x30 , +0xde ,0x90 ,0x20 ,0x04 ,0x00 ,0x9e ,0x88 ,0xf1 ,0x8d , +0xa5 ,0x7b ,0xbd ,0xfd ,0xaa ,0xa0 ,0xfc ,0x18 ,0x9c , +0x66 ,0xc8 ,0xd8 ,0x53 ,0x24 ,0x8b ,0x6b ,0x11 ,0x88 , +0x44 ,0xd5 ,0x3f ,0x7d ,0x0b ,0xa1 ,0x1d ,0xe0 ,0xf3 , +0xbf ,0xaf ,0x4c ,0xdd ,0x9b ,0x3f , } + }, + + [CRYPTO_MODE_HASH_SHAKE128 ] = { + .min_version =0x65 , + .test[4 ].outlen =16 , .test[4 ].data = {0x24 ,0xa7 ,0xca , +0x4b ,0x75 ,0xe3 ,0x89 ,0x8d ,0x4f ,0x12 ,0xe7 ,0x4d , +0xea ,0x8c ,0xbb ,0x65 } + }, + + [CRYPTO_MODE_HASH_SHAKE256 ] = { + .min_version =0x65 , + .test[4 ].outlen =32 , .test[4 ].data = {0xf5 ,0x97 ,0x7c , +0x82 ,0x83 ,0x54 ,0x6a ,0x63 ,0x72 ,0x3b ,0xc3 ,0x1d , +0x26 ,0x19 ,0x12 ,0x4f , +0x11 ,0xdb ,0x46 ,0x58 ,0x64 ,0x33 ,0x36 ,0x74 ,0x1d , +0xf8 ,0x17 ,0x57 ,0xd5 ,0xad ,0x30 ,0x62 } + }, + + [CRYPTO_MODE_HASH_CSHAKE128 ] = { + .min_version =0x65 , + .test[1 ].outlen =16 , .test[1 ].data = {0xe0 ,0x6f ,0xd8 , +0x50 ,0x57 ,0x6f ,0xe4 ,0xfa ,0x7e ,0x13 ,0x42 ,0xb5 , +0xf8 ,0x13 ,0xeb ,0x23 } + }, + + [CRYPTO_MODE_HASH_CSHAKE256 ] = { + .min_version =0x65 , + .test[1 ].outlen =32 , .test[1 ].data = {0xf3 ,0xf2 ,0xb5 , +0x47 ,0xf2 ,0x16 ,0xba ,0x6f ,0x49 ,0x83 ,0x3e ,0xad , +0x1e ,0x46 ,0x85 ,0x54 , +0xd0 ,0xd7 ,0xf9 ,0xc6 ,0x7e ,0xe9 ,0x27 ,0xc6 ,0xc3 , +0xc3 ,0xdb ,0x91 ,0xdb ,0x97 ,0x04 ,0x0f } + }, + + [CRYPTO_MODE_MAC_KMAC128 ] = { + .min_version =0x65 , + .test[1 ].outlen =16 , .test[1 ].data = {0x6c ,0x3f ,0x29 , +0xfe ,0x01 ,0x96 ,0x59 ,0x36 ,0xb7 ,0xae ,0xb7 ,0xff , +0x71 ,0xe0 ,0x3d ,0xff }, + .test[4 ].outlen =16 , .test[4 ].data = {0x58 ,0xd9 ,0x8d , +0xe8 ,0x1f ,0x64 ,0xb4 ,0xa3 ,0x9f ,0x63 ,0xaf ,0x21 , +0x99 ,0x03 ,0x97 ,0x06 }, + .test[5 ].outlen =16 , .test[5 ].data = {0xf8 ,0xf9 ,0xb7 , +0xa4 ,0x05 ,0x3d ,0x90 ,0x7c ,0xf2 ,0xa1 ,0x7c ,0x34 , +0x39 ,0xc2 ,0x87 ,0x4b }, + .test[6 ].outlen =16 , .test[6 ].data = {0xef ,0x4a ,0xd5 , +0x1d ,0xd7 ,0x83 ,0x56 ,0xd3 ,0xa8 ,0x3c ,0xf5 ,0xf8 , +0xd1 ,0x12 ,0xf4 ,0x44 } + }, + + [CRYPTO_MODE_MAC_KMAC256 ] = { + .min_version =0x65 , + .test[1 ].outlen =32 , .test[1 ].data = {0x0d ,0x86 ,0xfa , +0x92 ,0x92 ,0xe4 ,0x77 ,0x24 ,0x6a ,0xcc ,0x79 ,0xa0 , +0x1e ,0xb4 ,0xc3 ,0xac , +0xfc ,0x56 ,0xbc ,0x63 ,0xcc ,0x1b ,0x6e ,0xf6 ,0xc8 , +0x99 ,0xa5 ,0x3a ,0x38 ,0x14 ,0xa2 ,0x40 }, + .test[4 ].outlen =32 , .test[4 ].data = {0xad ,0x99 ,0xed , +0x20 ,0x1f ,0xbe ,0x45 ,0x07 ,0x3d ,0xf4 ,0xae ,0x9f , +0xc2 ,0xd8 ,0x06 ,0x18 , +0x31 ,0x4e ,0x8c ,0xb6 ,0x33 ,0xe8 ,0x31 ,0x36 ,0x00 , +0xdd ,0x42 ,0x20 ,0xda ,0x2b ,0xd5 ,0x2b }, + .test[5 ].outlen =32 , .test[5 ].data = {0xf9 ,0xc6 ,0x2b , +0x17 ,0xa0 ,0x04 ,0xd9 ,0xf2 ,0x6c ,0xbf ,0x5d ,0xa5 , +0x9a ,0xd7 ,0x36 ,0x1d , +0xad ,0x66 ,0x6b ,0x3d ,0xb1 ,0x52 ,0xd3 ,0x81 ,0x39 , +0x20 ,0xd4 ,0xf0 ,0x43 ,0x72 ,0x2c ,0xb7 }, + .test[6 ].outlen =32 , .test[6 ].data = {0xcc ,0x89 ,0xe4 , +0x05 ,0x58 ,0x77 ,0x38 ,0x8b ,0x18 ,0xa0 ,0x7c ,0x8d , +0x20 ,0x99 ,0xea ,0x6e , +0x6b ,0xe9 ,0xf7 ,0x0c ,0xe1 ,0xe5 ,0xce ,0xbc ,0x55 , +0x4c ,0x80 ,0xa5 ,0xdc ,0xae ,0xf7 ,0x94 } + }, + + [CRYPTO_MODE_MAC_KMACXOF128 ] = { + .min_version =0x65 , + .test[1 ].outlen =16 , .test[1 ].data = {0x84 ,0x07 ,0x89 , +0x29 ,0xa7 ,0xf4 ,0x98 ,0x91 ,0xf5 ,0x64 ,0x61 ,0x8d , +0xa5 ,0x93 ,0x00 ,0x31 }, + .test[4 ].outlen =16 , .test[4 ].data = {0xf0 ,0xa4 ,0x1b , +0x98 ,0x0f ,0xb3 ,0xf2 ,0xbd ,0xc3 ,0xfc ,0x64 ,0x1f , +0x73 ,0x1f ,0xd4 ,0x74 }, + .test[5 ].outlen =16 , .test[5 ].data = {0xa5 ,0xc5 ,0xad , +0x25 ,0x59 ,0xf1 ,0x5d ,0xea ,0x5b ,0x18 ,0x0a ,0x52 , +0xce ,0x6c ,0xc0 ,0x88 }, + .test[6 ].outlen =16 , .test[6 ].data = {0x1a ,0x81 ,0xdd , +0x81 ,0x47 ,0x89 ,0xf4 ,0x15 ,0xcc ,0x18 ,0x05 ,0x81 , +0xe3 ,0x95 ,0x21 ,0xc3 } + }, + + [CRYPTO_MODE_MAC_KMACXOF256 ] = { + .min_version =0x65 , + .test[1 ].outlen =32 , .test[1 ].data = {0xff ,0x85 ,0xe9 , +0x61 ,0x67 ,0x96 ,0x35 ,0x58 ,0x33 ,0x38 ,0x2c ,0xe8 , +0x25 ,0x77 ,0xbe ,0x63 , +0xd5 ,0x2c ,0xa7 ,0xef ,0xce ,0x9b ,0x63 ,0x71 ,0xb2 , +0x09 ,0x7c ,0xd8 ,0x60 ,0x4e ,0x5a ,0xfa }, + .test[4 ].outlen =32 , .test[4 ].data = {0x86 ,0x89 ,0xc2 , +0x4a ,0xe8 ,0x18 ,0x46 ,0x10 ,0x6b ,0xf2 ,0x09 ,0xd7 , +0x37 ,0x83 ,0xab ,0x77 , +0xb5 ,0xce ,0x7c ,0x96 ,0x9c ,0xfa ,0x0f ,0xa0 ,0xd8 , +0xde ,0xb5 ,0xb7 ,0xc6 ,0xcd ,0xa9 ,0x8f }, + .test[5 ].outlen =32 , .test[5 ].data = {0x4d ,0x71 ,0x81 , +0x5a ,0x5f ,0xac ,0x3b ,0x29 ,0xf2 ,0x5f ,0xb6 ,0x56 , +0xf1 ,0x76 ,0xcf ,0xdc , +0x51 ,0x56 ,0xd7 ,0x3c ,0x47 ,0xec ,0x6d ,0xea ,0xc6 , +0x3e ,0x54 ,0xe7 ,0x6f ,0xdc ,0xe8 ,0x39 }, + .test[6 ].outlen =32 , .test[6 ].data = {0x5f ,0xc5 ,0xe1 , +0x1e ,0xe7 ,0x55 ,0x0f ,0x62 ,0x71 ,0x29 ,0xf3 ,0x0a , +0xb3 ,0x30 ,0x68 ,0x06 , +0xea ,0xec ,0xe4 ,0x37 ,0x17 ,0x37 ,0x2d ,0x5d ,0x64 , +0x09 ,0x70 ,0x63 ,0x94 ,0x80 ,0x9b ,0x80 } + }, + + [CRYPTO_MODE_HASH_SM3 ] = { + .min_version =0x65 , + .test[1 ].outlen =32 , .test[1 ].data = {0xe0 ,0xba ,0xb8 , +0xf4 ,0xd8 ,0x17 ,0x2b ,0xa2 ,0x45 ,0x19 ,0x0d ,0x13 , +0xc9 ,0x41 ,0x17 ,0xe9 , +0x3b ,0x82 ,0x16 ,0x6c ,0x25 ,0xb2 ,0xb6 ,0x98 ,0x83 , +0x35 ,0x0c ,0x19 ,0x2c ,0x90 ,0x51 ,0x40 }, + .test[4 ].outlen =32 , .test[4 ].data = {0xe0 ,0xba ,0xb8 , +0xf4 ,0xd8 ,0x17 ,0x2b ,0xa2 ,0x45 ,0x19 ,0x0d ,0x13 , +0xc9 ,0x41 ,0x17 ,0xe9 , +0x3b ,0x82 ,0x16 ,0x6c ,0x25 ,0xb2 ,0xb6 ,0x98 ,0x83 , +0x35 ,0x0c ,0x19 ,0x2c ,0x90 ,0x51 ,0x40 }, + .test[5 ].outlen =32 , .test[5 ].data = {0xe0 ,0xba ,0xb8 , +0xf4 ,0xd8 ,0x17 ,0x2b ,0xa2 ,0x45 ,0x19 ,0x0d ,0x13 , +0xc9 ,0x41 ,0x17 ,0xe9 , +0x3b ,0x82 ,0x16 ,0x6c ,0x25 ,0xb2 ,0xb6 ,0x98 ,0x83 , +0x35 ,0x0c ,0x19 ,0x2c ,0x90 ,0x51 ,0x40 }, + .test[6 ].outlen =32 , .test[6 ].data = {0xe0 ,0xba ,0xb8 , +0xf4 ,0xd8 ,0x17 ,0x2b ,0xa2 ,0x45 ,0x19 ,0x0d ,0x13 , +0xc9 ,0x41 ,0x17 ,0xe9 , +0x3b ,0x82 ,0x16 ,0x6c ,0x25 ,0xb2 ,0xb6 ,0x98 ,0x83 , +0x35 ,0x0c ,0x19 ,0x2c ,0x90 ,0x51 ,0x40 } + }, + + [CRYPTO_MODE_HMAC_SM3 ] = { + .min_version =0x65 , + .test[1 ].outlen =32 , .test[1 ].data = {0x68 ,0xf0 ,0x65 , +0xd8 ,0xd8 ,0xc9 ,0xc2 ,0x0e ,0x10 ,0xfd ,0x52 ,0x7c , +0xf2 ,0xd7 ,0x42 ,0xd3 , +0x08 ,0x44 ,0x22 ,0xbc ,0xf0 ,0x9d ,0xcc ,0x34 ,0x7b , +0x76 ,0x13 ,0x91 ,0xba ,0xce ,0x4d ,0x17 }, + .test[4 ].outlen =32 , .test[4 ].data = {0xd8 ,0xab ,0x2a , +0x7b ,0x56 ,0x21 ,0xb1 ,0x59 ,0x64 ,0xb2 ,0xa3 ,0xd6 , +0x72 ,0xb3 ,0x95 ,0x81 , +0xa0 ,0xcd ,0x96 ,0x47 ,0xf0 ,0xbc ,0x8c ,0x16 ,0x5b , +0x9b ,0x7d ,0x2f ,0x71 ,0x3f ,0x23 ,0x19 }, + .test[5 ].outlen =32 , .test[5 ].data = {0xa0 ,0xd1 ,0xd5 , +0xa0 ,0x9e ,0x4c ,0xca ,0x8c ,0x7b ,0xe0 ,0x8f ,0x70 , +0x92 ,0x2e ,0x3f ,0x4c , +0xa0 ,0xca ,0xef ,0xa1 ,0x86 ,0x9d ,0xb2 ,0xe1 ,0xc5 , +0xfa ,0x9d ,0xfa ,0xbc ,0x11 ,0xcb ,0x1f }, + .test[6 ].outlen =32 , .test[6 ].data = {0xa0 ,0xd1 ,0xd5 , +0xa0 ,0x9e ,0x4c ,0xca ,0x8c ,0x7b ,0xe0 ,0x8f ,0x70 , +0x92 ,0x2e ,0x3f ,0x4c , +0xa0 ,0xca ,0xef ,0xa1 ,0x86 ,0x9d ,0xb2 ,0xe1 ,0xc5 , +0xfa ,0x9d ,0xfa ,0xbc ,0x11 ,0xcb ,0x1f } + }, + + [CRYPTO_MODE_MAC_SM4_XCBC ] = { + .min_version =0x65 , + .test[1 ].outlen =16 , .test[1 ].data = {0xb5 ,0x42 ,0xd0 ,0xbf , +0x93 ,0x57 ,0x65 ,0x69 ,0x32 ,0xb1 ,0x4e ,0x4d ,0x8e , +0xe4 ,0xae ,0x51 , }, + .test[4 ].outlen =16 , .test[4 ].data = {0x69 ,0xaf ,0x45 , +0xe6 ,0x0c ,0x78 ,0x71 ,0x7e ,0x44 ,0x6c ,0xfe ,0x68 , +0xd4 ,0xfe ,0x20 ,0x8b }, + .test[5 ].outlen =16 , .test[5 ].data = {0x69 ,0xaf ,0x45 , +0xe6 ,0x0c ,0x78 ,0x71 ,0x7e ,0x44 ,0x6c ,0xfe ,0x68 , +0xd4 ,0xfe ,0x20 ,0x8b }, + .test[6 ].outlen =16 , .test[6 ].data = {0x69 ,0xaf ,0x45 , +0xe6 ,0x0c ,0x78 ,0x71 ,0x7e ,0x44 ,0x6c ,0xfe ,0x68 , +0xd4 ,0xfe ,0x20 ,0x8b } + }, + + [CRYPTO_MODE_MAC_SM4_CMAC ] = { + .min_version =0x65 , + .test[1 ].outlen =16 , .test[1 ].data = {0x3d ,0x19 ,0x10 ,0x8e , +0x5d ,0xd2 ,0x2e ,0x96 ,0x92 ,0x1c ,0xeb ,0xea ,0x1d , +0xb5 ,0x1a ,0x4b , }, + .test[4 ].outlen =16 , .test[4 ].data = {0x36 ,0xbe ,0xec , +0x03 ,0x9c ,0xc7 ,0x0c ,0x28 ,0x23 ,0xdd ,0x71 ,0x8b , +0x3c ,0xbd ,0x7f ,0x37 }, + .test[5 ].outlen =16 , .test[5 ].data = {0x36 ,0xbe ,0xec , +0x03 ,0x9c ,0xc7 ,0x0c ,0x28 ,0x23 ,0xdd ,0x71 ,0x8b , +0x3c ,0xbd ,0x7f ,0x37 }, + .test[6 ].outlen =16 , .test[6 ].data = {0x36 ,0xbe ,0xec , +0x03 ,0x9c ,0xc7 ,0x0c ,0x28 ,0x23 ,0xdd ,0x71 ,0x8b , +0x3c ,0xbd ,0x7f ,0x37 } + }, +}; +#endif +int spacc_sg_to_ddt (struct device *dev,struct scatterlist *sg,int nbytes,struct pdu_ddt *ddt,int dma_direction) {
@@ -561,6 +1477,281 @@ int spacc_close(struct spacc_device *dev, int handle)return spacc_job_release (dev, handle); } +#if IS_ENABLED (CONFIG_CRYPTO_DEV_SPACC_AUTODETECT ) +static int spacc_set_auxinfo (struct spacc_device *spacc,int jobid, +u32 direction,u32 bitsize) +{ +int ret =0 ; +struct spacc_job *job; + +if (jobid <0 || jobid >=SPACC_MAX_JOBS ) +return -EINVAL ; + + job = &spacc->job[jobid]; + job->auxinfo_dir = direction; + job->auxinfo_bit_align = bitsize; + +return ret; +} + +static int spacc_check_modes (struct spacc_device *spacc,int algo_mode, +int keysz_idx,void *virt,char *key, +struct pdu_ddt *ddt) +{ +int enc; +int hash; +int aadlen; +int ivsize; +int proclen; +int rc =0 ; +int err =0 ; +bool output_zero_len; +bool output_mismatch; +struct spacc_job *job; + +if ((template[algo_mode] & (1 << keysz_idx)) ==0 ) +return 0 ; + +if (!testdata[algo_mode].test[keysz_idx].outlen) { + spacc->config.modes[algo_mode] &= ~(1 << keysz_idx); +return 0 ; + } + +/* +* Testing keysizes[keysz_idx] with algo 'algo_mode' which +* should match the ENUMs above +*/ +if (template[algo_mode] &128 ) { + enc =0 ; + hash = algo_mode; + }else { + enc = algo_mode; + hash =0 ; + } + + rc =spacc_open (spacc, enc, hash,-1 ,0 ,NULL ,NULL ); +if (rc <0 ) { + spacc->config.modes[algo_mode] &= ~(1 << keysz_idx); +return 0 ; + } + +if (template[algo_mode] &128 ) { +/* hash-only: digest written at offset 0 in dst, proclen=32 */ +spacc_set_operation (spacc, rc,OP_ENCRYPT ,ICV_HASH , +IP_ICV_OFFSET ,0 , + testdata[algo_mode].test[keysz_idx].outlen,0 ); + }else { +spacc_set_operation (spacc, rc,OP_ENCRYPT ,0 ,IP_ICV_APPEND ,0 , +0 ,0 ); + } + +/* if this is a hash or mac */ +if (template[algo_mode] &128 ) { +const unsigned char *hash_key = key; +unsigned char local_key[128 ]; +int klen; + +switch (algo_mode) { +case CRYPTO_MODE_HASH_CSHAKE128 : +case CRYPTO_MODE_HASH_CSHAKE256 : +case CRYPTO_MODE_MAC_KMAC128 : +case CRYPTO_MODE_MAC_KMAC256 : +case CRYPTO_MODE_MAC_KMACXOF128 : +case CRYPTO_MODE_MAC_KMACXOF256 : +/* +* Special initial bytes to encode +* length for cust strings +*/ +memcpy (local_key, key,sizeof (local_key)); + local_key[0 ] =0x01 ; + local_key[1 ] =0x70 ; + hash_key = local_key; +break ; + } + + klen = keysizes[1 ][keysz_idx] + + ((algo_mode ==CRYPTO_MODE_MAC_XCBC || + algo_mode ==CRYPTO_MODE_MAC_SM4_XCBC ) ?32 :0 ); + +if (klen >sizeof (local_key)) { + spacc->config.modes[algo_mode] &= ~(1 << keysz_idx); +spacc_close (spacc, rc); +return 0 ; + } + +spacc_write_context (spacc, rc,SPACC_HASH_OPERATION , + hash_key, klen, hash_key,16 ); + }else { +u32 keysize; + + ivsize =16 ; + keysize = keysizes[0 ][keysz_idx]; + +switch (algo_mode) { +case CRYPTO_MODE_CHACHA20_STREAM : +case CRYPTO_MODE_AES_CCM : +case CRYPTO_MODE_SM4_CCM : + ivsize =16 ; +break ; +case CRYPTO_MODE_SM4_GCM : +case CRYPTO_MODE_CHACHA20_POLY1305 : +case CRYPTO_MODE_AES_GCM : + ivsize =12 ; +break ; +case CRYPTO_MODE_KASUMI_ECB : +case CRYPTO_MODE_KASUMI_F8 : +case CRYPTO_MODE_3DES_CBC : +case CRYPTO_MODE_3DES_ECB : +case CRYPTO_MODE_DES_CBC : +case CRYPTO_MODE_DES_ECB : + ivsize =8 ; +break ; +case CRYPTO_MODE_SM4_XTS : +case CRYPTO_MODE_AES_XTS : + keysize <<=1 ; +break ; + } + +spacc_write_context (spacc, rc,SPACC_CRYPTO_OPERATION , + key, keysize, key, ivsize); + } + +spacc_set_key_exp (spacc, rc); + +switch (algo_mode) { +case CRYPTO_MODE_ZUC_UEA3 : +case CRYPTO_MODE_SNOW3G_UEA2 : +case CRYPTO_MODE_MAC_SNOW3G_UIA2 : +case CRYPTO_MODE_MAC_ZUC_UIA3 : +case CRYPTO_MODE_KASUMI_F8 : +spacc_set_auxinfo (spacc, rc,0 ,0 ); +break ; +case CRYPTO_MODE_MAC_KASUMI_F9 : +spacc_set_auxinfo (spacc, rc,0 ,8 ); +break ; + } + +memset (virt,0 ,256 ); + + aadlen =16 ; + proclen =32 ; + +if (!enc) { + aadlen =0 ; + proclen =32 ; + } + +switch (algo_mode) { +case CRYPTO_MODE_SM4_CS1 : +case CRYPTO_MODE_SM4_CS2 : +case CRYPTO_MODE_SM4_CS3 : +case CRYPTO_MODE_AES_CS1 : +case CRYPTO_MODE_AES_CS2 : +case CRYPTO_MODE_AES_CS3 : + proclen =31 ; + fallthrough; +case CRYPTO_MODE_SM4_XTS : +case CRYPTO_MODE_AES_XTS : + aadlen =0 ; + } + + err =spacc_packet_enqueue_ddt (spacc, rc, ddt, ddt, proclen,0 , + aadlen,0 ,0 ,0 , false); + job = &spacc->job[rc]; + +if (err ==0 ) { +/* +* No timeout, not interruptible: this only returns once +* job_done is actually true, i.e. the hardware has +* genuinely relinquished the job. That guarantees it is +* always safe to close the job/context and (via the +* caller) free the DMA buffer immediately below -- +* there is no "unconfirmed" case left to handle. +* +* Tradeoff: if the hardware ever genuinely fails to +* complete a submitted job, this hangs here +* unkillably (TASK_UNINTERRUPTIBLE, no timeout) for the +* rest of probe. Accepted deliberately in place of the +* abandoned-job/UAF risk of giving up early with no +* hardware cancel available. +*/ +wait_event (job->waitq,smp_load_acquire (&job->job_done)); + + job->job_done =0 ; + err = job->job_err; + } + + output_zero_len = !testdata[algo_mode].test[keysz_idx].outlen; + output_mismatch =memcmp (testdata[algo_mode].test[keysz_idx].data, virt, + testdata[algo_mode].test[keysz_idx].outlen); + +if (err !=0 || output_zero_len || output_mismatch) + spacc->config.modes[algo_mode] &= ~(1 << keysz_idx); + +spacc_close (spacc, rc); + +return 0 ; +} + +int spacc_autodetect (struct spacc_device *spacc) +{ +int x, y; +void *virt; +dma_addr_t dma; +struct pdu_ddt ddt; +unsigned char key[128 ]; + + spacc->autodetect = true; + + virt =dma_alloc_coherent (spacc->dptr,SPACC_TEST_DMA_BUFF_SIZE , + &dma,GFP_KERNEL ); +if (!virt) +return -ENOMEM ; + +/* DDT is guaranteed by the dma_type gate in spacc_init() */ +if (pdu_ddt_init (spacc->dptr, &ddt,1 )) { +dma_free_coherent (spacc->dptr,SPACC_TEST_DMA_BUFF_SIZE , + virt, dma); +return -EIO ; + } + +pdu_ddt_add (spacc->dptr, &ddt, dma,SPACC_TEST_DMA_BUFF_SIZE ); + +/* loop through and create a key for autodetect */ +for (x =0 ; x <sizeof (key); x++) + key[x] = x &0xff ; + +for (x =0 ; x <ARRAY_SIZE (template); x++) { +if (!template[x] || + spacc->config.version < testdata[x].min_version) { + spacc->config.modes[x] =0 ; +continue ; + } + + spacc->config.modes[x] = template[x]; +for (y =0 ; y <ARRAY_SIZE (keysizes[0 ]); y++) { +/* +* spacc_check_modes() now always returns 0 -- +* it only comes back once the job is confirmed +* done, closes itself, and disables the mode +* bit internally on any failure/mismatch. +*/ +spacc_check_modes (spacc, x, y, virt, key, &ddt); + } + +if (!(spacc->config.modes[x] &0x7F )) + spacc->config.modes[x] &= ~128 ; + } + +pdu_ddt_free (&ddt); +dma_free_coherent (spacc->dptr,SPACC_TEST_DMA_BUFF_SIZE , virt, dma); + spacc->autodetect = false; + +return 0 ; +} + +#else +static void spacc_static_modes (struct spacc_device *spacc,int x,int y) {/* disable the algos that are not supported here */
@@ -597,6 +1788,7 @@ int spacc_static_config(struct spacc_device *spacc) return 0; } +#endif int spacc_clone_handle (struct spacc_device *spacc,int old_handle,void *cbdata)
--
2.25.1
PATCH v27 4/4 crypto: spacc - Add SPAcc Kconfig and Makefile
In reply to Pavitrakumar ManagutteAdd Makefile and Kconfig for SPAcc driver.
--- drivers/crypto/Kconfig | 1 + drivers/crypto/Makefile | 1 + drivers/crypto/dwc-spacc/Kconfig | 64 +++++++++++++++++++++++++++++++ drivers/crypto/dwc-spacc/Makefile | 7 ++++ 4 files changed, 73 insertions(+) create mode 100644 drivers/crypto/dwc-spacc/Kconfig create mode 100644 drivers/crypto/dwc-spacc/Makefile
drivers/crypto/Kconfig +1 -0
@@ -734,6 +734,7 @@ 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"
drivers/crypto/Makefile +1 -0
@@ -40,6 +40,7 @@ obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/ obj-y += 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/
drivers/crypto/dwc-spacc/Kconfig new file +64 -0
64 lines not on this page · raw message
drivers/crypto/dwc-spacc/Makefile new file +7 -0
@@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_CRYPTO_DEV_SPACC) += snps-spacc.o + +snps-spacc-y := spacc_hal.o spacc_core.o \ +spacc_manager.o spacc_interrupt.o spacc_device.o + +snps-spacc-$(CONFIG_CRYPTO_DEV_SPACC_HASH) += spacc_ahash.o
--
2.25.1
[email protected]
AI reviewRe: [PATCH v27 4/4] crypto: spacc - Add SPAcc Kconfig and Makefile
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: - [High] crypto: spacc - CRYPTO_AHASH_ALG_BLOCK_ONLY inflates statesize past limit - [High] crypto: spacc…
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] crypto: spacc - CRYPTO_AHASH_ALG_BLOCK_ONLY inflates statesize past limit
- [High] crypto: spacc - use-after-free in spacc_hash_exit_tfm() and spacc_hash_setkey() --
commit c650f028323b3118ec1e7adfa8aafa6c190ddd1d
Author: Pavitrakumar Managutte <[email protected]>
crypto: spacc - Add SPAcc Kconfig and Makefile
This commit adds the Kconfig and Makefile for the Synopsys DesignWare SPAcc driver and hooks them into drivers/crypto/.
[ ... ]
drivers/crypto/dwc-spacc/Makefile line 7
Quoted 13 lines
drivers/crypto/dwc-spacc/Makefile new file +7
-0@@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_CRYPTO_DEV_SPACC) += snps-spacc.o + +snps-spacc-y := spacc_hal.o spacc_core.o \ +spacc_manager.o spacc_interrupt.o spacc_device.o + +snps-spacc-$(CONFIG_CRYPTO_DEV_SPACC_HASH) += spacc_ahash.o
[Severity: High]
As reported by Sashiko on v26 [1], enabling spacc_ahash.o builds spacc_hash_template and spacc_register_hash() in drivers/crypto/dwc-spacc/spacc_ahash.c with both CRYPTO_AHASH_ALG_BLOCK_ONLY and statesize set to HASH_MAX_STATESIZE:
drivers/crypto/dwc-spacc/spacc_ahash.c:spacc_hash_template:
.halg.base = {
...
.cra_flags = CRYPTO_ALG_TYPE_AHASH |
CRYPTO_ALG_ASYNC |
CRYPTO_AHASH_ALG_BLOCK_ONLY
},drivers/crypto/dwc-spacc/spacc_ahash.c:spacc_register_hash() {
...
salg->alg.hash.base.halg.digestsize = salg->mode->hashlen;
salg->alg.hash.base.halg.statesize = HASH_MAX_STATESIZE;
rc = crypto_engine_register_ahash(&salg->alg.hash);
}When crypto_engine_register_ahash() -> crypto_register_ahash() -> ahash_prepare_alg() sees CRYPTO_AHASH_ALG_BLOCK_ONLY, it adds cra_blocksize + 1 to statesize:
crypto/ahash.c:ahash_prepare_alg() {
...
if (base->cra_flags & CRYPTO_AHASH_ALG_BLOCK_ONLY) {
...
alg->halg.statesize += base->cra_blocksize + 1;
}
}This inflates crypto_ahash_statesize(tfm) to HASH_MAX_STATESIZE + cra_blocksize + 1 for every registered SPAcc hash algorithm.
As a result, any virtual-address request reaching ahash_do_req_chain() (such as the generic hmac template wrapping an unkeyed SPAcc hash like sha3-256) hits:
if (crypto_ahash_statesize(tfm) > HASH_MAX_STATESIZE) return -ENOSYS;
and fails with -ENOSYS. In addition, callers allocating a buffer of size HASH_MAX_STATESIZE and calling crypto_ahash_export() will overflow that buffer by cra_blocksize + 1 bytes when crypto_ahash_export() appends the block-only partial block buffer at out + ss - plen.
Furthermore, spacc_hash_init(), spacc_hash_update(), spacc_hash_final(), and spacc_hash_finup() delegate directly to the software fallback fbreq rather than performing block-only hardware hashing:
drivers/crypto/dwc-spacc/spacc_ahash.c:spacc_hash_update() {
...
rc = crypto_ahash_import(fbreq, ctx->state_buffer);
if (!rc)
rc = crypto_ahash_update(fbreq);
if (!rc)
rc = crypto_ahash_export(fbreq, ctx->state_buffer);
HASH_REQUEST_ZERO(fbreq);
return rc;
}Because spacc_hash_update() consumes trailing bytes into ctx->state_buffer via the fallback and returns 0 instead of returning the unprocessed tail length expected by ahash_update_finish(), partial blocks are split between the core block-only buffer and ctx->state_buffer.
Should CRYPTO_AHASH_ALG_BLOCK_ONLY be dropped from spacc_hash_template?
[Severity: High]
Can spacc_hash_exit_tfm() and spacc_hash_setkey() race with spacc_crypto_remove() and trigger a use-after-free on priv->spacc?
In drivers/crypto/dwc-spacc/spacc_device.c, spacc_crypto_remove() notes that sysfs unbind does not wait for existing transforms to be freed. At the end of spacc_crypto_remove(), spacc_remove() frees spacc->ctx and spacc->job via spacc_fini() before clearing drvdata:
drivers/crypto/dwc-spacc/spacc_device.c:spacc_crypto_remove() {
...
spacc_remove(pdev);
platform_set_drvdata(pdev, NULL);
}However, in drivers/crypto/dwc-spacc/spacc_ahash.c, neither spacc_hash_exit_tfm() nor spacc_hash_setkey() -> spacc_hash_commit_key() checks priv->removing or serializes against spacc_crypto_remove():
drivers/crypto/dwc-spacc/spacc_ahash.c:spacc_hash_exit_tfm() {
struct spacc_crypto_ctx *tctx = crypto_ahash_ctx(tfm);
struct spacc_priv *priv = dev_get_drvdata(tctx->dev);
if (priv && tctx->handle >= 0)
spacc_close(&priv->spacc, tctx->handle);
...
}drivers/crypto/dwc-spacc/spacc_ahash.c:spacc_hash_setkey() {
...
struct spacc_priv *priv = dev_get_drvdata(salg->dev);
...
if (!spacc_is_mode_keysize_supported(&priv->spacc, salg->mode->id,
klen, 1)) {
...
ret = spacc_hash_commit_key(tfm, priv, key, keylen, keybuf, klen);
}If an existing transform calls crypto_free_ahash() or crypto_ahash_setkey() concurrently with sysfs unbind and reads priv before platform_set_drvdata(pdev, NULL), won't spacc_close() or spacc_is_mode_keysize_supported() access spacc->job, spacc->ctx, and devm-managed priv after they have been freed?
[1] https://lore.kernel.org/r/[email protected]
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=4