Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto updates from Herbert Xu:
"API:
- Add library interfaces of certain crypto algorithms for WireGuard
- Remove the obsolete ablkcipher and blkcipher interfaces
- Move add_early_randomness() out of rng_mutex
Algorithms:
- Add blake2b shash algorithm
- Add blake2s shash algorithm
- Add curve25519 kpp algorithm
- Implement 4 way interleave in arm64/gcm-ce
- Implement ciphertext stealing in powerpc/spe-xts
- Add Eric Biggers's scalar accelerated ChaCha code for ARM
- Add accelerated 32r2 code from Zinc for MIPS
- Add OpenSSL/CRYPTOGRAMS poly1305 implementation for ARM and MIPS
Drivers:
- Fix entropy reading failures in ks-sa
- Add support for sam9x60 in atmel
- Add crypto accelerator for amlogic GXL
- Add sun8i-ce Crypto Engine
- Add sun8i-ss cryptographic offloader
- Add a host of algorithms to inside-secure
- Add NPCM RNG driver
- add HiSilicon HPRE accelerator
- Add HiSilicon TRNG driver"
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (285 commits)
crypto: vmx - Avoid weird build failures
crypto: lib/chacha20poly1305 - use chacha20_crypt()
crypto: x86/chacha - only unregister algorithms if registered
crypto: chacha_generic - remove unnecessary setkey() functions
crypto: amlogic - enable working on big endian kernel
crypto: sun8i-ce - enable working on big endian
crypto: mips/chacha - select CRYPTO_SKCIPHER, not CRYPTO_BLKCIPHER
hwrng: ks-sa - Enable COMPILE_TEST
crypto: essiv - remove redundant null pointer check before kfree
crypto: atmel-aes - Change data type for "lastc" buffer
crypto: atmel-tdes - Set the IV after {en,de}crypt
crypto: sun4i-ss - fix big endian issues
crypto: sun4i-ss - hide the Invalid keylen message
crypto: sun4i-ss - use crypto_ahash_digestsize
crypto: sun4i-ss - remove dependency on not 64BIT
crypto: sun4i-ss - Fix 64-bit size_t warnings on sun4i-ss-hash.c
MAINTAINERS: Add maintainer for HiSilicon SEC V2 driver
crypto: hisilicon - add DebugFS for HiSilicon SEC
Documentation: add DebugFS doc for HiSilicon SEC
crypto: hisilicon - add SRIOV for HiSilicon SEC
...
This commit is contained in:
+115
-56
@@ -52,12 +52,12 @@ config CRYPTO_AEAD2
|
||||
select CRYPTO_NULL2
|
||||
select CRYPTO_RNG2
|
||||
|
||||
config CRYPTO_BLKCIPHER
|
||||
config CRYPTO_SKCIPHER
|
||||
tristate
|
||||
select CRYPTO_BLKCIPHER2
|
||||
select CRYPTO_SKCIPHER2
|
||||
select CRYPTO_ALGAPI
|
||||
|
||||
config CRYPTO_BLKCIPHER2
|
||||
config CRYPTO_SKCIPHER2
|
||||
tristate
|
||||
select CRYPTO_ALGAPI2
|
||||
select CRYPTO_RNG2
|
||||
@@ -123,7 +123,7 @@ config CRYPTO_MANAGER2
|
||||
def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y)
|
||||
select CRYPTO_AEAD2
|
||||
select CRYPTO_HASH2
|
||||
select CRYPTO_BLKCIPHER2
|
||||
select CRYPTO_SKCIPHER2
|
||||
select CRYPTO_AKCIPHER2
|
||||
select CRYPTO_KPP2
|
||||
select CRYPTO_ACOMP2
|
||||
@@ -169,7 +169,7 @@ config CRYPTO_NULL
|
||||
config CRYPTO_NULL2
|
||||
tristate
|
||||
select CRYPTO_ALGAPI2
|
||||
select CRYPTO_BLKCIPHER2
|
||||
select CRYPTO_SKCIPHER2
|
||||
select CRYPTO_HASH2
|
||||
|
||||
config CRYPTO_PCRYPT
|
||||
@@ -184,7 +184,7 @@ config CRYPTO_PCRYPT
|
||||
|
||||
config CRYPTO_CRYPTD
|
||||
tristate "Software async crypto daemon"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_HASH
|
||||
select CRYPTO_MANAGER
|
||||
help
|
||||
@@ -195,7 +195,7 @@ config CRYPTO_CRYPTD
|
||||
config CRYPTO_AUTHENC
|
||||
tristate "Authenc support"
|
||||
select CRYPTO_AEAD
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_MANAGER
|
||||
select CRYPTO_HASH
|
||||
select CRYPTO_NULL
|
||||
@@ -217,7 +217,7 @@ config CRYPTO_SIMD
|
||||
config CRYPTO_GLUE_HELPER_X86
|
||||
tristate
|
||||
depends on X86
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
|
||||
config CRYPTO_ENGINE
|
||||
tristate
|
||||
@@ -264,6 +264,17 @@ config CRYPTO_ECRDSA
|
||||
standard algorithms (called GOST algorithms). Only signature verification
|
||||
is implemented.
|
||||
|
||||
config CRYPTO_CURVE25519
|
||||
tristate "Curve25519 algorithm"
|
||||
select CRYPTO_KPP
|
||||
select CRYPTO_LIB_CURVE25519_GENERIC
|
||||
|
||||
config CRYPTO_CURVE25519_X86
|
||||
tristate "x86_64 accelerated Curve25519 scalar multiplication library"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_LIB_CURVE25519_GENERIC
|
||||
select CRYPTO_ARCH_HAVE_LIB_CURVE25519
|
||||
|
||||
comment "Authenticated Encryption with Associated Data"
|
||||
|
||||
config CRYPTO_CCM
|
||||
@@ -309,6 +320,7 @@ config CRYPTO_AEGIS128
|
||||
config CRYPTO_AEGIS128_SIMD
|
||||
bool "Support SIMD acceleration for AEGIS-128"
|
||||
depends on CRYPTO_AEGIS128 && ((ARM || ARM64) && KERNEL_MODE_NEON)
|
||||
depends on !ARM || CC_IS_CLANG || GCC_VERSION >= 40800
|
||||
default y
|
||||
|
||||
config CRYPTO_AEGIS128_AESNI_SSE2
|
||||
@@ -322,7 +334,7 @@ config CRYPTO_AEGIS128_AESNI_SSE2
|
||||
config CRYPTO_SEQIV
|
||||
tristate "Sequence Number IV Generator"
|
||||
select CRYPTO_AEAD
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_NULL
|
||||
select CRYPTO_RNG_DEFAULT
|
||||
select CRYPTO_MANAGER
|
||||
@@ -345,7 +357,7 @@ comment "Block modes"
|
||||
|
||||
config CRYPTO_CBC
|
||||
tristate "CBC support"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_MANAGER
|
||||
help
|
||||
CBC: Cipher Block Chaining mode
|
||||
@@ -353,7 +365,7 @@ config CRYPTO_CBC
|
||||
|
||||
config CRYPTO_CFB
|
||||
tristate "CFB support"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_MANAGER
|
||||
help
|
||||
CFB: Cipher FeedBack mode
|
||||
@@ -361,7 +373,7 @@ config CRYPTO_CFB
|
||||
|
||||
config CRYPTO_CTR
|
||||
tristate "CTR support"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_SEQIV
|
||||
select CRYPTO_MANAGER
|
||||
help
|
||||
@@ -370,7 +382,7 @@ config CRYPTO_CTR
|
||||
|
||||
config CRYPTO_CTS
|
||||
tristate "CTS support"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_MANAGER
|
||||
help
|
||||
CTS: Cipher Text Stealing
|
||||
@@ -385,7 +397,7 @@ config CRYPTO_CTS
|
||||
|
||||
config CRYPTO_ECB
|
||||
tristate "ECB support"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_MANAGER
|
||||
help
|
||||
ECB: Electronic CodeBook mode
|
||||
@@ -394,7 +406,7 @@ config CRYPTO_ECB
|
||||
|
||||
config CRYPTO_LRW
|
||||
tristate "LRW support"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_MANAGER
|
||||
select CRYPTO_GF128MUL
|
||||
help
|
||||
@@ -406,7 +418,7 @@ config CRYPTO_LRW
|
||||
|
||||
config CRYPTO_OFB
|
||||
tristate "OFB support"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_MANAGER
|
||||
help
|
||||
OFB: the Output Feedback mode makes a block cipher into a synchronous
|
||||
@@ -418,7 +430,7 @@ config CRYPTO_OFB
|
||||
|
||||
config CRYPTO_PCBC
|
||||
tristate "PCBC support"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_MANAGER
|
||||
help
|
||||
PCBC: Propagating Cipher Block Chaining mode
|
||||
@@ -426,7 +438,7 @@ config CRYPTO_PCBC
|
||||
|
||||
config CRYPTO_XTS
|
||||
tristate "XTS support"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_MANAGER
|
||||
select CRYPTO_ECB
|
||||
help
|
||||
@@ -436,7 +448,7 @@ config CRYPTO_XTS
|
||||
|
||||
config CRYPTO_KEYWRAP
|
||||
tristate "Key wrapping support"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_MANAGER
|
||||
help
|
||||
Support for key wrapping (NIST SP800-38F / RFC3394) without
|
||||
@@ -445,7 +457,7 @@ config CRYPTO_KEYWRAP
|
||||
config CRYPTO_NHPOLY1305
|
||||
tristate
|
||||
select CRYPTO_HASH
|
||||
select CRYPTO_POLY1305
|
||||
select CRYPTO_LIB_POLY1305_GENERIC
|
||||
|
||||
config CRYPTO_NHPOLY1305_SSE2
|
||||
tristate "NHPoly1305 hash function (x86_64 SSE2 implementation)"
|
||||
@@ -466,7 +478,7 @@ config CRYPTO_NHPOLY1305_AVX2
|
||||
config CRYPTO_ADIANTUM
|
||||
tristate "Adiantum support"
|
||||
select CRYPTO_CHACHA20
|
||||
select CRYPTO_POLY1305
|
||||
select CRYPTO_LIB_POLY1305_GENERIC
|
||||
select CRYPTO_NHPOLY1305
|
||||
select CRYPTO_MANAGER
|
||||
help
|
||||
@@ -638,6 +650,47 @@ config CRYPTO_XXHASH
|
||||
xxHash non-cryptographic hash algorithm. Extremely fast, working at
|
||||
speeds close to RAM limits.
|
||||
|
||||
config CRYPTO_BLAKE2B
|
||||
tristate "BLAKE2b digest algorithm"
|
||||
select CRYPTO_HASH
|
||||
help
|
||||
Implementation of cryptographic hash function BLAKE2b (or just BLAKE2),
|
||||
optimized for 64bit platforms and can produce digests of any size
|
||||
between 1 to 64. The keyed hash is also implemented.
|
||||
|
||||
This module provides the following algorithms:
|
||||
|
||||
- blake2b-160
|
||||
- blake2b-256
|
||||
- blake2b-384
|
||||
- blake2b-512
|
||||
|
||||
See https://blake2.net for further information.
|
||||
|
||||
config CRYPTO_BLAKE2S
|
||||
tristate "BLAKE2s digest algorithm"
|
||||
select CRYPTO_LIB_BLAKE2S_GENERIC
|
||||
select CRYPTO_HASH
|
||||
help
|
||||
Implementation of cryptographic hash function BLAKE2s
|
||||
optimized for 8-32bit platforms and can produce digests of any size
|
||||
between 1 to 32. The keyed hash is also implemented.
|
||||
|
||||
This module provides the following algorithms:
|
||||
|
||||
- blake2s-128
|
||||
- blake2s-160
|
||||
- blake2s-224
|
||||
- blake2s-256
|
||||
|
||||
See https://blake2.net for further information.
|
||||
|
||||
config CRYPTO_BLAKE2S_X86
|
||||
tristate "BLAKE2s digest algorithm (x86 accelerated version)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_LIB_BLAKE2S_GENERIC
|
||||
select CRYPTO_ARCH_HAVE_LIB_BLAKE2S
|
||||
|
||||
config CRYPTO_CRCT10DIF
|
||||
tristate "CRCT10DIF algorithm"
|
||||
select CRYPTO_HASH
|
||||
@@ -685,6 +738,7 @@ config CRYPTO_GHASH
|
||||
config CRYPTO_POLY1305
|
||||
tristate "Poly1305 authenticator algorithm"
|
||||
select CRYPTO_HASH
|
||||
select CRYPTO_LIB_POLY1305_GENERIC
|
||||
help
|
||||
Poly1305 authenticator algorithm, RFC7539.
|
||||
|
||||
@@ -695,7 +749,8 @@ config CRYPTO_POLY1305
|
||||
config CRYPTO_POLY1305_X86_64
|
||||
tristate "Poly1305 authenticator algorithm (x86_64/SSE2/AVX2)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_POLY1305
|
||||
select CRYPTO_LIB_POLY1305_GENERIC
|
||||
select CRYPTO_ARCH_HAVE_LIB_POLY1305
|
||||
help
|
||||
Poly1305 authenticator algorithm, RFC7539.
|
||||
|
||||
@@ -704,6 +759,11 @@ config CRYPTO_POLY1305_X86_64
|
||||
in IETF protocols. This is the x86_64 assembler implementation using SIMD
|
||||
instructions.
|
||||
|
||||
config CRYPTO_POLY1305_MIPS
|
||||
tristate "Poly1305 authenticator algorithm (MIPS optimized)"
|
||||
depends on CPU_MIPS32 || (CPU_MIPS64 && 64BIT)
|
||||
select CRYPTO_ARCH_HAVE_LIB_POLY1305
|
||||
|
||||
config CRYPTO_MD4
|
||||
tristate "MD4 digest algorithm"
|
||||
select CRYPTO_HASH
|
||||
@@ -877,9 +937,6 @@ config CRYPTO_SHA1_PPC_SPE
|
||||
SHA-1 secure hash standard (DFIPS 180-4) implemented
|
||||
using powerpc SPE SIMD instruction set.
|
||||
|
||||
config CRYPTO_LIB_SHA256
|
||||
tristate
|
||||
|
||||
config CRYPTO_SHA256
|
||||
tristate "SHA224 and SHA256 digest algorithm"
|
||||
select CRYPTO_HASH
|
||||
@@ -1018,9 +1075,6 @@ config CRYPTO_GHASH_CLMUL_NI_INTEL
|
||||
|
||||
comment "Ciphers"
|
||||
|
||||
config CRYPTO_LIB_AES
|
||||
tristate
|
||||
|
||||
config CRYPTO_AES
|
||||
tristate "AES cipher algorithms"
|
||||
select CRYPTO_ALGAPI
|
||||
@@ -1067,7 +1121,7 @@ config CRYPTO_AES_NI_INTEL
|
||||
select CRYPTO_AEAD
|
||||
select CRYPTO_LIB_AES
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_GLUE_HELPER_X86 if 64BIT
|
||||
select CRYPTO_SIMD
|
||||
help
|
||||
@@ -1097,8 +1151,7 @@ config CRYPTO_AES_NI_INTEL
|
||||
config CRYPTO_AES_SPARC64
|
||||
tristate "AES cipher algorithms (SPARC64)"
|
||||
depends on SPARC64
|
||||
select CRYPTO_CRYPTD
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_SKCIPHER
|
||||
help
|
||||
Use SPARC64 crypto opcodes for AES algorithm.
|
||||
|
||||
@@ -1125,6 +1178,7 @@ config CRYPTO_AES_SPARC64
|
||||
config CRYPTO_AES_PPC_SPE
|
||||
tristate "AES cipher algorithms (PPC SPE)"
|
||||
depends on PPC && SPE
|
||||
select CRYPTO_SKCIPHER
|
||||
help
|
||||
AES cipher algorithms (FIPS-197). Additionally the acceleration
|
||||
for popular block cipher modes ECB, CBC, CTR and XTS is supported.
|
||||
@@ -1149,12 +1203,9 @@ config CRYPTO_ANUBIS
|
||||
<https://www.cosic.esat.kuleuven.be/nessie/reports/>
|
||||
<http://www.larc.usp.br/~pbarreto/AnubisPage.html>
|
||||
|
||||
config CRYPTO_LIB_ARC4
|
||||
tristate
|
||||
|
||||
config CRYPTO_ARC4
|
||||
tristate "ARC4 cipher algorithm"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_LIB_ARC4
|
||||
help
|
||||
ARC4 cipher algorithm.
|
||||
@@ -1190,7 +1241,7 @@ config CRYPTO_BLOWFISH_COMMON
|
||||
config CRYPTO_BLOWFISH_X86_64
|
||||
tristate "Blowfish cipher algorithm (x86_64)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_BLOWFISH_COMMON
|
||||
help
|
||||
Blowfish cipher algorithm (x86_64), by Bruce Schneier.
|
||||
@@ -1221,7 +1272,7 @@ config CRYPTO_CAMELLIA_X86_64
|
||||
tristate "Camellia cipher algorithm (x86_64)"
|
||||
depends on X86 && 64BIT
|
||||
depends on CRYPTO
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_GLUE_HELPER_X86
|
||||
help
|
||||
Camellia cipher algorithm module (x86_64).
|
||||
@@ -1238,7 +1289,7 @@ config CRYPTO_CAMELLIA_AESNI_AVX_X86_64
|
||||
tristate "Camellia cipher algorithm (x86_64/AES-NI/AVX)"
|
||||
depends on X86 && 64BIT
|
||||
depends on CRYPTO
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_CAMELLIA_X86_64
|
||||
select CRYPTO_GLUE_HELPER_X86
|
||||
select CRYPTO_SIMD
|
||||
@@ -1275,6 +1326,7 @@ config CRYPTO_CAMELLIA_SPARC64
|
||||
depends on SPARC64
|
||||
depends on CRYPTO
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_SKCIPHER
|
||||
help
|
||||
Camellia cipher algorithm module (SPARC64).
|
||||
|
||||
@@ -1303,7 +1355,7 @@ config CRYPTO_CAST5
|
||||
config CRYPTO_CAST5_AVX_X86_64
|
||||
tristate "CAST5 (CAST-128) cipher algorithm (x86_64/AVX)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_CAST5
|
||||
select CRYPTO_CAST_COMMON
|
||||
select CRYPTO_SIMD
|
||||
@@ -1325,7 +1377,7 @@ config CRYPTO_CAST6
|
||||
config CRYPTO_CAST6_AVX_X86_64
|
||||
tristate "CAST6 (CAST-256) cipher algorithm (x86_64/AVX)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_CAST6
|
||||
select CRYPTO_CAST_COMMON
|
||||
select CRYPTO_GLUE_HELPER_X86
|
||||
@@ -1338,9 +1390,6 @@ config CRYPTO_CAST6_AVX_X86_64
|
||||
This module provides the Cast6 cipher algorithm that processes
|
||||
eight blocks parallel using the AVX instruction set.
|
||||
|
||||
config CRYPTO_LIB_DES
|
||||
tristate
|
||||
|
||||
config CRYPTO_DES
|
||||
tristate "DES and Triple DES EDE cipher algorithms"
|
||||
select CRYPTO_ALGAPI
|
||||
@@ -1353,6 +1402,7 @@ config CRYPTO_DES_SPARC64
|
||||
depends on SPARC64
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_LIB_DES
|
||||
select CRYPTO_SKCIPHER
|
||||
help
|
||||
DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3),
|
||||
optimized using SPARC64 crypto opcodes.
|
||||
@@ -1360,7 +1410,7 @@ config CRYPTO_DES_SPARC64
|
||||
config CRYPTO_DES3_EDE_X86_64
|
||||
tristate "Triple DES EDE cipher algorithm (x86-64)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_LIB_DES
|
||||
help
|
||||
Triple DES EDE (FIPS 46-3) algorithm.
|
||||
@@ -1373,7 +1423,7 @@ config CRYPTO_DES3_EDE_X86_64
|
||||
config CRYPTO_FCRYPT
|
||||
tristate "FCrypt cipher algorithm"
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
help
|
||||
FCrypt algorithm used by RxRPC.
|
||||
|
||||
@@ -1392,7 +1442,7 @@ config CRYPTO_KHAZAD
|
||||
|
||||
config CRYPTO_SALSA20
|
||||
tristate "Salsa20 stream cipher algorithm"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
help
|
||||
Salsa20 stream cipher algorithm.
|
||||
|
||||
@@ -1404,7 +1454,8 @@ config CRYPTO_SALSA20
|
||||
|
||||
config CRYPTO_CHACHA20
|
||||
tristate "ChaCha stream cipher algorithms"
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_LIB_CHACHA_GENERIC
|
||||
select CRYPTO_SKCIPHER
|
||||
help
|
||||
The ChaCha20, XChaCha20, and XChaCha12 stream cipher algorithms.
|
||||
|
||||
@@ -1426,12 +1477,19 @@ config CRYPTO_CHACHA20
|
||||
config CRYPTO_CHACHA20_X86_64
|
||||
tristate "ChaCha stream cipher algorithms (x86_64/SSSE3/AVX2/AVX-512VL)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_CHACHA20
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_LIB_CHACHA_GENERIC
|
||||
select CRYPTO_ARCH_HAVE_LIB_CHACHA
|
||||
help
|
||||
SSSE3, AVX2, and AVX-512VL optimized implementations of the ChaCha20,
|
||||
XChaCha20, and XChaCha12 stream ciphers.
|
||||
|
||||
config CRYPTO_CHACHA_MIPS
|
||||
tristate "ChaCha stream cipher algorithms (MIPS 32r2 optimized)"
|
||||
depends on CPU_MIPS32_R2
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_ARCH_HAVE_LIB_CHACHA
|
||||
|
||||
config CRYPTO_SEED
|
||||
tristate "SEED cipher algorithm"
|
||||
select CRYPTO_ALGAPI
|
||||
@@ -1462,7 +1520,7 @@ config CRYPTO_SERPENT
|
||||
config CRYPTO_SERPENT_SSE2_X86_64
|
||||
tristate "Serpent cipher algorithm (x86_64/SSE2)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_GLUE_HELPER_X86
|
||||
select CRYPTO_SERPENT
|
||||
select CRYPTO_SIMD
|
||||
@@ -1481,7 +1539,7 @@ config CRYPTO_SERPENT_SSE2_X86_64
|
||||
config CRYPTO_SERPENT_SSE2_586
|
||||
tristate "Serpent cipher algorithm (i586/SSE2)"
|
||||
depends on X86 && !64BIT
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_GLUE_HELPER_X86
|
||||
select CRYPTO_SERPENT
|
||||
select CRYPTO_SIMD
|
||||
@@ -1500,7 +1558,7 @@ config CRYPTO_SERPENT_SSE2_586
|
||||
config CRYPTO_SERPENT_AVX_X86_64
|
||||
tristate "Serpent cipher algorithm (x86_64/AVX)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_GLUE_HELPER_X86
|
||||
select CRYPTO_SERPENT
|
||||
select CRYPTO_SIMD
|
||||
@@ -1631,7 +1689,7 @@ config CRYPTO_TWOFISH_X86_64
|
||||
config CRYPTO_TWOFISH_X86_64_3WAY
|
||||
tristate "Twofish cipher algorithm (x86_64, 3-way parallel)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_TWOFISH_COMMON
|
||||
select CRYPTO_TWOFISH_X86_64
|
||||
select CRYPTO_GLUE_HELPER_X86
|
||||
@@ -1652,7 +1710,7 @@ config CRYPTO_TWOFISH_X86_64_3WAY
|
||||
config CRYPTO_TWOFISH_AVX_X86_64
|
||||
tristate "Twofish cipher algorithm (x86_64/AVX)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_GLUE_HELPER_X86
|
||||
select CRYPTO_SIMD
|
||||
select CRYPTO_TWOFISH_COMMON
|
||||
@@ -1803,7 +1861,7 @@ config CRYPTO_USER_API_HASH
|
||||
config CRYPTO_USER_API_SKCIPHER
|
||||
tristate "User-space interface for symmetric key cipher algorithms"
|
||||
depends on NET
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_USER_API
|
||||
help
|
||||
This option enables the user-spaces interface for symmetric
|
||||
@@ -1822,7 +1880,7 @@ config CRYPTO_USER_API_AEAD
|
||||
tristate "User-space interface for AEAD cipher algorithms"
|
||||
depends on NET
|
||||
select CRYPTO_AEAD
|
||||
select CRYPTO_BLKCIPHER
|
||||
select CRYPTO_SKCIPHER
|
||||
select CRYPTO_NULL
|
||||
select CRYPTO_USER_API
|
||||
help
|
||||
@@ -1844,6 +1902,7 @@ config CRYPTO_STATS
|
||||
config CRYPTO_HASH_INFO
|
||||
bool
|
||||
|
||||
source "lib/crypto/Kconfig"
|
||||
source "drivers/crypto/Kconfig"
|
||||
source "crypto/asymmetric_keys/Kconfig"
|
||||
source "certs/Kconfig"
|
||||
|
||||
+6
-5
@@ -14,11 +14,9 @@ crypto_algapi-y := algapi.o scatterwalk.o $(crypto_algapi-y)
|
||||
obj-$(CONFIG_CRYPTO_ALGAPI2) += crypto_algapi.o
|
||||
|
||||
obj-$(CONFIG_CRYPTO_AEAD2) += aead.o
|
||||
obj-$(CONFIG_CRYPTO_AEAD2) += geniv.o
|
||||
|
||||
crypto_blkcipher-y := ablkcipher.o
|
||||
crypto_blkcipher-y += blkcipher.o
|
||||
crypto_blkcipher-y += skcipher.o
|
||||
obj-$(CONFIG_CRYPTO_BLKCIPHER2) += crypto_blkcipher.o
|
||||
obj-$(CONFIG_CRYPTO_SKCIPHER2) += skcipher.o
|
||||
obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o
|
||||
obj-$(CONFIG_CRYPTO_ECHAINIV) += echainiv.o
|
||||
|
||||
@@ -74,6 +72,8 @@ obj-$(CONFIG_CRYPTO_STREEBOG) += streebog_generic.o
|
||||
obj-$(CONFIG_CRYPTO_WP512) += wp512.o
|
||||
CFLAGS_wp512.o := $(call cc-option,-fno-schedule-insns) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149
|
||||
obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o
|
||||
obj-$(CONFIG_CRYPTO_BLAKE2B) += blake2b_generic.o
|
||||
obj-$(CONFIG_CRYPTO_BLAKE2S) += blake2s_generic.o
|
||||
obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o
|
||||
obj-$(CONFIG_CRYPTO_ECB) += ecb.o
|
||||
obj-$(CONFIG_CRYPTO_CBC) += cbc.o
|
||||
@@ -93,7 +93,7 @@ obj-$(CONFIG_CRYPTO_AEGIS128) += aegis128.o
|
||||
aegis128-y := aegis128-core.o
|
||||
|
||||
ifeq ($(ARCH),arm)
|
||||
CFLAGS_aegis128-neon-inner.o += -ffreestanding -march=armv7-a -mfloat-abi=softfp
|
||||
CFLAGS_aegis128-neon-inner.o += -ffreestanding -march=armv8-a -mfloat-abi=softfp
|
||||
CFLAGS_aegis128-neon-inner.o += -mfpu=crypto-neon-fp-armv8
|
||||
aegis128-$(CONFIG_CRYPTO_AEGIS128_SIMD) += aegis128-neon.o aegis128-neon-inner.o
|
||||
endif
|
||||
@@ -166,6 +166,7 @@ obj-$(CONFIG_CRYPTO_ZSTD) += zstd.o
|
||||
obj-$(CONFIG_CRYPTO_OFB) += ofb.o
|
||||
obj-$(CONFIG_CRYPTO_ECC) += ecc.o
|
||||
obj-$(CONFIG_CRYPTO_ESSIV) += essiv.o
|
||||
obj-$(CONFIG_CRYPTO_CURVE25519) += curve25519-generic.o
|
||||
|
||||
ecdh_generic-y += ecdh.o
|
||||
ecdh_generic-y += ecdh_helper.o
|
||||
|
||||
@@ -1,407 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Asynchronous block chaining cipher operations.
|
||||
*
|
||||
* This is the asynchronous version of blkcipher.c indicating completion
|
||||
* via a callback.
|
||||
*
|
||||
* Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
|
||||
*/
|
||||
|
||||
#include <crypto/internal/skcipher.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/cryptouser.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
#include <crypto/scatterwalk.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
struct ablkcipher_buffer {
|
||||
struct list_head entry;
|
||||
struct scatter_walk dst;
|
||||
unsigned int len;
|
||||
void *data;
|
||||
};
|
||||
|
||||
enum {
|
||||
ABLKCIPHER_WALK_SLOW = 1 << 0,
|
||||
};
|
||||
|
||||
static inline void ablkcipher_buffer_write(struct ablkcipher_buffer *p)
|
||||
{
|
||||
scatterwalk_copychunks(p->data, &p->dst, p->len, 1);
|
||||
}
|
||||
|
||||
void __ablkcipher_walk_complete(struct ablkcipher_walk *walk)
|
||||
{
|
||||
struct ablkcipher_buffer *p, *tmp;
|
||||
|
||||
list_for_each_entry_safe(p, tmp, &walk->buffers, entry) {
|
||||
ablkcipher_buffer_write(p);
|
||||
list_del(&p->entry);
|
||||
kfree(p);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__ablkcipher_walk_complete);
|
||||
|
||||
static inline void ablkcipher_queue_write(struct ablkcipher_walk *walk,
|
||||
struct ablkcipher_buffer *p)
|
||||
{
|
||||
p->dst = walk->out;
|
||||
list_add_tail(&p->entry, &walk->buffers);
|
||||
}
|
||||
|
||||
/* Get a spot of the specified length that does not straddle a page.
|
||||
* The caller needs to ensure that there is enough space for this operation.
|
||||
*/
|
||||
static inline u8 *ablkcipher_get_spot(u8 *start, unsigned int len)
|
||||
{
|
||||
u8 *end_page = (u8 *)(((unsigned long)(start + len - 1)) & PAGE_MASK);
|
||||
|
||||
return max(start, end_page);
|
||||
}
|
||||
|
||||
static inline void ablkcipher_done_slow(struct ablkcipher_walk *walk,
|
||||
unsigned int n)
|
||||
{
|
||||
for (;;) {
|
||||
unsigned int len_this_page = scatterwalk_pagelen(&walk->out);
|
||||
|
||||
if (len_this_page > n)
|
||||
len_this_page = n;
|
||||
scatterwalk_advance(&walk->out, n);
|
||||
if (n == len_this_page)
|
||||
break;
|
||||
n -= len_this_page;
|
||||
scatterwalk_start(&walk->out, sg_next(walk->out.sg));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void ablkcipher_done_fast(struct ablkcipher_walk *walk,
|
||||
unsigned int n)
|
||||
{
|
||||
scatterwalk_advance(&walk->in, n);
|
||||
scatterwalk_advance(&walk->out, n);
|
||||
}
|
||||
|
||||
static int ablkcipher_walk_next(struct ablkcipher_request *req,
|
||||
struct ablkcipher_walk *walk);
|
||||
|
||||
int ablkcipher_walk_done(struct ablkcipher_request *req,
|
||||
struct ablkcipher_walk *walk, int err)
|
||||
{
|
||||
struct crypto_tfm *tfm = req->base.tfm;
|
||||
unsigned int n; /* bytes processed */
|
||||
bool more;
|
||||
|
||||
if (unlikely(err < 0))
|
||||
goto finish;
|
||||
|
||||
n = walk->nbytes - err;
|
||||
walk->total -= n;
|
||||
more = (walk->total != 0);
|
||||
|
||||
if (likely(!(walk->flags & ABLKCIPHER_WALK_SLOW))) {
|
||||
ablkcipher_done_fast(walk, n);
|
||||
} else {
|
||||
if (WARN_ON(err)) {
|
||||
/* unexpected case; didn't process all bytes */
|
||||
err = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
ablkcipher_done_slow(walk, n);
|
||||
}
|
||||
|
||||
scatterwalk_done(&walk->in, 0, more);
|
||||
scatterwalk_done(&walk->out, 1, more);
|
||||
|
||||
if (more) {
|
||||
crypto_yield(req->base.flags);
|
||||
return ablkcipher_walk_next(req, walk);
|
||||
}
|
||||
err = 0;
|
||||
finish:
|
||||
walk->nbytes = 0;
|
||||
if (walk->iv != req->info)
|
||||
memcpy(req->info, walk->iv, tfm->crt_ablkcipher.ivsize);
|
||||
kfree(walk->iv_buffer);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ablkcipher_walk_done);
|
||||
|
||||
static inline int ablkcipher_next_slow(struct ablkcipher_request *req,
|
||||
struct ablkcipher_walk *walk,
|
||||
unsigned int bsize,
|
||||
unsigned int alignmask,
|
||||
void **src_p, void **dst_p)
|
||||
{
|
||||
unsigned aligned_bsize = ALIGN(bsize, alignmask + 1);
|
||||
struct ablkcipher_buffer *p;
|
||||
void *src, *dst, *base;
|
||||
unsigned int n;
|
||||
|
||||
n = ALIGN(sizeof(struct ablkcipher_buffer), alignmask + 1);
|
||||
n += (aligned_bsize * 3 - (alignmask + 1) +
|
||||
(alignmask & ~(crypto_tfm_ctx_alignment() - 1)));
|
||||
|
||||
p = kmalloc(n, GFP_ATOMIC);
|
||||
if (!p)
|
||||
return ablkcipher_walk_done(req, walk, -ENOMEM);
|
||||
|
||||
base = p + 1;
|
||||
|
||||
dst = (u8 *)ALIGN((unsigned long)base, alignmask + 1);
|
||||
src = dst = ablkcipher_get_spot(dst, bsize);
|
||||
|
||||
p->len = bsize;
|
||||
p->data = dst;
|
||||
|
||||
scatterwalk_copychunks(src, &walk->in, bsize, 0);
|
||||
|
||||
ablkcipher_queue_write(walk, p);
|
||||
|
||||
walk->nbytes = bsize;
|
||||
walk->flags |= ABLKCIPHER_WALK_SLOW;
|
||||
|
||||
*src_p = src;
|
||||
*dst_p = dst;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ablkcipher_copy_iv(struct ablkcipher_walk *walk,
|
||||
struct crypto_tfm *tfm,
|
||||
unsigned int alignmask)
|
||||
{
|
||||
unsigned bs = walk->blocksize;
|
||||
unsigned int ivsize = tfm->crt_ablkcipher.ivsize;
|
||||
unsigned aligned_bs = ALIGN(bs, alignmask + 1);
|
||||
unsigned int size = aligned_bs * 2 + ivsize + max(aligned_bs, ivsize) -
|
||||
(alignmask + 1);
|
||||
u8 *iv;
|
||||
|
||||
size += alignmask & ~(crypto_tfm_ctx_alignment() - 1);
|
||||
walk->iv_buffer = kmalloc(size, GFP_ATOMIC);
|
||||
if (!walk->iv_buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
iv = (u8 *)ALIGN((unsigned long)walk->iv_buffer, alignmask + 1);
|
||||
iv = ablkcipher_get_spot(iv, bs) + aligned_bs;
|
||||
iv = ablkcipher_get_spot(iv, bs) + aligned_bs;
|
||||
iv = ablkcipher_get_spot(iv, ivsize);
|
||||
|
||||
walk->iv = memcpy(iv, walk->iv, ivsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ablkcipher_next_fast(struct ablkcipher_request *req,
|
||||
struct ablkcipher_walk *walk)
|
||||
{
|
||||
walk->src.page = scatterwalk_page(&walk->in);
|
||||
walk->src.offset = offset_in_page(walk->in.offset);
|
||||
walk->dst.page = scatterwalk_page(&walk->out);
|
||||
walk->dst.offset = offset_in_page(walk->out.offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ablkcipher_walk_next(struct ablkcipher_request *req,
|
||||
struct ablkcipher_walk *walk)
|
||||
{
|
||||
struct crypto_tfm *tfm = req->base.tfm;
|
||||
unsigned int alignmask, bsize, n;
|
||||
void *src, *dst;
|
||||
int err;
|
||||
|
||||
alignmask = crypto_tfm_alg_alignmask(tfm);
|
||||
n = walk->total;
|
||||
if (unlikely(n < crypto_tfm_alg_blocksize(tfm))) {
|
||||
req->base.flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
|
||||
return ablkcipher_walk_done(req, walk, -EINVAL);
|
||||
}
|
||||
|
||||
walk->flags &= ~ABLKCIPHER_WALK_SLOW;
|
||||
src = dst = NULL;
|
||||
|
||||
bsize = min(walk->blocksize, n);
|
||||
n = scatterwalk_clamp(&walk->in, n);
|
||||
n = scatterwalk_clamp(&walk->out, n);
|
||||
|
||||
if (n < bsize ||
|
||||
!scatterwalk_aligned(&walk->in, alignmask) ||
|
||||
!scatterwalk_aligned(&walk->out, alignmask)) {
|
||||
err = ablkcipher_next_slow(req, walk, bsize, alignmask,
|
||||
&src, &dst);
|
||||
goto set_phys_lowmem;
|
||||
}
|
||||
|
||||
walk->nbytes = n;
|
||||
|
||||
return ablkcipher_next_fast(req, walk);
|
||||
|
||||
set_phys_lowmem:
|
||||
if (err >= 0) {
|
||||
walk->src.page = virt_to_page(src);
|
||||
walk->dst.page = virt_to_page(dst);
|
||||
walk->src.offset = ((unsigned long)src & (PAGE_SIZE - 1));
|
||||
walk->dst.offset = ((unsigned long)dst & (PAGE_SIZE - 1));
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ablkcipher_walk_first(struct ablkcipher_request *req,
|
||||
struct ablkcipher_walk *walk)
|
||||
{
|
||||
struct crypto_tfm *tfm = req->base.tfm;
|
||||
unsigned int alignmask;
|
||||
|
||||
alignmask = crypto_tfm_alg_alignmask(tfm);
|
||||
if (WARN_ON_ONCE(in_irq()))
|
||||
return -EDEADLK;
|
||||
|
||||
walk->iv = req->info;
|
||||
walk->nbytes = walk->total;
|
||||
if (unlikely(!walk->total))
|
||||
return 0;
|
||||
|
||||
walk->iv_buffer = NULL;
|
||||
if (unlikely(((unsigned long)walk->iv & alignmask))) {
|
||||
int err = ablkcipher_copy_iv(walk, tfm, alignmask);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
scatterwalk_start(&walk->in, walk->in.sg);
|
||||
scatterwalk_start(&walk->out, walk->out.sg);
|
||||
|
||||
return ablkcipher_walk_next(req, walk);
|
||||
}
|
||||
|
||||
int ablkcipher_walk_phys(struct ablkcipher_request *req,
|
||||
struct ablkcipher_walk *walk)
|
||||
{
|
||||
walk->blocksize = crypto_tfm_alg_blocksize(req->base.tfm);
|
||||
return ablkcipher_walk_first(req, walk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ablkcipher_walk_phys);
|
||||
|
||||
static int setkey_unaligned(struct crypto_ablkcipher *tfm, const u8 *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm);
|
||||
unsigned long alignmask = crypto_ablkcipher_alignmask(tfm);
|
||||
int ret;
|
||||
u8 *buffer, *alignbuffer;
|
||||
unsigned long absize;
|
||||
|
||||
absize = keylen + alignmask;
|
||||
buffer = kmalloc(absize, GFP_ATOMIC);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
|
||||
memcpy(alignbuffer, key, keylen);
|
||||
ret = cipher->setkey(tfm, alignbuffer, keylen);
|
||||
memset(alignbuffer, 0, keylen);
|
||||
kfree(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm);
|
||||
unsigned long alignmask = crypto_ablkcipher_alignmask(tfm);
|
||||
|
||||
if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) {
|
||||
crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((unsigned long)key & alignmask)
|
||||
return setkey_unaligned(tfm, key, keylen);
|
||||
|
||||
return cipher->setkey(tfm, key, keylen);
|
||||
}
|
||||
|
||||
static unsigned int crypto_ablkcipher_ctxsize(struct crypto_alg *alg, u32 type,
|
||||
u32 mask)
|
||||
{
|
||||
return alg->cra_ctxsize;
|
||||
}
|
||||
|
||||
static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type,
|
||||
u32 mask)
|
||||
{
|
||||
struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher;
|
||||
struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher;
|
||||
|
||||
if (alg->ivsize > PAGE_SIZE / 8)
|
||||
return -EINVAL;
|
||||
|
||||
crt->setkey = setkey;
|
||||
crt->encrypt = alg->encrypt;
|
||||
crt->decrypt = alg->decrypt;
|
||||
crt->base = __crypto_ablkcipher_cast(tfm);
|
||||
crt->ivsize = alg->ivsize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET
|
||||
static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
||||
{
|
||||
struct crypto_report_blkcipher rblkcipher;
|
||||
|
||||
memset(&rblkcipher, 0, sizeof(rblkcipher));
|
||||
|
||||
strscpy(rblkcipher.type, "ablkcipher", sizeof(rblkcipher.type));
|
||||
strscpy(rblkcipher.geniv, "<default>", sizeof(rblkcipher.geniv));
|
||||
|
||||
rblkcipher.blocksize = alg->cra_blocksize;
|
||||
rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;
|
||||
rblkcipher.max_keysize = alg->cra_ablkcipher.max_keysize;
|
||||
rblkcipher.ivsize = alg->cra_ablkcipher.ivsize;
|
||||
|
||||
return nla_put(skb, CRYPTOCFGA_REPORT_BLKCIPHER,
|
||||
sizeof(rblkcipher), &rblkcipher);
|
||||
}
|
||||
#else
|
||||
static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
__maybe_unused;
|
||||
static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
{
|
||||
struct ablkcipher_alg *ablkcipher = &alg->cra_ablkcipher;
|
||||
|
||||
seq_printf(m, "type : ablkcipher\n");
|
||||
seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ?
|
||||
"yes" : "no");
|
||||
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
|
||||
seq_printf(m, "min keysize : %u\n", ablkcipher->min_keysize);
|
||||
seq_printf(m, "max keysize : %u\n", ablkcipher->max_keysize);
|
||||
seq_printf(m, "ivsize : %u\n", ablkcipher->ivsize);
|
||||
seq_printf(m, "geniv : <default>\n");
|
||||
}
|
||||
|
||||
const struct crypto_type crypto_ablkcipher_type = {
|
||||
.ctxsize = crypto_ablkcipher_ctxsize,
|
||||
.init = crypto_init_ablkcipher_ops,
|
||||
#ifdef CONFIG_PROC_FS
|
||||
.show = crypto_ablkcipher_show,
|
||||
#endif
|
||||
.report = crypto_ablkcipher_report,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(crypto_ablkcipher_type);
|
||||
+3
-2
@@ -33,6 +33,7 @@
|
||||
#include <crypto/b128ops.h>
|
||||
#include <crypto/chacha.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <crypto/internal/poly1305.h>
|
||||
#include <crypto/internal/skcipher.h>
|
||||
#include <crypto/nhpoly1305.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
@@ -242,11 +243,11 @@ static void adiantum_hash_header(struct skcipher_request *req)
|
||||
|
||||
BUILD_BUG_ON(sizeof(header) % POLY1305_BLOCK_SIZE != 0);
|
||||
poly1305_core_blocks(&state, &tctx->header_hash_key,
|
||||
&header, sizeof(header) / POLY1305_BLOCK_SIZE);
|
||||
&header, sizeof(header) / POLY1305_BLOCK_SIZE, 1);
|
||||
|
||||
BUILD_BUG_ON(TWEAK_SIZE % POLY1305_BLOCK_SIZE != 0);
|
||||
poly1305_core_blocks(&state, &tctx->header_hash_key, req->iv,
|
||||
TWEAK_SIZE / POLY1305_BLOCK_SIZE);
|
||||
TWEAK_SIZE / POLY1305_BLOCK_SIZE, 1);
|
||||
|
||||
poly1305_core_emit(&state, &rctx->header_hash);
|
||||
}
|
||||
|
||||
+2
-163
@@ -7,19 +7,14 @@
|
||||
* Copyright (c) 2007-2015 Herbert Xu <herbert@gondor.apana.org.au>
|
||||
*/
|
||||
|
||||
#include <crypto/internal/geniv.h>
|
||||
#include <crypto/internal/rng.h>
|
||||
#include <crypto/null.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <linux/err.h>
|
||||
#include <crypto/internal/aead.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/cryptouser.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
#include "internal.h"
|
||||
@@ -212,162 +207,6 @@ static const struct crypto_type crypto_aead_type = {
|
||||
.tfmsize = offsetof(struct crypto_aead, base),
|
||||
};
|
||||
|
||||
static int aead_geniv_setkey(struct crypto_aead *tfm,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm);
|
||||
|
||||
return crypto_aead_setkey(ctx->child, key, keylen);
|
||||
}
|
||||
|
||||
static int aead_geniv_setauthsize(struct crypto_aead *tfm,
|
||||
unsigned int authsize)
|
||||
{
|
||||
struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm);
|
||||
|
||||
return crypto_aead_setauthsize(ctx->child, authsize);
|
||||
}
|
||||
|
||||
struct aead_instance *aead_geniv_alloc(struct crypto_template *tmpl,
|
||||
struct rtattr **tb, u32 type, u32 mask)
|
||||
{
|
||||
const char *name;
|
||||
struct crypto_aead_spawn *spawn;
|
||||
struct crypto_attr_type *algt;
|
||||
struct aead_instance *inst;
|
||||
struct aead_alg *alg;
|
||||
unsigned int ivsize;
|
||||
unsigned int maxauthsize;
|
||||
int err;
|
||||
|
||||
algt = crypto_get_attr_type(tb);
|
||||
if (IS_ERR(algt))
|
||||
return ERR_CAST(algt);
|
||||
|
||||
if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
name = crypto_attr_alg_name(tb[1]);
|
||||
if (IS_ERR(name))
|
||||
return ERR_CAST(name);
|
||||
|
||||
inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
|
||||
if (!inst)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
spawn = aead_instance_ctx(inst);
|
||||
|
||||
/* Ignore async algorithms if necessary. */
|
||||
mask |= crypto_requires_sync(algt->type, algt->mask);
|
||||
|
||||
crypto_set_aead_spawn(spawn, aead_crypto_instance(inst));
|
||||
err = crypto_grab_aead(spawn, name, type, mask);
|
||||
if (err)
|
||||
goto err_free_inst;
|
||||
|
||||
alg = crypto_spawn_aead_alg(spawn);
|
||||
|
||||
ivsize = crypto_aead_alg_ivsize(alg);
|
||||
maxauthsize = crypto_aead_alg_maxauthsize(alg);
|
||||
|
||||
err = -EINVAL;
|
||||
if (ivsize < sizeof(u64))
|
||||
goto err_drop_alg;
|
||||
|
||||
err = -ENAMETOOLONG;
|
||||
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
|
||||
"%s(%s)", tmpl->name, alg->base.cra_name) >=
|
||||
CRYPTO_MAX_ALG_NAME)
|
||||
goto err_drop_alg;
|
||||
if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
|
||||
"%s(%s)", tmpl->name, alg->base.cra_driver_name) >=
|
||||
CRYPTO_MAX_ALG_NAME)
|
||||
goto err_drop_alg;
|
||||
|
||||
inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
|
||||
inst->alg.base.cra_priority = alg->base.cra_priority;
|
||||
inst->alg.base.cra_blocksize = alg->base.cra_blocksize;
|
||||
inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
|
||||
inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
|
||||
|
||||
inst->alg.setkey = aead_geniv_setkey;
|
||||
inst->alg.setauthsize = aead_geniv_setauthsize;
|
||||
|
||||
inst->alg.ivsize = ivsize;
|
||||
inst->alg.maxauthsize = maxauthsize;
|
||||
|
||||
out:
|
||||
return inst;
|
||||
|
||||
err_drop_alg:
|
||||
crypto_drop_aead(spawn);
|
||||
err_free_inst:
|
||||
kfree(inst);
|
||||
inst = ERR_PTR(err);
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aead_geniv_alloc);
|
||||
|
||||
void aead_geniv_free(struct aead_instance *inst)
|
||||
{
|
||||
crypto_drop_aead(aead_instance_ctx(inst));
|
||||
kfree(inst);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aead_geniv_free);
|
||||
|
||||
int aead_init_geniv(struct crypto_aead *aead)
|
||||
{
|
||||
struct aead_geniv_ctx *ctx = crypto_aead_ctx(aead);
|
||||
struct aead_instance *inst = aead_alg_instance(aead);
|
||||
struct crypto_aead *child;
|
||||
int err;
|
||||
|
||||
spin_lock_init(&ctx->lock);
|
||||
|
||||
err = crypto_get_default_rng();
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
|
||||
crypto_aead_ivsize(aead));
|
||||
crypto_put_default_rng();
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
ctx->sknull = crypto_get_default_null_skcipher();
|
||||
err = PTR_ERR(ctx->sknull);
|
||||
if (IS_ERR(ctx->sknull))
|
||||
goto out;
|
||||
|
||||
child = crypto_spawn_aead(aead_instance_ctx(inst));
|
||||
err = PTR_ERR(child);
|
||||
if (IS_ERR(child))
|
||||
goto drop_null;
|
||||
|
||||
ctx->child = child;
|
||||
crypto_aead_set_reqsize(aead, crypto_aead_reqsize(child) +
|
||||
sizeof(struct aead_request));
|
||||
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
return err;
|
||||
|
||||
drop_null:
|
||||
crypto_put_default_null_skcipher();
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aead_init_geniv);
|
||||
|
||||
void aead_exit_geniv(struct crypto_aead *tfm)
|
||||
{
|
||||
struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm);
|
||||
|
||||
crypto_free_aead(ctx->child);
|
||||
crypto_put_default_null_skcipher();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aead_exit_geniv);
|
||||
|
||||
int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name,
|
||||
u32 type, u32 mask)
|
||||
{
|
||||
|
||||
+63
-62
@@ -13,6 +13,7 @@
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/scatterlist.h>
|
||||
@@ -35,15 +36,7 @@ struct aegis_ctx {
|
||||
union aegis_block key;
|
||||
};
|
||||
|
||||
struct aegis128_ops {
|
||||
int (*skcipher_walk_init)(struct skcipher_walk *walk,
|
||||
struct aead_request *req, bool atomic);
|
||||
|
||||
void (*crypt_chunk)(struct aegis_state *state, u8 *dst,
|
||||
const u8 *src, unsigned int size);
|
||||
};
|
||||
|
||||
static bool have_simd;
|
||||
static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_simd);
|
||||
|
||||
static const union aegis_block crypto_aegis_const[2] = {
|
||||
{ .words64 = {
|
||||
@@ -59,7 +52,7 @@ static const union aegis_block crypto_aegis_const[2] = {
|
||||
static bool aegis128_do_simd(void)
|
||||
{
|
||||
#ifdef CONFIG_CRYPTO_AEGIS128_SIMD
|
||||
if (have_simd)
|
||||
if (static_branch_likely(&have_simd))
|
||||
return crypto_simd_usable();
|
||||
#endif
|
||||
return false;
|
||||
@@ -67,10 +60,16 @@ static bool aegis128_do_simd(void)
|
||||
|
||||
bool crypto_aegis128_have_simd(void);
|
||||
void crypto_aegis128_update_simd(struct aegis_state *state, const void *msg);
|
||||
void crypto_aegis128_init_simd(struct aegis_state *state,
|
||||
const union aegis_block *key,
|
||||
const u8 *iv);
|
||||
void crypto_aegis128_encrypt_chunk_simd(struct aegis_state *state, u8 *dst,
|
||||
const u8 *src, unsigned int size);
|
||||
void crypto_aegis128_decrypt_chunk_simd(struct aegis_state *state, u8 *dst,
|
||||
const u8 *src, unsigned int size);
|
||||
void crypto_aegis128_final_simd(struct aegis_state *state,
|
||||
union aegis_block *tag_xor,
|
||||
u64 assoclen, u64 cryptlen);
|
||||
|
||||
static void crypto_aegis128_update(struct aegis_state *state)
|
||||
{
|
||||
@@ -323,25 +322,27 @@ static void crypto_aegis128_process_ad(struct aegis_state *state,
|
||||
}
|
||||
}
|
||||
|
||||
static void crypto_aegis128_process_crypt(struct aegis_state *state,
|
||||
struct aead_request *req,
|
||||
const struct aegis128_ops *ops)
|
||||
static __always_inline
|
||||
int crypto_aegis128_process_crypt(struct aegis_state *state,
|
||||
struct aead_request *req,
|
||||
struct skcipher_walk *walk,
|
||||
void (*crypt)(struct aegis_state *state,
|
||||
u8 *dst, const u8 *src,
|
||||
unsigned int size))
|
||||
{
|
||||
struct skcipher_walk walk;
|
||||
int err = 0;
|
||||
|
||||
ops->skcipher_walk_init(&walk, req, false);
|
||||
while (walk->nbytes) {
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
|
||||
while (walk.nbytes) {
|
||||
unsigned int nbytes = walk.nbytes;
|
||||
if (nbytes < walk->total)
|
||||
nbytes = round_down(nbytes, walk->stride);
|
||||
|
||||
if (nbytes < walk.total)
|
||||
nbytes = round_down(nbytes, walk.stride);
|
||||
crypt(state, walk->dst.virt.addr, walk->src.virt.addr, nbytes);
|
||||
|
||||
ops->crypt_chunk(state, walk.dst.virt.addr, walk.src.virt.addr,
|
||||
nbytes);
|
||||
|
||||
skcipher_walk_done(&walk, walk.nbytes - nbytes);
|
||||
err = skcipher_walk_done(walk, walk->nbytes - nbytes);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static void crypto_aegis128_final(struct aegis_state *state,
|
||||
@@ -390,39 +391,31 @@ static int crypto_aegis128_setauthsize(struct crypto_aead *tfm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void crypto_aegis128_crypt(struct aead_request *req,
|
||||
union aegis_block *tag_xor,
|
||||
unsigned int cryptlen,
|
||||
const struct aegis128_ops *ops)
|
||||
{
|
||||
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
|
||||
struct aegis_ctx *ctx = crypto_aead_ctx(tfm);
|
||||
struct aegis_state state;
|
||||
|
||||
crypto_aegis128_init(&state, &ctx->key, req->iv);
|
||||
crypto_aegis128_process_ad(&state, req->src, req->assoclen);
|
||||
crypto_aegis128_process_crypt(&state, req, ops);
|
||||
crypto_aegis128_final(&state, tag_xor, req->assoclen, cryptlen);
|
||||
}
|
||||
|
||||
static int crypto_aegis128_encrypt(struct aead_request *req)
|
||||
{
|
||||
const struct aegis128_ops *ops = &(struct aegis128_ops){
|
||||
.skcipher_walk_init = skcipher_walk_aead_encrypt,
|
||||
.crypt_chunk = crypto_aegis128_encrypt_chunk,
|
||||
};
|
||||
|
||||
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
|
||||
union aegis_block tag = {};
|
||||
unsigned int authsize = crypto_aead_authsize(tfm);
|
||||
struct aegis_ctx *ctx = crypto_aead_ctx(tfm);
|
||||
unsigned int cryptlen = req->cryptlen;
|
||||
struct skcipher_walk walk;
|
||||
struct aegis_state state;
|
||||
|
||||
if (aegis128_do_simd())
|
||||
ops = &(struct aegis128_ops){
|
||||
.skcipher_walk_init = skcipher_walk_aead_encrypt,
|
||||
.crypt_chunk = crypto_aegis128_encrypt_chunk_simd };
|
||||
|
||||
crypto_aegis128_crypt(req, &tag, cryptlen, ops);
|
||||
skcipher_walk_aead_encrypt(&walk, req, false);
|
||||
if (aegis128_do_simd()) {
|
||||
crypto_aegis128_init_simd(&state, &ctx->key, req->iv);
|
||||
crypto_aegis128_process_ad(&state, req->src, req->assoclen);
|
||||
crypto_aegis128_process_crypt(&state, req, &walk,
|
||||
crypto_aegis128_encrypt_chunk_simd);
|
||||
crypto_aegis128_final_simd(&state, &tag, req->assoclen,
|
||||
cryptlen);
|
||||
} else {
|
||||
crypto_aegis128_init(&state, &ctx->key, req->iv);
|
||||
crypto_aegis128_process_ad(&state, req->src, req->assoclen);
|
||||
crypto_aegis128_process_crypt(&state, req, &walk,
|
||||
crypto_aegis128_encrypt_chunk);
|
||||
crypto_aegis128_final(&state, &tag, req->assoclen, cryptlen);
|
||||
}
|
||||
|
||||
scatterwalk_map_and_copy(tag.bytes, req->dst, req->assoclen + cryptlen,
|
||||
authsize, 1);
|
||||
@@ -431,26 +424,33 @@ static int crypto_aegis128_encrypt(struct aead_request *req)
|
||||
|
||||
static int crypto_aegis128_decrypt(struct aead_request *req)
|
||||
{
|
||||
const struct aegis128_ops *ops = &(struct aegis128_ops){
|
||||
.skcipher_walk_init = skcipher_walk_aead_decrypt,
|
||||
.crypt_chunk = crypto_aegis128_decrypt_chunk,
|
||||
};
|
||||
static const u8 zeros[AEGIS128_MAX_AUTH_SIZE] = {};
|
||||
|
||||
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
|
||||
union aegis_block tag;
|
||||
unsigned int authsize = crypto_aead_authsize(tfm);
|
||||
unsigned int cryptlen = req->cryptlen - authsize;
|
||||
struct aegis_ctx *ctx = crypto_aead_ctx(tfm);
|
||||
struct skcipher_walk walk;
|
||||
struct aegis_state state;
|
||||
|
||||
scatterwalk_map_and_copy(tag.bytes, req->src, req->assoclen + cryptlen,
|
||||
authsize, 0);
|
||||
|
||||
if (aegis128_do_simd())
|
||||
ops = &(struct aegis128_ops){
|
||||
.skcipher_walk_init = skcipher_walk_aead_decrypt,
|
||||
.crypt_chunk = crypto_aegis128_decrypt_chunk_simd };
|
||||
|
||||
crypto_aegis128_crypt(req, &tag, cryptlen, ops);
|
||||
skcipher_walk_aead_decrypt(&walk, req, false);
|
||||
if (aegis128_do_simd()) {
|
||||
crypto_aegis128_init_simd(&state, &ctx->key, req->iv);
|
||||
crypto_aegis128_process_ad(&state, req->src, req->assoclen);
|
||||
crypto_aegis128_process_crypt(&state, req, &walk,
|
||||
crypto_aegis128_decrypt_chunk_simd);
|
||||
crypto_aegis128_final_simd(&state, &tag, req->assoclen,
|
||||
cryptlen);
|
||||
} else {
|
||||
crypto_aegis128_init(&state, &ctx->key, req->iv);
|
||||
crypto_aegis128_process_ad(&state, req->src, req->assoclen);
|
||||
crypto_aegis128_process_crypt(&state, req, &walk,
|
||||
crypto_aegis128_decrypt_chunk);
|
||||
crypto_aegis128_final(&state, &tag, req->assoclen, cryptlen);
|
||||
}
|
||||
|
||||
return crypto_memneq(tag.bytes, zeros, authsize) ? -EBADMSG : 0;
|
||||
}
|
||||
@@ -481,8 +481,9 @@ static struct aead_alg crypto_aegis128_alg = {
|
||||
|
||||
static int __init crypto_aegis128_module_init(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_CRYPTO_AEGIS128_SIMD))
|
||||
have_simd = crypto_aegis128_have_simd();
|
||||
if (IS_ENABLED(CONFIG_CRYPTO_AEGIS128_SIMD) &&
|
||||
crypto_aegis128_have_simd())
|
||||
static_branch_enable(&have_simd);
|
||||
|
||||
return crypto_register_aead(&crypto_aegis128_alg);
|
||||
}
|
||||
|
||||
@@ -132,6 +132,36 @@ void preload_sbox(void)
|
||||
:: "r"(crypto_aes_sbox));
|
||||
}
|
||||
|
||||
void crypto_aegis128_init_neon(void *state, const void *key, const void *iv)
|
||||
{
|
||||
static const uint8_t const0[] = {
|
||||
0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d,
|
||||
0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62,
|
||||
};
|
||||
static const uint8_t const1[] = {
|
||||
0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1,
|
||||
0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd,
|
||||
};
|
||||
uint8x16_t k = vld1q_u8(key);
|
||||
uint8x16_t kiv = k ^ vld1q_u8(iv);
|
||||
struct aegis128_state st = {{
|
||||
kiv,
|
||||
vld1q_u8(const1),
|
||||
vld1q_u8(const0),
|
||||
k ^ vld1q_u8(const0),
|
||||
k ^ vld1q_u8(const1),
|
||||
}};
|
||||
int i;
|
||||
|
||||
preload_sbox();
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
st = aegis128_update_neon(st, k);
|
||||
st = aegis128_update_neon(st, kiv);
|
||||
}
|
||||
aegis128_save_state_neon(st, state);
|
||||
}
|
||||
|
||||
void crypto_aegis128_update_neon(void *state, const void *msg)
|
||||
{
|
||||
struct aegis128_state st = aegis128_load_state_neon(state);
|
||||
@@ -210,3 +240,23 @@ void crypto_aegis128_decrypt_chunk_neon(void *state, void *dst, const void *src,
|
||||
|
||||
aegis128_save_state_neon(st, state);
|
||||
}
|
||||
|
||||
void crypto_aegis128_final_neon(void *state, void *tag_xor, uint64_t assoclen,
|
||||
uint64_t cryptlen)
|
||||
{
|
||||
struct aegis128_state st = aegis128_load_state_neon(state);
|
||||
uint8x16_t v;
|
||||
int i;
|
||||
|
||||
preload_sbox();
|
||||
|
||||
v = st.v[3] ^ (uint8x16_t)vcombine_u64(vmov_n_u64(8 * assoclen),
|
||||
vmov_n_u64(8 * cryptlen));
|
||||
|
||||
for (i = 0; i < 7; i++)
|
||||
st = aegis128_update_neon(st, v);
|
||||
|
||||
v = vld1q_u8(tag_xor);
|
||||
v ^= st.v[0] ^ st.v[1] ^ st.v[2] ^ st.v[3] ^ st.v[4];
|
||||
vst1q_u8(tag_xor, v);
|
||||
}
|
||||
|
||||
@@ -8,11 +8,14 @@
|
||||
|
||||
#include "aegis.h"
|
||||
|
||||
void crypto_aegis128_init_neon(void *state, const void *key, const void *iv);
|
||||
void crypto_aegis128_update_neon(void *state, const void *msg);
|
||||
void crypto_aegis128_encrypt_chunk_neon(void *state, void *dst, const void *src,
|
||||
unsigned int size);
|
||||
void crypto_aegis128_decrypt_chunk_neon(void *state, void *dst, const void *src,
|
||||
unsigned int size);
|
||||
void crypto_aegis128_final_neon(void *state, void *tag_xor, uint64_t assoclen,
|
||||
uint64_t cryptlen);
|
||||
|
||||
int aegis128_have_aes_insn __ro_after_init;
|
||||
|
||||
@@ -25,6 +28,15 @@ bool crypto_aegis128_have_simd(void)
|
||||
return IS_ENABLED(CONFIG_ARM64);
|
||||
}
|
||||
|
||||
void crypto_aegis128_init_simd(union aegis_block *state,
|
||||
const union aegis_block *key,
|
||||
const u8 *iv)
|
||||
{
|
||||
kernel_neon_begin();
|
||||
crypto_aegis128_init_neon(state, key, iv);
|
||||
kernel_neon_end();
|
||||
}
|
||||
|
||||
void crypto_aegis128_update_simd(union aegis_block *state, const void *msg)
|
||||
{
|
||||
kernel_neon_begin();
|
||||
@@ -47,3 +59,12 @@ void crypto_aegis128_decrypt_chunk_simd(union aegis_block *state, u8 *dst,
|
||||
crypto_aegis128_decrypt_chunk_neon(state, dst, src, size);
|
||||
kernel_neon_end();
|
||||
}
|
||||
|
||||
void crypto_aegis128_final_simd(union aegis_block *state,
|
||||
union aegis_block *tag_xor,
|
||||
u64 assoclen, u64 cryptlen)
|
||||
{
|
||||
kernel_neon_begin();
|
||||
crypto_aegis128_final_neon(state, tag_xor, assoclen, cryptlen);
|
||||
kernel_neon_end();
|
||||
}
|
||||
|
||||
+1
-1
@@ -1043,7 +1043,7 @@ void af_alg_async_cb(struct crypto_async_request *_req, int err)
|
||||
af_alg_free_resources(areq);
|
||||
sock_put(sk);
|
||||
|
||||
iocb->ki_complete(iocb, err ? err : resultlen, 0);
|
||||
iocb->ki_complete(iocb, err ? err : (int)resultlen, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(af_alg_async_cb);
|
||||
|
||||
|
||||
@@ -1052,32 +1052,6 @@ void crypto_stats_get(struct crypto_alg *alg)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_stats_get);
|
||||
|
||||
void crypto_stats_ablkcipher_encrypt(unsigned int nbytes, int ret,
|
||||
struct crypto_alg *alg)
|
||||
{
|
||||
if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
|
||||
atomic64_inc(&alg->stats.cipher.err_cnt);
|
||||
} else {
|
||||
atomic64_inc(&alg->stats.cipher.encrypt_cnt);
|
||||
atomic64_add(nbytes, &alg->stats.cipher.encrypt_tlen);
|
||||
}
|
||||
crypto_alg_put(alg);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_stats_ablkcipher_encrypt);
|
||||
|
||||
void crypto_stats_ablkcipher_decrypt(unsigned int nbytes, int ret,
|
||||
struct crypto_alg *alg)
|
||||
{
|
||||
if (ret && ret != -EINPROGRESS && ret != -EBUSY) {
|
||||
atomic64_inc(&alg->stats.cipher.err_cnt);
|
||||
} else {
|
||||
atomic64_inc(&alg->stats.cipher.decrypt_cnt);
|
||||
atomic64_add(nbytes, &alg->stats.cipher.decrypt_tlen);
|
||||
}
|
||||
crypto_alg_put(alg);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_stats_ablkcipher_decrypt);
|
||||
|
||||
void crypto_stats_aead_encrypt(unsigned int cryptlen, struct crypto_alg *alg,
|
||||
int ret)
|
||||
{
|
||||
|
||||
@@ -56,7 +56,7 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
|
||||
struct alg_sock *pask = alg_sk(psk);
|
||||
struct af_alg_ctx *ctx = ask->private;
|
||||
struct crypto_skcipher *tfm = pask->private;
|
||||
unsigned int bs = crypto_skcipher_blocksize(tfm);
|
||||
unsigned int bs = crypto_skcipher_chunksize(tfm);
|
||||
struct af_alg_async_req *areq;
|
||||
int err = 0;
|
||||
size_t len = 0;
|
||||
|
||||
+2
-1
@@ -406,7 +406,7 @@ EXPORT_SYMBOL_GPL(__crypto_alloc_tfm);
|
||||
*
|
||||
* The returned transform is of a non-determinate type. Most people
|
||||
* should use one of the more specific allocation functions such as
|
||||
* crypto_alloc_blkcipher.
|
||||
* crypto_alloc_skcipher().
|
||||
*
|
||||
* In case of error the return value is an error pointer.
|
||||
*/
|
||||
@@ -608,3 +608,4 @@ EXPORT_SYMBOL_GPL(crypto_req_done);
|
||||
|
||||
MODULE_DESCRIPTION("Cryptographic core API");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_SOFTDEP("pre: cryptomgr");
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0-only OR Apache-2.0)
|
||||
/*
|
||||
* BLAKE2b reference source code package - reference C implementations
|
||||
*
|
||||
* Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
|
||||
* terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
|
||||
* your option. The terms of these licenses can be found at:
|
||||
*
|
||||
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
|
||||
* - OpenSSL license : https://www.openssl.org/source/license.html
|
||||
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* More information about the BLAKE2 hash function can be found at
|
||||
* https://blake2.net.
|
||||
*
|
||||
* Note: the original sources have been modified for inclusion in linux kernel
|
||||
* in terms of coding style, using generic helpers and simplifications of error
|
||||
* handling.
|
||||
*/
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
|
||||
#define BLAKE2B_160_DIGEST_SIZE (160 / 8)
|
||||
#define BLAKE2B_256_DIGEST_SIZE (256 / 8)
|
||||
#define BLAKE2B_384_DIGEST_SIZE (384 / 8)
|
||||
#define BLAKE2B_512_DIGEST_SIZE (512 / 8)
|
||||
|
||||
enum blake2b_constant {
|
||||
BLAKE2B_BLOCKBYTES = 128,
|
||||
BLAKE2B_KEYBYTES = 64,
|
||||
};
|
||||
|
||||
struct blake2b_state {
|
||||
u64 h[8];
|
||||
u64 t[2];
|
||||
u64 f[2];
|
||||
u8 buf[BLAKE2B_BLOCKBYTES];
|
||||
size_t buflen;
|
||||
};
|
||||
|
||||
static const u64 blake2b_IV[8] = {
|
||||
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
|
||||
0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
|
||||
0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
|
||||
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
|
||||
};
|
||||
|
||||
static const u8 blake2b_sigma[12][16] = {
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
|
||||
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
|
||||
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
|
||||
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
|
||||
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
|
||||
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
|
||||
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
|
||||
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
|
||||
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
|
||||
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
|
||||
};
|
||||
|
||||
static void blake2b_increment_counter(struct blake2b_state *S, const u64 inc)
|
||||
{
|
||||
S->t[0] += inc;
|
||||
S->t[1] += (S->t[0] < inc);
|
||||
}
|
||||
|
||||
#define G(r,i,a,b,c,d) \
|
||||
do { \
|
||||
a = a + b + m[blake2b_sigma[r][2*i+0]]; \
|
||||
d = ror64(d ^ a, 32); \
|
||||
c = c + d; \
|
||||
b = ror64(b ^ c, 24); \
|
||||
a = a + b + m[blake2b_sigma[r][2*i+1]]; \
|
||||
d = ror64(d ^ a, 16); \
|
||||
c = c + d; \
|
||||
b = ror64(b ^ c, 63); \
|
||||
} while (0)
|
||||
|
||||
#define ROUND(r) \
|
||||
do { \
|
||||
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
|
||||
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
|
||||
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
|
||||
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
|
||||
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
|
||||
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
|
||||
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
|
||||
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
|
||||
} while (0)
|
||||
|
||||
static void blake2b_compress(struct blake2b_state *S,
|
||||
const u8 block[BLAKE2B_BLOCKBYTES])
|
||||
{
|
||||
u64 m[16];
|
||||
u64 v[16];
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < 16; ++i)
|
||||
m[i] = get_unaligned_le64(block + i * sizeof(m[i]));
|
||||
|
||||
for (i = 0; i < 8; ++i)
|
||||
v[i] = S->h[i];
|
||||
|
||||
v[ 8] = blake2b_IV[0];
|
||||
v[ 9] = blake2b_IV[1];
|
||||
v[10] = blake2b_IV[2];
|
||||
v[11] = blake2b_IV[3];
|
||||
v[12] = blake2b_IV[4] ^ S->t[0];
|
||||
v[13] = blake2b_IV[5] ^ S->t[1];
|
||||
v[14] = blake2b_IV[6] ^ S->f[0];
|
||||
v[15] = blake2b_IV[7] ^ S->f[1];
|
||||
|
||||
ROUND(0);
|
||||
ROUND(1);
|
||||
ROUND(2);
|
||||
ROUND(3);
|
||||
ROUND(4);
|
||||
ROUND(5);
|
||||
ROUND(6);
|
||||
ROUND(7);
|
||||
ROUND(8);
|
||||
ROUND(9);
|
||||
ROUND(10);
|
||||
ROUND(11);
|
||||
|
||||
for (i = 0; i < 8; ++i)
|
||||
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||
}
|
||||
|
||||
#undef G
|
||||
#undef ROUND
|
||||
|
||||
struct blake2b_tfm_ctx {
|
||||
u8 key[BLAKE2B_KEYBYTES];
|
||||
unsigned int keylen;
|
||||
};
|
||||
|
||||
static int blake2b_setkey(struct crypto_shash *tfm, const u8 *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
struct blake2b_tfm_ctx *tctx = crypto_shash_ctx(tfm);
|
||||
|
||||
if (keylen == 0 || keylen > BLAKE2B_KEYBYTES) {
|
||||
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(tctx->key, key, keylen);
|
||||
tctx->keylen = keylen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blake2b_init(struct shash_desc *desc)
|
||||
{
|
||||
struct blake2b_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
|
||||
struct blake2b_state *state = shash_desc_ctx(desc);
|
||||
const int digestsize = crypto_shash_digestsize(desc->tfm);
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
memcpy(state->h, blake2b_IV, sizeof(state->h));
|
||||
|
||||
/* Parameter block is all zeros except index 0, no xor for 1..7 */
|
||||
state->h[0] ^= 0x01010000 | tctx->keylen << 8 | digestsize;
|
||||
|
||||
if (tctx->keylen) {
|
||||
/*
|
||||
* Prefill the buffer with the key, next call to _update or
|
||||
* _final will process it
|
||||
*/
|
||||
memcpy(state->buf, tctx->key, tctx->keylen);
|
||||
state->buflen = BLAKE2B_BLOCKBYTES;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blake2b_update(struct shash_desc *desc, const u8 *in,
|
||||
unsigned int inlen)
|
||||
{
|
||||
struct blake2b_state *state = shash_desc_ctx(desc);
|
||||
const size_t left = state->buflen;
|
||||
const size_t fill = BLAKE2B_BLOCKBYTES - left;
|
||||
|
||||
if (!inlen)
|
||||
return 0;
|
||||
|
||||
if (inlen > fill) {
|
||||
state->buflen = 0;
|
||||
/* Fill buffer */
|
||||
memcpy(state->buf + left, in, fill);
|
||||
blake2b_increment_counter(state, BLAKE2B_BLOCKBYTES);
|
||||
/* Compress */
|
||||
blake2b_compress(state, state->buf);
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
while (inlen > BLAKE2B_BLOCKBYTES) {
|
||||
blake2b_increment_counter(state, BLAKE2B_BLOCKBYTES);
|
||||
blake2b_compress(state, in);
|
||||
in += BLAKE2B_BLOCKBYTES;
|
||||
inlen -= BLAKE2B_BLOCKBYTES;
|
||||
}
|
||||
}
|
||||
memcpy(state->buf + state->buflen, in, inlen);
|
||||
state->buflen += inlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blake2b_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct blake2b_state *state = shash_desc_ctx(desc);
|
||||
const int digestsize = crypto_shash_digestsize(desc->tfm);
|
||||
size_t i;
|
||||
|
||||
blake2b_increment_counter(state, state->buflen);
|
||||
/* Set last block */
|
||||
state->f[0] = (u64)-1;
|
||||
/* Padding */
|
||||
memset(state->buf + state->buflen, 0, BLAKE2B_BLOCKBYTES - state->buflen);
|
||||
blake2b_compress(state, state->buf);
|
||||
|
||||
/* Avoid temporary buffer and switch the internal output to LE order */
|
||||
for (i = 0; i < ARRAY_SIZE(state->h); i++)
|
||||
__cpu_to_le64s(&state->h[i]);
|
||||
|
||||
memcpy(out, state->h, digestsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg blake2b_algs[] = {
|
||||
{
|
||||
.base.cra_name = "blake2b-160",
|
||||
.base.cra_driver_name = "blake2b-160-generic",
|
||||
.base.cra_priority = 100,
|
||||
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||
.base.cra_blocksize = BLAKE2B_BLOCKBYTES,
|
||||
.base.cra_ctxsize = sizeof(struct blake2b_tfm_ctx),
|
||||
.base.cra_module = THIS_MODULE,
|
||||
.digestsize = BLAKE2B_160_DIGEST_SIZE,
|
||||
.setkey = blake2b_setkey,
|
||||
.init = blake2b_init,
|
||||
.update = blake2b_update,
|
||||
.final = blake2b_final,
|
||||
.descsize = sizeof(struct blake2b_state),
|
||||
}, {
|
||||
.base.cra_name = "blake2b-256",
|
||||
.base.cra_driver_name = "blake2b-256-generic",
|
||||
.base.cra_priority = 100,
|
||||
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||
.base.cra_blocksize = BLAKE2B_BLOCKBYTES,
|
||||
.base.cra_ctxsize = sizeof(struct blake2b_tfm_ctx),
|
||||
.base.cra_module = THIS_MODULE,
|
||||
.digestsize = BLAKE2B_256_DIGEST_SIZE,
|
||||
.setkey = blake2b_setkey,
|
||||
.init = blake2b_init,
|
||||
.update = blake2b_update,
|
||||
.final = blake2b_final,
|
||||
.descsize = sizeof(struct blake2b_state),
|
||||
}, {
|
||||
.base.cra_name = "blake2b-384",
|
||||
.base.cra_driver_name = "blake2b-384-generic",
|
||||
.base.cra_priority = 100,
|
||||
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||
.base.cra_blocksize = BLAKE2B_BLOCKBYTES,
|
||||
.base.cra_ctxsize = sizeof(struct blake2b_tfm_ctx),
|
||||
.base.cra_module = THIS_MODULE,
|
||||
.digestsize = BLAKE2B_384_DIGEST_SIZE,
|
||||
.setkey = blake2b_setkey,
|
||||
.init = blake2b_init,
|
||||
.update = blake2b_update,
|
||||
.final = blake2b_final,
|
||||
.descsize = sizeof(struct blake2b_state),
|
||||
}, {
|
||||
.base.cra_name = "blake2b-512",
|
||||
.base.cra_driver_name = "blake2b-512-generic",
|
||||
.base.cra_priority = 100,
|
||||
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||
.base.cra_blocksize = BLAKE2B_BLOCKBYTES,
|
||||
.base.cra_ctxsize = sizeof(struct blake2b_tfm_ctx),
|
||||
.base.cra_module = THIS_MODULE,
|
||||
.digestsize = BLAKE2B_512_DIGEST_SIZE,
|
||||
.setkey = blake2b_setkey,
|
||||
.init = blake2b_init,
|
||||
.update = blake2b_update,
|
||||
.final = blake2b_final,
|
||||
.descsize = sizeof(struct blake2b_state),
|
||||
}
|
||||
};
|
||||
|
||||
static int __init blake2b_mod_init(void)
|
||||
{
|
||||
return crypto_register_shashes(blake2b_algs, ARRAY_SIZE(blake2b_algs));
|
||||
}
|
||||
|
||||
static void __exit blake2b_mod_fini(void)
|
||||
{
|
||||
crypto_unregister_shashes(blake2b_algs, ARRAY_SIZE(blake2b_algs));
|
||||
}
|
||||
|
||||
subsys_initcall(blake2b_mod_init);
|
||||
module_exit(blake2b_mod_fini);
|
||||
|
||||
MODULE_AUTHOR("David Sterba <kdave@kernel.org>");
|
||||
MODULE_DESCRIPTION("BLAKE2b generic implementation");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_CRYPTO("blake2b-160");
|
||||
MODULE_ALIAS_CRYPTO("blake2b-160-generic");
|
||||
MODULE_ALIAS_CRYPTO("blake2b-256");
|
||||
MODULE_ALIAS_CRYPTO("blake2b-256-generic");
|
||||
MODULE_ALIAS_CRYPTO("blake2b-384");
|
||||
MODULE_ALIAS_CRYPTO("blake2b-384-generic");
|
||||
MODULE_ALIAS_CRYPTO("blake2b-512");
|
||||
MODULE_ALIAS_CRYPTO("blake2b-512-generic");
|
||||
@@ -0,0 +1,171 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
/*
|
||||
* Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
||||
*/
|
||||
|
||||
#include <crypto/internal/blake2s.h>
|
||||
#include <crypto/internal/simd.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static int crypto_blake2s_setkey(struct crypto_shash *tfm, const u8 *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(tfm);
|
||||
|
||||
if (keylen == 0 || keylen > BLAKE2S_KEY_SIZE) {
|
||||
crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(tctx->key, key, keylen);
|
||||
tctx->keylen = keylen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_blake2s_init(struct shash_desc *desc)
|
||||
{
|
||||
struct blake2s_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
|
||||
struct blake2s_state *state = shash_desc_ctx(desc);
|
||||
const int outlen = crypto_shash_digestsize(desc->tfm);
|
||||
|
||||
if (tctx->keylen)
|
||||
blake2s_init_key(state, outlen, tctx->key, tctx->keylen);
|
||||
else
|
||||
blake2s_init(state, outlen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_blake2s_update(struct shash_desc *desc, const u8 *in,
|
||||
unsigned int inlen)
|
||||
{
|
||||
struct blake2s_state *state = shash_desc_ctx(desc);
|
||||
const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
|
||||
|
||||
if (unlikely(!inlen))
|
||||
return 0;
|
||||
if (inlen > fill) {
|
||||
memcpy(state->buf + state->buflen, in, fill);
|
||||
blake2s_compress_generic(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
|
||||
state->buflen = 0;
|
||||
in += fill;
|
||||
inlen -= fill;
|
||||
}
|
||||
if (inlen > BLAKE2S_BLOCK_SIZE) {
|
||||
const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
|
||||
/* Hash one less (full) block than strictly possible */
|
||||
blake2s_compress_generic(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
|
||||
in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
|
||||
inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
|
||||
}
|
||||
memcpy(state->buf + state->buflen, in, inlen);
|
||||
state->buflen += inlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_blake2s_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct blake2s_state *state = shash_desc_ctx(desc);
|
||||
|
||||
blake2s_set_lastblock(state);
|
||||
memset(state->buf + state->buflen, 0,
|
||||
BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
|
||||
blake2s_compress_generic(state, state->buf, 1, state->buflen);
|
||||
cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
|
||||
memcpy(out, state->h, state->outlen);
|
||||
memzero_explicit(state, sizeof(*state));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg blake2s_algs[] = {{
|
||||
.base.cra_name = "blake2s-128",
|
||||
.base.cra_driver_name = "blake2s-128-generic",
|
||||
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||
.base.cra_ctxsize = sizeof(struct blake2s_tfm_ctx),
|
||||
.base.cra_priority = 200,
|
||||
.base.cra_blocksize = BLAKE2S_BLOCK_SIZE,
|
||||
.base.cra_module = THIS_MODULE,
|
||||
|
||||
.digestsize = BLAKE2S_128_HASH_SIZE,
|
||||
.setkey = crypto_blake2s_setkey,
|
||||
.init = crypto_blake2s_init,
|
||||
.update = crypto_blake2s_update,
|
||||
.final = crypto_blake2s_final,
|
||||
.descsize = sizeof(struct blake2s_state),
|
||||
}, {
|
||||
.base.cra_name = "blake2s-160",
|
||||
.base.cra_driver_name = "blake2s-160-generic",
|
||||
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||
.base.cra_ctxsize = sizeof(struct blake2s_tfm_ctx),
|
||||
.base.cra_priority = 200,
|
||||
.base.cra_blocksize = BLAKE2S_BLOCK_SIZE,
|
||||
.base.cra_module = THIS_MODULE,
|
||||
|
||||
.digestsize = BLAKE2S_160_HASH_SIZE,
|
||||
.setkey = crypto_blake2s_setkey,
|
||||
.init = crypto_blake2s_init,
|
||||
.update = crypto_blake2s_update,
|
||||
.final = crypto_blake2s_final,
|
||||
.descsize = sizeof(struct blake2s_state),
|
||||
}, {
|
||||
.base.cra_name = "blake2s-224",
|
||||
.base.cra_driver_name = "blake2s-224-generic",
|
||||
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||
.base.cra_ctxsize = sizeof(struct blake2s_tfm_ctx),
|
||||
.base.cra_priority = 200,
|
||||
.base.cra_blocksize = BLAKE2S_BLOCK_SIZE,
|
||||
.base.cra_module = THIS_MODULE,
|
||||
|
||||
.digestsize = BLAKE2S_224_HASH_SIZE,
|
||||
.setkey = crypto_blake2s_setkey,
|
||||
.init = crypto_blake2s_init,
|
||||
.update = crypto_blake2s_update,
|
||||
.final = crypto_blake2s_final,
|
||||
.descsize = sizeof(struct blake2s_state),
|
||||
}, {
|
||||
.base.cra_name = "blake2s-256",
|
||||
.base.cra_driver_name = "blake2s-256-generic",
|
||||
.base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY,
|
||||
.base.cra_ctxsize = sizeof(struct blake2s_tfm_ctx),
|
||||
.base.cra_priority = 200,
|
||||
.base.cra_blocksize = BLAKE2S_BLOCK_SIZE,
|
||||
.base.cra_module = THIS_MODULE,
|
||||
|
||||
.digestsize = BLAKE2S_256_HASH_SIZE,
|
||||
.setkey = crypto_blake2s_setkey,
|
||||
.init = crypto_blake2s_init,
|
||||
.update = crypto_blake2s_update,
|
||||
.final = crypto_blake2s_final,
|
||||
.descsize = sizeof(struct blake2s_state),
|
||||
}};
|
||||
|
||||
static int __init blake2s_mod_init(void)
|
||||
{
|
||||
return crypto_register_shashes(blake2s_algs, ARRAY_SIZE(blake2s_algs));
|
||||
}
|
||||
|
||||
static void __exit blake2s_mod_exit(void)
|
||||
{
|
||||
crypto_unregister_shashes(blake2s_algs, ARRAY_SIZE(blake2s_algs));
|
||||
}
|
||||
|
||||
subsys_initcall(blake2s_mod_init);
|
||||
module_exit(blake2s_mod_exit);
|
||||
|
||||
MODULE_ALIAS_CRYPTO("blake2s-128");
|
||||
MODULE_ALIAS_CRYPTO("blake2s-128-generic");
|
||||
MODULE_ALIAS_CRYPTO("blake2s-160");
|
||||
MODULE_ALIAS_CRYPTO("blake2s-160-generic");
|
||||
MODULE_ALIAS_CRYPTO("blake2s-224");
|
||||
MODULE_ALIAS_CRYPTO("blake2s-224-generic");
|
||||
MODULE_ALIAS_CRYPTO("blake2s-256");
|
||||
MODULE_ALIAS_CRYPTO("blake2s-256-generic");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -1,548 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Block chaining cipher operations.
|
||||
*
|
||||
* Generic encrypt/decrypt wrapper for ciphers, handles operations across
|
||||
* multiple page boundaries by using temporary blocks. In user context,
|
||||
* the kernel is given a chance to schedule us once per page.
|
||||
*
|
||||
* Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
|
||||
*/
|
||||
|
||||
#include <crypto/aead.h>
|
||||
#include <crypto/internal/skcipher.h>
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/cryptouser.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
enum {
|
||||
BLKCIPHER_WALK_PHYS = 1 << 0,
|
||||
BLKCIPHER_WALK_SLOW = 1 << 1,
|
||||
BLKCIPHER_WALK_COPY = 1 << 2,
|
||||
BLKCIPHER_WALK_DIFF = 1 << 3,
|
||||
};
|
||||
|
||||
static int blkcipher_walk_next(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk);
|
||||
static int blkcipher_walk_first(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk);
|
||||
|
||||
static inline void blkcipher_map_src(struct blkcipher_walk *walk)
|
||||
{
|
||||
walk->src.virt.addr = scatterwalk_map(&walk->in);
|
||||
}
|
||||
|
||||
static inline void blkcipher_map_dst(struct blkcipher_walk *walk)
|
||||
{
|
||||
walk->dst.virt.addr = scatterwalk_map(&walk->out);
|
||||
}
|
||||
|
||||
static inline void blkcipher_unmap_src(struct blkcipher_walk *walk)
|
||||
{
|
||||
scatterwalk_unmap(walk->src.virt.addr);
|
||||
}
|
||||
|
||||
static inline void blkcipher_unmap_dst(struct blkcipher_walk *walk)
|
||||
{
|
||||
scatterwalk_unmap(walk->dst.virt.addr);
|
||||
}
|
||||
|
||||
/* Get a spot of the specified length that does not straddle a page.
|
||||
* The caller needs to ensure that there is enough space for this operation.
|
||||
*/
|
||||
static inline u8 *blkcipher_get_spot(u8 *start, unsigned int len)
|
||||
{
|
||||
u8 *end_page = (u8 *)(((unsigned long)(start + len - 1)) & PAGE_MASK);
|
||||
return max(start, end_page);
|
||||
}
|
||||
|
||||
static inline void blkcipher_done_slow(struct blkcipher_walk *walk,
|
||||
unsigned int bsize)
|
||||
{
|
||||
u8 *addr;
|
||||
|
||||
addr = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1);
|
||||
addr = blkcipher_get_spot(addr, bsize);
|
||||
scatterwalk_copychunks(addr, &walk->out, bsize, 1);
|
||||
}
|
||||
|
||||
static inline void blkcipher_done_fast(struct blkcipher_walk *walk,
|
||||
unsigned int n)
|
||||
{
|
||||
if (walk->flags & BLKCIPHER_WALK_COPY) {
|
||||
blkcipher_map_dst(walk);
|
||||
memcpy(walk->dst.virt.addr, walk->page, n);
|
||||
blkcipher_unmap_dst(walk);
|
||||
} else if (!(walk->flags & BLKCIPHER_WALK_PHYS)) {
|
||||
if (walk->flags & BLKCIPHER_WALK_DIFF)
|
||||
blkcipher_unmap_dst(walk);
|
||||
blkcipher_unmap_src(walk);
|
||||
}
|
||||
|
||||
scatterwalk_advance(&walk->in, n);
|
||||
scatterwalk_advance(&walk->out, n);
|
||||
}
|
||||
|
||||
int blkcipher_walk_done(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk, int err)
|
||||
{
|
||||
unsigned int n; /* bytes processed */
|
||||
bool more;
|
||||
|
||||
if (unlikely(err < 0))
|
||||
goto finish;
|
||||
|
||||
n = walk->nbytes - err;
|
||||
walk->total -= n;
|
||||
more = (walk->total != 0);
|
||||
|
||||
if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW))) {
|
||||
blkcipher_done_fast(walk, n);
|
||||
} else {
|
||||
if (WARN_ON(err)) {
|
||||
/* unexpected case; didn't process all bytes */
|
||||
err = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
blkcipher_done_slow(walk, n);
|
||||
}
|
||||
|
||||
scatterwalk_done(&walk->in, 0, more);
|
||||
scatterwalk_done(&walk->out, 1, more);
|
||||
|
||||
if (more) {
|
||||
crypto_yield(desc->flags);
|
||||
return blkcipher_walk_next(desc, walk);
|
||||
}
|
||||
err = 0;
|
||||
finish:
|
||||
walk->nbytes = 0;
|
||||
if (walk->iv != desc->info)
|
||||
memcpy(desc->info, walk->iv, walk->ivsize);
|
||||
if (walk->buffer != walk->page)
|
||||
kfree(walk->buffer);
|
||||
if (walk->page)
|
||||
free_page((unsigned long)walk->page);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blkcipher_walk_done);
|
||||
|
||||
static inline int blkcipher_next_slow(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk,
|
||||
unsigned int bsize,
|
||||
unsigned int alignmask)
|
||||
{
|
||||
unsigned int n;
|
||||
unsigned aligned_bsize = ALIGN(bsize, alignmask + 1);
|
||||
|
||||
if (walk->buffer)
|
||||
goto ok;
|
||||
|
||||
walk->buffer = walk->page;
|
||||
if (walk->buffer)
|
||||
goto ok;
|
||||
|
||||
n = aligned_bsize * 3 - (alignmask + 1) +
|
||||
(alignmask & ~(crypto_tfm_ctx_alignment() - 1));
|
||||
walk->buffer = kmalloc(n, GFP_ATOMIC);
|
||||
if (!walk->buffer)
|
||||
return blkcipher_walk_done(desc, walk, -ENOMEM);
|
||||
|
||||
ok:
|
||||
walk->dst.virt.addr = (u8 *)ALIGN((unsigned long)walk->buffer,
|
||||
alignmask + 1);
|
||||
walk->dst.virt.addr = blkcipher_get_spot(walk->dst.virt.addr, bsize);
|
||||
walk->src.virt.addr = blkcipher_get_spot(walk->dst.virt.addr +
|
||||
aligned_bsize, bsize);
|
||||
|
||||
scatterwalk_copychunks(walk->src.virt.addr, &walk->in, bsize, 0);
|
||||
|
||||
walk->nbytes = bsize;
|
||||
walk->flags |= BLKCIPHER_WALK_SLOW;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blkcipher_next_copy(struct blkcipher_walk *walk)
|
||||
{
|
||||
u8 *tmp = walk->page;
|
||||
|
||||
blkcipher_map_src(walk);
|
||||
memcpy(tmp, walk->src.virt.addr, walk->nbytes);
|
||||
blkcipher_unmap_src(walk);
|
||||
|
||||
walk->src.virt.addr = tmp;
|
||||
walk->dst.virt.addr = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int blkcipher_next_fast(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
unsigned long diff;
|
||||
|
||||
walk->src.phys.page = scatterwalk_page(&walk->in);
|
||||
walk->src.phys.offset = offset_in_page(walk->in.offset);
|
||||
walk->dst.phys.page = scatterwalk_page(&walk->out);
|
||||
walk->dst.phys.offset = offset_in_page(walk->out.offset);
|
||||
|
||||
if (walk->flags & BLKCIPHER_WALK_PHYS)
|
||||
return 0;
|
||||
|
||||
diff = walk->src.phys.offset - walk->dst.phys.offset;
|
||||
diff |= walk->src.virt.page - walk->dst.virt.page;
|
||||
|
||||
blkcipher_map_src(walk);
|
||||
walk->dst.virt.addr = walk->src.virt.addr;
|
||||
|
||||
if (diff) {
|
||||
walk->flags |= BLKCIPHER_WALK_DIFF;
|
||||
blkcipher_map_dst(walk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int blkcipher_walk_next(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
unsigned int bsize;
|
||||
unsigned int n;
|
||||
int err;
|
||||
|
||||
n = walk->total;
|
||||
if (unlikely(n < walk->cipher_blocksize)) {
|
||||
desc->flags |= CRYPTO_TFM_RES_BAD_BLOCK_LEN;
|
||||
return blkcipher_walk_done(desc, walk, -EINVAL);
|
||||
}
|
||||
|
||||
bsize = min(walk->walk_blocksize, n);
|
||||
|
||||
walk->flags &= ~(BLKCIPHER_WALK_SLOW | BLKCIPHER_WALK_COPY |
|
||||
BLKCIPHER_WALK_DIFF);
|
||||
if (!scatterwalk_aligned(&walk->in, walk->alignmask) ||
|
||||
!scatterwalk_aligned(&walk->out, walk->alignmask)) {
|
||||
walk->flags |= BLKCIPHER_WALK_COPY;
|
||||
if (!walk->page) {
|
||||
walk->page = (void *)__get_free_page(GFP_ATOMIC);
|
||||
if (!walk->page)
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
|
||||
n = scatterwalk_clamp(&walk->in, n);
|
||||
n = scatterwalk_clamp(&walk->out, n);
|
||||
|
||||
if (unlikely(n < bsize)) {
|
||||
err = blkcipher_next_slow(desc, walk, bsize, walk->alignmask);
|
||||
goto set_phys_lowmem;
|
||||
}
|
||||
|
||||
walk->nbytes = n;
|
||||
if (walk->flags & BLKCIPHER_WALK_COPY) {
|
||||
err = blkcipher_next_copy(walk);
|
||||
goto set_phys_lowmem;
|
||||
}
|
||||
|
||||
return blkcipher_next_fast(desc, walk);
|
||||
|
||||
set_phys_lowmem:
|
||||
if (walk->flags & BLKCIPHER_WALK_PHYS) {
|
||||
walk->src.phys.page = virt_to_page(walk->src.virt.addr);
|
||||
walk->dst.phys.page = virt_to_page(walk->dst.virt.addr);
|
||||
walk->src.phys.offset &= PAGE_SIZE - 1;
|
||||
walk->dst.phys.offset &= PAGE_SIZE - 1;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline int blkcipher_copy_iv(struct blkcipher_walk *walk)
|
||||
{
|
||||
unsigned bs = walk->walk_blocksize;
|
||||
unsigned aligned_bs = ALIGN(bs, walk->alignmask + 1);
|
||||
unsigned int size = aligned_bs * 2 +
|
||||
walk->ivsize + max(aligned_bs, walk->ivsize) -
|
||||
(walk->alignmask + 1);
|
||||
u8 *iv;
|
||||
|
||||
size += walk->alignmask & ~(crypto_tfm_ctx_alignment() - 1);
|
||||
walk->buffer = kmalloc(size, GFP_ATOMIC);
|
||||
if (!walk->buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
iv = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1);
|
||||
iv = blkcipher_get_spot(iv, bs) + aligned_bs;
|
||||
iv = blkcipher_get_spot(iv, bs) + aligned_bs;
|
||||
iv = blkcipher_get_spot(iv, walk->ivsize);
|
||||
|
||||
walk->iv = memcpy(iv, walk->iv, walk->ivsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int blkcipher_walk_virt(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
walk->flags &= ~BLKCIPHER_WALK_PHYS;
|
||||
walk->walk_blocksize = crypto_blkcipher_blocksize(desc->tfm);
|
||||
walk->cipher_blocksize = walk->walk_blocksize;
|
||||
walk->ivsize = crypto_blkcipher_ivsize(desc->tfm);
|
||||
walk->alignmask = crypto_blkcipher_alignmask(desc->tfm);
|
||||
return blkcipher_walk_first(desc, walk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blkcipher_walk_virt);
|
||||
|
||||
int blkcipher_walk_phys(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
walk->flags |= BLKCIPHER_WALK_PHYS;
|
||||
walk->walk_blocksize = crypto_blkcipher_blocksize(desc->tfm);
|
||||
walk->cipher_blocksize = walk->walk_blocksize;
|
||||
walk->ivsize = crypto_blkcipher_ivsize(desc->tfm);
|
||||
walk->alignmask = crypto_blkcipher_alignmask(desc->tfm);
|
||||
return blkcipher_walk_first(desc, walk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blkcipher_walk_phys);
|
||||
|
||||
static int blkcipher_walk_first(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
if (WARN_ON_ONCE(in_irq()))
|
||||
return -EDEADLK;
|
||||
|
||||
walk->iv = desc->info;
|
||||
walk->nbytes = walk->total;
|
||||
if (unlikely(!walk->total))
|
||||
return 0;
|
||||
|
||||
walk->buffer = NULL;
|
||||
if (unlikely(((unsigned long)walk->iv & walk->alignmask))) {
|
||||
int err = blkcipher_copy_iv(walk);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
scatterwalk_start(&walk->in, walk->in.sg);
|
||||
scatterwalk_start(&walk->out, walk->out.sg);
|
||||
walk->page = NULL;
|
||||
|
||||
return blkcipher_walk_next(desc, walk);
|
||||
}
|
||||
|
||||
int blkcipher_walk_virt_block(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk,
|
||||
unsigned int blocksize)
|
||||
{
|
||||
walk->flags &= ~BLKCIPHER_WALK_PHYS;
|
||||
walk->walk_blocksize = blocksize;
|
||||
walk->cipher_blocksize = crypto_blkcipher_blocksize(desc->tfm);
|
||||
walk->ivsize = crypto_blkcipher_ivsize(desc->tfm);
|
||||
walk->alignmask = crypto_blkcipher_alignmask(desc->tfm);
|
||||
return blkcipher_walk_first(desc, walk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blkcipher_walk_virt_block);
|
||||
|
||||
int blkcipher_aead_walk_virt_block(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk,
|
||||
struct crypto_aead *tfm,
|
||||
unsigned int blocksize)
|
||||
{
|
||||
walk->flags &= ~BLKCIPHER_WALK_PHYS;
|
||||
walk->walk_blocksize = blocksize;
|
||||
walk->cipher_blocksize = crypto_aead_blocksize(tfm);
|
||||
walk->ivsize = crypto_aead_ivsize(tfm);
|
||||
walk->alignmask = crypto_aead_alignmask(tfm);
|
||||
return blkcipher_walk_first(desc, walk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blkcipher_aead_walk_virt_block);
|
||||
|
||||
static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
struct blkcipher_alg *cipher = &tfm->__crt_alg->cra_blkcipher;
|
||||
unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
|
||||
int ret;
|
||||
u8 *buffer, *alignbuffer;
|
||||
unsigned long absize;
|
||||
|
||||
absize = keylen + alignmask;
|
||||
buffer = kmalloc(absize, GFP_ATOMIC);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
|
||||
memcpy(alignbuffer, key, keylen);
|
||||
ret = cipher->setkey(tfm, alignbuffer, keylen);
|
||||
memset(alignbuffer, 0, keylen);
|
||||
kfree(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
|
||||
{
|
||||
struct blkcipher_alg *cipher = &tfm->__crt_alg->cra_blkcipher;
|
||||
unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
|
||||
|
||||
if (keylen < cipher->min_keysize || keylen > cipher->max_keysize) {
|
||||
tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((unsigned long)key & alignmask)
|
||||
return setkey_unaligned(tfm, key, keylen);
|
||||
|
||||
return cipher->setkey(tfm, key, keylen);
|
||||
}
|
||||
|
||||
static int async_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
return setkey(crypto_ablkcipher_tfm(tfm), key, keylen);
|
||||
}
|
||||
|
||||
static int async_encrypt(struct ablkcipher_request *req)
|
||||
{
|
||||
struct crypto_tfm *tfm = req->base.tfm;
|
||||
struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
|
||||
struct blkcipher_desc desc = {
|
||||
.tfm = __crypto_blkcipher_cast(tfm),
|
||||
.info = req->info,
|
||||
.flags = req->base.flags,
|
||||
};
|
||||
|
||||
|
||||
return alg->encrypt(&desc, req->dst, req->src, req->nbytes);
|
||||
}
|
||||
|
||||
static int async_decrypt(struct ablkcipher_request *req)
|
||||
{
|
||||
struct crypto_tfm *tfm = req->base.tfm;
|
||||
struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
|
||||
struct blkcipher_desc desc = {
|
||||
.tfm = __crypto_blkcipher_cast(tfm),
|
||||
.info = req->info,
|
||||
.flags = req->base.flags,
|
||||
};
|
||||
|
||||
return alg->decrypt(&desc, req->dst, req->src, req->nbytes);
|
||||
}
|
||||
|
||||
static unsigned int crypto_blkcipher_ctxsize(struct crypto_alg *alg, u32 type,
|
||||
u32 mask)
|
||||
{
|
||||
struct blkcipher_alg *cipher = &alg->cra_blkcipher;
|
||||
unsigned int len = alg->cra_ctxsize;
|
||||
|
||||
if ((mask & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_MASK &&
|
||||
cipher->ivsize) {
|
||||
len = ALIGN(len, (unsigned long)alg->cra_alignmask + 1);
|
||||
len += cipher->ivsize;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int crypto_init_blkcipher_ops_async(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher;
|
||||
struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
|
||||
|
||||
crt->setkey = async_setkey;
|
||||
crt->encrypt = async_encrypt;
|
||||
crt->decrypt = async_decrypt;
|
||||
crt->base = __crypto_ablkcipher_cast(tfm);
|
||||
crt->ivsize = alg->ivsize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_init_blkcipher_ops_sync(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct blkcipher_tfm *crt = &tfm->crt_blkcipher;
|
||||
struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
|
||||
unsigned long align = crypto_tfm_alg_alignmask(tfm) + 1;
|
||||
unsigned long addr;
|
||||
|
||||
crt->setkey = setkey;
|
||||
crt->encrypt = alg->encrypt;
|
||||
crt->decrypt = alg->decrypt;
|
||||
|
||||
addr = (unsigned long)crypto_tfm_ctx(tfm);
|
||||
addr = ALIGN(addr, align);
|
||||
addr += ALIGN(tfm->__crt_alg->cra_ctxsize, align);
|
||||
crt->iv = (void *)addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
|
||||
{
|
||||
struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
|
||||
|
||||
if (alg->ivsize > PAGE_SIZE / 8)
|
||||
return -EINVAL;
|
||||
|
||||
if ((mask & CRYPTO_ALG_TYPE_MASK) == CRYPTO_ALG_TYPE_MASK)
|
||||
return crypto_init_blkcipher_ops_sync(tfm);
|
||||
else
|
||||
return crypto_init_blkcipher_ops_async(tfm);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET
|
||||
static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
||||
{
|
||||
struct crypto_report_blkcipher rblkcipher;
|
||||
|
||||
memset(&rblkcipher, 0, sizeof(rblkcipher));
|
||||
|
||||
strscpy(rblkcipher.type, "blkcipher", sizeof(rblkcipher.type));
|
||||
strscpy(rblkcipher.geniv, "<default>", sizeof(rblkcipher.geniv));
|
||||
|
||||
rblkcipher.blocksize = alg->cra_blocksize;
|
||||
rblkcipher.min_keysize = alg->cra_blkcipher.min_keysize;
|
||||
rblkcipher.max_keysize = alg->cra_blkcipher.max_keysize;
|
||||
rblkcipher.ivsize = alg->cra_blkcipher.ivsize;
|
||||
|
||||
return nla_put(skb, CRYPTOCFGA_REPORT_BLKCIPHER,
|
||||
sizeof(rblkcipher), &rblkcipher);
|
||||
}
|
||||
#else
|
||||
static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
__maybe_unused;
|
||||
static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
{
|
||||
seq_printf(m, "type : blkcipher\n");
|
||||
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
|
||||
seq_printf(m, "min keysize : %u\n", alg->cra_blkcipher.min_keysize);
|
||||
seq_printf(m, "max keysize : %u\n", alg->cra_blkcipher.max_keysize);
|
||||
seq_printf(m, "ivsize : %u\n", alg->cra_blkcipher.ivsize);
|
||||
seq_printf(m, "geniv : <default>\n");
|
||||
}
|
||||
|
||||
const struct crypto_type crypto_blkcipher_type = {
|
||||
.ctxsize = crypto_blkcipher_ctxsize,
|
||||
.init = crypto_init_blkcipher_ops,
|
||||
#ifdef CONFIG_PROC_FS
|
||||
.show = crypto_blkcipher_show,
|
||||
#endif
|
||||
.report = crypto_blkcipher_report,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(crypto_blkcipher_type);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Generic block chaining cipher type");
|
||||
+11
-83
@@ -8,29 +8,10 @@
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/chacha.h>
|
||||
#include <crypto/internal/chacha.h>
|
||||
#include <crypto/internal/skcipher.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static void chacha_docrypt(u32 *state, u8 *dst, const u8 *src,
|
||||
unsigned int bytes, int nrounds)
|
||||
{
|
||||
/* aligned to potentially speed up crypto_xor() */
|
||||
u8 stream[CHACHA_BLOCK_SIZE] __aligned(sizeof(long));
|
||||
|
||||
while (bytes >= CHACHA_BLOCK_SIZE) {
|
||||
chacha_block(state, stream, nrounds);
|
||||
crypto_xor_cpy(dst, src, stream, CHACHA_BLOCK_SIZE);
|
||||
bytes -= CHACHA_BLOCK_SIZE;
|
||||
dst += CHACHA_BLOCK_SIZE;
|
||||
src += CHACHA_BLOCK_SIZE;
|
||||
}
|
||||
if (bytes) {
|
||||
chacha_block(state, stream, nrounds);
|
||||
crypto_xor_cpy(dst, src, stream, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
static int chacha_stream_xor(struct skcipher_request *req,
|
||||
const struct chacha_ctx *ctx, const u8 *iv)
|
||||
{
|
||||
@@ -40,7 +21,7 @@ static int chacha_stream_xor(struct skcipher_request *req,
|
||||
|
||||
err = skcipher_walk_virt(&walk, req, false);
|
||||
|
||||
crypto_chacha_init(state, ctx, iv);
|
||||
chacha_init_generic(state, ctx->key, iv);
|
||||
|
||||
while (walk.nbytes > 0) {
|
||||
unsigned int nbytes = walk.nbytes;
|
||||
@@ -48,75 +29,23 @@ static int chacha_stream_xor(struct skcipher_request *req,
|
||||
if (nbytes < walk.total)
|
||||
nbytes = round_down(nbytes, CHACHA_BLOCK_SIZE);
|
||||
|
||||
chacha_docrypt(state, walk.dst.virt.addr, walk.src.virt.addr,
|
||||
nbytes, ctx->nrounds);
|
||||
chacha_crypt_generic(state, walk.dst.virt.addr,
|
||||
walk.src.virt.addr, nbytes, ctx->nrounds);
|
||||
err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void crypto_chacha_init(u32 *state, const struct chacha_ctx *ctx, const u8 *iv)
|
||||
{
|
||||
state[0] = 0x61707865; /* "expa" */
|
||||
state[1] = 0x3320646e; /* "nd 3" */
|
||||
state[2] = 0x79622d32; /* "2-by" */
|
||||
state[3] = 0x6b206574; /* "te k" */
|
||||
state[4] = ctx->key[0];
|
||||
state[5] = ctx->key[1];
|
||||
state[6] = ctx->key[2];
|
||||
state[7] = ctx->key[3];
|
||||
state[8] = ctx->key[4];
|
||||
state[9] = ctx->key[5];
|
||||
state[10] = ctx->key[6];
|
||||
state[11] = ctx->key[7];
|
||||
state[12] = get_unaligned_le32(iv + 0);
|
||||
state[13] = get_unaligned_le32(iv + 4);
|
||||
state[14] = get_unaligned_le32(iv + 8);
|
||||
state[15] = get_unaligned_le32(iv + 12);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_chacha_init);
|
||||
|
||||
static int chacha_setkey(struct crypto_skcipher *tfm, const u8 *key,
|
||||
unsigned int keysize, int nrounds)
|
||||
{
|
||||
struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm);
|
||||
int i;
|
||||
|
||||
if (keysize != CHACHA_KEY_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ctx->key); i++)
|
||||
ctx->key[i] = get_unaligned_le32(key + i * sizeof(u32));
|
||||
|
||||
ctx->nrounds = nrounds;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_chacha20_setkey(struct crypto_skcipher *tfm, const u8 *key,
|
||||
unsigned int keysize)
|
||||
{
|
||||
return chacha_setkey(tfm, key, keysize, 20);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_chacha20_setkey);
|
||||
|
||||
int crypto_chacha12_setkey(struct crypto_skcipher *tfm, const u8 *key,
|
||||
unsigned int keysize)
|
||||
{
|
||||
return chacha_setkey(tfm, key, keysize, 12);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_chacha12_setkey);
|
||||
|
||||
int crypto_chacha_crypt(struct skcipher_request *req)
|
||||
static int crypto_chacha_crypt(struct skcipher_request *req)
|
||||
{
|
||||
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
||||
struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm);
|
||||
|
||||
return chacha_stream_xor(req, ctx, req->iv);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_chacha_crypt);
|
||||
|
||||
int crypto_xchacha_crypt(struct skcipher_request *req)
|
||||
static int crypto_xchacha_crypt(struct skcipher_request *req)
|
||||
{
|
||||
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
||||
struct chacha_ctx *ctx = crypto_skcipher_ctx(tfm);
|
||||
@@ -125,8 +54,8 @@ int crypto_xchacha_crypt(struct skcipher_request *req)
|
||||
u8 real_iv[16];
|
||||
|
||||
/* Compute the subkey given the original key and first 128 nonce bits */
|
||||
crypto_chacha_init(state, ctx, req->iv);
|
||||
hchacha_block(state, subctx.key, ctx->nrounds);
|
||||
chacha_init_generic(state, ctx->key, req->iv);
|
||||
hchacha_block_generic(state, subctx.key, ctx->nrounds);
|
||||
subctx.nrounds = ctx->nrounds;
|
||||
|
||||
/* Build the real IV */
|
||||
@@ -136,7 +65,6 @@ int crypto_xchacha_crypt(struct skcipher_request *req)
|
||||
/* Generate the stream and XOR it with the data */
|
||||
return chacha_stream_xor(req, &subctx, real_iv);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_xchacha_crypt);
|
||||
|
||||
static struct skcipher_alg algs[] = {
|
||||
{
|
||||
@@ -151,7 +79,7 @@ static struct skcipher_alg algs[] = {
|
||||
.max_keysize = CHACHA_KEY_SIZE,
|
||||
.ivsize = CHACHA_IV_SIZE,
|
||||
.chunksize = CHACHA_BLOCK_SIZE,
|
||||
.setkey = crypto_chacha20_setkey,
|
||||
.setkey = chacha20_setkey,
|
||||
.encrypt = crypto_chacha_crypt,
|
||||
.decrypt = crypto_chacha_crypt,
|
||||
}, {
|
||||
@@ -166,7 +94,7 @@ static struct skcipher_alg algs[] = {
|
||||
.max_keysize = CHACHA_KEY_SIZE,
|
||||
.ivsize = XCHACHA_IV_SIZE,
|
||||
.chunksize = CHACHA_BLOCK_SIZE,
|
||||
.setkey = crypto_chacha20_setkey,
|
||||
.setkey = chacha20_setkey,
|
||||
.encrypt = crypto_xchacha_crypt,
|
||||
.decrypt = crypto_xchacha_crypt,
|
||||
}, {
|
||||
@@ -181,7 +109,7 @@ static struct skcipher_alg algs[] = {
|
||||
.max_keysize = CHACHA_KEY_SIZE,
|
||||
.ivsize = XCHACHA_IV_SIZE,
|
||||
.chunksize = CHACHA_BLOCK_SIZE,
|
||||
.setkey = crypto_chacha12_setkey,
|
||||
.setkey = chacha12_setkey,
|
||||
.encrypt = crypto_xchacha_crypt,
|
||||
.decrypt = crypto_xchacha_crypt,
|
||||
}
|
||||
|
||||
+1
-1
@@ -919,7 +919,7 @@ static int cryptd_create(struct crypto_template *tmpl, struct rtattr **tb)
|
||||
return PTR_ERR(algt);
|
||||
|
||||
switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) {
|
||||
case CRYPTO_ALG_TYPE_BLKCIPHER:
|
||||
case CRYPTO_ALG_TYPE_SKCIPHER:
|
||||
return cryptd_create_skcipher(tmpl, tb, &queue);
|
||||
case CRYPTO_ALG_TYPE_HASH:
|
||||
return cryptd_create_hash(tmpl, tb, &queue);
|
||||
|
||||
@@ -213,20 +213,6 @@ static int crypto_transfer_request_to_engine(struct crypto_engine *engine,
|
||||
return crypto_transfer_request(engine, req, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* crypto_transfer_ablkcipher_request_to_engine - transfer one ablkcipher_request
|
||||
* to list into the engine queue
|
||||
* @engine: the hardware engine
|
||||
* @req: the request need to be listed into the engine queue
|
||||
* TODO: Remove this function when skcipher conversion is finished
|
||||
*/
|
||||
int crypto_transfer_ablkcipher_request_to_engine(struct crypto_engine *engine,
|
||||
struct ablkcipher_request *req)
|
||||
{
|
||||
return crypto_transfer_request_to_engine(engine, &req->base);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_transfer_ablkcipher_request_to_engine);
|
||||
|
||||
/**
|
||||
* crypto_transfer_aead_request_to_engine - transfer one aead_request
|
||||
* to list into the engine queue
|
||||
@@ -279,21 +265,6 @@ int crypto_transfer_skcipher_request_to_engine(struct crypto_engine *engine,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_transfer_skcipher_request_to_engine);
|
||||
|
||||
/**
|
||||
* crypto_finalize_ablkcipher_request - finalize one ablkcipher_request if
|
||||
* the request is done
|
||||
* @engine: the hardware engine
|
||||
* @req: the request need to be finalized
|
||||
* @err: error number
|
||||
* TODO: Remove this function when skcipher conversion is finished
|
||||
*/
|
||||
void crypto_finalize_ablkcipher_request(struct crypto_engine *engine,
|
||||
struct ablkcipher_request *req, int err)
|
||||
{
|
||||
return crypto_finalize_request(engine, &req->base, err);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_finalize_ablkcipher_request);
|
||||
|
||||
/**
|
||||
* crypto_finalize_aead_request - finalize one aead_request if
|
||||
* the request is done
|
||||
|
||||
@@ -213,8 +213,10 @@ static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
|
||||
drop_alg:
|
||||
crypto_mod_put(alg);
|
||||
|
||||
if (err)
|
||||
if (err) {
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
return nlmsg_unicast(net->crypto_nlsk, skb, NETLINK_CB(in_skb).portid);
|
||||
}
|
||||
|
||||
@@ -213,10 +213,6 @@ static int crypto_reportstat_one(struct crypto_alg *alg,
|
||||
if (crypto_report_cipher(skb, alg))
|
||||
goto nla_put_failure;
|
||||
break;
|
||||
case CRYPTO_ALG_TYPE_BLKCIPHER:
|
||||
if (crypto_report_cipher(skb, alg))
|
||||
goto nla_put_failure;
|
||||
break;
|
||||
case CRYPTO_ALG_TYPE_CIPHER:
|
||||
if (crypto_report_cipher(skb, alg))
|
||||
goto nla_put_failure;
|
||||
@@ -328,8 +324,10 @@ int crypto_reportstat(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
|
||||
drop_alg:
|
||||
crypto_mod_put(alg);
|
||||
|
||||
if (err)
|
||||
if (err) {
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
return nlmsg_unicast(net->crypto_nlsk, skb, NETLINK_CB(in_skb).portid);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <crypto/curve25519.h>
|
||||
#include <crypto/internal/kpp.h>
|
||||
#include <crypto/kpp.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
static int curve25519_set_secret(struct crypto_kpp *tfm, const void *buf,
|
||||
unsigned int len)
|
||||
{
|
||||
u8 *secret = kpp_tfm_ctx(tfm);
|
||||
|
||||
if (!len)
|
||||
curve25519_generate_secret(secret);
|
||||
else if (len == CURVE25519_KEY_SIZE &&
|
||||
crypto_memneq(buf, curve25519_null_point, CURVE25519_KEY_SIZE))
|
||||
memcpy(secret, buf, CURVE25519_KEY_SIZE);
|
||||
else
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int curve25519_compute_value(struct kpp_request *req)
|
||||
{
|
||||
struct crypto_kpp *tfm = crypto_kpp_reqtfm(req);
|
||||
const u8 *secret = kpp_tfm_ctx(tfm);
|
||||
u8 public_key[CURVE25519_KEY_SIZE];
|
||||
u8 buf[CURVE25519_KEY_SIZE];
|
||||
int copied, nbytes;
|
||||
u8 const *bp;
|
||||
|
||||
if (req->src) {
|
||||
copied = sg_copy_to_buffer(req->src,
|
||||
sg_nents_for_len(req->src,
|
||||
CURVE25519_KEY_SIZE),
|
||||
public_key, CURVE25519_KEY_SIZE);
|
||||
if (copied != CURVE25519_KEY_SIZE)
|
||||
return -EINVAL;
|
||||
bp = public_key;
|
||||
} else {
|
||||
bp = curve25519_base_point;
|
||||
}
|
||||
|
||||
curve25519_generic(buf, secret, bp);
|
||||
|
||||
/* might want less than we've got */
|
||||
nbytes = min_t(size_t, CURVE25519_KEY_SIZE, req->dst_len);
|
||||
copied = sg_copy_from_buffer(req->dst, sg_nents_for_len(req->dst,
|
||||
nbytes),
|
||||
buf, nbytes);
|
||||
if (copied != nbytes)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int curve25519_max_size(struct crypto_kpp *tfm)
|
||||
{
|
||||
return CURVE25519_KEY_SIZE;
|
||||
}
|
||||
|
||||
static struct kpp_alg curve25519_alg = {
|
||||
.base.cra_name = "curve25519",
|
||||
.base.cra_driver_name = "curve25519-generic",
|
||||
.base.cra_priority = 100,
|
||||
.base.cra_module = THIS_MODULE,
|
||||
.base.cra_ctxsize = CURVE25519_KEY_SIZE,
|
||||
|
||||
.set_secret = curve25519_set_secret,
|
||||
.generate_public_key = curve25519_compute_value,
|
||||
.compute_shared_secret = curve25519_compute_value,
|
||||
.max_size = curve25519_max_size,
|
||||
};
|
||||
|
||||
static int curve25519_init(void)
|
||||
{
|
||||
return crypto_register_kpp(&curve25519_alg);
|
||||
}
|
||||
|
||||
static void curve25519_exit(void)
|
||||
{
|
||||
crypto_unregister_kpp(&curve25519_alg);
|
||||
}
|
||||
|
||||
subsys_initcall(curve25519_init);
|
||||
module_exit(curve25519_exit);
|
||||
|
||||
MODULE_ALIAS_CRYPTO("curve25519");
|
||||
MODULE_ALIAS_CRYPTO("curve25519-generic");
|
||||
MODULE_LICENSE("GPL");
|
||||
+3
-2
@@ -336,7 +336,7 @@ static u64 vli_usub(u64 *result, const u64 *left, u64 right,
|
||||
static uint128_t mul_64_64(u64 left, u64 right)
|
||||
{
|
||||
uint128_t result;
|
||||
#if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__)
|
||||
#if defined(CONFIG_ARCH_SUPPORTS_INT128)
|
||||
unsigned __int128 m = (unsigned __int128)left * right;
|
||||
|
||||
result.m_low = m;
|
||||
@@ -1284,10 +1284,11 @@ EXPORT_SYMBOL(ecc_point_mult_shamir);
|
||||
static inline void ecc_swap_digits(const u64 *in, u64 *out,
|
||||
unsigned int ndigits)
|
||||
{
|
||||
const __be64 *src = (__force __be64 *)in;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ndigits; i++)
|
||||
out[i] = __swab64(in[ndigits - 1 - i]);
|
||||
out[i] = be64_to_cpu(src[ndigits - 1 - i]);
|
||||
}
|
||||
|
||||
static int __ecc_is_key_valid(const struct ecc_curve *curve,
|
||||
|
||||
+4
-5
@@ -188,8 +188,7 @@ static void essiv_aead_done(struct crypto_async_request *areq, int err)
|
||||
struct aead_request *req = areq->data;
|
||||
struct essiv_aead_request_ctx *rctx = aead_request_ctx(req);
|
||||
|
||||
if (rctx->assoc)
|
||||
kfree(rctx->assoc);
|
||||
kfree(rctx->assoc);
|
||||
aead_request_complete(req, err);
|
||||
}
|
||||
|
||||
@@ -486,7 +485,7 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
|
||||
type = algt->type & algt->mask;
|
||||
|
||||
switch (type) {
|
||||
case CRYPTO_ALG_TYPE_BLKCIPHER:
|
||||
case CRYPTO_ALG_TYPE_SKCIPHER:
|
||||
skcipher_inst = kzalloc(sizeof(*skcipher_inst) +
|
||||
sizeof(*ictx), GFP_KERNEL);
|
||||
if (!skcipher_inst)
|
||||
@@ -586,7 +585,7 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
|
||||
base->cra_alignmask = block_base->cra_alignmask;
|
||||
base->cra_priority = block_base->cra_priority;
|
||||
|
||||
if (type == CRYPTO_ALG_TYPE_BLKCIPHER) {
|
||||
if (type == CRYPTO_ALG_TYPE_SKCIPHER) {
|
||||
skcipher_inst->alg.setkey = essiv_skcipher_setkey;
|
||||
skcipher_inst->alg.encrypt = essiv_skcipher_encrypt;
|
||||
skcipher_inst->alg.decrypt = essiv_skcipher_decrypt;
|
||||
@@ -628,7 +627,7 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
|
||||
out_free_hash:
|
||||
crypto_mod_put(_hash_alg);
|
||||
out_drop_skcipher:
|
||||
if (type == CRYPTO_ALG_TYPE_BLKCIPHER)
|
||||
if (type == CRYPTO_ALG_TYPE_SKCIPHER)
|
||||
crypto_drop_skcipher(&ictx->u.skcipher_spawn);
|
||||
else
|
||||
crypto_drop_aead(&ictx->u.aead_spawn);
|
||||
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* geniv: Shared IV generator code
|
||||
*
|
||||
* This file provides common code to IV generators such as seqiv.
|
||||
*
|
||||
* Copyright (c) 2007-2019 Herbert Xu <herbert@gondor.apana.org.au>
|
||||
*/
|
||||
|
||||
#include <crypto/internal/geniv.h>
|
||||
#include <crypto/internal/rng.h>
|
||||
#include <crypto/null.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
static int aead_geniv_setkey(struct crypto_aead *tfm,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm);
|
||||
|
||||
return crypto_aead_setkey(ctx->child, key, keylen);
|
||||
}
|
||||
|
||||
static int aead_geniv_setauthsize(struct crypto_aead *tfm,
|
||||
unsigned int authsize)
|
||||
{
|
||||
struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm);
|
||||
|
||||
return crypto_aead_setauthsize(ctx->child, authsize);
|
||||
}
|
||||
|
||||
struct aead_instance *aead_geniv_alloc(struct crypto_template *tmpl,
|
||||
struct rtattr **tb, u32 type, u32 mask)
|
||||
{
|
||||
const char *name;
|
||||
struct crypto_aead_spawn *spawn;
|
||||
struct crypto_attr_type *algt;
|
||||
struct aead_instance *inst;
|
||||
struct aead_alg *alg;
|
||||
unsigned int ivsize;
|
||||
unsigned int maxauthsize;
|
||||
int err;
|
||||
|
||||
algt = crypto_get_attr_type(tb);
|
||||
if (IS_ERR(algt))
|
||||
return ERR_CAST(algt);
|
||||
|
||||
if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
name = crypto_attr_alg_name(tb[1]);
|
||||
if (IS_ERR(name))
|
||||
return ERR_CAST(name);
|
||||
|
||||
inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
|
||||
if (!inst)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
spawn = aead_instance_ctx(inst);
|
||||
|
||||
/* Ignore async algorithms if necessary. */
|
||||
mask |= crypto_requires_sync(algt->type, algt->mask);
|
||||
|
||||
crypto_set_aead_spawn(spawn, aead_crypto_instance(inst));
|
||||
err = crypto_grab_aead(spawn, name, type, mask);
|
||||
if (err)
|
||||
goto err_free_inst;
|
||||
|
||||
alg = crypto_spawn_aead_alg(spawn);
|
||||
|
||||
ivsize = crypto_aead_alg_ivsize(alg);
|
||||
maxauthsize = crypto_aead_alg_maxauthsize(alg);
|
||||
|
||||
err = -EINVAL;
|
||||
if (ivsize < sizeof(u64))
|
||||
goto err_drop_alg;
|
||||
|
||||
err = -ENAMETOOLONG;
|
||||
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
|
||||
"%s(%s)", tmpl->name, alg->base.cra_name) >=
|
||||
CRYPTO_MAX_ALG_NAME)
|
||||
goto err_drop_alg;
|
||||
if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
|
||||
"%s(%s)", tmpl->name, alg->base.cra_driver_name) >=
|
||||
CRYPTO_MAX_ALG_NAME)
|
||||
goto err_drop_alg;
|
||||
|
||||
inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
|
||||
inst->alg.base.cra_priority = alg->base.cra_priority;
|
||||
inst->alg.base.cra_blocksize = alg->base.cra_blocksize;
|
||||
inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
|
||||
inst->alg.base.cra_ctxsize = sizeof(struct aead_geniv_ctx);
|
||||
|
||||
inst->alg.setkey = aead_geniv_setkey;
|
||||
inst->alg.setauthsize = aead_geniv_setauthsize;
|
||||
|
||||
inst->alg.ivsize = ivsize;
|
||||
inst->alg.maxauthsize = maxauthsize;
|
||||
|
||||
out:
|
||||
return inst;
|
||||
|
||||
err_drop_alg:
|
||||
crypto_drop_aead(spawn);
|
||||
err_free_inst:
|
||||
kfree(inst);
|
||||
inst = ERR_PTR(err);
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aead_geniv_alloc);
|
||||
|
||||
void aead_geniv_free(struct aead_instance *inst)
|
||||
{
|
||||
crypto_drop_aead(aead_instance_ctx(inst));
|
||||
kfree(inst);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aead_geniv_free);
|
||||
|
||||
int aead_init_geniv(struct crypto_aead *aead)
|
||||
{
|
||||
struct aead_geniv_ctx *ctx = crypto_aead_ctx(aead);
|
||||
struct aead_instance *inst = aead_alg_instance(aead);
|
||||
struct crypto_aead *child;
|
||||
int err;
|
||||
|
||||
spin_lock_init(&ctx->lock);
|
||||
|
||||
err = crypto_get_default_rng();
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = crypto_rng_get_bytes(crypto_default_rng, ctx->salt,
|
||||
crypto_aead_ivsize(aead));
|
||||
crypto_put_default_rng();
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
ctx->sknull = crypto_get_default_null_skcipher();
|
||||
err = PTR_ERR(ctx->sknull);
|
||||
if (IS_ERR(ctx->sknull))
|
||||
goto out;
|
||||
|
||||
child = crypto_spawn_aead(aead_instance_ctx(inst));
|
||||
err = PTR_ERR(child);
|
||||
if (IS_ERR(child))
|
||||
goto drop_null;
|
||||
|
||||
ctx->child = child;
|
||||
crypto_aead_set_reqsize(aead, crypto_aead_reqsize(child) +
|
||||
sizeof(struct aead_request));
|
||||
|
||||
err = 0;
|
||||
|
||||
out:
|
||||
return err;
|
||||
|
||||
drop_null:
|
||||
crypto_put_default_null_skcipher();
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aead_init_geniv);
|
||||
|
||||
void aead_exit_geniv(struct crypto_aead *tfm)
|
||||
{
|
||||
struct aead_geniv_ctx *ctx = crypto_aead_ctx(tfm);
|
||||
|
||||
crypto_free_aead(ctx->child);
|
||||
crypto_put_default_null_skcipher();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aead_exit_geniv);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Shared IV generator code");
|
||||
@@ -44,13 +44,7 @@
|
||||
#include <linux/crypto.h>
|
||||
#include <crypto/internal/rng.h>
|
||||
|
||||
struct rand_data;
|
||||
int jent_read_entropy(struct rand_data *ec, unsigned char *data,
|
||||
unsigned int len);
|
||||
int jent_entropy_init(void);
|
||||
struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
|
||||
unsigned int flags);
|
||||
void jent_entropy_collector_free(struct rand_data *entropy_collector);
|
||||
#include "jitterentropy.h"
|
||||
|
||||
/***************************************************************************
|
||||
* Helper function
|
||||
|
||||
@@ -103,12 +103,7 @@ struct rand_data {
|
||||
* Helper functions
|
||||
***************************************************************************/
|
||||
|
||||
void jent_get_nstime(__u64 *out);
|
||||
void *jent_zalloc(unsigned int len);
|
||||
void jent_zfree(void *ptr);
|
||||
int jent_fips_enabled(void);
|
||||
void jent_panic(char *s);
|
||||
void jent_memcpy(void *dest, const void *src, unsigned int n);
|
||||
#include "jitterentropy.h"
|
||||
|
||||
/**
|
||||
* Update of the loop count used for the next round of
|
||||
@@ -172,7 +167,7 @@ static __u64 jent_loop_shuffle(struct rand_data *ec,
|
||||
* implies that careful retesting must be done.
|
||||
*
|
||||
* Input:
|
||||
* @ec entropy collector struct -- may be NULL
|
||||
* @ec entropy collector struct
|
||||
* @time time stamp to be injected
|
||||
* @loop_cnt if a value not equal to 0 is set, use the given value as number of
|
||||
* loops to perform the folding
|
||||
@@ -400,8 +395,8 @@ static void jent_gen_entropy(struct rand_data *ec)
|
||||
* primes the test if needed.
|
||||
*
|
||||
* Return:
|
||||
* 0 if FIPS test passed
|
||||
* < 0 if FIPS test failed
|
||||
* returns normally if FIPS test passed
|
||||
* panics the kernel if FIPS test failed
|
||||
*/
|
||||
static void jent_fips_test(struct rand_data *ec)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
extern void *jent_zalloc(unsigned int len);
|
||||
extern void jent_zfree(void *ptr);
|
||||
extern int jent_fips_enabled(void);
|
||||
extern void jent_panic(char *s);
|
||||
extern void jent_memcpy(void *dest, const void *src, unsigned int n);
|
||||
extern void jent_get_nstime(__u64 *out);
|
||||
|
||||
struct rand_data;
|
||||
extern int jent_entropy_init(void);
|
||||
extern int jent_read_entropy(struct rand_data *ec, unsigned char *data,
|
||||
unsigned int len);
|
||||
|
||||
extern struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
|
||||
unsigned int flags);
|
||||
extern void jent_entropy_collector_free(struct rand_data *entropy_collector);
|
||||
+2
-1
@@ -33,6 +33,7 @@
|
||||
#include <asm/unaligned.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <crypto/internal/poly1305.h>
|
||||
#include <crypto/nhpoly1305.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -78,7 +79,7 @@ static void process_nh_hash_value(struct nhpoly1305_state *state,
|
||||
BUILD_BUG_ON(NH_HASH_BYTES % POLY1305_BLOCK_SIZE != 0);
|
||||
|
||||
poly1305_core_blocks(&state->poly_state, &key->poly_key, state->nh_hash,
|
||||
NH_HASH_BYTES / POLY1305_BLOCK_SIZE);
|
||||
NH_HASH_BYTES / POLY1305_BLOCK_SIZE, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+13
-215
@@ -13,158 +13,26 @@
|
||||
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <crypto/poly1305.h>
|
||||
#include <crypto/internal/poly1305.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
static inline u64 mlt(u64 a, u64 b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
static inline u32 sr(u64 v, u_char n)
|
||||
{
|
||||
return v >> n;
|
||||
}
|
||||
|
||||
static inline u32 and(u32 v, u32 mask)
|
||||
{
|
||||
return v & mask;
|
||||
}
|
||||
|
||||
int crypto_poly1305_init(struct shash_desc *desc)
|
||||
static int crypto_poly1305_init(struct shash_desc *desc)
|
||||
{
|
||||
struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
|
||||
|
||||
poly1305_core_init(&dctx->h);
|
||||
dctx->buflen = 0;
|
||||
dctx->rset = false;
|
||||
dctx->rset = 0;
|
||||
dctx->sset = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_poly1305_init);
|
||||
|
||||
void poly1305_core_setkey(struct poly1305_key *key, const u8 *raw_key)
|
||||
{
|
||||
/* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
|
||||
key->r[0] = (get_unaligned_le32(raw_key + 0) >> 0) & 0x3ffffff;
|
||||
key->r[1] = (get_unaligned_le32(raw_key + 3) >> 2) & 0x3ffff03;
|
||||
key->r[2] = (get_unaligned_le32(raw_key + 6) >> 4) & 0x3ffc0ff;
|
||||
key->r[3] = (get_unaligned_le32(raw_key + 9) >> 6) & 0x3f03fff;
|
||||
key->r[4] = (get_unaligned_le32(raw_key + 12) >> 8) & 0x00fffff;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(poly1305_core_setkey);
|
||||
|
||||
/*
|
||||
* Poly1305 requires a unique key for each tag, which implies that we can't set
|
||||
* it on the tfm that gets accessed by multiple users simultaneously. Instead we
|
||||
* expect the key as the first 32 bytes in the update() call.
|
||||
*/
|
||||
unsigned int crypto_poly1305_setdesckey(struct poly1305_desc_ctx *dctx,
|
||||
const u8 *src, unsigned int srclen)
|
||||
{
|
||||
if (!dctx->sset) {
|
||||
if (!dctx->rset && srclen >= POLY1305_BLOCK_SIZE) {
|
||||
poly1305_core_setkey(&dctx->r, src);
|
||||
src += POLY1305_BLOCK_SIZE;
|
||||
srclen -= POLY1305_BLOCK_SIZE;
|
||||
dctx->rset = true;
|
||||
}
|
||||
if (srclen >= POLY1305_BLOCK_SIZE) {
|
||||
dctx->s[0] = get_unaligned_le32(src + 0);
|
||||
dctx->s[1] = get_unaligned_le32(src + 4);
|
||||
dctx->s[2] = get_unaligned_le32(src + 8);
|
||||
dctx->s[3] = get_unaligned_le32(src + 12);
|
||||
src += POLY1305_BLOCK_SIZE;
|
||||
srclen -= POLY1305_BLOCK_SIZE;
|
||||
dctx->sset = true;
|
||||
}
|
||||
}
|
||||
return srclen;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_poly1305_setdesckey);
|
||||
|
||||
static void poly1305_blocks_internal(struct poly1305_state *state,
|
||||
const struct poly1305_key *key,
|
||||
const void *src, unsigned int nblocks,
|
||||
u32 hibit)
|
||||
{
|
||||
u32 r0, r1, r2, r3, r4;
|
||||
u32 s1, s2, s3, s4;
|
||||
u32 h0, h1, h2, h3, h4;
|
||||
u64 d0, d1, d2, d3, d4;
|
||||
|
||||
if (!nblocks)
|
||||
return;
|
||||
|
||||
r0 = key->r[0];
|
||||
r1 = key->r[1];
|
||||
r2 = key->r[2];
|
||||
r3 = key->r[3];
|
||||
r4 = key->r[4];
|
||||
|
||||
s1 = r1 * 5;
|
||||
s2 = r2 * 5;
|
||||
s3 = r3 * 5;
|
||||
s4 = r4 * 5;
|
||||
|
||||
h0 = state->h[0];
|
||||
h1 = state->h[1];
|
||||
h2 = state->h[2];
|
||||
h3 = state->h[3];
|
||||
h4 = state->h[4];
|
||||
|
||||
do {
|
||||
/* h += m[i] */
|
||||
h0 += (get_unaligned_le32(src + 0) >> 0) & 0x3ffffff;
|
||||
h1 += (get_unaligned_le32(src + 3) >> 2) & 0x3ffffff;
|
||||
h2 += (get_unaligned_le32(src + 6) >> 4) & 0x3ffffff;
|
||||
h3 += (get_unaligned_le32(src + 9) >> 6) & 0x3ffffff;
|
||||
h4 += (get_unaligned_le32(src + 12) >> 8) | hibit;
|
||||
|
||||
/* h *= r */
|
||||
d0 = mlt(h0, r0) + mlt(h1, s4) + mlt(h2, s3) +
|
||||
mlt(h3, s2) + mlt(h4, s1);
|
||||
d1 = mlt(h0, r1) + mlt(h1, r0) + mlt(h2, s4) +
|
||||
mlt(h3, s3) + mlt(h4, s2);
|
||||
d2 = mlt(h0, r2) + mlt(h1, r1) + mlt(h2, r0) +
|
||||
mlt(h3, s4) + mlt(h4, s3);
|
||||
d3 = mlt(h0, r3) + mlt(h1, r2) + mlt(h2, r1) +
|
||||
mlt(h3, r0) + mlt(h4, s4);
|
||||
d4 = mlt(h0, r4) + mlt(h1, r3) + mlt(h2, r2) +
|
||||
mlt(h3, r1) + mlt(h4, r0);
|
||||
|
||||
/* (partial) h %= p */
|
||||
d1 += sr(d0, 26); h0 = and(d0, 0x3ffffff);
|
||||
d2 += sr(d1, 26); h1 = and(d1, 0x3ffffff);
|
||||
d3 += sr(d2, 26); h2 = and(d2, 0x3ffffff);
|
||||
d4 += sr(d3, 26); h3 = and(d3, 0x3ffffff);
|
||||
h0 += sr(d4, 26) * 5; h4 = and(d4, 0x3ffffff);
|
||||
h1 += h0 >> 26; h0 = h0 & 0x3ffffff;
|
||||
|
||||
src += POLY1305_BLOCK_SIZE;
|
||||
} while (--nblocks);
|
||||
|
||||
state->h[0] = h0;
|
||||
state->h[1] = h1;
|
||||
state->h[2] = h2;
|
||||
state->h[3] = h3;
|
||||
state->h[4] = h4;
|
||||
}
|
||||
|
||||
void poly1305_core_blocks(struct poly1305_state *state,
|
||||
const struct poly1305_key *key,
|
||||
const void *src, unsigned int nblocks)
|
||||
{
|
||||
poly1305_blocks_internal(state, key, src, nblocks, 1 << 24);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(poly1305_core_blocks);
|
||||
|
||||
static void poly1305_blocks(struct poly1305_desc_ctx *dctx,
|
||||
const u8 *src, unsigned int srclen, u32 hibit)
|
||||
static void poly1305_blocks(struct poly1305_desc_ctx *dctx, const u8 *src,
|
||||
unsigned int srclen)
|
||||
{
|
||||
unsigned int datalen;
|
||||
|
||||
@@ -174,12 +42,12 @@ static void poly1305_blocks(struct poly1305_desc_ctx *dctx,
|
||||
srclen = datalen;
|
||||
}
|
||||
|
||||
poly1305_blocks_internal(&dctx->h, &dctx->r,
|
||||
src, srclen / POLY1305_BLOCK_SIZE, hibit);
|
||||
poly1305_core_blocks(&dctx->h, dctx->r, src,
|
||||
srclen / POLY1305_BLOCK_SIZE, 1);
|
||||
}
|
||||
|
||||
int crypto_poly1305_update(struct shash_desc *desc,
|
||||
const u8 *src, unsigned int srclen)
|
||||
static int crypto_poly1305_update(struct shash_desc *desc,
|
||||
const u8 *src, unsigned int srclen)
|
||||
{
|
||||
struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
|
||||
unsigned int bytes;
|
||||
@@ -193,13 +61,13 @@ int crypto_poly1305_update(struct shash_desc *desc,
|
||||
|
||||
if (dctx->buflen == POLY1305_BLOCK_SIZE) {
|
||||
poly1305_blocks(dctx, dctx->buf,
|
||||
POLY1305_BLOCK_SIZE, 1 << 24);
|
||||
POLY1305_BLOCK_SIZE);
|
||||
dctx->buflen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (likely(srclen >= POLY1305_BLOCK_SIZE)) {
|
||||
poly1305_blocks(dctx, src, srclen, 1 << 24);
|
||||
poly1305_blocks(dctx, src, srclen);
|
||||
src += srclen - (srclen % POLY1305_BLOCK_SIZE);
|
||||
srclen %= POLY1305_BLOCK_SIZE;
|
||||
}
|
||||
@@ -211,87 +79,17 @@ int crypto_poly1305_update(struct shash_desc *desc,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_poly1305_update);
|
||||
|
||||
void poly1305_core_emit(const struct poly1305_state *state, void *dst)
|
||||
{
|
||||
u32 h0, h1, h2, h3, h4;
|
||||
u32 g0, g1, g2, g3, g4;
|
||||
u32 mask;
|
||||
|
||||
/* fully carry h */
|
||||
h0 = state->h[0];
|
||||
h1 = state->h[1];
|
||||
h2 = state->h[2];
|
||||
h3 = state->h[3];
|
||||
h4 = state->h[4];
|
||||
|
||||
h2 += (h1 >> 26); h1 = h1 & 0x3ffffff;
|
||||
h3 += (h2 >> 26); h2 = h2 & 0x3ffffff;
|
||||
h4 += (h3 >> 26); h3 = h3 & 0x3ffffff;
|
||||
h0 += (h4 >> 26) * 5; h4 = h4 & 0x3ffffff;
|
||||
h1 += (h0 >> 26); h0 = h0 & 0x3ffffff;
|
||||
|
||||
/* compute h + -p */
|
||||
g0 = h0 + 5;
|
||||
g1 = h1 + (g0 >> 26); g0 &= 0x3ffffff;
|
||||
g2 = h2 + (g1 >> 26); g1 &= 0x3ffffff;
|
||||
g3 = h3 + (g2 >> 26); g2 &= 0x3ffffff;
|
||||
g4 = h4 + (g3 >> 26) - (1 << 26); g3 &= 0x3ffffff;
|
||||
|
||||
/* select h if h < p, or h + -p if h >= p */
|
||||
mask = (g4 >> ((sizeof(u32) * 8) - 1)) - 1;
|
||||
g0 &= mask;
|
||||
g1 &= mask;
|
||||
g2 &= mask;
|
||||
g3 &= mask;
|
||||
g4 &= mask;
|
||||
mask = ~mask;
|
||||
h0 = (h0 & mask) | g0;
|
||||
h1 = (h1 & mask) | g1;
|
||||
h2 = (h2 & mask) | g2;
|
||||
h3 = (h3 & mask) | g3;
|
||||
h4 = (h4 & mask) | g4;
|
||||
|
||||
/* h = h % (2^128) */
|
||||
put_unaligned_le32((h0 >> 0) | (h1 << 26), dst + 0);
|
||||
put_unaligned_le32((h1 >> 6) | (h2 << 20), dst + 4);
|
||||
put_unaligned_le32((h2 >> 12) | (h3 << 14), dst + 8);
|
||||
put_unaligned_le32((h3 >> 18) | (h4 << 8), dst + 12);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(poly1305_core_emit);
|
||||
|
||||
int crypto_poly1305_final(struct shash_desc *desc, u8 *dst)
|
||||
static int crypto_poly1305_final(struct shash_desc *desc, u8 *dst)
|
||||
{
|
||||
struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc);
|
||||
__le32 digest[4];
|
||||
u64 f = 0;
|
||||
|
||||
if (unlikely(!dctx->sset))
|
||||
return -ENOKEY;
|
||||
|
||||
if (unlikely(dctx->buflen)) {
|
||||
dctx->buf[dctx->buflen++] = 1;
|
||||
memset(dctx->buf + dctx->buflen, 0,
|
||||
POLY1305_BLOCK_SIZE - dctx->buflen);
|
||||
poly1305_blocks(dctx, dctx->buf, POLY1305_BLOCK_SIZE, 0);
|
||||
}
|
||||
|
||||
poly1305_core_emit(&dctx->h, digest);
|
||||
|
||||
/* mac = (h + s) % (2^128) */
|
||||
f = (f >> 32) + le32_to_cpu(digest[0]) + dctx->s[0];
|
||||
put_unaligned_le32(f, dst + 0);
|
||||
f = (f >> 32) + le32_to_cpu(digest[1]) + dctx->s[1];
|
||||
put_unaligned_le32(f, dst + 4);
|
||||
f = (f >> 32) + le32_to_cpu(digest[2]) + dctx->s[2];
|
||||
put_unaligned_le32(f, dst + 8);
|
||||
f = (f >> 32) + le32_to_cpu(digest[3]) + dctx->s[3];
|
||||
put_unaligned_le32(f, dst + 12);
|
||||
|
||||
poly1305_final_generic(dctx, dst);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_poly1305_final);
|
||||
|
||||
static struct shash_alg poly1305_alg = {
|
||||
.digestsize = POLY1305_DIGEST_SIZE,
|
||||
|
||||
+9
-221
@@ -580,12 +580,6 @@ EXPORT_SYMBOL_GPL(skcipher_walk_aead_decrypt);
|
||||
|
||||
static unsigned int crypto_skcipher_extsize(struct crypto_alg *alg)
|
||||
{
|
||||
if (alg->cra_type == &crypto_blkcipher_type)
|
||||
return sizeof(struct crypto_blkcipher *);
|
||||
|
||||
if (alg->cra_type == &crypto_ablkcipher_type)
|
||||
return sizeof(struct crypto_ablkcipher *);
|
||||
|
||||
return crypto_alg_extsize(alg);
|
||||
}
|
||||
|
||||
@@ -595,205 +589,6 @@ static void skcipher_set_needkey(struct crypto_skcipher *tfm)
|
||||
crypto_skcipher_set_flags(tfm, CRYPTO_TFM_NEED_KEY);
|
||||
}
|
||||
|
||||
static int skcipher_setkey_blkcipher(struct crypto_skcipher *tfm,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
struct crypto_blkcipher **ctx = crypto_skcipher_ctx(tfm);
|
||||
struct crypto_blkcipher *blkcipher = *ctx;
|
||||
int err;
|
||||
|
||||
crypto_blkcipher_clear_flags(blkcipher, ~0);
|
||||
crypto_blkcipher_set_flags(blkcipher, crypto_skcipher_get_flags(tfm) &
|
||||
CRYPTO_TFM_REQ_MASK);
|
||||
err = crypto_blkcipher_setkey(blkcipher, key, keylen);
|
||||
crypto_skcipher_set_flags(tfm, crypto_blkcipher_get_flags(blkcipher) &
|
||||
CRYPTO_TFM_RES_MASK);
|
||||
if (unlikely(err)) {
|
||||
skcipher_set_needkey(tfm);
|
||||
return err;
|
||||
}
|
||||
|
||||
crypto_skcipher_clear_flags(tfm, CRYPTO_TFM_NEED_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skcipher_crypt_blkcipher(struct skcipher_request *req,
|
||||
int (*crypt)(struct blkcipher_desc *,
|
||||
struct scatterlist *,
|
||||
struct scatterlist *,
|
||||
unsigned int))
|
||||
{
|
||||
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
||||
struct crypto_blkcipher **ctx = crypto_skcipher_ctx(tfm);
|
||||
struct blkcipher_desc desc = {
|
||||
.tfm = *ctx,
|
||||
.info = req->iv,
|
||||
.flags = req->base.flags,
|
||||
};
|
||||
|
||||
|
||||
return crypt(&desc, req->dst, req->src, req->cryptlen);
|
||||
}
|
||||
|
||||
static int skcipher_encrypt_blkcipher(struct skcipher_request *req)
|
||||
{
|
||||
struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
|
||||
struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher);
|
||||
struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
|
||||
|
||||
return skcipher_crypt_blkcipher(req, alg->encrypt);
|
||||
}
|
||||
|
||||
static int skcipher_decrypt_blkcipher(struct skcipher_request *req)
|
||||
{
|
||||
struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
|
||||
struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher);
|
||||
struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
|
||||
|
||||
return skcipher_crypt_blkcipher(req, alg->decrypt);
|
||||
}
|
||||
|
||||
static void crypto_exit_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crypto_blkcipher **ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
crypto_free_blkcipher(*ctx);
|
||||
}
|
||||
|
||||
static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crypto_alg *calg = tfm->__crt_alg;
|
||||
struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm);
|
||||
struct crypto_blkcipher **ctx = crypto_tfm_ctx(tfm);
|
||||
struct crypto_blkcipher *blkcipher;
|
||||
struct crypto_tfm *btfm;
|
||||
|
||||
if (!crypto_mod_get(calg))
|
||||
return -EAGAIN;
|
||||
|
||||
btfm = __crypto_alloc_tfm(calg, CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
CRYPTO_ALG_TYPE_MASK);
|
||||
if (IS_ERR(btfm)) {
|
||||
crypto_mod_put(calg);
|
||||
return PTR_ERR(btfm);
|
||||
}
|
||||
|
||||
blkcipher = __crypto_blkcipher_cast(btfm);
|
||||
*ctx = blkcipher;
|
||||
tfm->exit = crypto_exit_skcipher_ops_blkcipher;
|
||||
|
||||
skcipher->setkey = skcipher_setkey_blkcipher;
|
||||
skcipher->encrypt = skcipher_encrypt_blkcipher;
|
||||
skcipher->decrypt = skcipher_decrypt_blkcipher;
|
||||
|
||||
skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher);
|
||||
skcipher->keysize = calg->cra_blkcipher.max_keysize;
|
||||
|
||||
skcipher_set_needkey(skcipher);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skcipher_setkey_ablkcipher(struct crypto_skcipher *tfm,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
struct crypto_ablkcipher **ctx = crypto_skcipher_ctx(tfm);
|
||||
struct crypto_ablkcipher *ablkcipher = *ctx;
|
||||
int err;
|
||||
|
||||
crypto_ablkcipher_clear_flags(ablkcipher, ~0);
|
||||
crypto_ablkcipher_set_flags(ablkcipher,
|
||||
crypto_skcipher_get_flags(tfm) &
|
||||
CRYPTO_TFM_REQ_MASK);
|
||||
err = crypto_ablkcipher_setkey(ablkcipher, key, keylen);
|
||||
crypto_skcipher_set_flags(tfm,
|
||||
crypto_ablkcipher_get_flags(ablkcipher) &
|
||||
CRYPTO_TFM_RES_MASK);
|
||||
if (unlikely(err)) {
|
||||
skcipher_set_needkey(tfm);
|
||||
return err;
|
||||
}
|
||||
|
||||
crypto_skcipher_clear_flags(tfm, CRYPTO_TFM_NEED_KEY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skcipher_crypt_ablkcipher(struct skcipher_request *req,
|
||||
int (*crypt)(struct ablkcipher_request *))
|
||||
{
|
||||
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
|
||||
struct crypto_ablkcipher **ctx = crypto_skcipher_ctx(tfm);
|
||||
struct ablkcipher_request *subreq = skcipher_request_ctx(req);
|
||||
|
||||
ablkcipher_request_set_tfm(subreq, *ctx);
|
||||
ablkcipher_request_set_callback(subreq, skcipher_request_flags(req),
|
||||
req->base.complete, req->base.data);
|
||||
ablkcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
|
||||
req->iv);
|
||||
|
||||
return crypt(subreq);
|
||||
}
|
||||
|
||||
static int skcipher_encrypt_ablkcipher(struct skcipher_request *req)
|
||||
{
|
||||
struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
|
||||
struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher);
|
||||
struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher;
|
||||
|
||||
return skcipher_crypt_ablkcipher(req, alg->encrypt);
|
||||
}
|
||||
|
||||
static int skcipher_decrypt_ablkcipher(struct skcipher_request *req)
|
||||
{
|
||||
struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
|
||||
struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher);
|
||||
struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher;
|
||||
|
||||
return skcipher_crypt_ablkcipher(req, alg->decrypt);
|
||||
}
|
||||
|
||||
static void crypto_exit_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crypto_ablkcipher **ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
crypto_free_ablkcipher(*ctx);
|
||||
}
|
||||
|
||||
static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct crypto_alg *calg = tfm->__crt_alg;
|
||||
struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm);
|
||||
struct crypto_ablkcipher **ctx = crypto_tfm_ctx(tfm);
|
||||
struct crypto_ablkcipher *ablkcipher;
|
||||
struct crypto_tfm *abtfm;
|
||||
|
||||
if (!crypto_mod_get(calg))
|
||||
return -EAGAIN;
|
||||
|
||||
abtfm = __crypto_alloc_tfm(calg, 0, 0);
|
||||
if (IS_ERR(abtfm)) {
|
||||
crypto_mod_put(calg);
|
||||
return PTR_ERR(abtfm);
|
||||
}
|
||||
|
||||
ablkcipher = __crypto_ablkcipher_cast(abtfm);
|
||||
*ctx = ablkcipher;
|
||||
tfm->exit = crypto_exit_skcipher_ops_ablkcipher;
|
||||
|
||||
skcipher->setkey = skcipher_setkey_ablkcipher;
|
||||
skcipher->encrypt = skcipher_encrypt_ablkcipher;
|
||||
skcipher->decrypt = skcipher_decrypt_ablkcipher;
|
||||
|
||||
skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher);
|
||||
skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) +
|
||||
sizeof(struct ablkcipher_request);
|
||||
skcipher->keysize = calg->cra_ablkcipher.max_keysize;
|
||||
|
||||
skcipher_set_needkey(skcipher);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int skcipher_setkey_unaligned(struct crypto_skcipher *tfm,
|
||||
const u8 *key, unsigned int keylen)
|
||||
{
|
||||
@@ -888,12 +683,6 @@ static int crypto_skcipher_init_tfm(struct crypto_tfm *tfm)
|
||||
struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm);
|
||||
struct skcipher_alg *alg = crypto_skcipher_alg(skcipher);
|
||||
|
||||
if (tfm->__crt_alg->cra_type == &crypto_blkcipher_type)
|
||||
return crypto_init_skcipher_ops_blkcipher(tfm);
|
||||
|
||||
if (tfm->__crt_alg->cra_type == &crypto_ablkcipher_type)
|
||||
return crypto_init_skcipher_ops_ablkcipher(tfm);
|
||||
|
||||
skcipher->setkey = skcipher_setkey;
|
||||
skcipher->encrypt = alg->encrypt;
|
||||
skcipher->decrypt = alg->decrypt;
|
||||
@@ -964,7 +753,7 @@ static int crypto_skcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct crypto_type crypto_skcipher_type2 = {
|
||||
static const struct crypto_type crypto_skcipher_type = {
|
||||
.extsize = crypto_skcipher_extsize,
|
||||
.init_tfm = crypto_skcipher_init_tfm,
|
||||
.free = crypto_skcipher_free_instance,
|
||||
@@ -973,7 +762,7 @@ static const struct crypto_type crypto_skcipher_type2 = {
|
||||
#endif
|
||||
.report = crypto_skcipher_report,
|
||||
.maskclear = ~CRYPTO_ALG_TYPE_MASK,
|
||||
.maskset = CRYPTO_ALG_TYPE_BLKCIPHER_MASK,
|
||||
.maskset = CRYPTO_ALG_TYPE_MASK,
|
||||
.type = CRYPTO_ALG_TYPE_SKCIPHER,
|
||||
.tfmsize = offsetof(struct crypto_skcipher, base),
|
||||
};
|
||||
@@ -981,7 +770,7 @@ static const struct crypto_type crypto_skcipher_type2 = {
|
||||
int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn,
|
||||
const char *name, u32 type, u32 mask)
|
||||
{
|
||||
spawn->base.frontend = &crypto_skcipher_type2;
|
||||
spawn->base.frontend = &crypto_skcipher_type;
|
||||
return crypto_grab_spawn(&spawn->base, name, type, mask);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_grab_skcipher);
|
||||
@@ -989,7 +778,7 @@ EXPORT_SYMBOL_GPL(crypto_grab_skcipher);
|
||||
struct crypto_skcipher *crypto_alloc_skcipher(const char *alg_name,
|
||||
u32 type, u32 mask)
|
||||
{
|
||||
return crypto_alloc_tfm(alg_name, &crypto_skcipher_type2, type, mask);
|
||||
return crypto_alloc_tfm(alg_name, &crypto_skcipher_type, type, mask);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_alloc_skcipher);
|
||||
|
||||
@@ -1001,7 +790,7 @@ struct crypto_sync_skcipher *crypto_alloc_sync_skcipher(
|
||||
/* Only sync algorithms allowed. */
|
||||
mask |= CRYPTO_ALG_ASYNC;
|
||||
|
||||
tfm = crypto_alloc_tfm(alg_name, &crypto_skcipher_type2, type, mask);
|
||||
tfm = crypto_alloc_tfm(alg_name, &crypto_skcipher_type, type, mask);
|
||||
|
||||
/*
|
||||
* Make sure we do not allocate something that might get used with
|
||||
@@ -1017,12 +806,11 @@ struct crypto_sync_skcipher *crypto_alloc_sync_skcipher(
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_alloc_sync_skcipher);
|
||||
|
||||
int crypto_has_skcipher2(const char *alg_name, u32 type, u32 mask)
|
||||
int crypto_has_skcipher(const char *alg_name, u32 type, u32 mask)
|
||||
{
|
||||
return crypto_type_has_alg(alg_name, &crypto_skcipher_type2,
|
||||
type, mask);
|
||||
return crypto_type_has_alg(alg_name, &crypto_skcipher_type, type, mask);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_has_skcipher2);
|
||||
EXPORT_SYMBOL_GPL(crypto_has_skcipher);
|
||||
|
||||
static int skcipher_prepare_alg(struct skcipher_alg *alg)
|
||||
{
|
||||
@@ -1037,7 +825,7 @@ static int skcipher_prepare_alg(struct skcipher_alg *alg)
|
||||
if (!alg->walksize)
|
||||
alg->walksize = alg->chunksize;
|
||||
|
||||
base->cra_type = &crypto_skcipher_type2;
|
||||
base->cra_type = &crypto_skcipher_type;
|
||||
base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
|
||||
base->cra_flags |= CRYPTO_ALG_TYPE_SKCIPHER;
|
||||
|
||||
|
||||
+2
-2
@@ -65,7 +65,7 @@ static int mode;
|
||||
static u32 num_mb = 8;
|
||||
static char *tvmem[TVMEMSIZE];
|
||||
|
||||
static char *check[] = {
|
||||
static const char *check[] = {
|
||||
"des", "md5", "des3_ede", "rot13", "sha1", "sha224", "sha256", "sm3",
|
||||
"blowfish", "twofish", "serpent", "sha384", "sha512", "md4", "aes",
|
||||
"cast6", "arc4", "michael_mic", "deflate", "crc32c", "tea", "xtea",
|
||||
@@ -1634,7 +1634,7 @@ static void test_cipher_speed(const char *algo, int enc, unsigned int secs,
|
||||
|
||||
static void test_available(void)
|
||||
{
|
||||
char **name = check;
|
||||
const char **name = check;
|
||||
|
||||
while (*name) {
|
||||
printk("alg %s ", *name);
|
||||
|
||||
@@ -4022,6 +4022,58 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
.alg = "authenc(hmac(sha512),rfc3686(ctr(aes)))",
|
||||
.test = alg_test_null,
|
||||
.fips_allowed = 1,
|
||||
}, {
|
||||
.alg = "blake2b-160",
|
||||
.test = alg_test_hash,
|
||||
.fips_allowed = 0,
|
||||
.suite = {
|
||||
.hash = __VECS(blake2b_160_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "blake2b-256",
|
||||
.test = alg_test_hash,
|
||||
.fips_allowed = 0,
|
||||
.suite = {
|
||||
.hash = __VECS(blake2b_256_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "blake2b-384",
|
||||
.test = alg_test_hash,
|
||||
.fips_allowed = 0,
|
||||
.suite = {
|
||||
.hash = __VECS(blake2b_384_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "blake2b-512",
|
||||
.test = alg_test_hash,
|
||||
.fips_allowed = 0,
|
||||
.suite = {
|
||||
.hash = __VECS(blake2b_512_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "blake2s-128",
|
||||
.test = alg_test_hash,
|
||||
.suite = {
|
||||
.hash = __VECS(blakes2s_128_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "blake2s-160",
|
||||
.test = alg_test_hash,
|
||||
.suite = {
|
||||
.hash = __VECS(blakes2s_160_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "blake2s-224",
|
||||
.test = alg_test_hash,
|
||||
.suite = {
|
||||
.hash = __VECS(blakes2s_224_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "blake2s-256",
|
||||
.test = alg_test_hash,
|
||||
.suite = {
|
||||
.hash = __VECS(blakes2s_256_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "cbc(aes)",
|
||||
.test = alg_test_skcipher,
|
||||
@@ -4125,6 +4177,12 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
.suite = {
|
||||
.cipher = __VECS(aes_cfb_tv_template)
|
||||
},
|
||||
}, {
|
||||
.alg = "cfb(sm4)",
|
||||
.test = alg_test_skcipher,
|
||||
.suite = {
|
||||
.cipher = __VECS(sm4_cfb_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "chacha20",
|
||||
.test = alg_test_skcipher,
|
||||
@@ -4259,6 +4317,12 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
.alg = "cts(cbc(paes))",
|
||||
.test = alg_test_null,
|
||||
.fips_allowed = 1,
|
||||
}, {
|
||||
.alg = "curve25519",
|
||||
.test = alg_test_kpp,
|
||||
.suite = {
|
||||
.kpp = __VECS(curve25519_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "deflate",
|
||||
.test = alg_test_comp,
|
||||
@@ -4654,6 +4718,12 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
.suite = {
|
||||
.hash = __VECS(hmac_sha512_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "hmac(sm3)",
|
||||
.test = alg_test_hash,
|
||||
.suite = {
|
||||
.hash = __VECS(hmac_sm3_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "hmac(streebog256)",
|
||||
.test = alg_test_hash,
|
||||
@@ -4790,6 +4860,12 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
.alg = "ofb(paes)",
|
||||
.test = alg_test_null,
|
||||
.fips_allowed = 1,
|
||||
}, {
|
||||
.alg = "ofb(sm4)",
|
||||
.test = alg_test_skcipher,
|
||||
.suite = {
|
||||
.cipher = __VECS(sm4_ofb_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "pcbc(fcrypt)",
|
||||
.test = alg_test_skcipher,
|
||||
@@ -4828,6 +4904,12 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
.suite = {
|
||||
.cipher = __VECS(aes_ctr_rfc3686_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "rfc3686(ctr(sm4))",
|
||||
.test = alg_test_skcipher,
|
||||
.suite = {
|
||||
.cipher = __VECS(sm4_ctr_rfc3686_tv_template)
|
||||
}
|
||||
}, {
|
||||
.alg = "rfc4106(gcm(aes))",
|
||||
.generic_driver = "rfc4106(gcm_base(ctr(aes-generic),ghash-generic))",
|
||||
|
||||
+2124
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -555,7 +555,7 @@ static int tgr192_final(struct shash_desc *desc, u8 * out)
|
||||
__le32 *le32p;
|
||||
u32 t, msb, lsb;
|
||||
|
||||
tgr192_update(desc, NULL, 0); /* flush */ ;
|
||||
tgr192_update(desc, NULL, 0); /* flush */
|
||||
|
||||
msb = 0;
|
||||
t = tctx->nblocks;
|
||||
@@ -583,7 +583,7 @@ static int tgr192_final(struct shash_desc *desc, u8 * out)
|
||||
while (tctx->count < 64) {
|
||||
tctx->hash[tctx->count++] = 0;
|
||||
}
|
||||
tgr192_update(desc, NULL, 0); /* flush */ ;
|
||||
tgr192_update(desc, NULL, 0); /* flush */
|
||||
memset(tctx->hash, 0, 56); /* fill next block with zeroes */
|
||||
}
|
||||
/* append the 64 bit count */
|
||||
|
||||
Reference in New Issue
Block a user