summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-11-13 16:01:07 +0000
committerMark Brown <broonie@kernel.org>2026-11-13 16:01:07 +0000
commitbb02ec4537b93865cbdb343cb385f613dc27fd48 (patch)
treeaff5ef867ae0dc7283a9c91e975e6163ef42f63b
parenta1905b52db599318f6803f181fda5dda4086337a (diff)
parentfd29be9b992511ff68d8a9c6f8a505d801e9f775 (diff)
downloadlinux-next-bb02ec4537b93865cbdb343cb385f613dc27fd48.tar.gz
linux-next-bb02ec4537b93865cbdb343cb385f613dc27fd48.zip
Merge branch 'master' of https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
-rw-r--r--Documentation/ABI/testing/sysfs-driver-qat4
-rw-r--r--Documentation/crypto/api-rng.rst17
-rw-r--r--Documentation/crypto/api-samples.rst37
-rw-r--r--Documentation/crypto/api.rst1
-rw-r--r--Documentation/crypto/architecture.rst8
-rw-r--r--Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml27
-rw-r--r--arch/arm/configs/am200epdkit_defconfig1
-rw-r--r--arch/arm/configs/spitz_defconfig1
-rw-r--r--arch/m68k/configs/amiga_defconfig1
-rw-r--r--arch/m68k/configs/apollo_defconfig1
-rw-r--r--arch/m68k/configs/atari_defconfig1
-rw-r--r--arch/m68k/configs/bvme6000_defconfig1
-rw-r--r--arch/m68k/configs/hp300_defconfig1
-rw-r--r--arch/m68k/configs/mac_defconfig1
-rw-r--r--arch/m68k/configs/multi_defconfig1
-rw-r--r--arch/m68k/configs/mvme147_defconfig1
-rw-r--r--arch/m68k/configs/mvme16x_defconfig1
-rw-r--r--arch/m68k/configs/q40_defconfig1
-rw-r--r--arch/m68k/configs/sun3_defconfig1
-rw-r--r--arch/m68k/configs/sun3x_defconfig1
-rw-r--r--arch/mips/configs/decstation_defconfig1
-rw-r--r--arch/mips/configs/decstation_r4k_defconfig1
-rw-r--r--arch/mips/configs/ip32_defconfig1
-rw-r--r--arch/mips/configs/rt305x_defconfig1
-rw-r--r--arch/mips/configs/xway_defconfig1
-rw-r--r--arch/powerpc/configs/44x/eiger_defconfig1
-rw-r--r--arch/powerpc/configs/44x/redwood_defconfig1
-rw-r--r--arch/s390/configs/debug_defconfig1
-rw-r--r--arch/s390/configs/defconfig1
-rw-r--r--arch/sh/configs/sh2007_defconfig1
-rw-r--r--arch/sh/configs/titan_defconfig1
-rw-r--r--arch/sparc/configs/sparc32_defconfig1
-rw-r--r--arch/x86/crypto/aria-avx.h3
-rw-r--r--arch/x86/crypto/aria_aesni_avx2_glue.c35
-rw-r--r--arch/x86/crypto/aria_aesni_avx_glue.c29
-rw-r--r--arch/x86/crypto/aria_gfni_avx512_glue.c8
-rw-r--r--crypto/Kconfig32
-rw-r--r--crypto/Makefile2
-rw-r--r--crypto/algif_rng.c109
-rw-r--r--crypto/arc4.c82
-rw-r--r--crypto/asymmetric_keys/selftest.c2
-rw-r--r--crypto/asymmetric_keys/x509_loader.c4
-rw-r--r--crypto/crypto_user.c2
-rw-r--r--crypto/drbg-testvecs.h228
-rw-r--r--crypto/drbg.c323
-rw-r--r--crypto/drbg.h20
-rw-r--r--crypto/ecc.c11
-rw-r--r--crypto/geniv.c2
-rw-r--r--crypto/jitterentropy-kcapi.c158
-rw-r--r--crypto/jitterentropy-kcapi.h17
-rw-r--r--crypto/lz4.c2
-rw-r--r--crypto/lz4hc.c2
-rw-r--r--crypto/lzo-rle.c2
-rw-r--r--crypto/lzo.c2
-rw-r--r--crypto/rng.c245
-rw-r--r--crypto/tcrypt.c19
-rw-r--r--crypto/testmgr.c109
-rw-r--r--crypto/testmgr.h280
-rw-r--r--crypto/zstd.c5
-rw-r--r--drivers/char/hw_random/cctrng.c51
-rw-r--r--drivers/char/hw_random/mtk-rng.c2
-rw-r--r--drivers/char/hw_random/octeon-rng.c1
-rw-r--r--drivers/crypto/atmel-i2c.c29
-rw-r--r--drivers/crypto/caam/jr.c11
-rw-r--r--drivers/crypto/gemini/sl3516-ce-core.c1
-rw-r--r--drivers/crypto/intel/keembay/keembay-ocs-aes-core.c3
-rw-r--r--drivers/crypto/intel/keembay/keembay-ocs-ecc.c7
-rw-r--r--drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c59
-rw-r--r--drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.h6
-rw-r--r--drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c38
-rw-r--r--drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.h1
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_accel_engine.c5
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_cfg_services.c3
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_cfg_services.h1
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_common_drv.h2
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_gen6_tl.c24
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_init.c8
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_rl.c15
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_rl.h1
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_rl_admin.c1
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_telemetry.c14
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_telemetry.h2
-rw-r--r--drivers/crypto/intel/qat/qat_common/qat_compression.c2
-rw-r--r--drivers/crypto/omap-aes.c8
-rw-r--r--drivers/crypto/qce/aead.c46
-rw-r--r--drivers/crypto/qce/cipher.h1
-rw-r--r--drivers/crypto/qce/common.h1
-rw-r--r--drivers/crypto/qce/sha.c62
-rw-r--r--drivers/crypto/qce/skcipher.c41
-rw-r--r--include/crypto/arc4.h3
-rw-r--r--include/crypto/internal/rng.h40
-rw-r--r--include/crypto/rng.h194
-rw-r--r--include/linux/crypto.h3
-rw-r--r--include/uapi/linux/cryptouser.h3
-rw-r--r--lib/lzo/lzo1x_compress.c1
95 files changed, 1077 insertions, 1466 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-qat b/Documentation/ABI/testing/sysfs-driver-qat
index b0561b9fc4eb..48e17de3e0fd 100644
--- a/Documentation/ABI/testing/sysfs-driver-qat
+++ b/Documentation/ABI/testing/sysfs-driver-qat
@@ -41,8 +41,8 @@ Description: (RW) Reports the current configuration of the QAT device.
Service combinations are permitted for all services except dcc.
On QAT GEN4 devices (qat_4xxx driver) a maximum of two services can be
- combined and on QAT GEN6 devices (qat_6xxx driver ) a maximum of three
- services can be combined.
+ combined. On QAT GEN5 devices (qat_420xx driver) and GEN6 devices
+ (qat_6xxx driver) a maximum of three services can be combined.
The order of services is not significant. For instance, sym;asym is
functionally equivalent to asym;sym.
diff --git a/Documentation/crypto/api-rng.rst b/Documentation/crypto/api-rng.rst
deleted file mode 100644
index 23a94c0b272e..000000000000
--- a/Documentation/crypto/api-rng.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-Random Number Generator (RNG)
-=============================
-
-Random Number Algorithm Definitions
------------------------------------
-
-.. kernel-doc:: include/crypto/rng.h
- :functions: rng_alg
-
-Crypto API Random Number API
-----------------------------
-
-.. kernel-doc:: include/crypto/rng.h
- :doc: Random number generator API
-
-.. kernel-doc:: include/crypto/rng.h
- :functions: crypto_alloc_rng crypto_rng_alg crypto_free_rng crypto_rng_generate crypto_rng_get_bytes crypto_rng_reset crypto_rng_seedsize
diff --git a/Documentation/crypto/api-samples.rst b/Documentation/crypto/api-samples.rst
index 388bb7d7a460..8816565dd046 100644
--- a/Documentation/crypto/api-samples.rst
+++ b/Documentation/crypto/api-samples.rst
@@ -148,40 +148,3 @@ Code Example For Use of Operational State Memory With SHASH
crypto_free_shash(alg);
return ret;
}
-
-
-Code Example For Random Number Generator Usage
-----------------------------------------------
-
-::
-
-
- static int get_random_numbers(u8 *buf, unsigned int len)
- {
- struct crypto_rng *rng = NULL;
- char *drbg = "stdrng";
- int ret;
-
- if (!buf || !len) {
- pr_debug("No output buffer provided\n");
- return -EINVAL;
- }
-
- rng = crypto_alloc_rng(drbg, 0, 0);
- if (IS_ERR(rng)) {
- pr_debug("could not allocate RNG handle for %s\n", drbg);
- return PTR_ERR(rng);
- }
-
- ret = crypto_rng_get_bytes(rng, buf, len);
- if (ret < 0)
- pr_debug("generation of random numbers failed\n");
- else if (ret == 0)
- pr_debug("RNG returned no data");
- else
- pr_debug("RNG returned %d bytes of data\n", ret);
-
- out:
- crypto_free_rng(rng);
- return ret;
- }
diff --git a/Documentation/crypto/api.rst b/Documentation/crypto/api.rst
index 8b2a90521886..bf5827eca88d 100644
--- a/Documentation/crypto/api.rst
+++ b/Documentation/crypto/api.rst
@@ -8,7 +8,6 @@ Programming Interface
api-skcipher
api-aead
api-digest
- api-rng
api-akcipher
api-sig
api-kpp
diff --git a/Documentation/crypto/architecture.rst b/Documentation/crypto/architecture.rst
index ec2e99d99aff..206cd9322dee 100644
--- a/Documentation/crypto/architecture.rst
+++ b/Documentation/crypto/architecture.rst
@@ -13,8 +13,6 @@ cipher types:
- Message digest, including keyed message digest
-- Random number generation
-
- User space interface
Ciphers And Templates
@@ -155,8 +153,6 @@ applicable to a cipher, it is not displayed:
- compression for compression type transformations
- - rng for random number generator
-
- kpp for a Key-agreement Protocol Primitive (KPP) cipher such as
an ECDH or DH implementation
@@ -166,8 +162,6 @@ applicable to a cipher, it is not displayed:
- ivsize: IV size in bytes
-- seedsize: required size of seed data for random number generator
-
- digestsize: output size of the message digest
- geniv: IV generator (obsolete)
@@ -208,8 +202,6 @@ the aforementioned cipher types:
- CRYPTO_ALG_TYPE_AHASH Asynchronous multi-block hash
-- CRYPTO_ALG_TYPE_RNG Random Number Generation
-
- CRYPTO_ALG_TYPE_AKCIPHER Asymmetric cipher
- CRYPTO_ALG_TYPE_SIG Asymmetric signature
diff --git a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
index 23bf98c2b9fa..b98c4c6b77f0 100644
--- a/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
+++ b/Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml
@@ -15,6 +15,9 @@ properties:
- enum:
- qcom,eliza-inline-crypto-engine
- qcom,hawi-inline-crypto-engine
+ - qcom,ipq5210-inline-crypto-engine
+ - qcom,ipq5424-inline-crypto-engine
+ - qcom,ipq9650-inline-crypto-engine
- qcom,kaanapali-inline-crypto-engine
- qcom,maili-inline-crypto-engine
- qcom,milos-inline-crypto-engine
@@ -81,7 +84,6 @@ allOf:
then:
required:
- - power-domains
- clock-names
properties:
clocks:
@@ -89,6 +91,29 @@ allOf:
clock-names:
minItems: 2
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - qcom,ipq5210-inline-crypto-engine
+ - qcom,ipq5424-inline-crypto-engine
+ - qcom,ipq9650-inline-crypto-engine
+ - qcom,kaanapali-inline-crypto-engine
+ - qcom,qcs8300-inline-crypto-engine
+ - qcom,sa8775p-inline-crypto-engine
+ - qcom,sc7180-inline-crypto-engine
+ - qcom,sc7280-inline-crypto-engine
+ - qcom,sm8450-inline-crypto-engine
+ - qcom,sm8550-inline-crypto-engine
+ - qcom,sm8650-inline-crypto-engine
+ - qcom,sm8750-inline-crypto-engine
+
+ then:
+ required:
+ - power-domains
+
examples:
- |
#include <dt-bindings/clock/qcom,sm8550-gcc.h>
diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig
index 61beac88e863..444091e601f2 100644
--- a/arch/arm/configs/am200epdkit_defconfig
+++ b/arch/arm/configs/am200epdkit_defconfig
@@ -85,7 +85,6 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_CRYPTO=y
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_ARC4=m
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index c7cf089001bf..6b988283bc7d 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -217,7 +217,6 @@ CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index 9c303ee2a4de..7eba56b1ae2d 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -526,7 +526,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_XTS=m
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index 1783ae09ed51..01e63ba7faa7 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -480,7 +480,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_XTS=m
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index 5f8c1eab65ed..8698aed36ede 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -505,7 +505,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_XTS=m
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
index 43cf1f3ca84f..36822436fab9 100644
--- a/arch/m68k/configs/bvme6000_defconfig
+++ b/arch/m68k/configs/bvme6000_defconfig
@@ -472,7 +472,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_XTS=m
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index b7be903e9ce9..e689c8b73399 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -482,7 +482,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_XTS=m
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index cda737fce9fe..b692fffeb675 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -501,7 +501,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_XTS=m
diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
index c1febb792413..f81db4a62098 100644
--- a/arch/m68k/configs/multi_defconfig
+++ b/arch/m68k/configs/multi_defconfig
@@ -591,7 +591,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_XTS=m
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
index 7d536ff9d1c7..2150c8e82850 100644
--- a/arch/m68k/configs/mvme147_defconfig
+++ b/arch/m68k/configs/mvme147_defconfig
@@ -472,7 +472,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_XTS=m
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
index f36b502021b4..bdd77765922d 100644
--- a/arch/m68k/configs/mvme16x_defconfig
+++ b/arch/m68k/configs/mvme16x_defconfig
@@ -473,7 +473,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_XTS=m
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index c632c25c0af3..42b05a629bf5 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -491,7 +491,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_XTS=m
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
index cf28894400a8..0b562b497b97 100644
--- a/arch/m68k/configs/sun3_defconfig
+++ b/arch/m68k/configs/sun3_defconfig
@@ -470,7 +470,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_XTS=m
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
index b3be0542a604..ad215cdfa0eb 100644
--- a/arch/m68k/configs/sun3x_defconfig
+++ b/arch/m68k/configs/sun3x_defconfig
@@ -470,7 +470,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_XTS=m
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 29915a002db1..e23784ae9636 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -178,7 +178,6 @@ CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST5=m
diff --git a/arch/mips/configs/decstation_r4k_defconfig b/arch/mips/configs/decstation_r4k_defconfig
index 7eef7a1bdc30..0a81d57ca9c1 100644
--- a/arch/mips/configs/decstation_r4k_defconfig
+++ b/arch/mips/configs/decstation_r4k_defconfig
@@ -178,7 +178,6 @@ CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST5=m
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 5ddbaa0aafaf..0c3bae4a7bac 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -162,7 +162,6 @@ CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_WP512=y
CONFIG_CRYPTO_ANUBIS=y
-CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_CAMELLIA=y
CONFIG_CRYPTO_CAST5=y
diff --git a/arch/mips/configs/rt305x_defconfig b/arch/mips/configs/rt305x_defconfig
index c920976bedd0..86327df02681 100644
--- a/arch/mips/configs/rt305x_defconfig
+++ b/arch/mips/configs/rt305x_defconfig
@@ -126,7 +126,6 @@ CONFIG_JFFS2_COMPRESSION_OPTIONS=y
CONFIG_SQUASHFS=y
# CONFIG_SQUASHFS_ZLIB is not set
CONFIG_SQUASHFS_XZ=y
-CONFIG_CRYPTO_ARC4=m
# CONFIG_XZ_DEC_X86 is not set
# CONFIG_XZ_DEC_POWERPC is not set
# CONFIG_XZ_DEC_IA64 is not set
diff --git a/arch/mips/configs/xway_defconfig b/arch/mips/configs/xway_defconfig
index f1c53bbb72e9..74cc4c5cce4c 100644
--- a/arch/mips/configs/xway_defconfig
+++ b/arch/mips/configs/xway_defconfig
@@ -138,7 +138,6 @@ CONFIG_JFFS2_COMPRESSION_OPTIONS=y
CONFIG_SQUASHFS=y
# CONFIG_SQUASHFS_ZLIB is not set
CONFIG_SQUASHFS_XZ=y
-CONFIG_CRYPTO_ARC4=m
CONFIG_PRINTK_TIME=y
CONFIG_STRIP_ASM_SYMS=y
CONFIG_DEBUG_FS=y
diff --git a/arch/powerpc/configs/44x/eiger_defconfig b/arch/powerpc/configs/44x/eiger_defconfig
index 48ab405ab80b..240f3f453b5c 100644
--- a/arch/powerpc/configs/44x/eiger_defconfig
+++ b/arch/powerpc/configs/44x/eiger_defconfig
@@ -85,6 +85,5 @@ CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_DES=y
diff --git a/arch/powerpc/configs/44x/redwood_defconfig b/arch/powerpc/configs/44x/redwood_defconfig
index 1e883938ca11..a8b93d7a592d 100644
--- a/arch/powerpc/configs/44x/redwood_defconfig
+++ b/arch/powerpc/configs/44x/redwood_defconfig
@@ -84,6 +84,5 @@ CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_DES=y
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index 4d76d64e2d0a..b263c843e3f0 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -801,7 +801,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index 3828f20ca434..0dbfd54038b7 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -785,7 +785,6 @@ CONFIG_CRYPTO_SM4_GENERIC=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_ADIANTUM=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_AEGIS128=m
diff --git a/arch/sh/configs/sh2007_defconfig b/arch/sh/configs/sh2007_defconfig
index 3060bcd9cc5f..ce641ed3a147 100644
--- a/arch/sh/configs/sh2007_defconfig
+++ b/arch/sh/configs/sh2007_defconfig
@@ -176,7 +176,6 @@ CONFIG_CRYPTO_TGR192=y
CONFIG_CRYPTO_WP512=y
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_ANUBIS=y
-CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLOWFISH=y
CONFIG_CRYPTO_CAMELLIA=y
CONFIG_CRYPTO_CAST5=y
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index 00863ecb228e..6f690a0a26d7 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -252,7 +252,6 @@ CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
diff --git a/arch/sparc/configs/sparc32_defconfig b/arch/sparc/configs/sparc32_defconfig
index d5579217fb4c..2f688b83e21b 100644
--- a/arch/sparc/configs/sparc32_defconfig
+++ b/arch/sparc/configs/sparc32_defconfig
@@ -84,7 +84,6 @@ CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
diff --git a/arch/x86/crypto/aria-avx.h b/arch/x86/crypto/aria-avx.h
index 6e1b2d8a31ed..0fff24861088 100644
--- a/arch/x86/crypto/aria-avx.h
+++ b/arch/x86/crypto/aria-avx.h
@@ -59,4 +59,7 @@ struct aria_avx_ops {
};
+
+void aria_avx_setup_16way_ops(struct aria_avx_ops *ops, bool use_gfni);
+void aria_avx2_setup_32way_ops(struct aria_avx_ops *ops, bool use_gfni);
#endif
diff --git a/arch/x86/crypto/aria_aesni_avx2_glue.c b/arch/x86/crypto/aria_aesni_avx2_glue.c
index 371be2fb6469..9029b0fbbef4 100644
--- a/arch/x86/crypto/aria_aesni_avx2_glue.c
+++ b/arch/x86/crypto/aria_aesni_avx2_glue.c
@@ -37,6 +37,24 @@ asmlinkage void aria_aesni_avx2_gfni_ctr_crypt_32way(const void *ctx, u8 *dst,
u8 *keystream, u8 *iv);
EXPORT_SYMBOL_GPL(aria_aesni_avx2_gfni_ctr_crypt_32way);
+/*
+ * Set up function pointers for the AVX 32-way asm functions for both this
+ * module and the the higher-tier modules.
+ */
+void aria_avx2_setup_32way_ops(struct aria_avx_ops *ops, bool use_gfni)
+{
+ if (use_gfni) {
+ ops->aria_encrypt_32way = aria_aesni_avx2_gfni_encrypt_32way;
+ ops->aria_decrypt_32way = aria_aesni_avx2_gfni_decrypt_32way;
+ ops->aria_ctr_crypt_32way = aria_aesni_avx2_gfni_ctr_crypt_32way;
+ } else {
+ ops->aria_encrypt_32way = aria_aesni_avx2_encrypt_32way;
+ ops->aria_decrypt_32way = aria_aesni_avx2_decrypt_32way;
+ ops->aria_ctr_crypt_32way = aria_aesni_avx2_ctr_crypt_32way;
+ }
+}
+EXPORT_SYMBOL_GPL(aria_avx2_setup_32way_ops);
+
static struct aria_avx_ops aria_ops;
struct aria_avx2_request_ctx {
@@ -202,21 +220,8 @@ static int __init aria_avx2_init(void)
return -ENODEV;
}
- if (boot_cpu_has(X86_FEATURE_GFNI)) {
- aria_ops.aria_encrypt_16way = aria_aesni_avx_gfni_encrypt_16way;
- aria_ops.aria_decrypt_16way = aria_aesni_avx_gfni_decrypt_16way;
- aria_ops.aria_ctr_crypt_16way = aria_aesni_avx_gfni_ctr_crypt_16way;
- aria_ops.aria_encrypt_32way = aria_aesni_avx2_gfni_encrypt_32way;
- aria_ops.aria_decrypt_32way = aria_aesni_avx2_gfni_decrypt_32way;
- aria_ops.aria_ctr_crypt_32way = aria_aesni_avx2_gfni_ctr_crypt_32way;
- } else {
- aria_ops.aria_encrypt_16way = aria_aesni_avx_encrypt_16way;
- aria_ops.aria_decrypt_16way = aria_aesni_avx_decrypt_16way;
- aria_ops.aria_ctr_crypt_16way = aria_aesni_avx_ctr_crypt_16way;
- aria_ops.aria_encrypt_32way = aria_aesni_avx2_encrypt_32way;
- aria_ops.aria_decrypt_32way = aria_aesni_avx2_decrypt_32way;
- aria_ops.aria_ctr_crypt_32way = aria_aesni_avx2_ctr_crypt_32way;
- }
+ aria_avx_setup_16way_ops(&aria_ops, boot_cpu_has(X86_FEATURE_GFNI));
+ aria_avx2_setup_32way_ops(&aria_ops, boot_cpu_has(X86_FEATURE_GFNI));
return crypto_register_skciphers(aria_algs, ARRAY_SIZE(aria_algs));
}
diff --git a/arch/x86/crypto/aria_aesni_avx_glue.c b/arch/x86/crypto/aria_aesni_avx_glue.c
index d23fc91c0ebd..b21054b5ac6c 100644
--- a/arch/x86/crypto/aria_aesni_avx_glue.c
+++ b/arch/x86/crypto/aria_aesni_avx_glue.c
@@ -39,6 +39,25 @@ EXPORT_SYMBOL_GPL(aria_aesni_avx_gfni_ctr_crypt_16way);
static struct aria_avx_ops aria_ops;
+/*
+ * Set up function pointers for the AVX 16-way asm functions for both this
+ * module's own dispatch table and the higher-tier (AVX2, GFNI/AVX-512)
+ * modules.
+ */
+void aria_avx_setup_16way_ops(struct aria_avx_ops *ops, bool use_gfni)
+{
+ if (use_gfni) {
+ ops->aria_encrypt_16way = aria_aesni_avx_gfni_encrypt_16way;
+ ops->aria_decrypt_16way = aria_aesni_avx_gfni_decrypt_16way;
+ ops->aria_ctr_crypt_16way = aria_aesni_avx_gfni_ctr_crypt_16way;
+ } else {
+ ops->aria_encrypt_16way = aria_aesni_avx_encrypt_16way;
+ ops->aria_decrypt_16way = aria_aesni_avx_decrypt_16way;
+ ops->aria_ctr_crypt_16way = aria_aesni_avx_ctr_crypt_16way;
+ }
+}
+EXPORT_SYMBOL_GPL(aria_avx_setup_16way_ops);
+
struct aria_avx_request_ctx {
u8 keystream[ARIA_AESNI_PARALLEL_BLOCK_SIZE];
};
@@ -188,15 +207,7 @@ static int __init aria_avx_init(void)
return -ENODEV;
}
- if (boot_cpu_has(X86_FEATURE_GFNI)) {
- aria_ops.aria_encrypt_16way = aria_aesni_avx_gfni_encrypt_16way;
- aria_ops.aria_decrypt_16way = aria_aesni_avx_gfni_decrypt_16way;
- aria_ops.aria_ctr_crypt_16way = aria_aesni_avx_gfni_ctr_crypt_16way;
- } else {
- aria_ops.aria_encrypt_16way = aria_aesni_avx_encrypt_16way;
- aria_ops.aria_decrypt_16way = aria_aesni_avx_decrypt_16way;
- aria_ops.aria_ctr_crypt_16way = aria_aesni_avx_ctr_crypt_16way;
- }
+ aria_avx_setup_16way_ops(&aria_ops, boot_cpu_has(X86_FEATURE_GFNI));
return crypto_register_skciphers(aria_algs, ARRAY_SIZE(aria_algs));
}
diff --git a/arch/x86/crypto/aria_gfni_avx512_glue.c b/arch/x86/crypto/aria_gfni_avx512_glue.c
index e05bbeb22d4a..bf676e85b95f 100644
--- a/arch/x86/crypto/aria_gfni_avx512_glue.c
+++ b/arch/x86/crypto/aria_gfni_avx512_glue.c
@@ -205,12 +205,8 @@ static int __init aria_avx512_init(void)
return -ENODEV;
}
- aria_ops.aria_encrypt_16way = aria_aesni_avx_gfni_encrypt_16way;
- aria_ops.aria_decrypt_16way = aria_aesni_avx_gfni_decrypt_16way;
- aria_ops.aria_ctr_crypt_16way = aria_aesni_avx_gfni_ctr_crypt_16way;
- aria_ops.aria_encrypt_32way = aria_aesni_avx2_gfni_encrypt_32way;
- aria_ops.aria_decrypt_32way = aria_aesni_avx2_gfni_decrypt_32way;
- aria_ops.aria_ctr_crypt_32way = aria_aesni_avx2_gfni_ctr_crypt_32way;
+ aria_avx_setup_16way_ops(&aria_ops, true);
+ aria_avx2_setup_32way_ops(&aria_ops, true);
aria_ops.aria_encrypt_64way = aria_gfni_avx512_encrypt_64way;
aria_ops.aria_decrypt_64way = aria_gfni_avx512_decrypt_64way;
aria_ops.aria_ctr_crypt_64way = aria_gfni_avx512_ctr_crypt_64way;
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 981d5dc422d4..6682ac091b38 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -98,15 +98,6 @@ config CRYPTO_HASH2
tristate
select CRYPTO_ALGAPI2
-config CRYPTO_RNG
- tristate
- select CRYPTO_RNG2
- select CRYPTO_ALGAPI
-
-config CRYPTO_RNG2
- tristate
- select CRYPTO_ALGAPI2
-
config CRYPTO_AKCIPHER2
tristate
select CRYPTO_ALGAPI2
@@ -151,14 +142,12 @@ config CRYPTO_MANAGER2
select CRYPTO_SIG2 if CRYPTO_SELFTESTS
select CRYPTO_HASH2 if CRYPTO_SELFTESTS
select CRYPTO_KPP2 if CRYPTO_SELFTESTS
- select CRYPTO_RNG2 if CRYPTO_SELFTESTS
select CRYPTO_SKCIPHER2 if CRYPTO_SELFTESTS
config CRYPTO_USER
tristate "Userspace cryptographic algorithm configuration"
depends on NET
select CRYPTO_MANAGER
- select CRYPTO_RNG
help
Userspace configuration for cryptographic instantiations such as
cbc(aes).
@@ -613,19 +602,6 @@ config CRYPTO_ADIANTUM
If unsure, say N.
-config CRYPTO_ARC4
- tristate "ARC4 (Alleged Rivest Cipher 4)"
- depends on CRYPTO_USER_API_ENABLE_OBSOLETE
- select CRYPTO_SKCIPHER
- select CRYPTO_LIB_ARC4
- help
- ARC4 cipher algorithm
-
- ARC4 is a stream cipher using keys ranging from 8 bits to 2048
- bits in length. This algorithm is required for driver-based
- WEP, but it should not be for other purposes because of the
- weakness of the algorithm.
-
config CRYPTO_CHACHA20
tristate "ChaCha"
select CRYPTO_LIB_CHACHA
@@ -1110,7 +1086,6 @@ config CRYPTO_DRBG
tristate "NIST SP800-90A DRBG (Deterministic Random Bit Generator)"
select CRYPTO_JITTERENTROPY
select CRYPTO_LIB_SHA512
- select CRYPTO_RNG
help
DRBG (Deterministic Random Bit Generator) (NIST SP800-90A)
@@ -1118,9 +1093,8 @@ config CRYPTO_DRBG
It's otherwise redundant with the kernel's regular RNG.
config CRYPTO_JITTERENTROPY
- tristate "CPU Jitter Non-Deterministic RNG (Random Number Generator)"
+ tristate
select CRYPTO_LIB_SHA3
- select CRYPTO_RNG
help
CPU Jitter RNG (Random Number Generator) from the Jitterentropy library
@@ -1288,7 +1262,7 @@ config CRYPTO_USER_API_SKCIPHER
config CRYPTO_USER_API_RNG
tristate "Random number generation algorithms (deprecated)"
depends on NET
- select CRYPTO_RNG
+ depends on CRYPTO_DRBG
select CRYPTO_USER_API
help
Enable the AF_ALG userspace interface for random number generation
@@ -1305,7 +1279,7 @@ config CRYPTO_USER_API_RNG
config CRYPTO_USER_API_RNG_CAVP
bool "Enable CAVP testing of DRBG"
- depends on CRYPTO_USER_API_RNG && CRYPTO_DRBG
+ depends on CRYPTO_USER_API_RNG
help
Enable extra APIs in the userspace interface for NIST CAVP
(Cryptographic Algorithm Validation Program) testing:
diff --git a/crypto/Makefile b/crypto/Makefile
index 33bb5ad595e8..42a4a0d5a466 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -133,7 +133,6 @@ obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia_generic.o
obj-$(CONFIG_CRYPTO_CAST_COMMON) += cast_common.o
obj-$(CONFIG_CRYPTO_CAST5) += cast5_generic.o
obj-$(CONFIG_CRYPTO_CAST6) += cast6_generic.o
-obj-$(CONFIG_CRYPTO_ARC4) += arc4.o
obj-$(CONFIG_CRYPTO_TEA) += tea.o
obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o
obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o
@@ -153,7 +152,6 @@ obj-$(CONFIG_CRYPTO_LZ4) += lz4.o
obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o
obj-$(CONFIG_CRYPTO_XXHASH) += xxhash_generic.o
obj-$(CONFIG_CRYPTO_842) += 842.o
-obj-$(CONFIG_CRYPTO_RNG2) += rng.o
obj-$(CONFIG_CRYPTO_DRBG) += drbg.o
obj-$(CONFIG_CRYPTO_JITTERENTROPY) += jitterentropy_rng.o
CFLAGS_jitterentropy.o = -O0
diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c
index bd522915d56d..7fe76479a6bd 100644
--- a/crypto/algif_rng.c
+++ b/crypto/algif_rng.c
@@ -40,11 +40,11 @@
#include <linux/capability.h>
#include <linux/module.h>
-#include <crypto/rng.h>
-#include <linux/random.h>
#include <crypto/if_alg.h>
#include <linux/net.h>
#include <net/sock.h>
+#include "drbg.h"
+#include "jitterentropy-kcapi.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
@@ -54,17 +54,26 @@ static const struct af_alg_allowlist_entry rng_allowlist[] = {
{},
};
+enum rng_type {
+ RNG_JITTERENTROPY = 1,
+ RNG_DRBG = 2,
+};
+
+struct rng_parent_ctx {
+ enum rng_type type;
+ union {
+ struct jitterentropy *jent;
+ struct drbg_state *drbg;
+ };
+ u8 *entropy;
+};
+
struct rng_ctx {
#define MAXSIZE 128
unsigned int len;
- struct crypto_rng *drng;
u8 *addtl;
size_t addtl_len;
-};
-
-struct rng_parent_ctx {
- struct crypto_rng *drng;
- u8 *entropy;
+ struct rng_parent_ctx *pctx;
};
static void rng_reset_addtl(struct rng_ctx *ctx)
@@ -74,11 +83,10 @@ static void rng_reset_addtl(struct rng_ctx *ctx)
ctx->addtl_len = 0;
}
-static int _rng_recvmsg(struct crypto_rng *drng, struct msghdr *msg, size_t len,
+static int _rng_recvmsg(struct rng_ctx *ctx, struct msghdr *msg, size_t len,
u8 *addtl, size_t addtl_len)
{
int err = 0;
- int genlen = 0;
u8 result[MAXSIZE];
if (len == 0)
@@ -92,15 +100,18 @@ static int _rng_recvmsg(struct crypto_rng *drng, struct msghdr *msg, size_t len,
*/
memset(result, 0, len);
- /*
- * The enforcement of a proper seeding of an RNG is done within an
- * RNG implementation. Some RNGs (DRBG, krng) do not need specific
- * seeding as they automatically seed. The X9.31 DRNG will return
- * an error if it was not seeded properly.
- */
- genlen = crypto_rng_generate(drng, addtl, addtl_len, result, len);
- if (genlen < 0)
- return genlen;
+ err = -EINVAL;
+ switch (ctx->pctx->type) {
+ case RNG_JITTERENTROPY:
+ err = crypto_jent_get_bytes(ctx->pctx->jent, result, len);
+ break;
+ case RNG_DRBG:
+ err = crypto_drbg_get_bytes(ctx->pctx->drbg, result, len, addtl,
+ addtl_len);
+ break;
+ }
+ if (err < 0)
+ return err;
err = memcpy_to_msg(msg, result, len);
memzero_explicit(result, len);
@@ -115,7 +126,7 @@ static int rng_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
struct alg_sock *ask = alg_sk(sk);
struct rng_ctx *ctx = ask->private;
- return _rng_recvmsg(ctx->drng, msg, len, NULL, 0);
+ return _rng_recvmsg(ctx, msg, len, NULL, 0);
}
static int rng_test_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
@@ -127,7 +138,7 @@ static int rng_test_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
int ret;
lock_sock(sock->sk);
- ret = _rng_recvmsg(ctx->drng, msg, len, ctx->addtl, ctx->addtl_len);
+ ret = _rng_recvmsg(ctx, msg, len, ctx->addtl, ctx->addtl_len);
rng_reset_addtl(ctx);
release_sock(sock->sk);
@@ -204,7 +215,6 @@ static struct proto_ops __maybe_unused algif_rng_test_ops = {
static void *rng_bind(const char *name)
{
struct rng_parent_ctx *pctx;
- struct crypto_rng *rng;
int err;
err = af_alg_check_restriction(name, rng_allowlist);
@@ -215,14 +225,30 @@ static void *rng_bind(const char *name)
if (!pctx)
return ERR_PTR(-ENOMEM);
- rng = crypto_alloc_rng(name, 0, AF_ALG_CRYPTOAPI_MASK);
- if (IS_ERR(rng)) {
- kfree(pctx);
- return ERR_CAST(rng);
+ if (strcmp(name, "jitterentropy_rng") == 0) {
+ pctx->type = RNG_JITTERENTROPY;
+ pctx->jent = crypto_jent_alloc();
+ if (IS_ERR(pctx->jent)) {
+ err = PTR_ERR(pctx->jent);
+ goto error;
+ }
+ } else if (strcmp(name, "stdrng") == 0 ||
+ strcmp(name, "drbg_nopr_hmac_sha512") == 0) {
+ pctx->type = RNG_DRBG;
+ pctx->drbg = crypto_drbg_alloc();
+ if (IS_ERR(pctx->drbg)) {
+ err = PTR_ERR(pctx->drbg);
+ goto error;
+ }
+ } else {
+ err = -ENOENT;
+ goto error;
}
-
- pctx->drng = rng;
return pctx;
+
+error:
+ kfree_sensitive(pctx);
+ return ERR_PTR(err);
}
static void rng_release(void *private)
@@ -231,7 +257,14 @@ static void rng_release(void *private)
if (unlikely(!pctx))
return;
- crypto_free_rng(pctx->drng);
+ switch (pctx->type) {
+ case RNG_JITTERENTROPY:
+ crypto_jent_free(pctx->jent);
+ break;
+ case RNG_DRBG:
+ crypto_drbg_free(pctx->drbg);
+ break;
+ }
kfree_sensitive(pctx->entropy);
kfree_sensitive(pctx);
}
@@ -266,7 +299,7 @@ static int rng_accept_parent(void *private, struct sock *sk)
* state of the RNG.
*/
- ctx->drng = pctx->drng;
+ ctx->pctx = pctx;
ask->private = ctx;
sk->sk_destruct = rng_sock_destruct;
@@ -283,11 +316,10 @@ static int rng_accept_parent(void *private, struct sock *sk)
static int rng_setkey(void *private, const u8 *seed, unsigned int seedlen)
{
struct rng_parent_ctx *pctx = private;
- /*
- * Check whether seedlen is of sufficient size is done in RNG
- * implementations.
- */
- return crypto_rng_reset(pctx->drng, seed, seedlen);
+
+ if (pctx->type != RNG_DRBG)
+ return 0;
+ return crypto_drbg_seed(pctx->drbg, seed, seedlen);
}
static int __maybe_unused rng_setentropy(void *private, sockptr_t entropy,
@@ -299,7 +331,7 @@ static int __maybe_unused rng_setentropy(void *private, sockptr_t entropy,
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
- if (pctx->entropy)
+ if (pctx->entropy || pctx->type != RNG_DRBG)
return -EINVAL;
if (len > MAXSIZE)
@@ -311,9 +343,9 @@ static int __maybe_unused rng_setentropy(void *private, sockptr_t entropy,
return PTR_ERR(kentropy);
}
- crypto_rng_alg(pctx->drng)->set_ent(pctx->drng, kentropy, len);
+ crypto_drbg_set_entropy(pctx->drbg, kentropy, len);
/*
- * Since rng doesn't perform any memory management for the entropy
+ * Since drbg doesn't perform any memory management for the entropy
* buffer, save kentropy pointer to pctx now to free it after use.
*/
pctx->entropy = kentropy;
@@ -346,3 +378,4 @@ static void __exit rng_exit(void)
module_init(rng_init);
module_exit(rng_exit);
+MODULE_IMPORT_NS("CRYPTO_INTERNAL"); /* for drbg and jitterentropy */
diff --git a/crypto/arc4.c b/crypto/arc4.c
deleted file mode 100644
index 1608018111d0..000000000000
--- a/crypto/arc4.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Cryptographic API
- *
- * ARC4 Cipher Algorithm
- *
- * Jon Oberheide <jon@oberheide.org>
- */
-
-#include <crypto/arc4.h>
-#include <crypto/internal/skcipher.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-
-#define ARC4_ALIGN __alignof__(struct arc4_ctx)
-
-static int crypto_arc4_setkey(struct crypto_lskcipher *tfm, const u8 *in_key,
- unsigned int key_len)
-{
- struct arc4_ctx *ctx = crypto_lskcipher_ctx(tfm);
-
- return arc4_setkey(ctx, in_key, key_len);
-}
-
-static int crypto_arc4_crypt(struct crypto_lskcipher *tfm, const u8 *src,
- u8 *dst, unsigned nbytes, u8 *siv, u32 flags)
-{
- struct arc4_ctx *ctx = crypto_lskcipher_ctx(tfm);
-
- if (!(flags & CRYPTO_LSKCIPHER_FLAG_CONT))
- memcpy(siv, ctx, sizeof(*ctx));
-
- ctx = (struct arc4_ctx *)siv;
-
- arc4_crypt(ctx, dst, src, nbytes);
- return 0;
-}
-
-static int crypto_arc4_init(struct crypto_lskcipher *tfm)
-{
- pr_warn_ratelimited("\"%s\" (%ld) uses obsolete ecb(arc4) skcipher\n",
- current->comm, (unsigned long)current->pid);
-
- return 0;
-}
-
-static struct lskcipher_alg arc4_alg = {
- .co.base.cra_name = "arc4",
- .co.base.cra_driver_name = "arc4-generic",
- .co.base.cra_priority = 100,
- .co.base.cra_blocksize = ARC4_BLOCK_SIZE,
- .co.base.cra_ctxsize = sizeof(struct arc4_ctx),
- .co.base.cra_alignmask = ARC4_ALIGN - 1,
- .co.base.cra_module = THIS_MODULE,
- .co.min_keysize = ARC4_MIN_KEY_SIZE,
- .co.max_keysize = ARC4_MAX_KEY_SIZE,
- .co.statesize = sizeof(struct arc4_ctx),
- .setkey = crypto_arc4_setkey,
- .encrypt = crypto_arc4_crypt,
- .decrypt = crypto_arc4_crypt,
- .init = crypto_arc4_init,
-};
-
-static int __init arc4_init(void)
-{
- return crypto_register_lskcipher(&arc4_alg);
-}
-
-static void __exit arc4_exit(void)
-{
- crypto_unregister_lskcipher(&arc4_alg);
-}
-
-module_init(arc4_init);
-module_exit(arc4_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
-MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>");
-MODULE_ALIAS_CRYPTO("ecb(arc4)");
diff --git a/crypto/asymmetric_keys/selftest.c b/crypto/asymmetric_keys/selftest.c
index 98dc5cdfdebe..42857b022586 100644
--- a/crypto/asymmetric_keys/selftest.c
+++ b/crypto/asymmetric_keys/selftest.c
@@ -41,7 +41,7 @@ void fips_signature_selftest(const char *name,
pkcs7 = pkcs7_parse_message(sig, sig_len);
if (IS_ERR(pkcs7))
- panic("Certs %s selftest: pkcs7_parse_message() = %d\n", name, ret);
+ panic("Certs %s selftest: pkcs7_parse_message() = %pe\n", name, pkcs7);
pkcs7_supply_detached_data(pkcs7, data, data_len);
diff --git a/crypto/asymmetric_keys/x509_loader.c b/crypto/asymmetric_keys/x509_loader.c
index 0d516c77cc26..373b5106e103 100644
--- a/crypto/asymmetric_keys/x509_loader.c
+++ b/crypto/asymmetric_keys/x509_loader.c
@@ -39,8 +39,8 @@ int x509_load_certificate_list(const u8 cert_list[],
KEY_ALLOC_BUILT_IN |
KEY_ALLOC_BYPASS_RESTRICTION);
if (IS_ERR(key)) {
- pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
- PTR_ERR(key));
+ pr_err("Problem loading in-kernel X.509 certificate (%pe)\n",
+ key);
} else {
pr_notice("Loaded X.509 cert '%s'\n",
key_ref_to_ptr(key)->description);
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index d3ccb507153b..08e2b4fb9bf7 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -16,9 +16,9 @@
#include <net/net_namespace.h>
#include <net/sock.h>
#include <crypto/internal/skcipher.h>
-#include <crypto/internal/rng.h>
#include <crypto/akcipher.h>
#include <crypto/kpp.h>
+#include <crypto/rng.h>
#include "internal.h"
diff --git a/crypto/drbg-testvecs.h b/crypto/drbg-testvecs.h
new file mode 100644
index 000000000000..d073257eb3d1
--- /dev/null
+++ b/crypto/drbg-testvecs.h
@@ -0,0 +1,228 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright 2026 Google LLC
+ */
+#ifndef _CRYPTO_DRBG_TESTVECS_H
+#define _CRYPTO_DRBG_TESTVECS_H
+
+#include <linux/types.h>
+
+struct drbg_testvec {
+ /* Instantiate */
+ const u8 *entropy;
+ size_t entropylen;
+ const u8 *pers;
+ size_t perslen;
+
+ /* Reseed (optional) */
+ const u8 *ent_reseed;
+ size_t ent_reseed_len;
+ const u8 *addtl_reseed;
+ size_t addtl_reseed_len;
+
+ /* Generate (twice) */
+ const u8 *addtla;
+ const u8 *addtlb;
+ size_t addtllen;
+
+ /* Expected output from last call to Generate */
+ const u8 *expected;
+ size_t expectedlen;
+};
+
+static const struct drbg_testvec drbg_testvecs[] = {
+ /*
+ * Borrowed from the first applicable test vector from ACVP:
+ * https://github.com/usnistgov/ACVP-Server/blob/v1.1.0.33/gen-val/json-files/hmacDRBG-1.0/prompt.json#L4596
+ * https://github.com/usnistgov/ACVP-Server/blob/v1.1.0.33/gen-val/json-files/hmacDRBG-1.0/expectedResults.json#L986
+ */
+ {
+ /* .entropy = ACVP entropyInput || nonce */
+ .entropy = "\x47\x28\x33\x05\x82\xE8\xA7\x58\x05\xBD\x07\x9E"
+ "\xDB\x59\x87\x08\x3B\x82\x40\x70\xA1\xB7\x33\x4F"
+ "\x0F\x53\xBE\xF6\x98\x75\xFA\x21\x00\x04\xBC\x58"
+ "\x9B\xB1\xB3\xBC\x2A\xF6\xA4\x2A\xE1\xB3\x65\x24"
+ "\xA8\xEE\x56\x70\x5E\x28\x06\x04\x80\xCE\xB7\x36"
+ "\xA4\xD1\x4E\xAA\xE7\xE8\x51\x40\x7D\x30\xF7\x91"
+ "\xF2\x9E\x98\xA7\xBB\xB3\x1D\xC6\x8A\x62\xC7\xE7"
+ "\x1F\xE1\x0A\x52\x45\x39\x88\x92\x43\xA6\x5B\xC3"
+ "\x9D\x60\xDE\xFE\x79\xEF\x87\x6F\xD5\x76\x51\x69"
+ "\x7B\x4C\x3D\x08\x60\xFA\xDC\x00\x94\xEC\x0A\xC5"
+ "\xE7\xCB\x30\x05\x9F\xCC\x07\x44\x07\x14\xF4\xF9"
+ "\xBC\x7D\xC0\x66\x63\x5B\xD3\x2A\xA7\xF2\x1D\x75"
+ "\x3F\x28\x5F\x4A\xEB\x63\xD7\x92\x5A\x9A\x7C\x3A"
+ "\x56\xEA\xCB\xA9\xA0\xF9\x5B\x99\xC2\x7D\x31\xBF"
+ "\x44\xC7\x64\x6B\x7E\x64\x60\x64\x05\x86\xF0\x6B"
+ "\x76\xA7\x3E\x63\xAD\xB6\x76\xED\x3D\x05\x2E\xC7"
+ "\xC7\x52\x8F\x07\x56\x23\xFC\x2F\x93\xD5\xF2\x29"
+ "\xC6\x84\x48\xD1\x88\xB9\x3F\x84\xB2\x93\xFC\x2F"
+ "\x00\xB1\xBC\xBE\xAC\xC4\x94\x36\xF1\x2B\xF0\xC7"
+ "\x36\xE8\x1D\x45\x0A\xA2\xFE\x72\xD7\x3E\x15\x6A"
+ "\x74\x23\xB2\xD1\x3C\x20\xF2\xB7\x19\xC5\xF0\x74"
+ "\x69\x06\xD1\x92\x47\xC9\x68\xDC\xEE\xBC\xF4\x3A"
+ "\x8B\x7C\xA4\xA4\x4A\x15\xF4\xF0\x26\x26\xC5\x7D"
+ "\x57\xDC\x00\x59\x07\xDF\x84\x2A\x23\xA9\xC1\xAF"
+ "\x47\x49\x88\xCC\x2F\x3B\x90\x39\xA0\x09\xAE\x3C"
+ "\x79\xF9\x97\x9D\xEF\x13\x1D\x2B\xB6\x18\xDB\xCF"
+ "\x95\x98\x17\x7F\xF6\x95\x44\x3A\x40\x90\x63\x16"
+ "\x70\x38\x22\xC5\xD8\xE4\x57\xA0\x8E\x51\x6B\xED"
+ "\x03\x18\xC6\x74\xFA\xCA\xF2\xD5\xB2\x5A\x0C\x02"
+ "\x48\x9F\x70\x0B\x1C\x0A\xD1\xD6\x4F\x3F\x70\x3C"
+ "\x1A\x62\x29\x63\xD0\x92\x76\x30\x7C\xB9\x54\xEC"
+ "\xF6\x92\xA3\x11\x66\xB2\x56\xE0\x75\x3D\x27\x01",
+ .entropylen = 384,
+ .pers = "\x03\x75\x33\x7B\x6B\xE5\x14\xAF\x0E\x43\x33\xCC\xD3"
+ "\xF4\xF0\x8B\x8A\xCC\xFE\x95\xC1\x20\xB9\x56\x3D\x2C"
+ "\x34\xC7\xA1\x4C\xBC\xDC\x0A\x8D\xBE\x68\x28\x89\x2A"
+ "\x92\x10\x05\x4E\xF9\xE2\x51\xF7\x4F\xF4\x48\x76\xC9"
+ "\xCE\xA8\x6D\xC1\xDE\x5C\x05\x95\x77\x24\xB4\x5D\x3D"
+ "\x16\x1D\xCB\x43\xE5\xD3\x01\x96\xCC\x3E\x2E\xE1\x97"
+ "\xB3\x42\xC2\xAB\xEC\x56\xA9\xF9\xF2\x28\x59\x01\x4E"
+ "\xFC\x8A\xC0\x5E\x4E\x33\x30\x91\x96\x93\xBA\xFA\xE1"
+ "\x9F\x20\xC3\xC1\xD1\xC6\xC3\x2C\x59\x8F\x56\xD5\x73"
+ "\xE8\x8D\xCF\xAC\xB1\x85\x3E\xC7\x73\x21\x59\x8D\x0F"
+ "\xF4\xA4\xC4\x0C\xD2\x18\x81\x5F\x3E\x37\xC9\x9F\xD9"
+ "\xDE\x3F\x15\x6F\xAC\x1A\xEC\x5E\x28\xD5\x56\xA2\x65"
+ "\xD2\x7C\x41\xDE\x57\x8C\x60\xAB\xA5\x03\x42\xC8\x3C"
+ "\x70\xC2\xD1\x11\x62\x25\x4E\x17\x58\xBB\x08\x51\x79"
+ "\xE6\xED\xBA\x9A\xA7\x07\xD5\x0E\x89\x43\x31\x4F\x99"
+ "\xEE\xED\xF1\x36\xFA\x1E\xC0\x25\x01\xDA\x19\xC2\x7D"
+ "\x5D\x78\x74\x5C\xC0\x72\x2E\xF1\x7B\x4E\x9C\xDB\xFE"
+ "\x60\x89\x62\x71\x9C\xEA\xD3\xDF\x82\xC7\x8B\xB4\x7B"
+ "\x7B\x7F\x6A\x62\x3C\x57\x76\xA5\x67\x5F\x70\xFB\xE0"
+ "\x1B\x23\x79\x71\xB5\x7C\xEA\x76\x99",
+ .perslen = 256,
+
+ .ent_reseed = "\xE0\x5B\x69\xC5\xF9\xD4\x5A\x1F\xC1\x71\x0C"
+ "\x37\x6F\xFE\x31\xE0\xEF\x3E\x9B\xD5\x46\x43"
+ "\xA2\x15\xFA\x86\x75\x1C\x95\x9F\xE6\xD6\x41"
+ "\x50\x36\x0F\x67\x68\x4A\x72\x32\x85\xB0\xCB"
+ "\xA4\x0D\x1F\xA2\x43\xCA\x30\xF1\x42\xF8\xC4"
+ "\x17\x6A\xD1\x2D\x43\x46\x8C\xA5\x72\x3C\xB1"
+ "\x44\x8E\xA1\x75\xAA\x20\x30\xDD\xCD\x0B\x5A"
+ "\x0D\xE6\x28\xCA\xBC\xA9\x3B\x11\x23\x88\x85"
+ "\xDF\xD8\x84\x11\x89\x7A\x4F\x00\x90\x0B\xD8"
+ "\x8A\x35\xE9\x5F\xEC\x05\x42\x15\xCA\x7E\xA3"
+ "\xEF\xEF\xE3\xB7\xBE\x96\x8C\x36\x7D\x15\x3C"
+ "\x7A\x78\x00\x61\xAF\x62\x45\xA7\x4B\xAE\x4A"
+ "\xFD\xC9\xE0\x89\x53\x36\x71\x8F\x38\xC4\x00"
+ "\x57\xD9\xE6\xC1\xEC\xBF\xF7\x4B\x3F\x55\xD6"
+ "\x54\x15\x72\xB2\x23\x76\xD1\x4E\x8E\x7E\xFB"
+ "\xC8\xD6\xA4\xA4\x7E\x8E\xD8\x76\xD3\xEB\x90"
+ "\x90\xEB\xB3\x84\x26\x34\x93\x36\xCA\xA9\x12"
+ "\xD3\x6D\x84\x07\xE1\x0E\xE7\x63\x24\x54\x90"
+ "\x42\x8C\x6B\xE7\x21\x53\x2D\x16\xE9\x68\xA9"
+ "\xC2\x9A\x7A\x93\x31\x5E\x35\x72\xE2\x0F\x3D"
+ "\x55\x41\x8C\xC5\xD1\xBB\xEE\x5F\x3C\x95\x52"
+ "\x2A\x65\x47\xB6\x84\x6A\x05\x19\xD9\xE7\x68"
+ "\x15\xFA\x49\xD9\x9D\xFD\x47\x9F\xB9\xA6\xBB"
+ "\xA8\xD4\x22\x6C\x8B\x59\x47\xEF\xD1\xD0\xBF"
+ "\xBC\xE4\x53\x31\x2F\xA5\xD4\x2C\x89\xCA\xE5"
+ "\x29\x64\xF8\x51\x2A\x02\xDE\x31\x0D\x54\x0E"
+ "\x0E\xB8\x78\xE6\x2A\x3E\x31\xA2\xA4\xCD\x91"
+ "\x79\xF2\x9B\x04\xA0\xDB\x78\xAC\x0D\xB5\xCA"
+ "\x60\x4C\x08\x96\xCA\x8A\xE9\x93\x9F\x62\x38"
+ "\xAE",
+ .ent_reseed_len = 320,
+ .addtl_reseed = "\xD5\x46\x71\x38\x46\xE0\xC1\x27\x2C\xF1\x07"
+ "\xDD\x29\x73\xD7\xF4\x5A\x3A\xE0\x99\x98\x0A"
+ "\xEB\xA5\x9E\x2E\x49\x21\x7B\x18\xC0\xD8\x3D"
+ "\xEE\x49\xF9\x52\x7C\x55\x5E\x5E\x06\xC2\x7E"
+ "\x34\x3A\xA5\xB7\x78\x21\xC1\xB8\x8B\x4E\x07"
+ "\x1F\x3F\xC4\xB4\x9B\x3F\x20\x2D\xEE\x70\x3B"
+ "\x18\xCF\x2B\x50\x15\x1B\xF3\x6C\xE7\x9F\x2A"
+ "\x2B\x69\x53\xCA\x88\x41\xA9\x07\x31\x14\x55"
+ "\xBD\x75\x49\x68\x98\x48\xCA\x46\xA5\xEC\xAA"
+ "\x9D\x8E\x6F\x40\xBA\xCA\xC8\xE9\x9F\xA4\xC5"
+ "\x94\x89\x2C\x4D\xE4\x0A\x66\xD3\xDB\x1A\xD9"
+ "\xA7\x3F\x6B\x0A\xE0\xE4\xDC\x0B\x8B\x64\xBF"
+ "\xB4\x95\xA1\xAE\x92\xA8\x7C\xE2\x4B\xED\xFD"
+ "\xFD\xE0\x54\x48\x7C\x25\xD6\xD1\x0A\xAB\x5E"
+ "\x33\x2F\x1D\xD3\x62\x47\xAB\x35\x8C\xA1\xC2"
+ "\x75\xDD\x75\xCA\x09\xE1\x38\xDE\x87\x79\x0C"
+ "\xD7\x5D\x3E\x6D\x28\x8F\x12\x98\x2C\x26\x34"
+ "\x91\x0B\x6B\xB7\x73",
+ .addtl_reseed_len = 192,
+
+ .addtla = "\xC8\xE1\x03\x59\xEA\x9F\xD3\x1F\xCC\xCB\x5A\x3E"
+ "\x23\xDB\x47\x75\x1B\x3A\x6C\x0B\xED\xE6\xC0\xB6"
+ "\x4B\x82\x53\x5B\x6D\xEE\x2B\x97\x0F\x59\x07\xA4"
+ "\xFE\xE2\x26\x4F\xFF\xF7\x46\xAF\x62\xC4\x42\xE8"
+ "\x06\xFA\x1F\xAA\x66\xF3\xA4\xCF\x85\x02\x3C\x11"
+ "\xEF\xD2\x16\x13\x7A\xBD\x03\x66\xC3\x4D\x6F\x3A"
+ "\xE5\xD3\xFF\x92\xB6\x45\xB8\x88\x94\x42\x2E\x84"
+ "\x02\xA5\x54\x12\xBF\xCB\xF1\x6E\x1C\x0C\x23\xFE"
+ "\x8A\xFD\xF5\x1A\x4C\xD6\x2A\x34\x7F\x21\x50\xBB"
+ "\x06\x64\x9A\x77\x70\x59\x1D\x12\xD1\xA0\x10\x70"
+ "\xD7\x4F\x3C\xEE\x82\xEF\x5B\x35\x8F\x05\xF6\x51"
+ "\xBC\x28\xE1\xB1\x54\xFF\x25\x12\x16\x2C\x62\xFC"
+ "\xB9\x74\x5E\x78\x41\xB2\x04\x80\x4E\xB1\x43\x2E"
+ "\x88\x7F\x34\xA4\x33\x66\xE8\x68\x60\x54\xEB\xCE"
+ "\xD1\x5F\xC4\xD6\x21\x5E\x22\x1A\x7E\xC5\x6D\xB7"
+ "\x93\x8F\x9C\x77\x6E\x56\xA5\xA8\xF7\xB2\x10\x19",
+ .addtlb = "\xB8\x1E\x9E\xE2\xB3\xE4\x04\x43\x51\x7B\x96\x32"
+ "\xAC\x95\xF2\x1E\x5E\x7A\xBF\x68\xE3\x7A\xCE\xE5"
+ "\x2B\x3B\xB0\x34\x7F\xE1\xB5\x37\x3C\x5B\xD2\x6B"
+ "\x17\xF6\x18\xAF\x7C\x01\xA5\x84\xFE\x07\x0B\x46"
+ "\xCC\x96\x61\xAB\xCD\x81\x95\x8A\x8A\xB6\xD8\xCC"
+ "\x94\x80\x45\xF6\xFF\x95\x3A\xB8\xDC\xBF\xB4\xBF"
+ "\x26\x8C\xE9\x79\x05\x58\x9C\x03\x08\x45\xB5\xC4"
+ "\xD8\xB4\xCD\x76\x13\xAE\x2B\xCC\xB5\x3E\x3C\x65"
+ "\x7A\xAA\xDC\x9B\x0B\x13\x8B\x82\x5A\x39\x60\x9A"
+ "\xF7\xA8\x38\xB5\x83\x8E\x0B\xD1\xE6\xBF\xA1\xDC"
+ "\x30\x45\xCC\x67\x41\x0F\xF9\x86\x27\xE0\x22\x3E"
+ "\x0D\x1F\x92\x13\x16\x9B\x84\x79\x91\xFE\xBC\xDF"
+ "\x15\x6C\xDC\xAE\xC5\x64\x46\x9C\xE8\xEA\xBB\x9D"
+ "\x27\xA2\x1E\xDF\xB2\xF2\x98\xB4\x88\x4E\x22\x5F"
+ "\x3C\xD0\x35\x2C\x5C\x89\xC7\xEC\xE3\xF3\x09\x60"
+ "\xEF\xAC\x78\xBF\x94\xAA\x8C\x30\x7F\xCF\xE4\x4B",
+ .addtllen = 192,
+
+ .expected = "\x93\xFF\x4F\x4A\xA7\xE0\xFC\x3B\xCF\xCE\x57\xCD"
+ "\xFD\xE9\x94\x6D\x0D\x45\x7E\xA3\x98\xBB\xE6\x54"
+ "\x36\xF9\x92\xE6\xBB\xC5\x93\x16\x69\x35\x01\xF0"
+ "\x5A\xE2\x43\xFC\x73\x7C\xA3\x5C\x5B\x49\x72\x69"
+ "\x6A\xC4\xB6\xD4\xB2\x48\x27\x72\xCA\xE3\xF3\xB8"
+ "\xD6\x95\x9F\x39\xC8\xD7\x72\xAF\xC2\x7C\x75\xE5"
+ "\xA4\xF7\x52\x4F\xDF\x80\x75\xCA\x4B\xFA\x75\x9A"
+ "\x7A\x8D\x48\x94\x30\x1C\x82\x5E\xD6\x3F\xF1\x78"
+ "\x84\xAA\x8D\x8B\x4F\x6A\x20\x12\xA2\x65\xC5\x02"
+ "\x32\xA1\xE4\x6B\x86\x2F\xCF\x92\xCD\x01\x55\xF7"
+ "\xB8\xAB\xC3\x2C\x42\xC3\xFD\x9B\x59\x2D\x47\x8E"
+ "\xB6\x8D\xE7\x04\x2E\x67\xD9\x07\x14\xA3\xF2\x74"
+ "\x79\x9C\xAB\xC6\xD6\x52\x3E\x91\x81\xA4\x3C\x9A"
+ "\x3E\x10\x1E\xD0\x28\xBC\x1C\x50\xF0\xB6\xEC\x01"
+ "\xE5\x40\x16\x08\xB5\x58\xE0\xC4\xC2\x9A\xBB\x13"
+ "\xAB\x10\x4B\x07\x24\x09\xEB\xF9\x5E\xAA\x3E\x3A"
+ "\x25\x34\x5B\x97\x92\xF9\x46\x8A\x8E\x5A\x06\x9C"
+ "\x2B\x1C\x8E\x47\x19\xC3\x3B\x14\x8A\xC1\xEB\xF7"
+ "\xB0\xA2\x05\xE0\x70\x12\x88\x21\xFF\xC0\x35\x6D"
+ "\xE9\x08\x7E\x11\x6E\xD7\x16\x48\x24\x43\xAF\x33"
+ "\xA3\x48\x44\x91\xC5\x32\x1D\x87\xF6\x9B\x10\x1C"
+ "\xA4\x7A\x74\x23\xB3\xFC\xB9\x87\x08\xE6\x9A\xEF"
+ "\xD5\x93\x82\x17\xD4\x78\xDA\x46\x34\xC2\x61\x8C"
+ "\xB7\x53\x89\xC4\x8A\xD8\xA0\x2E\xCE\xCA\x24\x16"
+ "\xF0\x18\x7F\xC3\x12\x3F\xD0\xB1\xEF\x37\x99\xA8"
+ "\x04\x1F\x76\x50\x81\x08\xCD\x4D\x43\xEF\x64\xB6"
+ "\x03\x57\xB7\x5F\xDD\xF6\xBA\x34\xE2\x88\xE7\x1F"
+ "\x62\xA5\xA4\x05\xEB\x1A\xFE\x0B\xFE\x74\x7D\x64"
+ "\x29\x83\xE8\x0B\x97\x7D\x94\x5B\xF9\x3C\x8E\xC8"
+ "\x6B\xCD\xAD\x63\x32\x6E\x00\xBF\x8E\x57\xF2\x32"
+ "\x88\x53\x17\x40\xE3\xF8\xF8\xD9\xFD\xCD\x76\x84"
+ "\xC6\xFD\xB1\x10\x40\xED\x75\xDD\xBD\x78\x8B\x0A"
+ "\x61\x1E\xCC\xC4\x4F\x95\xF1\x2F\x8F\x5A\xF0\x12"
+ "\x00\xCE\x75\xB8\xE9\xAB\x63\xC0\x7A\xF6\x9A\x47"
+ "\xD2\x3C\xB0\xAD\xAF\x03\xDF\x25\xDD\x0C\x0F\xB6"
+ "\x29\x09\x0F\x28\x5E\xA8\x67\xBB\xC9\x78\xBE\x12"
+ "\xD8\xD6\xD0\x98\x82\x29\xA3\x82\xFB\x8E\x1C\x79"
+ "\x28\x52\x22\x73\x3C\x6F\xB5\x33\xFF\x40\x26\x4C"
+ "\x30\xE4\xE0\x39\x59\x72\x65\x79\x9F\xB7\x89\x87"
+ "\x64\xAC\x45\x11\x0D\xDD\xC0\x44\x5E\x0D\xDF\xDB"
+ "\x91\x42\x5F\x52\x7F\xBB\x66\xEE\x32\x90\x8F\x6F"
+ "\xF8\xB9\xFE\xEA\x42\xFB\x60\x2B\xE3\xD9\xB2\xD1"
+ "\x74\x37\x14\xC6\xDA\x68\xE6\x09",
+ .expectedlen = 512,
+ }
+};
+
+#endif /* _CRYPTO_DRBG_TESTVECS_H */
diff --git a/crypto/drbg.c b/crypto/drbg.c
index d66c7211d6bb..faa39045bdc6 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -41,46 +41,45 @@
* ==========
* The SP 800-90A DRBG allows the user to specify a personalization string
* for initialization as well as an additional information string for each
- * random number request. The following code fragments show how a caller
- * uses the kernel crypto API to use the full functionality of the DRBG.
+ * random number request. The following code snippets show example use:
*
* Usage without any additional data
* ---------------------------------
- * struct crypto_rng *drng;
+ * struct drbg_state *drbg;
* int err;
* char data[DATALEN];
*
- * drng = crypto_alloc_rng(drng_name, 0, 0);
- * err = crypto_rng_get_bytes(drng, data, DATALEN);
- * crypto_free_rng(drng);
+ * drbg = crypto_drbg_alloc();
+ * err = crypto_drbg_seed(drbg, NULL, 0);
+ * err = crypto_drbg_get_bytes(drbg, data, sizeof(data), NULL, 0);
+ * crypto_drbg_free(drbg);
*
*
* Usage with personalization string during initialization
* -------------------------------------------------------
- * struct crypto_rng *drng;
+ * struct drbg_state *drbg;
* int err;
* char data[DATALEN];
* char personalization[11] = "some-string";
*
- * drng = crypto_alloc_rng(drng_name, 0, 0);
- * // The reset completely re-initializes the DRBG with the provided
- * // personalization string
- * err = crypto_rng_reset(drng, personalization, strlen(personalization));
- * err = crypto_rng_get_bytes(drng, data, DATALEN);
- * crypto_free_rng(drng);
+ * drbg = crypto_drbg_alloc();
+ * err = crypto_drbg_seed(drbg, personalization, sizeof(personalization));
+ * err = crypto_drbg_get_bytes(drbg, data, sizeof(data), NULL, 0);
+ * crypto_drbg_free(drbg);
*
*
* Usage with additional information string during random number request
* ---------------------------------------------------------------------
- * struct crypto_rng *drng;
+ * struct drbg_state *drbg;
* int err;
* char data[DATALEN];
* char addtl_string[11] = "some-string";
*
- * drng = crypto_alloc_rng(drng_name, 0, 0);
- * err = crypto_rng_generate(drng, addtl_string, strlen(addtl_string),
- data, DATALEN);
- * crypto_free_rng(drng);
+ * drbg = crypto_drbg_alloc();
+ * err = crypto_drbg_seed(drbg, NULL, 0);
+ * err = crypto_drbg_get_bytes(drbg, data, sizeof(data), addtl_string,
+ * sizeof(addtl_string));
+ * crypto_drbg_free(drbg);
*
*
* Usage with personalization and additional information strings
@@ -88,14 +87,17 @@
* Just mix both scenarios above.
*/
-#include <crypto/internal/rng.h>
+#include <crypto/rng.h>
#include <crypto/sha2.h>
#include <linux/fips.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
-#include <linux/string_choices.h>
-#include <linux/unaligned.h>
+#include <linux/once.h>
+#include <linux/slab.h>
+#include "drbg.h"
+#include "drbg-testvecs.h"
+#include "jitterentropy-kcapi.h"
/* State length in bytes */
#define DRBG_STATE_LEN SHA512_DIGEST_SIZE
@@ -130,7 +132,7 @@ struct drbg_state {
/* Number of RNG requests since last reseed -- 10.1.2.1 1c */
size_t reseed_ctr;
bool instantiated;
- struct crypto_rng *jent;
+ struct jitterentropy *jent;
const u8 *test_entropy;
size_t test_entropylen;
};
@@ -230,7 +232,7 @@ static int drbg_seed(struct drbg_state *drbg, const u8 *pers, size_t pers_len,
__must_hold(&drbg->drbg_mutex)
{
int ret;
- u8 entropy_buf[(32 + 16) * 2];
+ u8 entropy_buf[(32 + 16) * 2] = {};
size_t entropylen;
const u8 *entropy;
@@ -272,9 +274,9 @@ static int drbg_seed(struct drbg_state *drbg, const u8 *pers, size_t pers_len,
* Get seed from Jitter RNG, failures are
* fatal only in FIPS mode.
*/
- ret = crypto_rng_get_bytes(drbg->jent,
- &entropy_buf[entropylen],
- entropylen);
+ ret = crypto_jent_get_bytes(drbg->jent,
+ &entropy_buf[entropylen],
+ entropylen);
if (fips_enabled && ret) {
pr_devel("DRBG: jent failed with %d\n", ret);
@@ -402,36 +404,46 @@ static int drbg_generate(struct drbg_state *drbg, u8 *out, size_t outlen,
}
/***************************************************************
- * Kernel crypto API interface to DRBG
+ * Public API
***************************************************************/
-static int drbg_kcapi_init(struct crypto_tfm *tfm)
+static int drbg_selftest(void);
+
+static struct drbg_state *__crypto_drbg_alloc(void)
{
- struct drbg_state *drbg = crypto_tfm_ctx(tfm);
+ struct drbg_state *drbg = kzalloc_obj(*drbg);
+
+ if (!drbg)
+ return ERR_PTR(-ENOMEM);
mutex_init(&drbg->drbg_mutex);
+ return drbg;
+}
- return 0;
+struct drbg_state *crypto_drbg_alloc(void)
+{
+ int err = drbg_selftest();
+
+ if (err)
+ return ERR_PTR(err);
+ return __crypto_drbg_alloc();
}
+EXPORT_SYMBOL_NS_GPL(crypto_drbg_alloc, "CRYPTO_INTERNAL");
/* Set test entropy in the DRBG. */
-static void drbg_kcapi_set_entropy(struct crypto_rng *tfm,
- const u8 *data, unsigned int len)
+void crypto_drbg_set_entropy(struct drbg_state *drbg, const u8 *data,
+ size_t len)
{
- struct drbg_state *drbg = crypto_rng_ctx(tfm);
-
- mutex_lock(&drbg->drbg_mutex);
+ guard(mutex)(&drbg->drbg_mutex);
drbg->test_entropy = data;
drbg->test_entropylen = len;
- mutex_unlock(&drbg->drbg_mutex);
}
+EXPORT_SYMBOL_NS_GPL(crypto_drbg_set_entropy, "CRYPTO_INTERNAL");
/* Seed (i.e. instantiate) or re-seed the DRBG. */
-static int drbg_kcapi_seed(struct crypto_rng *tfm,
- const u8 *pers, unsigned int pers_len)
+int crypto_drbg_seed(struct drbg_state *drbg, const u8 *pers, size_t pers_len)
{
static const u8 initial_key[DRBG_STATE_LEN]; /* all zeroes */
- struct drbg_state *drbg = crypto_rng_ctx(tfm);
int ret;
pr_devel("DRBG: Initializing DRBG\n");
@@ -452,9 +464,9 @@ static int drbg_kcapi_seed(struct crypto_rng *tfm,
memset(drbg->V, 1, DRBG_STATE_LEN);
hmac_sha512_preparekey(&drbg->key, initial_key, DRBG_STATE_LEN);
- /* Allocate jitterentropy_rng if not in test mode. */
+ /* Allocate jitterentropy if not in test mode. */
if (drbg->test_entropylen == 0) {
- drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0);
+ drbg->jent = crypto_jent_alloc();
if (IS_ERR(drbg->jent)) {
ret = PTR_ERR(drbg->jent);
drbg->jent = NULL;
@@ -466,55 +478,109 @@ static int drbg_kcapi_seed(struct crypto_rng *tfm,
ret = drbg_seed(drbg, pers, pers_len, /* reseed= */ false);
if (ret) {
- crypto_free_rng(drbg->jent);
+ crypto_jent_free(drbg->jent);
drbg->jent = NULL;
return ret;
}
drbg->instantiated = true;
return 0;
}
+EXPORT_SYMBOL_NS_GPL(crypto_drbg_seed, "CRYPTO_INTERNAL");
-/*
- * Generate random numbers invoked by the kernel crypto API:
- *
- * src is additional input supplied to the RNG.
- * slen is the length of src.
- * dst is the output buffer where random data is to be stored.
- * dlen is the length of dst.
- */
-static int drbg_kcapi_generate(struct crypto_rng *tfm,
- const u8 *src, unsigned int slen,
- u8 *dst, unsigned int dlen)
+int crypto_drbg_get_bytes(struct drbg_state *drbg, u8 *out, size_t out_len,
+ const u8 *addtl, size_t addtl_len)
{
- struct drbg_state *drbg = crypto_rng_ctx(tfm);
-
/*
* Break the request into multiple requests if needed, to avoid
* exceeding the maximum request length of the core algorithm.
*/
- do {
- unsigned int n = min(dlen, DRBG_MAX_REQUEST_BYTES);
+ while (out_len) {
+ size_t n = min(out_len, DRBG_MAX_REQUEST_BYTES);
int err;
mutex_lock(&drbg->drbg_mutex);
- err = drbg_generate(drbg, dst, n, src, slen);
+ err = drbg_generate(drbg, out, n, addtl, addtl_len);
mutex_unlock(&drbg->drbg_mutex);
if (err < 0)
return err;
- dst += n;
- dlen -= n;
- } while (dlen);
+ out += n;
+ out_len -= n;
+ }
return 0;
}
+EXPORT_SYMBOL_NS_GPL(crypto_drbg_get_bytes, "CRYPTO_INTERNAL");
/* Uninstantiate the DRBG. */
-static void drbg_kcapi_exit(struct crypto_tfm *tfm)
+void crypto_drbg_free(struct drbg_state *drbg)
+{
+ if (!IS_ERR_OR_NULL(drbg)) {
+ mutex_destroy(&drbg->drbg_mutex);
+ crypto_jent_free(drbg->jent);
+ kfree_sensitive(drbg);
+ }
+}
+EXPORT_SYMBOL_NS_GPL(crypto_drbg_free, "CRYPTO_INTERNAL");
+
+#ifdef CONFIG_CRYPTO_FIPS
+static DEFINE_MUTEX(crypto_default_rng_lock);
+static struct drbg_state *crypto_default_rng;
+static int crypto_default_rng_refcnt;
+
+static int crypto_get_default_rng(void)
+{
+ struct drbg_state *drbg;
+ int err;
+
+ guard(mutex)(&crypto_default_rng_lock);
+ if (!crypto_default_rng) {
+ drbg = crypto_drbg_alloc();
+ if (IS_ERR(drbg))
+ return PTR_ERR(drbg);
+
+ err = crypto_drbg_seed(drbg, NULL, 0);
+ if (err) {
+ crypto_drbg_free(drbg);
+ return err;
+ }
+ crypto_default_rng = drbg;
+ }
+
+ crypto_default_rng_refcnt++;
+ return 0;
+}
+
+static void crypto_put_default_rng(void)
{
- struct drbg_state *drbg = crypto_tfm_ctx(tfm);
+ guard(mutex)(&crypto_default_rng_lock);
+ crypto_default_rng_refcnt--;
+}
- crypto_free_rng(drbg->jent);
- memzero_explicit(drbg, sizeof(*drbg));
+int __crypto_stdrng_get_bytes(void *buf, size_t len)
+{
+ int err;
+
+ err = crypto_get_default_rng();
+ if (err)
+ return err;
+
+ err = crypto_drbg_get_bytes(crypto_default_rng, buf, len, NULL, 0);
+ crypto_put_default_rng();
+ return err;
+}
+EXPORT_SYMBOL_GPL(__crypto_stdrng_get_bytes);
+
+int crypto_del_default_rng(void)
+{
+ guard(mutex)(&crypto_default_rng_lock);
+ if (crypto_default_rng_refcnt)
+ return -EBUSY;
+
+ crypto_drbg_free(crypto_default_rng);
+ crypto_default_rng = NULL;
+ return 0;
}
+EXPORT_SYMBOL_GPL(crypto_del_default_rng);
+#endif /* CONFIG_CRYPTO_FIPS */
/*
* Tests as defined in 11.3.2 in addition to the cipher tests: testing
@@ -526,20 +592,16 @@ static void drbg_kcapi_exit(struct crypto_tfm *tfm)
* Note 2: There is no sensible way of testing the reseed counter
* enforcement, so skip it.
*/
-static inline int __init drbg_healthcheck_sanity(void)
+static void drbg_healthcheck_sanity(void)
{
#define OUTBUFLEN 16
u8 buf[OUTBUFLEN];
struct drbg_state *drbg = NULL;
int ret;
- /* only perform test in FIPS mode */
- if (!fips_enabled)
- return 0;
-
drbg = kzalloc_obj(struct drbg_state);
if (!drbg)
- return -ENOMEM;
+ panic("DRBG: out of memory");
guard(mutex_init)(&drbg->drbg_mutex);
drbg->instantiated = true;
@@ -568,44 +630,110 @@ static inline int __init drbg_healthcheck_sanity(void)
pr_devel("DRBG: Sanity tests for failure code paths successfully "
"completed\n");
- kfree(drbg);
+ mutex_destroy(&drbg->drbg_mutex);
+ kfree_sensitive(drbg);
+}
+
+DEFINE_FREE(crypto_drbg_free, struct drbg_state *, crypto_drbg_free(_T))
+
+static int drbg_selftest_one_vec(const struct drbg_testvec *test)
+{
+ struct drbg_state *drbg __free(crypto_drbg_free) = NULL;
+ unsigned char *buf __free(kfree_sensitive) = NULL;
+ int err;
+
+ buf = kzalloc(test->expectedlen, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ drbg = __crypto_drbg_alloc();
+ if (IS_ERR(drbg))
+ return PTR_ERR(drbg);
+
+ crypto_drbg_set_entropy(drbg, test->entropy, test->entropylen);
+ err = crypto_drbg_seed(drbg, test->pers, test->perslen);
+ if (err) {
+ pr_err("DRBG: Instantiation failed: %d\n", err);
+ return err;
+ }
+
+ if (test->ent_reseed_len) {
+ crypto_drbg_set_entropy(drbg, test->ent_reseed,
+ test->ent_reseed_len);
+ err = crypto_drbg_seed(drbg, test->addtl_reseed,
+ test->addtl_reseed_len);
+ if (err) {
+ pr_err("DRBG: Reseed failed: %d\n", err);
+ return err;
+ }
+ }
+
+ err = crypto_drbg_get_bytes(drbg, buf, test->expectedlen, test->addtla,
+ test->addtllen);
+ if (err) {
+ pr_err("DRBG: Generation failed (first): %d\n", err);
+ return err;
+ }
+
+ err = crypto_drbg_get_bytes(drbg, buf, test->expectedlen, test->addtlb,
+ test->addtllen);
+ if (err) {
+ pr_err("DRBG: Generation failed (second): %d\n", err);
+ return err;
+ }
+
+ if (memcmp(test->expected, buf, test->expectedlen) != 0) {
+ pr_err("DRBG: Actual output doesn't match expected output\n");
+ return -ELIBBAD;
+ }
return 0;
}
-static struct rng_alg drbg_alg = {
- .base.cra_name = "stdrng",
- .base.cra_driver_name = "drbg_nopr_hmac_sha512",
- .base.cra_priority = 201,
- .base.cra_ctxsize = sizeof(struct drbg_state),
- .base.cra_module = THIS_MODULE,
- .base.cra_init = drbg_kcapi_init,
- .set_ent = drbg_kcapi_set_entropy,
- .seed = drbg_kcapi_seed,
- .generate = drbg_kcapi_generate,
- .base.cra_exit = drbg_kcapi_exit,
-};
+static int drbg_selftest_err;
-static int __init drbg_init(void)
+static void drbg_selftest_once(void)
{
- int ret;
+ if (!fips_enabled && !IS_ENABLED(CONFIG_CRYPTO_SELFTESTS))
+ return;
- ret = drbg_healthcheck_sanity();
- if (ret)
- return ret;
+ if (fips_enabled)
+ drbg_healthcheck_sanity();
- /*
- * In FIPS mode, boost the algorithm priority to ensure that when users
- * request "stdrng", they really get the algorithm from here.
- */
+ for (size_t i = 0; i < ARRAY_SIZE(drbg_testvecs); i++) {
+ int err = drbg_selftest_one_vec(&drbg_testvecs[i]);
+
+ if (err) {
+ if (fips_enabled)
+ panic("DRBG self-test %zu failed: %d\n", i,
+ err);
+ else
+ WARN(1, "DRBG self-test %zu failed: %d\n", i,
+ err);
+ drbg_selftest_err = err;
+ break;
+ }
+ }
if (fips_enabled)
- drbg_alg.base.cra_priority += 2000;
+ pr_info("DRBG: self-tests passed\n");
+}
+
+static int drbg_selftest(void)
+{
+ DO_ONCE_SLEEPABLE(drbg_selftest_once);
+ return drbg_selftest_err;
+}
- return crypto_register_rng(&drbg_alg);
+static int __init drbg_init(void)
+{
+ return drbg_selftest();
}
static void __exit drbg_exit(void)
{
- crypto_unregister_rng(&drbg_alg);
+ /*
+ * Note there's no need to call crypto_del_default_rng() from here, as
+ * it can exist only when this file is built-in.
+ */
}
module_init(drbg_init);
@@ -613,5 +741,4 @@ module_exit(drbg_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
MODULE_DESCRIPTION("NIST SP800-90A Deterministic Random Bit Generator (DRBG)");
-MODULE_ALIAS_CRYPTO("stdrng");
-MODULE_ALIAS_CRYPTO("drbg_nopr_hmac_sha512");
+MODULE_IMPORT_NS("CRYPTO_INTERNAL"); /* for jitterentropy */
diff --git a/crypto/drbg.h b/crypto/drbg.h
new file mode 100644
index 000000000000..f07a36237404
--- /dev/null
+++ b/crypto/drbg.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright 2026 Google LLC
+ */
+#ifndef _CRYPTO_DRBG_H
+#define _CRYPTO_DRBG_H
+
+#include <linux/types.h>
+
+struct drbg_state;
+
+struct drbg_state *crypto_drbg_alloc(void);
+void crypto_drbg_set_entropy(struct drbg_state *drbg, const u8 *data,
+ size_t len);
+int crypto_drbg_seed(struct drbg_state *drbg, const u8 *pers, size_t pers_len);
+int crypto_drbg_get_bytes(struct drbg_state *drbg, u8 *out, size_t out_len,
+ const u8 *addtl, size_t addtl_len);
+void crypto_drbg_free(struct drbg_state *drbg);
+
+#endif /* _CRYPTO_DRBG_H */
diff --git a/crypto/ecc.c b/crypto/ecc.c
index c7366eb7ce1f..6696bf0d90a6 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -1614,20 +1614,26 @@ int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
{
int ret = 0;
struct ecc_point *pk;
+ u64 rand_z[ECC_MAX_DIGITS];
+ unsigned int nbytes;
const struct ecc_curve *curve = ecc_get_curve(curve_id);
- if (!private_key) {
+ if (!private_key || ndigits > ARRAY_SIZE(rand_z)) {
ret = -EINVAL;
goto out;
}
+ nbytes = ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
+
+ get_random_bytes(rand_z, nbytes);
+
pk = ecc_alloc_point(ndigits);
if (!pk) {
ret = -ENOMEM;
goto out;
}
- ecc_point_mult(pk, &curve->g, private_key, NULL, curve, ndigits);
+ ecc_point_mult(pk, &curve->g, private_key, rand_z, curve, ndigits);
/* SP800-56A rev 3 5.6.2.1.3 key check */
if (ecc_is_pubkey_valid_full(curve, pk)) {
@@ -1641,6 +1647,7 @@ int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
err_free_point:
ecc_free_point(pk);
out:
+ memzero_explicit(rand_z, sizeof(rand_z));
return ret;
}
EXPORT_SYMBOL(ecc_make_pub_key);
diff --git a/crypto/geniv.c b/crypto/geniv.c
index 04befe3a7f44..a5c3efda1ae8 100644
--- a/crypto/geniv.c
+++ b/crypto/geniv.c
@@ -8,7 +8,7 @@
*/
#include <crypto/internal/geniv.h>
-#include <crypto/internal/rng.h>
+#include <crypto/rng.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index 652852649a31..1311df988222 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -1,6 +1,6 @@
/*
* Non-physical true random number generator based on timing jitter --
- * Linux Kernel Crypto API specific code
+ * Public API
*
* Copyright Stephan Mueller <smueller@chronox.de>, 2015 - 2023
*
@@ -44,9 +44,9 @@
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/time.h>
-#include <crypto/internal/rng.h>
#include "jitterentropy.h"
+#include "jitterentropy-kcapi.h"
/***************************************************************************
* Helper function
@@ -169,7 +169,7 @@ void jent_read_random_block(struct sha3_ctx *hash_state, char *dst,
}
/***************************************************************************
- * Kernel crypto API interface
+ * Public API
***************************************************************************/
struct jitterentropy {
@@ -178,24 +178,66 @@ struct jitterentropy {
struct sha3_ctx hash_state;
};
-static void jent_kcapi_cleanup(struct crypto_tfm *tfm)
+static int jent_init_err;
+
+static void jent_init_once(void)
{
- struct jitterentropy *rng = crypto_tfm_ctx(tfm);
+ struct sha3_ctx hash_state;
+ int err;
+
+ sha3_256_init(&hash_state);
+ err = jent_entropy_init(CONFIG_CRYPTO_JITTERENTROPY_OSR, 0, &hash_state,
+ NULL);
+ memzero_explicit(&hash_state, sizeof(hash_state));
+ if (err) {
+ /* Handle permanent health test error */
+ if (fips_enabled)
+ panic("jitterentropy: Initialization failed with host not compliant with requirements: %d\n",
+ err);
- mutex_lock(&rng->jent_lock);
+ pr_info("jitterentropy: Initialization failed with host not compliant with requirements: %d\n",
+ err);
+ jent_init_err = err;
+ }
+}
- memzero_explicit(&rng->hash_state, sizeof(rng->hash_state));
+static int jent_init(void)
+{
+ static DEFINE_MUTEX(jent_init_mutex);
+ static bool initialized;
- if (rng->entropy_collector)
- jent_entropy_collector_free(rng->entropy_collector);
- rng->entropy_collector = NULL;
- mutex_unlock(&rng->jent_lock);
+ /*
+ * To avoid lockdep reports of inconsistent ordering of drbg_mutex and
+ * once_mutex, implement one-time-init locally instead of using
+ * DO_ONCE_SLEEPABLE.
+ */
+ guard(mutex)(&jent_init_mutex);
+ if (!initialized) {
+ jent_init_once();
+ initialized = true;
+ }
+ if (jent_init_err) {
+ /*
+ * jent_init_err is a private custom error code from
+ * jitterentropy.c. Select an errno value instead.
+ */
+ return -EOPNOTSUPP;
+ }
+ return 0;
}
-static int jent_kcapi_init(struct crypto_tfm *tfm)
+struct jitterentropy *crypto_jent_alloc(void)
{
- struct jitterentropy *rng = crypto_tfm_ctx(tfm);
- int ret = 0;
+ struct jitterentropy *rng;
+ int err;
+
+ err = jent_init();
+ if (err)
+ return ERR_PTR(err);
+
+ rng = kzalloc_obj(*rng);
+ if (!rng)
+ return ERR_PTR(-ENOMEM);
mutex_init(&rng->jent_lock);
@@ -205,27 +247,21 @@ static int jent_kcapi_init(struct crypto_tfm *tfm)
rng->entropy_collector = jent_entropy_collector_alloc(
CONFIG_CRYPTO_JITTERENTROPY_OSR, 0, &rng->hash_state);
if (!rng->entropy_collector) {
- ret = -ENOMEM;
- goto err;
+ crypto_jent_free(rng);
+ return ERR_PTR(-ENOMEM);
}
-
- return 0;
-
-err:
- jent_kcapi_cleanup(tfm);
- return ret;
+ return rng;
}
+EXPORT_SYMBOL_NS_GPL(crypto_jent_alloc, "CRYPTO_INTERNAL");
-static int jent_kcapi_random(struct crypto_rng *tfm,
- const u8 *src, unsigned int slen,
- u8 *rdata, unsigned int dlen)
+int crypto_jent_get_bytes(struct jitterentropy *rng, u8 *out,
+ unsigned int out_len)
{
- struct jitterentropy *rng = crypto_rng_ctx(tfm);
- int ret = 0;
+ int ret;
- mutex_lock(&rng->jent_lock);
+ guard(mutex)(&rng->jent_lock);
- ret = jent_read_entropy(rng->entropy_collector, rdata, dlen);
+ ret = jent_read_entropy(rng->entropy_collector, out, out_len);
if (ret == -3) {
/* Handle permanent health test error */
@@ -239,70 +275,41 @@ static int jent_kcapi_random(struct crypto_rng *tfm,
panic("Jitter RNG permanent health test failure\n");
pr_err("Jitter RNG permanent health test failure\n");
- ret = -EFAULT;
- } else if (ret == -2) {
+ return -EFAULT;
+ }
+ if (ret == -2) {
/* Handle intermittent health test error */
pr_warn_ratelimited("Reset Jitter RNG due to intermittent health test failure\n");
- ret = -EAGAIN;
- } else if (ret == -1) {
+ return -EAGAIN;
+ }
+ if (ret == -1) {
/* Handle other errors */
- ret = -EINVAL;
+ return -EINVAL;
}
-
- mutex_unlock(&rng->jent_lock);
-
return ret;
}
+EXPORT_SYMBOL_NS_GPL(crypto_jent_get_bytes, "CRYPTO_INTERNAL");
-static int jent_kcapi_reset(struct crypto_rng *tfm,
- const u8 *seed, unsigned int slen)
+void crypto_jent_free(struct jitterentropy *rng)
{
- return 0;
-}
-
-static struct rng_alg jent_alg = {
- .generate = jent_kcapi_random,
- .seed = jent_kcapi_reset,
- .seedsize = 0,
- .base = {
- .cra_name = "jitterentropy_rng",
- .cra_driver_name = "jitterentropy_rng",
- .cra_priority = 100,
- .cra_ctxsize = sizeof(struct jitterentropy),
- .cra_module = THIS_MODULE,
- .cra_init = jent_kcapi_init,
- .cra_exit = jent_kcapi_cleanup,
+ if (!IS_ERR_OR_NULL(rng)) {
+ mutex_destroy(&rng->jent_lock);
+ if (rng->entropy_collector)
+ jent_entropy_collector_free(rng->entropy_collector);
+ kfree_sensitive(rng);
}
-};
+}
+EXPORT_SYMBOL_NS_GPL(crypto_jent_free, "CRYPTO_INTERNAL");
static int __init jent_mod_init(void)
{
- struct sha3_ctx hash_state;
- int ret = 0;
-
jent_testing_init();
-
- sha3_256_init(&hash_state);
-
- ret = jent_entropy_init(CONFIG_CRYPTO_JITTERENTROPY_OSR, 0, &hash_state,
- NULL);
- memzero_explicit(&hash_state, sizeof(hash_state));
- if (ret) {
- /* Handle permanent health test error */
- if (fips_enabled)
- panic("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
-
- jent_testing_exit();
- pr_info("jitterentropy: Initialization failed with host not compliant with requirements: %d\n", ret);
- return -EFAULT;
- }
- return crypto_register_rng(&jent_alg);
+ return 0;
}
static void __exit jent_mod_exit(void)
{
jent_testing_exit();
- crypto_unregister_rng(&jent_alg);
}
module_init(jent_mod_init);
@@ -311,4 +318,3 @@ module_exit(jent_mod_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
MODULE_DESCRIPTION("Non-physical True Random Number Generator based on CPU Jitter");
-MODULE_ALIAS_CRYPTO("jitterentropy_rng");
diff --git a/crypto/jitterentropy-kcapi.h b/crypto/jitterentropy-kcapi.h
new file mode 100644
index 000000000000..9909df28ed7a
--- /dev/null
+++ b/crypto/jitterentropy-kcapi.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright 2026 Google LLC
+ */
+#ifndef _CRYPTO_JITTERENTROPY_KCAPI_H
+#define _CRYPTO_JITTERENTROPY_KCAPI_H
+
+#include <linux/types.h>
+
+struct jitterentropy;
+
+struct jitterentropy *crypto_jent_alloc(void);
+int crypto_jent_get_bytes(struct jitterentropy *rng, u8 *out,
+ unsigned int out_len);
+void crypto_jent_free(struct jitterentropy *rng);
+
+#endif /* _CRYPTO_JITTERENTROPY_KCAPI_H */
diff --git a/crypto/lz4.c b/crypto/lz4.c
index 57b713516aef..c37e29afc831 100644
--- a/crypto/lz4.c
+++ b/crypto/lz4.c
@@ -35,7 +35,7 @@ static int __lz4_compress_crypto(const u8 *src, unsigned int slen,
slen, *dlen, ctx);
if (!out_len)
- return -EINVAL;
+ return -ENOSPC;
*dlen = out_len;
return 0;
diff --git a/crypto/lz4hc.c b/crypto/lz4hc.c
index bb84f8a68cb5..3098466eb72a 100644
--- a/crypto/lz4hc.c
+++ b/crypto/lz4hc.c
@@ -33,7 +33,7 @@ static int __lz4hc_compress_crypto(const u8 *src, unsigned int slen,
*dlen, LZ4HC_DEFAULT_CLEVEL, ctx);
if (!out_len)
- return -EINVAL;
+ return -ENOSPC;
*dlen = out_len;
return 0;
diff --git a/crypto/lzo-rle.c b/crypto/lzo-rle.c
index 794e7ec49536..483327873efd 100644
--- a/crypto/lzo-rle.c
+++ b/crypto/lzo-rle.c
@@ -34,7 +34,7 @@ static int __lzorle_compress(const u8 *src, unsigned int slen,
err = lzorle1x_1_compress_safe(src, slen, dst, &tmp_len, ctx);
if (err != LZO_E_OK)
- return -EINVAL;
+ return err == LZO_E_OUTPUT_OVERRUN ? -ENOSPC : -EINVAL;
*dlen = tmp_len;
return 0;
diff --git a/crypto/lzo.c b/crypto/lzo.c
index d43242b24b4e..378b491b0cbd 100644
--- a/crypto/lzo.c
+++ b/crypto/lzo.c
@@ -34,7 +34,7 @@ static int __lzo_compress(const u8 *src, unsigned int slen,
err = lzo1x_1_compress_safe(src, slen, dst, &tmp_len, ctx);
if (err != LZO_E_OK)
- return -EINVAL;
+ return err == LZO_E_OUTPUT_OVERRUN ? -ENOSPC : -EINVAL;
*dlen = tmp_len;
return 0;
diff --git a/crypto/rng.c b/crypto/rng.c
deleted file mode 100644
index 828b0d807473..000000000000
--- a/crypto/rng.c
+++ /dev/null
@@ -1,245 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Cryptographic API.
- *
- * RNG operations.
- *
- * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com>
- * Copyright (c) 2015 Herbert Xu <herbert@gondor.apana.org.au>
- */
-
-#include <crypto/internal/rng.h>
-#include <linux/atomic.h>
-#include <linux/cryptouser.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/random.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <net/netlink.h>
-
-#include "internal.h"
-
-static DEFINE_MUTEX(crypto_default_rng_lock);
-static struct crypto_rng *crypto_default_rng;
-static int crypto_default_rng_refcnt;
-
-int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen)
-{
- u8 *buf = NULL;
- int err;
-
- if (!seed && slen) {
- buf = kmalloc(slen, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- err = get_random_bytes_wait(buf, slen);
- if (err)
- goto out;
- seed = buf;
- }
-
- err = crypto_rng_alg(tfm)->seed(tfm, seed, slen);
-out:
- kfree_sensitive(buf);
- return err;
-}
-EXPORT_SYMBOL_GPL(crypto_rng_reset);
-
-static int crypto_rng_init_tfm(struct crypto_tfm *tfm)
-{
- return 0;
-}
-
-static unsigned int seedsize(struct crypto_alg *alg)
-{
- struct rng_alg *ralg = container_of(alg, struct rng_alg, base);
-
- return ralg->seedsize;
-}
-
-static int __maybe_unused crypto_rng_report(
- struct sk_buff *skb, struct crypto_alg *alg)
-{
- struct crypto_report_rng rrng = {
- .type = "rng",
- };
-
- rrng.seedsize = seedsize(alg);
-
- return nla_put(skb, CRYPTOCFGA_REPORT_RNG, sizeof(rrng), &rrng);
-}
-
-static void __maybe_unused crypto_rng_show(struct seq_file *m,
- struct crypto_alg *alg)
-{
- seq_printf(m, "type : rng\n");
- seq_printf(m, "seedsize : %u\n", seedsize(alg));
-}
-
-static const struct crypto_type crypto_rng_type = {
- .extsize = crypto_alg_extsize,
- .init_tfm = crypto_rng_init_tfm,
-#ifdef CONFIG_PROC_FS
- .show = crypto_rng_show,
-#endif
-#if IS_ENABLED(CONFIG_CRYPTO_USER)
- .report = crypto_rng_report,
-#endif
- .maskclear = ~CRYPTO_ALG_TYPE_MASK,
- .maskset = CRYPTO_ALG_TYPE_MASK,
- .type = CRYPTO_ALG_TYPE_RNG,
- .tfmsize = offsetof(struct crypto_rng, base),
- .algsize = offsetof(struct rng_alg, base),
-};
-
-struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask)
-{
- return crypto_alloc_tfm(alg_name, &crypto_rng_type, type, mask);
-}
-EXPORT_SYMBOL_GPL(crypto_alloc_rng);
-
-static int crypto_get_default_rng(void)
-{
- struct crypto_rng *rng;
- int err;
-
- mutex_lock(&crypto_default_rng_lock);
- if (!crypto_default_rng) {
- rng = crypto_alloc_rng("stdrng", 0, 0);
- err = PTR_ERR(rng);
- if (IS_ERR(rng))
- goto unlock;
-
- err = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
- if (err) {
- crypto_free_rng(rng);
- goto unlock;
- }
-
- crypto_default_rng = rng;
- }
-
- crypto_default_rng_refcnt++;
- err = 0;
-
-unlock:
- mutex_unlock(&crypto_default_rng_lock);
-
- return err;
-}
-
-static void crypto_put_default_rng(void)
-{
- mutex_lock(&crypto_default_rng_lock);
- crypto_default_rng_refcnt--;
- mutex_unlock(&crypto_default_rng_lock);
-}
-
-int __crypto_stdrng_get_bytes(void *buf, unsigned int len)
-{
- int err;
-
- err = crypto_get_default_rng();
- if (err)
- return err;
-
- err = crypto_rng_get_bytes(crypto_default_rng, buf, len);
- crypto_put_default_rng();
- return err;
-}
-EXPORT_SYMBOL_GPL(__crypto_stdrng_get_bytes);
-
-#if defined(CONFIG_CRYPTO_RNG) || defined(CONFIG_CRYPTO_RNG_MODULE)
-int crypto_del_default_rng(void)
-{
- int err = -EBUSY;
-
- mutex_lock(&crypto_default_rng_lock);
- if (crypto_default_rng_refcnt)
- goto out;
-
- crypto_free_rng(crypto_default_rng);
- crypto_default_rng = NULL;
-
- err = 0;
-
-out:
- mutex_unlock(&crypto_default_rng_lock);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(crypto_del_default_rng);
-#endif
-
-static void rng_default_set_ent(struct crypto_rng *tfm, const u8 *data,
- unsigned int len)
-{
-}
-
-int crypto_register_rng(struct rng_alg *alg)
-{
- struct crypto_alg *base = &alg->base;
-
- if (alg->seedsize > PAGE_SIZE / 8)
- return -EINVAL;
-
- base->cra_type = &crypto_rng_type;
- base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
- base->cra_flags |= CRYPTO_ALG_TYPE_RNG;
-
- if (!alg->set_ent)
- alg->set_ent = rng_default_set_ent;
-
- return crypto_register_alg(base);
-}
-EXPORT_SYMBOL_GPL(crypto_register_rng);
-
-void crypto_unregister_rng(struct rng_alg *alg)
-{
- crypto_unregister_alg(&alg->base);
-}
-EXPORT_SYMBOL_GPL(crypto_unregister_rng);
-
-int crypto_register_rngs(struct rng_alg *algs, int count)
-{
- int i, ret;
-
- for (i = 0; i < count; i++) {
- ret = crypto_register_rng(algs + i);
- if (ret) {
- crypto_unregister_rngs(algs, i);
- return ret;
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(crypto_register_rngs);
-
-void crypto_unregister_rngs(struct rng_alg *algs, int count)
-{
- int i;
-
- for (i = count - 1; i >= 0; --i)
- crypto_unregister_rng(algs + i);
-}
-EXPORT_SYMBOL_GPL(crypto_unregister_rngs);
-
-static void __exit rng_exit(void)
-{
- int err;
-
- err = crypto_del_default_rng();
- if (err)
- pr_err("Failed delete default RNG: %d\n", err);
-}
-
-module_exit(rng_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Random Number Generator");
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index e6834bdde9b9..579a05d39856 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -1579,10 +1579,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
ret = min(ret, tcrypt_test("xts(cast6)"));
break;
- case 16:
- ret = min(ret, tcrypt_test("ecb(arc4)"));
- break;
-
case 18:
ret = min(ret, tcrypt_test("crc32c"));
break;
@@ -1995,11 +1991,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
speed_template_32_64);
break;
- case 208:
- test_cipher_speed("ecb(arc4)", ENCRYPT, sec, NULL, 0,
- speed_template_8);
- break;
-
case 209:
test_cipher_speed("ecb(cast5)", ENCRYPT, sec, NULL, 0,
speed_template_8_16);
@@ -2486,11 +2477,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
speed_template_32_48_64);
break;
- case 505:
- test_acipher_speed("ecb(arc4)", ENCRYPT, sec, NULL, 0,
- speed_template_8);
- break;
-
case 506:
test_acipher_speed("ecb(cast5)", ENCRYPT, sec, NULL, 0,
speed_template_8_16);
@@ -2709,11 +2695,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
speed_template_32_48_64, num_mb);
break;
- case 605:
- test_mb_skcipher_speed("ecb(arc4)", ENCRYPT, sec, NULL, 0,
- speed_template_8, num_mb);
- break;
-
case 606:
test_mb_skcipher_speed("ecb(cast5)", ENCRYPT, sec, NULL, 0,
speed_template_8_16, num_mb);
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 9419d61d0602..417977f12735 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -33,7 +33,6 @@
#include <crypto/acompress.h>
#include <crypto/sig.h>
#include <crypto/internal/cipher.h>
-#include <crypto/internal/rng.h>
#include <crypto/internal/simd.h>
#include "internal.h"
@@ -116,11 +115,6 @@ struct hash_test_suite {
unsigned int count;
};
-struct drbg_test_suite {
- const struct drbg_testvec *vecs;
- unsigned int count;
-};
-
struct akcipher_test_suite {
const struct akcipher_testvec *vecs;
unsigned int count;
@@ -148,7 +142,6 @@ struct alg_test_desc {
struct cipher_test_suite cipher;
struct comp_test_suite comp;
struct hash_test_suite hash;
- struct drbg_test_suite drbg;
struct akcipher_test_suite akcipher;
struct sig_test_suite sig;
struct kpp_test_suite kpp;
@@ -3481,90 +3474,6 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver,
return err;
}
-static int drbg_cavs_test(const struct drbg_testvec *test, const char *driver,
- u32 type, u32 mask)
-{
- int ret = -EAGAIN;
- struct crypto_rng *drng;
- unsigned char *buf = kzalloc(test->expectedlen, GFP_KERNEL);
-
- if (!buf)
- return -ENOMEM;
-
- drng = crypto_alloc_rng(driver, type, mask);
- if (IS_ERR(drng)) {
- kfree_sensitive(buf);
- if (PTR_ERR(drng) == -ENOENT)
- return 0;
- printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for "
- "%s\n", driver);
- return PTR_ERR(drng);
- }
-
- crypto_rng_set_entropy(drng, test->entropy, test->entropylen);
- ret = crypto_rng_reset(drng, test->pers, test->perslen);
- if (ret) {
- printk(KERN_ERR "alg: drbg: Failed to instantiate rng\n");
- goto outbuf;
- }
-
- if (test->ent_reseed_len) {
- crypto_rng_set_entropy(drng, test->ent_reseed,
- test->ent_reseed_len);
- ret = crypto_rng_reset(drng, test->addtl_reseed,
- test->addtl_reseed_len);
- if (ret) {
- printk(KERN_ERR "alg: drbg: Failed to reseed rng\n");
- goto outbuf;
- }
- }
-
- ret = crypto_rng_generate(drng, test->addtla, test->addtllen,
- buf, test->expectedlen);
- if (ret < 0) {
- printk(KERN_ERR "alg: drbg: could not obtain random data for "
- "driver %s\n", driver);
- goto outbuf;
- }
-
- ret = crypto_rng_generate(drng, test->addtlb, test->addtllen,
- buf, test->expectedlen);
- if (ret < 0) {
- printk(KERN_ERR "alg: drbg: could not obtain random data for "
- "driver %s\n", driver);
- goto outbuf;
- }
-
- ret = memcmp(test->expected, buf, test->expectedlen);
-
-outbuf:
- crypto_free_rng(drng);
- kfree_sensitive(buf);
- return ret;
-}
-
-
-static int alg_test_drbg(const struct alg_test_desc *desc, const char *driver,
- u32 type, u32 mask)
-{
- int err = 0;
- int i = 0;
- const struct drbg_testvec *template = desc->suite.drbg.vecs;
- unsigned int tcount = desc->suite.drbg.count;
-
- for (i = 0; i < tcount; i++) {
- err = drbg_cavs_test(&template[i], driver, type, mask);
- if (err) {
- printk(KERN_ERR "alg: drbg: Test %d failed for %s\n",
- i, driver);
- err = -EINVAL;
- break;
- }
- }
- return err;
-
-}
-
static int do_test_kpp(struct crypto_kpp *tfm, const struct kpp_testvec *vec,
const char *alg)
{
@@ -4645,13 +4554,6 @@ static const struct alg_test_desc alg_test_descs[] = {
.alg = "digest_null",
.test = alg_test_null,
}, {
- .alg = "drbg_nopr_hmac_sha512",
- .test = alg_test_drbg,
- .fips_allowed = 1,
- .suite = {
- .drbg = __VECS(drbg_nopr_hmac_sha512_tv_template)
- }
- }, {
.alg = "ecb(aes)",
.generic_driver = "ecb(aes-lib)",
.test = alg_test_skcipher,
@@ -4666,13 +4568,6 @@ static const struct alg_test_desc alg_test_descs[] = {
.cipher = __VECS(anubis_tv_template)
}
}, {
- .alg = "ecb(arc4)",
- .generic_driver = "arc4-generic",
- .test = alg_test_skcipher,
- .suite = {
- .cipher = __VECS(arc4_tv_template)
- }
- }, {
.alg = "ecb(aria)",
.test = alg_test_skcipher,
.suite = {
@@ -5022,10 +4917,6 @@ static const struct alg_test_desc alg_test_descs[] = {
.hash = __VECS(hmac_streebog512_tv_template)
}
}, {
- .alg = "jitterentropy_rng",
- .fips_allowed = 1,
- .test = alg_test_null,
- }, {
.alg = "krb5enc(cmac(camellia),cts(cbc(camellia)))",
.test = alg_test_aead,
.suite.aead = __VECS(krb5_test_camellia_cts_cmac)
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 0ee15a8fae27..14b0e1181b7b 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -119,29 +119,6 @@ struct aead_testvec {
int crypt_error;
};
-struct drbg_testvec {
- /* Instantiate */
- const unsigned char *entropy;
- size_t entropylen;
- const unsigned char *pers;
- size_t perslen;
-
- /* Reseed (optional) */
- const unsigned char *ent_reseed;
- size_t ent_reseed_len;
- const unsigned char *addtl_reseed;
- size_t addtl_reseed_len;
-
- /* Generate (twice) */
- const unsigned char *addtla;
- const unsigned char *addtlb;
- size_t addtllen;
-
- /* Expected output from last call to Generate */
- const unsigned char *expected;
- size_t expectedlen;
-};
-
struct akcipher_testvec {
const unsigned char *key;
const unsigned char *m;
@@ -23755,201 +23732,6 @@ static const struct aead_testvec aegis128_tv_template[] = {
},
};
-static const struct drbg_testvec drbg_nopr_hmac_sha512_tv_template[] = {
- /*
- * Borrowed from the first applicable test vector from ACVP:
- * https://github.com/usnistgov/ACVP-Server/blob/v1.1.0.33/gen-val/json-files/hmacDRBG-1.0/prompt.json#L4596
- * https://github.com/usnistgov/ACVP-Server/blob/v1.1.0.33/gen-val/json-files/hmacDRBG-1.0/expectedResults.json#L986
- */
- {
- /* .entropy = ACVP entropyInput || nonce */
- .entropy = "\x47\x28\x33\x05\x82\xE8\xA7\x58\x05\xBD\x07\x9E"
- "\xDB\x59\x87\x08\x3B\x82\x40\x70\xA1\xB7\x33\x4F"
- "\x0F\x53\xBE\xF6\x98\x75\xFA\x21\x00\x04\xBC\x58"
- "\x9B\xB1\xB3\xBC\x2A\xF6\xA4\x2A\xE1\xB3\x65\x24"
- "\xA8\xEE\x56\x70\x5E\x28\x06\x04\x80\xCE\xB7\x36"
- "\xA4\xD1\x4E\xAA\xE7\xE8\x51\x40\x7D\x30\xF7\x91"
- "\xF2\x9E\x98\xA7\xBB\xB3\x1D\xC6\x8A\x62\xC7\xE7"
- "\x1F\xE1\x0A\x52\x45\x39\x88\x92\x43\xA6\x5B\xC3"
- "\x9D\x60\xDE\xFE\x79\xEF\x87\x6F\xD5\x76\x51\x69"
- "\x7B\x4C\x3D\x08\x60\xFA\xDC\x00\x94\xEC\x0A\xC5"
- "\xE7\xCB\x30\x05\x9F\xCC\x07\x44\x07\x14\xF4\xF9"
- "\xBC\x7D\xC0\x66\x63\x5B\xD3\x2A\xA7\xF2\x1D\x75"
- "\x3F\x28\x5F\x4A\xEB\x63\xD7\x92\x5A\x9A\x7C\x3A"
- "\x56\xEA\xCB\xA9\xA0\xF9\x5B\x99\xC2\x7D\x31\xBF"
- "\x44\xC7\x64\x6B\x7E\x64\x60\x64\x05\x86\xF0\x6B"
- "\x76\xA7\x3E\x63\xAD\xB6\x76\xED\x3D\x05\x2E\xC7"
- "\xC7\x52\x8F\x07\x56\x23\xFC\x2F\x93\xD5\xF2\x29"
- "\xC6\x84\x48\xD1\x88\xB9\x3F\x84\xB2\x93\xFC\x2F"
- "\x00\xB1\xBC\xBE\xAC\xC4\x94\x36\xF1\x2B\xF0\xC7"
- "\x36\xE8\x1D\x45\x0A\xA2\xFE\x72\xD7\x3E\x15\x6A"
- "\x74\x23\xB2\xD1\x3C\x20\xF2\xB7\x19\xC5\xF0\x74"
- "\x69\x06\xD1\x92\x47\xC9\x68\xDC\xEE\xBC\xF4\x3A"
- "\x8B\x7C\xA4\xA4\x4A\x15\xF4\xF0\x26\x26\xC5\x7D"
- "\x57\xDC\x00\x59\x07\xDF\x84\x2A\x23\xA9\xC1\xAF"
- "\x47\x49\x88\xCC\x2F\x3B\x90\x39\xA0\x09\xAE\x3C"
- "\x79\xF9\x97\x9D\xEF\x13\x1D\x2B\xB6\x18\xDB\xCF"
- "\x95\x98\x17\x7F\xF6\x95\x44\x3A\x40\x90\x63\x16"
- "\x70\x38\x22\xC5\xD8\xE4\x57\xA0\x8E\x51\x6B\xED"
- "\x03\x18\xC6\x74\xFA\xCA\xF2\xD5\xB2\x5A\x0C\x02"
- "\x48\x9F\x70\x0B\x1C\x0A\xD1\xD6\x4F\x3F\x70\x3C"
- "\x1A\x62\x29\x63\xD0\x92\x76\x30\x7C\xB9\x54\xEC"
- "\xF6\x92\xA3\x11\x66\xB2\x56\xE0\x75\x3D\x27\x01",
- .entropylen = 384,
- .pers = "\x03\x75\x33\x7B\x6B\xE5\x14\xAF\x0E\x43\x33\xCC\xD3"
- "\xF4\xF0\x8B\x8A\xCC\xFE\x95\xC1\x20\xB9\x56\x3D\x2C"
- "\x34\xC7\xA1\x4C\xBC\xDC\x0A\x8D\xBE\x68\x28\x89\x2A"
- "\x92\x10\x05\x4E\xF9\xE2\x51\xF7\x4F\xF4\x48\x76\xC9"
- "\xCE\xA8\x6D\xC1\xDE\x5C\x05\x95\x77\x24\xB4\x5D\x3D"
- "\x16\x1D\xCB\x43\xE5\xD3\x01\x96\xCC\x3E\x2E\xE1\x97"
- "\xB3\x42\xC2\xAB\xEC\x56\xA9\xF9\xF2\x28\x59\x01\x4E"
- "\xFC\x8A\xC0\x5E\x4E\x33\x30\x91\x96\x93\xBA\xFA\xE1"
- "\x9F\x20\xC3\xC1\xD1\xC6\xC3\x2C\x59\x8F\x56\xD5\x73"
- "\xE8\x8D\xCF\xAC\xB1\x85\x3E\xC7\x73\x21\x59\x8D\x0F"
- "\xF4\xA4\xC4\x0C\xD2\x18\x81\x5F\x3E\x37\xC9\x9F\xD9"
- "\xDE\x3F\x15\x6F\xAC\x1A\xEC\x5E\x28\xD5\x56\xA2\x65"
- "\xD2\x7C\x41\xDE\x57\x8C\x60\xAB\xA5\x03\x42\xC8\x3C"
- "\x70\xC2\xD1\x11\x62\x25\x4E\x17\x58\xBB\x08\x51\x79"
- "\xE6\xED\xBA\x9A\xA7\x07\xD5\x0E\x89\x43\x31\x4F\x99"
- "\xEE\xED\xF1\x36\xFA\x1E\xC0\x25\x01\xDA\x19\xC2\x7D"
- "\x5D\x78\x74\x5C\xC0\x72\x2E\xF1\x7B\x4E\x9C\xDB\xFE"
- "\x60\x89\x62\x71\x9C\xEA\xD3\xDF\x82\xC7\x8B\xB4\x7B"
- "\x7B\x7F\x6A\x62\x3C\x57\x76\xA5\x67\x5F\x70\xFB\xE0"
- "\x1B\x23\x79\x71\xB5\x7C\xEA\x76\x99",
- .perslen = 256,
-
- .ent_reseed = "\xE0\x5B\x69\xC5\xF9\xD4\x5A\x1F\xC1\x71\x0C"
- "\x37\x6F\xFE\x31\xE0\xEF\x3E\x9B\xD5\x46\x43"
- "\xA2\x15\xFA\x86\x75\x1C\x95\x9F\xE6\xD6\x41"
- "\x50\x36\x0F\x67\x68\x4A\x72\x32\x85\xB0\xCB"
- "\xA4\x0D\x1F\xA2\x43\xCA\x30\xF1\x42\xF8\xC4"
- "\x17\x6A\xD1\x2D\x43\x46\x8C\xA5\x72\x3C\xB1"
- "\x44\x8E\xA1\x75\xAA\x20\x30\xDD\xCD\x0B\x5A"
- "\x0D\xE6\x28\xCA\xBC\xA9\x3B\x11\x23\x88\x85"
- "\xDF\xD8\x84\x11\x89\x7A\x4F\x00\x90\x0B\xD8"
- "\x8A\x35\xE9\x5F\xEC\x05\x42\x15\xCA\x7E\xA3"
- "\xEF\xEF\xE3\xB7\xBE\x96\x8C\x36\x7D\x15\x3C"
- "\x7A\x78\x00\x61\xAF\x62\x45\xA7\x4B\xAE\x4A"
- "\xFD\xC9\xE0\x89\x53\x36\x71\x8F\x38\xC4\x00"
- "\x57\xD9\xE6\xC1\xEC\xBF\xF7\x4B\x3F\x55\xD6"
- "\x54\x15\x72\xB2\x23\x76\xD1\x4E\x8E\x7E\xFB"
- "\xC8\xD6\xA4\xA4\x7E\x8E\xD8\x76\xD3\xEB\x90"
- "\x90\xEB\xB3\x84\x26\x34\x93\x36\xCA\xA9\x12"
- "\xD3\x6D\x84\x07\xE1\x0E\xE7\x63\x24\x54\x90"
- "\x42\x8C\x6B\xE7\x21\x53\x2D\x16\xE9\x68\xA9"
- "\xC2\x9A\x7A\x93\x31\x5E\x35\x72\xE2\x0F\x3D"
- "\x55\x41\x8C\xC5\xD1\xBB\xEE\x5F\x3C\x95\x52"
- "\x2A\x65\x47\xB6\x84\x6A\x05\x19\xD9\xE7\x68"
- "\x15\xFA\x49\xD9\x9D\xFD\x47\x9F\xB9\xA6\xBB"
- "\xA8\xD4\x22\x6C\x8B\x59\x47\xEF\xD1\xD0\xBF"
- "\xBC\xE4\x53\x31\x2F\xA5\xD4\x2C\x89\xCA\xE5"
- "\x29\x64\xF8\x51\x2A\x02\xDE\x31\x0D\x54\x0E"
- "\x0E\xB8\x78\xE6\x2A\x3E\x31\xA2\xA4\xCD\x91"
- "\x79\xF2\x9B\x04\xA0\xDB\x78\xAC\x0D\xB5\xCA"
- "\x60\x4C\x08\x96\xCA\x8A\xE9\x93\x9F\x62\x38"
- "\xAE",
- .ent_reseed_len = 320,
- .addtl_reseed = "\xD5\x46\x71\x38\x46\xE0\xC1\x27\x2C\xF1\x07"
- "\xDD\x29\x73\xD7\xF4\x5A\x3A\xE0\x99\x98\x0A"
- "\xEB\xA5\x9E\x2E\x49\x21\x7B\x18\xC0\xD8\x3D"
- "\xEE\x49\xF9\x52\x7C\x55\x5E\x5E\x06\xC2\x7E"
- "\x34\x3A\xA5\xB7\x78\x21\xC1\xB8\x8B\x4E\x07"
- "\x1F\x3F\xC4\xB4\x9B\x3F\x20\x2D\xEE\x70\x3B"
- "\x18\xCF\x2B\x50\x15\x1B\xF3\x6C\xE7\x9F\x2A"
- "\x2B\x69\x53\xCA\x88\x41\xA9\x07\x31\x14\x55"
- "\xBD\x75\x49\x68\x98\x48\xCA\x46\xA5\xEC\xAA"
- "\x9D\x8E\x6F\x40\xBA\xCA\xC8\xE9\x9F\xA4\xC5"
- "\x94\x89\x2C\x4D\xE4\x0A\x66\xD3\xDB\x1A\xD9"
- "\xA7\x3F\x6B\x0A\xE0\xE4\xDC\x0B\x8B\x64\xBF"
- "\xB4\x95\xA1\xAE\x92\xA8\x7C\xE2\x4B\xED\xFD"
- "\xFD\xE0\x54\x48\x7C\x25\xD6\xD1\x0A\xAB\x5E"
- "\x33\x2F\x1D\xD3\x62\x47\xAB\x35\x8C\xA1\xC2"
- "\x75\xDD\x75\xCA\x09\xE1\x38\xDE\x87\x79\x0C"
- "\xD7\x5D\x3E\x6D\x28\x8F\x12\x98\x2C\x26\x34"
- "\x91\x0B\x6B\xB7\x73",
- .addtl_reseed_len = 192,
-
- .addtla = "\xC8\xE1\x03\x59\xEA\x9F\xD3\x1F\xCC\xCB\x5A\x3E"
- "\x23\xDB\x47\x75\x1B\x3A\x6C\x0B\xED\xE6\xC0\xB6"
- "\x4B\x82\x53\x5B\x6D\xEE\x2B\x97\x0F\x59\x07\xA4"
- "\xFE\xE2\x26\x4F\xFF\xF7\x46\xAF\x62\xC4\x42\xE8"
- "\x06\xFA\x1F\xAA\x66\xF3\xA4\xCF\x85\x02\x3C\x11"
- "\xEF\xD2\x16\x13\x7A\xBD\x03\x66\xC3\x4D\x6F\x3A"
- "\xE5\xD3\xFF\x92\xB6\x45\xB8\x88\x94\x42\x2E\x84"
- "\x02\xA5\x54\x12\xBF\xCB\xF1\x6E\x1C\x0C\x23\xFE"
- "\x8A\xFD\xF5\x1A\x4C\xD6\x2A\x34\x7F\x21\x50\xBB"
- "\x06\x64\x9A\x77\x70\x59\x1D\x12\xD1\xA0\x10\x70"
- "\xD7\x4F\x3C\xEE\x82\xEF\x5B\x35\x8F\x05\xF6\x51"
- "\xBC\x28\xE1\xB1\x54\xFF\x25\x12\x16\x2C\x62\xFC"
- "\xB9\x74\x5E\x78\x41\xB2\x04\x80\x4E\xB1\x43\x2E"
- "\x88\x7F\x34\xA4\x33\x66\xE8\x68\x60\x54\xEB\xCE"
- "\xD1\x5F\xC4\xD6\x21\x5E\x22\x1A\x7E\xC5\x6D\xB7"
- "\x93\x8F\x9C\x77\x6E\x56\xA5\xA8\xF7\xB2\x10\x19",
- .addtlb = "\xB8\x1E\x9E\xE2\xB3\xE4\x04\x43\x51\x7B\x96\x32"
- "\xAC\x95\xF2\x1E\x5E\x7A\xBF\x68\xE3\x7A\xCE\xE5"
- "\x2B\x3B\xB0\x34\x7F\xE1\xB5\x37\x3C\x5B\xD2\x6B"
- "\x17\xF6\x18\xAF\x7C\x01\xA5\x84\xFE\x07\x0B\x46"
- "\xCC\x96\x61\xAB\xCD\x81\x95\x8A\x8A\xB6\xD8\xCC"
- "\x94\x80\x45\xF6\xFF\x95\x3A\xB8\xDC\xBF\xB4\xBF"
- "\x26\x8C\xE9\x79\x05\x58\x9C\x03\x08\x45\xB5\xC4"
- "\xD8\xB4\xCD\x76\x13\xAE\x2B\xCC\xB5\x3E\x3C\x65"
- "\x7A\xAA\xDC\x9B\x0B\x13\x8B\x82\x5A\x39\x60\x9A"
- "\xF7\xA8\x38\xB5\x83\x8E\x0B\xD1\xE6\xBF\xA1\xDC"
- "\x30\x45\xCC\x67\x41\x0F\xF9\x86\x27\xE0\x22\x3E"
- "\x0D\x1F\x92\x13\x16\x9B\x84\x79\x91\xFE\xBC\xDF"
- "\x15\x6C\xDC\xAE\xC5\x64\x46\x9C\xE8\xEA\xBB\x9D"
- "\x27\xA2\x1E\xDF\xB2\xF2\x98\xB4\x88\x4E\x22\x5F"
- "\x3C\xD0\x35\x2C\x5C\x89\xC7\xEC\xE3\xF3\x09\x60"
- "\xEF\xAC\x78\xBF\x94\xAA\x8C\x30\x7F\xCF\xE4\x4B",
- .addtllen = 192,
-
- .expected = "\x93\xFF\x4F\x4A\xA7\xE0\xFC\x3B\xCF\xCE\x57\xCD"
- "\xFD\xE9\x94\x6D\x0D\x45\x7E\xA3\x98\xBB\xE6\x54"
- "\x36\xF9\x92\xE6\xBB\xC5\x93\x16\x69\x35\x01\xF0"
- "\x5A\xE2\x43\xFC\x73\x7C\xA3\x5C\x5B\x49\x72\x69"
- "\x6A\xC4\xB6\xD4\xB2\x48\x27\x72\xCA\xE3\xF3\xB8"
- "\xD6\x95\x9F\x39\xC8\xD7\x72\xAF\xC2\x7C\x75\xE5"
- "\xA4\xF7\x52\x4F\xDF\x80\x75\xCA\x4B\xFA\x75\x9A"
- "\x7A\x8D\x48\x94\x30\x1C\x82\x5E\xD6\x3F\xF1\x78"
- "\x84\xAA\x8D\x8B\x4F\x6A\x20\x12\xA2\x65\xC5\x02"
- "\x32\xA1\xE4\x6B\x86\x2F\xCF\x92\xCD\x01\x55\xF7"
- "\xB8\xAB\xC3\x2C\x42\xC3\xFD\x9B\x59\x2D\x47\x8E"
- "\xB6\x8D\xE7\x04\x2E\x67\xD9\x07\x14\xA3\xF2\x74"
- "\x79\x9C\xAB\xC6\xD6\x52\x3E\x91\x81\xA4\x3C\x9A"
- "\x3E\x10\x1E\xD0\x28\xBC\x1C\x50\xF0\xB6\xEC\x01"
- "\xE5\x40\x16\x08\xB5\x58\xE0\xC4\xC2\x9A\xBB\x13"
- "\xAB\x10\x4B\x07\x24\x09\xEB\xF9\x5E\xAA\x3E\x3A"
- "\x25\x34\x5B\x97\x92\xF9\x46\x8A\x8E\x5A\x06\x9C"
- "\x2B\x1C\x8E\x47\x19\xC3\x3B\x14\x8A\xC1\xEB\xF7"
- "\xB0\xA2\x05\xE0\x70\x12\x88\x21\xFF\xC0\x35\x6D"
- "\xE9\x08\x7E\x11\x6E\xD7\x16\x48\x24\x43\xAF\x33"
- "\xA3\x48\x44\x91\xC5\x32\x1D\x87\xF6\x9B\x10\x1C"
- "\xA4\x7A\x74\x23\xB3\xFC\xB9\x87\x08\xE6\x9A\xEF"
- "\xD5\x93\x82\x17\xD4\x78\xDA\x46\x34\xC2\x61\x8C"
- "\xB7\x53\x89\xC4\x8A\xD8\xA0\x2E\xCE\xCA\x24\x16"
- "\xF0\x18\x7F\xC3\x12\x3F\xD0\xB1\xEF\x37\x99\xA8"
- "\x04\x1F\x76\x50\x81\x08\xCD\x4D\x43\xEF\x64\xB6"
- "\x03\x57\xB7\x5F\xDD\xF6\xBA\x34\xE2\x88\xE7\x1F"
- "\x62\xA5\xA4\x05\xEB\x1A\xFE\x0B\xFE\x74\x7D\x64"
- "\x29\x83\xE8\x0B\x97\x7D\x94\x5B\xF9\x3C\x8E\xC8"
- "\x6B\xCD\xAD\x63\x32\x6E\x00\xBF\x8E\x57\xF2\x32"
- "\x88\x53\x17\x40\xE3\xF8\xF8\xD9\xFD\xCD\x76\x84"
- "\xC6\xFD\xB1\x10\x40\xED\x75\xDD\xBD\x78\x8B\x0A"
- "\x61\x1E\xCC\xC4\x4F\x95\xF1\x2F\x8F\x5A\xF0\x12"
- "\x00\xCE\x75\xB8\xE9\xAB\x63\xC0\x7A\xF6\x9A\x47"
- "\xD2\x3C\xB0\xAD\xAF\x03\xDF\x25\xDD\x0C\x0F\xB6"
- "\x29\x09\x0F\x28\x5E\xA8\x67\xBB\xC9\x78\xBE\x12"
- "\xD8\xD6\xD0\x98\x82\x29\xA3\x82\xFB\x8E\x1C\x79"
- "\x28\x52\x22\x73\x3C\x6F\xB5\x33\xFF\x40\x26\x4C"
- "\x30\xE4\xE0\x39\x59\x72\x65\x79\x9F\xB7\x89\x87"
- "\x64\xAC\x45\x11\x0D\xDD\xC0\x44\x5E\x0D\xDF\xDB"
- "\x91\x42\x5F\x52\x7F\xBB\x66\xEE\x32\x90\x8F\x6F"
- "\xF8\xB9\xFE\xEA\x42\xFB\x60\x2B\xE3\xD9\xB2\xD1"
- "\x74\x37\x14\xC6\xDA\x68\xE6\x09",
- .expectedlen = 512,
- }
-};
-
/* Cast5 test vectors from RFC 2144 */
static const struct cipher_testvec cast5_tv_template[] = {
{
@@ -24389,68 +24171,6 @@ static const struct cipher_testvec cast5_ctr_tv_template[] = {
};
/*
- * ARC4 test vectors from OpenSSL
- */
-static const struct cipher_testvec arc4_tv_template[] = {
- {
- .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
- .klen = 8,
- .ptext = "\x01\x23\x45\x67\x89\xab\xcd\xef",
- .ctext = "\x75\xb7\x87\x80\x99\xe0\xc5\x96",
- .len = 8,
- }, {
- .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
- .klen = 8,
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00",
- .ctext = "\x74\x94\xc2\xe7\x10\x4b\x08\x79",
- .len = 8,
- }, {
- .key = "\x00\x00\x00\x00\x00\x00\x00\x00",
- .klen = 8,
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00",
- .ctext = "\xde\x18\x89\x41\xa3\x37\x5d\x3a",
- .len = 8,
- }, {
- .key = "\xef\x01\x23\x45",
- .klen = 4,
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00",
- .ctext = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
- "\xbd\x61\x5a\x11\x62\xe1\xc7\xba"
- "\x36\xb6\x78\x58",
- .len = 20,
- }, {
- .key = "\x01\x23\x45\x67\x89\xab\xcd\xef",
- .klen = 8,
- .ptext = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
- "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
- "\x12\x34\x56\x78\x9A\xBC\xDE\xF0"
- "\x12\x34\x56\x78",
- .ctext = "\x66\xa0\x94\x9f\x8a\xf7\xd6\x89"
- "\x1f\x7f\x83\x2b\xa8\x33\xc0\x0c"
- "\x89\x2e\xbe\x30\x14\x3c\xe2\x87"
- "\x40\x01\x1e\xcf",
- .len = 28,
- }, {
- .key = "\xef\x01\x23\x45",
- .klen = 4,
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00",
- .ctext = "\xd6\xa1\x41\xa7\xec\x3c\x38\xdf"
- "\xbd\x61",
- .len = 10,
- }, {
- .key = "\x01\x23\x45\x67\x89\xAB\xCD\xEF"
- "\x00\x00\x00\x00\x00\x00\x00\x00",
- .klen = 16,
- .ptext = "\x01\x23\x45\x67\x89\xAB\xCD\xEF",
- .ctext = "\x69\x72\x36\x59\x1B\x52\x42\xB1",
- .len = 8,
- },
-};
-
-/*
* TEA test vectors
*/
static const struct cipher_testvec tea_tv_template[] = {
diff --git a/crypto/zstd.c b/crypto/zstd.c
index 76bdaca32733..cd5d00e0c3aa 100644
--- a/crypto/zstd.c
+++ b/crypto/zstd.c
@@ -86,8 +86,11 @@ static int zstd_compress_one(struct acomp_req *req, struct zstd_ctx *ctx,
out_len = zstd_compress_cctx(ctx->cctx, dst, req->dlen, src, req->slen,
&ctx->params);
- if (zstd_is_error(out_len))
+ if (zstd_is_error(out_len)) {
+ if (zstd_get_error_code(out_len) == ZSTD_error_dstSize_tooSmall)
+ return -ENOSPC;
return -EINVAL;
+ }
*dlen = out_len;
diff --git a/drivers/char/hw_random/cctrng.c b/drivers/char/hw_random/cctrng.c
index b869915d7048..b5f2c75d2eb8 100644
--- a/drivers/char/hw_random/cctrng.c
+++ b/drivers/char/hw_random/cctrng.c
@@ -1,21 +1,23 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2019-2020 ARM Limited or its affiliates. */
-#include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/bitfield.h>
+#include <linux/circ_buf.h>
#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/err.h>
+#include <linux/fips.h>
+#include <linux/kernel.h>
#include <linux/hw_random.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
+#include <linux/irqreturn.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
-#include <linux/interrupt.h>
-#include <linux/irqreturn.h>
#include <linux/workqueue.h>
-#include <linux/circ_buf.h>
-#include <linux/completion.h>
-#include <linux/of.h>
-#include <linux/bitfield.h>
-#include <linux/fips.h>
#include "cctrng.h"
@@ -68,8 +70,8 @@ struct cctrng_drvdata {
/* pending_hw - 1 when HW is pending, 0 when it is idle */
atomic_t pending_hw;
- /* protects against multiple concurrent consumers of data_buf */
- spinlock_t read_lock;
+ /* protects data_buf */
+ struct mutex lock;
};
@@ -91,11 +93,7 @@ static int cc_trng_pm_get(struct device *dev)
static void cc_trng_pm_put_suspend(struct device *dev)
{
- int rc;
-
- rc = pm_runtime_put_autosuspend(dev);
- if (rc)
- dev_err(dev, "pm_runtime_put_autosuspend returned %x\n", rc);
+ pm_runtime_put_autosuspend(dev);
}
static int cc_trng_pm_init(struct cctrng_drvdata *drvdata)
@@ -213,11 +211,8 @@ static int cctrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
size_t size;
size_t left;
- if (!spin_trylock(&drvdata->read_lock)) {
- /* concurrent consumers from data_buf cannot be served */
- dev_dbg_ratelimited(dev, "unable to hold lock\n");
- return 0;
- }
+ if (mutex_lock_interruptible(&drvdata->lock))
+ return -ERESTARTSYS;
/* copy till end of data buffer (without wrap back) */
cnt_w = CIRC_CNT_TO_END(drvdata->circ.head,
@@ -232,12 +227,12 @@ static int cctrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
cnt_w = CIRC_CNT(drvdata->circ.head,
drvdata->circ.tail, CCTRNG_DATA_BUF_WORDS);
size = min((cnt_w<<2), left);
- memcpy(data, &(buf[drvdata->circ.tail]), size);
+ memcpy(data + copied, &buf[drvdata->circ.tail], size);
copied += size;
circ_idx_inc(&drvdata->circ.tail, size);
}
- spin_unlock(&drvdata->read_lock);
+ mutex_unlock(&drvdata->lock);
if (circ_buf_space(drvdata) >= CC_TRNG_EHR_IN_WORDS) {
if (atomic_cmpxchg(&drvdata->pending_hw, 0, 1) == 0) {
@@ -347,6 +342,7 @@ static void cc_trng_compwork_handler(struct work_struct *w)
}
/* read EHR data from registers */
+ mutex_lock(&drvdata->lock);
for (i = 0; i < CC_TRNG_EHR_IN_WORDS; i++) {
/* calc word ptr in data_buf */
u32 *buf = (u32 *)drvdata->circ.buf;
@@ -358,6 +354,7 @@ static void cc_trng_compwork_handler(struct work_struct *w)
* returned, restart the entropy collection.
*/
if (buf[drvdata->circ.head] == 0) {
+ mutex_unlock(&drvdata->lock);
dev_dbg(dev, "Got 0 value in EHR. active_rosc %u\n",
drvdata->active_rosc);
goto next_rosc;
@@ -365,6 +362,7 @@ static void cc_trng_compwork_handler(struct work_struct *w)
circ_idx_inc(&drvdata->circ.head, 1<<2);
}
+ mutex_unlock(&drvdata->lock);
atomic_set(&drvdata->pending_hw, 0);
@@ -499,7 +497,7 @@ static int cctrng_probe(struct platform_device *pdev)
INIT_WORK(&drvdata->compwork, cc_trng_compwork_handler);
INIT_WORK(&drvdata->startwork, cc_trng_startwork_handler);
- spin_lock_init(&drvdata->read_lock);
+ mutex_init(&drvdata->lock);
/* register the driver isr function */
rc = devm_request_irq(dev, irq, cc_isr, IRQF_SHARED, "cctrng", drvdata);
@@ -533,9 +531,8 @@ static int cctrng_probe(struct platform_device *pdev)
/* registration of the hwrng device */
rc = devm_hwrng_register(dev, &drvdata->rng);
if (rc) {
- dev_err(dev, "Could not register hwrng device.\n");
- cc_trng_pm_fini(drvdata);
- return rc;
+ pm_runtime_put_noidle(dev);
+ return dev_err_probe(dev, rc, "Could not register hwrng device\n");
}
/* trigger HW to start generate data */
diff --git a/drivers/char/hw_random/mtk-rng.c b/drivers/char/hw_random/mtk-rng.c
index 127b82d979e8..3ac4d7450313 100644
--- a/drivers/char/hw_random/mtk-rng.c
+++ b/drivers/char/hw_random/mtk-rng.c
@@ -25,7 +25,7 @@
#define RNG_AUTOSUSPEND_TIMEOUT 100
#define USEC_POLL 2
-#define TIMEOUT_POLL 60
+#define TIMEOUT_POLL 1000
#define RNG_CTRL 0x00
#define RNG_EN BIT(0)
diff --git a/drivers/char/hw_random/octeon-rng.c b/drivers/char/hw_random/octeon-rng.c
index c3dee6b182a8..c2a149d95e5e 100644
--- a/drivers/char/hw_random/octeon-rng.c
+++ b/drivers/char/hw_random/octeon-rng.c
@@ -116,3 +116,4 @@ module_platform_driver(octeon_rng_driver);
MODULE_AUTHOR("David Daney");
MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Cavium Octeon HW random number generator");
diff --git a/drivers/crypto/atmel-i2c.c b/drivers/crypto/atmel-i2c.c
index 109e2a7ae0dc..7a400c05e13c 100644
--- a/drivers/crypto/atmel-i2c.c
+++ b/drivers/crypto/atmel-i2c.c
@@ -347,11 +347,28 @@ free_cmd:
return ret;
}
+/*
+ * A device behind an I2C mux sits on a channel adapter. Try the adapter of
+ * the client first, as before, then its parents. Without the property,
+ * assume 100 kHz, the default of most I2C controller drivers.
+ */
+static u32 atmel_i2c_bus_speed(struct i2c_adapter *adap)
+{
+ u32 bus_clk_rate;
+
+ for (; adap; adap = i2c_parent_is_i2c_adapter(adap)) {
+ if (!device_property_read_u32(&adap->dev, "clock-frequency",
+ &bus_clk_rate) && bus_clk_rate)
+ return bus_clk_rate;
+ }
+
+ return I2C_MAX_STANDARD_MODE_FREQ;
+}
+
int atmel_i2c_probe(struct i2c_client *client)
{
struct atmel_i2c_client_priv *i2c_priv;
struct device *dev = &client->dev;
- int ret;
u32 bus_clk_rate;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
@@ -360,14 +377,8 @@ int atmel_i2c_probe(struct i2c_client *client)
}
bus_clk_rate = i2c_acpi_find_bus_speed(&client->adapter->dev);
- if (!bus_clk_rate) {
- ret = device_property_read_u32(&client->adapter->dev,
- "clock-frequency", &bus_clk_rate);
- if (ret) {
- dev_err(dev, "failed to read clock-frequency property\n");
- return ret;
- }
- }
+ if (!bus_clk_rate)
+ bus_clk_rate = atmel_i2c_bus_speed(client->adapter);
if (bus_clk_rate > I2C_MAX_FAST_MODE_PLUS_FREQ) {
dev_err(dev, "%u exceeds maximum supported clock frequency (1MHz)\n",
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index 0c03d7bcba19..ccabc3750642 100644
--- a/drivers/crypto/caam/jr.c
+++ b/drivers/crypto/caam/jr.c
@@ -178,6 +178,15 @@ static int caam_jr_shutdown(struct device *dev)
return ret;
}
+static void caam_jr_platform_shutdown(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = caam_jr_shutdown(&pdev->dev);
+ if (ret)
+ dev_err(&pdev->dev, "Failed to shut down job ring: %d\n", ret);
+}
+
static void caam_jr_remove(struct platform_device *pdev)
{
int ret;
@@ -811,7 +820,7 @@ static struct platform_driver caam_jr_driver = {
},
.probe = caam_jr_probe,
.remove = caam_jr_remove,
- .shutdown = caam_jr_remove,
+ .shutdown = caam_jr_platform_shutdown,
};
static int __init jr_driver_init(void)
diff --git a/drivers/crypto/gemini/sl3516-ce-core.c b/drivers/crypto/gemini/sl3516-ce-core.c
index ac0e6ef2b7b1..7c6f4cec36f8 100644
--- a/drivers/crypto/gemini/sl3516-ce-core.c
+++ b/drivers/crypto/gemini/sl3516-ce-core.c
@@ -8,7 +8,6 @@
*/
#include <crypto/engine.h>
-#include <crypto/internal/rng.h>
#include <crypto/internal/skcipher.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
diff --git a/drivers/crypto/intel/keembay/keembay-ocs-aes-core.c b/drivers/crypto/intel/keembay/keembay-ocs-aes-core.c
index 91fc0991a1e4..5a28f2ce28a5 100644
--- a/drivers/crypto/intel/keembay/keembay-ocs-aes-core.c
+++ b/drivers/crypto/intel/keembay/keembay-ocs-aes-core.c
@@ -129,7 +129,8 @@ static struct ocs_aes_dev *kmb_ocs_aes_find_dev(struct ocs_aes_tctx *tctx)
}
/* Only a single OCS device available */
- aes_dev = list_first_entry(&ocs_aes.dev_list, struct ocs_aes_dev, list);
+ aes_dev = list_first_entry_or_null(&ocs_aes.dev_list,
+ struct ocs_aes_dev, list);
tctx->aes_dev = aes_dev;
exit:
diff --git a/drivers/crypto/intel/keembay/keembay-ocs-ecc.c b/drivers/crypto/intel/keembay/keembay-ocs-ecc.c
index e8d6001be894..e544c06e3329 100644
--- a/drivers/crypto/intel/keembay/keembay-ocs-ecc.c
+++ b/drivers/crypto/intel/keembay/keembay-ocs-ecc.c
@@ -208,11 +208,14 @@ static struct ocs_ecc_dev *kmb_ocs_ecc_find_dev(struct ocs_ecc_ctx *tctx)
spin_lock(&ocs_ecc.lock);
/* Only a single OCS device available. */
- tctx->ecc_dev = list_first_entry(&ocs_ecc.dev_list, struct ocs_ecc_dev,
- list);
+ tctx->ecc_dev = list_first_entry_or_null(&ocs_ecc.dev_list,
+ struct ocs_ecc_dev, list);
spin_unlock(&ocs_ecc.lock);
+ if (!tctx->ecc_dev)
+ return ERR_PTR(-ENODEV);
+
return tctx->ecc_dev;
}
diff --git a/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c b/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c
index d6f1f626cf5a..23684868b4e3 100644
--- a/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c
+++ b/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c
@@ -89,6 +89,14 @@ static const struct adf_fw_config adf_fw_dcc_config[] = {
{ADF_AE_GROUP_4, ADF_FW_ADMIN_OBJ},
};
+static const struct adf_fw_config adf_fw_asym_sym_dc_config[] = {
+ {ADF_AE_GROUP_3, ADF_FW_DC_OBJ},
+ {ADF_AE_GROUP_2, ADF_FW_DC_OBJ},
+ {ADF_AE_GROUP_1, ADF_FW_SYM_OBJ},
+ {ADF_AE_GROUP_0, ADF_FW_ASYM_OBJ},
+ {ADF_AE_GROUP_4, ADF_FW_ADMIN_OBJ},
+};
+
static struct adf_hw_device_class adf_420xx_class = {
.name = ADF_420XX_DEVICE_NAME,
@@ -135,6 +143,8 @@ static u32 uof_get_num_objs(struct adf_accel_dev *accel_dev)
return ARRAY_SIZE(adf_fw_asym_dc_config);
case SVC_SYM_DC:
return ARRAY_SIZE(adf_fw_sym_dc_config);
+ case SVC_SYM_ASYM_DC:
+ return ARRAY_SIZE(adf_fw_asym_sym_dc_config);
default:
return 0;
}
@@ -157,6 +167,8 @@ static const struct adf_fw_config *get_fw_config(struct adf_accel_dev *accel_dev
return adf_fw_asym_dc_config;
case SVC_SYM_DC:
return adf_fw_sym_dc_config;
+ case SVC_SYM_ASYM_DC:
+ return adf_fw_asym_sym_dc_config;
default:
return NULL;
}
@@ -288,13 +300,26 @@ static u32 get_accel_cap(struct adf_accel_dev *accel_dev)
return capabilities_asym | capabilities_dc;
case SVC_SYM_DC:
return capabilities_sym | capabilities_dc;
+ case SVC_SYM_ASYM_DC:
+ return capabilities_sym | capabilities_asym | capabilities_dc;
default:
return 0;
}
}
+static const u32 thrd_to_arb_map_asym_sym_dc[ADF_420XX_MAX_ACCELENGINES] = {
+ 0x00000011, 0x00000011, 0x00000011, 0x00000011,
+ 0x00002222, 0x00002222, 0x00002222, 0x00002222,
+ 0x000000cc, 0x000000cc, 0x000000cc, 0x000000cc,
+ 0x000000cc, 0x000000cc, 0x000000cc, 0x000000cc,
+ 0x0
+};
+
static const u32 *adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev)
{
+ if (adf_get_service_enabled(accel_dev) == SVC_SYM_ASYM_DC)
+ return thrd_to_arb_map_asym_sym_dc;
+
if (adf_gen4_init_thd2arb_map(accel_dev))
dev_warn(&GET_DEV(accel_dev),
"Failed to generate thread to arbiter mapping");
@@ -425,6 +450,36 @@ static void adf_gen4_set_err_mask(struct adf_dev_err_mask *dev_err_mask)
dev_err_mask->ssmfeatren_mask = ADF_420XX_SSMFEATREN_MASK;
}
+static u16 adf_420xx_get_ring_to_svc_map(struct adf_accel_dev *accel_dev)
+{
+ if (adf_get_service_enabled(accel_dev) == SVC_SYM_ASYM_DC)
+ return ADF_420XX_SYM_ASYM_DC_RING_TO_SRV_MAP;
+
+ return adf_gen4_get_ring_to_svc_map(accel_dev);
+}
+
+static bool adf_420xx_services_supported(unsigned long mask)
+{
+ int num_svc;
+
+ if (mask >= BIT(SVC_COUNT))
+ return false;
+
+ if (test_bit(SVC_DECOMP, &mask))
+ return false;
+
+ num_svc = hweight_long(mask);
+ switch (num_svc) {
+ case ADF_ONE_SERVICE:
+ return true;
+ case ADF_TWO_SERVICES:
+ case ADF_THREE_SERVICES:
+ return !test_bit(SVC_DCC, &mask);
+ default:
+ return false;
+ }
+}
+
void adf_init_hw_data_420xx(struct adf_hw_device_data *hw_data, u32 dev_id)
{
hw_data->dev_class = &adf_420xx_class;
@@ -472,7 +527,7 @@ void adf_init_hw_data_420xx(struct adf_hw_device_data *hw_data, u32 dev_id)
hw_data->get_ena_thd_mask = get_ena_thd_mask;
hw_data->set_msix_rttable = adf_gen4_set_msix_default_rttable;
hw_data->set_ssm_wdtimer = adf_gen4_set_ssm_wdtimer;
- hw_data->get_ring_to_svc_map = adf_gen4_get_ring_to_svc_map;
+ hw_data->get_ring_to_svc_map = adf_420xx_get_ring_to_svc_map;
hw_data->disable_iov = adf_disable_sriov;
hw_data->ring_pair_reset = adf_gen4_ring_pair_reset;
hw_data->bank_state_save = adf_bank_state_save;
@@ -485,7 +540,7 @@ void adf_init_hw_data_420xx(struct adf_hw_device_data *hw_data, u32 dev_id)
hw_data->get_hb_clock = adf_gen4_get_heartbeat_clock;
hw_data->num_hb_ctrs = ADF_NUM_HB_CNT_PER_AE;
hw_data->clock_frequency = ADF_420XX_AE_FREQ;
- hw_data->services_supported = adf_gen4_services_supported;
+ hw_data->services_supported = adf_420xx_services_supported;
hw_data->get_svc_slice_cnt = adf_gen4_get_svc_slice_cnt;
hw_data->accel_capabilities_ext_mask = ADF_ACCEL_CAPABILITIES_EXT_ZSTD_LZ4S;
diff --git a/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.h b/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.h
index 99abbfc14820..1fdaed3dd952 100644
--- a/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.h
+++ b/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.h
@@ -17,6 +17,12 @@
#define ADF_420XX_PARITYERRORMASK_PKE_MASK (0xFFF)
#define ADF_420XX_PARITYERRORMASK_WAT_WCP_MASK (0x3FF03FF)
+#define ADF_420XX_SYM_ASYM_DC_RING_TO_SRV_MAP \
+ (ASYM << ADF_CFG_SERV_RING_PAIR_0_SHIFT | \
+ SYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \
+ COMP << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \
+ COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT)
+
/*
* SSMFEATREN bit mask
* BIT(4) - enables parity detection on CPP
diff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c b/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c
index ca9bc5dccf67..27c813d1c6c3 100644
--- a/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c
+++ b/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c
@@ -573,6 +573,19 @@ static int adf_gen6_init_thd2arb_map(struct adf_accel_dev *accel_dev)
return 0;
}
+static void init_num_wcy_svc_aes(struct adf_rl_hw_data *device_data)
+{
+ u32 ae_mask = 0;
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(adf_wcy_fw_config); i++) {
+ if (adf_wcy_fw_config[i].obj == ADF_FW_WCY_OBJ)
+ ae_mask |= adf_wcy_fw_config[i].ae_mask;
+ }
+
+ device_data->svc_ae_mask[SVC_SYM] = hweight32(ae_mask);
+}
+
static void init_num_svc_aes(struct adf_rl_hw_data *device_data)
{
enum adf_fw_objs obj_type, obj_iter;
@@ -608,6 +621,9 @@ static u32 adf_gen6_get_svc_slice_cnt(struct adf_accel_dev *accel_dev,
{
struct adf_rl_hw_data *device_data = &accel_dev->hw_device->rl_data;
+ if (adf_6xxx_is_wcy(GET_HW_DATA(accel_dev)))
+ return (svc == SVC_SYM) ? device_data->slices.wcp_cnt : 0;
+
switch (svc) {
case SVC_SYM:
return device_data->slices.cph_cnt;
@@ -973,8 +989,10 @@ static void adf_gen6_init_kpt(struct adf_kpt_hw_data *kpt_data)
kpt_data->user_input.swk_cnt_per_pasid = ADF_6XXX_KPT_DEFAULT_SWK_CNT_PER_PASID;
}
-static void adf_gen6_init_rl_data(struct adf_rl_hw_data *rl_data)
+static void adf_gen6_init_rl_data(struct adf_hw_device_data *hw_data)
{
+ struct adf_rl_hw_data *rl_data = &hw_data->rl_data;
+
rl_data->pciout_tb_offset = ADF_GEN6_RL_TOKEN_PCIEOUT_BUCKET_OFFSET;
rl_data->pciin_tb_offset = ADF_GEN6_RL_TOKEN_PCIEIN_BUCKET_OFFSET;
rl_data->r2l_offset = ADF_GEN6_RL_R2L_OFFSET;
@@ -982,14 +1000,18 @@ static void adf_gen6_init_rl_data(struct adf_rl_hw_data *rl_data)
rl_data->c2s_offset = ADF_GEN6_RL_C2S_OFFSET;
rl_data->pcie_scale_div = ADF_6XXX_RL_PCIE_SCALE_FACTOR_DIV;
rl_data->pcie_scale_mul = ADF_6XXX_RL_PCIE_SCALE_FACTOR_MUL;
- rl_data->max_tp[SVC_ASYM] = ADF_6XXX_RL_MAX_TP_ASYM;
- rl_data->max_tp[SVC_SYM] = ADF_6XXX_RL_MAX_TP_SYM;
- rl_data->max_tp[SVC_DC] = ADF_6XXX_RL_MAX_TP_DC;
- rl_data->max_tp[SVC_DECOMP] = ADF_6XXX_RL_MAX_TP_DECOMP;
rl_data->scan_interval = ADF_6XXX_RL_SCANS_PER_SEC;
rl_data->scale_ref = ADF_6XXX_RL_SLICE_REF;
-
- init_num_svc_aes(rl_data);
+ if (adf_6xxx_is_wcy(hw_data)) {
+ rl_data->max_tp[SVC_SYM] = ADF_6XXX_RL_MAX_TP_WCY_SYM;
+ init_num_wcy_svc_aes(rl_data);
+ } else {
+ rl_data->max_tp[SVC_ASYM] = ADF_6XXX_RL_MAX_TP_ASYM;
+ rl_data->max_tp[SVC_SYM] = ADF_6XXX_RL_MAX_TP_SYM;
+ rl_data->max_tp[SVC_DC] = ADF_6XXX_RL_MAX_TP_DC;
+ rl_data->max_tp[SVC_DECOMP] = ADF_6XXX_RL_MAX_TP_DECOMP;
+ init_num_svc_aes(rl_data);
+ }
}
static void adf_gen6_init_services_supported(struct adf_hw_device_data *hw_data)
@@ -1067,7 +1089,7 @@ void adf_init_hw_data_6xxx(struct adf_hw_device_data *hw_data)
adf_gen6_init_vf_mig_ops(&hw_data->vfmig_ops);
adf_gen6_init_ras_ops(&hw_data->ras_ops);
adf_gen6_init_tl_data(&hw_data->tl_data);
- adf_gen6_init_rl_data(&hw_data->rl_data);
+ adf_gen6_init_rl_data(hw_data);
adf_gen6_init_anti_rb(&hw_data->anti_rb_data);
adf_gen6_init_kpt(&hw_data->kpt_data);
}
diff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.h b/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.h
index 2719ddbc1e05..2bce8a3b0fcc 100644
--- a/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.h
+++ b/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.h
@@ -158,6 +158,7 @@
#define ADF_6XXX_RL_SCANS_PER_SEC 954
#define ADF_6XXX_RL_MAX_TP_ASYM 173750UL
#define ADF_6XXX_RL_MAX_TP_SYM 95000UL
+#define ADF_6XXX_RL_MAX_TP_WCY_SYM 61000UL
#define ADF_6XXX_RL_MAX_TP_DC 40000UL
#define ADF_6XXX_RL_MAX_TP_DECOMP 40000UL
#define ADF_6XXX_RL_SLICE_REF 1000UL
diff --git a/drivers/crypto/intel/qat/qat_common/adf_accel_engine.c b/drivers/crypto/intel/qat/qat_common/adf_accel_engine.c
index 09d4f547e082..bb97bbedbb8a 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_accel_engine.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_accel_engine.c
@@ -204,16 +204,15 @@ int adf_ae_init(struct adf_accel_dev *accel_dev)
return 0;
}
-int adf_ae_shutdown(struct adf_accel_dev *accel_dev)
+void adf_ae_shutdown(struct adf_accel_dev *accel_dev)
{
struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
struct adf_hw_device_data *hw_device = accel_dev->hw_device;
if (!hw_device->fw_name)
- return 0;
+ return;
qat_hal_deinit(loader_data->fw_loader);
kfree(accel_dev->fw_loader);
accel_dev->fw_loader = NULL;
- return 0;
}
diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg_services.c b/drivers/crypto/intel/qat/qat_common/adf_cfg_services.c
index f7237c7ef2b1..ef245c2e80c1 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_cfg_services.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_cfg_services.c
@@ -148,6 +148,9 @@ int adf_get_service_enabled(struct adf_accel_dev *accel_dev)
if (ret)
return ret;
+ if (test_bit(SVC_SYM, &mask) && test_bit(SVC_ASYM, &mask) && test_bit(SVC_DC, &mask))
+ return SVC_SYM_ASYM_DC;
+
if (test_bit(SVC_SYM, &mask) && test_bit(SVC_ASYM, &mask))
return SVC_SYM_ASYM;
diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h b/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h
index 89be2f2c7233..d8b45645d2a9 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h
+++ b/drivers/crypto/intel/qat/qat_common/adf_cfg_services.h
@@ -24,6 +24,7 @@ enum adf_composed_services {
SVC_SYM_ASYM = SVC_COUNT,
SVC_SYM_DC,
SVC_ASYM_DC,
+ SVC_SYM_ASYM_DC,
};
enum {
diff --git a/drivers/crypto/intel/qat/qat_common/adf_common_drv.h b/drivers/crypto/intel/qat/qat_common/adf_common_drv.h
index 762a0b5e774a..533388cfa252 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_common_drv.h
+++ b/drivers/crypto/intel/qat/qat_common/adf_common_drv.h
@@ -67,7 +67,7 @@ int adf_dev_started(struct adf_accel_dev *accel_dev);
int adf_dev_restarting_notify(struct adf_accel_dev *accel_dev);
int adf_dev_restarted_notify(struct adf_accel_dev *accel_dev);
int adf_ae_init(struct adf_accel_dev *accel_dev);
-int adf_ae_shutdown(struct adf_accel_dev *accel_dev);
+void adf_ae_shutdown(struct adf_accel_dev *accel_dev);
int adf_ae_fw_load(struct adf_accel_dev *accel_dev);
void adf_ae_fw_release(struct adf_accel_dev *accel_dev);
int adf_ae_start(struct adf_accel_dev *accel_dev);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen6_tl.c b/drivers/crypto/intel/qat/qat_common/adf_gen6_tl.c
index faa60b04c406..2e5d909a3e3e 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_gen6_tl.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_gen6_tl.c
@@ -34,11 +34,11 @@
#define CPR_QUEUE_COUNT 5
#define DCPR_QUEUE_COUNT 3
-#define PKE_QUEUE_COUNT 1
-#define WAT_QUEUE_COUNT 7
-#define WCP_QUEUE_COUNT 7
-#define USC_QUEUE_COUNT 3
-#define ATH_QUEUE_COUNT 2
+#define PKE_QUEUE_COUNT 18
+#define WAT_QUEUE_COUNT 18
+#define WCP_QUEUE_COUNT 18
+#define UCS_QUEUE_COUNT 6
+#define ATH_QUEUE_COUNT 8
/* Device level counters. */
static const struct adf_tl_dbg_counter dev_counters[] = {
@@ -247,12 +247,12 @@ void adf_gen6_init_tl_data(struct adf_tl_hw_data *tl_data)
tl_data->num_rp_counters = ARRAY_SIZE(rp_counters);
tl_data->max_sl_cnt = ADF_GEN6_TL_MAX_SLICES_PER_TYPE;
- tl_data->multiplier.cpr_cnt = CPR_QUEUE_COUNT;
- tl_data->multiplier.dcpr_cnt = DCPR_QUEUE_COUNT;
- tl_data->multiplier.pke_cnt = PKE_QUEUE_COUNT;
- tl_data->multiplier.wat_cnt = WAT_QUEUE_COUNT;
- tl_data->multiplier.wcp_cnt = WCP_QUEUE_COUNT;
- tl_data->multiplier.ucs_cnt = USC_QUEUE_COUNT;
- tl_data->multiplier.ath_cnt = ATH_QUEUE_COUNT;
+ tl_data->cmdq_cnt.cpr_cnt = CPR_QUEUE_COUNT;
+ tl_data->cmdq_cnt.dcpr_cnt = DCPR_QUEUE_COUNT;
+ tl_data->cmdq_cnt.pke_cnt = PKE_QUEUE_COUNT;
+ tl_data->cmdq_cnt.wat_cnt = WAT_QUEUE_COUNT;
+ tl_data->cmdq_cnt.wcp_cnt = WCP_QUEUE_COUNT;
+ tl_data->cmdq_cnt.ucs_cnt = UCS_QUEUE_COUNT;
+ tl_data->cmdq_cnt.ath_cnt = ATH_QUEUE_COUNT;
}
EXPORT_SYMBOL_GPL(adf_gen6_init_tl_data);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_init.c b/drivers/crypto/intel/qat/qat_common/adf_init.c
index 81cb5e6c9f4a..6af0866b9539 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_init.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_init.c
@@ -393,12 +393,8 @@ static void adf_dev_shutdown(struct adf_accel_dev *accel_dev)
}
if (test_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status)) {
- if (adf_ae_shutdown(accel_dev))
- dev_err(&GET_DEV(accel_dev),
- "Failed to shutdown Accel Engine\n");
- else
- clear_bit(ADF_STATUS_AE_INITIALISED,
- &accel_dev->status);
+ adf_ae_shutdown(accel_dev);
+ clear_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status);
}
mutex_lock(&service_lock);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_rl.c b/drivers/crypto/intel/qat/qat_common/adf_rl.c
index 997ef448a4df..d083276f69cb 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_rl.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_rl.c
@@ -1050,14 +1050,19 @@ int adf_rl_init(struct adf_accel_dev *accel_dev)
{
struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
struct adf_rl_hw_data *rl_hw_data = &hw_data->rl_data;
+ enum adf_base_services svc;
struct adf_rl *rl;
int ret = 0;
- /* Validate device parameters */
- if (RL_VALIDATE_NON_ZERO(rl_hw_data->max_tp[SVC_ASYM]) ||
- RL_VALIDATE_NON_ZERO(rl_hw_data->max_tp[SVC_SYM]) ||
- RL_VALIDATE_NON_ZERO(rl_hw_data->max_tp[SVC_DC]) ||
- RL_VALIDATE_NON_ZERO(rl_hw_data->scan_interval) ||
+ for (svc = 0; svc < SVC_BASE_COUNT; svc++) {
+ if (adf_is_service_enabled(accel_dev, svc) &&
+ RL_VALIDATE_NON_ZERO(rl_hw_data->max_tp[svc])) {
+ ret = -EOPNOTSUPP;
+ goto err_ret;
+ }
+ }
+
+ if (RL_VALIDATE_NON_ZERO(rl_hw_data->scan_interval) ||
RL_VALIDATE_NON_ZERO(rl_hw_data->pcie_scale_div) ||
RL_VALIDATE_NON_ZERO(rl_hw_data->pcie_scale_mul) ||
RL_VALIDATE_NON_ZERO(rl_hw_data->scale_ref)) {
diff --git a/drivers/crypto/intel/qat/qat_common/adf_rl.h b/drivers/crypto/intel/qat/qat_common/adf_rl.h
index c1f3f9a51195..c8620c72cc97 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_rl.h
+++ b/drivers/crypto/intel/qat/qat_common/adf_rl.h
@@ -69,6 +69,7 @@ struct rl_slice_cnt {
u8 pke_cnt;
u8 cph_cnt;
u8 cpr_cnt;
+ u8 wcp_cnt;
};
struct adf_rl_interface_data {
diff --git a/drivers/crypto/intel/qat/qat_common/adf_rl_admin.c b/drivers/crypto/intel/qat/qat_common/adf_rl_admin.c
index 4a3e0591fdba..d2bb4cc95ecf 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_rl_admin.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_rl_admin.c
@@ -64,6 +64,7 @@ int adf_rl_send_admin_init_msg(struct adf_accel_dev *accel_dev,
/* For symmetric crypto, slice tokens are relative to the UCS slice */
slices_int->cph_cnt = slices_resp.ucs_cnt;
slices_int->cpr_cnt = slices_resp.cpr_cnt;
+ slices_int->wcp_cnt = slices_resp.wcp_cnt;
return 0;
}
diff --git a/drivers/crypto/intel/qat/qat_common/adf_telemetry.c b/drivers/crypto/intel/qat/qat_common/adf_telemetry.c
index 8c575113cbcd..44e26ea8cd7f 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_telemetry.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_telemetry.c
@@ -219,13 +219,13 @@ static void adf_set_cmdq_cnt(struct adf_accel_dev *accel_dev,
slice_cnt = &accel_dev->telemetry->slice_cnt;
cmdq_cnt = &accel_dev->telemetry->cmdq_cnt;
- cmdq_cnt->cpr_cnt = slice_cnt->cpr_cnt * tl_data->multiplier.cpr_cnt;
- cmdq_cnt->dcpr_cnt = slice_cnt->dcpr_cnt * tl_data->multiplier.dcpr_cnt;
- cmdq_cnt->pke_cnt = slice_cnt->pke_cnt * tl_data->multiplier.pke_cnt;
- cmdq_cnt->wat_cnt = slice_cnt->wat_cnt * tl_data->multiplier.wat_cnt;
- cmdq_cnt->wcp_cnt = slice_cnt->wcp_cnt * tl_data->multiplier.wcp_cnt;
- cmdq_cnt->ucs_cnt = slice_cnt->ucs_cnt * tl_data->multiplier.ucs_cnt;
- cmdq_cnt->ath_cnt = slice_cnt->ath_cnt * tl_data->multiplier.ath_cnt;
+ cmdq_cnt->cpr_cnt = slice_cnt->cpr_cnt ? tl_data->cmdq_cnt.cpr_cnt : 0;
+ cmdq_cnt->dcpr_cnt = slice_cnt->dcpr_cnt ? tl_data->cmdq_cnt.dcpr_cnt : 0;
+ cmdq_cnt->pke_cnt = slice_cnt->pke_cnt ? tl_data->cmdq_cnt.pke_cnt : 0;
+ cmdq_cnt->wat_cnt = slice_cnt->wat_cnt ? tl_data->cmdq_cnt.wat_cnt : 0;
+ cmdq_cnt->wcp_cnt = slice_cnt->wcp_cnt ? tl_data->cmdq_cnt.wcp_cnt : 0;
+ cmdq_cnt->ucs_cnt = slice_cnt->ucs_cnt ? tl_data->cmdq_cnt.ucs_cnt : 0;
+ cmdq_cnt->ath_cnt = slice_cnt->ath_cnt ? tl_data->cmdq_cnt.ath_cnt : 0;
}
int adf_tl_run(struct adf_accel_dev *accel_dev, int state)
diff --git a/drivers/crypto/intel/qat/qat_common/adf_telemetry.h b/drivers/crypto/intel/qat/qat_common/adf_telemetry.h
index 02d75c3c214a..96879d02c4fa 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_telemetry.h
+++ b/drivers/crypto/intel/qat/qat_common/adf_telemetry.h
@@ -44,7 +44,7 @@ struct adf_tl_hw_data {
u8 num_cmdq_counters;
u8 max_rp;
u8 max_sl_cnt;
- struct icp_qat_fw_init_admin_slice_cnt multiplier;
+ struct icp_qat_fw_init_admin_slice_cnt cmdq_cnt;
};
struct adf_telemetry {
diff --git a/drivers/crypto/intel/qat/qat_common/qat_compression.c b/drivers/crypto/intel/qat/qat_common/qat_compression.c
index 8129ad0c32d8..7a5b648302a0 100644
--- a/drivers/crypto/intel/qat/qat_common/qat_compression.c
+++ b/drivers/crypto/intel/qat/qat_common/qat_compression.c
@@ -241,7 +241,7 @@ static int qat_compression_alloc_dc_data(struct adf_accel_dev *accel_dev)
err:
accel_dev->dc_data = NULL;
kfree(obuff);
- devm_kfree(dev, dc_data);
+ kfree(dc_data);
return -ENOMEM;
}
diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c
index 815b8fb34cf4..e34393f56ef0 100644
--- a/drivers/crypto/omap-aes.c
+++ b/drivers/crypto/omap-aes.c
@@ -1199,9 +1199,11 @@ static void omap_aes_remove(struct platform_device *pdev)
omap_aes_unregister_algs(dd->pdata);
- crypto_engine_unregister_aeads(dd->pdata->aead_algs_info->algs_list,
- dd->pdata->aead_algs_info->registered);
- dd->pdata->aead_algs_info->registered = 0;
+ if (dd->pdata->aead_algs_info) {
+ crypto_engine_unregister_aeads(dd->pdata->aead_algs_info->algs_list,
+ dd->pdata->aead_algs_info->registered);
+ dd->pdata->aead_algs_info->registered = 0;
+ }
crypto_engine_exit(dd->engine);
diff --git a/drivers/crypto/qce/aead.c b/drivers/crypto/qce/aead.c
index e0061bfab216..8ce1a9f3c9d8 100644
--- a/drivers/crypto/qce/aead.c
+++ b/drivers/crypto/qce/aead.c
@@ -498,7 +498,9 @@ static int qce_aead_crypt(struct aead_request *req, int encrypt)
struct qce_aead_reqctx *rctx = aead_request_ctx_dma(req);
struct qce_aead_ctx *ctx = crypto_aead_ctx(tfm);
struct qce_alg_template *tmpl = to_aead_tmpl(tfm);
- unsigned int blocksize = crypto_aead_blocksize(tfm);
+ unsigned int blocksize = crypto_aead_blocksize(tfm), authsize;
+ struct scatterlist __sg[2], *msg_sg;
+ bool fallback = ctx->need_fallback;
rctx->flags = tmpl->alg_flags;
rctx->flags |= encrypt ? QCE_ENCRYPT : QCE_DECRYPT;
@@ -511,14 +513,40 @@ static int qce_aead_crypt(struct aead_request *req, int encrypt)
/* CE does not handle 0 length messages */
if (!rctx->cryptlen) {
if (!(IS_CCM(rctx->flags) && IS_DECRYPT(rctx->flags)))
- ctx->need_fallback = true;
+ fallback = true;
}
- /* If fallback is needed, schedule and exit */
- if (ctx->need_fallback) {
- /* Reset need_fallback in case the same ctx is used for another transaction */
- ctx->need_fallback = false;
+ /*
+ * CCM uses AES-CTR internally and the CE stalls on a partial final
+ * block, so a payload that is not a multiple of the block size has to
+ * be handled by the fallback.
+ */
+ if (IS_CCM(rctx->flags) && !IS_ALIGNED(rctx->cryptlen, AES_BLOCK_SIZE))
+ fallback = true;
+ /*
+ * The CE reliably processes CCM only when the message payload is a
+ * single contiguous buffer. The associated data is linearized into a
+ * bounce buffer before being handed to the engine, but a fragmented
+ * payload makes the engine stall waiting for input, so route those
+ * requests to the fallback.
+ */
+ if (IS_CCM(rctx->flags)) {
+ authsize = ctx->authsize;
+
+ msg_sg = scatterwalk_ffwd(__sg, req->src, req->assoclen);
+ if (sg_nents_for_len(msg_sg, rctx->cryptlen +
+ (encrypt ? 0 : authsize)) > 1)
+ fallback = true;
+
+ msg_sg = scatterwalk_ffwd(__sg, req->dst, req->assoclen);
+ if (sg_nents_for_len(msg_sg, rctx->cryptlen +
+ (encrypt ? authsize : 0)) > 1)
+ fallback = true;
+ }
+
+ /* If fallback is needed, schedule and exit */
+ if (fallback) {
aead_request_set_tfm(&rctx->fallback_req, ctx->fallback);
aead_request_set_callback(&rctx->fallback_req, req->base.flags,
req->base.complete, req->base.data);
@@ -577,8 +605,7 @@ static int qce_aead_ccm_setkey(struct crypto_aead *tfm, const u8 *key,
memcpy(ctx->enc_key, key, keylen);
memcpy(ctx->auth_key, key, keylen);
- if (keylen == AES_KEYSIZE_192)
- ctx->need_fallback = true;
+ ctx->need_fallback = (keylen == AES_KEYSIZE_192);
return IS_CCM_RFC4309(flags) ?
crypto_aead_setkey(ctx->fallback, key, keylen + QCE_CCM4309_SALT_SIZE) :
@@ -606,8 +633,7 @@ static int qce_aead_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int
authenc_keys.enckeylen != AES_KEYSIZE_192 &&
authenc_keys.enckeylen != AES_KEYSIZE_256)
return -EINVAL;
- if (authenc_keys.enckeylen == AES_KEYSIZE_192)
- ctx->need_fallback = true;
+ ctx->need_fallback = (authenc_keys.enckeylen == AES_KEYSIZE_192);
}
ctx->enc_keylen = authenc_keys.enckeylen;
diff --git a/drivers/crypto/qce/cipher.h b/drivers/crypto/qce/cipher.h
index 850f257d00f3..daea07551118 100644
--- a/drivers/crypto/qce/cipher.h
+++ b/drivers/crypto/qce/cipher.h
@@ -14,6 +14,7 @@
struct qce_cipher_ctx {
u8 enc_key[QCE_MAX_KEY_SIZE];
unsigned int enc_keylen;
+ bool use_fallback;
struct crypto_skcipher *fallback;
};
diff --git a/drivers/crypto/qce/common.h b/drivers/crypto/qce/common.h
index 9cd2e6ed8bbb..587d349da91d 100644
--- a/drivers/crypto/qce/common.h
+++ b/drivers/crypto/qce/common.h
@@ -82,7 +82,6 @@ struct qce_alg_template {
struct aead_alg aead;
} alg;
struct qce_device *qce;
- const u8 *hash_zero;
const u32 digest_size;
};
diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c
index b67d749db05f..738454dd3565 100644
--- a/drivers/crypto/qce/sha.c
+++ b/drivers/crypto/qce/sha.c
@@ -7,6 +7,7 @@
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/string.h>
+#include <linux/unaligned.h>
#include <crypto/internal/hash.h>
#include "common.h"
@@ -249,18 +250,56 @@ static int qce_ahash_update(struct ahash_request *req)
return qce->async_req_enqueue(tmpl->qce, &req->base);
}
+/*
+ * BAM DMA cannot handle zero-length transfers, so the driver always holds
+ * back at least one byte to submit to the engine. A zero rctx->buflen at
+ * finalization time does not necessarily mean the message is empty: the
+ * caller may have imported a state that already reflects some hashed data
+ * with nothing currently buffered. Handle both cases through the software
+ * fallback: reconstruct the running state when there is one instead of
+ * assuming the message is empty.
+ */
+static int qce_ahash_finalize_zero(struct ahash_request *req)
+{
+ struct qce_sha_reqctx *rctx = ahash_request_ctx_dma(req);
+ HASH_FBREQ_ON_STACK(fbreq, req);
+ struct __sha256_ctx core;
+ struct scatterlist sg;
+ int ret, i;
+
+ sg_init_table(&sg, 1);
+ ahash_request_set_crypt(fbreq, &sg, req->result, 0);
+
+ if (rctx->first_blk) {
+ ret = crypto_ahash_init(fbreq) ?: crypto_ahash_finup(fbreq);
+ } else {
+ core = (struct __sha256_ctx){
+ .bytecount = rctx->count,
+ };
+
+ /* rctx->digest is the raw big-endian dump of the engine's regs */
+ for (i = 0; i < SHA256_STATE_WORDS; i++)
+ core.state.h[i] = get_unaligned_be32(rctx->digest +
+ i * sizeof(u32));
+ if (IS_SHA_HMAC(rctx->flags))
+ core.bytecount += SHA256_BLOCK_SIZE;
+
+ ret = crypto_ahash_import_core(fbreq, &core) ?:
+ crypto_ahash_finup(fbreq);
+ }
+
+ HASH_REQUEST_ZERO(fbreq);
+ return ret;
+}
+
static int qce_ahash_final(struct ahash_request *req)
{
struct qce_sha_reqctx *rctx = ahash_request_ctx_dma(req);
struct qce_alg_template *tmpl = to_ahash_tmpl(req->base.tfm);
struct qce_device *qce = tmpl->qce;
- if (!rctx->buflen) {
- if (tmpl->hash_zero)
- memcpy(req->result, tmpl->hash_zero,
- tmpl->alg.ahash.halg.digestsize);
- return 0;
- }
+ if (!rctx->buflen)
+ return qce_ahash_finalize_zero(req);
rctx->last_blk = true;
@@ -292,12 +331,8 @@ static int qce_ahash_digest(struct ahash_request *req)
rctx->first_blk = true;
rctx->last_blk = true;
- if (!rctx->nbytes_orig) {
- if (tmpl->hash_zero)
- memcpy(req->result, tmpl->hash_zero,
- tmpl->alg.ahash.halg.digestsize);
- return 0;
- }
+ if (!rctx->nbytes_orig)
+ return qce_ahash_finalize_zero(req);
return qce->async_req_enqueue(tmpl->qce, &req->base);
}
@@ -431,9 +466,6 @@ static int qce_ahash_register_one(const struct qce_ahash_def *def,
alg->halg.digestsize = def->digestsize;
alg->halg.statesize = def->statesize;
- if (IS_SHA256(def->flags))
- tmpl->hash_zero = sha256_zero_message_hash;
-
base = &alg->halg.base;
base->cra_blocksize = def->blocksize;
base->cra_priority = 175;
diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c
index 03a3cec2bb90..79f764429edc 100644
--- a/drivers/crypto/qce/skcipher.c
+++ b/drivers/crypto/qce/skcipher.c
@@ -12,6 +12,7 @@
#include <linux/errno.h>
#include <crypto/aes.h>
#include <crypto/internal/skcipher.h>
+#include <crypto/xts.h>
#include "cipher.h"
@@ -179,14 +180,17 @@ static int qce_skcipher_setkey(struct crypto_skcipher *ablk, const u8 *key,
if (!key || !keylen)
return -EINVAL;
- /*
- * AES XTS key1 = key2 not supported by crypto engine.
- * Revisit to request a fallback cipher in this case.
- */
if (IS_XTS(flags)) {
+ ret = xts_verify_key(ablk, key, keylen);
+ if (ret)
+ return ret;
__keylen = keylen >> 1;
- if (!memcmp(key, key + __keylen, __keylen))
- return -ENOKEY;
+ /*
+ * QCE does not support key1 == key2 for XTS.
+ * Use fallback cipher in this case.
+ */
+ ctx->use_fallback = !crypto_memneq(key, key + __keylen,
+ __keylen);
} else {
__keylen = keylen;
}
@@ -215,12 +219,20 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
struct qce_cipher_reqctx *rctx = skcipher_request_ctx(req);
struct qce_alg_template *tmpl = to_cipher_tmpl(tfm);
unsigned int blocksize = crypto_skcipher_blocksize(tfm);
- int keylen;
+ int keylen, src_nents, dst_nents;
rctx->flags = tmpl->alg_flags;
rctx->flags |= encrypt ? QCE_ENCRYPT : QCE_DECRYPT;
keylen = IS_XTS(rctx->flags) ? ctx->enc_keylen >> 1 : ctx->enc_keylen;
+ /*
+ * XTS requires at least one full block of data. Reject anything
+ * shorter here as the engine would stall waiting for more input if
+ * such a request reached it.
+ */
+ if (IS_XTS(rctx->flags) && req->cryptlen < AES_BLOCK_SIZE)
+ return -EINVAL;
+
/* CE does not handle 0 length messages */
if (!req->cryptlen)
return 0;
@@ -233,6 +245,11 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
if (!IS_ALIGNED(req->cryptlen, blocksize))
return -EINVAL;
+ src_nents = sg_nents_for_len(req->src, req->cryptlen);
+ dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
+ if (src_nents < 0 || dst_nents < 0)
+ return -EINVAL;
+
/*
* Conditions for requesting a fallback cipher
* AES-192 (not supported by crypto engine (CE))
@@ -240,12 +257,20 @@ static int qce_skcipher_crypt(struct skcipher_request *req, int encrypt)
* AES-XTS request with len > QCE_SECTOR_SIZE and
* is not a multiple of it.(Revisit this condition to check if it is
* needed in all versions of CE)
+ * AES-CTR with a partial final block (the CE stalls waiting for a full
+ * block of input).
+ * AES-XTS with key1 == key2 (not supported by the CE).
+ * A payload fragmented across more than one scatterlist entry (the CE
+ * stalls waiting for input in that case too).
*/
if (IS_AES(rctx->flags) &&
((keylen != AES_KEYSIZE_128 && keylen != AES_KEYSIZE_256) ||
+ (IS_CTR(rctx->flags) && !IS_ALIGNED(req->cryptlen, AES_BLOCK_SIZE)) ||
(IS_XTS(rctx->flags) && ((req->cryptlen <= aes_sw_max_len) ||
(req->cryptlen > QCE_SECTOR_SIZE &&
- req->cryptlen % QCE_SECTOR_SIZE))))) {
+ req->cryptlen % QCE_SECTOR_SIZE))) ||
+ (IS_XTS(rctx->flags) && ctx->use_fallback) ||
+ src_nents > 1 || dst_nents > 1)) {
skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback);
skcipher_request_set_callback(&rctx->fallback_req,
req->base.flags,
diff --git a/include/crypto/arc4.h b/include/crypto/arc4.h
index f3c22fe01704..f88a5fb85c9a 100644
--- a/include/crypto/arc4.h
+++ b/include/crypto/arc4.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * Common values for ARC4 Cipher Algorithm
+ * ARC4 Cipher Algorithm
*/
#ifndef _CRYPTO_ARC4_H
@@ -10,7 +10,6 @@
#define ARC4_MIN_KEY_SIZE 1
#define ARC4_MAX_KEY_SIZE 256
-#define ARC4_BLOCK_SIZE 1
struct arc4_ctx {
u32 S[256];
diff --git a/include/crypto/internal/rng.h b/include/crypto/internal/rng.h
deleted file mode 100644
index e0711b6a597f..000000000000
--- a/include/crypto/internal/rng.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * RNG: Random Number Generator algorithms under the crypto API
- *
- * Copyright (c) 2008 Neil Horman <nhorman@tuxdriver.com>
- * Copyright (c) 2015 Herbert Xu <herbert@gondor.apana.org.au>
- */
-
-#ifndef _CRYPTO_INTERNAL_RNG_H
-#define _CRYPTO_INTERNAL_RNG_H
-
-#include <crypto/algapi.h>
-#include <crypto/rng.h>
-
-int crypto_register_rng(struct rng_alg *alg);
-void crypto_unregister_rng(struct rng_alg *alg);
-int crypto_register_rngs(struct rng_alg *algs, int count);
-void crypto_unregister_rngs(struct rng_alg *algs, int count);
-
-#if defined(CONFIG_CRYPTO_RNG) || defined(CONFIG_CRYPTO_RNG_MODULE)
-int crypto_del_default_rng(void);
-#else
-static inline int crypto_del_default_rng(void)
-{
- return 0;
-}
-#endif
-
-static inline void *crypto_rng_ctx(struct crypto_rng *tfm)
-{
- return crypto_tfm_ctx(&tfm->base);
-}
-
-static inline void crypto_rng_set_entropy(struct crypto_rng *tfm,
- const u8 *data, unsigned int len)
-{
- crypto_rng_alg(tfm)->set_ent(tfm, data, len);
-}
-
-#endif
diff --git a/include/crypto/rng.h b/include/crypto/rng.h
index 07f494b2c881..719401225f92 100644
--- a/include/crypto/rng.h
+++ b/include/crypto/rng.h
@@ -9,71 +9,23 @@
#ifndef _CRYPTO_RNG_H
#define _CRYPTO_RNG_H
-#include <linux/atomic.h>
-#include <linux/container_of.h>
-#include <linux/crypto.h>
#include <linux/fips.h>
#include <linux/random.h>
-struct crypto_rng;
-
-/**
- * struct rng_alg - random number generator definition
- *
- * @generate: The function defined by this variable obtains a
- * random number. The random number generator transform
- * must generate the random number out of the context
- * provided with this call, plus any additional data
- * if provided to the call.
- * @seed: Seed or reseed the random number generator. With the
- * invocation of this function call, the random number
- * generator shall become ready for generation. If the
- * random number generator requires a seed for setting
- * up a new state, the seed must be provided by the
- * consumer while invoking this function. The required
- * size of the seed is defined with @seedsize .
- * @set_ent: Set entropy that would otherwise be obtained from
- * entropy source. Internal use only.
- * @seedsize: The seed size required for a random number generator
- * initialization defined with this variable. Some
- * random number generators does not require a seed
- * as the seeding is implemented internally without
- * the need of support by the consumer. In this case,
- * the seed size is set to zero.
- * @base: Common crypto API algorithm data structure.
- */
-struct rng_alg {
- int (*generate)(struct crypto_rng *tfm,
- const u8 *src, unsigned int slen,
- u8 *dst, unsigned int dlen);
- int (*seed)(struct crypto_rng *tfm, const u8 *seed, unsigned int slen);
- void (*set_ent)(struct crypto_rng *tfm, const u8 *data,
- unsigned int len);
-
- unsigned int seedsize;
-
- struct crypto_alg base;
-};
-
-struct crypto_rng {
- struct crypto_tfm base;
-};
-
-int __crypto_stdrng_get_bytes(void *buf, unsigned int len);
+int __crypto_stdrng_get_bytes(void *buf, size_t len);
/**
* crypto_stdrng_get_bytes() - get cryptographically secure random bytes
* @buf: output buffer holding the random numbers
* @len: length of the output buffer
*
- * This function fills the caller-allocated buffer with random numbers using the
- * normal Linux RNG if fips_enabled=0, or the highest-priority "stdrng"
- * algorithm in the crypto_rng subsystem if fips_enabled=1.
+ * This function fills the given buffer with random numbers using the normal
+ * Linux RNG if fips_enabled=0, or a NIST SP800-90A DRBG if fips_enabled=1.
*
* Context: May sleep
* Return: 0 function was successful; < 0 if an error occurred
*/
-static inline int crypto_stdrng_get_bytes(void *buf, unsigned int len)
+static inline int crypto_stdrng_get_bytes(void *buf, size_t len)
{
might_sleep();
if (fips_enabled)
@@ -81,139 +33,13 @@ static inline int crypto_stdrng_get_bytes(void *buf, unsigned int len)
return get_random_bytes_wait(buf, len);
}
-/**
- * DOC: Random number generator API
- *
- * The random number generator API is used with the ciphers of type
- * CRYPTO_ALG_TYPE_RNG (listed as type "rng" in /proc/crypto)
- */
-
-/**
- * crypto_alloc_rng() -- allocate RNG handle
- * @alg_name: is the cra_name / name or cra_driver_name / driver name of the
- * message digest cipher
- * @type: specifies the type of the cipher
- * @mask: specifies the mask for the cipher
- *
- * Allocate a cipher handle for a random number generator. The returned struct
- * crypto_rng is the cipher handle that is required for any subsequent
- * API invocation for that random number generator.
- *
- * For all random number generators, this call creates a new private copy of
- * the random number generator that does not share a state with other
- * instances. The only exception is the "krng" random number generator which
- * is a kernel crypto API use case for the get_random_bytes() function of the
- * /dev/random driver.
- *
- * Return: allocated cipher handle in case of success; IS_ERR() is true in case
- * of an error, PTR_ERR() returns the error code.
- */
-struct crypto_rng *crypto_alloc_rng(const char *alg_name, u32 type, u32 mask);
-
-static inline struct crypto_tfm *crypto_rng_tfm(struct crypto_rng *tfm)
-{
- return &tfm->base;
-}
-
-static inline struct rng_alg *__crypto_rng_alg(struct crypto_alg *alg)
-{
- return container_of(alg, struct rng_alg, base);
-}
-
-/**
- * crypto_rng_alg() - obtain 'struct rng_alg' pointer from RNG handle
- * @tfm: RNG handle
- *
- * Return: Pointer to 'struct rng_alg', derived from @tfm RNG handle
- */
-static inline struct rng_alg *crypto_rng_alg(struct crypto_rng *tfm)
-{
- return __crypto_rng_alg(crypto_rng_tfm(tfm)->__crt_alg);
-}
-
-/**
- * crypto_free_rng() - zeroize and free RNG handle
- * @tfm: cipher handle to be freed
- *
- * If @tfm is a NULL or error pointer, this function does nothing.
- */
-static inline void crypto_free_rng(struct crypto_rng *tfm)
-{
- crypto_destroy_tfm(tfm, crypto_rng_tfm(tfm));
-}
-
-/**
- * crypto_rng_generate() - get random number
- * @tfm: cipher handle
- * @src: Input buffer holding additional data, may be NULL
- * @slen: Length of additional data
- * @dst: output buffer holding the random numbers
- * @dlen: length of the output buffer
- *
- * This function fills the caller-allocated buffer with random
- * numbers using the random number generator referenced by the
- * cipher handle.
- *
- * Return: 0 function was successful; < 0 if an error occurred
- */
-static inline int crypto_rng_generate(struct crypto_rng *tfm,
- const u8 *src, unsigned int slen,
- u8 *dst, unsigned int dlen)
+#ifdef CONFIG_CRYPTO_FIPS
+int crypto_del_default_rng(void);
+#else
+static inline int crypto_del_default_rng(void)
{
- return crypto_rng_alg(tfm)->generate(tfm, src, slen, dst, dlen);
-}
-
-/**
- * crypto_rng_get_bytes() - get random number
- * @tfm: cipher handle
- * @rdata: output buffer holding the random numbers
- * @dlen: length of the output buffer
- *
- * This function fills the caller-allocated buffer with random numbers using the
- * random number generator referenced by the cipher handle.
- *
- * Return: 0 function was successful; < 0 if an error occurred
- */
-static inline int crypto_rng_get_bytes(struct crypto_rng *tfm,
- u8 *rdata, unsigned int dlen)
-{
- return crypto_rng_generate(tfm, NULL, 0, rdata, dlen);
-}
-
-/**
- * crypto_rng_reset() - re-initialize the RNG
- * @tfm: cipher handle
- * @seed: seed input data
- * @slen: length of the seed input data
- *
- * The reset function completely re-initializes the random number generator
- * referenced by the cipher handle by clearing the current state. The new state
- * is initialized with the caller provided seed or automatically, depending on
- * the random number generator type. (The SP800-90A DRBGs perform an automatic
- * seeding.) The seed is provided as a parameter to this function call. The
- * provided seed should have the length of the seed size defined for the random
- * number generator as defined by crypto_rng_seedsize.
- *
- * Return: 0 if the setting of the key was successful; < 0 if an error occurred
- */
-int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed,
- unsigned int slen);
-
-/**
- * crypto_rng_seedsize() - obtain seed size of RNG
- * @tfm: cipher handle
- *
- * The function returns the seed size for the random number generator
- * referenced by the cipher handle. This value may be zero if the random
- * number generator does not implement or require a reseeding. For example,
- * the SP800-90A DRBGs implement an automated reseeding after reaching a
- * pre-defined threshold.
- *
- * Return: seed size for the random number generator
- */
-static inline int crypto_rng_seedsize(struct crypto_rng *tfm)
-{
- return crypto_rng_alg(tfm)->seedsize;
+ return 0;
}
+#endif
#endif
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index b7c97f1c47c9..bfad00a1339c 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -31,7 +31,6 @@
#define CRYPTO_ALG_TYPE_KPP 0x00000008
#define CRYPTO_ALG_TYPE_ACOMPRESS 0x0000000a
#define CRYPTO_ALG_TYPE_SCOMPRESS 0x0000000b
-#define CRYPTO_ALG_TYPE_RNG 0x0000000c
#define CRYPTO_ALG_TYPE_HASH 0x0000000e
#define CRYPTO_ALG_TYPE_SHASH 0x0000000e
#define CRYPTO_ALG_TYPE_AHASH 0x0000000f
@@ -307,7 +306,7 @@ struct cipher_alg {
* @cra_type: Type of the cryptographic transformation. This is a pointer to
* struct crypto_type, which implements callbacks common for all
* transformation types. There are multiple options, such as
- * &crypto_skcipher_type, &crypto_ahash_type, &crypto_rng_type.
+ * &crypto_skcipher_type, &crypto_ahash_type.
* This field might be empty. In that case, there are no common
* callbacks. This is the case for: cipher.
* @cra_u: Callbacks implementing the transformation. This is a union of
diff --git a/include/uapi/linux/cryptouser.h b/include/uapi/linux/cryptouser.h
index db05e0419972..29f9c6c4290b 100644
--- a/include/uapi/linux/cryptouser.h
+++ b/include/uapi/linux/cryptouser.h
@@ -49,7 +49,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_REPORT_BLKCIPHER, /* struct crypto_report_blkcipher */
CRYPTOCFGA_REPORT_AEAD, /* struct crypto_report_aead */
CRYPTOCFGA_REPORT_COMPRESS, /* struct crypto_report_comp */
- CRYPTOCFGA_REPORT_RNG, /* struct crypto_report_rng */
+ CRYPTOCFGA_REPORT_RNG, /* No longer supported, do not use. */
CRYPTOCFGA_REPORT_CIPHER, /* struct crypto_report_cipher */
CRYPTOCFGA_REPORT_AKCIPHER, /* struct crypto_report_akcipher */
CRYPTOCFGA_REPORT_KPP, /* struct crypto_report_kpp */
@@ -191,6 +191,7 @@ struct crypto_report_comp {
char type[CRYPTO_MAX_NAME];
};
+/* No longer supported, do not use. */
struct crypto_report_rng {
char type[CRYPTO_MAX_NAME];
unsigned int seedsize;
diff --git a/lib/lzo/lzo1x_compress.c b/lib/lzo/lzo1x_compress.c
index 01586af2347f..621bbb969fb4 100644
--- a/lib/lzo/lzo1x_compress.c
+++ b/lib/lzo/lzo1x_compress.c
@@ -349,6 +349,7 @@ static int LZO_SAFE(lzogeneric1x_1_compress)(
// LZO v0 will never write 17 as first byte (except for zero-length
// input), so this is used to version the bitstream
if (bitstream_version > 0) {
+ NEED_OP(2);
*op++ = 17;
*op++ = bitstream_version;
m4_max_offset = M4_MAX_OFFSET_V1;