aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--crypto/Kconfig2100
-rw-r--r--crypto/Makefile41
-rw-r--r--crypto/acompress.c8
-rw-r--r--crypto/adiantum.c18
-rw-r--r--crypto/aegis.h19
-rw-r--r--crypto/aegis128-core.c250
-rw-r--r--crypto/aegis128-neon-inner.c122
-rw-r--r--crypto/aegis128-neon.c29
-rw-r--r--crypto/af_alg.c199
-rw-r--r--crypto/ahash.c58
-rw-r--r--crypto/akcipher.c8
-rw-r--r--crypto/algapi.c272
-rw-r--r--crypto/algboss.c37
-rw-r--r--crypto/algif_aead.c32
-rw-r--r--crypto/algif_hash.c24
-rw-r--r--crypto/algif_rng.c177
-rw-r--r--crypto/algif_skcipher.c32
-rw-r--r--crypto/ansi_cprng.c2
-rw-r--r--crypto/api.c105
-rw-r--r--crypto/arc4.c11
-rw-r--r--crypto/aria_generic.c313
-rw-r--r--crypto/asymmetric_keys/Kconfig31
-rw-r--r--crypto/asymmetric_keys/Makefile14
-rw-r--r--crypto/asymmetric_keys/asym_tpm.c957
-rw-r--r--crypto/asymmetric_keys/asymmetric_type.c65
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.c26
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.h5
-rw-r--r--crypto/asymmetric_keys/pkcs7_trust.c8
-rw-r--r--crypto/asymmetric_keys/pkcs7_verify.c22
-rw-r--r--crypto/asymmetric_keys/public_key.c196
-rw-r--r--crypto/asymmetric_keys/restrict.c55
-rw-r--r--crypto/asymmetric_keys/selftest.c224
-rw-r--r--crypto/asymmetric_keys/signature.c4
-rw-r--r--crypto/asymmetric_keys/tpm.asn15
-rw-r--r--crypto/asymmetric_keys/tpm_parser.c102
-rw-r--r--crypto/asymmetric_keys/verify_pefile.c4
-rw-r--r--crypto/asymmetric_keys/x509.asn12
-rw-r--r--crypto/asymmetric_keys/x509_cert_parser.c115
-rw-r--r--crypto/asymmetric_keys/x509_loader.c57
-rw-r--r--crypto/asymmetric_keys/x509_parser.h12
-rw-r--r--crypto/asymmetric_keys/x509_public_key.c44
-rw-r--r--crypto/async_tx/async_pq.c72
-rw-r--r--crypto/async_tx/async_raid6_recov.c163
-rw-r--r--crypto/async_tx/async_xor.c126
-rw-r--r--crypto/async_tx/raid6test.c34
-rw-r--r--crypto/authenc.c16
-rw-r--r--crypto/authencesn.c16
-rw-r--r--crypto/blake2b_generic.c253
-rw-r--r--crypto/blake2s_generic.c169
-rw-r--r--crypto/blowfish_generic.c23
-rw-r--r--crypto/camellia_generic.c47
-rw-r--r--crypto/cast5_generic.c23
-rw-r--r--crypto/cast6_generic.c39
-rw-r--r--crypto/cbc.c145
-rw-r--r--crypto/ccm.c64
-rw-r--r--crypto/cfb.c4
-rw-r--r--crypto/chacha20poly1305.c14
-rw-r--r--crypto/cipher.c7
-rw-r--r--crypto/cmac.c7
-rw-r--r--crypto/crc32_generic.c24
-rw-r--r--crypto/crc32c_generic.c4
-rw-r--r--crypto/crc64_rocksoft_generic.c89
-rw-r--r--crypto/crct10dif_generic.c2
-rw-r--r--crypto/cryptd.c119
-rw-r--r--crypto/crypto_engine.c200
-rw-r--r--crypto/ctr.c48
-rw-r--r--crypto/cts.c40
-rw-r--r--crypto/curve25519-generic.c4
-rw-r--r--crypto/deflate.c2
-rw-r--r--crypto/dh.c726
-rw-r--r--crypto/dh_helper.c42
-rw-r--r--crypto/drbg.c218
-rw-r--r--crypto/ecb.c1
-rw-r--r--crypto/ecc.c357
-rw-r--r--crypto/ecc_curve_defs.h49
-rw-r--r--crypto/ecdh.c135
-rw-r--r--crypto/ecdh_helper.c7
-rw-r--r--crypto/ecdsa.c376
-rw-r--r--crypto/ecdsasignature.asn14
-rw-r--r--crypto/echainiv.c2
-rw-r--r--crypto/ecrdsa.c11
-rw-r--r--crypto/ecrdsa_defs.h2
-rw-r--r--crypto/essiv.c19
-rw-r--r--crypto/fcrypt.c6
-rw-r--r--crypto/fips.c35
-rw-r--r--crypto/gcm.c108
-rw-r--r--crypto/geniv.c34
-rw-r--r--crypto/gf128mul.c4
-rw-r--r--crypto/hctr2.c581
-rw-r--r--crypto/hmac.c9
-rw-r--r--crypto/internal.h62
-rw-r--r--crypto/jitterentropy-kcapi.c37
-rw-r--r--crypto/jitterentropy.c459
-rw-r--r--crypto/jitterentropy.h1
-rw-r--r--crypto/kdf_sp800108.c153
-rw-r--r--crypto/keywrap.c6
-rw-r--r--crypto/khazad.c2
-rw-r--r--crypto/kpp.c35
-rw-r--r--crypto/lrw.c161
-rw-r--r--crypto/md5.c3
-rw-r--r--crypto/michael_mic.c31
-rw-r--r--crypto/ofb.c2
-rw-r--r--crypto/pcbc.c2
-rw-r--r--crypto/pcrypt.c74
-rw-r--r--crypto/polyval-generic.c245
-rw-r--r--crypto/proc.c6
-rw-r--r--crypto/ripemd.h14
-rw-r--r--crypto/rmd128.c323
-rw-r--r--crypto/rmd256.c342
-rw-r--r--crypto/rmd320.c391
-rw-r--r--crypto/rng.c4
-rw-r--r--crypto/rsa-pkcs1pad.c117
-rw-r--r--crypto/rsa.c86
-rw-r--r--crypto/salsa20_generic.c212
-rw-r--r--crypto/seed.c2
-rw-r--r--crypto/seqiv.c20
-rw-r--r--crypto/serpent_generic.c165
-rw-r--r--crypto/sha1_generic.c7
-rw-r--r--crypto/sha256_generic.c24
-rw-r--r--crypto/sha3_generic.c2
-rw-r--r--crypto/sha512_generic.c5
-rw-r--r--crypto/shash.c42
-rw-r--r--crypto/simd.c6
-rw-r--r--crypto/skcipher.c25
-rw-r--r--crypto/sm2.c460
-rw-r--r--crypto/sm2signature.asn14
-rw-r--r--crypto/sm3.c246
-rw-r--r--crypto/sm3_generic.c143
-rw-r--r--crypto/sm4.c184
-rw-r--r--crypto/sm4_generic.c180
-rw-r--r--crypto/tcrypt.c712
-rw-r--r--crypto/tcrypt.h29
-rw-r--r--crypto/testmgr.c696
-rw-r--r--crypto/testmgr.h8702
-rw-r--r--crypto/tgr192.c682
-rw-r--r--crypto/twofish_common.c2
-rw-r--r--crypto/twofish_generic.c11
-rw-r--r--crypto/vmac.c7
-rw-r--r--crypto/wp512.c42
-rw-r--r--crypto/xcbc.c7
-rw-r--r--crypto/xctr.c191
-rw-r--r--crypto/xor.c73
-rw-r--r--crypto/xts.c183
-rw-r--r--crypto/zstd.c30
-rw-r--r--include/crypto/internal/ecc.h (renamed from crypto/ecc.h)100
-rw-r--r--lib/crypto/memneq.c (renamed from crypto/memneq.c)27
146 files changed, 16122 insertions, 9940 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig
index c24a47406f8f..d779667671b2 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -15,12 +15,13 @@ source "crypto/async_tx/Kconfig"
#
menuconfig CRYPTO
tristate "Cryptographic API"
+ select CRYPTO_LIB_UTILS
help
This option provides the core Cryptographic API.
if CRYPTO
-comment "Crypto core or helper"
+menu "Crypto core or helper"
config CRYPTO_FIPS
bool "FIPS 200 compliance"
@@ -32,6 +33,27 @@ config CRYPTO_FIPS
certification. You should say no unless you know what
this is.
+config CRYPTO_FIPS_NAME
+ string "FIPS Module Name"
+ default "Linux Kernel Cryptographic API"
+ depends on CRYPTO_FIPS
+ help
+ This option sets the FIPS Module name reported by the Crypto API via
+ the /proc/sys/crypto/fips_name file.
+
+config CRYPTO_FIPS_CUSTOM_VERSION
+ bool "Use Custom FIPS Module Version"
+ depends on CRYPTO_FIPS
+ default n
+
+config CRYPTO_FIPS_VERSION
+ string "FIPS Module Version"
+ default "(none)"
+ depends on CRYPTO_FIPS_CUSTOM_VERSION
+ help
+ This option provides the ability to override the FIPS Module Version.
+ By default the KERNELRELEASE value is used.
+
config CRYPTO_ALGAPI
tristate
select CRYPTO_ALGAPI2
@@ -145,7 +167,7 @@ config CRYPTO_MANAGER_DISABLE_TESTS
config CRYPTO_MANAGER_EXTRA_TESTS
bool "Enable extra run-time crypto self tests"
- depends on DEBUG_KERNEL && !CRYPTO_MANAGER_DISABLE_TESTS
+ depends on DEBUG_KERNEL && !CRYPTO_MANAGER_DISABLE_TESTS && CRYPTO_MANAGER
help
Enable extra run-time self tests of registered crypto algorithms,
including randomized fuzz tests.
@@ -197,11 +219,12 @@ config CRYPTO_AUTHENC
select CRYPTO_NULL
help
Authenc: Combined mode wrapper for IPsec.
- This is required for IPSec.
+
+ This is required for IPSec ESP (XFRM_ESP).
config CRYPTO_TEST
tristate "Testing module"
- depends on m
+ depends on m || EXPERT
select CRYPTO_MANAGER
help
Quick & dirty crypto test module.
@@ -210,45 +233,68 @@ config CRYPTO_SIMD
tristate
select CRYPTO_CRYPTD
-config CRYPTO_GLUE_HELPER_X86
- tristate
- depends on X86
- select CRYPTO_SKCIPHER
-
config CRYPTO_ENGINE
tristate
-comment "Public-key cryptography"
+endmenu
+
+menu "Public-key cryptography"
config CRYPTO_RSA
- tristate "RSA algorithm"
+ tristate "RSA (Rivest-Shamir-Adleman)"
select CRYPTO_AKCIPHER
select CRYPTO_MANAGER
select MPILIB
select ASN1
help
- Generic implementation of the RSA public key algorithm.
+ RSA (Rivest-Shamir-Adleman) public key algorithm (RFC8017)
config CRYPTO_DH
- tristate "Diffie-Hellman algorithm"
+ tristate "DH (Diffie-Hellman)"
select CRYPTO_KPP
select MPILIB
help
- Generic implementation of the Diffie-Hellman algorithm.
+ DH (Diffie-Hellman) key exchange algorithm
+
+config CRYPTO_DH_RFC7919_GROUPS
+ bool "RFC 7919 FFDHE groups"
+ depends on CRYPTO_DH
+ select CRYPTO_RNG_DEFAULT
+ help
+ FFDHE (Finite-Field-based Diffie-Hellman Ephemeral) groups
+ defined in RFC7919.
+
+ Support these finite-field groups in DH key exchanges:
+ - ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192
+
+ If unsure, say N.
config CRYPTO_ECC
tristate
+ select CRYPTO_RNG_DEFAULT
config CRYPTO_ECDH
- tristate "ECDH algorithm"
+ tristate "ECDH (Elliptic Curve Diffie-Hellman)"
select CRYPTO_ECC
select CRYPTO_KPP
- select CRYPTO_RNG_DEFAULT
help
- Generic implementation of the ECDH algorithm
+ ECDH (Elliptic Curve Diffie-Hellman) key exchange algorithm
+ using curves P-192, P-256, and P-384 (FIPS 186)
+
+config CRYPTO_ECDSA
+ tristate "ECDSA (Elliptic Curve Digital Signature Algorithm)"
+ select CRYPTO_ECC
+ select CRYPTO_AKCIPHER
+ select ASN1
+ help
+ ECDSA (Elliptic Curve Digital Signature Algorithm) (FIPS 186,
+ ISO/IEC 14888-3)
+ using curves P-192, P-256, and P-384
+
+ Only signature verification is implemented.
config CRYPTO_ECRDSA
- tristate "EC-RDSA (GOST 34.10) algorithm"
+ tristate "EC-RDSA (Elliptic Curve Russian Digital Signature Algorithm)"
select CRYPTO_ECC
select CRYPTO_AKCIPHER
select CRYPTO_STREEBOG
@@ -256,168 +302,441 @@ config CRYPTO_ECRDSA
select ASN1
help
Elliptic Curve Russian Digital Signature Algorithm (GOST R 34.10-2012,
- RFC 7091, ISO/IEC 14888-3:2018) is one of the Russian cryptographic
- standard algorithms (called GOST algorithms). Only signature verification
- is implemented.
+ RFC 7091, ISO/IEC 14888-3)
+
+ One of the Russian cryptographic standard algorithms (called GOST
+ algorithms). Only signature verification is implemented.
+
+config CRYPTO_SM2
+ tristate "SM2 (ShangMi 2)"
+ select CRYPTO_SM3
+ select CRYPTO_AKCIPHER
+ select CRYPTO_MANAGER
+ select MPILIB
+ select ASN1
+ help
+ SM2 (ShangMi 2) public key algorithm
+
+ Published by State Encryption Management Bureau, China,
+ as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012.
+
+ References:
+ https://datatracker.ietf.org/doc/draft-shen-sm2-ecdsa/
+ http://www.oscca.gov.cn/sca/xxgk/2010-12/17/content_1002386.shtml
+ http://www.gmbz.org.cn/main/bzlb.html
config CRYPTO_CURVE25519
- tristate "Curve25519 algorithm"
+ tristate "Curve25519"
select CRYPTO_KPP
select CRYPTO_LIB_CURVE25519_GENERIC
+ help
+ Curve25519 elliptic curve (RFC7748)
-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
+endmenu
-comment "Authenticated Encryption with Associated Data"
+menu "Block ciphers"
-config CRYPTO_CCM
- tristate "CCM support"
- select CRYPTO_CTR
- select CRYPTO_HASH
- select CRYPTO_AEAD
- select CRYPTO_MANAGER
+config CRYPTO_AES
+ tristate "AES (Advanced Encryption Standard)"
+ select CRYPTO_ALGAPI
+ select CRYPTO_LIB_AES
help
- Support for Counter with CBC MAC. Required for IPsec.
+ AES cipher algorithms (Rijndael)(FIPS-197, ISO/IEC 18033-3)
-config CRYPTO_GCM
- tristate "GCM/GMAC support"
- select CRYPTO_CTR
- select CRYPTO_AEAD
- select CRYPTO_GHASH
- select CRYPTO_NULL
- select CRYPTO_MANAGER
+ Rijndael appears to be consistently a very good performer in
+ both hardware and software across a wide range of computing
+ environments regardless of its use in feedback or non-feedback
+ modes. Its key setup time is excellent, and its key agility is
+ good. Rijndael's very low memory requirements make it very well
+ suited for restricted-space environments, in which it also
+ demonstrates excellent performance. Rijndael's operations are
+ among the easiest to defend against power and timing attacks.
+
+ The AES specifies three key sizes: 128, 192 and 256 bits
+
+config CRYPTO_AES_TI
+ tristate "AES (Advanced Encryption Standard) (fixed time)"
+ select CRYPTO_ALGAPI
+ select CRYPTO_LIB_AES
help
- Support for Galois/Counter Mode (GCM) and Galois Message
- Authentication Code (GMAC). Required for IPSec.
+ AES cipher algorithms (Rijndael)(FIPS-197, ISO/IEC 18033-3)
-config CRYPTO_CHACHA20POLY1305
- tristate "ChaCha20-Poly1305 AEAD support"
- select CRYPTO_CHACHA20
- select CRYPTO_POLY1305
- select CRYPTO_AEAD
- select CRYPTO_MANAGER
+ This is a generic implementation of AES that attempts to eliminate
+ data dependent latencies as much as possible without affecting
+ performance too much. It is intended for use by the generic CCM
+ and GCM drivers, and other CTR or CMAC/XCBC based modes that rely
+ solely on encryption (although decryption is supported as well, but
+ with a more dramatic performance hit)
+
+ Instead of using 16 lookup tables of 1 KB each, (8 for encryption and
+ 8 for decryption), this implementation only uses just two S-boxes of
+ 256 bytes each, and attempts to eliminate data dependent latencies by
+ prefetching the entire table into the cache at the start of each
+ block. Interrupts are also disabled to avoid races where cachelines
+ are evicted when the CPU is interrupted to do something else.
+
+config CRYPTO_ANUBIS
+ tristate "Anubis"
+ depends on CRYPTO_USER_API_ENABLE_OBSOLETE
+ select CRYPTO_ALGAPI
help
- ChaCha20-Poly1305 AEAD support, RFC7539.
+ Anubis cipher algorithm
- Support for the AEAD wrapper using the ChaCha20 stream cipher combined
- with the Poly1305 authenticator. It is defined in RFC7539 for use in
- IETF protocols.
+ Anubis is a variable key length cipher which can use keys from
+ 128 bits to 320 bits in length. It was evaluated as a entrant
+ in the NESSIE competition.
-config CRYPTO_AEGIS128
- tristate "AEGIS-128 AEAD algorithm"
- select CRYPTO_AEAD
- select CRYPTO_AES # for AES S-box tables
+ See https://web.archive.org/web/20160606112246/http://www.larc.usp.br/~pbarreto/AnubisPage.html
+ for further information.
+
+config CRYPTO_ARIA
+ tristate "ARIA"
+ select CRYPTO_ALGAPI
help
- Support for the AEGIS-128 dedicated AEAD algorithm.
+ ARIA cipher algorithm (RFC5794)
-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
+ ARIA is a standard encryption algorithm of the Republic of Korea.
+ The ARIA specifies three key sizes and rounds.
+ 128-bit: 12 rounds.
+ 192-bit: 14 rounds.
+ 256-bit: 16 rounds.
-config CRYPTO_AEGIS128_AESNI_SSE2
- tristate "AEGIS-128 AEAD algorithm (x86_64 AESNI+SSE2 implementation)"
- depends on X86 && 64BIT
- select CRYPTO_AEAD
- select CRYPTO_SIMD
+ See:
+ https://seed.kisa.or.kr/kisa/algorithm/EgovAriaInfo.do
+
+config CRYPTO_BLOWFISH
+ tristate "Blowfish"
+ select CRYPTO_ALGAPI
+ select CRYPTO_BLOWFISH_COMMON
help
- AESNI+SSE2 implementation of the AEGIS-128 dedicated AEAD algorithm.
+ Blowfish cipher algorithm, by Bruce Schneier
-config CRYPTO_SEQIV
- tristate "Sequence Number IV Generator"
- select CRYPTO_AEAD
+ This is a variable key length cipher which can use keys from 32
+ bits to 448 bits in length. It's fast, simple and specifically
+ designed for use on "large microprocessors".
+
+ See https://www.schneier.com/blowfish.html for further information.
+
+config CRYPTO_BLOWFISH_COMMON
+ tristate
+ help
+ Common parts of the Blowfish cipher algorithm shared by the
+ generic c and the assembler implementations.
+
+config CRYPTO_CAMELLIA
+ tristate "Camellia"
+ select CRYPTO_ALGAPI
+ help
+ Camellia cipher algorithms (ISO/IEC 18033-3)
+
+ Camellia is a symmetric key block cipher developed jointly
+ at NTT and Mitsubishi Electric Corporation.
+
+ The Camellia specifies three key sizes: 128, 192 and 256 bits.
+
+ See https://info.isl.ntt.co.jp/crypt/eng/camellia/ for further information.
+
+config CRYPTO_CAST_COMMON
+ tristate
+ help
+ Common parts of the CAST cipher algorithms shared by the
+ generic c and the assembler implementations.
+
+config CRYPTO_CAST5
+ tristate "CAST5 (CAST-128)"
+ select CRYPTO_ALGAPI
+ select CRYPTO_CAST_COMMON
+ help
+ CAST5 (CAST-128) cipher algorithm (RFC2144, ISO/IEC 18033-3)
+
+config CRYPTO_CAST6
+ tristate "CAST6 (CAST-256)"
+ select CRYPTO_ALGAPI
+ select CRYPTO_CAST_COMMON
+ help
+ CAST6 (CAST-256) encryption algorithm (RFC2612)
+
+config CRYPTO_DES
+ tristate "DES and Triple DES EDE"
+ select CRYPTO_ALGAPI
+ select CRYPTO_LIB_DES
+ help
+ DES (Data Encryption Standard)(FIPS 46-2, ISO/IEC 18033-3) and
+ Triple DES EDE (Encrypt/Decrypt/Encrypt) (FIPS 46-3, ISO/IEC 18033-3)
+ cipher algorithms
+
+config CRYPTO_FCRYPT
+ tristate "FCrypt"
+ select CRYPTO_ALGAPI
select CRYPTO_SKCIPHER
- select CRYPTO_NULL
- select CRYPTO_RNG_DEFAULT
- select CRYPTO_MANAGER
help
- This IV generator generates an IV based on a sequence number by
- xoring it with a salt. This algorithm is mainly useful for CTR
+ FCrypt algorithm used by RxRPC
-config CRYPTO_ECHAINIV
- tristate "Encrypted Chain IV Generator"
- select CRYPTO_AEAD
- select CRYPTO_NULL
- select CRYPTO_RNG_DEFAULT
+ See https://ota.polyonymo.us/fcrypt-paper.txt
+
+config CRYPTO_KHAZAD
+ tristate "Khazad"
+ depends on CRYPTO_USER_API_ENABLE_OBSOLETE
+ select CRYPTO_ALGAPI
+ help
+ Khazad cipher algorithm
+
+ Khazad was a finalist in the initial NESSIE competition. It is
+ an algorithm optimized for 64-bit processors with good performance
+ on 32-bit processors. Khazad uses an 128 bit key size.
+
+ See https://web.archive.org/web/20171011071731/http://www.larc.usp.br/~pbarreto/KhazadPage.html
+ for further information.
+
+config CRYPTO_SEED
+ tristate "SEED"
+ depends on CRYPTO_USER_API_ENABLE_OBSOLETE
+ select CRYPTO_ALGAPI
+ help
+ SEED cipher algorithm (RFC4269, ISO/IEC 18033-3)
+
+ SEED is a 128-bit symmetric key block cipher that has been
+ developed by KISA (Korea Information Security Agency) as a
+ national standard encryption algorithm of the Republic of Korea.
+ It is a 16 round block cipher with the key size of 128 bit.
+
+ See https://seed.kisa.or.kr/kisa/algorithm/EgovSeedInfo.do
+ for further information.
+
+config CRYPTO_SERPENT
+ tristate "Serpent"
+ select CRYPTO_ALGAPI
+ help
+ Serpent cipher algorithm, by Anderson, Biham & Knudsen
+
+ Keys are allowed to be from 0 to 256 bits in length, in steps
+ of 8 bits.
+
+ See https://www.cl.cam.ac.uk/~rja14/serpent.html for further information.
+
+config CRYPTO_SM4
+ tristate
+
+config CRYPTO_SM4_GENERIC
+ tristate "SM4 (ShangMi 4)"
+ select CRYPTO_ALGAPI
+ select CRYPTO_SM4
+ help
+ SM4 cipher algorithms (OSCCA GB/T 32907-2016,
+ ISO/IEC 18033-3:2010/Amd 1:2021)
+
+ SM4 (GBT.32907-2016) is a cryptographic standard issued by the
+ Organization of State Commercial Administration of China (OSCCA)
+ as an authorized cryptographic algorithms for the use within China.
+
+ SMS4 was originally created for use in protecting wireless
+ networks, and is mandated in the Chinese National Standard for
+ Wireless LAN WAPI (Wired Authentication and Privacy Infrastructure)
+ (GB.15629.11-2003).
+
+ The latest SM4 standard (GBT.32907-2016) was proposed by OSCCA and
+ standardized through TC 260 of the Standardization Administration
+ of the People's Republic of China (SAC).
+
+ The input, output, and key of SMS4 are each 128 bits.
+
+ See https://eprint.iacr.org/2008/329.pdf for further information.
+
+ If unsure, say N.
+
+config CRYPTO_TEA
+ tristate "TEA, XTEA and XETA"
+ depends on CRYPTO_USER_API_ENABLE_OBSOLETE
+ select CRYPTO_ALGAPI
+ help
+ TEA (Tiny Encryption Algorithm) cipher algorithms
+
+ Tiny Encryption Algorithm is a simple cipher that uses
+ many rounds for security. It is very fast and uses
+ little memory.
+
+ Xtendend Tiny Encryption Algorithm is a modification to
+ the TEA algorithm to address a potential key weakness
+ in the TEA algorithm.
+
+ Xtendend Encryption Tiny Algorithm is a mis-implementation
+ of the XTEA algorithm for compatibility purposes.
+
+config CRYPTO_TWOFISH
+ tristate "Twofish"
+ select CRYPTO_ALGAPI
+ select CRYPTO_TWOFISH_COMMON
+ help
+ Twofish cipher algorithm
+
+ Twofish was submitted as an AES (Advanced Encryption Standard)
+ candidate cipher by researchers at CounterPane Systems. It is a
+ 16 round block cipher supporting key sizes of 128, 192, and 256
+ bits.
+
+ See https://www.schneier.com/twofish.html for further information.
+
+config CRYPTO_TWOFISH_COMMON
+ tristate
+ help
+ Common parts of the Twofish cipher algorithm shared by the
+ generic c and the assembler implementations.
+
+endmenu
+
+menu "Length-preserving ciphers and modes"
+
+config CRYPTO_ADIANTUM
+ tristate "Adiantum"
+ select CRYPTO_CHACHA20
+ select CRYPTO_LIB_POLY1305_GENERIC
+ select CRYPTO_NHPOLY1305
select CRYPTO_MANAGER
help
- This IV generator generates an IV based on the encryption of
- a sequence number xored with a salt. This is the default
- algorithm for CBC.
+ Adiantum tweakable, length-preserving encryption mode
+
+ Designed for fast and secure disk encryption, especially on
+ CPUs without dedicated crypto instructions. It encrypts
+ each sector using the XChaCha12 stream cipher, two passes of
+ an ε-almost-∆-universal hash function, and an invocation of
+ the AES-256 block cipher on a single 16-byte block. On CPUs
+ without AES instructions, Adiantum is much faster than
+ AES-XTS.
+
+ Adiantum's security is provably reducible to that of its
+ underlying stream and block ciphers, subject to a security
+ bound. Unlike XTS, Adiantum is a true wide-block encryption
+ mode, so it actually provides an even stronger notion of
+ security than XTS, subject to the security bound.
+
+ If unsure, say N.
+
+config CRYPTO_ARC4
+ tristate "ARC4 (Alleged Rivest Cipher 4)"
+ depends on CRYPTO_USER_API_ENABLE_OBSOLETE
+ select CRYPTO_SKCIPHER
+ select CRYPTO_LIB_ARC4
+ help
+ ARC4 cipher algorithm
+
+ ARC4 is a stream cipher using keys ranging from 8 bits to 2048
+ bits in length. This algorithm is required for driver-based
+ WEP, but it should not be for other purposes because of the
+ weakness of the algorithm.
+
+config CRYPTO_CHACHA20
+ tristate "ChaCha"
+ select CRYPTO_LIB_CHACHA_GENERIC
+ select CRYPTO_SKCIPHER
+ help
+ The ChaCha20, XChaCha20, and XChaCha12 stream cipher algorithms
+
+ ChaCha20 is a 256-bit high-speed stream cipher designed by Daniel J.
+ Bernstein and further specified in RFC7539 for use in IETF protocols.
+ This is the portable C implementation of ChaCha20. See
+ https://cr.yp.to/chacha/chacha-20080128.pdf for further information.
+
+ XChaCha20 is the application of the XSalsa20 construction to ChaCha20
+ rather than to Salsa20. XChaCha20 extends ChaCha20's nonce length
+ from 64 bits (or 96 bits using the RFC7539 convention) to 192 bits,
+ while provably retaining ChaCha20's security. See
+ https://cr.yp.to/snuffle/xsalsa-20081128.pdf for further information.
-comment "Block modes"
+ XChaCha12 is XChaCha20 reduced to 12 rounds, with correspondingly
+ reduced security margin but increased performance. It can be needed
+ in some performance-sensitive scenarios.
config CRYPTO_CBC
- tristate "CBC support"
+ tristate "CBC (Cipher Block Chaining)"
select CRYPTO_SKCIPHER
select CRYPTO_MANAGER
help
- CBC: Cipher Block Chaining mode
- This block cipher algorithm is required for IPSec.
+ CBC (Cipher Block Chaining) mode (NIST SP800-38A)
+
+ This block cipher mode is required for IPSec ESP (XFRM_ESP).
config CRYPTO_CFB
- tristate "CFB support"
+ tristate "CFB (Cipher Feedback)"
select CRYPTO_SKCIPHER
select CRYPTO_MANAGER
help
- CFB: Cipher FeedBack mode
- This block cipher algorithm is required for TPM2 Cryptography.
+ CFB (Cipher Feedback) mode (NIST SP800-38A)
+
+ This block cipher mode is required for TPM2 Cryptography.
config CRYPTO_CTR
- tristate "CTR support"
+ tristate "CTR (Counter)"
select CRYPTO_SKCIPHER
- select CRYPTO_SEQIV
select CRYPTO_MANAGER
help
- CTR: Counter mode
- This block cipher algorithm is required for IPSec.
+ CTR (Counter) mode (NIST SP800-38A)
config CRYPTO_CTS
- tristate "CTS support"
+ tristate "CTS (Cipher Text Stealing)"
select CRYPTO_SKCIPHER
select CRYPTO_MANAGER
help
- CTS: Cipher Text Stealing
- This is the Cipher Text Stealing mode as described by
- Section 8 of rfc2040 and referenced by rfc3962
- (rfc3962 includes errata information in its Appendix A) or
- CBC-CS3 as defined by NIST in Sp800-38A addendum from Oct 2010.
+ CBC-CS3 variant of CTS (Cipher Text Stealing) (NIST
+ Addendum to SP800-38A (October 2010))
+
This mode is required for Kerberos gss mechanism support
for AES encryption.
- See: https://csrc.nist.gov/publications/detail/sp/800-38a/addendum/final
-
config CRYPTO_ECB
- tristate "ECB support"
+ tristate "ECB (Electronic Codebook)"
select CRYPTO_SKCIPHER
select CRYPTO_MANAGER
help
- ECB: Electronic CodeBook mode
- This is the simplest block cipher algorithm. It simply encrypts
- the input block by block.
+ ECB (Electronic Codebook) mode (NIST SP800-38A)
+
+config CRYPTO_HCTR2
+ tristate "HCTR2"
+ select CRYPTO_XCTR
+ select CRYPTO_POLYVAL
+ select CRYPTO_MANAGER
+ help
+ HCTR2 length-preserving encryption mode
+
+ A mode for storage encryption that is efficient on processors with
+ instructions to accelerate AES and carryless multiplication, e.g.
+ x86 processors with AES-NI and CLMUL, and ARM processors with the
+ ARMv8 crypto extensions.
+
+ See https://eprint.iacr.org/2021/1441
+
+config CRYPTO_KEYWRAP
+ tristate "KW (AES Key Wrap)"
+ select CRYPTO_SKCIPHER
+ select CRYPTO_MANAGER
+ help
+ KW (AES Key Wrap) authenticated encryption mode (NIST SP800-38F
+ and RFC3394) without padding.
config CRYPTO_LRW
- tristate "LRW support"
+ tristate "LRW (Liskov Rivest Wagner)"
select CRYPTO_SKCIPHER
select CRYPTO_MANAGER
select CRYPTO_GF128MUL
+ select CRYPTO_ECB
help
- LRW: Liskov Rivest Wagner, a tweakable, non malleable, non movable
+ LRW (Liskov Rivest Wagner) mode
+
+ A tweakable, non malleable, non movable
narrow block cipher mode for dm-crypt. Use it with cipher
specification string aes-lrw-benbi, the key must be 256, 320 or 384.
The first 128, 192 or 256 bits in the key are used for AES and the
rest is used to tie each cipher block to its logical position.
+ See https://people.csail.mit.edu/rivest/pubs/LRW02.pdf
+
config CRYPTO_OFB
- tristate "OFB support"
+ tristate "OFB (Output Feedback)"
select CRYPTO_SKCIPHER
select CRYPTO_MANAGER
help
- OFB: the Output Feedback mode makes a block cipher into a synchronous
+ OFB (Output Feedback) mode (NIST SP800-38A)
+
+ This mode makes a block cipher into a synchronous
stream cipher. It generates keystream blocks, which are then XORed
with the plaintext blocks to get the ciphertext. Flipping a bit in the
ciphertext produces a flipped bit in the plaintext at the same
@@ -425,82 +744,133 @@ config CRYPTO_OFB
normally even when applied before encryption.
config CRYPTO_PCBC
- tristate "PCBC support"
+ tristate "PCBC (Propagating Cipher Block Chaining)"
select CRYPTO_SKCIPHER
select CRYPTO_MANAGER
help
- PCBC: Propagating Cipher Block Chaining mode
- This block cipher algorithm is required for RxRPC.
+ PCBC (Propagating Cipher Block Chaining) mode
-config CRYPTO_XTS
- tristate "XTS support"
+ This block cipher mode is required for RxRPC.
+
+config CRYPTO_XCTR
+ tristate
select CRYPTO_SKCIPHER
select CRYPTO_MANAGER
- select CRYPTO_ECB
help
- XTS: IEEE1619/D16 narrow block cipher use with aes-xts-plain,
- key size 256, 384 or 512 bits. This implementation currently
- can't handle a sectorsize which is not a multiple of 16 bytes.
+ XCTR (XOR Counter) mode for HCTR2
-config CRYPTO_KEYWRAP
- tristate "Key wrapping support"
+ This blockcipher mode is a variant of CTR mode using XORs and little-endian
+ addition rather than big-endian arithmetic.
+
+ XCTR mode is used to implement HCTR2.
+
+config CRYPTO_XTS
+ tristate "XTS (XOR Encrypt XOR with ciphertext stealing)"
select CRYPTO_SKCIPHER
select CRYPTO_MANAGER
+ select CRYPTO_ECB
help
- Support for key wrapping (NIST SP800-38F / RFC3394) without
- padding.
+ XTS (XOR Encrypt XOR with ciphertext stealing) mode (NIST SP800-38E
+ and IEEE 1619)
+
+ Use with aes-xts-plain, key size 256, 384 or 512 bits. This
+ implementation currently can't handle a sectorsize which is not a
+ multiple of 16 bytes.
config CRYPTO_NHPOLY1305
tristate
select CRYPTO_HASH
select CRYPTO_LIB_POLY1305_GENERIC
-config CRYPTO_NHPOLY1305_SSE2
- tristate "NHPoly1305 hash function (x86_64 SSE2 implementation)"
- depends on X86 && 64BIT
- select CRYPTO_NHPOLY1305
+endmenu
+
+menu "AEAD (authenticated encryption with associated data) ciphers"
+
+config CRYPTO_AEGIS128
+ tristate "AEGIS-128"
+ select CRYPTO_AEAD
+ select CRYPTO_AES # for AES S-box tables
help
- SSE2 optimized implementation of the hash function used by the
- Adiantum encryption mode.
+ AEGIS-128 AEAD algorithm
-config CRYPTO_NHPOLY1305_AVX2
- tristate "NHPoly1305 hash function (x86_64 AVX2 implementation)"
- depends on X86 && 64BIT
- select CRYPTO_NHPOLY1305
+config CRYPTO_AEGIS128_SIMD
+ bool "AEGIS-128 (arm NEON, arm64 NEON)"
+ depends on CRYPTO_AEGIS128 && ((ARM || ARM64) && KERNEL_MODE_NEON)
+ default y
help
- AVX2 optimized implementation of the hash function used by the
- Adiantum encryption mode.
+ AEGIS-128 AEAD algorithm
-config CRYPTO_ADIANTUM
- tristate "Adiantum support"
+ Architecture: arm or arm64 using:
+ - NEON (Advanced SIMD) extension
+
+config CRYPTO_CHACHA20POLY1305
+ tristate "ChaCha20-Poly1305"
select CRYPTO_CHACHA20
- select CRYPTO_LIB_POLY1305_GENERIC
- select CRYPTO_NHPOLY1305
+ select CRYPTO_POLY1305
+ select CRYPTO_AEAD
select CRYPTO_MANAGER
help
- Adiantum is a tweakable, length-preserving encryption mode
- designed for fast and secure disk encryption, especially on
- CPUs without dedicated crypto instructions. It encrypts
- each sector using the XChaCha12 stream cipher, two passes of
- an ε-almost-∆-universal hash function, and an invocation of
- the AES-256 block cipher on a single 16-byte block. On CPUs
- without AES instructions, Adiantum is much faster than
- AES-XTS.
+ ChaCha20 stream cipher and Poly1305 authenticator combined
+ mode (RFC8439)
- Adiantum's security is provably reducible to that of its
- underlying stream and block ciphers, subject to a security
- bound. Unlike XTS, Adiantum is a true wide-block encryption
- mode, so it actually provides an even stronger notion of
- security than XTS, subject to the security bound.
+config CRYPTO_CCM
+ tristate "CCM (Counter with Cipher Block Chaining-MAC)"
+ select CRYPTO_CTR
+ select CRYPTO_HASH
+ select CRYPTO_AEAD
+ select CRYPTO_MANAGER
+ help
+ CCM (Counter with Cipher Block Chaining-Message Authentication Code)
+ authenticated encryption mode (NIST SP800-38C)
- If unsure, say N.
+config CRYPTO_GCM
+ tristate "GCM (Galois/Counter Mode) and GMAC (GCM MAC)"
+ select CRYPTO_CTR
+ select CRYPTO_AEAD
+ select CRYPTO_GHASH
+ select CRYPTO_NULL
+ select CRYPTO_MANAGER
+ help
+ GCM (Galois/Counter Mode) authenticated encryption mode and GMAC
+ (GCM Message Authentication Code) (NIST SP800-38D)
+
+ This is required for IPSec ESP (XFRM_ESP).
+
+config CRYPTO_SEQIV
+ tristate "Sequence Number IV Generator"
+ select CRYPTO_AEAD
+ select CRYPTO_SKCIPHER
+ select CRYPTO_NULL
+ select CRYPTO_RNG_DEFAULT
+ select CRYPTO_MANAGER
+ help
+ Sequence Number IV generator
+
+ This IV generator generates an IV based on a sequence number by
+ xoring it with a salt. This algorithm is mainly useful for CTR.
+
+ This is required for IPsec ESP (XFRM_ESP).
+
+config CRYPTO_ECHAINIV
+ tristate "Encrypted Chain IV Generator"
+ select CRYPTO_AEAD
+ select CRYPTO_NULL
+ select CRYPTO_RNG_DEFAULT
+ select CRYPTO_MANAGER
+ help
+ Encrypted Chain IV generator
+
+ This IV generator generates an IV based on the encryption of
+ a sequence number xored with a salt. This is the default
+ algorithm for CBC.
config CRYPTO_ESSIV
- tristate "ESSIV support for block encryption"
+ tristate "Encrypted Salt-Sector IV Generator"
select CRYPTO_AUTHENC
help
- Encrypted salt-sector initialization vector (ESSIV) is an IV
- generation method that is used in some cases by fscrypt and/or
+ Encrypted Salt-Sector IV generator
+
+ This IV generator is used in some cases by fscrypt and/or
dm-crypt. It uses the hash of the block encryption key as the
symmetric key for a block encryption pass applied to the input
IV, making low entropy IV sources more suitable for block
@@ -523,1285 +893,356 @@ config CRYPTO_ESSIV
combined with ESSIV the only feasible mode for h/w accelerated
block encryption)
-comment "Hash modes"
-
-config CRYPTO_CMAC
- tristate "CMAC support"
- select CRYPTO_HASH
- select CRYPTO_MANAGER
- help
- Cipher-based Message Authentication Code (CMAC) specified by
- The National Institute of Standards and Technology (NIST).
-
- https://tools.ietf.org/html/rfc4493
- http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf
-
-config CRYPTO_HMAC
- tristate "HMAC support"
- select CRYPTO_HASH
- select CRYPTO_MANAGER
- help
- HMAC: Keyed-Hashing for Message Authentication (RFC2104).
- This is required for IPSec.
-
-config CRYPTO_XCBC
- tristate "XCBC support"
- select CRYPTO_HASH
- select CRYPTO_MANAGER
- help
- XCBC: Keyed-Hashing with encryption algorithm
- http://www.ietf.org/rfc/rfc3566.txt
- http://csrc.nist.gov/encryption/modes/proposedmodes/
- xcbc-mac/xcbc-mac-spec.pdf
-
-config CRYPTO_VMAC
- tristate "VMAC support"
- select CRYPTO_HASH
- select CRYPTO_MANAGER
- help
- VMAC is a message authentication algorithm designed for
- very high speed on 64-bit architectures.
-
- See also:
- <http://fastcrypto.org/vmac>
-
-comment "Digest"
-
-config CRYPTO_CRC32C
- tristate "CRC32c CRC algorithm"
- select CRYPTO_HASH
- select CRC32
- help
- Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used
- by iSCSI for header and data digests and by others.
- See Castagnoli93. Module will be crc32c.
+endmenu
-config CRYPTO_CRC32C_INTEL
- tristate "CRC32c INTEL hardware acceleration"
- depends on X86
- select CRYPTO_HASH
- help
- In Intel processor with SSE4.2 supported, the processor will
- support CRC32C implementation using hardware accelerated CRC32
- instruction. This option will create 'crc32c-intel' module,
- which will enable any routine to use the CRC32 instruction to
- gain performance compared with software implementation.
- Module will be crc32c-intel.
-
-config CRYPTO_CRC32C_VPMSUM
- tristate "CRC32c CRC algorithm (powerpc64)"
- depends on PPC64 && ALTIVEC
- select CRYPTO_HASH
- select CRC32
- help
- CRC32c algorithm implemented using vector polynomial multiply-sum
- (vpmsum) instructions, introduced in POWER8. Enable on POWER8
- and newer processors for improved performance.
-
-
-config CRYPTO_CRC32C_SPARC64
- tristate "CRC32c CRC algorithm (SPARC64)"
- depends on SPARC64
- select CRYPTO_HASH
- select CRC32
- help
- CRC32c CRC algorithm implemented using sparc64 crypto instructions,
- when available.
-
-config CRYPTO_CRC32
- tristate "CRC32 CRC algorithm"
- select CRYPTO_HASH
- select CRC32
- help
- CRC-32-IEEE 802.3 cyclic redundancy-check algorithm.
- Shash crypto api wrappers to crc32_le function.
-
-config CRYPTO_CRC32_PCLMUL
- tristate "CRC32 PCLMULQDQ hardware acceleration"
- depends on X86
- select CRYPTO_HASH
- select CRC32
- help
- From Intel Westmere and AMD Bulldozer processor with SSE4.2
- and PCLMULQDQ supported, the processor will support
- CRC32 PCLMULQDQ implementation using hardware accelerated PCLMULQDQ
- instruction. This option will create 'crc32-pclmul' module,
- which will enable any routine to use the CRC-32-IEEE 802.3 checksum
- and gain better performance as compared with the table implementation.
-
-config CRYPTO_CRC32_MIPS
- tristate "CRC32c and CRC32 CRC algorithm (MIPS)"
- depends on MIPS_CRC_SUPPORT
- select CRYPTO_HASH
- help
- CRC32c and CRC32 CRC algorithms implemented using mips crypto
- instructions, when available.
-
-
-config CRYPTO_XXHASH
- tristate "xxHash hash algorithm"
- select CRYPTO_HASH
- select XXHASH
- help
- xxHash non-cryptographic hash algorithm. Extremely fast, working at
- speeds close to RAM limits.
+menu "Hashes, digests, and MACs"
config CRYPTO_BLAKE2B
- tristate "BLAKE2b digest algorithm"
+ tristate "BLAKE2b"
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.
+ BLAKE2b cryptographic hash function (RFC 7693)
- This module provides the following algorithms:
+ BLAKE2b is optimized for 64-bit platforms and can produce digests
+ of any size between 1 and 64 bytes. 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
+ Used by the btrfs filesystem.
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
- help
- CRC T10 Data Integrity Field computation is being cast as
- a crypto transform. This allows for faster crc t10 diff
- transforms to be used if they are available.
-
-config CRYPTO_CRCT10DIF_PCLMUL
- tristate "CRCT10DIF PCLMULQDQ hardware acceleration"
- depends on X86 && 64BIT && CRC_T10DIF
- select CRYPTO_HASH
- help
- For x86_64 processors with SSE4.2 and PCLMULQDQ supported,
- CRC T10 DIF PCLMULQDQ computation can be hardware
- accelerated PCLMULQDQ instruction. This option will create
- 'crct10dif-pclmul' module, which is faster when computing the
- crct10dif checksum as compared with the generic table implementation.
-
-config CRYPTO_CRCT10DIF_VPMSUM
- tristate "CRC32T10DIF powerpc64 hardware acceleration"
- depends on PPC64 && ALTIVEC && CRC_T10DIF
+config CRYPTO_CMAC
+ tristate "CMAC (Cipher-based MAC)"
select CRYPTO_HASH
+ select CRYPTO_MANAGER
help
- CRC10T10DIF algorithm implemented using vector polynomial
- multiply-sum (vpmsum) instructions, introduced in POWER8. Enable on
- POWER8 and newer processors for improved performance.
-
-config CRYPTO_VPMSUM_TESTER
- tristate "Powerpc64 vpmsum hardware acceleration tester"
- depends on CRYPTO_CRCT10DIF_VPMSUM && CRYPTO_CRC32C_VPMSUM
- help
- Stress test for CRC32c and CRC-T10DIF algorithms implemented with
- POWER8 vpmsum instructions.
- Unless you are testing these algorithms, you don't need this.
+ CMAC (Cipher-based Message Authentication Code) authentication
+ mode (NIST SP800-38B and IETF RFC4493)
config CRYPTO_GHASH
- tristate "GHASH hash function"
+ tristate "GHASH"
select CRYPTO_GF128MUL
select CRYPTO_HASH
help
- GHASH is the hash function used in GCM (Galois/Counter Mode).
- It is not a general-purpose cryptographic hash function.
+ GCM GHASH function (NIST SP800-38D)
-config CRYPTO_POLY1305
- tristate "Poly1305 authenticator algorithm"
+config CRYPTO_HMAC
+ tristate "HMAC (Keyed-Hash MAC)"
select CRYPTO_HASH
- select CRYPTO_LIB_POLY1305_GENERIC
- help
- Poly1305 authenticator algorithm, RFC7539.
-
- Poly1305 is an authenticator algorithm designed by Daniel J. Bernstein.
- It is used for the ChaCha20-Poly1305 AEAD, specified in RFC7539 for use
- in IETF protocols. This is the portable C implementation of Poly1305.
-
-config CRYPTO_POLY1305_X86_64
- tristate "Poly1305 authenticator algorithm (x86_64/SSE2/AVX2)"
- depends on X86 && 64BIT
- select CRYPTO_LIB_POLY1305_GENERIC
- select CRYPTO_ARCH_HAVE_LIB_POLY1305
+ select CRYPTO_MANAGER
help
- Poly1305 authenticator algorithm, RFC7539.
-
- Poly1305 is an authenticator algorithm designed by Daniel J. Bernstein.
- It is used for the ChaCha20-Poly1305 AEAD, specified in RFC7539 for use
- in IETF protocols. This is the x86_64 assembler implementation using SIMD
- instructions.
+ HMAC (Keyed-Hash Message Authentication Code) (FIPS 198 and
+ RFC2104)
-config CRYPTO_POLY1305_MIPS
- tristate "Poly1305 authenticator algorithm (MIPS optimized)"
- depends on CPU_MIPS32 || (CPU_MIPS64 && 64BIT)
- select CRYPTO_ARCH_HAVE_LIB_POLY1305
+ This is required for IPsec AH (XFRM_AH) and IPsec ESP (XFRM_ESP).
config CRYPTO_MD4
- tristate "MD4 digest algorithm"
+ tristate "MD4"
select CRYPTO_HASH
help
- MD4 message digest algorithm (RFC1320).
+ MD4 message digest algorithm (RFC1320)
config CRYPTO_MD5
- tristate "MD5 digest algorithm"
+ tristate "MD5"
select CRYPTO_HASH
help
- MD5 message digest algorithm (RFC1321).
+ MD5 message digest algorithm (RFC1321)
-config CRYPTO_MD5_OCTEON
- tristate "MD5 digest algorithm (OCTEON)"
- depends on CPU_CAVIUM_OCTEON
- select CRYPTO_MD5
+config CRYPTO_MICHAEL_MIC
+ tristate "Michael MIC"
select CRYPTO_HASH
help
- MD5 message digest algorithm (RFC1321) implemented
- using OCTEON crypto instructions, when available.
+ Michael MIC (Message Integrity Code) (IEEE 802.11i)
-config CRYPTO_MD5_PPC
- tristate "MD5 digest algorithm (PPC)"
- depends on PPC
- select CRYPTO_HASH
- help
- MD5 message digest algorithm (RFC1321) implemented
- in PPC assembler.
+ Defined by the IEEE 802.11i TKIP (Temporal Key Integrity Protocol),
+ known as WPA (Wif-Fi Protected Access).
-config CRYPTO_MD5_SPARC64
- tristate "MD5 digest algorithm (SPARC64)"
- depends on SPARC64
- select CRYPTO_MD5
- select CRYPTO_HASH
- help
- MD5 message digest algorithm (RFC1321) implemented
- using sparc64 crypto instructions, when available.
+ This algorithm is required for TKIP, but it should not be used for
+ other purposes because of the weakness of the algorithm.
-config CRYPTO_MICHAEL_MIC
- tristate "Michael MIC keyed digest algorithm"
+config CRYPTO_POLYVAL
+ tristate
+ select CRYPTO_GF128MUL
select CRYPTO_HASH
help
- Michael MIC is used for message integrity protection in TKIP
- (IEEE 802.11i). This algorithm is required for TKIP, but it
- should not be used for other purposes because of the weakness
- of the algorithm.
+ POLYVAL hash function for HCTR2
-config CRYPTO_RMD128
- tristate "RIPEMD-128 digest algorithm"
+ This is used in HCTR2. It is not a general-purpose
+ cryptographic hash function.
+
+config CRYPTO_POLY1305
+ tristate "Poly1305"
select CRYPTO_HASH
+ select CRYPTO_LIB_POLY1305_GENERIC
help
- RIPEMD-128 (ISO/IEC 10118-3:2004).
-
- RIPEMD-128 is a 128-bit cryptographic hash function. It should only
- be used as a secure replacement for RIPEMD. For other use cases,
- RIPEMD-160 should be used.
+ Poly1305 authenticator algorithm (RFC7539)
- Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
- See <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
+ Poly1305 is an authenticator algorithm designed by Daniel J. Bernstein.
+ It is used for the ChaCha20-Poly1305 AEAD, specified in RFC7539 for use
+ in IETF protocols. This is the portable C implementation of Poly1305.
config CRYPTO_RMD160
- tristate "RIPEMD-160 digest algorithm"
+ tristate "RIPEMD-160"
select CRYPTO_HASH
help
- RIPEMD-160 (ISO/IEC 10118-3:2004).
+ RIPEMD-160 hash function (ISO/IEC 10118-3)
RIPEMD-160 is a 160-bit cryptographic hash function. It is intended
to be used as a secure replacement for the 128-bit hash functions
- MD4, MD5 and it's predecessor RIPEMD
+ MD4, MD5 and its predecessor RIPEMD
(not to be confused with RIPEMD-128).
- It's speed is comparable to SHA1 and there are no known attacks
+ Its speed is comparable to SHA-1 and there are no known attacks
against RIPEMD-160.
Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
- See <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
-
-config CRYPTO_RMD256
- tristate "RIPEMD-256 digest algorithm"
- select CRYPTO_HASH
- help
- RIPEMD-256 is an optional extension of RIPEMD-128 with a
- 256 bit hash. It is intended for applications that require
- longer hash-results, without needing a larger security level
- (than RIPEMD-128).
-
- Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
- See <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
-
-config CRYPTO_RMD320
- tristate "RIPEMD-320 digest algorithm"
- select CRYPTO_HASH
- help
- RIPEMD-320 is an optional extension of RIPEMD-160 with a
- 320 bit hash. It is intended for applications that require
- longer hash-results, without needing a larger security level
- (than RIPEMD-160).
-
- Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
- See <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
+ See https://homes.esat.kuleuven.be/~bosselae/ripemd160.html
+ for further information.
config CRYPTO_SHA1
- tristate "SHA1 digest algorithm"
- select CRYPTO_HASH
- help
- SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
-
-config CRYPTO_SHA1_SSSE3
- tristate "SHA1 digest algorithm (SSSE3/AVX/AVX2/SHA-NI)"
- depends on X86 && 64BIT
- select CRYPTO_SHA1
+ tristate "SHA-1"
select CRYPTO_HASH
+ select CRYPTO_LIB_SHA1
help
- SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
- using Supplemental SSE3 (SSSE3) instructions or Advanced Vector
- Extensions (AVX/AVX2) or SHA-NI(SHA Extensions New Instructions),
- when available.
-
-config CRYPTO_SHA256_SSSE3
- tristate "SHA256 digest algorithm (SSSE3/AVX/AVX2/SHA-NI)"
- depends on X86 && 64BIT
- select CRYPTO_SHA256
- select CRYPTO_HASH
- help
- SHA-256 secure hash standard (DFIPS 180-2) implemented
- using Supplemental SSE3 (SSSE3) instructions, or Advanced Vector
- Extensions version 1 (AVX1), or Advanced Vector Extensions
- version 2 (AVX2) instructions, or SHA-NI (SHA Extensions New
- Instructions) when available.
-
-config CRYPTO_SHA512_SSSE3
- tristate "SHA512 digest algorithm (SSSE3/AVX/AVX2)"
- depends on X86 && 64BIT
- select CRYPTO_SHA512
- select CRYPTO_HASH
- help
- SHA-512 secure hash standard (DFIPS 180-2) implemented
- using Supplemental SSE3 (SSSE3) instructions, or Advanced Vector
- Extensions version 1 (AVX1), or Advanced Vector Extensions
- version 2 (AVX2) instructions, when available.
-
-config CRYPTO_SHA1_OCTEON
- tristate "SHA1 digest algorithm (OCTEON)"
- depends on CPU_CAVIUM_OCTEON
- select CRYPTO_SHA1
- select CRYPTO_HASH
- help
- SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
- using OCTEON crypto instructions, when available.
-
-config CRYPTO_SHA1_SPARC64
- tristate "SHA1 digest algorithm (SPARC64)"
- depends on SPARC64
- select CRYPTO_SHA1
- select CRYPTO_HASH
- help
- SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
- using sparc64 crypto instructions, when available.
-
-config CRYPTO_SHA1_PPC
- tristate "SHA1 digest algorithm (powerpc)"
- depends on PPC
- help
- This is the powerpc hardware accelerated implementation of the
- SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
-
-config CRYPTO_SHA1_PPC_SPE
- tristate "SHA1 digest algorithm (PPC SPE)"
- depends on PPC && SPE
- help
- SHA-1 secure hash standard (DFIPS 180-4) implemented
- using powerpc SPE SIMD instruction set.
+ SHA-1 secure hash algorithm (FIPS 180, ISO/IEC 10118-3)
config CRYPTO_SHA256
- tristate "SHA224 and SHA256 digest algorithm"
+ tristate "SHA-224 and SHA-256"
select CRYPTO_HASH
select CRYPTO_LIB_SHA256
help
- SHA256 secure hash standard (DFIPS 180-2).
-
- This version of SHA implements a 256 bit hash with 128 bits of
- security against collision attacks.
-
- This code also includes SHA-224, a 224 bit hash with 112 bits
- of security against collision attacks.
-
-config CRYPTO_SHA256_PPC_SPE
- tristate "SHA224 and SHA256 digest algorithm (PPC SPE)"
- depends on PPC && SPE
- select CRYPTO_SHA256
- select CRYPTO_HASH
- help
- SHA224 and SHA256 secure hash standard (DFIPS 180-2)
- implemented using powerpc SPE SIMD instruction set.
-
-config CRYPTO_SHA256_OCTEON
- tristate "SHA224 and SHA256 digest algorithm (OCTEON)"
- depends on CPU_CAVIUM_OCTEON
- select CRYPTO_SHA256
- select CRYPTO_HASH
- help
- SHA-256 secure hash standard (DFIPS 180-2) implemented
- using OCTEON crypto instructions, when available.
+ SHA-224 and SHA-256 secure hash algorithms (FIPS 180, ISO/IEC 10118-3)
-config CRYPTO_SHA256_SPARC64
- tristate "SHA224 and SHA256 digest algorithm (SPARC64)"
- depends on SPARC64
- select CRYPTO_SHA256
- select CRYPTO_HASH
- help
- SHA-256 secure hash standard (DFIPS 180-2) implemented
- using sparc64 crypto instructions, when available.
+ This is required for IPsec AH (XFRM_AH) and IPsec ESP (XFRM_ESP).
+ Used by the btrfs filesystem, Ceph, NFS, and SMB.
config CRYPTO_SHA512
- tristate "SHA384 and SHA512 digest algorithms"
+ tristate "SHA-384 and SHA-512"
select CRYPTO_HASH
help
- SHA512 secure hash standard (DFIPS 180-2).
-
- This version of SHA implements a 512 bit hash with 256 bits of
- security against collision attacks.
-
- This code also includes SHA-384, a 384 bit hash with 192 bits
- of security against collision attacks.
-
-config CRYPTO_SHA512_OCTEON
- tristate "SHA384 and SHA512 digest algorithms (OCTEON)"
- depends on CPU_CAVIUM_OCTEON
- select CRYPTO_SHA512
- select CRYPTO_HASH
- help
- SHA-512 secure hash standard (DFIPS 180-2) implemented
- using OCTEON crypto instructions, when available.
-
-config CRYPTO_SHA512_SPARC64
- tristate "SHA384 and SHA512 digest algorithm (SPARC64)"
- depends on SPARC64
- select CRYPTO_SHA512
- select CRYPTO_HASH
- help
- SHA-512 secure hash standard (DFIPS 180-2) implemented
- using sparc64 crypto instructions, when available.
+ SHA-384 and SHA-512 secure hash algorithms (FIPS 180, ISO/IEC 10118-3)
config CRYPTO_SHA3
- tristate "SHA3 digest algorithm"
+ tristate "SHA-3"
select CRYPTO_HASH
help
- SHA-3 secure hash standard (DFIPS 202). It's based on
- cryptographic sponge function family called Keccak.
-
- References:
- http://keccak.noekeon.org/
+ SHA-3 secure hash algorithms (FIPS 202, ISO/IEC 10118-3)
config CRYPTO_SM3
- tristate "SM3 digest algorithm"
+ tristate
+
+config CRYPTO_SM3_GENERIC
+ tristate "SM3 (ShangMi 3)"
select CRYPTO_HASH
+ select CRYPTO_SM3
help
- SM3 secure hash function as defined by OSCCA GM/T 0004-2012 SM3).
- It is part of the Chinese Commercial Cryptography suite.
+ SM3 (ShangMi 3) secure hash function (OSCCA GM/T 0004-2012, ISO/IEC 10118-3)
+
+ This is part of the Chinese Commercial Cryptography suite.
References:
http://www.oscca.gov.cn/UpFile/20101222141857786.pdf
https://datatracker.ietf.org/doc/html/draft-shen-sm3-hash
config CRYPTO_STREEBOG
- tristate "Streebog Hash Function"
+ tristate "Streebog"
select CRYPTO_HASH
help
- Streebog Hash Function (GOST R 34.11-2012, RFC 6986) is one of the Russian
- cryptographic standard algorithms (called GOST algorithms).
- This setting enables two hash algorithms with 256 and 512 bits output.
+ Streebog Hash Function (GOST R 34.11-2012, RFC 6986, ISO/IEC 10118-3)
+
+ This is one of the Russian cryptographic standard algorithms (called
+ GOST algorithms). This setting enables two hash algorithms with
+ 256 and 512 bits output.
References:
https://tc26.ru/upload/iblock/fed/feddbb4d26b685903faa2ba11aea43f6.pdf
https://tools.ietf.org/html/rfc6986
-config CRYPTO_TGR192
- tristate "Tiger digest algorithms"
+config CRYPTO_VMAC
+ tristate "VMAC"
select CRYPTO_HASH
+ select CRYPTO_MANAGER
help
- Tiger hash algorithm 192, 160 and 128-bit hashes
-
- Tiger is a hash function optimized for 64-bit processors while
- still having decent performance on 32-bit processors.
- Tiger was developed by Ross Anderson and Eli Biham.
+ VMAC is a message authentication algorithm designed for
+ very high speed on 64-bit architectures.
- See also:
- <http://www.cs.technion.ac.il/~biham/Reports/Tiger/>.
+ See https://fastcrypto.org/vmac for further information.
config CRYPTO_WP512
- tristate "Whirlpool digest algorithms"
+ tristate "Whirlpool"
select CRYPTO_HASH
help
- Whirlpool hash algorithm 512, 384 and 256-bit hashes
-
- Whirlpool-512 is part of the NESSIE cryptographic primitives.
- Whirlpool will be part of the ISO/IEC 10118-3:2003(E) standard
-
- See also:
- <http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html>
-
-config CRYPTO_GHASH_CLMUL_NI_INTEL
- tristate "GHASH hash function (CLMUL-NI accelerated)"
- depends on X86 && 64BIT
- select CRYPTO_CRYPTD
- help
- This is the x86_64 CLMUL-NI accelerated implementation of
- GHASH, the hash function used in GCM (Galois/Counter mode).
-
-comment "Ciphers"
-
-config CRYPTO_AES
- tristate "AES cipher algorithms"
- select CRYPTO_ALGAPI
- select CRYPTO_LIB_AES
- help
- AES cipher algorithms (FIPS-197). AES uses the Rijndael
- algorithm.
-
- Rijndael appears to be consistently a very good performer in
- both hardware and software across a wide range of computing
- environments regardless of its use in feedback or non-feedback
- modes. Its key setup time is excellent, and its key agility is
- good. Rijndael's very low memory requirements make it very well
- suited for restricted-space environments, in which it also
- demonstrates excellent performance. Rijndael's operations are
- among the easiest to defend against power and timing attacks.
-
- The AES specifies three key sizes: 128, 192 and 256 bits
-
- See <http://csrc.nist.gov/CryptoToolkit/aes/> for more information.
-
-config CRYPTO_AES_TI
- tristate "Fixed time AES cipher"
- select CRYPTO_ALGAPI
- select CRYPTO_LIB_AES
- help
- This is a generic implementation of AES that attempts to eliminate
- data dependent latencies as much as possible without affecting
- performance too much. It is intended for use by the generic CCM
- and GCM drivers, and other CTR or CMAC/XCBC based modes that rely
- solely on encryption (although decryption is supported as well, but
- with a more dramatic performance hit)
+ Whirlpool hash function (ISO/IEC 10118-3)
- Instead of using 16 lookup tables of 1 KB each, (8 for encryption and
- 8 for decryption), this implementation only uses just two S-boxes of
- 256 bytes each, and attempts to eliminate data dependent latencies by
- prefetching the entire table into the cache at the start of each
- block. Interrupts are also disabled to avoid races where cachelines
- are evicted when the CPU is interrupted to do something else.
+ 512, 384 and 256-bit hashes.
-config CRYPTO_AES_NI_INTEL
- tristate "AES cipher algorithms (AES-NI)"
- depends on X86
- select CRYPTO_AEAD
- select CRYPTO_LIB_AES
- select CRYPTO_ALGAPI
- select CRYPTO_SKCIPHER
- select CRYPTO_GLUE_HELPER_X86 if 64BIT
- select CRYPTO_SIMD
- help
- Use Intel AES-NI instructions for AES algorithm.
-
- AES cipher algorithms (FIPS-197). AES uses the Rijndael
- algorithm.
-
- Rijndael appears to be consistently a very good performer in
- both hardware and software across a wide range of computing
- environments regardless of its use in feedback or non-feedback
- modes. Its key setup time is excellent, and its key agility is
- good. Rijndael's very low memory requirements make it very well
- suited for restricted-space environments, in which it also
- demonstrates excellent performance. Rijndael's operations are
- among the easiest to defend against power and timing attacks.
-
- The AES specifies three key sizes: 128, 192 and 256 bits
-
- See <http://csrc.nist.gov/encryption/aes/> for more information.
-
- In addition to AES cipher algorithm support, the acceleration
- for some popular block cipher mode is supported too, including
- ECB, CBC, LRW, XTS. The 64 bit version has additional
- acceleration for CTR.
-
-config CRYPTO_AES_SPARC64
- tristate "AES cipher algorithms (SPARC64)"
- depends on SPARC64
- select CRYPTO_SKCIPHER
- help
- Use SPARC64 crypto opcodes for AES algorithm.
-
- AES cipher algorithms (FIPS-197). AES uses the Rijndael
- algorithm.
-
- Rijndael appears to be consistently a very good performer in
- both hardware and software across a wide range of computing
- environments regardless of its use in feedback or non-feedback
- modes. Its key setup time is excellent, and its key agility is
- good. Rijndael's very low memory requirements make it very well
- suited for restricted-space environments, in which it also
- demonstrates excellent performance. Rijndael's operations are
- among the easiest to defend against power and timing attacks.
-
- The AES specifies three key sizes: 128, 192 and 256 bits
-
- See <http://csrc.nist.gov/encryption/aes/> for more information.
-
- In addition to AES cipher algorithm support, the acceleration
- for some popular block cipher mode is supported too, including
- ECB and CBC.
-
-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.
- This module should only be used for low power (router) devices
- without hardware AES acceleration (e.g. caam crypto). It reduces the
- size of the AES tables from 16KB to 8KB + 256 bytes and mitigates
- timining attacks. Nevertheless it might be not as secure as other
- architecture specific assembler implementations that work on 1KB
- tables or 256 bytes S-boxes.
-
-config CRYPTO_ANUBIS
- tristate "Anubis cipher algorithm"
- select CRYPTO_ALGAPI
- help
- Anubis cipher algorithm.
-
- Anubis is a variable key length cipher which can use keys from
- 128 bits to 320 bits in length. It was evaluated as a entrant
- in the NESSIE competition.
-
- See also:
- <https://www.cosic.esat.kuleuven.be/nessie/reports/>
- <http://www.larc.usp.br/~pbarreto/AnubisPage.html>
-
-config CRYPTO_ARC4
- tristate "ARC4 cipher algorithm"
- select CRYPTO_SKCIPHER
- select CRYPTO_LIB_ARC4
- help
- ARC4 cipher algorithm.
-
- ARC4 is a stream cipher using keys ranging from 8 bits to 2048
- bits in length. This algorithm is required for driver-based
- WEP, but it should not be for other purposes because of the
- weakness of the algorithm.
-
-config CRYPTO_BLOWFISH
- tristate "Blowfish cipher algorithm"
- select CRYPTO_ALGAPI
- select CRYPTO_BLOWFISH_COMMON
- help
- Blowfish cipher algorithm, by Bruce Schneier.
-
- This is a variable key length cipher which can use keys from 32
- bits to 448 bits in length. It's fast, simple and specifically
- designed for use on "large microprocessors".
-
- See also:
- <http://www.schneier.com/blowfish.html>
-
-config CRYPTO_BLOWFISH_COMMON
- tristate
- help
- Common parts of the Blowfish cipher algorithm shared by the
- generic c and the assembler implementations.
-
- See also:
- <http://www.schneier.com/blowfish.html>
-
-config CRYPTO_BLOWFISH_X86_64
- tristate "Blowfish cipher algorithm (x86_64)"
- depends on X86 && 64BIT
- select CRYPTO_SKCIPHER
- select CRYPTO_BLOWFISH_COMMON
- help
- Blowfish cipher algorithm (x86_64), by Bruce Schneier.
-
- This is a variable key length cipher which can use keys from 32
- bits to 448 bits in length. It's fast, simple and specifically
- designed for use on "large microprocessors".
-
- See also:
- <http://www.schneier.com/blowfish.html>
-
-config CRYPTO_CAMELLIA
- tristate "Camellia cipher algorithms"
- depends on CRYPTO
- select CRYPTO_ALGAPI
- help
- Camellia cipher algorithms module.
-
- Camellia is a symmetric key block cipher developed jointly
- at NTT and Mitsubishi Electric Corporation.
-
- The Camellia specifies three key sizes: 128, 192 and 256 bits.
-
- See also:
- <https://info.isl.ntt.co.jp/crypt/eng/camellia/index_s.html>
-
-config CRYPTO_CAMELLIA_X86_64
- tristate "Camellia cipher algorithm (x86_64)"
- depends on X86 && 64BIT
- depends on CRYPTO
- select CRYPTO_SKCIPHER
- select CRYPTO_GLUE_HELPER_X86
- help
- Camellia cipher algorithm module (x86_64).
-
- Camellia is a symmetric key block cipher developed jointly
- at NTT and Mitsubishi Electric Corporation.
-
- The Camellia specifies three key sizes: 128, 192 and 256 bits.
-
- See also:
- <https://info.isl.ntt.co.jp/crypt/eng/camellia/index_s.html>
-
-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_SKCIPHER
- select CRYPTO_CAMELLIA_X86_64
- select CRYPTO_GLUE_HELPER_X86
- select CRYPTO_SIMD
- select CRYPTO_XTS
- help
- Camellia cipher algorithm module (x86_64/AES-NI/AVX).
-
- Camellia is a symmetric key block cipher developed jointly
- at NTT and Mitsubishi Electric Corporation.
-
- The Camellia specifies three key sizes: 128, 192 and 256 bits.
-
- See also:
- <https://info.isl.ntt.co.jp/crypt/eng/camellia/index_s.html>
-
-config CRYPTO_CAMELLIA_AESNI_AVX2_X86_64
- tristate "Camellia cipher algorithm (x86_64/AES-NI/AVX2)"
- depends on X86 && 64BIT
- depends on CRYPTO
- select CRYPTO_CAMELLIA_AESNI_AVX_X86_64
- help
- Camellia cipher algorithm module (x86_64/AES-NI/AVX2).
-
- Camellia is a symmetric key block cipher developed jointly
- at NTT and Mitsubishi Electric Corporation.
-
- The Camellia specifies three key sizes: 128, 192 and 256 bits.
-
- See also:
- <https://info.isl.ntt.co.jp/crypt/eng/camellia/index_s.html>
-
-config CRYPTO_CAMELLIA_SPARC64
- tristate "Camellia cipher algorithm (SPARC64)"
- depends on SPARC64
- depends on CRYPTO
- select CRYPTO_ALGAPI
- select CRYPTO_SKCIPHER
- help
- Camellia cipher algorithm module (SPARC64).
-
- Camellia is a symmetric key block cipher developed jointly
- at NTT and Mitsubishi Electric Corporation.
-
- The Camellia specifies three key sizes: 128, 192 and 256 bits.
-
- See also:
- <https://info.isl.ntt.co.jp/crypt/eng/camellia/index_s.html>
-
-config CRYPTO_CAST_COMMON
- tristate
- help
- Common parts of the CAST cipher algorithms shared by the
- generic c and the assembler implementations.
-
-config CRYPTO_CAST5
- tristate "CAST5 (CAST-128) cipher algorithm"
- select CRYPTO_ALGAPI
- select CRYPTO_CAST_COMMON
- help
- The CAST5 encryption algorithm (synonymous with CAST-128) is
- described in RFC2144.
-
-config CRYPTO_CAST5_AVX_X86_64
- tristate "CAST5 (CAST-128) cipher algorithm (x86_64/AVX)"
- depends on X86 && 64BIT
- select CRYPTO_SKCIPHER
- select CRYPTO_CAST5
- select CRYPTO_CAST_COMMON
- select CRYPTO_SIMD
- help
- The CAST5 encryption algorithm (synonymous with CAST-128) is
- described in RFC2144.
-
- This module provides the Cast5 cipher algorithm that processes
- sixteen blocks parallel using the AVX instruction set.
-
-config CRYPTO_CAST6
- tristate "CAST6 (CAST-256) cipher algorithm"
- select CRYPTO_ALGAPI
- select CRYPTO_CAST_COMMON
- help
- The CAST6 encryption algorithm (synonymous with CAST-256) is
- described in RFC2612.
-
-config CRYPTO_CAST6_AVX_X86_64
- tristate "CAST6 (CAST-256) cipher algorithm (x86_64/AVX)"
- depends on X86 && 64BIT
- select CRYPTO_SKCIPHER
- select CRYPTO_CAST6
- select CRYPTO_CAST_COMMON
- select CRYPTO_GLUE_HELPER_X86
- select CRYPTO_SIMD
- select CRYPTO_XTS
- help
- The CAST6 encryption algorithm (synonymous with CAST-256) is
- described in RFC2612.
-
- This module provides the Cast6 cipher algorithm that processes
- eight blocks parallel using the AVX instruction set.
-
-config CRYPTO_DES
- tristate "DES and Triple DES EDE cipher algorithms"
- select CRYPTO_ALGAPI
- select CRYPTO_LIB_DES
- help
- DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
-
-config CRYPTO_DES_SPARC64
- tristate "DES and Triple DES EDE cipher algorithms (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.
-
-config CRYPTO_DES3_EDE_X86_64
- tristate "Triple DES EDE cipher algorithm (x86-64)"
- depends on X86 && 64BIT
- select CRYPTO_SKCIPHER
- select CRYPTO_LIB_DES
- help
- Triple DES EDE (FIPS 46-3) algorithm.
-
- This module provides implementation of the Triple DES EDE cipher
- algorithm that is optimized for x86-64 processors. Two versions of
- algorithm are provided; regular processing one input block and
- one that processes three blocks parallel.
-
-config CRYPTO_FCRYPT
- tristate "FCrypt cipher algorithm"
- select CRYPTO_ALGAPI
- select CRYPTO_SKCIPHER
- help
- FCrypt algorithm used by RxRPC.
-
-config CRYPTO_KHAZAD
- tristate "Khazad cipher algorithm"
- select CRYPTO_ALGAPI
- help
- Khazad cipher algorithm.
-
- Khazad was a finalist in the initial NESSIE competition. It is
- an algorithm optimized for 64-bit processors with good performance
- on 32-bit processors. Khazad uses an 128 bit key size.
-
- See also:
- <http://www.larc.usp.br/~pbarreto/KhazadPage.html>
-
-config CRYPTO_SALSA20
- tristate "Salsa20 stream cipher algorithm"
- select CRYPTO_SKCIPHER
- help
- Salsa20 stream cipher algorithm.
-
- Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT
- Stream Cipher Project. See <http://www.ecrypt.eu.org/stream/>
-
- The Salsa20 stream cipher algorithm is designed by Daniel J.
- Bernstein <djb@cr.yp.to>. See <http://cr.yp.to/snuffle.html>
-
-config CRYPTO_CHACHA20
- tristate "ChaCha stream cipher algorithms"
- select CRYPTO_LIB_CHACHA_GENERIC
- select CRYPTO_SKCIPHER
- help
- The ChaCha20, XChaCha20, and XChaCha12 stream cipher algorithms.
-
- ChaCha20 is a 256-bit high-speed stream cipher designed by Daniel J.
- Bernstein and further specified in RFC7539 for use in IETF protocols.
- This is the portable C implementation of ChaCha20. See also:
- <http://cr.yp.to/chacha/chacha-20080128.pdf>
-
- XChaCha20 is the application of the XSalsa20 construction to ChaCha20
- rather than to Salsa20. XChaCha20 extends ChaCha20's nonce length
- from 64 bits (or 96 bits using the RFC7539 convention) to 192 bits,
- while provably retaining ChaCha20's security. See also:
- <https://cr.yp.to/snuffle/xsalsa-20081128.pdf>
-
- XChaCha12 is XChaCha20 reduced to 12 rounds, with correspondingly
- reduced security margin but increased performance. It can be needed
- in some performance-sensitive scenarios.
-
-config CRYPTO_CHACHA20_X86_64
- tristate "ChaCha stream cipher algorithms (x86_64/SSSE3/AVX2/AVX-512VL)"
- depends on X86 && 64BIT
- 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
- help
- SEED cipher algorithm (RFC4269).
-
- SEED is a 128-bit symmetric key block cipher that has been
- developed by KISA (Korea Information Security Agency) as a
- national standard encryption algorithm of the Republic of Korea.
- It is a 16 round block cipher with the key size of 128 bit.
-
- See also:
- <http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp>
-
-config CRYPTO_SERPENT
- tristate "Serpent cipher algorithm"
- select CRYPTO_ALGAPI
- help
- Serpent cipher algorithm, by Anderson, Biham & Knudsen.
-
- Keys are allowed to be from 0 to 256 bits in length, in steps
- of 8 bits. Also includes the 'Tnepres' algorithm, a reversed
- variant of Serpent for compatibility with old kerneli.org code.
-
- See also:
- <http://www.cl.cam.ac.uk/~rja14/serpent.html>
-
-config CRYPTO_SERPENT_SSE2_X86_64
- tristate "Serpent cipher algorithm (x86_64/SSE2)"
- depends on X86 && 64BIT
- select CRYPTO_SKCIPHER
- select CRYPTO_GLUE_HELPER_X86
- select CRYPTO_SERPENT
- select CRYPTO_SIMD
- help
- Serpent cipher algorithm, by Anderson, Biham & Knudsen.
-
- Keys are allowed to be from 0 to 256 bits in length, in steps
- of 8 bits.
-
- This module provides Serpent cipher algorithm that processes eight
- blocks parallel using SSE2 instruction set.
-
- See also:
- <http://www.cl.cam.ac.uk/~rja14/serpent.html>
-
-config CRYPTO_SERPENT_SSE2_586
- tristate "Serpent cipher algorithm (i586/SSE2)"
- depends on X86 && !64BIT
- select CRYPTO_SKCIPHER
- select CRYPTO_GLUE_HELPER_X86
- select CRYPTO_SERPENT
- select CRYPTO_SIMD
- help
- Serpent cipher algorithm, by Anderson, Biham & Knudsen.
-
- Keys are allowed to be from 0 to 256 bits in length, in steps
- of 8 bits.
-
- This module provides Serpent cipher algorithm that processes four
- blocks parallel using SSE2 instruction set.
-
- See also:
- <http://www.cl.cam.ac.uk/~rja14/serpent.html>
-
-config CRYPTO_SERPENT_AVX_X86_64
- tristate "Serpent cipher algorithm (x86_64/AVX)"
- depends on X86 && 64BIT
- select CRYPTO_SKCIPHER
- select CRYPTO_GLUE_HELPER_X86
- select CRYPTO_SERPENT
- select CRYPTO_SIMD
- select CRYPTO_XTS
- help
- Serpent cipher algorithm, by Anderson, Biham & Knudsen.
-
- Keys are allowed to be from 0 to 256 bits in length, in steps
- of 8 bits.
-
- This module provides the Serpent cipher algorithm that processes
- eight blocks parallel using the AVX instruction set.
-
- See also:
- <http://www.cl.cam.ac.uk/~rja14/serpent.html>
-
-config CRYPTO_SERPENT_AVX2_X86_64
- tristate "Serpent cipher algorithm (x86_64/AVX2)"
- depends on X86 && 64BIT
- select CRYPTO_SERPENT_AVX_X86_64
- help
- Serpent cipher algorithm, by Anderson, Biham & Knudsen.
-
- Keys are allowed to be from 0 to 256 bits in length, in steps
- of 8 bits.
-
- This module provides Serpent cipher algorithm that processes 16
- blocks parallel using AVX2 instruction set.
+ Whirlpool-512 is part of the NESSIE cryptographic primitives.
- See also:
- <http://www.cl.cam.ac.uk/~rja14/serpent.html>
+ See https://web.archive.org/web/20171129084214/http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html
+ for further information.
-config CRYPTO_SM4
- tristate "SM4 cipher algorithm"
- select CRYPTO_ALGAPI
+config CRYPTO_XCBC
+ tristate "XCBC-MAC (Extended Cipher Block Chaining MAC)"
+ select CRYPTO_HASH
+ select CRYPTO_MANAGER
help
- SM4 cipher algorithms (OSCCA GB/T 32907-2016).
-
- SM4 (GBT.32907-2016) is a cryptographic standard issued by the
- Organization of State Commercial Administration of China (OSCCA)
- as an authorized cryptographic algorithms for the use within China.
+ XCBC-MAC (Extended Cipher Block Chaining Message Authentication
+ Code) (RFC3566)
- SMS4 was originally created for use in protecting wireless
- networks, and is mandated in the Chinese National Standard for
- Wireless LAN WAPI (Wired Authentication and Privacy Infrastructure)
- (GB.15629.11-2003).
-
- The latest SM4 standard (GBT.32907-2016) was proposed by OSCCA and
- standardized through TC 260 of the Standardization Administration
- of the People's Republic of China (SAC).
-
- The input, output, and key of SMS4 are each 128 bits.
-
- See also: <https://eprint.iacr.org/2008/329.pdf>
-
- If unsure, say N.
-
-config CRYPTO_TEA
- tristate "TEA, XTEA and XETA cipher algorithms"
- select CRYPTO_ALGAPI
+config CRYPTO_XXHASH
+ tristate "xxHash"
+ select CRYPTO_HASH
+ select XXHASH
help
- TEA cipher algorithm.
-
- Tiny Encryption Algorithm is a simple cipher that uses
- many rounds for security. It is very fast and uses
- little memory.
+ xxHash non-cryptographic hash algorithm
- Xtendend Tiny Encryption Algorithm is a modification to
- the TEA algorithm to address a potential key weakness
- in the TEA algorithm.
-
- Xtendend Encryption Tiny Algorithm is a mis-implementation
- of the XTEA algorithm for compatibility purposes.
+ Extremely fast, working at speeds close to RAM limits.
-config CRYPTO_TWOFISH
- tristate "Twofish cipher algorithm"
- select CRYPTO_ALGAPI
- select CRYPTO_TWOFISH_COMMON
- help
- Twofish cipher algorithm.
+ Used by the btrfs filesystem.
- Twofish was submitted as an AES (Advanced Encryption Standard)
- candidate cipher by researchers at CounterPane Systems. It is a
- 16 round block cipher supporting key sizes of 128, 192, and 256
- bits.
+endmenu
- See also:
- <http://www.schneier.com/twofish.html>
+menu "CRCs (cyclic redundancy checks)"
-config CRYPTO_TWOFISH_COMMON
- tristate
- help
- Common parts of the Twofish cipher algorithm shared by the
- generic c and the assembler implementations.
-
-config CRYPTO_TWOFISH_586
- tristate "Twofish cipher algorithms (i586)"
- depends on (X86 || UML_X86) && !64BIT
- select CRYPTO_ALGAPI
- select CRYPTO_TWOFISH_COMMON
+config CRYPTO_CRC32C
+ tristate "CRC32c"
+ select CRYPTO_HASH
+ select CRC32
help
- Twofish cipher algorithm.
+ CRC32c CRC algorithm with the iSCSI polynomial (RFC 3385 and RFC 3720)
- Twofish was submitted as an AES (Advanced Encryption Standard)
- candidate cipher by researchers at CounterPane Systems. It is a
- 16 round block cipher supporting key sizes of 128, 192, and 256
- bits.
+ A 32-bit CRC (cyclic redundancy check) with a polynomial defined
+ by G. Castagnoli, S. Braeuer and M. Herrman in "Optimization of Cyclic
+ Redundancy-Check Codes with 24 and 32 Parity Bits", IEEE Transactions
+ on Communications, Vol. 41, No. 6, June 1993, selected for use with
+ iSCSI.
- See also:
- <http://www.schneier.com/twofish.html>
+ Used by btrfs, ext4, jbd2, NVMeoF/TCP, and iSCSI.
-config CRYPTO_TWOFISH_X86_64
- tristate "Twofish cipher algorithm (x86_64)"
- depends on (X86 || UML_X86) && 64BIT
- select CRYPTO_ALGAPI
- select CRYPTO_TWOFISH_COMMON
+config CRYPTO_CRC32
+ tristate "CRC32"
+ select CRYPTO_HASH
+ select CRC32
help
- Twofish cipher algorithm (x86_64).
-
- Twofish was submitted as an AES (Advanced Encryption Standard)
- candidate cipher by researchers at CounterPane Systems. It is a
- 16 round block cipher supporting key sizes of 128, 192, and 256
- bits.
+ CRC32 CRC algorithm (IEEE 802.3)
- See also:
- <http://www.schneier.com/twofish.html>
+ Used by RoCEv2 and f2fs.
-config CRYPTO_TWOFISH_X86_64_3WAY
- tristate "Twofish cipher algorithm (x86_64, 3-way parallel)"
- depends on X86 && 64BIT
- select CRYPTO_SKCIPHER
- select CRYPTO_TWOFISH_COMMON
- select CRYPTO_TWOFISH_X86_64
- select CRYPTO_GLUE_HELPER_X86
+config CRYPTO_CRCT10DIF
+ tristate "CRCT10DIF"
+ select CRYPTO_HASH
help
- Twofish cipher algorithm (x86_64, 3-way parallel).
+ CRC16 CRC algorithm used for the T10 (SCSI) Data Integrity Field (DIF)
- Twofish was submitted as an AES (Advanced Encryption Standard)
- candidate cipher by researchers at CounterPane Systems. It is a
- 16 round block cipher supporting key sizes of 128, 192, and 256
- bits.
+ CRC algorithm used by the SCSI Block Commands standard.
- This module provides Twofish cipher algorithm that processes three
- blocks parallel, utilizing resources of out-of-order CPUs better.
-
- See also:
- <http://www.schneier.com/twofish.html>
-
-config CRYPTO_TWOFISH_AVX_X86_64
- tristate "Twofish cipher algorithm (x86_64/AVX)"
- depends on X86 && 64BIT
- select CRYPTO_SKCIPHER
- select CRYPTO_GLUE_HELPER_X86
- select CRYPTO_SIMD
- select CRYPTO_TWOFISH_COMMON
- select CRYPTO_TWOFISH_X86_64
- select CRYPTO_TWOFISH_X86_64_3WAY
+config CRYPTO_CRC64_ROCKSOFT
+ tristate "CRC64 based on Rocksoft Model algorithm"
+ depends on CRC64
+ select CRYPTO_HASH
help
- Twofish cipher algorithm (x86_64/AVX).
+ CRC64 CRC algorithm based on the Rocksoft Model CRC Algorithm
- Twofish was submitted as an AES (Advanced Encryption Standard)
- candidate cipher by researchers at CounterPane Systems. It is a
- 16 round block cipher supporting key sizes of 128, 192, and 256
- bits.
+ Used by the NVMe implementation of T10 DIF (BLK_DEV_INTEGRITY)
- This module provides the Twofish cipher algorithm that processes
- eight blocks parallel using the AVX Instruction Set.
+ See https://zlib.net/crc_v3.txt
- See also:
- <http://www.schneier.com/twofish.html>
+endmenu
-comment "Compression"
+menu "Compression"
config CRYPTO_DEFLATE
- tristate "Deflate compression algorithm"
+ tristate "Deflate"
select CRYPTO_ALGAPI
select CRYPTO_ACOMP2
select ZLIB_INFLATE
select ZLIB_DEFLATE
help
- This is the Deflate algorithm (RFC1951), specified for use in
- IPSec with the IPCOMP protocol (RFC3173, RFC2394).
+ Deflate compression algorithm (RFC1951)
- You will most probably want this if using IPSec.
+ Used by IPSec with the IPCOMP protocol (RFC3173, RFC2394)
config CRYPTO_LZO
- tristate "LZO compression algorithm"
+ tristate "LZO"
select CRYPTO_ALGAPI
select CRYPTO_ACOMP2
select LZO_COMPRESS
select LZO_DECOMPRESS
help
- This is the LZO algorithm.
+ LZO compression algorithm
+
+ See https://www.oberhumer.com/opensource/lzo/ for further information.
config CRYPTO_842
- tristate "842 compression algorithm"
+ tristate "842"
select CRYPTO_ALGAPI
select CRYPTO_ACOMP2
select 842_COMPRESS
select 842_DECOMPRESS
help
- This is the 842 algorithm.
+ 842 compression algorithm by IBM
+
+ See https://github.com/plauth/lib842 for further information.
config CRYPTO_LZ4
- tristate "LZ4 compression algorithm"
+ tristate "LZ4"
select CRYPTO_ALGAPI
select CRYPTO_ACOMP2
select LZ4_COMPRESS
select LZ4_DECOMPRESS
help
- This is the LZ4 algorithm.
+ LZ4 compression algorithm
+
+ See https://github.com/lz4/lz4 for further information.
config CRYPTO_LZ4HC
- tristate "LZ4HC compression algorithm"
+ tristate "LZ4HC"
select CRYPTO_ALGAPI
select CRYPTO_ACOMP2
select LZ4HC_COMPRESS
select LZ4_DECOMPRESS
help
- This is the LZ4 high compression mode algorithm.
+ LZ4 high compression mode algorithm
+
+ See https://github.com/lz4/lz4 for further information.
config CRYPTO_ZSTD
- tristate "Zstd compression algorithm"
+ tristate "Zstd"
select CRYPTO_ALGAPI
select CRYPTO_ACOMP2
select ZSTD_COMPRESS
select ZSTD_DECOMPRESS
help
- This is the zstd algorithm.
+ zstd compression algorithm
+
+ See https://github.com/facebook/zstd for further information.
+
+endmenu
-comment "Random Number Generation"
+menu "Random number generation"
config CRYPTO_ANSI_CPRNG
- tristate "Pseudo Random Number Generation for Cryptographic modules"
+ tristate "ANSI PRNG (Pseudo Random Number Generator)"
select CRYPTO_AES
select CRYPTO_RNG
help
- This option enables the generic pseudo random number generator
- for cryptographic modules. Uses the Algorithm specified in
- ANSI X9.31 A.2.4. Note that this option must be enabled if
- CRYPTO_FIPS is selected
+ Pseudo RNG (random number generator) (ANSI X9.31 Appendix A.2.4)
+
+ This uses the AES cipher algorithm.
+
+ Note that this option must be enabled if CRYPTO_FIPS is selected
menuconfig CRYPTO_DRBG_MENU
- tristate "NIST SP800-90A DRBG"
+ tristate "NIST SP800-90A DRBG (Deterministic Random Bit Generator)"
help
- NIST SP800-90A compliant DRBG. In the following submenu, one or
- more of the DRBG types must be selected.
+ DRBG (Deterministic Random Bit Generator) (NIST SP800-90A)
+
+ In the following submenu, one or more of the DRBG types must be selected.
if CRYPTO_DRBG_MENU
@@ -1809,20 +1250,24 @@ config CRYPTO_DRBG_HMAC
bool
default y
select CRYPTO_HMAC
- select CRYPTO_SHA256
+ select CRYPTO_SHA512
config CRYPTO_DRBG_HASH
- bool "Enable Hash DRBG"
+ bool "Hash_DRBG"
select CRYPTO_SHA256
help
- Enable the Hash DRBG variant as defined in NIST SP800-90A.
+ Hash_DRBG variant as defined in NIST SP800-90A.
+
+ This uses the SHA-1, SHA-256, SHA-384, or SHA-512 hash algorithms.
config CRYPTO_DRBG_CTR
- bool "Enable CTR DRBG"
+ bool "CTR_DRBG"
select CRYPTO_AES
- depends on CRYPTO_CTR
+ select CRYPTO_CTR
help
- Enable the CTR DRBG variant as defined in NIST SP800-90A.
+ CTR_DRBG variant as defined in NIST SP800-90A.
+
+ This uses the AES cipher algorithm with the counter block mode.
config CRYPTO_DRBG
tristate
@@ -1833,72 +1278,143 @@ config CRYPTO_DRBG
endif # if CRYPTO_DRBG_MENU
config CRYPTO_JITTERENTROPY
- tristate "Jitterentropy Non-Deterministic Random Number Generator"
+ tristate "CPU Jitter Non-Deterministic RNG (Random Number Generator)"
select CRYPTO_RNG
help
- The Jitterentropy RNG is a noise that is intended
- to provide seed to another RNG. The RNG does not
- perform any cryptographic whitening of the generated
- random numbers. This Jitterentropy RNG registers with
- the kernel crypto API and can be used by any caller.
+ CPU Jitter RNG (Random Number Generator) from the Jitterentropy library
+
+ A non-physical non-deterministic ("true") RNG (e.g., an entropy source
+ compliant with NIST SP800-90B) intended to provide a seed to a
+ deterministic RNG (e.g. per NIST SP800-90C).
+ This RNG does not perform any cryptographic whitening of the generated
+
+ See https://www.chronox.de/jent.html
+
+config CRYPTO_KDF800108_CTR
+ tristate
+ select CRYPTO_HMAC
+ select CRYPTO_SHA256
+
+endmenu
+menu "Userspace interface"
config CRYPTO_USER_API
tristate
config CRYPTO_USER_API_HASH
- tristate "User-space interface for hash algorithms"
+ tristate "Hash algorithms"
depends on NET
select CRYPTO_HASH
select CRYPTO_USER_API
help
- This option enables the user-spaces interface for hash
- algorithms.
+ Enable the userspace interface for hash algorithms.
+
+ See Documentation/crypto/userspace-if.rst and
+ https://www.chronox.de/libkcapi/html/index.html
config CRYPTO_USER_API_SKCIPHER
- tristate "User-space interface for symmetric key cipher algorithms"
+ tristate "Symmetric key cipher algorithms"
depends on NET
select CRYPTO_SKCIPHER
select CRYPTO_USER_API
help
- This option enables the user-spaces interface for symmetric
- key cipher algorithms.
+ Enable the userspace interface for symmetric key cipher algorithms.
+
+ See Documentation/crypto/userspace-if.rst and
+ https://www.chronox.de/libkcapi/html/index.html
config CRYPTO_USER_API_RNG
- tristate "User-space interface for random number generator algorithms"
+ tristate "RNG (random number generator) algorithms"
depends on NET
select CRYPTO_RNG
select CRYPTO_USER_API
help
- This option enables the user-spaces interface for random
- number generator algorithms.
+ Enable the userspace interface for RNG (random number generator)
+ algorithms.
+
+ See Documentation/crypto/userspace-if.rst and
+ https://www.chronox.de/libkcapi/html/index.html
+
+config CRYPTO_USER_API_RNG_CAVP
+ bool "Enable CAVP testing of DRBG"
+ depends on CRYPTO_USER_API_RNG && CRYPTO_DRBG
+ help
+ Enable extra APIs in the userspace interface for NIST CAVP
+ (Cryptographic Algorithm Validation Program) testing:
+ - resetting DRBG entropy
+ - providing Additional Data
+
+ This should only be enabled for CAVP testing. You should say
+ no unless you know what this is.
config CRYPTO_USER_API_AEAD
- tristate "User-space interface for AEAD cipher algorithms"
+ tristate "AEAD cipher algorithms"
depends on NET
select CRYPTO_AEAD
select CRYPTO_SKCIPHER
select CRYPTO_NULL
select CRYPTO_USER_API
help
- This option enables the user-spaces interface for AEAD
- cipher algorithms.
+ Enable the userspace interface for AEAD cipher algorithms.
+
+ See Documentation/crypto/userspace-if.rst and
+ https://www.chronox.de/libkcapi/html/index.html
+
+config CRYPTO_USER_API_ENABLE_OBSOLETE
+ bool "Obsolete cryptographic algorithms"
+ depends on CRYPTO_USER_API
+ default y
+ help
+ Allow obsolete cryptographic algorithms to be selected that have
+ already been phased out from internal use by the kernel, and are
+ only useful for userspace clients that still rely on them.
config CRYPTO_STATS
- bool "Crypto usage statistics for User-space"
+ bool "Crypto usage statistics"
depends on CRYPTO_USER
help
- This option enables the gathering of crypto stats.
- This will collect:
- - encrypt/decrypt size and numbers of symmeric operations
- - compress/decompress size and numbers of compress operations
- - size and numbers of hash operations
- - encrypt/decrypt/sign/verify numbers for asymmetric operations
- - generate/seed numbers for rng operations
+ Enable the gathering of crypto stats.
+
+ This collects data sizes, numbers of requests, and numbers
+ of errors processed by:
+ - AEAD ciphers (encrypt, decrypt)
+ - asymmetric key ciphers (encrypt, decrypt, verify, sign)
+ - symmetric key ciphers (encrypt, decrypt)
+ - compression algorithms (compress, decompress)
+ - hash algorithms (hash)
+ - key-agreement protocol primitives (setsecret, generate
+ public key, compute shared secret)
+ - RNG (generate, seed)
+
+endmenu
config CRYPTO_HASH_INFO
bool
-source "lib/crypto/Kconfig"
+if !KMSAN # avoid false positives from assembly
+if ARM
+source "arch/arm/crypto/Kconfig"
+endif
+if ARM64
+source "arch/arm64/crypto/Kconfig"
+endif
+if MIPS
+source "arch/mips/crypto/Kconfig"
+endif
+if PPC
+source "arch/powerpc/crypto/Kconfig"
+endif
+if S390
+source "arch/s390/crypto/Kconfig"
+endif
+if SPARC
+source "arch/sparc/crypto/Kconfig"
+endif
+if X86
+source "arch/x86/crypto/Kconfig"
+endif
+endif
+
source "drivers/crypto/Kconfig"
source "crypto/asymmetric_keys/Kconfig"
source "certs/Kconfig"
diff --git a/crypto/Makefile b/crypto/Makefile
index 4ca12b6044f7..303b21c43df0 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -4,7 +4,7 @@
#
obj-$(CONFIG_CRYPTO) += crypto.o
-crypto-y := api.o cipher.o compress.o memneq.o
+crypto-y := api.o cipher.o compress.o
obj-$(CONFIG_CRYPTO_ENGINE) += crypto_engine.o
obj-$(CONFIG_CRYPTO_FIPS) += fips.o
@@ -42,6 +42,20 @@ rsa_generic-y += rsa_helper.o
rsa_generic-y += rsa-pkcs1pad.o
obj-$(CONFIG_CRYPTO_RSA) += rsa_generic.o
+$(obj)/sm2signature.asn1.o: $(obj)/sm2signature.asn1.c $(obj)/sm2signature.asn1.h
+$(obj)/sm2.o: $(obj)/sm2signature.asn1.h
+
+sm2_generic-y += sm2signature.asn1.o
+sm2_generic-y += sm2.o
+
+obj-$(CONFIG_CRYPTO_SM2) += sm2_generic.o
+
+$(obj)/ecdsasignature.asn1.o: $(obj)/ecdsasignature.asn1.c $(obj)/ecdsasignature.asn1.h
+$(obj)/ecdsa.o: $(obj)/ecdsasignature.asn1.h
+ecdsa_generic-y += ecdsa.o
+ecdsa_generic-y += ecdsasignature.asn1.o
+obj-$(CONFIG_CRYPTO_ECDSA) += ecdsa_generic.o
+
crypto_acompress-y := acompress.o
crypto_acompress-y += scompress.o
obj-$(CONFIG_CRYPTO_ACOMP2) += crypto_acompress.o
@@ -59,21 +73,18 @@ obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o
obj-$(CONFIG_CRYPTO_NULL2) += crypto_null.o
obj-$(CONFIG_CRYPTO_MD4) += md4.o
obj-$(CONFIG_CRYPTO_MD5) += md5.o
-obj-$(CONFIG_CRYPTO_RMD128) += rmd128.o
obj-$(CONFIG_CRYPTO_RMD160) += rmd160.o
-obj-$(CONFIG_CRYPTO_RMD256) += rmd256.o
-obj-$(CONFIG_CRYPTO_RMD320) += rmd320.o
obj-$(CONFIG_CRYPTO_SHA1) += sha1_generic.o
obj-$(CONFIG_CRYPTO_SHA256) += sha256_generic.o
obj-$(CONFIG_CRYPTO_SHA512) += sha512_generic.o
obj-$(CONFIG_CRYPTO_SHA3) += sha3_generic.o
-obj-$(CONFIG_CRYPTO_SM3) += sm3_generic.o
+obj-$(CONFIG_CRYPTO_SM3) += sm3.o
+obj-$(CONFIG_CRYPTO_SM3_GENERIC) += sm3_generic.o
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
+CFLAGS_blake2b_generic.o := -Wframe-larger-than=4096 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105930
obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o
obj-$(CONFIG_CRYPTO_ECB) += ecb.o
obj-$(CONFIG_CRYPTO_CBC) += cbc.o
@@ -83,6 +94,8 @@ obj-$(CONFIG_CRYPTO_CTS) += cts.o
obj-$(CONFIG_CRYPTO_LRW) += lrw.o
obj-$(CONFIG_CRYPTO_XTS) += xts.o
obj-$(CONFIG_CRYPTO_CTR) += ctr.o
+obj-$(CONFIG_CRYPTO_XCTR) += xctr.o
+obj-$(CONFIG_CRYPTO_HCTR2) += hctr2.o
obj-$(CONFIG_CRYPTO_KEYWRAP) += keywrap.o
obj-$(CONFIG_CRYPTO_ADIANTUM) += adiantum.o
obj-$(CONFIG_CRYPTO_NHPOLY1305) += nhpoly1305.o
@@ -109,6 +122,8 @@ CFLAGS_aegis128-neon-inner.o += $(aegis128-cflags-y)
CFLAGS_REMOVE_aegis128-neon-inner.o += -mgeneral-regs-only
aegis128-$(CONFIG_CRYPTO_AEGIS128_SIMD) += aegis128-neon.o aegis128-neon-inner.o
endif
+# Enable <arm_neon.h>
+CFLAGS_aegis128-neon-inner.o += -isystem $(shell $(CC) -print-file-name=include)
obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o
obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
@@ -122,7 +137,8 @@ obj-$(CONFIG_CRYPTO_SERPENT) += serpent_generic.o
CFLAGS_serpent_generic.o := $(call cc-option,-fsched-pressure) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149
obj-$(CONFIG_CRYPTO_AES) += aes_generic.o
CFLAGS_aes_generic.o := $(call cc-option,-fno-code-hoisting) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83356
-obj-$(CONFIG_CRYPTO_SM4) += sm4_generic.o
+obj-$(CONFIG_CRYPTO_SM4) += sm4.o
+obj-$(CONFIG_CRYPTO_SM4_GENERIC) += sm4_generic.o
obj-$(CONFIG_CRYPTO_AES_TI) += aes_ti.o
obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia_generic.o
obj-$(CONFIG_CRYPTO_CAST_COMMON) += cast_common.o
@@ -133,7 +149,7 @@ obj-$(CONFIG_CRYPTO_TEA) += tea.o
obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o
obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o
obj-$(CONFIG_CRYPTO_SEED) += seed.o
-obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o
+obj-$(CONFIG_CRYPTO_ARIA) += aria_generic.o
obj-$(CONFIG_CRYPTO_CHACHA20) += chacha_generic.o
obj-$(CONFIG_CRYPTO_POLY1305) += poly1305_generic.o
obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
@@ -141,6 +157,7 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o
obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o
obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o
+obj-$(CONFIG_CRYPTO_CRC64_ROCKSOFT) += crc64_rocksoft_generic.o
obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
obj-$(CONFIG_CRYPTO_LZO) += lzo.o lzo-rle.o
obj-$(CONFIG_CRYPTO_LZ4) += lz4.o
@@ -157,6 +174,7 @@ UBSAN_SANITIZE_jitterentropy.o = n
jitterentropy_rng-y := jitterentropy.o jitterentropy-kcapi.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
+obj-$(CONFIG_CRYPTO_POLYVAL) += polyval-generic.o
obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o
obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
@@ -189,3 +207,8 @@ obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/
obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o
crypto_simd-y := simd.o
obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o
+
+#
+# Key derivation function
+#
+obj-$(CONFIG_CRYPTO_KDF800108_CTR) += kdf_sp800108.o
diff --git a/crypto/acompress.c b/crypto/acompress.c
index 84a76723e851..c32c72048a1c 100644
--- a/crypto/acompress.c
+++ b/crypto/acompress.c
@@ -109,6 +109,14 @@ struct crypto_acomp *crypto_alloc_acomp(const char *alg_name, u32 type,
}
EXPORT_SYMBOL_GPL(crypto_alloc_acomp);
+struct crypto_acomp *crypto_alloc_acomp_node(const char *alg_name, u32 type,
+ u32 mask, int node)
+{
+ return crypto_alloc_tfm_node(alg_name, &crypto_acomp_type, type, mask,
+ node);
+}
+EXPORT_SYMBOL_GPL(crypto_alloc_acomp_node);
+
struct acomp_req *acomp_request_alloc(struct crypto_acomp *acomp)
{
struct crypto_tfm *tfm = crypto_acomp_tfm(acomp);
diff --git a/crypto/adiantum.c b/crypto/adiantum.c
index cf2b9f4103dd..84450130cb6b 100644
--- a/crypto/adiantum.c
+++ b/crypto/adiantum.c
@@ -32,6 +32,7 @@
#include <crypto/b128ops.h>
#include <crypto/chacha.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/hash.h>
#include <crypto/internal/poly1305.h>
#include <crypto/internal/skcipher.h>
@@ -177,7 +178,7 @@ static int adiantum_setkey(struct crypto_skcipher *tfm, const u8 *key,
keyp += NHPOLY1305_KEY_SIZE;
WARN_ON(keyp != &data->derived_keys[ARRAY_SIZE(data->derived_keys)]);
out:
- kzfree(data);
+ kfree_sensitive(data);
return err;
}
@@ -490,7 +491,6 @@ static bool adiantum_supported_algorithms(struct skcipher_alg *streamcipher_alg,
static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
{
- struct crypto_attr_type *algt;
u32 mask;
const char *nhpoly1305_name;
struct skcipher_instance *inst;
@@ -500,14 +500,9 @@ static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
struct shash_alg *hash_alg;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask)
- return -EINVAL;
-
- mask = crypto_requires_sync(algt->type, algt->mask);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
+ if (err)
+ return err;
inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL);
if (!inst)
@@ -565,8 +560,6 @@ static int adiantum_create(struct crypto_template *tmpl, struct rtattr **tb)
hash_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
goto err_free_inst;
- inst->alg.base.cra_flags = streamcipher_alg->base.cra_flags &
- CRYPTO_ALG_ASYNC;
inst->alg.base.cra_blocksize = BLOCKCIPHER_BLOCK_SIZE;
inst->alg.base.cra_ctxsize = sizeof(struct adiantum_tfm_ctx);
inst->alg.base.cra_alignmask = streamcipher_alg->base.cra_alignmask |
@@ -624,3 +617,4 @@ MODULE_DESCRIPTION("Adiantum length-preserving encryption mode");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Eric Biggers <ebiggers@google.com>");
MODULE_ALIAS_CRYPTO("adiantum");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/aegis.h b/crypto/aegis.h
index 6920ebe77679..6ef9c174c973 100644
--- a/crypto/aegis.h
+++ b/crypto/aegis.h
@@ -21,9 +21,28 @@ union aegis_block {
u8 bytes[AEGIS_BLOCK_SIZE];
};
+struct aegis_state;
+
+extern int aegis128_have_aes_insn;
+
#define AEGIS_BLOCK_ALIGN (__alignof__(union aegis_block))
#define AEGIS_ALIGNED(p) IS_ALIGNED((uintptr_t)p, AEGIS_BLOCK_ALIGN)
+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);
+int crypto_aegis128_final_simd(struct aegis_state *state,
+ union aegis_block *tag_xor,
+ unsigned int assoclen,
+ unsigned int cryptlen,
+ unsigned int authsize);
+
static __always_inline void crypto_aegis_block_xor(union aegis_block *dst,
const union aegis_block *src)
{
diff --git a/crypto/aegis128-core.c b/crypto/aegis128-core.c
index 44fb4956f0dd..c4f1bfa1d04f 100644
--- a/crypto/aegis128-core.c
+++ b/crypto/aegis128-core.c
@@ -58,19 +58,6 @@ static bool aegis128_do_simd(void)
return false;
}
-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)
{
union aegis_block tmp;
@@ -84,9 +71,10 @@ static void crypto_aegis128_update(struct aegis_state *state)
}
static void crypto_aegis128_update_a(struct aegis_state *state,
- const union aegis_block *msg)
+ const union aegis_block *msg,
+ bool do_simd)
{
- if (aegis128_do_simd()) {
+ if (IS_ENABLED(CONFIG_CRYPTO_AEGIS128_SIMD) && do_simd) {
crypto_aegis128_update_simd(state, msg);
return;
}
@@ -95,9 +83,10 @@ static void crypto_aegis128_update_a(struct aegis_state *state,
crypto_aegis_block_xor(&state->blocks[0], msg);
}
-static void crypto_aegis128_update_u(struct aegis_state *state, const void *msg)
+static void crypto_aegis128_update_u(struct aegis_state *state, const void *msg,
+ bool do_simd)
{
- if (aegis128_do_simd()) {
+ if (IS_ENABLED(CONFIG_CRYPTO_AEGIS128_SIMD) && do_simd) {
crypto_aegis128_update_simd(state, msg);
return;
}
@@ -126,27 +115,28 @@ static void crypto_aegis128_init(struct aegis_state *state,
crypto_aegis_block_xor(&state->blocks[4], &crypto_aegis_const[1]);
for (i = 0; i < 5; i++) {
- crypto_aegis128_update_a(state, key);
- crypto_aegis128_update_a(state, &key_iv);
+ crypto_aegis128_update_a(state, key, false);
+ crypto_aegis128_update_a(state, &key_iv, false);
}
}
static void crypto_aegis128_ad(struct aegis_state *state,
- const u8 *src, unsigned int size)
+ const u8 *src, unsigned int size,
+ bool do_simd)
{
if (AEGIS_ALIGNED(src)) {
const union aegis_block *src_blk =
(const union aegis_block *)src;
while (size >= AEGIS_BLOCK_SIZE) {
- crypto_aegis128_update_a(state, src_blk);
+ crypto_aegis128_update_a(state, src_blk, do_simd);
size -= AEGIS_BLOCK_SIZE;
src_blk++;
}
} else {
while (size >= AEGIS_BLOCK_SIZE) {
- crypto_aegis128_update_u(state, src);
+ crypto_aegis128_update_u(state, src, do_simd);
size -= AEGIS_BLOCK_SIZE;
src += AEGIS_BLOCK_SIZE;
@@ -154,6 +144,12 @@ static void crypto_aegis128_ad(struct aegis_state *state,
}
}
+static void crypto_aegis128_wipe_chunk(struct aegis_state *state, u8 *dst,
+ const u8 *src, unsigned int size)
+{
+ memzero_explicit(dst, size);
+}
+
static void crypto_aegis128_encrypt_chunk(struct aegis_state *state, u8 *dst,
const u8 *src, unsigned int size)
{
@@ -172,7 +168,7 @@ static void crypto_aegis128_encrypt_chunk(struct aegis_state *state, u8 *dst,
crypto_aegis_block_xor(&tmp, &state->blocks[1]);
crypto_aegis_block_xor(&tmp, src_blk);
- crypto_aegis128_update_a(state, src_blk);
+ crypto_aegis128_update_a(state, src_blk, false);
*dst_blk = tmp;
@@ -188,7 +184,7 @@ static void crypto_aegis128_encrypt_chunk(struct aegis_state *state, u8 *dst,
crypto_aegis_block_xor(&tmp, &state->blocks[1]);
crypto_xor(tmp.bytes, src, AEGIS_BLOCK_SIZE);
- crypto_aegis128_update_u(state, src);
+ crypto_aegis128_update_u(state, src, false);
memcpy(dst, tmp.bytes, AEGIS_BLOCK_SIZE);
@@ -207,7 +203,7 @@ static void crypto_aegis128_encrypt_chunk(struct aegis_state *state, u8 *dst,
crypto_aegis_block_xor(&tmp, &state->blocks[4]);
crypto_aegis_block_xor(&tmp, &state->blocks[1]);
- crypto_aegis128_update_a(state, &msg);
+ crypto_aegis128_update_a(state, &msg, false);
crypto_aegis_block_xor(&msg, &tmp);
@@ -233,7 +229,7 @@ static void crypto_aegis128_decrypt_chunk(struct aegis_state *state, u8 *dst,
crypto_aegis_block_xor(&tmp, &state->blocks[1]);
crypto_aegis_block_xor(&tmp, src_blk);
- crypto_aegis128_update_a(state, &tmp);
+ crypto_aegis128_update_a(state, &tmp, false);
*dst_blk = tmp;
@@ -249,7 +245,7 @@ static void crypto_aegis128_decrypt_chunk(struct aegis_state *state, u8 *dst,
crypto_aegis_block_xor(&tmp, &state->blocks[1]);
crypto_xor(tmp.bytes, src, AEGIS_BLOCK_SIZE);
- crypto_aegis128_update_a(state, &tmp);
+ crypto_aegis128_update_a(state, &tmp, false);
memcpy(dst, tmp.bytes, AEGIS_BLOCK_SIZE);
@@ -271,7 +267,7 @@ static void crypto_aegis128_decrypt_chunk(struct aegis_state *state, u8 *dst,
memset(msg.bytes + size, 0, AEGIS_BLOCK_SIZE - size);
- crypto_aegis128_update_a(state, &msg);
+ crypto_aegis128_update_a(state, &msg, false);
memcpy(dst, msg.bytes, size);
}
@@ -279,7 +275,8 @@ static void crypto_aegis128_decrypt_chunk(struct aegis_state *state, u8 *dst,
static void crypto_aegis128_process_ad(struct aegis_state *state,
struct scatterlist *sg_src,
- unsigned int assoclen)
+ unsigned int assoclen,
+ bool do_simd)
{
struct scatter_walk walk;
union aegis_block buf;
@@ -296,13 +293,13 @@ static void crypto_aegis128_process_ad(struct aegis_state *state,
if (pos > 0) {
unsigned int fill = AEGIS_BLOCK_SIZE - pos;
memcpy(buf.bytes + pos, src, fill);
- crypto_aegis128_update_a(state, &buf);
+ crypto_aegis128_update_a(state, &buf, do_simd);
pos = 0;
left -= fill;
src += fill;
}
- crypto_aegis128_ad(state, src, left);
+ crypto_aegis128_ad(state, src, left, do_simd);
src += left & ~(AEGIS_BLOCK_SIZE - 1);
left &= AEGIS_BLOCK_SIZE - 1;
}
@@ -318,13 +315,12 @@ static void crypto_aegis128_process_ad(struct aegis_state *state,
if (pos > 0) {
memset(buf.bytes + pos, 0, AEGIS_BLOCK_SIZE - pos);
- crypto_aegis128_update_a(state, &buf);
+ crypto_aegis128_update_a(state, &buf, do_simd);
}
}
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,
@@ -361,7 +357,7 @@ static void crypto_aegis128_final(struct aegis_state *state,
crypto_aegis_block_xor(&tmp, &state->blocks[3]);
for (i = 0; i < 7; i++)
- crypto_aegis128_update_a(state, &tmp);
+ crypto_aegis128_update_a(state, &tmp, false);
for (i = 0; i < AEGIS128_STATE_BLOCKS; i++)
crypto_aegis_block_xor(tag_xor, &state->blocks[i]);
@@ -389,7 +385,7 @@ static int crypto_aegis128_setauthsize(struct crypto_aead *tfm,
return 0;
}
-static int crypto_aegis128_encrypt(struct aead_request *req)
+static int crypto_aegis128_encrypt_generic(struct aead_request *req)
{
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
union aegis_block tag = {};
@@ -400,27 +396,18 @@ static int crypto_aegis128_encrypt(struct aead_request *req)
struct aegis_state state;
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);
- }
+ crypto_aegis128_init(&state, &ctx->key, req->iv);
+ crypto_aegis128_process_ad(&state, req->src, req->assoclen, false);
+ crypto_aegis128_process_crypt(&state, &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);
return 0;
}
-static int crypto_aegis128_decrypt(struct aead_request *req)
+static int crypto_aegis128_decrypt_generic(struct aead_request *req)
{
static const u8 zeros[AEGIS128_MAX_AUTH_SIZE] = {};
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
@@ -435,60 +422,152 @@ static int crypto_aegis128_decrypt(struct aead_request *req)
authsize, 0);
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);
+ crypto_aegis128_init(&state, &ctx->key, req->iv);
+ crypto_aegis128_process_ad(&state, req->src, req->assoclen, false);
+ crypto_aegis128_process_crypt(&state, &walk,
+ crypto_aegis128_decrypt_chunk);
+ crypto_aegis128_final(&state, &tag, req->assoclen, cryptlen);
+
+ if (unlikely(crypto_memneq(tag.bytes, zeros, authsize))) {
+ /*
+ * From Chapter 4. 'Security Analysis' of the AEGIS spec [0]
+ *
+ * "3. If verification fails, the decrypted plaintext and the
+ * wrong authentication tag should not be given as output."
+ *
+ * [0] https://competitions.cr.yp.to/round3/aegisv11.pdf
+ */
+ skcipher_walk_aead_decrypt(&walk, req, false);
+ crypto_aegis128_process_crypt(NULL, &walk,
+ crypto_aegis128_wipe_chunk);
+ memzero_explicit(&tag, sizeof(tag));
+ return -EBADMSG;
}
-
- return crypto_memneq(tag.bytes, zeros, authsize) ? -EBADMSG : 0;
+ return 0;
}
-static struct aead_alg crypto_aegis128_alg = {
- .setkey = crypto_aegis128_setkey,
- .setauthsize = crypto_aegis128_setauthsize,
- .encrypt = crypto_aegis128_encrypt,
- .decrypt = crypto_aegis128_decrypt,
+static int crypto_aegis128_encrypt_simd(struct aead_request *req)
+{
+ 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())
+ return crypto_aegis128_encrypt_generic(req);
+
+ skcipher_walk_aead_encrypt(&walk, req, false);
+ crypto_aegis128_init_simd(&state, &ctx->key, req->iv);
+ crypto_aegis128_process_ad(&state, req->src, req->assoclen, true);
+ crypto_aegis128_process_crypt(&state, &walk,
+ crypto_aegis128_encrypt_chunk_simd);
+ crypto_aegis128_final_simd(&state, &tag, req->assoclen, cryptlen, 0);
- .ivsize = AEGIS128_NONCE_SIZE,
- .maxauthsize = AEGIS128_MAX_AUTH_SIZE,
- .chunksize = AEGIS_BLOCK_SIZE,
+ scatterwalk_map_and_copy(tag.bytes, req->dst, req->assoclen + cryptlen,
+ authsize, 1);
+ return 0;
+}
- .base = {
- .cra_blocksize = 1,
- .cra_ctxsize = sizeof(struct aegis_ctx),
- .cra_alignmask = 0,
+static int crypto_aegis128_decrypt_simd(struct aead_request *req)
+{
+ 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;
- .cra_priority = 100,
+ if (!aegis128_do_simd())
+ return crypto_aegis128_decrypt_generic(req);
- .cra_name = "aegis128",
- .cra_driver_name = "aegis128-generic",
+ scatterwalk_map_and_copy(tag.bytes, req->src, req->assoclen + cryptlen,
+ authsize, 0);
- .cra_module = THIS_MODULE,
+ skcipher_walk_aead_decrypt(&walk, req, false);
+ crypto_aegis128_init_simd(&state, &ctx->key, req->iv);
+ crypto_aegis128_process_ad(&state, req->src, req->assoclen, true);
+ crypto_aegis128_process_crypt(&state, &walk,
+ crypto_aegis128_decrypt_chunk_simd);
+
+ if (unlikely(crypto_aegis128_final_simd(&state, &tag, req->assoclen,
+ cryptlen, authsize))) {
+ skcipher_walk_aead_decrypt(&walk, req, false);
+ crypto_aegis128_process_crypt(NULL, &walk,
+ crypto_aegis128_wipe_chunk);
+ return -EBADMSG;
}
+ return 0;
+}
+
+static struct aead_alg crypto_aegis128_alg_generic = {
+ .setkey = crypto_aegis128_setkey,
+ .setauthsize = crypto_aegis128_setauthsize,
+ .encrypt = crypto_aegis128_encrypt_generic,
+ .decrypt = crypto_aegis128_decrypt_generic,
+
+ .ivsize = AEGIS128_NONCE_SIZE,
+ .maxauthsize = AEGIS128_MAX_AUTH_SIZE,
+ .chunksize = AEGIS_BLOCK_SIZE,
+
+ .base.cra_blocksize = 1,
+ .base.cra_ctxsize = sizeof(struct aegis_ctx),
+ .base.cra_alignmask = 0,
+ .base.cra_priority = 100,
+ .base.cra_name = "aegis128",
+ .base.cra_driver_name = "aegis128-generic",
+ .base.cra_module = THIS_MODULE,
+};
+
+static struct aead_alg crypto_aegis128_alg_simd = {
+ .setkey = crypto_aegis128_setkey,
+ .setauthsize = crypto_aegis128_setauthsize,
+ .encrypt = crypto_aegis128_encrypt_simd,
+ .decrypt = crypto_aegis128_decrypt_simd,
+
+ .ivsize = AEGIS128_NONCE_SIZE,
+ .maxauthsize = AEGIS128_MAX_AUTH_SIZE,
+ .chunksize = AEGIS_BLOCK_SIZE,
+
+ .base.cra_blocksize = 1,
+ .base.cra_ctxsize = sizeof(struct aegis_ctx),
+ .base.cra_alignmask = 0,
+ .base.cra_priority = 200,
+ .base.cra_name = "aegis128",
+ .base.cra_driver_name = "aegis128-simd",
+ .base.cra_module = THIS_MODULE,
};
static int __init crypto_aegis128_module_init(void)
{
+ int ret;
+
+ ret = crypto_register_aead(&crypto_aegis128_alg_generic);
+ if (ret)
+ return ret;
+
if (IS_ENABLED(CONFIG_CRYPTO_AEGIS128_SIMD) &&
- crypto_aegis128_have_simd())
+ crypto_aegis128_have_simd()) {
+ ret = crypto_register_aead(&crypto_aegis128_alg_simd);
+ if (ret) {
+ crypto_unregister_aead(&crypto_aegis128_alg_generic);
+ return ret;
+ }
static_branch_enable(&have_simd);
-
- return crypto_register_aead(&crypto_aegis128_alg);
+ }
+ return 0;
}
static void __exit crypto_aegis128_module_exit(void)
{
- crypto_unregister_aead(&crypto_aegis128_alg);
+ if (IS_ENABLED(CONFIG_CRYPTO_AEGIS128_SIMD) &&
+ crypto_aegis128_have_simd())
+ crypto_unregister_aead(&crypto_aegis128_alg_simd);
+
+ crypto_unregister_aead(&crypto_aegis128_alg_generic);
}
subsys_initcall(crypto_aegis128_module_init);
@@ -499,3 +578,4 @@ MODULE_AUTHOR("Ondrej Mosnacek <omosnacek@gmail.com>");
MODULE_DESCRIPTION("AEGIS-128 AEAD algorithm");
MODULE_ALIAS_CRYPTO("aegis128");
MODULE_ALIAS_CRYPTO("aegis128-generic");
+MODULE_ALIAS_CRYPTO("aegis128-simd");
diff --git a/crypto/aegis128-neon-inner.c b/crypto/aegis128-neon-inner.c
index 2a660ac1bc3a..7de485907d81 100644
--- a/crypto/aegis128-neon-inner.c
+++ b/crypto/aegis128-neon-inner.c
@@ -20,7 +20,6 @@
extern int aegis128_have_aes_insn;
void *memcpy(void *dest, const void *src, size_t n);
-void *memset(void *s, int c, size_t n);
struct aegis128_state {
uint8x16_t v[5];
@@ -173,10 +172,57 @@ void crypto_aegis128_update_neon(void *state, const void *msg)
aegis128_save_state_neon(st, state);
}
+#ifdef CONFIG_ARM
+/*
+ * AArch32 does not provide these intrinsics natively because it does not
+ * implement the underlying instructions. AArch32 only provides 64-bit
+ * wide vtbl.8/vtbx.8 instruction, so use those instead.
+ */
+static uint8x16_t vqtbl1q_u8(uint8x16_t a, uint8x16_t b)
+{
+ union {
+ uint8x16_t val;
+ uint8x8x2_t pair;
+ } __a = { a };
+
+ return vcombine_u8(vtbl2_u8(__a.pair, vget_low_u8(b)),
+ vtbl2_u8(__a.pair, vget_high_u8(b)));
+}
+
+static uint8x16_t vqtbx1q_u8(uint8x16_t v, uint8x16_t a, uint8x16_t b)
+{
+ union {
+ uint8x16_t val;
+ uint8x8x2_t pair;
+ } __a = { a };
+
+ return vcombine_u8(vtbx2_u8(vget_low_u8(v), __a.pair, vget_low_u8(b)),
+ vtbx2_u8(vget_high_u8(v), __a.pair, vget_high_u8(b)));
+}
+
+static int8_t vminvq_s8(int8x16_t v)
+{
+ int8x8_t s = vpmin_s8(vget_low_s8(v), vget_high_s8(v));
+
+ s = vpmin_s8(s, s);
+ s = vpmin_s8(s, s);
+ s = vpmin_s8(s, s);
+
+ return vget_lane_s8(s, 0);
+}
+#endif
+
+static const uint8_t permute[] __aligned(64) = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+};
+
void crypto_aegis128_encrypt_chunk_neon(void *state, void *dst, const void *src,
unsigned int size)
{
struct aegis128_state st = aegis128_load_state_neon(state);
+ const int short_input = size < AEGIS_BLOCK_SIZE;
uint8x16_t msg;
preload_sbox();
@@ -186,7 +232,8 @@ void crypto_aegis128_encrypt_chunk_neon(void *state, void *dst, const void *src,
msg = vld1q_u8(src);
st = aegis128_update_neon(st, msg);
- vst1q_u8(dst, msg ^ s);
+ msg ^= s;
+ vst1q_u8(dst, msg);
size -= AEGIS_BLOCK_SIZE;
src += AEGIS_BLOCK_SIZE;
@@ -195,13 +242,26 @@ void crypto_aegis128_encrypt_chunk_neon(void *state, void *dst, const void *src,
if (size > 0) {
uint8x16_t s = st.v[1] ^ (st.v[2] & st.v[3]) ^ st.v[4];
- uint8_t buf[AEGIS_BLOCK_SIZE] = {};
+ uint8_t buf[AEGIS_BLOCK_SIZE];
+ const void *in = src;
+ void *out = dst;
+ uint8x16_t m;
- memcpy(buf, src, size);
- msg = vld1q_u8(buf);
- st = aegis128_update_neon(st, msg);
- vst1q_u8(buf, msg ^ s);
- memcpy(dst, buf, size);
+ if (__builtin_expect(short_input, 0))
+ in = out = memcpy(buf + AEGIS_BLOCK_SIZE - size, src, size);
+
+ m = vqtbl1q_u8(vld1q_u8(in + size - AEGIS_BLOCK_SIZE),
+ vld1q_u8(permute + 32 - size));
+
+ st = aegis128_update_neon(st, m);
+
+ vst1q_u8(out + size - AEGIS_BLOCK_SIZE,
+ vqtbl1q_u8(m ^ s, vld1q_u8(permute + size)));
+
+ if (__builtin_expect(short_input, 0))
+ memcpy(dst, out, size);
+ else
+ vst1q_u8(out - AEGIS_BLOCK_SIZE, msg);
}
aegis128_save_state_neon(st, state);
@@ -211,6 +271,7 @@ void crypto_aegis128_decrypt_chunk_neon(void *state, void *dst, const void *src,
unsigned int size)
{
struct aegis128_state st = aegis128_load_state_neon(state);
+ const int short_input = size < AEGIS_BLOCK_SIZE;
uint8x16_t msg;
preload_sbox();
@@ -228,21 +289,34 @@ void crypto_aegis128_decrypt_chunk_neon(void *state, void *dst, const void *src,
if (size > 0) {
uint8x16_t s = st.v[1] ^ (st.v[2] & st.v[3]) ^ st.v[4];
uint8_t buf[AEGIS_BLOCK_SIZE];
+ const void *in = src;
+ void *out = dst;
+ uint8x16_t m;
- vst1q_u8(buf, s);
- memcpy(buf, src, size);
- msg = vld1q_u8(buf) ^ s;
- vst1q_u8(buf, msg);
- memcpy(dst, buf, size);
+ if (__builtin_expect(short_input, 0))
+ in = out = memcpy(buf + AEGIS_BLOCK_SIZE - size, src, size);
- st = aegis128_update_neon(st, msg);
+ m = s ^ vqtbx1q_u8(s, vld1q_u8(in + size - AEGIS_BLOCK_SIZE),
+ vld1q_u8(permute + 32 - size));
+
+ st = aegis128_update_neon(st, m);
+
+ vst1q_u8(out + size - AEGIS_BLOCK_SIZE,
+ vqtbl1q_u8(m, vld1q_u8(permute + size)));
+
+ if (__builtin_expect(short_input, 0))
+ memcpy(dst, out, size);
+ else
+ vst1q_u8(out - AEGIS_BLOCK_SIZE, msg);
}
aegis128_save_state_neon(st, state);
}
-void crypto_aegis128_final_neon(void *state, void *tag_xor, uint64_t assoclen,
- uint64_t cryptlen)
+int crypto_aegis128_final_neon(void *state, void *tag_xor,
+ unsigned int assoclen,
+ unsigned int cryptlen,
+ unsigned int authsize)
{
struct aegis128_state st = aegis128_load_state_neon(state);
uint8x16_t v;
@@ -250,13 +324,21 @@ void crypto_aegis128_final_neon(void *state, void *tag_xor, uint64_t assoclen,
preload_sbox();
- v = st.v[3] ^ (uint8x16_t)vcombine_u64(vmov_n_u64(8 * assoclen),
- vmov_n_u64(8 * cryptlen));
+ v = st.v[3] ^ (uint8x16_t)vcombine_u64(vmov_n_u64(8ULL * assoclen),
+ vmov_n_u64(8ULL * 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];
+ v = st.v[0] ^ st.v[1] ^ st.v[2] ^ st.v[3] ^ st.v[4];
+
+ if (authsize > 0) {
+ v = vqtbl1q_u8(~vceqq_u8(v, vld1q_u8(tag_xor)),
+ vld1q_u8(permute + authsize));
+
+ return vminvq_s8((int8x16_t)v);
+ }
+
vst1q_u8(tag_xor, v);
+ return 0;
}
diff --git a/crypto/aegis128-neon.c b/crypto/aegis128-neon.c
index 8271b1fa0fbc..a7856915ec85 100644
--- a/crypto/aegis128-neon.c
+++ b/crypto/aegis128-neon.c
@@ -14,8 +14,10 @@ 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 crypto_aegis128_final_neon(void *state, void *tag_xor,
+ unsigned int assoclen,
+ unsigned int cryptlen,
+ unsigned int authsize);
int aegis128_have_aes_insn __ro_after_init;
@@ -28,7 +30,7 @@ bool crypto_aegis128_have_simd(void)
return IS_ENABLED(CONFIG_ARM64);
}
-void crypto_aegis128_init_simd(union aegis_block *state,
+void crypto_aegis128_init_simd(struct aegis_state *state,
const union aegis_block *key,
const u8 *iv)
{
@@ -37,14 +39,14 @@ void crypto_aegis128_init_simd(union aegis_block *state,
kernel_neon_end();
}
-void crypto_aegis128_update_simd(union aegis_block *state, const void *msg)
+void crypto_aegis128_update_simd(struct aegis_state *state, const void *msg)
{
kernel_neon_begin();
crypto_aegis128_update_neon(state, msg);
kernel_neon_end();
}
-void crypto_aegis128_encrypt_chunk_simd(union aegis_block *state, u8 *dst,
+void crypto_aegis128_encrypt_chunk_simd(struct aegis_state *state, u8 *dst,
const u8 *src, unsigned int size)
{
kernel_neon_begin();
@@ -52,7 +54,7 @@ void crypto_aegis128_encrypt_chunk_simd(union aegis_block *state, u8 *dst,
kernel_neon_end();
}
-void crypto_aegis128_decrypt_chunk_simd(union aegis_block *state, u8 *dst,
+void crypto_aegis128_decrypt_chunk_simd(struct aegis_state *state, u8 *dst,
const u8 *src, unsigned int size)
{
kernel_neon_begin();
@@ -60,11 +62,18 @@ void crypto_aegis128_decrypt_chunk_simd(union aegis_block *state, u8 *dst,
kernel_neon_end();
}
-void crypto_aegis128_final_simd(union aegis_block *state,
- union aegis_block *tag_xor,
- u64 assoclen, u64 cryptlen)
+int crypto_aegis128_final_simd(struct aegis_state *state,
+ union aegis_block *tag_xor,
+ unsigned int assoclen,
+ unsigned int cryptlen,
+ unsigned int authsize)
{
+ int ret;
+
kernel_neon_begin();
- crypto_aegis128_final_neon(state, tag_xor, assoclen, cryptlen);
+ ret = crypto_aegis128_final_neon(state, tag_xor, assoclen, cryptlen,
+ authsize);
kernel_neon_end();
+
+ return ret;
}
diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 439367a8e95c..e893c0f6c879 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/net.h>
#include <linux/rwsem.h>
+#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/security.h>
@@ -24,12 +25,9 @@ struct alg_type_list {
struct list_head list;
};
-static atomic_long_t alg_memory_allocated;
-
static struct proto alg_proto = {
.name = "ALG",
.owner = THIS_MODULE,
- .memory_allocated = &alg_memory_allocated,
.obj_size = sizeof(struct alg_sock),
};
@@ -128,21 +126,15 @@ EXPORT_SYMBOL_GPL(af_alg_release);
void af_alg_release_parent(struct sock *sk)
{
struct alg_sock *ask = alg_sk(sk);
- unsigned int nokey = ask->nokey_refcnt;
- bool last = nokey && !ask->refcnt;
+ unsigned int nokey = atomic_read(&ask->nokey_refcnt);
sk = ask->parent;
ask = alg_sk(sk);
- local_bh_disable();
- bh_lock_sock(sk);
- ask->nokey_refcnt -= nokey;
- if (!last)
- last = !--ask->refcnt;
- bh_unlock_sock(sk);
- local_bh_enable();
+ if (nokey)
+ atomic_dec(&ask->nokey_refcnt);
- if (last)
+ if (atomic_dec_and_test(&ask->refcnt))
sock_put(sk);
}
EXPORT_SYMBOL_GPL(af_alg_release_parent);
@@ -152,7 +144,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
const u32 allowed = CRYPTO_ALG_KERN_DRIVER_ONLY;
struct sock *sk = sock->sk;
struct alg_sock *ask = alg_sk(sk);
- struct sockaddr_alg *sa = (void *)uaddr;
+ struct sockaddr_alg_new *sa = (void *)uaddr;
const struct af_alg_type *type;
void *private;
int err;
@@ -160,7 +152,11 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if (sock->state == SS_CONNECTED)
return -EINVAL;
- if (addr_len < sizeof(*sa))
+ BUILD_BUG_ON(offsetof(struct sockaddr_alg_new, salg_name) !=
+ offsetof(struct sockaddr_alg, salg_name));
+ BUILD_BUG_ON(offsetof(struct sockaddr_alg, salg_name) != sizeof(*sa));
+
+ if (addr_len < sizeof(*sa) + 1)
return -EINVAL;
/* If caller uses non-allowed flag, return error. */
@@ -168,7 +164,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
return -EINVAL;
sa->salg_type[sizeof(sa->salg_type) - 1] = 0;
- sa->salg_name[sizeof(sa->salg_name) + addr_len - sizeof(*sa) - 1] = 0;
+ sa->salg_name[addr_len - sizeof(*sa) - 1] = 0;
type = alg_get_type(sa->salg_type);
if (PTR_ERR(type) == -ENOENT) {
@@ -187,7 +183,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
err = -EBUSY;
lock_sock(sk);
- if (ask->refcnt | ask->nokey_refcnt)
+ if (atomic_read(&ask->refcnt))
goto unlock;
swap(ask->type, type);
@@ -203,8 +199,7 @@ unlock:
return err;
}
-static int alg_setkey(struct sock *sk, char __user *ukey,
- unsigned int keylen)
+static int alg_setkey(struct sock *sk, sockptr_t ukey, unsigned int keylen)
{
struct alg_sock *ask = alg_sk(sk);
const struct af_alg_type *type = ask->type;
@@ -216,7 +211,7 @@ static int alg_setkey(struct sock *sk, char __user *ukey,
return -ENOMEM;
err = -EFAULT;
- if (copy_from_user(key, ukey, keylen))
+ if (copy_from_sockptr(key, ukey, keylen))
goto out;
err = type->setkey(ask->private, key, keylen);
@@ -228,7 +223,7 @@ out:
}
static int alg_setsockopt(struct socket *sock, int level, int optname,
- char __user *optval, unsigned int optlen)
+ sockptr_t optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct alg_sock *ask = alg_sk(sk);
@@ -236,7 +231,7 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
int err = -EBUSY;
lock_sock(sk);
- if (ask->refcnt)
+ if (atomic_read(&ask->refcnt) != atomic_read(&ask->nokey_refcnt))
goto unlock;
type = ask->type;
@@ -260,6 +255,14 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
if (!type->setauthsize)
goto unlock;
err = type->setauthsize(ask->private, optlen);
+ break;
+ case ALG_SET_DRBG_ENTROPY:
+ if (sock->state == SS_CONNECTED)
+ goto unlock;
+ if (!type->setentropy)
+ goto unlock;
+
+ err = type->setentropy(ask->private, optval, optlen);
}
unlock:
@@ -292,6 +295,11 @@ int af_alg_accept(struct sock *sk, struct socket *newsock, bool kern)
security_sock_graft(sk2, newsock);
security_sk_clone(sk, sk2);
+ /*
+ * newsock->ops assigned here to allow type->accept call to override
+ * them when required.
+ */
+ newsock->ops = type->ops;
err = type->accept(ask->private, sk2);
nokey = err == -ENOKEY;
@@ -301,14 +309,15 @@ int af_alg_accept(struct sock *sk, struct socket *newsock, bool kern)
if (err)
goto unlock;
- if (nokey || !ask->refcnt++)
+ if (atomic_inc_return_relaxed(&ask->refcnt) == 1)
sock_hold(sk);
- ask->nokey_refcnt += nokey;
+ if (nokey) {
+ atomic_inc(&ask->nokey_refcnt);
+ atomic_set(&alg_sk(sk2)->nokey_refcnt, 1);
+ }
alg_sk(sk2)->parent = sk;
alg_sk(sk2)->type = type;
- alg_sk(sk2)->nokey_refcnt = nokey;
- newsock->ops = type->ops;
newsock->state = SS_CONNECTED;
if (nokey)
@@ -339,7 +348,6 @@ static const struct proto_ops alg_proto_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
.sendmsg = sock_no_sendmsg,
@@ -396,11 +404,11 @@ int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len)
ssize_t n;
int npages, i;
- n = iov_iter_get_pages(iter, sgl->pages, len, ALG_MAX_PAGES, &off);
+ n = iov_iter_get_pages2(iter, sgl->pages, len, ALG_MAX_PAGES, &off);
if (n < 0)
return n;
- npages = (off + n + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ npages = DIV_ROUND_UP(off + n, PAGE_SIZE);
if (WARN_ON(npages == 0))
return -EINVAL;
/* Add one extra for linking */
@@ -480,8 +488,8 @@ static int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con)
/**
* af_alg_alloc_tsgl - allocate the TX SGL
*
- * @sk socket of connection to user space
- * @return: 0 upon success, < 0 upon error
+ * @sk: socket of connection to user space
+ * Return: 0 upon success, < 0 upon error
*/
static int af_alg_alloc_tsgl(struct sock *sk)
{
@@ -514,15 +522,15 @@ static int af_alg_alloc_tsgl(struct sock *sk)
}
/**
- * aead_count_tsgl - Count number of TX SG entries
+ * af_alg_count_tsgl - Count number of TX SG entries
*
* The counting starts from the beginning of the SGL to @bytes. If
- * an offset is provided, the counting of the SG entries starts at the offset.
+ * an @offset is provided, the counting of the SG entries starts at the @offset.
*
- * @sk socket of connection to user space
- * @bytes Count the number of SG entries holding given number of bytes.
- * @offset Start the counting of SG entries from the given offset.
- * @return Number of TX SG entries found given the constraints
+ * @sk: socket of connection to user space
+ * @bytes: Count the number of SG entries holding given number of bytes.
+ * @offset: Start the counting of SG entries from the given offset.
+ * Return: Number of TX SG entries found given the constraints
*/
unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset)
{
@@ -566,19 +574,19 @@ unsigned int af_alg_count_tsgl(struct sock *sk, size_t bytes, size_t offset)
EXPORT_SYMBOL_GPL(af_alg_count_tsgl);
/**
- * aead_pull_tsgl - Release the specified buffers from TX SGL
+ * af_alg_pull_tsgl - Release the specified buffers from TX SGL
*
- * If @dst is non-null, reassign the pages to dst. The caller must release
+ * If @dst is non-null, reassign the pages to @dst. The caller must release
* the pages. If @dst_offset is given only reassign the pages to @dst starting
* at the @dst_offset (byte). The caller must ensure that @dst is large
* enough (e.g. by using af_alg_count_tsgl with the same offset).
*
- * @sk socket of connection to user space
- * @used Number of bytes to pull from TX SGL
- * @dst If non-NULL, buffer is reassigned to dst SGL instead of releasing. The
- * caller must release the buffers in dst.
- * @dst_offset Reassign the TX SGL from given offset. All buffers before
- * reaching the offset is released.
+ * @sk: socket of connection to user space
+ * @used: Number of bytes to pull from TX SGL
+ * @dst: If non-NULL, buffer is reassigned to dst SGL instead of releasing. The
+ * caller must release the buffers in dst.
+ * @dst_offset: Reassign the TX SGL from given offset. All buffers before
+ * reaching the offset is released.
*/
void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
size_t dst_offset)
@@ -639,13 +647,14 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst,
if (!ctx->used)
ctx->merge = 0;
+ ctx->init = ctx->more;
}
EXPORT_SYMBOL_GPL(af_alg_pull_tsgl);
/**
* af_alg_free_areq_sgls - Release TX and RX SGLs of the request
*
- * @areq Request holding the TX and RX SGL
+ * @areq: Request holding the TX and RX SGL
*/
static void af_alg_free_areq_sgls(struct af_alg_async_req *areq)
{
@@ -680,9 +689,9 @@ static void af_alg_free_areq_sgls(struct af_alg_async_req *areq)
/**
* af_alg_wait_for_wmem - wait for availability of writable memory
*
- * @sk socket of connection to user space
- * @flags If MSG_DONTWAIT is set, then only report if function would sleep
- * @return 0 when writable memory is available, < 0 upon error
+ * @sk: socket of connection to user space
+ * @flags: If MSG_DONTWAIT is set, then only report if function would sleep
+ * Return: 0 when writable memory is available, < 0 upon error
*/
static int af_alg_wait_for_wmem(struct sock *sk, unsigned int flags)
{
@@ -713,7 +722,7 @@ static int af_alg_wait_for_wmem(struct sock *sk, unsigned int flags)
/**
* af_alg_wmem_wakeup - wakeup caller when writable memory is available
*
- * @sk socket of connection to user space
+ * @sk: socket of connection to user space
*/
void af_alg_wmem_wakeup(struct sock *sk)
{
@@ -736,11 +745,12 @@ EXPORT_SYMBOL_GPL(af_alg_wmem_wakeup);
/**
* af_alg_wait_for_data - wait for availability of TX data
*
- * @sk socket of connection to user space
- * @flags If MSG_DONTWAIT is set, then only report if function would sleep
- * @return 0 when writable memory is available, < 0 upon error
+ * @sk: socket of connection to user space
+ * @flags: If MSG_DONTWAIT is set, then only report if function would sleep
+ * @min: Set to minimum request size if partial requests are allowed.
+ * Return: 0 when writable memory is available, < 0 upon error
*/
-int af_alg_wait_for_data(struct sock *sk, unsigned flags)
+int af_alg_wait_for_data(struct sock *sk, unsigned flags, unsigned min)
{
DEFINE_WAIT_FUNC(wait, woken_wake_function);
struct alg_sock *ask = alg_sk(sk);
@@ -758,7 +768,9 @@ int af_alg_wait_for_data(struct sock *sk, unsigned flags)
if (signal_pending(current))
break;
timeout = MAX_SCHEDULE_TIMEOUT;
- if (sk_wait_event(sk, &timeout, (ctx->used || !ctx->more),
+ if (sk_wait_event(sk, &timeout,
+ ctx->init && (!ctx->more ||
+ (min && ctx->used >= min)),
&wait)) {
err = 0;
break;
@@ -775,7 +787,7 @@ EXPORT_SYMBOL_GPL(af_alg_wait_for_data);
/**
* af_alg_data_wakeup - wakeup caller when new data can be sent to kernel
*
- * @sk socket of connection to user space
+ * @sk: socket of connection to user space
*/
static void af_alg_data_wakeup(struct sock *sk)
{
@@ -805,12 +817,12 @@ static void af_alg_data_wakeup(struct sock *sk)
*
* In addition, the ctx is filled with the information sent via CMSG.
*
- * @sock socket of connection to user space
- * @msg message from user space
- * @size size of message from user space
- * @ivsize the size of the IV for the cipher operation to verify that the
+ * @sock: socket of connection to user space
+ * @msg: message from user space
+ * @size: size of message from user space
+ * @ivsize: the size of the IV for the cipher operation to verify that the
* user-space-provided IV has the right size
- * @return the number of copied data upon success, < 0 upon error
+ * Return: the number of copied data upon success, < 0 upon error
*/
int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
unsigned int ivsize)
@@ -821,8 +833,8 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
struct af_alg_tsgl *sgl;
struct af_alg_control con = {};
long copied = 0;
- bool enc = 0;
- bool init = 0;
+ bool enc = false;
+ bool init = false;
int err = 0;
if (msg->msg_controllen) {
@@ -830,13 +842,13 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
if (err)
return err;
- init = 1;
+ init = true;
switch (con.op) {
case ALG_OP_ENCRYPT:
- enc = 1;
+ enc = true;
break;
case ALG_OP_DECRYPT:
- enc = 0;
+ enc = false;
break;
default:
return -EINVAL;
@@ -847,10 +859,17 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
}
lock_sock(sk);
- if (!ctx->more && ctx->used) {
- err = -EINVAL;
- goto unlock;
+ if (ctx->init && !ctx->more) {
+ if (ctx->used) {
+ err = -EINVAL;
+ goto unlock;
+ }
+
+ pr_info_once(
+ "%s sent an empty control message without MSG_MORE.\n",
+ current->comm);
}
+ ctx->init = true;
if (init) {
ctx->enc = enc;
@@ -909,16 +928,19 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
sg_unmark_end(sg + sgl->cur - 1);
do {
+ struct page *pg;
unsigned int i = sgl->cur;
plen = min_t(size_t, len, PAGE_SIZE);
- sg_assign_page(sg + i, alloc_page(GFP_KERNEL));
- if (!sg_page(sg + i)) {
+ pg = alloc_page(GFP_KERNEL);
+ if (!pg) {
err = -ENOMEM;
goto unlock;
}
+ sg_assign_page(sg + i, pg);
+
err = memcpy_from_msg(page_address(sg_page(sg + i)),
msg, plen);
if (err) {
@@ -955,6 +977,11 @@ EXPORT_SYMBOL_GPL(af_alg_sendmsg);
/**
* af_alg_sendpage - sendpage system call handler
+ * @sock: socket of connection to user space to write to
+ * @page: data to send
+ * @offset: offset into page to begin sending
+ * @size: length of data
+ * @flags: message send/receive flags
*
* This is a generic implementation of sendpage to fill ctx->tsgl_list.
*/
@@ -1013,6 +1040,7 @@ EXPORT_SYMBOL_GPL(af_alg_sendpage);
/**
* af_alg_free_resources - release resources required for crypto request
+ * @areq: Request holding the TX and RX SGL
*/
void af_alg_free_resources(struct af_alg_async_req *areq)
{
@@ -1025,6 +1053,9 @@ EXPORT_SYMBOL_GPL(af_alg_free_resources);
/**
* af_alg_async_cb - AIO callback handler
+ * @_req: async request info
+ * @err: if non-zero, error result to be returned via ki_complete();
+ * otherwise return the AIO output length via ki_complete().
*
* This handler cleans up the struct af_alg_async_req upon completion of the
* AIO operation.
@@ -1045,12 +1076,15 @@ 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 : (int)resultlen, 0);
+ iocb->ki_complete(iocb, err ? err : (int)resultlen);
}
EXPORT_SYMBOL_GPL(af_alg_async_cb);
/**
* af_alg_poll - poll system call handler
+ * @file: file pointer
+ * @sock: socket to poll
+ * @wait: poll_table
*/
__poll_t af_alg_poll(struct file *file, struct socket *sock,
poll_table *wait)
@@ -1076,9 +1110,9 @@ EXPORT_SYMBOL_GPL(af_alg_poll);
/**
* af_alg_alloc_areq - allocate struct af_alg_async_req
*
- * @sk socket of connection to user space
- * @areqlen size of struct af_alg_async_req + crypto_*_reqsize
- * @return allocated data structure or ERR_PTR upon error
+ * @sk: socket of connection to user space
+ * @areqlen: size of struct af_alg_async_req + crypto_*_reqsize
+ * Return: allocated data structure or ERR_PTR upon error
*/
struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk,
unsigned int areqlen)
@@ -1103,13 +1137,13 @@ EXPORT_SYMBOL_GPL(af_alg_alloc_areq);
* af_alg_get_rsgl - create the RX SGL for the output data from the crypto
* operation
*
- * @sk socket of connection to user space
- * @msg user space message
- * @flags flags used to invoke recvmsg with
- * @areq instance of the cryptographic request that will hold the RX SGL
- * @maxsize maximum number of bytes to be pulled from user space
- * @outlen number of bytes in the RX SGL
- * @return 0 on success, < 0 upon error
+ * @sk: socket of connection to user space
+ * @msg: user space message
+ * @flags: flags used to invoke recvmsg with
+ * @areq: instance of the cryptographic request that will hold the RX SGL
+ * @maxsize: maximum number of bytes to be pulled from user space
+ * @outlen: number of bytes in the RX SGL
+ * Return: 0 on success, < 0 upon error
*/
int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,
struct af_alg_async_req *areq, size_t maxsize,
@@ -1157,7 +1191,6 @@ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags,
len += err;
atomic_add(err, &ctx->rcvused);
rsgl->sg_num_bytes = err;
- iov_iter_advance(&msg->msg_iter, err);
}
*outlen = len;
diff --git a/crypto/ahash.c b/crypto/ahash.c
index 68a0f0cb75c4..c2ca631a111f 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -10,7 +10,6 @@
#include <crypto/internal/hash.h>
#include <crypto/scatterwalk.h>
-#include <linux/bug.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -46,10 +45,7 @@ static int hash_walk_next(struct crypto_hash_walk *walk)
unsigned int nbytes = min(walk->entrylen,
((unsigned int)(PAGE_SIZE)) - offset);
- if (walk->flags & CRYPTO_ALG_ASYNC)
- walk->data = kmap(walk->pg);
- else
- walk->data = kmap_atomic(walk->pg);
+ walk->data = kmap_atomic(walk->pg);
walk->data += offset;
if (offset & alignmask) {
@@ -99,16 +95,8 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err)
}
}
- if (walk->flags & CRYPTO_ALG_ASYNC)
- kunmap(walk->pg);
- else {
- kunmap_atomic(walk->data);
- /*
- * The may sleep test only makes sense for sync users.
- * Async users don't need to sleep here anyway.
- */
- crypto_yield(walk->flags);
- }
+ kunmap_atomic(walk->data);
+ crypto_yield(walk->flags);
if (err)
return err;
@@ -140,33 +128,12 @@ int crypto_hash_walk_first(struct ahash_request *req,
walk->alignmask = crypto_ahash_alignmask(crypto_ahash_reqtfm(req));
walk->sg = req->src;
- walk->flags = req->base.flags & CRYPTO_TFM_REQ_MASK;
+ walk->flags = req->base.flags;
return hash_walk_new_entry(walk);
}
EXPORT_SYMBOL_GPL(crypto_hash_walk_first);
-int crypto_ahash_walk_first(struct ahash_request *req,
- struct crypto_hash_walk *walk)
-{
- walk->total = req->nbytes;
-
- if (!walk->total) {
- walk->entrylen = 0;
- return 0;
- }
-
- walk->alignmask = crypto_ahash_alignmask(crypto_ahash_reqtfm(req));
- walk->sg = req->src;
- walk->flags = req->base.flags & CRYPTO_TFM_REQ_MASK;
- walk->flags |= CRYPTO_ALG_ASYNC;
-
- BUILD_BUG_ON(CRYPTO_TFM_REQ_MASK & CRYPTO_ALG_ASYNC);
-
- return hash_walk_new_entry(walk);
-}
-EXPORT_SYMBOL_GPL(crypto_ahash_walk_first);
-
static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key,
unsigned int keylen)
{
@@ -183,7 +150,7 @@ static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key,
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen);
ret = tfm->setkey(tfm, alignbuffer, keylen);
- kzfree(buffer);
+ kfree_sensitive(buffer);
return ret;
}
@@ -302,7 +269,7 @@ static void ahash_restore_req(struct ahash_request *req, int err)
req->priv = NULL;
/* Free the req->priv.priv from the ADJUSTED request. */
- kzfree(priv);
+ kfree_sensitive(priv);
}
static void ahash_notify_einprogress(struct ahash_request *req)
@@ -477,6 +444,14 @@ static int ahash_def_finup(struct ahash_request *req)
return ahash_def_finup_finish1(req, err);
}
+static void crypto_ahash_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct crypto_ahash *hash = __crypto_ahash_cast(tfm);
+ struct ahash_alg *alg = crypto_ahash_alg(hash);
+
+ alg->exit_tfm(hash);
+}
+
static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
{
struct crypto_ahash *hash = __crypto_ahash_cast(tfm);
@@ -500,7 +475,10 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
ahash_set_needkey(hash);
}
- return 0;
+ if (alg->exit_tfm)
+ tfm->exit = crypto_ahash_exit_tfm;
+
+ return alg->init_tfm ? alg->init_tfm(hash) : 0;
}
static unsigned int crypto_ahash_extsize(struct crypto_alg *alg)
diff --git a/crypto/akcipher.c b/crypto/akcipher.c
index f866085c8a4a..ab975a420e1e 100644
--- a/crypto/akcipher.c
+++ b/crypto/akcipher.c
@@ -120,6 +120,12 @@ static int akcipher_default_op(struct akcipher_request *req)
return -ENOSYS;
}
+static int akcipher_default_set_key(struct crypto_akcipher *tfm,
+ const void *key, unsigned int keylen)
+{
+ return -ENOSYS;
+}
+
int crypto_register_akcipher(struct akcipher_alg *alg)
{
struct crypto_alg *base = &alg->base;
@@ -132,6 +138,8 @@ int crypto_register_akcipher(struct akcipher_alg *alg)
alg->encrypt = akcipher_default_op;
if (!alg->decrypt)
alg->decrypt = akcipher_default_op;
+ if (!alg->set_priv_key)
+ alg->set_priv_key = akcipher_default_set_key;
akcipher_prepare_alg(alg);
return crypto_register_alg(base);
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 69605e21af92..5c69ff8e8fa5 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -6,6 +6,7 @@
*/
#include <crypto/algapi.h>
+#include <crypto/internal/simd.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/fips.h>
@@ -21,6 +22,11 @@
static LIST_HEAD(crypto_template_list);
+#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
+DEFINE_PER_CPU(bool, crypto_simd_disabled_for_test);
+EXPORT_PER_CPU_SYMBOL_GPL(crypto_simd_disabled_for_test);
+#endif
+
static inline void crypto_check_module_sig(struct module *mod)
{
if (fips_enabled && mod && !module_sig_ok(mod))
@@ -216,6 +222,32 @@ void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
}
EXPORT_SYMBOL_GPL(crypto_remove_spawns);
+static struct crypto_larval *crypto_alloc_test_larval(struct crypto_alg *alg)
+{
+ struct crypto_larval *larval;
+
+ if (!IS_ENABLED(CONFIG_CRYPTO_MANAGER))
+ return NULL;
+
+ larval = crypto_larval_alloc(alg->cra_name,
+ alg->cra_flags | CRYPTO_ALG_TESTED, 0);
+ if (IS_ERR(larval))
+ return larval;
+
+ larval->adult = crypto_mod_get(alg);
+ if (!larval->adult) {
+ kfree(larval);
+ return ERR_PTR(-ENOENT);
+ }
+
+ refcount_set(&larval->alg.cra_refcnt, 1);
+ memcpy(larval->alg.cra_driver_name, alg->cra_driver_name,
+ CRYPTO_MAX_ALG_NAME);
+ larval->alg.cra_priority = alg->cra_priority;
+
+ return larval;
+}
+
static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
{
struct crypto_alg *q;
@@ -250,31 +282,22 @@ static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
goto err;
}
- larval = crypto_larval_alloc(alg->cra_name,
- alg->cra_flags | CRYPTO_ALG_TESTED, 0);
+ larval = crypto_alloc_test_larval(alg);
if (IS_ERR(larval))
goto out;
- ret = -ENOENT;
- larval->adult = crypto_mod_get(alg);
- if (!larval->adult)
- goto free_larval;
-
- refcount_set(&larval->alg.cra_refcnt, 1);
- memcpy(larval->alg.cra_driver_name, alg->cra_driver_name,
- CRYPTO_MAX_ALG_NAME);
- larval->alg.cra_priority = alg->cra_priority;
-
list_add(&alg->cra_list, &crypto_alg_list);
- list_add(&larval->alg.cra_list, &crypto_alg_list);
+
+ if (larval)
+ list_add(&larval->alg.cra_list, &crypto_alg_list);
+ else
+ alg->cra_flags |= CRYPTO_ALG_TESTED;
crypto_stats_init(alg);
out:
return larval;
-free_larval:
- kfree(larval);
err:
larval = ERR_PTR(ret);
goto out;
@@ -305,8 +328,16 @@ void crypto_alg_tested(const char *name, int err)
found:
q->cra_flags |= CRYPTO_ALG_DEAD;
alg = test->adult;
- if (err || list_empty(&alg->cra_list))
+
+ if (list_empty(&alg->cra_list))
+ goto complete;
+
+ if (err == -ECANCELED)
+ alg->cra_flags |= CRYPTO_ALG_FIPS_INTERNAL;
+ else if (err)
goto complete;
+ else
+ alg->cra_flags &= ~CRYPTO_ALG_FIPS_INTERNAL;
alg->cra_flags |= CRYPTO_ALG_TESTED;
@@ -389,29 +420,10 @@ void crypto_remove_final(struct list_head *list)
}
EXPORT_SYMBOL_GPL(crypto_remove_final);
-static void crypto_wait_for_test(struct crypto_larval *larval)
-{
- int err;
-
- err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult);
- if (err != NOTIFY_STOP) {
- if (WARN_ON(err != NOTIFY_DONE))
- goto out;
- crypto_alg_tested(larval->alg.cra_driver_name, 0);
- }
-
- err = wait_for_completion_killable(&larval->completion);
- WARN_ON(err);
- if (!err)
- crypto_probing_notify(CRYPTO_MSG_ALG_LOADED, larval);
-
-out:
- crypto_larval_kill(&larval->alg);
-}
-
int crypto_register_alg(struct crypto_alg *alg)
{
struct crypto_larval *larval;
+ bool test_started;
int err;
alg->cra_flags &= ~CRYPTO_ALG_DEAD;
@@ -421,12 +433,16 @@ int crypto_register_alg(struct crypto_alg *alg)
down_write(&crypto_alg_sem);
larval = __crypto_register_alg(alg);
+ test_started = static_key_enabled(&crypto_boot_test_finished);
+ if (!IS_ERR_OR_NULL(larval))
+ larval->test_started = test_started;
up_write(&crypto_alg_sem);
- if (IS_ERR(larval))
+ if (IS_ERR_OR_NULL(larval))
return PTR_ERR(larval);
- crypto_wait_for_test(larval);
+ if (test_started)
+ crypto_wait_for_test(larval);
return 0;
}
EXPORT_SYMBOL_GPL(crypto_register_alg);
@@ -602,6 +618,7 @@ int crypto_register_instance(struct crypto_template *tmpl,
{
struct crypto_larval *larval;
struct crypto_spawn *spawn;
+ u32 fips_internal = 0;
int err;
err = crypto_check_alg(&inst->alg);
@@ -624,14 +641,20 @@ int crypto_register_instance(struct crypto_template *tmpl,
spawn->inst = inst;
spawn->registered = true;
+ fips_internal |= spawn->alg->cra_flags;
+
crypto_mod_put(spawn->alg);
spawn = next;
}
+ inst->alg.cra_flags |= (fips_internal & CRYPTO_ALG_FIPS_INTERNAL);
+
larval = __crypto_register_alg(&inst->alg);
if (IS_ERR(larval))
goto unlock;
+ else if (larval)
+ larval->test_started = true;
hlist_add_head(&inst->list, &tmpl->instances);
inst->tmpl = tmpl;
@@ -640,7 +663,7 @@ unlock:
up_write(&crypto_alg_sem);
err = PTR_ERR(larval);
- if (IS_ERR(larval))
+ if (IS_ERR_OR_NULL(larval))
goto err;
crypto_wait_for_test(larval);
@@ -679,7 +702,8 @@ int crypto_grab_spawn(struct crypto_spawn *spawn, struct crypto_instance *inst,
if (IS_ERR(name))
return PTR_ERR(name);
- alg = crypto_find_alg(name, spawn->frontend, type, mask);
+ alg = crypto_find_alg(name, spawn->frontend,
+ type | CRYPTO_ALG_FIPS_INTERNAL, mask);
if (IS_ERR(alg))
return PTR_ERR(alg);
@@ -690,6 +714,8 @@ int crypto_grab_spawn(struct crypto_spawn *spawn, struct crypto_instance *inst,
spawn->mask = mask;
spawn->next = inst->spawns;
inst->spawns = spawn;
+ inst->alg.cra_flags |=
+ (alg->cra_flags & CRYPTO_ALG_INHERITED_FLAGS);
err = 0;
}
up_write(&crypto_alg_sem);
@@ -716,17 +742,27 @@ EXPORT_SYMBOL_GPL(crypto_drop_spawn);
static struct crypto_alg *crypto_spawn_alg(struct crypto_spawn *spawn)
{
- struct crypto_alg *alg;
+ struct crypto_alg *alg = ERR_PTR(-EAGAIN);
+ struct crypto_alg *target;
+ bool shoot = false;
down_read(&crypto_alg_sem);
- alg = spawn->alg;
- if (!spawn->dead && !crypto_mod_get(alg)) {
- alg->cra_flags |= CRYPTO_ALG_DYING;
- alg = NULL;
+ if (!spawn->dead) {
+ alg = spawn->alg;
+ if (!crypto_mod_get(alg)) {
+ target = crypto_alg_get(alg);
+ shoot = true;
+ alg = ERR_PTR(-EAGAIN);
+ }
}
up_read(&crypto_alg_sem);
- return alg ?: ERR_PTR(-EAGAIN);
+ if (shoot) {
+ crypto_shoot_alg(target);
+ crypto_alg_put(target);
+ }
+
+ return alg;
}
struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
@@ -806,7 +842,23 @@ struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb)
}
EXPORT_SYMBOL_GPL(crypto_get_attr_type);
-int crypto_check_attr_type(struct rtattr **tb, u32 type)
+/**
+ * crypto_check_attr_type() - check algorithm type and compute inherited mask
+ * @tb: the template parameters
+ * @type: the algorithm type the template would be instantiated as
+ * @mask_ret: (output) the mask that should be passed to crypto_grab_*()
+ * to restrict the flags of any inner algorithms
+ *
+ * Validate that the algorithm type the user requested is compatible with the
+ * one the template would actually be instantiated as. E.g., if the user is
+ * doing crypto_alloc_shash("cbc(aes)", ...), this would return an error because
+ * the "cbc" template creates an "skcipher" algorithm, not an "shash" algorithm.
+ *
+ * Also compute the mask to use to restrict the flags of any inner algorithms.
+ *
+ * Return: 0 on success; -errno on failure
+ */
+int crypto_check_attr_type(struct rtattr **tb, u32 type, u32 *mask_ret)
{
struct crypto_attr_type *algt;
@@ -817,6 +869,7 @@ int crypto_check_attr_type(struct rtattr **tb, u32 type)
if ((algt->type ^ type) & algt->mask)
return -EINVAL;
+ *mask_ret = crypto_algt_inherited_mask(algt);
return 0;
}
EXPORT_SYMBOL_GPL(crypto_check_attr_type);
@@ -839,24 +892,6 @@ const char *crypto_attr_alg_name(struct rtattr *rta)
}
EXPORT_SYMBOL_GPL(crypto_attr_alg_name);
-int crypto_attr_u32(struct rtattr *rta, u32 *num)
-{
- struct crypto_attr_u32 *nu32;
-
- if (!rta)
- return -ENOENT;
- if (RTA_PAYLOAD(rta) < sizeof(*nu32))
- return -EINVAL;
- if (rta->rta_type != CRYPTOA_U32)
- return -EINVAL;
-
- nu32 = RTA_DATA(rta);
- *num = nu32->num;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(crypto_attr_u32);
-
int crypto_inst_setname(struct crypto_instance *inst, const char *name,
struct crypto_alg *alg)
{
@@ -904,6 +939,14 @@ out:
}
EXPORT_SYMBOL_GPL(crypto_enqueue_request);
+void crypto_enqueue_request_head(struct crypto_queue *queue,
+ struct crypto_async_request *request)
+{
+ queue->qlen++;
+ list_add(&request->list, &queue->list);
+}
+EXPORT_SYMBOL_GPL(crypto_enqueue_request_head);
+
struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
{
struct list_head *request;
@@ -954,59 +997,6 @@ void crypto_inc(u8 *a, unsigned int size)
}
EXPORT_SYMBOL_GPL(crypto_inc);
-void __crypto_xor(u8 *dst, const u8 *src1, const u8 *src2, unsigned int len)
-{
- int relalign = 0;
-
- if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) {
- int size = sizeof(unsigned long);
- int d = (((unsigned long)dst ^ (unsigned long)src1) |
- ((unsigned long)dst ^ (unsigned long)src2)) &
- (size - 1);
-
- relalign = d ? 1 << __ffs(d) : size;
-
- /*
- * If we care about alignment, process as many bytes as
- * needed to advance dst and src to values whose alignments
- * equal their relative alignment. This will allow us to
- * process the remainder of the input using optimal strides.
- */
- while (((unsigned long)dst & (relalign - 1)) && len > 0) {
- *dst++ = *src1++ ^ *src2++;
- len--;
- }
- }
-
- while (IS_ENABLED(CONFIG_64BIT) && len >= 8 && !(relalign & 7)) {
- *(u64 *)dst = *(u64 *)src1 ^ *(u64 *)src2;
- dst += 8;
- src1 += 8;
- src2 += 8;
- len -= 8;
- }
-
- while (len >= 4 && !(relalign & 3)) {
- *(u32 *)dst = *(u32 *)src1 ^ *(u32 *)src2;
- dst += 4;
- src1 += 4;
- src2 += 4;
- len -= 4;
- }
-
- while (len >= 2 && !(relalign & 1)) {
- *(u16 *)dst = *(u16 *)src1 ^ *(u16 *)src2;
- dst += 2;
- src1 += 2;
- src2 += 2;
- len -= 2;
- }
-
- while (len--)
- *dst++ = *src1++ ^ *src2++;
-}
-EXPORT_SYMBOL_GPL(__crypto_xor);
-
unsigned int crypto_alg_extsize(struct crypto_alg *alg)
{
return alg->cra_ctxsize +
@@ -1242,9 +1232,48 @@ void crypto_stats_skcipher_decrypt(unsigned int cryptlen, int ret,
EXPORT_SYMBOL_GPL(crypto_stats_skcipher_decrypt);
#endif
+static void __init crypto_start_tests(void)
+{
+ for (;;) {
+ struct crypto_larval *larval = NULL;
+ struct crypto_alg *q;
+
+ down_write(&crypto_alg_sem);
+
+ list_for_each_entry(q, &crypto_alg_list, cra_list) {
+ struct crypto_larval *l;
+
+ if (!crypto_is_larval(q))
+ continue;
+
+ l = (void *)q;
+
+ if (!crypto_is_test_larval(l))
+ continue;
+
+ if (l->test_started)
+ continue;
+
+ l->test_started = true;
+ larval = l;
+ break;
+ }
+
+ up_write(&crypto_alg_sem);
+
+ if (!larval)
+ break;
+
+ crypto_wait_for_test(larval);
+ }
+
+ static_branch_enable(&crypto_boot_test_finished);
+}
+
static int __init crypto_algapi_init(void)
{
crypto_init_proc();
+ crypto_start_tests();
return 0;
}
@@ -1253,8 +1282,13 @@ static void __exit crypto_algapi_exit(void)
crypto_exit_proc();
}
-module_init(crypto_algapi_init);
+/*
+ * We run this at late_initcall so that all the built-in algorithms
+ * have had a chance to register themselves first.
+ */
+late_initcall(crypto_algapi_init);
module_exit(crypto_algapi_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Cryptographic algorithms API");
+MODULE_SOFTDEP("pre: cryptomgr");
diff --git a/crypto/algboss.c b/crypto/algboss.c
index 535f1f87e6c1..eb5fe84efb83 100644
--- a/crypto/algboss.c
+++ b/crypto/algboss.c
@@ -28,16 +28,9 @@ struct cryptomgr_param {
struct crypto_attr_type data;
} type;
- union {
+ struct {
struct rtattr attr;
- struct {
- struct rtattr attr;
- struct crypto_attr_alg data;
- } alg;
- struct {
- struct rtattr attr;
- struct crypto_attr_u32 data;
- } nu32;
+ struct crypto_attr_alg data;
} attrs[CRYPTO_MAX_ATTRS];
char template[CRYPTO_MAX_ALG_NAME];
@@ -74,7 +67,7 @@ out:
complete_all(&param->larval->completion);
crypto_alg_put(&param->larval->alg);
kfree(param);
- module_put_and_exit(0);
+ module_put_and_kthread_exit(0);
}
static int cryptomgr_schedule_probe(struct crypto_larval *larval)
@@ -104,12 +97,10 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
i = 0;
for (;;) {
- int notnum = 0;
-
name = ++p;
for (; isalnum(*p) || *p == '-' || *p == '_'; p++)
- notnum |= !isdigit(*p);
+ ;
if (*p == '(') {
int recursion = 0;
@@ -123,7 +114,6 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
break;
}
- notnum = 1;
p++;
}
@@ -131,18 +121,9 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
if (!len)
goto err_free_param;
- if (notnum) {
- param->attrs[i].alg.attr.rta_len =
- sizeof(param->attrs[i].alg);
- param->attrs[i].alg.attr.rta_type = CRYPTOA_ALG;
- memcpy(param->attrs[i].alg.data.name, name, len);
- } else {
- param->attrs[i].nu32.attr.rta_len =
- sizeof(param->attrs[i].nu32);
- param->attrs[i].nu32.attr.rta_type = CRYPTOA_U32;
- param->attrs[i].nu32.data.num =
- simple_strtol(name, NULL, 0);
- }
+ param->attrs[i].attr.rta_len = sizeof(param->attrs[i]);
+ param->attrs[i].attr.rta_type = CRYPTOA_ALG;
+ memcpy(param->attrs[i].data.name, name, len);
param->tb[i + 1] = &param->attrs[i].attr;
i++;
@@ -178,8 +159,6 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval)
if (IS_ERR(thread))
goto err_put_larval;
- wait_for_completion_interruptible(&larval->completion);
-
return NOTIFY_STOP;
err_put_larval:
@@ -211,7 +190,7 @@ skiptest:
crypto_alg_tested(param->driver, err);
kfree(param);
- module_put_and_exit(0);
+ module_put_and_kthread_exit(0);
}
static int cryptomgr_schedule_test(struct crypto_alg *alg)
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index eb1910b6d434..42493b4d8ce4 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -78,7 +78,7 @@ static int crypto_aead_copy_sgl(struct crypto_sync_skcipher *null_tfm,
SYNC_SKCIPHER_REQUEST_ON_STACK(skreq, null_tfm);
skcipher_request_set_sync_tfm(skreq, null_tfm);
- skcipher_request_set_callback(skreq, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ skcipher_request_set_callback(skreq, CRYPTO_TFM_REQ_MAY_SLEEP,
NULL, NULL);
skcipher_request_set_crypt(skreq, src, dst, len, NULL);
@@ -106,8 +106,8 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
size_t usedpages = 0; /* [in] RX bufs to be used from user */
size_t processed = 0; /* [in] TX bufs to be consumed */
- if (!ctx->used) {
- err = af_alg_wait_for_data(sk, flags);
+ if (!ctx->init || ctx->more) {
+ err = af_alg_wait_for_data(sk, flags, 0);
if (err)
return err;
}
@@ -120,7 +120,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
/*
* Make sure sufficient data is present -- note, the same check is
- * is also present in sendmsg/sendpage. The checks in sendpage/sendmsg
+ * also present in sendmsg/sendpage. The checks in sendpage/sendmsg
* shall provide an information to the data sender that something is
* wrong, but they are irrelevant to maintain the kernel integrity.
* We need this check here too in case user space decides to not honor
@@ -291,19 +291,20 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
areq->outlen = outlen;
aead_request_set_callback(&areq->cra_u.aead_req,
- CRYPTO_TFM_REQ_MAY_BACKLOG,
+ CRYPTO_TFM_REQ_MAY_SLEEP,
af_alg_async_cb, areq);
err = ctx->enc ? crypto_aead_encrypt(&areq->cra_u.aead_req) :
crypto_aead_decrypt(&areq->cra_u.aead_req);
/* AIO operation in progress */
- if (err == -EINPROGRESS || err == -EBUSY)
+ if (err == -EINPROGRESS)
return -EIOCBQUEUED;
sock_put(sk);
} else {
/* Synchronous operation */
aead_request_set_callback(&areq->cra_u.aead_req,
+ CRYPTO_TFM_REQ_MAY_SLEEP |
CRYPTO_TFM_REQ_MAY_BACKLOG,
crypto_req_done, &ctx->wait);
err = crypto_wait_req(ctx->enc ?
@@ -361,11 +362,9 @@ static struct proto_ops algif_aead_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
.accept = sock_no_accept,
- .setsockopt = sock_no_setsockopt,
.release = af_alg_release,
.sendmsg = aead_sendmsg,
@@ -384,7 +383,7 @@ static int aead_check_key(struct socket *sock)
struct alg_sock *ask = alg_sk(sk);
lock_sock(sk);
- if (ask->refcnt)
+ if (!atomic_read(&ask->nokey_refcnt))
goto unlock_child;
psk = ask->parent;
@@ -396,11 +395,8 @@ static int aead_check_key(struct socket *sock)
if (crypto_aead_get_flags(tfm->aead) & CRYPTO_TFM_NEED_KEY)
goto unlock;
- if (!pask->refcnt++)
- sock_hold(psk);
-
- ask->refcnt = 1;
- sock_put(psk);
+ atomic_dec(&pask->nokey_refcnt);
+ atomic_set(&ask->nokey_refcnt, 0);
err = 0;
@@ -457,11 +453,9 @@ static struct proto_ops algif_aead_ops_nokey = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
.accept = sock_no_accept,
- .setsockopt = sock_no_setsockopt,
.release = af_alg_release,
.sendmsg = aead_sendmsg_nokey,
@@ -561,12 +555,6 @@ static int aead_accept_parent_nokey(void *private, struct sock *sk)
INIT_LIST_HEAD(&ctx->tsgl_list);
ctx->len = len;
- ctx->used = 0;
- atomic_set(&ctx->rcvused, 0);
- ctx->more = 0;
- ctx->merge = 0;
- ctx->enc = 0;
- ctx->aead_assoclen = 0;
crypto_init_wait(&ctx->wait);
ask->private = ctx;
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
index 178f4cd75ef1..1d017ec5c63c 100644
--- a/crypto/algif_hash.c
+++ b/crypto/algif_hash.c
@@ -83,7 +83,7 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
goto unlock;
}
- ctx->more = 0;
+ ctx->more = false;
while (msg_data_left(msg)) {
int len = msg_data_left(msg);
@@ -102,11 +102,12 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
err = crypto_wait_req(crypto_ahash_update(&ctx->req),
&ctx->wait);
af_alg_free_sg(&ctx->sgl);
- if (err)
+ if (err) {
+ iov_iter_revert(&msg->msg_iter, len);
goto unlock;
+ }
copied += len;
- iov_iter_advance(&msg->msg_iter, len);
}
err = 0;
@@ -211,7 +212,7 @@ static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
}
if (!result || ctx->more) {
- ctx->more = 0;
+ ctx->more = false;
err = crypto_wait_req(crypto_ahash_final(&ctx->req),
&ctx->wait);
if (err)
@@ -279,10 +280,8 @@ static struct proto_ops algif_hash_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
- .setsockopt = sock_no_setsockopt,
.release = af_alg_release,
.sendmsg = hash_sendmsg,
@@ -301,7 +300,7 @@ static int hash_check_key(struct socket *sock)
struct alg_sock *ask = alg_sk(sk);
lock_sock(sk);
- if (ask->refcnt)
+ if (!atomic_read(&ask->nokey_refcnt))
goto unlock_child;
psk = ask->parent;
@@ -313,11 +312,8 @@ static int hash_check_key(struct socket *sock)
if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
goto unlock;
- if (!pask->refcnt++)
- sock_hold(psk);
-
- ask->refcnt = 1;
- sock_put(psk);
+ atomic_dec(&pask->nokey_refcnt);
+ atomic_set(&ask->nokey_refcnt, 0);
err = 0;
@@ -386,10 +382,8 @@ static struct proto_ops algif_hash_ops_nokey = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
- .setsockopt = sock_no_setsockopt,
.release = af_alg_release,
.sendmsg = hash_sendmsg_nokey,
@@ -436,7 +430,7 @@ static int hash_accept_parent_nokey(void *private, struct sock *sk)
ctx->result = NULL;
ctx->len = len;
- ctx->more = 0;
+ ctx->more = false;
crypto_init_wait(&ctx->wait);
ask->private = ctx;
diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c
index 22df3799a17b..407408c43730 100644
--- a/crypto/algif_rng.c
+++ b/crypto/algif_rng.c
@@ -38,6 +38,7 @@
* DAMAGE.
*/
+#include <linux/capability.h>
#include <linux/module.h>
#include <crypto/rng.h>
#include <linux/random.h>
@@ -53,15 +54,26 @@ struct rng_ctx {
#define MAXSIZE 128
unsigned int len;
struct crypto_rng *drng;
+ u8 *addtl;
+ size_t addtl_len;
};
-static int rng_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
- int flags)
+struct rng_parent_ctx {
+ struct crypto_rng *drng;
+ u8 *entropy;
+};
+
+static void rng_reset_addtl(struct rng_ctx *ctx)
{
- struct sock *sk = sock->sk;
- struct alg_sock *ask = alg_sk(sk);
- struct rng_ctx *ctx = ask->private;
- int err = -EFAULT;
+ kfree_sensitive(ctx->addtl);
+ ctx->addtl = NULL;
+ ctx->addtl_len = 0;
+}
+
+static int _rng_recvmsg(struct crypto_rng *drng, struct msghdr *msg, size_t len,
+ u8 *addtl, size_t addtl_len)
+{
+ int err = 0;
int genlen = 0;
u8 result[MAXSIZE];
@@ -82,7 +94,7 @@ static int rng_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
* seeding as they automatically seed. The X9.31 DRNG will return
* an error if it was not seeded properly.
*/
- genlen = crypto_rng_get_bytes(ctx->drng, result, len);
+ genlen = crypto_rng_generate(drng, addtl, addtl_len, result, len);
if (genlen < 0)
return genlen;
@@ -92,6 +104,63 @@ static int rng_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
return err ? err : len;
}
+static int rng_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+ int flags)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct rng_ctx *ctx = ask->private;
+
+ return _rng_recvmsg(ctx->drng, msg, len, NULL, 0);
+}
+
+static int rng_test_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+ int flags)
+{
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+ struct rng_ctx *ctx = ask->private;
+ int ret;
+
+ lock_sock(sock->sk);
+ ret = _rng_recvmsg(ctx->drng, msg, len, ctx->addtl, ctx->addtl_len);
+ rng_reset_addtl(ctx);
+ release_sock(sock->sk);
+
+ return ret;
+}
+
+static int rng_test_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
+{
+ int err;
+ struct alg_sock *ask = alg_sk(sock->sk);
+ struct rng_ctx *ctx = ask->private;
+
+ lock_sock(sock->sk);
+ if (len > MAXSIZE) {
+ err = -EMSGSIZE;
+ goto unlock;
+ }
+
+ rng_reset_addtl(ctx);
+ ctx->addtl = kmalloc(len, GFP_KERNEL);
+ if (!ctx->addtl) {
+ err = -ENOMEM;
+ goto unlock;
+ }
+
+ err = memcpy_from_msg(ctx->addtl, msg, len);
+ if (err) {
+ rng_reset_addtl(ctx);
+ goto unlock;
+ }
+ ctx->addtl_len = len;
+
+unlock:
+ release_sock(sock->sk);
+ return err ? err : len;
+}
+
static struct proto_ops algif_rng_ops = {
.family = PF_ALG,
@@ -101,11 +170,9 @@ static struct proto_ops algif_rng_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
.accept = sock_no_accept,
- .setsockopt = sock_no_setsockopt,
.sendmsg = sock_no_sendmsg,
.sendpage = sock_no_sendpage,
@@ -113,14 +180,53 @@ static struct proto_ops algif_rng_ops = {
.recvmsg = rng_recvmsg,
};
+static struct proto_ops __maybe_unused algif_rng_test_ops = {
+ .family = PF_ALG,
+
+ .connect = sock_no_connect,
+ .socketpair = sock_no_socketpair,
+ .getname = sock_no_getname,
+ .ioctl = sock_no_ioctl,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .mmap = sock_no_mmap,
+ .bind = sock_no_bind,
+ .accept = sock_no_accept,
+ .sendpage = sock_no_sendpage,
+
+ .release = af_alg_release,
+ .recvmsg = rng_test_recvmsg,
+ .sendmsg = rng_test_sendmsg,
+};
+
static void *rng_bind(const char *name, u32 type, u32 mask)
{
- return crypto_alloc_rng(name, type, mask);
+ struct rng_parent_ctx *pctx;
+ struct crypto_rng *rng;
+
+ pctx = kzalloc(sizeof(*pctx), GFP_KERNEL);
+ if (!pctx)
+ return ERR_PTR(-ENOMEM);
+
+ rng = crypto_alloc_rng(name, type, mask);
+ if (IS_ERR(rng)) {
+ kfree(pctx);
+ return ERR_CAST(rng);
+ }
+
+ pctx->drng = rng;
+ return pctx;
}
static void rng_release(void *private)
{
- crypto_free_rng(private);
+ struct rng_parent_ctx *pctx = private;
+
+ if (unlikely(!pctx))
+ return;
+ crypto_free_rng(pctx->drng);
+ kfree_sensitive(pctx->entropy);
+ kfree_sensitive(pctx);
}
static void rng_sock_destruct(struct sock *sk)
@@ -128,6 +234,7 @@ static void rng_sock_destruct(struct sock *sk)
struct alg_sock *ask = alg_sk(sk);
struct rng_ctx *ctx = ask->private;
+ rng_reset_addtl(ctx);
sock_kfree_s(sk, ctx, ctx->len);
af_alg_release_parent(sk);
}
@@ -135,6 +242,7 @@ static void rng_sock_destruct(struct sock *sk)
static int rng_accept_parent(void *private, struct sock *sk)
{
struct rng_ctx *ctx;
+ struct rng_parent_ctx *pctx = private;
struct alg_sock *ask = alg_sk(sk);
unsigned int len = sizeof(*ctx);
@@ -143,6 +251,8 @@ static int rng_accept_parent(void *private, struct sock *sk)
return -ENOMEM;
ctx->len = len;
+ ctx->addtl = NULL;
+ ctx->addtl_len = 0;
/*
* No seeding done at that point -- if multiple accepts are
@@ -150,20 +260,58 @@ static int rng_accept_parent(void *private, struct sock *sk)
* state of the RNG.
*/
- ctx->drng = private;
+ ctx->drng = pctx->drng;
ask->private = ctx;
sk->sk_destruct = rng_sock_destruct;
+ /*
+ * Non NULL pctx->entropy means that CAVP test has been initiated on
+ * this socket, replace proto_ops algif_rng_ops with algif_rng_test_ops.
+ */
+ if (IS_ENABLED(CONFIG_CRYPTO_USER_API_RNG_CAVP) && pctx->entropy)
+ sk->sk_socket->ops = &algif_rng_test_ops;
+
return 0;
}
static int rng_setkey(void *private, const u8 *seed, unsigned int seedlen)
{
+ struct rng_parent_ctx *pctx = private;
/*
* Check whether seedlen is of sufficient size is done in RNG
* implementations.
*/
- return crypto_rng_reset(private, seed, seedlen);
+ return crypto_rng_reset(pctx->drng, seed, seedlen);
+}
+
+static int __maybe_unused rng_setentropy(void *private, sockptr_t entropy,
+ unsigned int len)
+{
+ struct rng_parent_ctx *pctx = private;
+ u8 *kentropy = NULL;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ if (pctx->entropy)
+ return -EINVAL;
+
+ if (len > MAXSIZE)
+ return -EMSGSIZE;
+
+ if (len) {
+ kentropy = memdup_sockptr(entropy, len);
+ if (IS_ERR(kentropy))
+ return PTR_ERR(kentropy);
+ }
+
+ crypto_rng_alg(pctx->drng)->set_ent(pctx->drng, kentropy, len);
+ /*
+ * Since rng doesn't perform any memory management for the entropy
+ * buffer, save kentropy pointer to pctx now to free it after use.
+ */
+ pctx->entropy = kentropy;
+ return 0;
}
static const struct af_alg_type algif_type_rng = {
@@ -171,6 +319,9 @@ static const struct af_alg_type algif_type_rng = {
.release = rng_release,
.accept = rng_accept_parent,
.setkey = rng_setkey,
+#ifdef CONFIG_CRYPTO_USER_API_RNG_CAVP
+ .setentropy = rng_setentropy,
+#endif
.ops = &algif_rng_ops,
.name = "rng",
.owner = THIS_MODULE
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index e2c8ab408bed..ee8890ee8f33 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -61,8 +61,8 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
int err = 0;
size_t len = 0;
- if (!ctx->used) {
- err = af_alg_wait_for_data(sk, flags);
+ if (!ctx->init || (ctx->more && ctx->used < bs)) {
+ err = af_alg_wait_for_data(sk, flags, bs);
if (err)
return err;
}
@@ -74,14 +74,10 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
return PTR_ERR(areq);
/* convert iovecs of output buffers into RX SGL */
- err = af_alg_get_rsgl(sk, msg, flags, areq, -1, &len);
+ err = af_alg_get_rsgl(sk, msg, flags, areq, ctx->used, &len);
if (err)
goto free;
- /* Process only as much RX buffers for which we have TX data */
- if (len > ctx->used)
- len = ctx->used;
-
/*
* If more buffers are to be expected to be processed, process only
* full block size buffers.
@@ -127,7 +123,7 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg,
crypto_skcipher_decrypt(&areq->cra_u.skcipher_req);
/* AIO operation in progress */
- if (err == -EINPROGRESS || err == -EBUSY)
+ if (err == -EINPROGRESS)
return -EIOCBQUEUED;
sock_put(sk);
@@ -192,11 +188,9 @@ static struct proto_ops algif_skcipher_ops = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
.accept = sock_no_accept,
- .setsockopt = sock_no_setsockopt,
.release = af_alg_release,
.sendmsg = skcipher_sendmsg,
@@ -215,7 +209,7 @@ static int skcipher_check_key(struct socket *sock)
struct alg_sock *ask = alg_sk(sk);
lock_sock(sk);
- if (ask->refcnt)
+ if (!atomic_read(&ask->nokey_refcnt))
goto unlock_child;
psk = ask->parent;
@@ -227,11 +221,8 @@ static int skcipher_check_key(struct socket *sock)
if (crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_NEED_KEY)
goto unlock;
- if (!pask->refcnt++)
- sock_hold(psk);
-
- ask->refcnt = 1;
- sock_put(psk);
+ atomic_dec(&pask->nokey_refcnt);
+ atomic_set(&ask->nokey_refcnt, 0);
err = 0;
@@ -288,11 +279,9 @@ static struct proto_ops algif_skcipher_ops_nokey = {
.ioctl = sock_no_ioctl,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
- .getsockopt = sock_no_getsockopt,
.mmap = sock_no_mmap,
.bind = sock_no_bind,
.accept = sock_no_accept,
- .setsockopt = sock_no_setsockopt,
.release = af_alg_release,
.sendmsg = skcipher_sendmsg_nokey,
@@ -340,6 +329,7 @@ static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
if (!ctx)
return -ENOMEM;
+ memset(ctx, 0, len);
ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(tfm),
GFP_KERNEL);
@@ -347,16 +337,10 @@ static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
sock_kfree_s(sk, ctx, len);
return -ENOMEM;
}
-
memset(ctx->iv, 0, crypto_skcipher_ivsize(tfm));
INIT_LIST_HEAD(&ctx->tsgl_list);
ctx->len = len;
- ctx->used = 0;
- atomic_set(&ctx->rcvused, 0);
- ctx->more = 0;
- ctx->merge = 0;
- ctx->enc = 0;
crypto_init_wait(&ctx->wait);
ask->private = ctx;
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c
index c475c1129ff2..3f512efaba3a 100644
--- a/crypto/ansi_cprng.c
+++ b/crypto/ansi_cprng.c
@@ -7,6 +7,7 @@
* (C) Neil Horman <nhorman@tuxdriver.com>
*/
+#include <crypto/internal/cipher.h>
#include <crypto/internal/rng.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -470,3 +471,4 @@ subsys_initcall(prng_mod_init);
module_exit(prng_mod_fini);
MODULE_ALIAS_CRYPTO("stdrng");
MODULE_ALIAS_CRYPTO("ansi_cprng");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/api.c b/crypto/api.c
index 7d71a9b10e5f..64f2d365a8e9 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -12,6 +12,7 @@
#include <linux/err.h>
#include <linux/errno.h>
+#include <linux/jump_label.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/module.h>
@@ -30,6 +31,9 @@ EXPORT_SYMBOL_GPL(crypto_alg_sem);
BLOCKING_NOTIFIER_HEAD(crypto_chain);
EXPORT_SYMBOL_GPL(crypto_chain);
+DEFINE_STATIC_KEY_FALSE(crypto_boot_test_finished);
+EXPORT_SYMBOL_GPL(crypto_boot_test_finished);
+
static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg);
struct crypto_alg *crypto_mod_get(struct crypto_alg *alg)
@@ -47,11 +51,6 @@ void crypto_mod_put(struct crypto_alg *alg)
}
EXPORT_SYMBOL_GPL(crypto_mod_put);
-static inline int crypto_is_test_larval(struct crypto_larval *larval)
-{
- return larval->alg.cra_driver_name[0];
-}
-
static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type,
u32 mask)
{
@@ -115,7 +114,7 @@ struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask)
larval->alg.cra_priority = -1;
larval->alg.cra_destroy = crypto_larval_destroy;
- strlcpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME);
+ strscpy(larval->alg.cra_name, name, CRYPTO_MAX_ALG_NAME);
init_completion(&larval->completion);
return larval;
@@ -163,11 +162,52 @@ void crypto_larval_kill(struct crypto_alg *alg)
}
EXPORT_SYMBOL_GPL(crypto_larval_kill);
+void crypto_wait_for_test(struct crypto_larval *larval)
+{
+ int err;
+
+ err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult);
+ if (WARN_ON_ONCE(err != NOTIFY_STOP))
+ goto out;
+
+ err = wait_for_completion_killable(&larval->completion);
+ WARN_ON(err);
+ if (!err)
+ crypto_notify(CRYPTO_MSG_ALG_LOADED, larval);
+
+out:
+ crypto_larval_kill(&larval->alg);
+}
+EXPORT_SYMBOL_GPL(crypto_wait_for_test);
+
+static void crypto_start_test(struct crypto_larval *larval)
+{
+ if (!crypto_is_test_larval(larval))
+ return;
+
+ if (larval->test_started)
+ return;
+
+ down_write(&crypto_alg_sem);
+ if (larval->test_started) {
+ up_write(&crypto_alg_sem);
+ return;
+ }
+
+ larval->test_started = true;
+ up_write(&crypto_alg_sem);
+
+ crypto_wait_for_test(larval);
+}
+
static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
{
struct crypto_larval *larval = (void *)alg;
long timeout;
+ if (!static_branch_likely(&crypto_boot_test_finished))
+ crypto_start_test(larval);
+
timeout = wait_for_completion_killable_timeout(
&larval->completion, 60 * HZ);
@@ -183,6 +223,8 @@ static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
else if (crypto_is_test_larval(larval) &&
!(alg->cra_flags & CRYPTO_ALG_TESTED))
alg = ERR_PTR(-EAGAIN);
+ else if (alg->cra_flags & CRYPTO_ALG_FIPS_INTERNAL)
+ alg = ERR_PTR(-EAGAIN);
else if (!crypto_mod_get(alg))
alg = ERR_PTR(-EAGAIN);
crypto_mod_put(&larval->alg);
@@ -193,6 +235,7 @@ static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
u32 mask)
{
+ const u32 fips = CRYPTO_ALG_FIPS_INTERNAL;
struct crypto_alg *alg;
u32 test = 0;
@@ -200,8 +243,20 @@ static struct crypto_alg *crypto_alg_lookup(const char *name, u32 type,
test |= CRYPTO_ALG_TESTED;
down_read(&crypto_alg_sem);
- alg = __crypto_alg_lookup(name, type | test, mask | test);
- if (!alg && test) {
+ alg = __crypto_alg_lookup(name, (type | test) & ~fips,
+ (mask | test) & ~fips);
+ if (alg) {
+ if (((type | mask) ^ fips) & fips)
+ mask |= fips;
+ mask &= fips;
+
+ if (!crypto_is_larval(alg) &&
+ ((type ^ alg->cra_flags) & mask)) {
+ /* Algorithm is disallowed in FIPS mode. */
+ crypto_mod_put(alg);
+ alg = ERR_PTR(-ENOENT);
+ }
+ } else if (test) {
alg = __crypto_alg_lookup(name, type, mask);
if (alg && !crypto_is_larval(alg)) {
/* Test failed */
@@ -266,7 +321,7 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
/*
* If the internal flag is set for a cipher, require a caller to
- * to invoke the cipher with the internal flag to use that cipher.
+ * invoke the cipher with the internal flag to use that cipher.
* Also, if a caller wants to allocate a cipher that may or may
* not be an internal cipher, use type | CRYPTO_ALG_INTERNAL and
* !(mask & CRYPTO_ALG_INTERNAL).
@@ -333,12 +388,13 @@ static unsigned int crypto_ctxsize(struct crypto_alg *alg, u32 type, u32 mask)
return len;
}
-static void crypto_shoot_alg(struct crypto_alg *alg)
+void crypto_shoot_alg(struct crypto_alg *alg)
{
down_write(&crypto_alg_sem);
alg->cra_flags |= CRYPTO_ALG_DYING;
up_write(&crypto_alg_sem);
}
+EXPORT_SYMBOL_GPL(crypto_shoot_alg);
struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
u32 mask)
@@ -432,8 +488,9 @@ err:
}
EXPORT_SYMBOL_GPL(crypto_alloc_base);
-void *crypto_create_tfm(struct crypto_alg *alg,
- const struct crypto_type *frontend)
+void *crypto_create_tfm_node(struct crypto_alg *alg,
+ const struct crypto_type *frontend,
+ int node)
{
char *mem;
struct crypto_tfm *tfm = NULL;
@@ -444,12 +501,13 @@ void *crypto_create_tfm(struct crypto_alg *alg,
tfmsize = frontend->tfmsize;
total = tfmsize + sizeof(*tfm) + frontend->extsize(alg);
- mem = kzalloc(total, GFP_KERNEL);
+ mem = kzalloc_node(total, GFP_KERNEL, node);
if (mem == NULL)
goto out_err;
tfm = (struct crypto_tfm *)(mem + tfmsize);
tfm->__crt_alg = alg;
+ tfm->node = node;
err = frontend->init_tfm(tfm);
if (err)
@@ -471,7 +529,7 @@ out_err:
out:
return mem;
}
-EXPORT_SYMBOL_GPL(crypto_create_tfm);
+EXPORT_SYMBOL_GPL(crypto_create_tfm_node);
struct crypto_alg *crypto_find_alg(const char *alg_name,
const struct crypto_type *frontend,
@@ -489,11 +547,13 @@ struct crypto_alg *crypto_find_alg(const char *alg_name,
EXPORT_SYMBOL_GPL(crypto_find_alg);
/*
- * crypto_alloc_tfm - Locate algorithm and allocate transform
+ * crypto_alloc_tfm_node - Locate algorithm and allocate transform
* @alg_name: Name of algorithm
* @frontend: Frontend algorithm type
* @type: Type of algorithm
* @mask: Mask for type comparison
+ * @node: NUMA node in which users desire to put requests, if node is
+ * NUMA_NO_NODE, it means users have no special requirement.
*
* crypto_alloc_tfm() will first attempt to locate an already loaded
* algorithm. If that fails and the kernel supports dynamically loadable
@@ -508,8 +568,10 @@ EXPORT_SYMBOL_GPL(crypto_find_alg);
*
* In case of error the return value is an error pointer.
*/
-void *crypto_alloc_tfm(const char *alg_name,
- const struct crypto_type *frontend, u32 type, u32 mask)
+
+void *crypto_alloc_tfm_node(const char *alg_name,
+ const struct crypto_type *frontend, u32 type, u32 mask,
+ int node)
{
void *tfm;
int err;
@@ -523,7 +585,7 @@ void *crypto_alloc_tfm(const char *alg_name,
goto err;
}
- tfm = crypto_create_tfm(alg, frontend);
+ tfm = crypto_create_tfm_node(alg, frontend, node);
if (!IS_ERR(tfm))
return tfm;
@@ -541,7 +603,7 @@ err:
return ERR_PTR(err);
}
-EXPORT_SYMBOL_GPL(crypto_alloc_tfm);
+EXPORT_SYMBOL_GPL(crypto_alloc_tfm_node);
/*
* crypto_destroy_tfm - Free crypto transform
@@ -555,7 +617,7 @@ void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm)
{
struct crypto_alg *alg;
- if (unlikely(!mem))
+ if (IS_ERR_OR_NULL(mem))
return;
alg = tfm->__crt_alg;
@@ -564,7 +626,7 @@ void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm)
alg->cra_exit(tfm);
crypto_exit_ops(tfm);
crypto_mod_put(alg);
- kzfree(mem);
+ kfree_sensitive(mem);
}
EXPORT_SYMBOL_GPL(crypto_destroy_tfm);
@@ -596,4 +658,3 @@ EXPORT_SYMBOL_GPL(crypto_req_done);
MODULE_DESCRIPTION("Cryptographic core API");
MODULE_LICENSE("GPL");
-MODULE_SOFTDEP("pre: cryptomgr");
diff --git a/crypto/arc4.c b/crypto/arc4.c
index aa79571dbd49..3254dcc34368 100644
--- a/crypto/arc4.c
+++ b/crypto/arc4.c
@@ -11,7 +11,9 @@
#include <crypto/arc4.h>
#include <crypto/internal/skcipher.h>
#include <linux/init.h>
+#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/sched.h>
static int crypto_arc4_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
unsigned int key_len)
@@ -39,6 +41,14 @@ static int crypto_arc4_crypt(struct skcipher_request *req)
return err;
}
+static int crypto_arc4_init(struct crypto_skcipher *tfm)
+{
+ pr_warn_ratelimited("\"%s\" (%ld) uses obsolete ecb(arc4) skcipher\n",
+ current->comm, (unsigned long)current->pid);
+
+ return 0;
+}
+
static struct skcipher_alg arc4_alg = {
/*
* For legacy reasons, this is named "ecb(arc4)", not "arc4".
@@ -55,6 +65,7 @@ static struct skcipher_alg arc4_alg = {
.setkey = crypto_arc4_setkey,
.encrypt = crypto_arc4_crypt,
.decrypt = crypto_arc4_crypt,
+ .init = crypto_arc4_init,
};
static int __init arc4_init(void)
diff --git a/crypto/aria_generic.c b/crypto/aria_generic.c
new file mode 100644
index 000000000000..4cc29b82b99d
--- /dev/null
+++ b/crypto/aria_generic.c
@@ -0,0 +1,313 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Cryptographic API.
+ *
+ * ARIA Cipher Algorithm.
+ *
+ * Documentation of ARIA can be found in RFC 5794.
+ * Copyright (c) 2022 Taehee Yoo <ap420073@gmail.com>
+ *
+ * Information for ARIA
+ * http://210.104.33.10/ARIA/index-e.html (English)
+ * http://seed.kisa.or.kr/ (Korean)
+ *
+ * Public domain version is distributed above.
+ */
+
+#include <crypto/aria.h>
+
+static const u32 key_rc[20] = {
+ 0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0,
+ 0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0,
+ 0xdb92371d, 0x2126e970, 0x03249775, 0x04e8c90e,
+ 0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0,
+ 0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0
+};
+
+static void aria_set_encrypt_key(struct aria_ctx *ctx, const u8 *in_key,
+ unsigned int key_len)
+{
+ const __be32 *key = (const __be32 *)in_key;
+ u32 w0[4], w1[4], w2[4], w3[4];
+ u32 reg0, reg1, reg2, reg3;
+ const u32 *ck;
+ int rkidx = 0;
+
+ ck = &key_rc[(key_len - 16) / 2];
+
+ w0[0] = be32_to_cpu(key[0]);
+ w0[1] = be32_to_cpu(key[1]);
+ w0[2] = be32_to_cpu(key[2]);
+ w0[3] = be32_to_cpu(key[3]);
+
+ reg0 = w0[0] ^ ck[0];
+ reg1 = w0[1] ^ ck[1];
+ reg2 = w0[2] ^ ck[2];
+ reg3 = w0[3] ^ ck[3];
+
+ aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
+
+ if (key_len > 16) {
+ w1[0] = be32_to_cpu(key[4]);
+ w1[1] = be32_to_cpu(key[5]);
+ if (key_len > 24) {
+ w1[2] = be32_to_cpu(key[6]);
+ w1[3] = be32_to_cpu(key[7]);
+ } else {
+ w1[2] = 0;
+ w1[3] = 0;
+ }
+ } else {
+ w1[0] = 0;
+ w1[1] = 0;
+ w1[2] = 0;
+ w1[3] = 0;
+ }
+
+ w1[0] ^= reg0;
+ w1[1] ^= reg1;
+ w1[2] ^= reg2;
+ w1[3] ^= reg3;
+
+ reg0 = w1[0];
+ reg1 = w1[1];
+ reg2 = w1[2];
+ reg3 = w1[3];
+
+ reg0 ^= ck[4];
+ reg1 ^= ck[5];
+ reg2 ^= ck[6];
+ reg3 ^= ck[7];
+
+ aria_subst_diff_even(&reg0, &reg1, &reg2, &reg3);
+
+ reg0 ^= w0[0];
+ reg1 ^= w0[1];
+ reg2 ^= w0[2];
+ reg3 ^= w0[3];
+
+ w2[0] = reg0;
+ w2[1] = reg1;
+ w2[2] = reg2;
+ w2[3] = reg3;
+
+ reg0 ^= ck[8];
+ reg1 ^= ck[9];
+ reg2 ^= ck[10];
+ reg3 ^= ck[11];
+
+ aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
+
+ w3[0] = reg0 ^ w1[0];
+ w3[1] = reg1 ^ w1[1];
+ w3[2] = reg2 ^ w1[2];
+ w3[3] = reg3 ^ w1[3];
+
+ aria_gsrk(ctx->enc_key[rkidx], w0, w1, 19);
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w1, w2, 19);
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w2, w3, 19);
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w3, w0, 19);
+
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w0, w1, 31);
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w1, w2, 31);
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w2, w3, 31);
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w3, w0, 31);
+
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w0, w1, 67);
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w1, w2, 67);
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w2, w3, 67);
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w3, w0, 67);
+
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w0, w1, 97);
+ if (key_len > 16) {
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w1, w2, 97);
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w2, w3, 97);
+
+ if (key_len > 24) {
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w3, w0, 97);
+
+ rkidx++;
+ aria_gsrk(ctx->enc_key[rkidx], w0, w1, 109);
+ }
+ }
+}
+
+static void aria_set_decrypt_key(struct aria_ctx *ctx)
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ ctx->dec_key[0][i] = ctx->enc_key[ctx->rounds][i];
+ ctx->dec_key[ctx->rounds][i] = ctx->enc_key[0][i];
+ }
+
+ for (i = 1; i < ctx->rounds; i++) {
+ ctx->dec_key[i][0] = aria_m(ctx->enc_key[ctx->rounds - i][0]);
+ ctx->dec_key[i][1] = aria_m(ctx->enc_key[ctx->rounds - i][1]);
+ ctx->dec_key[i][2] = aria_m(ctx->enc_key[ctx->rounds - i][2]);
+ ctx->dec_key[i][3] = aria_m(ctx->enc_key[ctx->rounds - i][3]);
+
+ aria_diff_word(&ctx->dec_key[i][0], &ctx->dec_key[i][1],
+ &ctx->dec_key[i][2], &ctx->dec_key[i][3]);
+ aria_diff_byte(&ctx->dec_key[i][1],
+ &ctx->dec_key[i][2], &ctx->dec_key[i][3]);
+ aria_diff_word(&ctx->dec_key[i][0], &ctx->dec_key[i][1],
+ &ctx->dec_key[i][2], &ctx->dec_key[i][3]);
+ }
+}
+
+int aria_set_key(struct crypto_tfm *tfm, const u8 *in_key, unsigned int key_len)
+{
+ struct aria_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ if (key_len != 16 && key_len != 24 && key_len != 32)
+ return -EINVAL;
+
+ ctx->key_length = key_len;
+ ctx->rounds = (key_len + 32) / 4;
+
+ aria_set_encrypt_key(ctx, in_key, key_len);
+ aria_set_decrypt_key(ctx);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(aria_set_key);
+
+static void __aria_crypt(struct aria_ctx *ctx, u8 *out, const u8 *in,
+ u32 key[][ARIA_RD_KEY_WORDS])
+{
+ const __be32 *src = (const __be32 *)in;
+ __be32 *dst = (__be32 *)out;
+ u32 reg0, reg1, reg2, reg3;
+ int rounds, rkidx = 0;
+
+ rounds = ctx->rounds;
+
+ reg0 = be32_to_cpu(src[0]);
+ reg1 = be32_to_cpu(src[1]);
+ reg2 = be32_to_cpu(src[2]);
+ reg3 = be32_to_cpu(src[3]);
+
+ aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
+ rkidx++;
+
+ aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
+ aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
+ rkidx++;
+
+ while ((rounds -= 2) > 0) {
+ aria_subst_diff_even(&reg0, &reg1, &reg2, &reg3);
+ aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
+ rkidx++;
+
+ aria_subst_diff_odd(&reg0, &reg1, &reg2, &reg3);
+ aria_add_round_key(key[rkidx], &reg0, &reg1, &reg2, &reg3);
+ rkidx++;
+ }
+
+ reg0 = key[rkidx][0] ^ make_u32((u8)(x1[get_u8(reg0, 0)]),
+ (u8)(x2[get_u8(reg0, 1)] >> 8),
+ (u8)(s1[get_u8(reg0, 2)]),
+ (u8)(s2[get_u8(reg0, 3)]));
+ reg1 = key[rkidx][1] ^ make_u32((u8)(x1[get_u8(reg1, 0)]),
+ (u8)(x2[get_u8(reg1, 1)] >> 8),
+ (u8)(s1[get_u8(reg1, 2)]),
+ (u8)(s2[get_u8(reg1, 3)]));
+ reg2 = key[rkidx][2] ^ make_u32((u8)(x1[get_u8(reg2, 0)]),
+ (u8)(x2[get_u8(reg2, 1)] >> 8),
+ (u8)(s1[get_u8(reg2, 2)]),
+ (u8)(s2[get_u8(reg2, 3)]));
+ reg3 = key[rkidx][3] ^ make_u32((u8)(x1[get_u8(reg3, 0)]),
+ (u8)(x2[get_u8(reg3, 1)] >> 8),
+ (u8)(s1[get_u8(reg3, 2)]),
+ (u8)(s2[get_u8(reg3, 3)]));
+
+ dst[0] = cpu_to_be32(reg0);
+ dst[1] = cpu_to_be32(reg1);
+ dst[2] = cpu_to_be32(reg2);
+ dst[3] = cpu_to_be32(reg3);
+}
+
+void aria_encrypt(void *_ctx, u8 *out, const u8 *in)
+{
+ struct aria_ctx *ctx = (struct aria_ctx *)_ctx;
+
+ __aria_crypt(ctx, out, in, ctx->enc_key);
+}
+EXPORT_SYMBOL_GPL(aria_encrypt);
+
+void aria_decrypt(void *_ctx, u8 *out, const u8 *in)
+{
+ struct aria_ctx *ctx = (struct aria_ctx *)_ctx;
+
+ __aria_crypt(ctx, out, in, ctx->dec_key);
+}
+EXPORT_SYMBOL_GPL(aria_decrypt);
+
+static void __aria_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+{
+ struct aria_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ __aria_crypt(ctx, out, in, ctx->enc_key);
+}
+
+static void __aria_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+{
+ struct aria_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ __aria_crypt(ctx, out, in, ctx->dec_key);
+}
+
+static struct crypto_alg aria_alg = {
+ .cra_name = "aria",
+ .cra_driver_name = "aria-generic",
+ .cra_priority = 100,
+ .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
+ .cra_blocksize = ARIA_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct aria_ctx),
+ .cra_alignmask = 3,
+ .cra_module = THIS_MODULE,
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = ARIA_MIN_KEY_SIZE,
+ .cia_max_keysize = ARIA_MAX_KEY_SIZE,
+ .cia_setkey = aria_set_key,
+ .cia_encrypt = __aria_encrypt,
+ .cia_decrypt = __aria_decrypt
+ }
+ }
+};
+
+static int __init aria_init(void)
+{
+ return crypto_register_alg(&aria_alg);
+}
+
+static void __exit aria_fini(void)
+{
+ crypto_unregister_alg(&aria_alg);
+}
+
+subsys_initcall(aria_init);
+module_exit(aria_fini);
+
+MODULE_DESCRIPTION("ARIA Cipher Algorithm");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Taehee Yoo <ap420073@gmail.com>");
+MODULE_ALIAS_CRYPTO("aria");
+MODULE_ALIAS_CRYPTO("aria-generic");
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 1f1f004dc757..3df3fe4ed95f 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -22,18 +22,6 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
appropriate hash algorithms (such as SHA-1) must be available.
ENOPKG will be reported if the requisite algorithm is unavailable.
-config ASYMMETRIC_TPM_KEY_SUBTYPE
- tristate "Asymmetric TPM backed private key subtype"
- depends on TCG_TPM
- depends on TRUSTED_KEYS
- select CRYPTO_HMAC
- select CRYPTO_SHA1
- select CRYPTO_HASH_INFO
- help
- This option provides support for TPM backed private key type handling.
- Operations such as sign, verify, encrypt, decrypt are performed by
- the TPM after the private key is loaded.
-
config X509_CERTIFICATE_PARSER
tristate "X.509 certificate parser"
depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
@@ -54,15 +42,6 @@ config PKCS8_PRIVATE_KEY_PARSER
private key data and provides the ability to instantiate a crypto key
from that data.
-config TPM_KEY_PARSER
- tristate "TPM private key parser"
- depends on ASYMMETRIC_TPM_KEY_SUBTYPE
- select ASN1
- help
- This option provides support for parsing TPM format blobs for
- private key data and provides the ability to instantiate a crypto key
- from that data.
-
config PKCS7_MESSAGE_PARSER
tristate "PKCS#7 message parser"
depends on X509_CERTIFICATE_PARSER
@@ -96,4 +75,14 @@ config SIGNED_PE_FILE_VERIFICATION
This option provides support for verifying the signature(s) on a
signed PE binary.
+config FIPS_SIGNATURE_SELFTEST
+ bool "Run FIPS selftests on the X.509+PKCS7 signature verification"
+ help
+ This option causes some selftests to be run on the signature
+ verification code, using some built in data. This is required
+ for FIPS.
+ depends on KEYS
+ depends on ASYMMETRIC_KEY_TYPE
+ depends on PKCS7_MESSAGE_PARSER
+
endif # ASYMMETRIC_KEY_TYPE
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index 28b91adba2ae..0d1fa1b692c6 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -11,7 +11,6 @@ asymmetric_keys-y := \
signature.o
obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
-obj-$(CONFIG_ASYMMETRIC_TPM_KEY_SUBTYPE) += asym_tpm.o
#
# X.509 Certificate handling
@@ -21,7 +20,9 @@ x509_key_parser-y := \
x509.asn1.o \
x509_akid.asn1.o \
x509_cert_parser.o \
+ x509_loader.o \
x509_public_key.o
+x509_key_parser-$(CONFIG_FIPS_SIGNATURE_SELFTEST) += selftest.o
$(obj)/x509_cert_parser.o: \
$(obj)/x509.asn1.h \
@@ -75,14 +76,3 @@ verify_signed_pefile-y := \
$(obj)/mscode_parser.o: $(obj)/mscode.asn1.h $(obj)/mscode.asn1.h
$(obj)/mscode.asn1.o: $(obj)/mscode.asn1.c $(obj)/mscode.asn1.h
-
-#
-# TPM private key parsing
-#
-obj-$(CONFIG_TPM_KEY_PARSER) += tpm_key_parser.o
-tpm_key_parser-y := \
- tpm.asn1.o \
- tpm_parser.o
-
-$(obj)/tpm_parser.o: $(obj)/tpm.asn1.h
-$(obj)/tpm.asn1.o: $(obj)/tpm.asn1.c $(obj)/tpm.asn1.h
diff --git a/crypto/asymmetric_keys/asym_tpm.c b/crypto/asymmetric_keys/asym_tpm.c
deleted file mode 100644
index 378b18b9bc34..000000000000
--- a/crypto/asymmetric_keys/asym_tpm.c
+++ /dev/null
@@ -1,957 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#define pr_fmt(fmt) "ASYM-TPM: "fmt
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/seq_file.h>
-#include <linux/scatterlist.h>
-#include <linux/tpm.h>
-#include <linux/tpm_command.h>
-#include <crypto/akcipher.h>
-#include <crypto/hash.h>
-#include <crypto/sha.h>
-#include <asm/unaligned.h>
-#include <keys/asymmetric-subtype.h>
-#include <keys/trusted_tpm.h>
-#include <crypto/asym_tpm_subtype.h>
-#include <crypto/public_key.h>
-
-#define TPM_ORD_FLUSHSPECIFIC 186
-#define TPM_ORD_LOADKEY2 65
-#define TPM_ORD_UNBIND 30
-#define TPM_ORD_SIGN 60
-
-#define TPM_RT_KEY 0x00000001
-
-/*
- * Load a TPM key from the blob provided by userspace
- */
-static int tpm_loadkey2(struct tpm_buf *tb,
- uint32_t keyhandle, unsigned char *keyauth,
- const unsigned char *keyblob, int keybloblen,
- uint32_t *newhandle)
-{
- unsigned char nonceodd[TPM_NONCE_SIZE];
- unsigned char enonce[TPM_NONCE_SIZE];
- unsigned char authdata[SHA1_DIGEST_SIZE];
- uint32_t authhandle = 0;
- unsigned char cont = 0;
- uint32_t ordinal;
- int ret;
-
- ordinal = htonl(TPM_ORD_LOADKEY2);
-
- /* session for loading the key */
- ret = oiap(tb, &authhandle, enonce);
- if (ret < 0) {
- pr_info("oiap failed (%d)\n", ret);
- return ret;
- }
-
- /* generate odd nonce */
- ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
- if (ret < 0) {
- pr_info("tpm_get_random failed (%d)\n", ret);
- return ret;
- }
-
- /* calculate authorization HMAC value */
- ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
- nonceodd, cont, sizeof(uint32_t), &ordinal,
- keybloblen, keyblob, 0, 0);
- if (ret < 0)
- return ret;
-
- /* build the request buffer */
- tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_LOADKEY2);
- tpm_buf_append_u32(tb, keyhandle);
- tpm_buf_append(tb, keyblob, keybloblen);
- tpm_buf_append_u32(tb, authhandle);
- tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
- tpm_buf_append_u8(tb, cont);
- tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
-
- ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
- if (ret < 0) {
- pr_info("authhmac failed (%d)\n", ret);
- return ret;
- }
-
- ret = TSS_checkhmac1(tb->data, ordinal, nonceodd, keyauth,
- SHA1_DIGEST_SIZE, 0, 0);
- if (ret < 0) {
- pr_info("TSS_checkhmac1 failed (%d)\n", ret);
- return ret;
- }
-
- *newhandle = LOAD32(tb->data, TPM_DATA_OFFSET);
- return 0;
-}
-
-/*
- * Execute the FlushSpecific TPM command
- */
-static int tpm_flushspecific(struct tpm_buf *tb, uint32_t handle)
-{
- tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_FLUSHSPECIFIC);
- tpm_buf_append_u32(tb, handle);
- tpm_buf_append_u32(tb, TPM_RT_KEY);
-
- return trusted_tpm_send(tb->data, MAX_BUF_SIZE);
-}
-
-/*
- * Decrypt a blob provided by userspace using a specific key handle.
- * The handle is a well known handle or previously loaded by e.g. LoadKey2
- */
-static int tpm_unbind(struct tpm_buf *tb,
- uint32_t keyhandle, unsigned char *keyauth,
- const unsigned char *blob, uint32_t bloblen,
- void *out, uint32_t outlen)
-{
- unsigned char nonceodd[TPM_NONCE_SIZE];
- unsigned char enonce[TPM_NONCE_SIZE];
- unsigned char authdata[SHA1_DIGEST_SIZE];
- uint32_t authhandle = 0;
- unsigned char cont = 0;
- uint32_t ordinal;
- uint32_t datalen;
- int ret;
-
- ordinal = htonl(TPM_ORD_UNBIND);
- datalen = htonl(bloblen);
-
- /* session for loading the key */
- ret = oiap(tb, &authhandle, enonce);
- if (ret < 0) {
- pr_info("oiap failed (%d)\n", ret);
- return ret;
- }
-
- /* generate odd nonce */
- ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
- if (ret < 0) {
- pr_info("tpm_get_random failed (%d)\n", ret);
- return ret;
- }
-
- /* calculate authorization HMAC value */
- ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
- nonceodd, cont, sizeof(uint32_t), &ordinal,
- sizeof(uint32_t), &datalen,
- bloblen, blob, 0, 0);
- if (ret < 0)
- return ret;
-
- /* build the request buffer */
- tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_UNBIND);
- tpm_buf_append_u32(tb, keyhandle);
- tpm_buf_append_u32(tb, bloblen);
- tpm_buf_append(tb, blob, bloblen);
- tpm_buf_append_u32(tb, authhandle);
- tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
- tpm_buf_append_u8(tb, cont);
- tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
-
- ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
- if (ret < 0) {
- pr_info("authhmac failed (%d)\n", ret);
- return ret;
- }
-
- datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
-
- ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
- keyauth, SHA1_DIGEST_SIZE,
- sizeof(uint32_t), TPM_DATA_OFFSET,
- datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
- 0, 0);
- if (ret < 0) {
- pr_info("TSS_checkhmac1 failed (%d)\n", ret);
- return ret;
- }
-
- memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
- min(outlen, datalen));
-
- return datalen;
-}
-
-/*
- * Sign a blob provided by userspace (that has had the hash function applied)
- * using a specific key handle. The handle is assumed to have been previously
- * loaded by e.g. LoadKey2.
- *
- * Note that the key signature scheme of the used key should be set to
- * TPM_SS_RSASSAPKCS1v15_DER. This allows the hashed input to be of any size
- * up to key_length_in_bytes - 11 and not be limited to size 20 like the
- * TPM_SS_RSASSAPKCS1v15_SHA1 signature scheme.
- */
-static int tpm_sign(struct tpm_buf *tb,
- uint32_t keyhandle, unsigned char *keyauth,
- const unsigned char *blob, uint32_t bloblen,
- void *out, uint32_t outlen)
-{
- unsigned char nonceodd[TPM_NONCE_SIZE];
- unsigned char enonce[TPM_NONCE_SIZE];
- unsigned char authdata[SHA1_DIGEST_SIZE];
- uint32_t authhandle = 0;
- unsigned char cont = 0;
- uint32_t ordinal;
- uint32_t datalen;
- int ret;
-
- ordinal = htonl(TPM_ORD_SIGN);
- datalen = htonl(bloblen);
-
- /* session for loading the key */
- ret = oiap(tb, &authhandle, enonce);
- if (ret < 0) {
- pr_info("oiap failed (%d)\n", ret);
- return ret;
- }
-
- /* generate odd nonce */
- ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE);
- if (ret < 0) {
- pr_info("tpm_get_random failed (%d)\n", ret);
- return ret;
- }
-
- /* calculate authorization HMAC value */
- ret = TSS_authhmac(authdata, keyauth, SHA1_DIGEST_SIZE, enonce,
- nonceodd, cont, sizeof(uint32_t), &ordinal,
- sizeof(uint32_t), &datalen,
- bloblen, blob, 0, 0);
- if (ret < 0)
- return ret;
-
- /* build the request buffer */
- tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_SIGN);
- tpm_buf_append_u32(tb, keyhandle);
- tpm_buf_append_u32(tb, bloblen);
- tpm_buf_append(tb, blob, bloblen);
- tpm_buf_append_u32(tb, authhandle);
- tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
- tpm_buf_append_u8(tb, cont);
- tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
-
- ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
- if (ret < 0) {
- pr_info("authhmac failed (%d)\n", ret);
- return ret;
- }
-
- datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
-
- ret = TSS_checkhmac1(tb->data, ordinal, nonceodd,
- keyauth, SHA1_DIGEST_SIZE,
- sizeof(uint32_t), TPM_DATA_OFFSET,
- datalen, TPM_DATA_OFFSET + sizeof(uint32_t),
- 0, 0);
- if (ret < 0) {
- pr_info("TSS_checkhmac1 failed (%d)\n", ret);
- return ret;
- }
-
- memcpy(out, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t),
- min(datalen, outlen));
-
- return datalen;
-}
-
-/* Room to fit two u32 zeros for algo id and parameters length. */
-#define SETKEY_PARAMS_SIZE (sizeof(u32) * 2)
-
-/*
- * Maximum buffer size for the BER/DER encoded public key. The public key
- * is of the form SEQUENCE { INTEGER n, INTEGER e } where n is a maximum 2048
- * bit key and e is usually 65537
- * The encoding overhead is:
- * - max 4 bytes for SEQUENCE
- * - max 4 bytes for INTEGER n type/length
- * - 257 bytes of n
- * - max 2 bytes for INTEGER e type/length
- * - 3 bytes of e
- * - 4+4 of zeros for set_pub_key parameters (SETKEY_PARAMS_SIZE)
- */
-#define PUB_KEY_BUF_SIZE (4 + 4 + 257 + 2 + 3 + SETKEY_PARAMS_SIZE)
-
-/*
- * Provide a part of a description of the key for /proc/keys.
- */
-static void asym_tpm_describe(const struct key *asymmetric_key,
- struct seq_file *m)
-{
- struct tpm_key *tk = asymmetric_key->payload.data[asym_crypto];
-
- if (!tk)
- return;
-
- seq_printf(m, "TPM1.2/Blob");
-}
-
-static void asym_tpm_destroy(void *payload0, void *payload3)
-{
- struct tpm_key *tk = payload0;
-
- if (!tk)
- return;
-
- kfree(tk->blob);
- tk->blob_len = 0;
-
- kfree(tk);
-}
-
-/* How many bytes will it take to encode the length */
-static inline uint32_t definite_length(uint32_t len)
-{
- if (len <= 127)
- return 1;
- if (len <= 255)
- return 2;
- return 3;
-}
-
-static inline uint8_t *encode_tag_length(uint8_t *buf, uint8_t tag,
- uint32_t len)
-{
- *buf++ = tag;
-
- if (len <= 127) {
- buf[0] = len;
- return buf + 1;
- }
-
- if (len <= 255) {
- buf[0] = 0x81;
- buf[1] = len;
- return buf + 2;
- }
-
- buf[0] = 0x82;
- put_unaligned_be16(len, buf + 1);
- return buf + 3;
-}
-
-static uint32_t derive_pub_key(const void *pub_key, uint32_t len, uint8_t *buf)
-{
- uint8_t *cur = buf;
- uint32_t n_len = definite_length(len) + 1 + len + 1;
- uint32_t e_len = definite_length(3) + 1 + 3;
- uint8_t e[3] = { 0x01, 0x00, 0x01 };
-
- /* SEQUENCE */
- cur = encode_tag_length(cur, 0x30, n_len + e_len);
- /* INTEGER n */
- cur = encode_tag_length(cur, 0x02, len + 1);
- cur[0] = 0x00;
- memcpy(cur + 1, pub_key, len);
- cur += len + 1;
- cur = encode_tag_length(cur, 0x02, sizeof(e));
- memcpy(cur, e, sizeof(e));
- cur += sizeof(e);
- /* Zero parameters to satisfy set_pub_key ABI. */
- memset(cur, 0, SETKEY_PARAMS_SIZE);
-
- return cur - buf;
-}
-
-/*
- * Determine the crypto algorithm name.
- */
-static int determine_akcipher(const char *encoding, const char *hash_algo,
- char alg_name[CRYPTO_MAX_ALG_NAME])
-{
- if (strcmp(encoding, "pkcs1") == 0) {
- if (!hash_algo) {
- strcpy(alg_name, "pkcs1pad(rsa)");
- return 0;
- }
-
- if (snprintf(alg_name, CRYPTO_MAX_ALG_NAME, "pkcs1pad(rsa,%s)",
- hash_algo) >= CRYPTO_MAX_ALG_NAME)
- return -EINVAL;
-
- return 0;
- }
-
- if (strcmp(encoding, "raw") == 0) {
- strcpy(alg_name, "rsa");
- return 0;
- }
-
- return -ENOPKG;
-}
-
-/*
- * Query information about a key.
- */
-static int tpm_key_query(const struct kernel_pkey_params *params,
- struct kernel_pkey_query *info)
-{
- struct tpm_key *tk = params->key->payload.data[asym_crypto];
- int ret;
- char alg_name[CRYPTO_MAX_ALG_NAME];
- struct crypto_akcipher *tfm;
- uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
- uint32_t der_pub_key_len;
- int len;
-
- /* TPM only works on private keys, public keys still done in software */
- ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
- if (ret < 0)
- return ret;
-
- tfm = crypto_alloc_akcipher(alg_name, 0, 0);
- if (IS_ERR(tfm))
- return PTR_ERR(tfm);
-
- der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
- der_pub_key);
-
- ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
- if (ret < 0)
- goto error_free_tfm;
-
- len = crypto_akcipher_maxsize(tfm);
-
- info->key_size = tk->key_len;
- info->max_data_size = tk->key_len / 8;
- info->max_sig_size = len;
- info->max_enc_size = len;
- info->max_dec_size = tk->key_len / 8;
-
- info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT |
- KEYCTL_SUPPORTS_DECRYPT |
- KEYCTL_SUPPORTS_VERIFY |
- KEYCTL_SUPPORTS_SIGN;
-
- ret = 0;
-error_free_tfm:
- crypto_free_akcipher(tfm);
- pr_devel("<==%s() = %d\n", __func__, ret);
- return ret;
-}
-
-/*
- * Encryption operation is performed with the public key. Hence it is done
- * in software
- */
-static int tpm_key_encrypt(struct tpm_key *tk,
- struct kernel_pkey_params *params,
- const void *in, void *out)
-{
- char alg_name[CRYPTO_MAX_ALG_NAME];
- struct crypto_akcipher *tfm;
- struct akcipher_request *req;
- struct crypto_wait cwait;
- struct scatterlist in_sg, out_sg;
- uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
- uint32_t der_pub_key_len;
- int ret;
-
- pr_devel("==>%s()\n", __func__);
-
- ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
- if (ret < 0)
- return ret;
-
- tfm = crypto_alloc_akcipher(alg_name, 0, 0);
- if (IS_ERR(tfm))
- return PTR_ERR(tfm);
-
- der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
- der_pub_key);
-
- ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
- if (ret < 0)
- goto error_free_tfm;
-
- ret = -ENOMEM;
- req = akcipher_request_alloc(tfm, GFP_KERNEL);
- if (!req)
- goto error_free_tfm;
-
- sg_init_one(&in_sg, in, params->in_len);
- sg_init_one(&out_sg, out, params->out_len);
- akcipher_request_set_crypt(req, &in_sg, &out_sg, params->in_len,
- params->out_len);
- crypto_init_wait(&cwait);
- akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
- CRYPTO_TFM_REQ_MAY_SLEEP,
- crypto_req_done, &cwait);
-
- ret = crypto_akcipher_encrypt(req);
- ret = crypto_wait_req(ret, &cwait);
-
- if (ret == 0)
- ret = req->dst_len;
-
- akcipher_request_free(req);
-error_free_tfm:
- crypto_free_akcipher(tfm);
- pr_devel("<==%s() = %d\n", __func__, ret);
- return ret;
-}
-
-/*
- * Decryption operation is performed with the private key in the TPM.
- */
-static int tpm_key_decrypt(struct tpm_key *tk,
- struct kernel_pkey_params *params,
- const void *in, void *out)
-{
- struct tpm_buf tb;
- uint32_t keyhandle;
- uint8_t srkauth[SHA1_DIGEST_SIZE];
- uint8_t keyauth[SHA1_DIGEST_SIZE];
- int r;
-
- pr_devel("==>%s()\n", __func__);
-
- if (params->hash_algo)
- return -ENOPKG;
-
- if (strcmp(params->encoding, "pkcs1"))
- return -ENOPKG;
-
- r = tpm_buf_init(&tb, 0, 0);
- if (r)
- return r;
-
- /* TODO: Handle a non-all zero SRK authorization */
- memset(srkauth, 0, sizeof(srkauth));
-
- r = tpm_loadkey2(&tb, SRKHANDLE, srkauth,
- tk->blob, tk->blob_len, &keyhandle);
- if (r < 0) {
- pr_devel("loadkey2 failed (%d)\n", r);
- goto error;
- }
-
- /* TODO: Handle a non-all zero key authorization */
- memset(keyauth, 0, sizeof(keyauth));
-
- r = tpm_unbind(&tb, keyhandle, keyauth,
- in, params->in_len, out, params->out_len);
- if (r < 0)
- pr_devel("tpm_unbind failed (%d)\n", r);
-
- if (tpm_flushspecific(&tb, keyhandle) < 0)
- pr_devel("flushspecific failed (%d)\n", r);
-
-error:
- tpm_buf_destroy(&tb);
- pr_devel("<==%s() = %d\n", __func__, r);
- return r;
-}
-
-/*
- * Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
- */
-static const u8 digest_info_md5[] = {
- 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08,
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, /* OID */
- 0x05, 0x00, 0x04, 0x10
-};
-
-static const u8 digest_info_sha1[] = {
- 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
- 0x2b, 0x0e, 0x03, 0x02, 0x1a,
- 0x05, 0x00, 0x04, 0x14
-};
-
-static const u8 digest_info_rmd160[] = {
- 0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
- 0x2b, 0x24, 0x03, 0x02, 0x01,
- 0x05, 0x00, 0x04, 0x14
-};
-
-static const u8 digest_info_sha224[] = {
- 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
- 0x05, 0x00, 0x04, 0x1c
-};
-
-static const u8 digest_info_sha256[] = {
- 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
- 0x05, 0x00, 0x04, 0x20
-};
-
-static const u8 digest_info_sha384[] = {
- 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
- 0x05, 0x00, 0x04, 0x30
-};
-
-static const u8 digest_info_sha512[] = {
- 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
- 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
- 0x05, 0x00, 0x04, 0x40
-};
-
-static const struct asn1_template {
- const char *name;
- const u8 *data;
- size_t size;
-} asn1_templates[] = {
-#define _(X) { #X, digest_info_##X, sizeof(digest_info_##X) }
- _(md5),
- _(sha1),
- _(rmd160),
- _(sha256),
- _(sha384),
- _(sha512),
- _(sha224),
- { NULL }
-#undef _
-};
-
-static const struct asn1_template *lookup_asn1(const char *name)
-{
- const struct asn1_template *p;
-
- for (p = asn1_templates; p->name; p++)
- if (strcmp(name, p->name) == 0)
- return p;
- return NULL;
-}
-
-/*
- * Sign operation is performed with the private key in the TPM.
- */
-static int tpm_key_sign(struct tpm_key *tk,
- struct kernel_pkey_params *params,
- const void *in, void *out)
-{
- struct tpm_buf tb;
- uint32_t keyhandle;
- uint8_t srkauth[SHA1_DIGEST_SIZE];
- uint8_t keyauth[SHA1_DIGEST_SIZE];
- void *asn1_wrapped = NULL;
- uint32_t in_len = params->in_len;
- int r;
-
- pr_devel("==>%s()\n", __func__);
-
- if (strcmp(params->encoding, "pkcs1"))
- return -ENOPKG;
-
- if (params->hash_algo) {
- const struct asn1_template *asn1 =
- lookup_asn1(params->hash_algo);
-
- if (!asn1)
- return -ENOPKG;
-
- /* request enough space for the ASN.1 template + input hash */
- asn1_wrapped = kzalloc(in_len + asn1->size, GFP_KERNEL);
- if (!asn1_wrapped)
- return -ENOMEM;
-
- /* Copy ASN.1 template, then the input */
- memcpy(asn1_wrapped, asn1->data, asn1->size);
- memcpy(asn1_wrapped + asn1->size, in, in_len);
-
- in = asn1_wrapped;
- in_len += asn1->size;
- }
-
- if (in_len > tk->key_len / 8 - 11) {
- r = -EOVERFLOW;
- goto error_free_asn1_wrapped;
- }
-
- r = tpm_buf_init(&tb, 0, 0);
- if (r)
- goto error_free_asn1_wrapped;
-
- /* TODO: Handle a non-all zero SRK authorization */
- memset(srkauth, 0, sizeof(srkauth));
-
- r = tpm_loadkey2(&tb, SRKHANDLE, srkauth,
- tk->blob, tk->blob_len, &keyhandle);
- if (r < 0) {
- pr_devel("loadkey2 failed (%d)\n", r);
- goto error_free_tb;
- }
-
- /* TODO: Handle a non-all zero key authorization */
- memset(keyauth, 0, sizeof(keyauth));
-
- r = tpm_sign(&tb, keyhandle, keyauth, in, in_len, out, params->out_len);
- if (r < 0)
- pr_devel("tpm_sign failed (%d)\n", r);
-
- if (tpm_flushspecific(&tb, keyhandle) < 0)
- pr_devel("flushspecific failed (%d)\n", r);
-
-error_free_tb:
- tpm_buf_destroy(&tb);
-error_free_asn1_wrapped:
- kfree(asn1_wrapped);
- pr_devel("<==%s() = %d\n", __func__, r);
- return r;
-}
-
-/*
- * Do encryption, decryption and signing ops.
- */
-static int tpm_key_eds_op(struct kernel_pkey_params *params,
- const void *in, void *out)
-{
- struct tpm_key *tk = params->key->payload.data[asym_crypto];
- int ret = -EOPNOTSUPP;
-
- /* Perform the encryption calculation. */
- switch (params->op) {
- case kernel_pkey_encrypt:
- ret = tpm_key_encrypt(tk, params, in, out);
- break;
- case kernel_pkey_decrypt:
- ret = tpm_key_decrypt(tk, params, in, out);
- break;
- case kernel_pkey_sign:
- ret = tpm_key_sign(tk, params, in, out);
- break;
- default:
- BUG();
- }
-
- return ret;
-}
-
-/*
- * Verify a signature using a public key.
- */
-static int tpm_key_verify_signature(const struct key *key,
- const struct public_key_signature *sig)
-{
- const struct tpm_key *tk = key->payload.data[asym_crypto];
- struct crypto_wait cwait;
- struct crypto_akcipher *tfm;
- struct akcipher_request *req;
- struct scatterlist src_sg[2];
- char alg_name[CRYPTO_MAX_ALG_NAME];
- uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
- uint32_t der_pub_key_len;
- int ret;
-
- pr_devel("==>%s()\n", __func__);
-
- BUG_ON(!tk);
- BUG_ON(!sig);
- BUG_ON(!sig->s);
-
- if (!sig->digest)
- return -ENOPKG;
-
- ret = determine_akcipher(sig->encoding, sig->hash_algo, alg_name);
- if (ret < 0)
- return ret;
-
- tfm = crypto_alloc_akcipher(alg_name, 0, 0);
- if (IS_ERR(tfm))
- return PTR_ERR(tfm);
-
- der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
- der_pub_key);
-
- ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
- if (ret < 0)
- goto error_free_tfm;
-
- ret = -ENOMEM;
- req = akcipher_request_alloc(tfm, GFP_KERNEL);
- if (!req)
- goto error_free_tfm;
-
- sg_init_table(src_sg, 2);
- sg_set_buf(&src_sg[0], sig->s, sig->s_size);
- sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
- akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
- sig->digest_size);
- crypto_init_wait(&cwait);
- akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
- CRYPTO_TFM_REQ_MAY_SLEEP,
- crypto_req_done, &cwait);
- ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
-
- akcipher_request_free(req);
-error_free_tfm:
- crypto_free_akcipher(tfm);
- pr_devel("<==%s() = %d\n", __func__, ret);
- if (WARN_ON_ONCE(ret > 0))
- ret = -EINVAL;
- return ret;
-}
-
-/*
- * Parse enough information out of TPM_KEY structure:
- * TPM_STRUCT_VER -> 4 bytes
- * TPM_KEY_USAGE -> 2 bytes
- * TPM_KEY_FLAGS -> 4 bytes
- * TPM_AUTH_DATA_USAGE -> 1 byte
- * TPM_KEY_PARMS -> variable
- * UINT32 PCRInfoSize -> 4 bytes
- * BYTE* -> PCRInfoSize bytes
- * TPM_STORE_PUBKEY
- * UINT32 encDataSize;
- * BYTE* -> encDataSize;
- *
- * TPM_KEY_PARMS:
- * TPM_ALGORITHM_ID -> 4 bytes
- * TPM_ENC_SCHEME -> 2 bytes
- * TPM_SIG_SCHEME -> 2 bytes
- * UINT32 parmSize -> 4 bytes
- * BYTE* -> variable
- */
-static int extract_key_parameters(struct tpm_key *tk)
-{
- const void *cur = tk->blob;
- uint32_t len = tk->blob_len;
- const void *pub_key;
- uint32_t sz;
- uint32_t key_len;
-
- if (len < 11)
- return -EBADMSG;
-
- /* Ensure this is a legacy key */
- if (get_unaligned_be16(cur + 4) != 0x0015)
- return -EBADMSG;
-
- /* Skip to TPM_KEY_PARMS */
- cur += 11;
- len -= 11;
-
- if (len < 12)
- return -EBADMSG;
-
- /* Make sure this is an RSA key */
- if (get_unaligned_be32(cur) != 0x00000001)
- return -EBADMSG;
-
- /* Make sure this is TPM_ES_RSAESPKCSv15 encoding scheme */
- if (get_unaligned_be16(cur + 4) != 0x0002)
- return -EBADMSG;
-
- /* Make sure this is TPM_SS_RSASSAPKCS1v15_DER signature scheme */
- if (get_unaligned_be16(cur + 6) != 0x0003)
- return -EBADMSG;
-
- sz = get_unaligned_be32(cur + 8);
- if (len < sz + 12)
- return -EBADMSG;
-
- /* Move to TPM_RSA_KEY_PARMS */
- len -= 12;
- cur += 12;
-
- /* Grab the RSA key length */
- key_len = get_unaligned_be32(cur);
-
- switch (key_len) {
- case 512:
- case 1024:
- case 1536:
- case 2048:
- break;
- default:
- return -EINVAL;
- }
-
- /* Move just past TPM_KEY_PARMS */
- cur += sz;
- len -= sz;
-
- if (len < 4)
- return -EBADMSG;
-
- sz = get_unaligned_be32(cur);
- if (len < 4 + sz)
- return -EBADMSG;
-
- /* Move to TPM_STORE_PUBKEY */
- cur += 4 + sz;
- len -= 4 + sz;
-
- /* Grab the size of the public key, it should jive with the key size */
- sz = get_unaligned_be32(cur);
- if (sz > 256)
- return -EINVAL;
-
- pub_key = cur + 4;
-
- tk->key_len = key_len;
- tk->pub_key = pub_key;
- tk->pub_key_len = sz;
-
- return 0;
-}
-
-/* Given the blob, parse it and load it into the TPM */
-struct tpm_key *tpm_key_create(const void *blob, uint32_t blob_len)
-{
- int r;
- struct tpm_key *tk;
-
- r = tpm_is_tpm2(NULL);
- if (r < 0)
- goto error;
-
- /* We don't support TPM2 yet */
- if (r > 0) {
- r = -ENODEV;
- goto error;
- }
-
- r = -ENOMEM;
- tk = kzalloc(sizeof(struct tpm_key), GFP_KERNEL);
- if (!tk)
- goto error;
-
- tk->blob = kmemdup(blob, blob_len, GFP_KERNEL);
- if (!tk->blob)
- goto error_memdup;
-
- tk->blob_len = blob_len;
-
- r = extract_key_parameters(tk);
- if (r < 0)
- goto error_extract;
-
- return tk;
-
-error_extract:
- kfree(tk->blob);
- tk->blob_len = 0;
-error_memdup:
- kfree(tk);
-error:
- return ERR_PTR(r);
-}
-EXPORT_SYMBOL_GPL(tpm_key_create);
-
-/*
- * TPM-based asymmetric key subtype
- */
-struct asymmetric_key_subtype asym_tpm_subtype = {
- .owner = THIS_MODULE,
- .name = "asym_tpm",
- .name_len = sizeof("asym_tpm") - 1,
- .describe = asym_tpm_describe,
- .destroy = asym_tpm_destroy,
- .query = tpm_key_query,
- .eds_op = tpm_key_eds_op,
- .verify_signature = tpm_key_verify_signature,
-};
-EXPORT_SYMBOL_GPL(asym_tpm_subtype);
-
-MODULE_DESCRIPTION("TPM based asymmetric key subtype");
-MODULE_AUTHOR("Intel Corporation");
-MODULE_LICENSE("GPL v2");
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index 6e5fc8e31f01..41a2f0eb4ce4 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Asymmetric public-key cryptography key type
*
- * See Documentation/crypto/asymmetric-keys.txt
+ * See Documentation/crypto/asymmetric-keys.rst
*
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
@@ -36,16 +36,23 @@ static DECLARE_RWSEM(asymmetric_key_parsers_sem);
* find_asymmetric_key - Find a key by ID.
* @keyring: The keys to search.
* @id_0: The first ID to look for or NULL.
- * @id_1: The second ID to look for or NULL.
- * @partial: Use partial match if true, exact if false.
+ * @id_1: The second ID to look for or NULL, matched together with @id_0
+ * against @keyring keys' id[0] and id[1].
+ * @id_2: The fallback ID to match against @keyring keys' id[2] if both of the
+ * other IDs are NULL.
+ * @partial: Use partial match for @id_0 and @id_1 if true, exact if false.
*
* Find a key in the given keyring by identifier. The preferred identifier is
* the id_0 and the fallback identifier is the id_1. If both are given, the
- * lookup is by the former, but the latter must also match.
+ * former is matched (exactly or partially) against either of the sought key's
+ * identifiers and the latter must match the found key's second identifier
+ * exactly. If both are missing, id_2 must match the sought key's third
+ * identifier exactly.
*/
struct key *find_asymmetric_key(struct key *keyring,
const struct asymmetric_key_id *id_0,
const struct asymmetric_key_id *id_1,
+ const struct asymmetric_key_id *id_2,
bool partial)
{
struct key *key;
@@ -54,14 +61,17 @@ struct key *find_asymmetric_key(struct key *keyring,
char *req, *p;
int len;
- BUG_ON(!id_0 && !id_1);
+ WARN_ON(!id_0 && !id_1 && !id_2);
if (id_0) {
lookup = id_0->data;
len = id_0->len;
- } else {
+ } else if (id_1) {
lookup = id_1->data;
len = id_1->len;
+ } else {
+ lookup = id_2->data;
+ len = id_2->len;
}
/* Construct an identifier "id:<keyid>". */
@@ -69,7 +79,10 @@ struct key *find_asymmetric_key(struct key *keyring,
if (!req)
return ERR_PTR(-ENOMEM);
- if (partial) {
+ if (!id_0 && !id_1) {
+ *p++ = 'd';
+ *p++ = 'n';
+ } else if (partial) {
*p++ = 'i';
*p++ = 'd';
} else {
@@ -152,7 +165,8 @@ EXPORT_SYMBOL_GPL(asymmetric_key_generate_id);
/**
* asymmetric_key_id_same - Return true if two asymmetric keys IDs are the same.
- * @kid_1, @kid_2: The key IDs to compare
+ * @kid1: The key ID to compare
+ * @kid2: The key ID to compare
*/
bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1,
const struct asymmetric_key_id *kid2)
@@ -168,7 +182,8 @@ EXPORT_SYMBOL_GPL(asymmetric_key_id_same);
/**
* asymmetric_key_id_partial - Return true if two asymmetric keys IDs
* partially match
- * @kid_1, @kid_2: The key IDs to compare
+ * @kid1: The key ID to compare
+ * @kid2: The key ID to compare
*/
bool asymmetric_key_id_partial(const struct asymmetric_key_id *kid1,
const struct asymmetric_key_id *kid2)
@@ -183,8 +198,8 @@ bool asymmetric_key_id_partial(const struct asymmetric_key_id *kid1,
EXPORT_SYMBOL_GPL(asymmetric_key_id_partial);
/**
- * asymmetric_match_key_ids - Search asymmetric key IDs
- * @kids: The list of key IDs to check
+ * asymmetric_match_key_ids - Search asymmetric key IDs 1 & 2
+ * @kids: The pair of key IDs to check
* @match_id: The key ID we're looking for
* @match: The match function to use
*/
@@ -198,7 +213,7 @@ static bool asymmetric_match_key_ids(
if (!kids || !match_id)
return false;
- for (i = 0; i < ARRAY_SIZE(kids->id); i++)
+ for (i = 0; i < 2; i++)
if (match(kids->id[i], match_id))
return true;
return false;
@@ -242,7 +257,7 @@ struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id)
}
/*
- * Match asymmetric keys by an exact match on an ID.
+ * Match asymmetric keys by an exact match on one of the first two IDs.
*/
static bool asymmetric_key_cmp(const struct key *key,
const struct key_match_data *match_data)
@@ -255,7 +270,7 @@ static bool asymmetric_key_cmp(const struct key *key,
}
/*
- * Match asymmetric keys by a partial match on an IDs.
+ * Match asymmetric keys by a partial match on one of the first two IDs.
*/
static bool asymmetric_key_cmp_partial(const struct key *key,
const struct key_match_data *match_data)
@@ -268,14 +283,27 @@ static bool asymmetric_key_cmp_partial(const struct key *key,
}
/*
+ * Match asymmetric keys by an exact match on the third IDs.
+ */
+static bool asymmetric_key_cmp_name(const struct key *key,
+ const struct key_match_data *match_data)
+{
+ const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
+ const struct asymmetric_key_id *match_id = match_data->preparsed;
+
+ return kids && asymmetric_key_id_same(kids->id[2], match_id);
+}
+
+/*
* Preparse the match criterion. If we don't set lookup_type and cmp,
* the default will be an exact match on the key description.
*
* There are some specifiers for matching key IDs rather than by the key
* description:
*
- * "id:<id>" - find a key by partial match on any available ID
- * "ex:<id>" - find a key by exact match on any available ID
+ * "id:<id>" - find a key by partial match on one of the first two IDs
+ * "ex:<id>" - find a key by exact match on one of the first two IDs
+ * "dn:<id>" - find a key by exact match on the third ID
*
* These have to be searched by iteration rather than by direct lookup because
* the key is hashed according to its description.
@@ -299,6 +327,11 @@ static int asymmetric_key_match_preparse(struct key_match_data *match_data)
spec[1] == 'x' &&
spec[2] == ':') {
id = spec + 3;
+ } else if (spec[0] == 'd' &&
+ spec[1] == 'n' &&
+ spec[2] == ':') {
+ id = spec + 3;
+ cmp = asymmetric_key_cmp_name;
} else {
goto default_match;
}
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index 967329e0a07b..277482bb1777 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -248,6 +248,15 @@ int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
case OID_sha224:
ctx->sinfo->sig->hash_algo = "sha224";
break;
+ case OID_sm3:
+ ctx->sinfo->sig->hash_algo = "sm3";
+ break;
+ case OID_gost2012Digest256:
+ ctx->sinfo->sig->hash_algo = "streebog256";
+ break;
+ case OID_gost2012Digest512:
+ ctx->sinfo->sig->hash_algo = "streebog512";
+ break;
default:
printk("Unsupported digest algo: %u\n", ctx->last_oid);
return -ENOPKG;
@@ -269,6 +278,23 @@ int pkcs7_sig_note_pkey_algo(void *context, size_t hdrlen,
ctx->sinfo->sig->pkey_algo = "rsa";
ctx->sinfo->sig->encoding = "pkcs1";
break;
+ case OID_id_ecdsa_with_sha1:
+ case OID_id_ecdsa_with_sha224:
+ case OID_id_ecdsa_with_sha256:
+ case OID_id_ecdsa_with_sha384:
+ case OID_id_ecdsa_with_sha512:
+ ctx->sinfo->sig->pkey_algo = "ecdsa";
+ ctx->sinfo->sig->encoding = "x962";
+ break;
+ case OID_SM2_with_SM3:
+ ctx->sinfo->sig->pkey_algo = "sm2";
+ ctx->sinfo->sig->encoding = "raw";
+ break;
+ case OID_gost2012PKey256:
+ case OID_gost2012PKey512:
+ ctx->sinfo->sig->pkey_algo = "ecrdsa";
+ ctx->sinfo->sig->encoding = "raw";
+ break;
default:
printk("Unsupported pkey algo: %u\n", ctx->last_oid);
return -ENOPKG;
diff --git a/crypto/asymmetric_keys/pkcs7_parser.h b/crypto/asymmetric_keys/pkcs7_parser.h
index 6565fdc2d4ca..e17f7ce4fb43 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.h
+++ b/crypto/asymmetric_keys/pkcs7_parser.h
@@ -41,10 +41,9 @@ struct pkcs7_signed_info {
*
* This contains the generated digest of _either_ the Content Data or
* the Authenticated Attributes [RFC2315 9.3]. If the latter, one of
- * the attributes contains the digest of the the Content Data within
- * it.
+ * the attributes contains the digest of the Content Data within it.
*
- * THis also contains the issuing cert serial number and issuer's name
+ * This also contains the issuing cert serial number and issuer's name
* [PKCS#7 or CMS ver 1] or issuing cert's SKID [CMS ver 3].
*/
struct public_key_signature *sig;
diff --git a/crypto/asymmetric_keys/pkcs7_trust.c b/crypto/asymmetric_keys/pkcs7_trust.c
index 61af3c4d82cc..9a87c34ed173 100644
--- a/crypto/asymmetric_keys/pkcs7_trust.c
+++ b/crypto/asymmetric_keys/pkcs7_trust.c
@@ -16,7 +16,7 @@
#include <crypto/public_key.h>
#include "pkcs7_parser.h"
-/**
+/*
* Check the trust on one PKCS#7 SignedInfo block.
*/
static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
@@ -48,7 +48,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
* keys.
*/
key = find_asymmetric_key(trust_keyring,
- x509->id, x509->skid, false);
+ x509->id, x509->skid, NULL, false);
if (!IS_ERR(key)) {
/* One of the X.509 certificates in the PKCS#7 message
* is apparently the same as one we already trust.
@@ -82,7 +82,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
key = find_asymmetric_key(trust_keyring,
last->sig->auth_ids[0],
last->sig->auth_ids[1],
- false);
+ NULL, false);
if (!IS_ERR(key)) {
x509 = last;
pr_devel("sinfo %u: Root cert %u signer is key %x\n",
@@ -97,7 +97,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
* the signed info directly.
*/
key = find_asymmetric_key(trust_keyring,
- sinfo->sig->auth_ids[0], NULL, false);
+ sinfo->sig->auth_ids[0], NULL, NULL, false);
if (!IS_ERR(key)) {
pr_devel("sinfo %u: Direct signer is key %x\n",
sinfo->index, key_serial(key));
diff --git a/crypto/asymmetric_keys/pkcs7_verify.c b/crypto/asymmetric_keys/pkcs7_verify.c
index ce49820caa97..f6321c785714 100644
--- a/crypto/asymmetric_keys/pkcs7_verify.c
+++ b/crypto/asymmetric_keys/pkcs7_verify.c
@@ -141,11 +141,10 @@ int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u32 *len,
*buf = sinfo->sig->digest;
*len = sinfo->sig->digest_size;
- for (i = 0; i < HASH_ALGO__LAST; i++)
- if (!strcmp(hash_algo_name[i], sinfo->sig->hash_algo)) {
- *hash_algo = i;
- break;
- }
+ i = match_string(hash_algo_name, HASH_ALGO__LAST,
+ sinfo->sig->hash_algo);
+ if (i >= 0)
+ *hash_algo = i;
return 0;
}
@@ -175,12 +174,6 @@ static int pkcs7_find_key(struct pkcs7_message *pkcs7,
pr_devel("Sig %u: Found cert serial match X.509[%u]\n",
sinfo->index, certix);
- if (strcmp(x509->pub->pkey_algo, sinfo->sig->pkey_algo) != 0) {
- pr_warn("Sig %u: X.509 algo and PKCS#7 sig algo don't match\n",
- sinfo->index);
- continue;
- }
-
sinfo->signer = x509;
return 0;
}
@@ -227,9 +220,6 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
return 0;
}
- if (x509->unsupported_key)
- goto unsupported_crypto_in_x509;
-
pr_debug("- issuer %s\n", x509->issuer);
sig = x509->sig;
if (sig->auth_ids[0])
@@ -246,7 +236,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
* authority.
*/
if (x509->unsupported_sig)
- goto unsupported_crypto_in_x509;
+ goto unsupported_sig_in_x509;
x509->signer = x509;
pr_debug("- self-signed\n");
return 0;
@@ -310,7 +300,7 @@ static int pkcs7_verify_sig_chain(struct pkcs7_message *pkcs7,
might_sleep();
}
-unsupported_crypto_in_x509:
+unsupported_sig_in_x509:
/* Just prune the certificate chain at this point if we lack some
* crypto module to go further. Note, however, we don't want to set
* sinfo->unsupported_crypto as the signed info block may still be
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index d7f43d4ea925..2f8352e88860 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* In-software asymmetric public-key crypto subtype
*
- * See Documentation/crypto/asymmetric-keys.txt
+ * See Documentation/crypto/asymmetric-keys.rst
*
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
@@ -14,9 +14,12 @@
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/scatterlist.h>
+#include <linux/asn1.h>
#include <keys/asymmetric-subtype.h>
#include <crypto/public_key.h>
#include <crypto/akcipher.h>
+#include <crypto/sm2.h>
+#include <crypto/sm3_base.h>
MODULE_DESCRIPTION("In-software asymmetric public-key subtype");
MODULE_AUTHOR("Red Hat, Inc.");
@@ -57,38 +60,83 @@ static void public_key_destroy(void *payload0, void *payload3)
}
/*
- * Determine the crypto algorithm name.
+ * Given a public_key, and an encoding and hash_algo to be used for signing
+ * and/or verification with that key, determine the name of the corresponding
+ * akcipher algorithm. Also check that encoding and hash_algo are allowed.
*/
-static
-int software_key_determine_akcipher(const char *encoding,
- const char *hash_algo,
- const struct public_key *pkey,
- char alg_name[CRYPTO_MAX_ALG_NAME])
+static int
+software_key_determine_akcipher(const struct public_key *pkey,
+ const char *encoding, const char *hash_algo,
+ char alg_name[CRYPTO_MAX_ALG_NAME])
{
int n;
- if (strcmp(encoding, "pkcs1") == 0) {
- /* The data wangled by the RSA algorithm is typically padded
- * and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
- * sec 8.2].
+ if (!encoding)
+ return -EINVAL;
+
+ if (strcmp(pkey->pkey_algo, "rsa") == 0) {
+ /*
+ * RSA signatures usually use EMSA-PKCS1-1_5 [RFC3447 sec 8.2].
+ */
+ if (strcmp(encoding, "pkcs1") == 0) {
+ if (!hash_algo)
+ n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+ "pkcs1pad(%s)",
+ pkey->pkey_algo);
+ else
+ n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
+ "pkcs1pad(%s,%s)",
+ pkey->pkey_algo, hash_algo);
+ return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
+ }
+ if (strcmp(encoding, "raw") != 0)
+ return -EINVAL;
+ /*
+ * Raw RSA cannot differentiate between different hash
+ * algorithms.
+ */
+ if (hash_algo)
+ return -EINVAL;
+ } else if (strncmp(pkey->pkey_algo, "ecdsa", 5) == 0) {
+ if (strcmp(encoding, "x962") != 0)
+ return -EINVAL;
+ /*
+ * ECDSA signatures are taken over a raw hash, so they don't
+ * differentiate between different hash algorithms. That means
+ * that the verifier should hard-code a specific hash algorithm.
+ * Unfortunately, in practice ECDSA is used with multiple SHAs,
+ * so we have to allow all of them and not just one.
*/
if (!hash_algo)
- n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
- "pkcs1pad(%s)",
- pkey->pkey_algo);
- else
- n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
- "pkcs1pad(%s,%s)",
- pkey->pkey_algo, hash_algo);
- return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
- }
-
- if (strcmp(encoding, "raw") == 0) {
- strcpy(alg_name, pkey->pkey_algo);
- return 0;
+ return -EINVAL;
+ if (strcmp(hash_algo, "sha1") != 0 &&
+ strcmp(hash_algo, "sha224") != 0 &&
+ strcmp(hash_algo, "sha256") != 0 &&
+ strcmp(hash_algo, "sha384") != 0 &&
+ strcmp(hash_algo, "sha512") != 0)
+ return -EINVAL;
+ } else if (strcmp(pkey->pkey_algo, "sm2") == 0) {
+ if (strcmp(encoding, "raw") != 0)
+ return -EINVAL;
+ if (!hash_algo)
+ return -EINVAL;
+ if (strcmp(hash_algo, "sm3") != 0)
+ return -EINVAL;
+ } else if (strcmp(pkey->pkey_algo, "ecrdsa") == 0) {
+ if (strcmp(encoding, "raw") != 0)
+ return -EINVAL;
+ if (!hash_algo)
+ return -EINVAL;
+ if (strcmp(hash_algo, "streebog256") != 0 &&
+ strcmp(hash_algo, "streebog512") != 0)
+ return -EINVAL;
+ } else {
+ /* Unknown public key algorithm */
+ return -ENOPKG;
}
-
- return -ENOPKG;
+ if (strscpy(alg_name, pkey->pkey_algo, CRYPTO_MAX_ALG_NAME) < 0)
+ return -EINVAL;
+ return 0;
}
static u8 *pkey_pack_u32(u8 *dst, u32 val)
@@ -109,9 +157,8 @@ static int software_key_query(const struct kernel_pkey_params *params,
u8 *key, *ptr;
int ret, len;
- ret = software_key_determine_akcipher(params->encoding,
- params->hash_algo,
- pkey, alg_name);
+ ret = software_key_determine_akcipher(pkey, params->encoding,
+ params->hash_algo, alg_name);
if (ret < 0)
return ret;
@@ -119,6 +166,7 @@ static int software_key_query(const struct kernel_pkey_params *params,
if (IS_ERR(tfm))
return PTR_ERR(tfm);
+ ret = -ENOMEM;
key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
GFP_KERNEL);
if (!key)
@@ -174,9 +222,8 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
pr_devel("==>%s()\n", __func__);
- ret = software_key_determine_akcipher(params->encoding,
- params->hash_algo,
- pkey, alg_name);
+ ret = software_key_determine_akcipher(pkey, params->encoding,
+ params->hash_algo, alg_name);
if (ret < 0)
return ret;
@@ -245,6 +292,65 @@ error_free_tfm:
return ret;
}
+#if IS_REACHABLE(CONFIG_CRYPTO_SM2)
+static int cert_sig_digest_update(const struct public_key_signature *sig,
+ struct crypto_akcipher *tfm_pkey)
+{
+ struct crypto_shash *tfm;
+ struct shash_desc *desc;
+ size_t desc_size;
+ unsigned char dgst[SM3_DIGEST_SIZE];
+ int ret;
+
+ BUG_ON(!sig->data);
+
+ /* SM2 signatures always use the SM3 hash algorithm */
+ if (!sig->hash_algo || strcmp(sig->hash_algo, "sm3") != 0)
+ return -EINVAL;
+
+ ret = sm2_compute_z_digest(tfm_pkey, SM2_DEFAULT_USERID,
+ SM2_DEFAULT_USERID_LEN, dgst);
+ if (ret)
+ return ret;
+
+ tfm = crypto_alloc_shash(sig->hash_algo, 0, 0);
+ if (IS_ERR(tfm))
+ return PTR_ERR(tfm);
+
+ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
+ desc = kzalloc(desc_size, GFP_KERNEL);
+ if (!desc) {
+ ret = -ENOMEM;
+ goto error_free_tfm;
+ }
+
+ desc->tfm = tfm;
+
+ ret = crypto_shash_init(desc);
+ if (ret < 0)
+ goto error_free_desc;
+
+ ret = crypto_shash_update(desc, dgst, SM3_DIGEST_SIZE);
+ if (ret < 0)
+ goto error_free_desc;
+
+ ret = crypto_shash_finup(desc, sig->data, sig->data_size, sig->digest);
+
+error_free_desc:
+ kfree(desc);
+error_free_tfm:
+ crypto_free_shash(tfm);
+ return ret;
+}
+#else
+static inline int cert_sig_digest_update(
+ const struct public_key_signature *sig,
+ struct crypto_akcipher *tfm_pkey)
+{
+ return -ENOTSUPP;
+}
+#endif /* ! IS_REACHABLE(CONFIG_CRYPTO_SM2) */
+
/*
* Verify a signature using a public key.
*/
@@ -265,9 +371,23 @@ int public_key_verify_signature(const struct public_key *pkey,
BUG_ON(!sig);
BUG_ON(!sig->s);
- ret = software_key_determine_akcipher(sig->encoding,
- sig->hash_algo,
- pkey, alg_name);
+ /*
+ * If the signature specifies a public key algorithm, it *must* match
+ * the key's actual public key algorithm.
+ *
+ * Small exception: ECDSA signatures don't specify the curve, but ECDSA
+ * keys do. So the strings can mismatch slightly in that case:
+ * "ecdsa-nist-*" for the key, but "ecdsa" for the signature.
+ */
+ if (sig->pkey_algo) {
+ if (strcmp(pkey->pkey_algo, sig->pkey_algo) != 0 &&
+ (strncmp(pkey->pkey_algo, "ecdsa-", 6) != 0 ||
+ strcmp(sig->pkey_algo, "ecdsa") != 0))
+ return -EKEYREJECTED;
+ }
+
+ ret = software_key_determine_akcipher(pkey, sig->encoding,
+ sig->hash_algo, alg_name);
if (ret < 0)
return ret;
@@ -298,6 +418,12 @@ int public_key_verify_signature(const struct public_key *pkey,
if (ret)
goto error_free_key;
+ if (strcmp(pkey->pkey_algo, "sm2") == 0 && sig->data_size) {
+ ret = cert_sig_digest_update(sig, tfm);
+ if (ret)
+ goto error_free_key;
+ }
+
sg_init_table(src_sg, 2);
sg_set_buf(&src_sg[0], sig->s, sig->s_size);
sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c
index 77ebebada29c..6b1ac5f5896a 100644
--- a/crypto/asymmetric_keys/restrict.c
+++ b/crypto/asymmetric_keys/restrict.c
@@ -87,7 +87,7 @@ int restrict_link_by_signature(struct key *dest_keyring,
sig = payload->data[asym_auth];
if (!sig)
return -ENOPKG;
- if (!sig->auth_ids[0] && !sig->auth_ids[1])
+ if (!sig->auth_ids[0] && !sig->auth_ids[1] && !sig->auth_ids[2])
return -ENOKEY;
if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
@@ -96,7 +96,7 @@ int restrict_link_by_signature(struct key *dest_keyring,
/* See if we have a key that signed this one. */
key = find_asymmetric_key(trust_keyring,
sig->auth_ids[0], sig->auth_ids[1],
- false);
+ sig->auth_ids[2], false);
if (IS_ERR(key))
return -ENOKEY;
@@ -108,11 +108,11 @@ int restrict_link_by_signature(struct key *dest_keyring,
return ret;
}
-static bool match_either_id(const struct asymmetric_key_ids *pair,
+static bool match_either_id(const struct asymmetric_key_id **pair,
const struct asymmetric_key_id *single)
{
- return (asymmetric_key_id_same(pair->id[0], single) ||
- asymmetric_key_id_same(pair->id[1], single));
+ return (asymmetric_key_id_same(pair[0], single) ||
+ asymmetric_key_id_same(pair[1], single));
}
static int key_or_keyring_common(struct key *dest_keyring,
@@ -140,20 +140,22 @@ static int key_or_keyring_common(struct key *dest_keyring,
sig = payload->data[asym_auth];
if (!sig)
return -ENOPKG;
- if (!sig->auth_ids[0] && !sig->auth_ids[1])
+ if (!sig->auth_ids[0] && !sig->auth_ids[1] && !sig->auth_ids[2])
return -ENOKEY;
if (trusted) {
if (trusted->type == &key_type_keyring) {
/* See if we have a key that signed this one. */
key = find_asymmetric_key(trusted, sig->auth_ids[0],
- sig->auth_ids[1], false);
+ sig->auth_ids[1],
+ sig->auth_ids[2], false);
if (IS_ERR(key))
key = NULL;
} else if (trusted->type == &key_type_asymmetric) {
- const struct asymmetric_key_ids *signer_ids;
+ const struct asymmetric_key_id **signer_ids;
- signer_ids = asymmetric_key_ids(trusted);
+ signer_ids = (const struct asymmetric_key_id **)
+ asymmetric_key_ids(trusted)->id;
/*
* The auth_ids come from the candidate key (the
@@ -164,22 +166,29 @@ static int key_or_keyring_common(struct key *dest_keyring,
* The signer_ids are identifiers for the
* signing key specified for dest_keyring.
*
- * The first auth_id is the preferred id, and
- * the second is the fallback. If only one
- * auth_id is present, it may match against
- * either signer_id. If two auth_ids are
- * present, the first auth_id must match one
- * signer_id and the second auth_id must match
- * the second signer_id.
+ * The first auth_id is the preferred id, 2nd and
+ * 3rd are the fallbacks. If exactly one of
+ * auth_ids[0] and auth_ids[1] is present, it may
+ * match either signer_ids[0] or signed_ids[1].
+ * If both are present the first one may match
+ * either signed_id but the second one must match
+ * the second signer_id. If neither of them is
+ * available, auth_ids[2] is matched against
+ * signer_ids[2] as a fallback.
*/
- if (!sig->auth_ids[0] || !sig->auth_ids[1]) {
+ if (!sig->auth_ids[0] && !sig->auth_ids[1]) {
+ if (asymmetric_key_id_same(signer_ids[2],
+ sig->auth_ids[2]))
+ key = __key_get(trusted);
+
+ } else if (!sig->auth_ids[0] || !sig->auth_ids[1]) {
const struct asymmetric_key_id *auth_id;
auth_id = sig->auth_ids[0] ?: sig->auth_ids[1];
if (match_either_id(signer_ids, auth_id))
key = __key_get(trusted);
- } else if (asymmetric_key_id_same(signer_ids->id[1],
+ } else if (asymmetric_key_id_same(signer_ids[1],
sig->auth_ids[1]) &&
match_either_id(signer_ids,
sig->auth_ids[0])) {
@@ -193,7 +202,8 @@ static int key_or_keyring_common(struct key *dest_keyring,
if (check_dest && !key) {
/* See if the destination has a key that signed this one. */
key = find_asymmetric_key(dest_keyring, sig->auth_ids[0],
- sig->auth_ids[1], false);
+ sig->auth_ids[1], sig->auth_ids[2],
+ false);
if (IS_ERR(key))
key = NULL;
}
@@ -244,9 +254,10 @@ int restrict_link_by_key_or_keyring(struct key *dest_keyring,
* @payload: The payload of the new key.
* @trusted: A key or ring of keys that can be used to vouch for the new cert.
*
- * Check the new certificate only against the key or keys passed in the data
- * parameter. If one of those is the signing key and validates the new
- * certificate, then mark the new certificate as being ok to link.
+ * Check the new certificate against the key or keys passed in the data
+ * parameter and against the keys already linked to the destination keyring. If
+ * one of those is the signing key and validates the new certificate, then mark
+ * the new certificate as being ok to link.
*
* Returns 0 if the new certificate was accepted, -ENOKEY if we
* couldn't find a matching parent certificate in the trusted list,
diff --git a/crypto/asymmetric_keys/selftest.c b/crypto/asymmetric_keys/selftest.c
new file mode 100644
index 000000000000..fa0bf7f24284
--- /dev/null
+++ b/crypto/asymmetric_keys/selftest.c
@@ -0,0 +1,224 @@
+/* Self-testing for signature checking.
+ *
+ * Copyright (C) 2022 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ */
+
+#include <linux/kernel.h>
+#include <linux/cred.h>
+#include <linux/key.h>
+#include <crypto/pkcs7.h>
+#include "x509_parser.h"
+
+struct certs_test {
+ const u8 *data;
+ size_t data_len;
+ const u8 *pkcs7;
+ size_t pkcs7_len;
+};
+
+/*
+ * Set of X.509 certificates to provide public keys for the tests. These will
+ * be loaded into a temporary keyring for the duration of the testing.
+ */
+static const __initconst u8 certs_selftest_keys[] = {
+ "\x30\x82\x05\x55\x30\x82\x03\x3d\xa0\x03\x02\x01\x02\x02\x14\x73"
+ "\x98\xea\x98\x2d\xd0\x2e\xa8\xb1\xcf\x57\xc7\xf2\x97\xb3\xe6\x1a"
+ "\xfc\x8c\x0a\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b"
+ "\x05\x00\x30\x34\x31\x32\x30\x30\x06\x03\x55\x04\x03\x0c\x29\x43"
+ "\x65\x72\x74\x69\x66\x69\x63\x61\x74\x65\x20\x76\x65\x72\x69\x66"
+ "\x69\x63\x61\x74\x69\x6f\x6e\x20\x73\x65\x6c\x66\x2d\x74\x65\x73"
+ "\x74\x69\x6e\x67\x20\x6b\x65\x79\x30\x20\x17\x0d\x32\x32\x30\x35"
+ "\x31\x38\x32\x32\x33\x32\x34\x31\x5a\x18\x0f\x32\x31\x32\x32\x30"
+ "\x34\x32\x34\x32\x32\x33\x32\x34\x31\x5a\x30\x34\x31\x32\x30\x30"
+ "\x06\x03\x55\x04\x03\x0c\x29\x43\x65\x72\x74\x69\x66\x69\x63\x61"
+ "\x74\x65\x20\x76\x65\x72\x69\x66\x69\x63\x61\x74\x69\x6f\x6e\x20"
+ "\x73\x65\x6c\x66\x2d\x74\x65\x73\x74\x69\x6e\x67\x20\x6b\x65\x79"
+ "\x30\x82\x02\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01"
+ "\x01\x05\x00\x03\x82\x02\x0f\x00\x30\x82\x02\x0a\x02\x82\x02\x01"
+ "\x00\xcc\xac\x49\xdd\x3b\xca\xb0\x15\x7e\x84\x6a\xb2\x0a\x69\x5f"
+ "\x1c\x0a\x61\x82\x3b\x4f\x2c\xa3\x95\x2c\x08\x58\x4b\xb1\x5d\x99"
+ "\xe0\xc3\xc1\x79\xc2\xb3\xeb\xc0\x1e\x6d\x3e\x54\x1d\xbd\xb7\x92"
+ "\x7b\x4d\xb5\x95\x58\xb2\x52\x2e\xc6\x24\x4b\x71\x63\x80\x32\x77"
+ "\xa7\x38\x5e\xdb\x72\xae\x6e\x0d\xec\xfb\xb6\x6d\x01\x7f\xe9\x55"
+ "\x66\xdf\xbf\x1d\x76\x78\x02\x31\xe8\xe5\x07\xf8\xb7\x82\x5c\x0d"
+ "\xd4\xbb\xfb\xa2\x59\x0d\x2e\x3a\x78\x95\x3a\x8b\x46\x06\x47\x44"
+ "\x46\xd7\xcd\x06\x6a\x41\x13\xe3\x19\xf6\xbb\x6e\x38\xf4\x83\x01"
+ "\xa3\xbf\x4a\x39\x4f\xd7\x0a\xe9\x38\xb3\xf5\x94\x14\x4e\xdd\xf7"
+ "\x43\xfd\x24\xb2\x49\x3c\xa5\xf7\x7a\x7c\xd4\x45\x3d\x97\x75\x68"
+ "\xf1\xed\x4c\x42\x0b\x70\xca\x85\xf3\xde\xe5\x88\x2c\xc5\xbe\xb6"
+ "\x97\x34\xba\x24\x02\xcd\x8b\x86\x9f\xa9\x73\xca\x73\xcf\x92\x81"
+ "\xee\x75\x55\xbb\x18\x67\x5c\xff\x3f\xb5\xdd\x33\x1b\x0c\xe9\x78"
+ "\xdb\x5c\xcf\xaa\x5c\x43\x42\xdf\x5e\xa9\x6d\xec\xd7\xd7\xff\xe6"
+ "\xa1\x3a\x92\x1a\xda\xae\xf6\x8c\x6f\x7b\xd5\xb4\x6e\x06\xe9\x8f"
+ "\xe8\xde\x09\x31\x89\xed\x0e\x11\xa1\xfa\x8a\xe9\xe9\x64\x59\x62"
+ "\x53\xda\xd1\x70\xbe\x11\xd4\x99\x97\x11\xcf\x99\xde\x0b\x9d\x94"
+ "\x7e\xaa\xb8\x52\xea\x37\xdb\x90\x7e\x35\xbd\xd9\xfe\x6d\x0a\x48"
+ "\x70\x28\xdd\xd5\x0d\x7f\x03\x80\x93\x14\x23\x8f\xb9\x22\xcd\x7c"
+ "\x29\xfe\xf1\x72\xb5\x5c\x0b\x12\xcf\x9c\x15\xf6\x11\x4c\x7a\x45"
+ "\x25\x8c\x45\x0a\x34\xac\x2d\x9a\x81\xca\x0b\x13\x22\xcd\xeb\x1a"
+ "\x38\x88\x18\x97\x96\x08\x81\xaa\xcc\x8f\x0f\x8a\x32\x7b\x76\x68"
+ "\x03\x68\x43\xbf\x11\xba\x55\x60\xfd\x80\x1c\x0d\x9b\x69\xb6\x09"
+ "\x72\xbc\x0f\x41\x2f\x07\x82\xc6\xe3\xb2\x13\x91\xc4\x6d\x14\x95"
+ "\x31\xbe\x19\xbd\xbc\xed\xe1\x4c\x74\xa2\xe0\x78\x0b\xbb\x94\xec"
+ "\x4c\x53\x3a\xa2\xb5\x84\x1d\x4b\x65\x7e\xdc\xf7\xdb\x36\x7d\xbe"
+ "\x9e\x3b\x36\x66\x42\x66\x76\x35\xbf\xbe\xf0\xc1\x3c\x7c\xe9\x42"
+ "\x5c\x24\x53\x03\x05\xa8\x67\x24\x50\x02\x75\xff\x24\x46\x3b\x35"
+ "\x89\x76\xe6\x70\xda\xc5\x51\x8c\x9a\xe5\x05\xb0\x0b\xd0\x2d\xd4"
+ "\x7d\x57\x75\x94\x6b\xf9\x0a\xad\x0e\x41\x00\x15\xd0\x4f\xc0\x7f"
+ "\x90\x2d\x18\x48\x8f\x28\xfe\x5d\xa7\xcd\x99\x9e\xbd\x02\x6c\x8a"
+ "\x31\xf3\x1c\xc7\x4b\xe6\x93\xcd\x42\xa2\xe4\x68\x10\x47\x9d\xfc"
+ "\x21\x02\x03\x01\x00\x01\xa3\x5d\x30\x5b\x30\x0c\x06\x03\x55\x1d"
+ "\x13\x01\x01\xff\x04\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04"
+ "\x04\x03\x02\x07\x80\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14"
+ "\xf5\x87\x03\xbb\x33\xce\x1b\x73\xee\x02\xec\xcd\xee\x5b\x88\x17"
+ "\x51\x8f\xe3\xdb\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80"
+ "\x14\xf5\x87\x03\xbb\x33\xce\x1b\x73\xee\x02\xec\xcd\xee\x5b\x88"
+ "\x17\x51\x8f\xe3\xdb\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01"
+ "\x01\x0b\x05\x00\x03\x82\x02\x01\x00\xc0\x2e\x12\x41\x7b\x73\x85"
+ "\x16\xc8\xdb\x86\x79\xe8\xf5\xcd\x44\xf4\xc6\xe2\x81\x23\x5e\x47"
+ "\xcb\xab\x25\xf1\x1e\x58\x3e\x31\x7f\x78\xad\x85\xeb\xfe\x14\x88"
+ "\x60\xf7\x7f\xd2\x26\xa2\xf4\x98\x2a\xfd\xba\x05\x0c\x20\x33\x12"
+ "\xcc\x4d\x14\x61\x64\x81\x93\xd3\x33\xed\xc8\xff\xf1\x78\xcc\x5f"
+ "\x51\x9f\x09\xd7\xbe\x0d\x5c\x74\xfd\x9b\xdf\x52\x4a\xc9\xa8\x71"
+ "\x25\x33\x04\x10\x67\x36\xd0\xb3\x0b\xc9\xa1\x40\x72\xae\x41\x7b"
+ "\x68\xe6\xe4\x7b\xd0\x28\xf7\x6d\xe7\x3f\x50\xfc\x91\x7c\x91\x56"
+ "\xd4\xdf\xa6\xbb\xe8\x4d\x1b\x58\xaa\x28\xfa\xc1\x19\xeb\x11\x2f"
+ "\x24\x8b\x7c\xc5\xa9\x86\x26\xaa\x6e\xb7\x9b\xd5\xf8\x06\xfb\x02"
+ "\x52\x7b\x9c\x9e\xa1\xe0\x07\x8b\x5e\xe4\xb8\x55\x29\xf6\x48\x52"
+ "\x1c\x1b\x54\x2d\x46\xd8\xe5\x71\xb9\x60\xd1\x45\xb5\x92\x89\x8a"
+ "\x63\x58\x2a\xb3\xc6\xb2\x76\xe2\x3c\x82\x59\x04\xae\x5a\xc4\x99"
+ "\x7b\x2e\x4b\x46\x57\xb8\x29\x24\xb2\xfd\xee\x2c\x0d\xa4\x83\xfa"
+ "\x65\x2a\x07\x35\x8b\x97\xcf\xbd\x96\x2e\xd1\x7e\x6c\xc2\x1e\x87"
+ "\xb6\x6c\x76\x65\xb5\xb2\x62\xda\x8b\xe9\x73\xe3\xdb\x33\xdd\x13"
+ "\x3a\x17\x63\x6a\x76\xde\x8d\x8f\xe0\x47\x61\x28\x3a\x83\xff\x8f"
+ "\xe7\xc7\xe0\x4a\xa3\xe5\x07\xcf\xe9\x8c\x35\x35\x2e\xe7\x80\x66"
+ "\x31\xbf\x91\x58\x0a\xe1\x25\x3d\x38\xd3\xa4\xf0\x59\x34\x47\x07"
+ "\x62\x0f\xbe\x30\xdd\x81\x88\x58\xf0\x28\xb0\x96\xe5\x82\xf8\x05"
+ "\xb7\x13\x01\xbc\xfa\xc6\x1f\x86\x72\xcc\xf9\xee\x8e\xd9\xd6\x04"
+ "\x8c\x24\x6c\xbf\x0f\x5d\x37\x39\xcf\x45\xc1\x93\x3a\xd2\xed\x5c"
+ "\x58\x79\x74\x86\x62\x30\x7e\x8e\xbb\xdd\x7a\xa9\xed\xca\x40\xcb"
+ "\x62\x47\xf4\xb4\x9f\x52\x7f\x72\x63\xa8\xf0\x2b\xaf\x45\x2a\x48"
+ "\x19\x6d\xe3\xfb\xf9\x19\x66\x69\xc8\xcc\x62\x87\x6c\x53\x2b\x2d"
+ "\x6e\x90\x6c\x54\x3a\x82\x25\x41\xcb\x18\x6a\xa4\x22\xa8\xa1\xc4"
+ "\x47\xd7\x81\x00\x1c\x15\x51\x0f\x1a\xaf\xef\x9f\xa6\x61\x8c\xbd"
+ "\x6b\x8b\xed\xe6\xac\x0e\xb6\x3a\x4c\x92\xe6\x0f\x91\x0a\x0f\x71"
+ "\xc7\xa0\xb9\x0d\x3a\x17\x5a\x6f\x35\xc8\xe7\x50\x4f\x46\xe8\x70"
+ "\x60\x48\x06\x82\x8b\x66\x58\xe6\x73\x91\x9c\x12\x3d\x35\x8e\x46"
+ "\xad\x5a\xf5\xb3\xdb\x69\x21\x04\xfd\xd3\x1c\xdf\x94\x9d\x56\xb0"
+ "\x0a\xd1\x95\x76\x8d\xec\x9e\xdd\x0b\x15\x97\x64\xad\xe5\xf2\x62"
+ "\x02\xfc\x9e\x5f\x56\x42\x39\x05\xb3"
+};
+
+/*
+ * Signed data and detached signature blobs that form the verification tests.
+ */
+static const __initconst u8 certs_selftest_1_data[] = {
+ "\x54\x68\x69\x73\x20\x69\x73\x20\x73\x6f\x6d\x65\x20\x74\x65\x73"
+ "\x74\x20\x64\x61\x74\x61\x20\x75\x73\x65\x64\x20\x66\x6f\x72\x20"
+ "\x73\x65\x6c\x66\x2d\x74\x65\x73\x74\x69\x6e\x67\x20\x63\x65\x72"
+ "\x74\x69\x66\x69\x63\x61\x74\x65\x20\x76\x65\x72\x69\x66\x69\x63"
+ "\x61\x74\x69\x6f\x6e\x2e\x0a"
+};
+
+static const __initconst u8 certs_selftest_1_pkcs7[] = {
+ "\x30\x82\x02\xab\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x07\x02\xa0"
+ "\x82\x02\x9c\x30\x82\x02\x98\x02\x01\x01\x31\x0d\x30\x0b\x06\x09"
+ "\x60\x86\x48\x01\x65\x03\x04\x02\x01\x30\x0b\x06\x09\x2a\x86\x48"
+ "\x86\xf7\x0d\x01\x07\x01\x31\x82\x02\x75\x30\x82\x02\x71\x02\x01"
+ "\x01\x30\x4c\x30\x34\x31\x32\x30\x30\x06\x03\x55\x04\x03\x0c\x29"
+ "\x43\x65\x72\x74\x69\x66\x69\x63\x61\x74\x65\x20\x76\x65\x72\x69"
+ "\x66\x69\x63\x61\x74\x69\x6f\x6e\x20\x73\x65\x6c\x66\x2d\x74\x65"
+ "\x73\x74\x69\x6e\x67\x20\x6b\x65\x79\x02\x14\x73\x98\xea\x98\x2d"
+ "\xd0\x2e\xa8\xb1\xcf\x57\xc7\xf2\x97\xb3\xe6\x1a\xfc\x8c\x0a\x30"
+ "\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x30\x0d\x06\x09"
+ "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x04\x82\x02\x00\xac"
+ "\xb0\xf2\x07\xd6\x99\x6d\xc0\xc0\xd9\x8d\x31\x0d\x7e\x04\xeb\xc3"
+ "\x88\x90\xc4\x58\x46\xd4\xe2\xa0\xa3\x25\xe3\x04\x50\x37\x85\x8c"
+ "\x91\xc6\xfc\xc5\xd4\x92\xfd\x05\xd8\xb8\xa3\xb8\xba\x89\x13\x00"
+ "\x88\x79\x99\x51\x6b\x5b\x28\x31\xc0\xb3\x1b\x7a\x68\x2c\x00\xdb"
+ "\x4b\x46\x11\xf3\xfa\x50\x8e\x19\x89\xa2\x4c\xda\x4c\x89\x01\x11"
+ "\x89\xee\xd3\xc8\xc1\xe7\xa7\xf6\xb2\xa2\xf8\x65\xb8\x35\x20\x33"
+ "\xba\x12\x62\xd5\xbd\xaa\x71\xe5\x5b\xc0\x6a\x32\xff\x6a\x2e\x23"
+ "\xef\x2b\xb6\x58\xb1\xfb\x5f\x82\x34\x40\x6d\x9f\xbc\x27\xac\x37"
+ "\x23\x99\xcf\x7d\x20\xb2\x39\x01\xc0\x12\xce\xd7\x5d\x2f\xb6\xab"
+ "\xb5\x56\x4f\xef\xf4\x72\x07\x58\x65\xa9\xeb\x1f\x75\x1c\x5f\x0c"
+ "\x88\xe0\xa4\xe2\xcd\x73\x2b\x9e\xb2\x05\x7e\x12\xf8\xd0\x66\x41"
+ "\xcc\x12\x63\xd4\xd6\xac\x9b\x1d\x14\x77\x8d\x1c\x57\xd5\x27\xc6"
+ "\x49\xa2\x41\x43\xf3\x59\x29\xe5\xcb\xd1\x75\xbc\x3a\x97\x2a\x72"
+ "\x22\x66\xc5\x3b\xc1\xba\xfc\x53\x18\x98\xe2\x21\x64\xc6\x52\x87"
+ "\x13\xd5\x7c\x42\xe8\xfb\x9c\x9a\x45\x32\xd5\xa5\x22\x62\x9d\xd4"
+ "\xcb\xa4\xfa\x77\xbb\x50\x24\x0b\x8b\x88\x99\x15\x56\xa9\x1e\x92"
+ "\xbf\x5d\x94\x77\xb6\xf1\x67\x01\x60\x06\x58\x5c\xdf\x18\x52\x79"
+ "\x37\x30\x93\x7d\x87\x04\xf1\xe0\x55\x59\x52\xf3\xc2\xb1\x1c\x5b"
+ "\x12\x7c\x49\x87\xfb\xf7\xed\xdd\x95\x71\xec\x4b\x1a\x85\x08\xb0"
+ "\xa0\x36\xc4\x7b\xab\x40\xe0\xf1\x98\xcc\xaf\x19\x40\x8f\x47\x6f"
+ "\xf0\x6c\x84\x29\x7f\x7f\x04\x46\xcb\x08\x0f\xe0\xc1\xc9\x70\x6e"
+ "\x95\x3b\xa4\xbc\x29\x2b\x53\x67\x45\x1b\x0d\xbc\x13\xa5\x76\x31"
+ "\xaf\xb9\xd0\xe0\x60\x12\xd2\xf4\xb7\x7c\x58\x7e\xf6\x2d\xbb\x24"
+ "\x14\x5a\x20\x24\xa8\x12\xdf\x25\xbd\x42\xce\x96\x7c\x2e\xba\x14"
+ "\x1b\x81\x9f\x18\x45\xa4\xc6\x70\x3e\x0e\xf0\xd3\x7b\x9c\x10\xbe"
+ "\xb8\x7a\x89\xc5\x9e\xd9\x97\xdf\xd7\xe7\xc6\x1d\xc0\x20\x6c\xb8"
+ "\x1e\x3a\x63\xb8\x39\x8e\x8e\x62\xd5\xd2\xb4\xcd\xff\x46\xfc\x8e"
+ "\xec\x07\x35\x0c\xff\xb0\x05\xe6\xf4\xe5\xfe\xa2\xe3\x0a\xe6\x36"
+ "\xa7\x4a\x7e\x62\x1d\xc4\x50\x39\x35\x4e\x28\xcb\x4a\xfb\x9d\xdb"
+ "\xdd\x23\xd6\x53\xb1\x74\x77\x12\xf7\x9c\xf0\x9a\x6b\xf7\xa9\x64"
+ "\x2d\x86\x21\x2a\xcf\xc6\x54\xf5\xc9\xad\xfa\xb5\x12\xb4\xf3\x51"
+ "\x77\x55\x3c\x6f\x0c\x32\xd3\x8c\x44\x39\x71\x25\xfe\x96\xd2"
+};
+
+/*
+ * List of tests to be run.
+ */
+#define TEST(data, pkcs7) { data, sizeof(data) - 1, pkcs7, sizeof(pkcs7) - 1 }
+static const struct certs_test certs_tests[] __initconst = {
+ TEST(certs_selftest_1_data, certs_selftest_1_pkcs7),
+};
+
+int __init fips_signature_selftest(void)
+{
+ struct key *keyring;
+ int ret, i;
+
+ pr_notice("Running certificate verification selftests\n");
+
+ keyring = keyring_alloc(".certs_selftest",
+ GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
+ (KEY_POS_ALL & ~KEY_POS_SETATTR) |
+ KEY_USR_VIEW | KEY_USR_READ |
+ KEY_USR_SEARCH,
+ KEY_ALLOC_NOT_IN_QUOTA,
+ NULL, NULL);
+ if (IS_ERR(keyring))
+ panic("Can't allocate certs selftest keyring: %ld\n",
+ PTR_ERR(keyring));
+
+ ret = x509_load_certificate_list(certs_selftest_keys,
+ sizeof(certs_selftest_keys) - 1, keyring);
+ if (ret < 0)
+ panic("Can't allocate certs selftest keyring: %d\n", ret);
+
+ for (i = 0; i < ARRAY_SIZE(certs_tests); i++) {
+ const struct certs_test *test = &certs_tests[i];
+ struct pkcs7_message *pkcs7;
+
+ pkcs7 = pkcs7_parse_message(test->pkcs7, test->pkcs7_len);
+ if (IS_ERR(pkcs7))
+ panic("Certs selftest %d: pkcs7_parse_message() = %d\n", i, ret);
+
+ pkcs7_supply_detached_data(pkcs7, test->data, test->data_len);
+
+ ret = pkcs7_verify(pkcs7, VERIFYING_MODULE_SIGNATURE);
+ if (ret < 0)
+ panic("Certs selftest %d: pkcs7_verify() = %d\n", i, ret);
+
+ ret = pkcs7_validate_trust(pkcs7, keyring);
+ if (ret < 0)
+ panic("Certs selftest %d: pkcs7_validate_trust() = %d\n", i, ret);
+
+ pkcs7_free_message(pkcs7);
+ }
+
+ key_put(keyring);
+ return 0;
+}
diff --git a/crypto/asymmetric_keys/signature.c b/crypto/asymmetric_keys/signature.c
index e24a031db1e4..2deff81f8af5 100644
--- a/crypto/asymmetric_keys/signature.c
+++ b/crypto/asymmetric_keys/signature.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Signature verification with an asymmetric key
*
- * See Documentation/crypto/asymmetric-keys.txt
+ * See Documentation/crypto/asymmetric-keys.rst
*
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
@@ -35,7 +35,7 @@ void public_key_signature_free(struct public_key_signature *sig)
EXPORT_SYMBOL_GPL(public_key_signature_free);
/**
- * query_asymmetric_key - Get information about an aymmetric key.
+ * query_asymmetric_key - Get information about an asymmetric key.
* @params: Various parameters.
* @info: Where to put the information.
*/
diff --git a/crypto/asymmetric_keys/tpm.asn1 b/crypto/asymmetric_keys/tpm.asn1
deleted file mode 100644
index d7f194232f30..000000000000
--- a/crypto/asymmetric_keys/tpm.asn1
+++ /dev/null
@@ -1,5 +0,0 @@
---
--- Unencryted TPM Blob. For details of the format, see:
--- http://david.woodhou.se/draft-woodhouse-cert-best-practice.html#I-D.mavrogiannopoulos-tpmuri
---
-PrivateKeyInfo ::= OCTET STRING ({ tpm_note_key })
diff --git a/crypto/asymmetric_keys/tpm_parser.c b/crypto/asymmetric_keys/tpm_parser.c
deleted file mode 100644
index 96405d8dcd98..000000000000
--- a/crypto/asymmetric_keys/tpm_parser.c
+++ /dev/null
@@ -1,102 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#define pr_fmt(fmt) "TPM-PARSER: "fmt
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <keys/asymmetric-subtype.h>
-#include <keys/asymmetric-parser.h>
-#include <crypto/asym_tpm_subtype.h>
-#include "tpm.asn1.h"
-
-struct tpm_parse_context {
- const void *blob;
- u32 blob_len;
-};
-
-/*
- * Note the key data of the ASN.1 blob.
- */
-int tpm_note_key(void *context, size_t hdrlen,
- unsigned char tag,
- const void *value, size_t vlen)
-{
- struct tpm_parse_context *ctx = context;
-
- ctx->blob = value;
- ctx->blob_len = vlen;
-
- return 0;
-}
-
-/*
- * Parse a TPM-encrypted private key blob.
- */
-static struct tpm_key *tpm_parse(const void *data, size_t datalen)
-{
- struct tpm_parse_context ctx;
- long ret;
-
- memset(&ctx, 0, sizeof(ctx));
-
- /* Attempt to decode the private key */
- ret = asn1_ber_decoder(&tpm_decoder, &ctx, data, datalen);
- if (ret < 0)
- goto error;
-
- return tpm_key_create(ctx.blob, ctx.blob_len);
-
-error:
- return ERR_PTR(ret);
-}
-/*
- * Attempt to parse a data blob for a key as a TPM private key blob.
- */
-static int tpm_key_preparse(struct key_preparsed_payload *prep)
-{
- struct tpm_key *tk;
-
- /*
- * TPM 1.2 keys are max 2048 bits long, so assume the blob is no
- * more than 4x that
- */
- if (prep->datalen > 256 * 4)
- return -EMSGSIZE;
-
- tk = tpm_parse(prep->data, prep->datalen);
-
- if (IS_ERR(tk))
- return PTR_ERR(tk);
-
- /* We're pinning the module by being linked against it */
- __module_get(asym_tpm_subtype.owner);
- prep->payload.data[asym_subtype] = &asym_tpm_subtype;
- prep->payload.data[asym_key_ids] = NULL;
- prep->payload.data[asym_crypto] = tk;
- prep->payload.data[asym_auth] = NULL;
- prep->quotalen = 100;
- return 0;
-}
-
-static struct asymmetric_key_parser tpm_key_parser = {
- .owner = THIS_MODULE,
- .name = "tpm_parser",
- .parse = tpm_key_preparse,
-};
-
-static int __init tpm_key_init(void)
-{
- return register_asymmetric_key_parser(&tpm_key_parser);
-}
-
-static void __exit tpm_key_exit(void)
-{
- unregister_asymmetric_key_parser(&tpm_key_parser);
-}
-
-module_init(tpm_key_init);
-module_exit(tpm_key_exit);
-
-MODULE_DESCRIPTION("TPM private key-blob parser");
-MODULE_LICENSE("GPL v2");
diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c
index cc9dbcecaaca..7553ab18db89 100644
--- a/crypto/asymmetric_keys/verify_pefile.c
+++ b/crypto/asymmetric_keys/verify_pefile.c
@@ -376,7 +376,7 @@ static int pefile_digest_pe(const void *pebuf, unsigned int pelen,
}
error:
- kzfree(desc);
+ kfree_sensitive(desc);
error_no_desc:
crypto_free_shash(tfm);
kleave(" = %d", ret);
@@ -447,6 +447,6 @@ int verify_pefile_signature(const void *pebuf, unsigned pelen,
ret = pefile_digest_pe(pebuf, pelen, &ctx);
error:
- kzfree(ctx.digest);
+ kfree_sensitive(ctx.digest);
return ret;
}
diff --git a/crypto/asymmetric_keys/x509.asn1 b/crypto/asymmetric_keys/x509.asn1
index 5c9f4e4a5231..92d59c32f96a 100644
--- a/crypto/asymmetric_keys/x509.asn1
+++ b/crypto/asymmetric_keys/x509.asn1
@@ -7,7 +7,7 @@ Certificate ::= SEQUENCE {
TBSCertificate ::= SEQUENCE {
version [ 0 ] Version DEFAULT,
serialNumber CertificateSerialNumber ({ x509_note_serial }),
- signature AlgorithmIdentifier ({ x509_note_pkey_algo }),
+ signature AlgorithmIdentifier ({ x509_note_sig_algo }),
issuer Name ({ x509_note_issuer }),
validity Validity,
subject Name ({ x509_note_subject }),
diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
index 26ec20ef4899..7a9b084e2043 100644
--- a/crypto/asymmetric_keys/x509_cert_parser.c
+++ b/crypto/asymmetric_keys/x509_cert_parser.c
@@ -19,15 +19,13 @@
struct x509_parse_context {
struct x509_certificate *cert; /* Certificate being constructed */
unsigned long data; /* Start of data */
- const void *cert_start; /* Start of cert content */
const void *key; /* Key data */
size_t key_size; /* Size of key data */
const void *params; /* Key parameters */
size_t params_size; /* Size of key parameters */
- enum OID key_algo; /* Public key algorithm */
+ enum OID key_algo; /* Algorithm used by the cert's key */
enum OID last_oid; /* Last OID encountered */
- enum OID algo_oid; /* Algorithm OID */
- unsigned char nr_mpi; /* Number of MPIs stored */
+ enum OID sig_algo; /* Algorithm used to sign the cert */
u8 o_size; /* Size of organizationName (O) */
u8 cn_size; /* Size of commonName (CN) */
u8 email_size; /* Size of emailAddress */
@@ -187,11 +185,10 @@ int x509_note_tbs_certificate(void *context, size_t hdrlen,
}
/*
- * Record the public key algorithm
+ * Record the algorithm that was used to sign this certificate.
*/
-int x509_note_pkey_algo(void *context, size_t hdrlen,
- unsigned char tag,
- const void *value, size_t vlen)
+int x509_note_sig_algo(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
{
struct x509_parse_context *ctx = context;
@@ -227,6 +224,26 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
ctx->cert->sig->hash_algo = "sha224";
goto rsa_pkcs1;
+ case OID_id_ecdsa_with_sha1:
+ ctx->cert->sig->hash_algo = "sha1";
+ goto ecdsa;
+
+ case OID_id_ecdsa_with_sha224:
+ ctx->cert->sig->hash_algo = "sha224";
+ goto ecdsa;
+
+ case OID_id_ecdsa_with_sha256:
+ ctx->cert->sig->hash_algo = "sha256";
+ goto ecdsa;
+
+ case OID_id_ecdsa_with_sha384:
+ ctx->cert->sig->hash_algo = "sha384";
+ goto ecdsa;
+
+ case OID_id_ecdsa_with_sha512:
+ ctx->cert->sig->hash_algo = "sha512";
+ goto ecdsa;
+
case OID_gost2012Signature256:
ctx->cert->sig->hash_algo = "streebog256";
goto ecrdsa;
@@ -234,17 +251,31 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
case OID_gost2012Signature512:
ctx->cert->sig->hash_algo = "streebog512";
goto ecrdsa;
+
+ case OID_SM2_with_SM3:
+ ctx->cert->sig->hash_algo = "sm3";
+ goto sm2;
}
rsa_pkcs1:
ctx->cert->sig->pkey_algo = "rsa";
ctx->cert->sig->encoding = "pkcs1";
- ctx->algo_oid = ctx->last_oid;
+ ctx->sig_algo = ctx->last_oid;
return 0;
ecrdsa:
ctx->cert->sig->pkey_algo = "ecrdsa";
ctx->cert->sig->encoding = "raw";
- ctx->algo_oid = ctx->last_oid;
+ ctx->sig_algo = ctx->last_oid;
+ return 0;
+sm2:
+ ctx->cert->sig->pkey_algo = "sm2";
+ ctx->cert->sig->encoding = "raw";
+ ctx->sig_algo = ctx->last_oid;
+ return 0;
+ecdsa:
+ ctx->cert->sig->pkey_algo = "ecdsa";
+ ctx->cert->sig->encoding = "x962";
+ ctx->sig_algo = ctx->last_oid;
return 0;
}
@@ -257,16 +288,23 @@ int x509_note_signature(void *context, size_t hdrlen,
{
struct x509_parse_context *ctx = context;
- pr_debug("Signature type: %u size %zu\n", ctx->last_oid, vlen);
+ pr_debug("Signature: alg=%u, size=%zu\n", ctx->last_oid, vlen);
- if (ctx->last_oid != ctx->algo_oid) {
- pr_warn("Got cert with pkey (%u) and sig (%u) algorithm OIDs\n",
- ctx->algo_oid, ctx->last_oid);
+ /*
+ * In X.509 certificates, the signature's algorithm is stored in two
+ * places: inside the TBSCertificate (the data that is signed), and
+ * alongside the signature. These *must* match.
+ */
+ if (ctx->last_oid != ctx->sig_algo) {
+ pr_warn("signatureAlgorithm (%u) differs from tbsCertificate.signature (%u)\n",
+ ctx->last_oid, ctx->sig_algo);
return -EINVAL;
}
if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0 ||
- strcmp(ctx->cert->sig->pkey_algo, "ecrdsa") == 0) {
+ strcmp(ctx->cert->sig->pkey_algo, "ecrdsa") == 0 ||
+ strcmp(ctx->cert->sig->pkey_algo, "sm2") == 0 ||
+ strcmp(ctx->cert->sig->pkey_algo, "ecdsa") == 0) {
/* Discard the BIT STRING metadata */
if (vlen < 1 || *(const u8 *)value != 0)
return -EBADMSG;
@@ -405,8 +443,18 @@ int x509_note_issuer(void *context, size_t hdrlen,
const void *value, size_t vlen)
{
struct x509_parse_context *ctx = context;
+ struct asymmetric_key_id *kid;
+
ctx->cert->raw_issuer = value;
ctx->cert->raw_issuer_size = vlen;
+
+ if (!ctx->cert->sig->auth_ids[2]) {
+ kid = asymmetric_key_generate_id(value, vlen, "", 0);
+ if (IS_ERR(kid))
+ return PTR_ERR(kid);
+ ctx->cert->sig->auth_ids[2] = kid;
+ }
+
return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen);
}
@@ -449,15 +497,44 @@ int x509_extract_key_data(void *context, size_t hdrlen,
const void *value, size_t vlen)
{
struct x509_parse_context *ctx = context;
+ enum OID oid;
ctx->key_algo = ctx->last_oid;
- if (ctx->last_oid == OID_rsaEncryption)
+ switch (ctx->last_oid) {
+ case OID_rsaEncryption:
ctx->cert->pub->pkey_algo = "rsa";
- else if (ctx->last_oid == OID_gost2012PKey256 ||
- ctx->last_oid == OID_gost2012PKey512)
+ break;
+ case OID_gost2012PKey256:
+ case OID_gost2012PKey512:
ctx->cert->pub->pkey_algo = "ecrdsa";
- else
+ break;
+ case OID_sm2:
+ ctx->cert->pub->pkey_algo = "sm2";
+ break;
+ case OID_id_ecPublicKey:
+ if (parse_OID(ctx->params, ctx->params_size, &oid) != 0)
+ return -EBADMSG;
+
+ switch (oid) {
+ case OID_sm2:
+ ctx->cert->pub->pkey_algo = "sm2";
+ break;
+ case OID_id_prime192v1:
+ ctx->cert->pub->pkey_algo = "ecdsa-nist-p192";
+ break;
+ case OID_id_prime256v1:
+ ctx->cert->pub->pkey_algo = "ecdsa-nist-p256";
+ break;
+ case OID_id_ansip384r1:
+ ctx->cert->pub->pkey_algo = "ecdsa-nist-p384";
+ break;
+ default:
+ return -ENOPKG;
+ }
+ break;
+ default:
return -ENOPKG;
+ }
/* Discard the BIT STRING metadata */
if (vlen < 1 || *(const u8 *)value != 0)
diff --git a/crypto/asymmetric_keys/x509_loader.c b/crypto/asymmetric_keys/x509_loader.c
new file mode 100644
index 000000000000..1bc169dee22e
--- /dev/null
+++ b/crypto/asymmetric_keys/x509_loader.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/kernel.h>
+#include <linux/key.h>
+#include <keys/asymmetric-type.h>
+
+int x509_load_certificate_list(const u8 cert_list[],
+ const unsigned long list_size,
+ const struct key *keyring)
+{
+ key_ref_t key;
+ const u8 *p, *end;
+ size_t plen;
+
+ p = cert_list;
+ end = p + list_size;
+ while (p < end) {
+ /* Each cert begins with an ASN.1 SEQUENCE tag and must be more
+ * than 256 bytes in size.
+ */
+ if (end - p < 4)
+ goto dodgy_cert;
+ if (p[0] != 0x30 &&
+ p[1] != 0x82)
+ goto dodgy_cert;
+ plen = (p[2] << 8) | p[3];
+ plen += 4;
+ if (plen > end - p)
+ goto dodgy_cert;
+
+ key = key_create_or_update(make_key_ref(keyring, 1),
+ "asymmetric",
+ NULL,
+ p,
+ plen,
+ ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
+ KEY_USR_VIEW | KEY_USR_READ),
+ KEY_ALLOC_NOT_IN_QUOTA |
+ KEY_ALLOC_BUILT_IN |
+ KEY_ALLOC_BYPASS_RESTRICTION);
+ if (IS_ERR(key)) {
+ pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
+ PTR_ERR(key));
+ } else {
+ pr_notice("Loaded X.509 cert '%s'\n",
+ key_ref_to_ptr(key)->description);
+ key_ref_put(key);
+ }
+ p += plen;
+ }
+
+ return 0;
+
+dodgy_cert:
+ pr_err("Problem parsing in-kernel X.509 certificate list\n");
+ return 0;
+}
diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
index c233f136fb35..a299c9c56f40 100644
--- a/crypto/asymmetric_keys/x509_parser.h
+++ b/crypto/asymmetric_keys/x509_parser.h
@@ -22,7 +22,7 @@ struct x509_certificate {
time64_t valid_to;
const void *tbs; /* Signed data */
unsigned tbs_size; /* Size of signed data */
- unsigned raw_sig_size; /* Size of sigature */
+ unsigned raw_sig_size; /* Size of signature */
const void *raw_sig; /* Signature data */
const void *raw_serial; /* Raw serial number in ASN.1 */
unsigned raw_serial_size;
@@ -36,12 +36,20 @@ struct x509_certificate {
bool seen; /* Infinite recursion prevention */
bool verified;
bool self_signed; /* T if self-signed (check unsupported_sig too) */
- bool unsupported_key; /* T if key uses unsupported crypto */
bool unsupported_sig; /* T if signature uses unsupported crypto */
bool blacklisted;
};
/*
+ * selftest.c
+ */
+#ifdef CONFIG_FIPS_SIGNATURE_SELFTEST
+extern int __init fips_signature_selftest(void);
+#else
+static inline int fips_signature_selftest(void) { return 0; }
+#endif
+
+/*
* x509_cert_parser.c
*/
extern void x509_free_certificate(struct x509_certificate *cert);
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
index d964cc82b69c..0b4943a4592b 100644
--- a/crypto/asymmetric_keys/x509_public_key.c
+++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -30,17 +30,8 @@ int x509_get_sig_params(struct x509_certificate *cert)
pr_devel("==>%s()\n", __func__);
- if (!cert->pub->pkey_algo)
- cert->unsupported_key = true;
-
- if (!sig->pkey_algo)
- cert->unsupported_sig = true;
-
- /* We check the hash if we can - even if we can't then verify it */
- if (!sig->hash_algo) {
- cert->unsupported_sig = true;
- return 0;
- }
+ sig->data = cert->tbs;
+ sig->data_size = cert->tbs_size;
sig->s = kmemdup(cert->raw_sig, cert->raw_sig_size, GFP_KERNEL);
if (!sig->s)
@@ -78,7 +69,8 @@ int x509_get_sig_params(struct x509_certificate *cert)
if (ret < 0)
goto error_2;
- ret = is_hash_blacklisted(sig->digest, sig->digest_size, "tbs");
+ ret = is_hash_blacklisted(sig->digest, sig->digest_size,
+ BLACKLIST_HASH_X509_TBS);
if (ret == -EKEYREJECTED) {
pr_err("Cert %*phN is blacklisted\n",
sig->digest_size, sig->digest);
@@ -125,10 +117,6 @@ int x509_check_for_self_signed(struct x509_certificate *cert)
goto out;
}
- ret = -EKEYREJECTED;
- if (strcmp(cert->pub->pkey_algo, cert->sig->pkey_algo) != 0)
- goto out;
-
ret = public_key_verify_signature(cert->pub, cert->sig);
if (ret < 0) {
if (ret == -ENOPKG) {
@@ -168,12 +156,6 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
pr_devel("Cert Issuer: %s\n", cert->issuer);
pr_devel("Cert Subject: %s\n", cert->subject);
-
- if (cert->unsupported_key) {
- ret = -ENOPKG;
- goto error_free_cert;
- }
-
pr_devel("Cert Key Algo: %s\n", cert->pub->pkey_algo);
pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to);
@@ -218,6 +200,13 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
goto error_free_desc;
kids->id[0] = cert->id;
kids->id[1] = cert->skid;
+ kids->id[2] = asymmetric_key_generate_id(cert->raw_subject,
+ cert->raw_subject_size,
+ "", 0);
+ if (IS_ERR(kids->id[2])) {
+ ret = PTR_ERR(kids->id[2]);
+ goto error_free_kids;
+ }
/* We're pinning the module by being linked against it */
__module_get(public_key_subtype.owner);
@@ -234,8 +223,11 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
cert->skid = NULL;
cert->sig = NULL;
desc = NULL;
+ kids = NULL;
ret = 0;
+error_free_kids:
+ kfree(kids);
error_free_desc:
kfree(desc);
error_free_cert:
@@ -252,9 +244,15 @@ static struct asymmetric_key_parser x509_key_parser = {
/*
* Module stuff
*/
+extern int __init certs_selftest(void);
static int __init x509_key_init(void)
{
- return register_asymmetric_key_parser(&x509_key_parser);
+ int ret;
+
+ ret = register_asymmetric_key_parser(&x509_key_parser);
+ if (ret < 0)
+ return ret;
+ return fips_signature_selftest();
}
static void __exit x509_key_exit(void)
diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c
index 341ece61cf9b..f9cdc5e91664 100644
--- a/crypto/async_tx/async_pq.c
+++ b/crypto/async_tx/async_pq.c
@@ -104,7 +104,7 @@ do_async_gen_syndrome(struct dma_chan *chan,
* do_sync_gen_syndrome - synchronously calculate a raid6 syndrome
*/
static void
-do_sync_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
+do_sync_gen_syndrome(struct page **blocks, unsigned int *offsets, int disks,
size_t len, struct async_submit_ctl *submit)
{
void **srcs;
@@ -121,7 +121,8 @@ do_sync_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
BUG_ON(i > disks - 3); /* P or Q can't be zero */
srcs[i] = (void*)raid6_empty_zero_page;
} else {
- srcs[i] = page_address(blocks[i]) + offset;
+ srcs[i] = page_address(blocks[i]) + offsets[i];
+
if (i < disks - 2) {
stop = i;
if (start == -1)
@@ -138,10 +139,23 @@ do_sync_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
async_tx_sync_epilog(submit);
}
+static inline bool
+is_dma_pq_aligned_offs(struct dma_device *dev, unsigned int *offs,
+ int src_cnt, size_t len)
+{
+ int i;
+
+ for (i = 0; i < src_cnt; i++) {
+ if (!is_dma_pq_aligned(dev, offs[i], 0, len))
+ return false;
+ }
+ return true;
+}
+
/**
* async_gen_syndrome - asynchronously calculate a raid6 syndrome
* @blocks: source blocks from idx 0..disks-3, P @ disks-2 and Q @ disks-1
- * @offset: common offset into each block (src and dest) to start transaction
+ * @offsets: offset array into each block (src and dest) to start transaction
* @disks: number of blocks (including missing P or Q, see below)
* @len: length of operation in bytes
* @submit: submission/completion modifiers
@@ -160,7 +174,7 @@ do_sync_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
* path.
*/
struct dma_async_tx_descriptor *
-async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
+async_gen_syndrome(struct page **blocks, unsigned int *offsets, int disks,
size_t len, struct async_submit_ctl *submit)
{
int src_cnt = disks - 2;
@@ -179,7 +193,7 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
if (unmap && !(submit->flags & ASYNC_TX_PQ_XOR_DST) &&
(src_cnt <= dma_maxpq(device, 0) ||
dma_maxpq(device, DMA_PREP_CONTINUE) > 0) &&
- is_dma_pq_aligned(device, offset, 0, len)) {
+ is_dma_pq_aligned_offs(device, offsets, disks, len)) {
struct dma_async_tx_descriptor *tx;
enum dma_ctrl_flags dma_flags = 0;
unsigned char coefs[MAX_DISKS];
@@ -196,8 +210,8 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
for (i = 0, j = 0; i < src_cnt; i++) {
if (blocks[i] == NULL)
continue;
- unmap->addr[j] = dma_map_page(device->dev, blocks[i], offset,
- len, DMA_TO_DEVICE);
+ unmap->addr[j] = dma_map_page(device->dev, blocks[i],
+ offsets[i], len, DMA_TO_DEVICE);
coefs[j] = raid6_gfexp[i];
unmap->to_cnt++;
j++;
@@ -210,7 +224,8 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
unmap->bidi_cnt++;
if (P(blocks, disks))
unmap->addr[j++] = dma_map_page(device->dev, P(blocks, disks),
- offset, len, DMA_BIDIRECTIONAL);
+ P(offsets, disks),
+ len, DMA_BIDIRECTIONAL);
else {
unmap->addr[j++] = 0;
dma_flags |= DMA_PREP_PQ_DISABLE_P;
@@ -219,7 +234,8 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
unmap->bidi_cnt++;
if (Q(blocks, disks))
unmap->addr[j++] = dma_map_page(device->dev, Q(blocks, disks),
- offset, len, DMA_BIDIRECTIONAL);
+ Q(offsets, disks),
+ len, DMA_BIDIRECTIONAL);
else {
unmap->addr[j++] = 0;
dma_flags |= DMA_PREP_PQ_DISABLE_Q;
@@ -240,13 +256,13 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
if (!P(blocks, disks)) {
P(blocks, disks) = pq_scribble_page;
- BUG_ON(len + offset > PAGE_SIZE);
+ P(offsets, disks) = 0;
}
if (!Q(blocks, disks)) {
Q(blocks, disks) = pq_scribble_page;
- BUG_ON(len + offset > PAGE_SIZE);
+ Q(offsets, disks) = 0;
}
- do_sync_gen_syndrome(blocks, offset, disks, len, submit);
+ do_sync_gen_syndrome(blocks, offsets, disks, len, submit);
return NULL;
}
@@ -270,6 +286,7 @@ pq_val_chan(struct async_submit_ctl *submit, struct page **blocks, int disks, si
* @len: length of operation in bytes
* @pqres: on val failure SUM_CHECK_P_RESULT and/or SUM_CHECK_Q_RESULT are set
* @spare: temporary result buffer for the synchronous case
+ * @s_off: spare buffer page offset
* @submit: submission / completion modifiers
*
* The same notes from async_gen_syndrome apply to the 'blocks',
@@ -278,9 +295,9 @@ pq_val_chan(struct async_submit_ctl *submit, struct page **blocks, int disks, si
* specified.
*/
struct dma_async_tx_descriptor *
-async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
+async_syndrome_val(struct page **blocks, unsigned int *offsets, int disks,
size_t len, enum sum_check_flags *pqres, struct page *spare,
- struct async_submit_ctl *submit)
+ unsigned int s_off, struct async_submit_ctl *submit)
{
struct dma_chan *chan = pq_val_chan(submit, blocks, disks, len);
struct dma_device *device = chan ? chan->device : NULL;
@@ -295,7 +312,7 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
unmap = dmaengine_get_unmap_data(device->dev, disks, GFP_NOWAIT);
if (unmap && disks <= dma_maxpq(device, 0) &&
- is_dma_pq_aligned(device, offset, 0, len)) {
+ is_dma_pq_aligned_offs(device, offsets, disks, len)) {
struct device *dev = device->dev;
dma_addr_t pq[2];
int i, j = 0, src_cnt = 0;
@@ -307,7 +324,7 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
for (i = 0; i < disks-2; i++)
if (likely(blocks[i])) {
unmap->addr[j] = dma_map_page(dev, blocks[i],
- offset, len,
+ offsets[i], len,
DMA_TO_DEVICE);
coefs[j] = raid6_gfexp[i];
unmap->to_cnt++;
@@ -320,7 +337,7 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
dma_flags |= DMA_PREP_PQ_DISABLE_P;
} else {
pq[0] = dma_map_page(dev, P(blocks, disks),
- offset, len,
+ P(offsets, disks), len,
DMA_TO_DEVICE);
unmap->addr[j++] = pq[0];
unmap->to_cnt++;
@@ -330,7 +347,7 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
dma_flags |= DMA_PREP_PQ_DISABLE_Q;
} else {
pq[1] = dma_map_page(dev, Q(blocks, disks),
- offset, len,
+ Q(offsets, disks), len,
DMA_TO_DEVICE);
unmap->addr[j++] = pq[1];
unmap->to_cnt++;
@@ -355,7 +372,9 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
async_tx_submit(chan, tx, submit);
} else {
struct page *p_src = P(blocks, disks);
+ unsigned int p_off = P(offsets, disks);
struct page *q_src = Q(blocks, disks);
+ unsigned int q_off = Q(offsets, disks);
enum async_tx_flags flags_orig = submit->flags;
dma_async_tx_callback cb_fn_orig = submit->cb_fn;
void *scribble = submit->scribble;
@@ -381,27 +400,32 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
if (p_src) {
init_async_submit(submit, ASYNC_TX_XOR_ZERO_DST, NULL,
NULL, NULL, scribble);
- tx = async_xor(spare, blocks, offset, disks-2, len, submit);
+ tx = async_xor_offs(spare, s_off,
+ blocks, offsets, disks-2, len, submit);
async_tx_quiesce(&tx);
- p = page_address(p_src) + offset;
- s = page_address(spare) + offset;
+ p = page_address(p_src) + p_off;
+ s = page_address(spare) + s_off;
*pqres |= !!memcmp(p, s, len) << SUM_CHECK_P;
}
if (q_src) {
P(blocks, disks) = NULL;
Q(blocks, disks) = spare;
+ Q(offsets, disks) = s_off;
init_async_submit(submit, 0, NULL, NULL, NULL, scribble);
- tx = async_gen_syndrome(blocks, offset, disks, len, submit);
+ tx = async_gen_syndrome(blocks, offsets, disks,
+ len, submit);
async_tx_quiesce(&tx);
- q = page_address(q_src) + offset;
- s = page_address(spare) + offset;
+ q = page_address(q_src) + q_off;
+ s = page_address(spare) + s_off;
*pqres |= !!memcmp(q, s, len) << SUM_CHECK_Q;
}
/* restore P, Q and submit */
P(blocks, disks) = p_src;
+ P(offsets, disks) = p_off;
Q(blocks, disks) = q_src;
+ Q(offsets, disks) = q_off;
submit->cb_fn = cb_fn_orig;
submit->cb_param = cb_param_orig;
diff --git a/crypto/async_tx/async_raid6_recov.c b/crypto/async_tx/async_raid6_recov.c
index f249142ceac4..354b8cd5537f 100644
--- a/crypto/async_tx/async_raid6_recov.c
+++ b/crypto/async_tx/async_raid6_recov.c
@@ -15,8 +15,9 @@
#include <linux/dmaengine.h>
static struct dma_async_tx_descriptor *
-async_sum_product(struct page *dest, struct page **srcs, unsigned char *coef,
- size_t len, struct async_submit_ctl *submit)
+async_sum_product(struct page *dest, unsigned int d_off,
+ struct page **srcs, unsigned int *src_offs, unsigned char *coef,
+ size_t len, struct async_submit_ctl *submit)
{
struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ,
&dest, 1, srcs, 2, len);
@@ -37,11 +38,14 @@ async_sum_product(struct page *dest, struct page **srcs, unsigned char *coef,
if (submit->flags & ASYNC_TX_FENCE)
dma_flags |= DMA_PREP_FENCE;
- unmap->addr[0] = dma_map_page(dev, srcs[0], 0, len, DMA_TO_DEVICE);
- unmap->addr[1] = dma_map_page(dev, srcs[1], 0, len, DMA_TO_DEVICE);
+ unmap->addr[0] = dma_map_page(dev, srcs[0], src_offs[0],
+ len, DMA_TO_DEVICE);
+ unmap->addr[1] = dma_map_page(dev, srcs[1], src_offs[1],
+ len, DMA_TO_DEVICE);
unmap->to_cnt = 2;
- unmap->addr[2] = dma_map_page(dev, dest, 0, len, DMA_BIDIRECTIONAL);
+ unmap->addr[2] = dma_map_page(dev, dest, d_off,
+ len, DMA_BIDIRECTIONAL);
unmap->bidi_cnt = 1;
/* engine only looks at Q, but expects it to follow P */
pq[1] = unmap->addr[2];
@@ -66,9 +70,9 @@ async_sum_product(struct page *dest, struct page **srcs, unsigned char *coef,
async_tx_quiesce(&submit->depend_tx);
amul = raid6_gfmul[coef[0]];
bmul = raid6_gfmul[coef[1]];
- a = page_address(srcs[0]);
- b = page_address(srcs[1]);
- c = page_address(dest);
+ a = page_address(srcs[0]) + src_offs[0];
+ b = page_address(srcs[1]) + src_offs[1];
+ c = page_address(dest) + d_off;
while (len--) {
ax = amul[*a++];
@@ -80,8 +84,9 @@ async_sum_product(struct page *dest, struct page **srcs, unsigned char *coef,
}
static struct dma_async_tx_descriptor *
-async_mult(struct page *dest, struct page *src, u8 coef, size_t len,
- struct async_submit_ctl *submit)
+async_mult(struct page *dest, unsigned int d_off, struct page *src,
+ unsigned int s_off, u8 coef, size_t len,
+ struct async_submit_ctl *submit)
{
struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ,
&dest, 1, &src, 1, len);
@@ -101,9 +106,11 @@ async_mult(struct page *dest, struct page *src, u8 coef, size_t len,
if (submit->flags & ASYNC_TX_FENCE)
dma_flags |= DMA_PREP_FENCE;
- unmap->addr[0] = dma_map_page(dev, src, 0, len, DMA_TO_DEVICE);
+ unmap->addr[0] = dma_map_page(dev, src, s_off,
+ len, DMA_TO_DEVICE);
unmap->to_cnt++;
- unmap->addr[1] = dma_map_page(dev, dest, 0, len, DMA_BIDIRECTIONAL);
+ unmap->addr[1] = dma_map_page(dev, dest, d_off,
+ len, DMA_BIDIRECTIONAL);
dma_dest[1] = unmap->addr[1];
unmap->bidi_cnt++;
unmap->len = len;
@@ -133,8 +140,8 @@ async_mult(struct page *dest, struct page *src, u8 coef, size_t len,
*/
async_tx_quiesce(&submit->depend_tx);
qmul = raid6_gfmul[coef];
- d = page_address(dest);
- s = page_address(src);
+ d = page_address(dest) + d_off;
+ s = page_address(src) + s_off;
while (len--)
*d++ = qmul[*s++];
@@ -144,11 +151,14 @@ async_mult(struct page *dest, struct page *src, u8 coef, size_t len,
static struct dma_async_tx_descriptor *
__2data_recov_4(int disks, size_t bytes, int faila, int failb,
- struct page **blocks, struct async_submit_ctl *submit)
+ struct page **blocks, unsigned int *offs,
+ struct async_submit_ctl *submit)
{
struct dma_async_tx_descriptor *tx = NULL;
struct page *p, *q, *a, *b;
+ unsigned int p_off, q_off, a_off, b_off;
struct page *srcs[2];
+ unsigned int src_offs[2];
unsigned char coef[2];
enum async_tx_flags flags = submit->flags;
dma_async_tx_callback cb_fn = submit->cb_fn;
@@ -156,26 +166,34 @@ __2data_recov_4(int disks, size_t bytes, int faila, int failb,
void *scribble = submit->scribble;
p = blocks[disks-2];
+ p_off = offs[disks-2];
q = blocks[disks-1];
+ q_off = offs[disks-1];
a = blocks[faila];
+ a_off = offs[faila];
b = blocks[failb];
+ b_off = offs[failb];
/* in the 4 disk case P + Pxy == P and Q + Qxy == Q */
/* Dx = A*(P+Pxy) + B*(Q+Qxy) */
srcs[0] = p;
+ src_offs[0] = p_off;
srcs[1] = q;
+ src_offs[1] = q_off;
coef[0] = raid6_gfexi[failb-faila];
coef[1] = raid6_gfinv[raid6_gfexp[faila]^raid6_gfexp[failb]];
init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL, scribble);
- tx = async_sum_product(b, srcs, coef, bytes, submit);
+ tx = async_sum_product(b, b_off, srcs, src_offs, coef, bytes, submit);
/* Dy = P+Pxy+Dx */
srcs[0] = p;
+ src_offs[0] = p_off;
srcs[1] = b;
+ src_offs[1] = b_off;
init_async_submit(submit, flags | ASYNC_TX_XOR_ZERO_DST, tx, cb_fn,
cb_param, scribble);
- tx = async_xor(a, srcs, 0, 2, bytes, submit);
+ tx = async_xor_offs(a, a_off, srcs, src_offs, 2, bytes, submit);
return tx;
@@ -183,11 +201,14 @@ __2data_recov_4(int disks, size_t bytes, int faila, int failb,
static struct dma_async_tx_descriptor *
__2data_recov_5(int disks, size_t bytes, int faila, int failb,
- struct page **blocks, struct async_submit_ctl *submit)
+ struct page **blocks, unsigned int *offs,
+ struct async_submit_ctl *submit)
{
struct dma_async_tx_descriptor *tx = NULL;
struct page *p, *q, *g, *dp, *dq;
+ unsigned int p_off, q_off, g_off, dp_off, dq_off;
struct page *srcs[2];
+ unsigned int src_offs[2];
unsigned char coef[2];
enum async_tx_flags flags = submit->flags;
dma_async_tx_callback cb_fn = submit->cb_fn;
@@ -208,60 +229,77 @@ __2data_recov_5(int disks, size_t bytes, int faila, int failb,
BUG_ON(good_srcs > 1);
p = blocks[disks-2];
+ p_off = offs[disks-2];
q = blocks[disks-1];
+ q_off = offs[disks-1];
g = blocks[good];
+ g_off = offs[good];
/* Compute syndrome with zero for the missing data pages
* Use the dead data pages as temporary storage for delta p and
* delta q
*/
dp = blocks[faila];
+ dp_off = offs[faila];
dq = blocks[failb];
+ dq_off = offs[failb];
init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL, scribble);
- tx = async_memcpy(dp, g, 0, 0, bytes, submit);
+ tx = async_memcpy(dp, g, dp_off, g_off, bytes, submit);
init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL, scribble);
- tx = async_mult(dq, g, raid6_gfexp[good], bytes, submit);
+ tx = async_mult(dq, dq_off, g, g_off,
+ raid6_gfexp[good], bytes, submit);
/* compute P + Pxy */
srcs[0] = dp;
+ src_offs[0] = dp_off;
srcs[1] = p;
+ src_offs[1] = p_off;
init_async_submit(submit, ASYNC_TX_FENCE|ASYNC_TX_XOR_DROP_DST, tx,
NULL, NULL, scribble);
- tx = async_xor(dp, srcs, 0, 2, bytes, submit);
+ tx = async_xor_offs(dp, dp_off, srcs, src_offs, 2, bytes, submit);
/* compute Q + Qxy */
srcs[0] = dq;
+ src_offs[0] = dq_off;
srcs[1] = q;
+ src_offs[1] = q_off;
init_async_submit(submit, ASYNC_TX_FENCE|ASYNC_TX_XOR_DROP_DST, tx,
NULL, NULL, scribble);
- tx = async_xor(dq, srcs, 0, 2, bytes, submit);
+ tx = async_xor_offs(dq, dq_off, srcs, src_offs, 2, bytes, submit);
/* Dx = A*(P+Pxy) + B*(Q+Qxy) */
srcs[0] = dp;
+ src_offs[0] = dp_off;
srcs[1] = dq;
+ src_offs[1] = dq_off;
coef[0] = raid6_gfexi[failb-faila];
coef[1] = raid6_gfinv[raid6_gfexp[faila]^raid6_gfexp[failb]];
init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL, scribble);
- tx = async_sum_product(dq, srcs, coef, bytes, submit);
+ tx = async_sum_product(dq, dq_off, srcs, src_offs, coef, bytes, submit);
/* Dy = P+Pxy+Dx */
srcs[0] = dp;
+ src_offs[0] = dp_off;
srcs[1] = dq;
+ src_offs[1] = dq_off;
init_async_submit(submit, flags | ASYNC_TX_XOR_DROP_DST, tx, cb_fn,
cb_param, scribble);
- tx = async_xor(dp, srcs, 0, 2, bytes, submit);
+ tx = async_xor_offs(dp, dp_off, srcs, src_offs, 2, bytes, submit);
return tx;
}
static struct dma_async_tx_descriptor *
__2data_recov_n(int disks, size_t bytes, int faila, int failb,
- struct page **blocks, struct async_submit_ctl *submit)
+ struct page **blocks, unsigned int *offs,
+ struct async_submit_ctl *submit)
{
struct dma_async_tx_descriptor *tx = NULL;
struct page *p, *q, *dp, *dq;
+ unsigned int p_off, q_off, dp_off, dq_off;
struct page *srcs[2];
+ unsigned int src_offs[2];
unsigned char coef[2];
enum async_tx_flags flags = submit->flags;
dma_async_tx_callback cb_fn = submit->cb_fn;
@@ -269,56 +307,74 @@ __2data_recov_n(int disks, size_t bytes, int faila, int failb,
void *scribble = submit->scribble;
p = blocks[disks-2];
+ p_off = offs[disks-2];
q = blocks[disks-1];
+ q_off = offs[disks-1];
/* Compute syndrome with zero for the missing data pages
* Use the dead data pages as temporary storage for
* delta p and delta q
*/
dp = blocks[faila];
+ dp_off = offs[faila];
blocks[faila] = NULL;
blocks[disks-2] = dp;
+ offs[disks-2] = dp_off;
dq = blocks[failb];
+ dq_off = offs[failb];
blocks[failb] = NULL;
blocks[disks-1] = dq;
+ offs[disks-1] = dq_off;
init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL, scribble);
- tx = async_gen_syndrome(blocks, 0, disks, bytes, submit);
+ tx = async_gen_syndrome(blocks, offs, disks, bytes, submit);
/* Restore pointer table */
blocks[faila] = dp;
+ offs[faila] = dp_off;
blocks[failb] = dq;
+ offs[failb] = dq_off;
blocks[disks-2] = p;
+ offs[disks-2] = p_off;
blocks[disks-1] = q;
+ offs[disks-1] = q_off;
/* compute P + Pxy */
srcs[0] = dp;
+ src_offs[0] = dp_off;
srcs[1] = p;
+ src_offs[1] = p_off;
init_async_submit(submit, ASYNC_TX_FENCE|ASYNC_TX_XOR_DROP_DST, tx,
NULL, NULL, scribble);
- tx = async_xor(dp, srcs, 0, 2, bytes, submit);
+ tx = async_xor_offs(dp, dp_off, srcs, src_offs, 2, bytes, submit);
/* compute Q + Qxy */
srcs[0] = dq;
+ src_offs[0] = dq_off;
srcs[1] = q;
+ src_offs[1] = q_off;
init_async_submit(submit, ASYNC_TX_FENCE|ASYNC_TX_XOR_DROP_DST, tx,
NULL, NULL, scribble);
- tx = async_xor(dq, srcs, 0, 2, bytes, submit);
+ tx = async_xor_offs(dq, dq_off, srcs, src_offs, 2, bytes, submit);
/* Dx = A*(P+Pxy) + B*(Q+Qxy) */
srcs[0] = dp;
+ src_offs[0] = dp_off;
srcs[1] = dq;
+ src_offs[1] = dq_off;
coef[0] = raid6_gfexi[failb-faila];
coef[1] = raid6_gfinv[raid6_gfexp[faila]^raid6_gfexp[failb]];
init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL, scribble);
- tx = async_sum_product(dq, srcs, coef, bytes, submit);
+ tx = async_sum_product(dq, dq_off, srcs, src_offs, coef, bytes, submit);
/* Dy = P+Pxy+Dx */
srcs[0] = dp;
+ src_offs[0] = dp_off;
srcs[1] = dq;
+ src_offs[1] = dq_off;
init_async_submit(submit, flags | ASYNC_TX_XOR_DROP_DST, tx, cb_fn,
cb_param, scribble);
- tx = async_xor(dp, srcs, 0, 2, bytes, submit);
+ tx = async_xor_offs(dp, dp_off, srcs, src_offs, 2, bytes, submit);
return tx;
}
@@ -330,11 +386,13 @@ __2data_recov_n(int disks, size_t bytes, int faila, int failb,
* @faila: first failed drive index
* @failb: second failed drive index
* @blocks: array of source pointers where the last two entries are p and q
+ * @offs: array of offset for pages in blocks
* @submit: submission/completion modifiers
*/
struct dma_async_tx_descriptor *
async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
- struct page **blocks, struct async_submit_ctl *submit)
+ struct page **blocks, unsigned int *offs,
+ struct async_submit_ctl *submit)
{
void *scribble = submit->scribble;
int non_zero_srcs, i;
@@ -358,7 +416,7 @@ async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
if (blocks[i] == NULL)
ptrs[i] = (void *) raid6_empty_zero_page;
else
- ptrs[i] = page_address(blocks[i]);
+ ptrs[i] = page_address(blocks[i]) + offs[i];
raid6_2data_recov(disks, bytes, faila, failb, ptrs);
@@ -383,16 +441,19 @@ async_raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
* explicitly handle the special case of a 4 disk array with
* both data disks missing.
*/
- return __2data_recov_4(disks, bytes, faila, failb, blocks, submit);
+ return __2data_recov_4(disks, bytes, faila, failb,
+ blocks, offs, submit);
case 3:
/* dma devices do not uniformly understand a single
* source pq operation (in contrast to the synchronous
* case), so explicitly handle the special case of a 5 disk
* array with 2 of 3 data disks missing.
*/
- return __2data_recov_5(disks, bytes, faila, failb, blocks, submit);
+ return __2data_recov_5(disks, bytes, faila, failb,
+ blocks, offs, submit);
default:
- return __2data_recov_n(disks, bytes, faila, failb, blocks, submit);
+ return __2data_recov_n(disks, bytes, faila, failb,
+ blocks, offs, submit);
}
}
EXPORT_SYMBOL_GPL(async_raid6_2data_recov);
@@ -403,14 +464,17 @@ EXPORT_SYMBOL_GPL(async_raid6_2data_recov);
* @bytes: block size
* @faila: failed drive index
* @blocks: array of source pointers where the last two entries are p and q
+ * @offs: array of offset for pages in blocks
* @submit: submission/completion modifiers
*/
struct dma_async_tx_descriptor *
async_raid6_datap_recov(int disks, size_t bytes, int faila,
- struct page **blocks, struct async_submit_ctl *submit)
+ struct page **blocks, unsigned int *offs,
+ struct async_submit_ctl *submit)
{
struct dma_async_tx_descriptor *tx = NULL;
struct page *p, *q, *dq;
+ unsigned int p_off, q_off, dq_off;
u8 coef;
enum async_tx_flags flags = submit->flags;
dma_async_tx_callback cb_fn = submit->cb_fn;
@@ -418,6 +482,7 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
void *scribble = submit->scribble;
int good_srcs, good, i;
struct page *srcs[2];
+ unsigned int src_offs[2];
pr_debug("%s: disks: %d len: %zu\n", __func__, disks, bytes);
@@ -434,7 +499,7 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
if (blocks[i] == NULL)
ptrs[i] = (void*)raid6_empty_zero_page;
else
- ptrs[i] = page_address(blocks[i]);
+ ptrs[i] = page_address(blocks[i]) + offs[i];
raid6_datap_recov(disks, bytes, faila, ptrs);
@@ -458,55 +523,67 @@ async_raid6_datap_recov(int disks, size_t bytes, int faila,
BUG_ON(good_srcs == 0);
p = blocks[disks-2];
+ p_off = offs[disks-2];
q = blocks[disks-1];
+ q_off = offs[disks-1];
/* Compute syndrome with zero for the missing data page
* Use the dead data page as temporary storage for delta q
*/
dq = blocks[faila];
+ dq_off = offs[faila];
blocks[faila] = NULL;
blocks[disks-1] = dq;
+ offs[disks-1] = dq_off;
/* in the 4-disk case we only need to perform a single source
* multiplication with the one good data block.
*/
if (good_srcs == 1) {
struct page *g = blocks[good];
+ unsigned int g_off = offs[good];
init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL,
scribble);
- tx = async_memcpy(p, g, 0, 0, bytes, submit);
+ tx = async_memcpy(p, g, p_off, g_off, bytes, submit);
init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL,
scribble);
- tx = async_mult(dq, g, raid6_gfexp[good], bytes, submit);
+ tx = async_mult(dq, dq_off, g, g_off,
+ raid6_gfexp[good], bytes, submit);
} else {
init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL,
scribble);
- tx = async_gen_syndrome(blocks, 0, disks, bytes, submit);
+ tx = async_gen_syndrome(blocks, offs, disks, bytes, submit);
}
/* Restore pointer table */
blocks[faila] = dq;
+ offs[faila] = dq_off;
blocks[disks-1] = q;
+ offs[disks-1] = q_off;
/* calculate g^{-faila} */
coef = raid6_gfinv[raid6_gfexp[faila]];
srcs[0] = dq;
+ src_offs[0] = dq_off;
srcs[1] = q;
+ src_offs[1] = q_off;
init_async_submit(submit, ASYNC_TX_FENCE|ASYNC_TX_XOR_DROP_DST, tx,
NULL, NULL, scribble);
- tx = async_xor(dq, srcs, 0, 2, bytes, submit);
+ tx = async_xor_offs(dq, dq_off, srcs, src_offs, 2, bytes, submit);
init_async_submit(submit, ASYNC_TX_FENCE, tx, NULL, NULL, scribble);
- tx = async_mult(dq, dq, coef, bytes, submit);
+ tx = async_mult(dq, dq_off, dq, dq_off, coef, bytes, submit);
srcs[0] = p;
+ src_offs[0] = p_off;
srcs[1] = dq;
+ src_offs[1] = dq_off;
init_async_submit(submit, flags | ASYNC_TX_XOR_DROP_DST, tx, cb_fn,
cb_param, scribble);
- tx = async_xor(p, srcs, 0, 2, bytes, submit);
+ tx = async_xor_offs(p, p_off, srcs, src_offs, 2, bytes, submit);
return tx;
}
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
index 4e5eebe52e6a..1a3855284091 100644
--- a/crypto/async_tx/async_xor.c
+++ b/crypto/async_tx/async_xor.c
@@ -97,7 +97,8 @@ do_async_xor(struct dma_chan *chan, struct dmaengine_unmap_data *unmap,
}
static void
-do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset,
+do_sync_xor_offs(struct page *dest, unsigned int offset,
+ struct page **src_list, unsigned int *src_offs,
int src_cnt, size_t len, struct async_submit_ctl *submit)
{
int i;
@@ -114,7 +115,8 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset,
/* convert to buffer pointers */
for (i = 0; i < src_cnt; i++)
if (src_list[i])
- srcs[xor_src_cnt++] = page_address(src_list[i]) + offset;
+ srcs[xor_src_cnt++] = page_address(src_list[i]) +
+ (src_offs ? src_offs[i] : offset);
src_cnt = xor_src_cnt;
/* set destination address */
dest_buf = page_address(dest) + offset;
@@ -135,11 +137,31 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset,
async_tx_sync_epilog(submit);
}
+static inline bool
+dma_xor_aligned_offsets(struct dma_device *device, unsigned int offset,
+ unsigned int *src_offs, int src_cnt, int len)
+{
+ int i;
+
+ if (!is_dma_xor_aligned(device, offset, 0, len))
+ return false;
+
+ if (!src_offs)
+ return true;
+
+ for (i = 0; i < src_cnt; i++) {
+ if (!is_dma_xor_aligned(device, src_offs[i], 0, len))
+ return false;
+ }
+ return true;
+}
+
/**
- * async_xor - attempt to xor a set of blocks with a dma engine.
+ * async_xor_offs - attempt to xor a set of blocks with a dma engine.
* @dest: destination page
+ * @offset: dst offset to start transaction
* @src_list: array of source pages
- * @offset: common src/dst offset to start transaction
+ * @src_offs: array of source pages offset, NULL means common src/dst offset
* @src_cnt: number of source pages
* @len: length in bytes
* @submit: submission / completion modifiers
@@ -148,8 +170,8 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset,
*
* xor_blocks always uses the dest as a source so the
* ASYNC_TX_XOR_ZERO_DST flag must be set to not include dest data in
- * the calculation. The assumption with dma eninges is that they only
- * use the destination buffer as a source when it is explicity specified
+ * the calculation. The assumption with dma engines is that they only
+ * use the destination buffer as a source when it is explicitly specified
* in the source list.
*
* src_list note: if the dest is also a source it must be at index zero.
@@ -157,8 +179,9 @@ do_sync_xor(struct page *dest, struct page **src_list, unsigned int offset,
* is not specified.
*/
struct dma_async_tx_descriptor *
-async_xor(struct page *dest, struct page **src_list, unsigned int offset,
- int src_cnt, size_t len, struct async_submit_ctl *submit)
+async_xor_offs(struct page *dest, unsigned int offset,
+ struct page **src_list, unsigned int *src_offs,
+ int src_cnt, size_t len, struct async_submit_ctl *submit)
{
struct dma_chan *chan = async_tx_find_channel(submit, DMA_XOR,
&dest, 1, src_list,
@@ -171,7 +194,8 @@ async_xor(struct page *dest, struct page **src_list, unsigned int offset,
if (device)
unmap = dmaengine_get_unmap_data(device->dev, src_cnt+1, GFP_NOWAIT);
- if (unmap && is_dma_xor_aligned(device, offset, 0, len)) {
+ if (unmap && dma_xor_aligned_offsets(device, offset,
+ src_offs, src_cnt, len)) {
struct dma_async_tx_descriptor *tx;
int i, j;
@@ -184,7 +208,8 @@ async_xor(struct page *dest, struct page **src_list, unsigned int offset,
continue;
unmap->to_cnt++;
unmap->addr[j++] = dma_map_page(device->dev, src_list[i],
- offset, len, DMA_TO_DEVICE);
+ src_offs ? src_offs[i] : offset,
+ len, DMA_TO_DEVICE);
}
/* map it bidirectional as it may be re-used as a source */
@@ -208,16 +233,49 @@ async_xor(struct page *dest, struct page **src_list, unsigned int offset,
if (submit->flags & ASYNC_TX_XOR_DROP_DST) {
src_cnt--;
src_list++;
+ if (src_offs)
+ src_offs++;
}
/* wait for any prerequisite operations */
async_tx_quiesce(&submit->depend_tx);
- do_sync_xor(dest, src_list, offset, src_cnt, len, submit);
+ do_sync_xor_offs(dest, offset, src_list, src_offs,
+ src_cnt, len, submit);
return NULL;
}
}
+EXPORT_SYMBOL_GPL(async_xor_offs);
+
+/**
+ * async_xor - attempt to xor a set of blocks with a dma engine.
+ * @dest: destination page
+ * @src_list: array of source pages
+ * @offset: common src/dst offset to start transaction
+ * @src_cnt: number of source pages
+ * @len: length in bytes
+ * @submit: submission / completion modifiers
+ *
+ * honored flags: ASYNC_TX_ACK, ASYNC_TX_XOR_ZERO_DST, ASYNC_TX_XOR_DROP_DST
+ *
+ * xor_blocks always uses the dest as a source so the
+ * ASYNC_TX_XOR_ZERO_DST flag must be set to not include dest data in
+ * the calculation. The assumption with dma engines is that they only
+ * use the destination buffer as a source when it is explicitly specified
+ * in the source list.
+ *
+ * src_list note: if the dest is also a source it must be at index zero.
+ * The contents of this array will be overwritten if a scribble region
+ * is not specified.
+ */
+struct dma_async_tx_descriptor *
+async_xor(struct page *dest, struct page **src_list, unsigned int offset,
+ int src_cnt, size_t len, struct async_submit_ctl *submit)
+{
+ return async_xor_offs(dest, offset, src_list, NULL,
+ src_cnt, len, submit);
+}
EXPORT_SYMBOL_GPL(async_xor);
static int page_is_zero(struct page *p, unsigned int offset, size_t len)
@@ -237,10 +295,11 @@ xor_val_chan(struct async_submit_ctl *submit, struct page *dest,
}
/**
- * async_xor_val - attempt a xor parity check with a dma engine.
+ * async_xor_val_offs - attempt a xor parity check with a dma engine.
* @dest: destination page used if the xor is performed synchronously
+ * @offset: des offset in pages to start transaction
* @src_list: array of source pages
- * @offset: offset in pages to start transaction
+ * @src_offs: array of source pages offset, NULL means common src/det offset
* @src_cnt: number of source pages
* @len: length in bytes
* @result: 0 if sum == 0 else non-zero
@@ -253,9 +312,10 @@ xor_val_chan(struct async_submit_ctl *submit, struct page *dest,
* is not specified.
*/
struct dma_async_tx_descriptor *
-async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
- int src_cnt, size_t len, enum sum_check_flags *result,
- struct async_submit_ctl *submit)
+async_xor_val_offs(struct page *dest, unsigned int offset,
+ struct page **src_list, unsigned int *src_offs,
+ int src_cnt, size_t len, enum sum_check_flags *result,
+ struct async_submit_ctl *submit)
{
struct dma_chan *chan = xor_val_chan(submit, dest, src_list, src_cnt, len);
struct dma_device *device = chan ? chan->device : NULL;
@@ -268,7 +328,7 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
unmap = dmaengine_get_unmap_data(device->dev, src_cnt, GFP_NOWAIT);
if (unmap && src_cnt <= device->max_xor &&
- is_dma_xor_aligned(device, offset, 0, len)) {
+ dma_xor_aligned_offsets(device, offset, src_offs, src_cnt, len)) {
unsigned long dma_prep_flags = 0;
int i;
@@ -281,7 +341,8 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
for (i = 0; i < src_cnt; i++) {
unmap->addr[i] = dma_map_page(device->dev, src_list[i],
- offset, len, DMA_TO_DEVICE);
+ src_offs ? src_offs[i] : offset,
+ len, DMA_TO_DEVICE);
unmap->to_cnt++;
}
unmap->len = len;
@@ -312,7 +373,8 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
submit->flags |= ASYNC_TX_XOR_DROP_DST;
submit->flags &= ~ASYNC_TX_ACK;
- tx = async_xor(dest, src_list, offset, src_cnt, len, submit);
+ tx = async_xor_offs(dest, offset, src_list, src_offs,
+ src_cnt, len, submit);
async_tx_quiesce(&tx);
@@ -325,6 +387,32 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
return tx;
}
+EXPORT_SYMBOL_GPL(async_xor_val_offs);
+
+/**
+ * async_xor_val - attempt a xor parity check with a dma engine.
+ * @dest: destination page used if the xor is performed synchronously
+ * @src_list: array of source pages
+ * @offset: offset in pages to start transaction
+ * @src_cnt: number of source pages
+ * @len: length in bytes
+ * @result: 0 if sum == 0 else non-zero
+ * @submit: submission / completion modifiers
+ *
+ * honored flags: ASYNC_TX_ACK
+ *
+ * src_list note: if the dest is also a source it must be at index zero.
+ * The contents of this array will be overwritten if a scribble region
+ * is not specified.
+ */
+struct dma_async_tx_descriptor *
+async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
+ int src_cnt, size_t len, enum sum_check_flags *result,
+ struct async_submit_ctl *submit)
+{
+ return async_xor_val_offs(dest, offset, src_list, NULL, src_cnt,
+ len, result, submit);
+}
EXPORT_SYMBOL_GPL(async_xor_val);
MODULE_AUTHOR("Intel Corporation");
diff --git a/crypto/async_tx/raid6test.c b/crypto/async_tx/raid6test.c
index 14e73dcd7475..d3fbee1e03e5 100644
--- a/crypto/async_tx/raid6test.c
+++ b/crypto/async_tx/raid6test.c
@@ -18,6 +18,7 @@
#define NDISKS 64 /* Including P and Q */
static struct page *dataptrs[NDISKS];
+unsigned int dataoffs[NDISKS];
static addr_conv_t addr_conv[NDISKS];
static struct page *data[NDISKS+3];
static struct page *spare;
@@ -36,8 +37,9 @@ static void makedata(int disks)
int i;
for (i = 0; i < disks; i++) {
- prandom_bytes(page_address(data[i]), PAGE_SIZE);
+ get_random_bytes(page_address(data[i]), PAGE_SIZE);
dataptrs[i] = data[i];
+ dataoffs[i] = 0;
}
}
@@ -52,7 +54,8 @@ static char disk_type(int d, int disks)
}
/* Recover two failed blocks. */
-static void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, struct page **ptrs)
+static void raid6_dual_recov(int disks, size_t bytes, int faila, int failb,
+ struct page **ptrs, unsigned int *offs)
{
struct async_submit_ctl submit;
struct completion cmp;
@@ -66,7 +69,8 @@ static void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, stru
if (faila == disks-2) {
/* P+Q failure. Just rebuild the syndrome. */
init_async_submit(&submit, 0, NULL, NULL, NULL, addr_conv);
- tx = async_gen_syndrome(ptrs, 0, disks, bytes, &submit);
+ tx = async_gen_syndrome(ptrs, offs,
+ disks, bytes, &submit);
} else {
struct page *blocks[NDISKS];
struct page *dest;
@@ -89,22 +93,26 @@ static void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, stru
tx = async_xor(dest, blocks, 0, count, bytes, &submit);
init_async_submit(&submit, 0, tx, NULL, NULL, addr_conv);
- tx = async_gen_syndrome(ptrs, 0, disks, bytes, &submit);
+ tx = async_gen_syndrome(ptrs, offs,
+ disks, bytes, &submit);
}
} else {
if (failb == disks-2) {
/* data+P failure. */
init_async_submit(&submit, 0, NULL, NULL, NULL, addr_conv);
- tx = async_raid6_datap_recov(disks, bytes, faila, ptrs, &submit);
+ tx = async_raid6_datap_recov(disks, bytes,
+ faila, ptrs, offs, &submit);
} else {
/* data+data failure. */
init_async_submit(&submit, 0, NULL, NULL, NULL, addr_conv);
- tx = async_raid6_2data_recov(disks, bytes, faila, failb, ptrs, &submit);
+ tx = async_raid6_2data_recov(disks, bytes,
+ faila, failb, ptrs, offs, &submit);
}
}
init_completion(&cmp);
init_async_submit(&submit, ASYNC_TX_ACK, tx, callback, &cmp, addr_conv);
- tx = async_syndrome_val(ptrs, 0, disks, bytes, &result, spare, &submit);
+ tx = async_syndrome_val(ptrs, offs,
+ disks, bytes, &result, spare, 0, &submit);
async_tx_issue_pending(tx);
if (wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)) == 0)
@@ -126,7 +134,7 @@ static int test_disks(int i, int j, int disks)
dataptrs[i] = recovi;
dataptrs[j] = recovj;
- raid6_dual_recov(disks, PAGE_SIZE, i, j, dataptrs);
+ raid6_dual_recov(disks, PAGE_SIZE, i, j, dataptrs, dataoffs);
erra = memcmp(page_address(data[i]), page_address(recovi), PAGE_SIZE);
errb = memcmp(page_address(data[j]), page_address(recovj), PAGE_SIZE);
@@ -162,7 +170,7 @@ static int test(int disks, int *tests)
/* Generate assumed good syndrome */
init_completion(&cmp);
init_async_submit(&submit, ASYNC_TX_ACK, NULL, callback, &cmp, addr_conv);
- tx = async_gen_syndrome(dataptrs, 0, disks, PAGE_SIZE, &submit);
+ tx = async_gen_syndrome(dataptrs, dataoffs, disks, PAGE_SIZE, &submit);
async_tx_issue_pending(tx);
if (wait_for_completion_timeout(&cmp, msecs_to_jiffies(3000)) == 0) {
@@ -181,7 +189,7 @@ static int test(int disks, int *tests)
}
-static int raid6_test(void)
+static int __init raid6_test(void)
{
int err = 0;
int tests = 0;
@@ -209,7 +217,7 @@ static int raid6_test(void)
err += test(12, &tests);
}
- /* the 24 disk case is special for ioatdma as it is the boudary point
+ /* the 24 disk case is special for ioatdma as it is the boundary point
* at which it needs to switch from 8-source ops to 16-source
* ops for continuation (assumes DMA_HAS_PQ_CONTINUE is not set)
*/
@@ -228,12 +236,12 @@ static int raid6_test(void)
return 0;
}
-static void raid6_test_exit(void)
+static void __exit raid6_test_exit(void)
{
}
/* when compiled-in wait for drivers to load first (assumes dma drivers
- * are also compliled-in)
+ * are also compiled-in)
*/
late_initcall(raid6_test);
module_exit(raid6_test_exit);
diff --git a/crypto/authenc.c b/crypto/authenc.c
index 775e7138fd10..17f674a7cdff 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -253,7 +253,7 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req,
dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, req->assoclen);
skcipher_request_set_tfm(skreq, ctx->enc);
- skcipher_request_set_callback(skreq, aead_request_flags(req),
+ skcipher_request_set_callback(skreq, flags,
req->base.complete, req->base.data);
skcipher_request_set_crypt(skreq, src, dst,
req->cryptlen - authsize, req->iv);
@@ -372,7 +372,6 @@ static void crypto_authenc_free(struct aead_instance *inst)
static int crypto_authenc_create(struct crypto_template *tmpl,
struct rtattr **tb)
{
- struct crypto_attr_type *algt;
u32 mask;
struct aead_instance *inst;
struct authenc_instance_ctx *ctx;
@@ -381,14 +380,9 @@ static int crypto_authenc_create(struct crypto_template *tmpl,
struct skcipher_alg *enc;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
- return -EINVAL;
-
- mask = crypto_requires_sync(algt->type, algt->mask);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
+ if (err)
+ return err;
inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
if (!inst)
@@ -423,8 +417,6 @@ static int crypto_authenc_create(struct crypto_template *tmpl,
enc->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
goto err_free_inst;
- inst->alg.base.cra_flags = (auth_base->cra_flags |
- enc->base.cra_flags) & CRYPTO_ALG_ASYNC;
inst->alg.base.cra_priority = enc->base.cra_priority * 10 +
auth_base->cra_priority;
inst->alg.base.cra_blocksize = enc->base.cra_blocksize;
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index 589008146fce..b60e61b1904c 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -390,7 +390,6 @@ static void crypto_authenc_esn_free(struct aead_instance *inst)
static int crypto_authenc_esn_create(struct crypto_template *tmpl,
struct rtattr **tb)
{
- struct crypto_attr_type *algt;
u32 mask;
struct aead_instance *inst;
struct authenc_esn_instance_ctx *ctx;
@@ -399,14 +398,9 @@ static int crypto_authenc_esn_create(struct crypto_template *tmpl,
struct skcipher_alg *enc;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
- return -EINVAL;
-
- mask = crypto_requires_sync(algt->type, algt->mask);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
+ if (err)
+ return err;
inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
if (!inst)
@@ -437,8 +431,6 @@ static int crypto_authenc_esn_create(struct crypto_template *tmpl,
enc->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
goto err_free_inst;
- inst->alg.base.cra_flags = (auth_base->cra_flags |
- enc->base.cra_flags) & CRYPTO_ALG_ASYNC;
inst->alg.base.cra_priority = enc->base.cra_priority * 10 +
auth_base->cra_priority;
inst->alg.base.cra_blocksize = enc->base.cra_blocksize;
@@ -458,7 +450,7 @@ static int crypto_authenc_esn_create(struct crypto_template *tmpl,
inst->alg.encrypt = crypto_authenc_esn_encrypt;
inst->alg.decrypt = crypto_authenc_esn_decrypt;
- inst->free = crypto_authenc_esn_free,
+ inst->free = crypto_authenc_esn_free;
err = aead_register_instance(tmpl, inst);
if (err) {
diff --git a/crypto/blake2b_generic.c b/crypto/blake2b_generic.c
index 1d262374fa4e..6704c0355889 100644
--- a/crypto/blake2b_generic.c
+++ b/crypto/blake2b_generic.c
@@ -1,55 +1,27 @@
// SPDX-License-Identifier: (GPL-2.0-only OR Apache-2.0)
/*
- * BLAKE2b reference source code package - reference C implementations
+ * Generic implementation of the BLAKE2b digest algorithm. Based on the BLAKE2b
+ * reference implementation, but it has been heavily modified for use in the
+ * kernel. The reference implementation was:
*
- * 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:
+ * 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
+ * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
+ * - OpenSSL license : https://www.openssl.org/source/license.html
+ * - Apache 2.0 : https://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.
+ * More information about BLAKE2 can be found at https://blake2.net.
*/
#include <asm/unaligned.h>
#include <linux/module.h>
-#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
+#include <crypto/internal/blake2b.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 },
@@ -95,8 +67,8 @@ static void blake2b_increment_counter(struct blake2b_state *S, const u64 inc)
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])
+static void blake2b_compress_one_generic(struct blake2b_state *S,
+ const u8 block[BLAKE2B_BLOCK_SIZE])
{
u64 m[16];
u64 v[16];
@@ -108,14 +80,14 @@ static void blake2b_compress(struct blake2b_state *S,
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];
+ v[ 8] = BLAKE2B_IV0;
+ v[ 9] = BLAKE2B_IV1;
+ v[10] = BLAKE2B_IV2;
+ v[11] = BLAKE2B_IV3;
+ v[12] = BLAKE2B_IV4 ^ S->t[0];
+ v[13] = BLAKE2B_IV5 ^ S->t[1];
+ v[14] = BLAKE2B_IV6 ^ S->f[0];
+ v[15] = BLAKE2B_IV7 ^ S->f[1];
ROUND(0);
ROUND(1);
@@ -129,7 +101,9 @@ static void blake2b_compress(struct blake2b_state *S,
ROUND(9);
ROUND(10);
ROUND(11);
-
+#ifdef CONFIG_CC_IS_CLANG
+#pragma nounroll /* https://bugs.llvm.org/show_bug.cgi?id=45803 */
+#endif
for (i = 0; i < 8; ++i)
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
}
@@ -137,159 +111,54 @@ static void blake2b_compress(struct blake2b_state *S,
#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)
+void blake2b_compress_generic(struct blake2b_state *state,
+ const u8 *block, size_t nblocks, u32 inc)
{
- struct blake2b_tfm_ctx *tctx = crypto_shash_ctx(tfm);
-
- if (keylen == 0 || keylen > BLAKE2B_KEYBYTES)
- return -EINVAL;
-
- memcpy(tctx->key, key, keylen);
- tctx->keylen = keylen;
-
- return 0;
+ do {
+ blake2b_increment_counter(state, inc);
+ blake2b_compress_one_generic(state, block);
+ block += BLAKE2B_BLOCK_SIZE;
+ } while (--nblocks);
}
+EXPORT_SYMBOL(blake2b_compress_generic);
-static int blake2b_init(struct shash_desc *desc)
+static int crypto_blake2b_update_generic(struct shash_desc *desc,
+ const u8 *in, unsigned int inlen)
{
- 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;
+ return crypto_blake2b_update(desc, in, inlen, blake2b_compress_generic);
}
-static int blake2b_update(struct shash_desc *desc, const u8 *in,
- unsigned int inlen)
+static int crypto_blake2b_final_generic(struct shash_desc *desc, u8 *out)
{
- 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;
+ return crypto_blake2b_final(desc, out, blake2b_compress_generic);
}
-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;
-}
+#define BLAKE2B_ALG(name, driver_name, digest_size) \
+ { \
+ .base.cra_name = name, \
+ .base.cra_driver_name = driver_name, \
+ .base.cra_priority = 100, \
+ .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY, \
+ .base.cra_blocksize = BLAKE2B_BLOCK_SIZE, \
+ .base.cra_ctxsize = sizeof(struct blake2b_tfm_ctx), \
+ .base.cra_module = THIS_MODULE, \
+ .digestsize = digest_size, \
+ .setkey = crypto_blake2b_setkey, \
+ .init = crypto_blake2b_init, \
+ .update = crypto_blake2b_update_generic, \
+ .final = crypto_blake2b_final_generic, \
+ .descsize = sizeof(struct blake2b_state), \
+ }
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),
- }
+ BLAKE2B_ALG("blake2b-160", "blake2b-160-generic",
+ BLAKE2B_160_HASH_SIZE),
+ BLAKE2B_ALG("blake2b-256", "blake2b-256-generic",
+ BLAKE2B_256_HASH_SIZE),
+ BLAKE2B_ALG("blake2b-384", "blake2b-384-generic",
+ BLAKE2B_384_HASH_SIZE),
+ BLAKE2B_ALG("blake2b-512", "blake2b-512-generic",
+ BLAKE2B_512_HASH_SIZE),
};
static int __init blake2b_mod_init(void)
diff --git a/crypto/blake2s_generic.c b/crypto/blake2s_generic.c
deleted file mode 100644
index 005783ff45ad..000000000000
--- a/crypto/blake2s_generic.c
+++ /dev/null
@@ -1,169 +0,0 @@
-// 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)
- 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");
diff --git a/crypto/blowfish_generic.c b/crypto/blowfish_generic.c
index c3c2041fe0c5..003b52c6880e 100644
--- a/crypto/blowfish_generic.c
+++ b/crypto/blowfish_generic.c
@@ -14,7 +14,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
-#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <linux/crypto.h>
#include <linux/types.h>
#include <crypto/blowfish.h>
@@ -36,12 +36,10 @@
static void bf_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
{
struct bf_ctx *ctx = crypto_tfm_ctx(tfm);
- const __be32 *in_blk = (const __be32 *)src;
- __be32 *const out_blk = (__be32 *)dst;
const u32 *P = ctx->p;
const u32 *S = ctx->s;
- u32 yl = be32_to_cpu(in_blk[0]);
- u32 yr = be32_to_cpu(in_blk[1]);
+ u32 yl = get_unaligned_be32(src);
+ u32 yr = get_unaligned_be32(src + 4);
ROUND(yr, yl, 0);
ROUND(yl, yr, 1);
@@ -63,19 +61,17 @@ static void bf_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
yl ^= P[16];
yr ^= P[17];
- out_blk[0] = cpu_to_be32(yr);
- out_blk[1] = cpu_to_be32(yl);
+ put_unaligned_be32(yr, dst);
+ put_unaligned_be32(yl, dst + 4);
}
static void bf_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
{
struct bf_ctx *ctx = crypto_tfm_ctx(tfm);
- const __be32 *in_blk = (const __be32 *)src;
- __be32 *const out_blk = (__be32 *)dst;
const u32 *P = ctx->p;
const u32 *S = ctx->s;
- u32 yl = be32_to_cpu(in_blk[0]);
- u32 yr = be32_to_cpu(in_blk[1]);
+ u32 yl = get_unaligned_be32(src);
+ u32 yr = get_unaligned_be32(src + 4);
ROUND(yr, yl, 17);
ROUND(yl, yr, 16);
@@ -97,8 +93,8 @@ static void bf_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
yl ^= P[1];
yr ^= P[0];
- out_blk[0] = cpu_to_be32(yr);
- out_blk[1] = cpu_to_be32(yl);
+ put_unaligned_be32(yr, dst);
+ put_unaligned_be32(yl, dst + 4);
}
static struct crypto_alg alg = {
@@ -108,7 +104,6 @@ static struct crypto_alg alg = {
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = BF_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct bf_ctx),
- .cra_alignmask = 3,
.cra_module = THIS_MODULE,
.cra_u = { .cipher = {
.cia_min_keysize = BF_MIN_KEY_SIZE,
diff --git a/crypto/camellia_generic.c b/crypto/camellia_generic.c
index 9a5783e5196a..fd1a88af9e77 100644
--- a/crypto/camellia_generic.c
+++ b/crypto/camellia_generic.c
@@ -6,15 +6,7 @@
/*
* Algorithm Specification
- * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
- */
-
-/*
- *
- * NOTE --- NOTE --- NOTE --- NOTE
- * This implementation assumes that all memory addresses passed
- * as parameters are four-byte aligned.
- *
+ * https://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
*/
#include <linux/crypto.h>
@@ -994,16 +986,14 @@ camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
- const __be32 *src = (const __be32 *)in;
- __be32 *dst = (__be32 *)out;
unsigned int max;
u32 tmp[4];
- tmp[0] = be32_to_cpu(src[0]);
- tmp[1] = be32_to_cpu(src[1]);
- tmp[2] = be32_to_cpu(src[2]);
- tmp[3] = be32_to_cpu(src[3]);
+ tmp[0] = get_unaligned_be32(in);
+ tmp[1] = get_unaligned_be32(in + 4);
+ tmp[2] = get_unaligned_be32(in + 8);
+ tmp[3] = get_unaligned_be32(in + 12);
if (cctx->key_length == 16)
max = 24;
@@ -1013,25 +1003,23 @@ static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
camellia_do_encrypt(cctx->key_table, tmp, max);
/* do_encrypt returns 0,1 swapped with 2,3 */
- dst[0] = cpu_to_be32(tmp[2]);
- dst[1] = cpu_to_be32(tmp[3]);
- dst[2] = cpu_to_be32(tmp[0]);
- dst[3] = cpu_to_be32(tmp[1]);
+ put_unaligned_be32(tmp[2], out);
+ put_unaligned_be32(tmp[3], out + 4);
+ put_unaligned_be32(tmp[0], out + 8);
+ put_unaligned_be32(tmp[1], out + 12);
}
static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
- const __be32 *src = (const __be32 *)in;
- __be32 *dst = (__be32 *)out;
unsigned int max;
u32 tmp[4];
- tmp[0] = be32_to_cpu(src[0]);
- tmp[1] = be32_to_cpu(src[1]);
- tmp[2] = be32_to_cpu(src[2]);
- tmp[3] = be32_to_cpu(src[3]);
+ tmp[0] = get_unaligned_be32(in);
+ tmp[1] = get_unaligned_be32(in + 4);
+ tmp[2] = get_unaligned_be32(in + 8);
+ tmp[3] = get_unaligned_be32(in + 12);
if (cctx->key_length == 16)
max = 24;
@@ -1041,10 +1029,10 @@ static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
camellia_do_decrypt(cctx->key_table, tmp, max);
/* do_decrypt returns 0,1 swapped with 2,3 */
- dst[0] = cpu_to_be32(tmp[2]);
- dst[1] = cpu_to_be32(tmp[3]);
- dst[2] = cpu_to_be32(tmp[0]);
- dst[3] = cpu_to_be32(tmp[1]);
+ put_unaligned_be32(tmp[2], out);
+ put_unaligned_be32(tmp[3], out + 4);
+ put_unaligned_be32(tmp[0], out + 8);
+ put_unaligned_be32(tmp[1], out + 12);
}
static struct crypto_alg camellia_alg = {
@@ -1054,7 +1042,6 @@ static struct crypto_alg camellia_alg = {
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = CAMELLIA_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct camellia_ctx),
- .cra_alignmask = 3,
.cra_module = THIS_MODULE,
.cra_u = {
.cipher = {
diff --git a/crypto/cast5_generic.c b/crypto/cast5_generic.c
index 4095085d4e51..0257c14cefc2 100644
--- a/crypto/cast5_generic.c
+++ b/crypto/cast5_generic.c
@@ -13,7 +13,7 @@
*/
-#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <linux/init.h>
#include <linux/crypto.h>
#include <linux/module.h>
@@ -302,8 +302,6 @@ static const u32 sb8[256] = {
void __cast5_encrypt(struct cast5_ctx *c, u8 *outbuf, const u8 *inbuf)
{
- const __be32 *src = (const __be32 *)inbuf;
- __be32 *dst = (__be32 *)outbuf;
u32 l, r, t;
u32 I; /* used by the Fx macros */
u32 *Km;
@@ -315,8 +313,8 @@ void __cast5_encrypt(struct cast5_ctx *c, u8 *outbuf, const u8 *inbuf)
/* (L0,R0) <-- (m1...m64). (Split the plaintext into left and
* right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
*/
- l = be32_to_cpu(src[0]);
- r = be32_to_cpu(src[1]);
+ l = get_unaligned_be32(inbuf);
+ r = get_unaligned_be32(inbuf + 4);
/* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
* Li = Ri-1;
@@ -347,8 +345,8 @@ void __cast5_encrypt(struct cast5_ctx *c, u8 *outbuf, const u8 *inbuf)
/* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and
* concatenate to form the ciphertext.) */
- dst[0] = cpu_to_be32(r);
- dst[1] = cpu_to_be32(l);
+ put_unaligned_be32(r, outbuf);
+ put_unaligned_be32(l, outbuf + 4);
}
EXPORT_SYMBOL_GPL(__cast5_encrypt);
@@ -359,8 +357,6 @@ static void cast5_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
void __cast5_decrypt(struct cast5_ctx *c, u8 *outbuf, const u8 *inbuf)
{
- const __be32 *src = (const __be32 *)inbuf;
- __be32 *dst = (__be32 *)outbuf;
u32 l, r, t;
u32 I;
u32 *Km;
@@ -369,8 +365,8 @@ void __cast5_decrypt(struct cast5_ctx *c, u8 *outbuf, const u8 *inbuf)
Km = c->Km;
Kr = c->Kr;
- l = be32_to_cpu(src[0]);
- r = be32_to_cpu(src[1]);
+ l = get_unaligned_be32(inbuf);
+ r = get_unaligned_be32(inbuf + 4);
if (!(c->rr)) {
t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
@@ -391,8 +387,8 @@ void __cast5_decrypt(struct cast5_ctx *c, u8 *outbuf, const u8 *inbuf)
t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]);
t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]);
- dst[0] = cpu_to_be32(r);
- dst[1] = cpu_to_be32(l);
+ put_unaligned_be32(r, outbuf);
+ put_unaligned_be32(l, outbuf + 4);
}
EXPORT_SYMBOL_GPL(__cast5_decrypt);
@@ -513,7 +509,6 @@ static struct crypto_alg alg = {
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = CAST5_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct cast5_ctx),
- .cra_alignmask = 3,
.cra_module = THIS_MODULE,
.cra_u = {
.cipher = {
diff --git a/crypto/cast6_generic.c b/crypto/cast6_generic.c
index c77ff6c8a2b2..75346380aa0b 100644
--- a/crypto/cast6_generic.c
+++ b/crypto/cast6_generic.c
@@ -10,7 +10,7 @@
*/
-#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <linux/init.h>
#include <linux/crypto.h>
#include <linux/module.h>
@@ -172,16 +172,14 @@ static inline void QBAR(u32 *block, const u8 *Kr, const u32 *Km)
void __cast6_encrypt(const void *ctx, u8 *outbuf, const u8 *inbuf)
{
const struct cast6_ctx *c = ctx;
- const __be32 *src = (const __be32 *)inbuf;
- __be32 *dst = (__be32 *)outbuf;
u32 block[4];
const u32 *Km;
const u8 *Kr;
- block[0] = be32_to_cpu(src[0]);
- block[1] = be32_to_cpu(src[1]);
- block[2] = be32_to_cpu(src[2]);
- block[3] = be32_to_cpu(src[3]);
+ block[0] = get_unaligned_be32(inbuf);
+ block[1] = get_unaligned_be32(inbuf + 4);
+ block[2] = get_unaligned_be32(inbuf + 8);
+ block[3] = get_unaligned_be32(inbuf + 12);
Km = c->Km[0]; Kr = c->Kr[0]; Q(block, Kr, Km);
Km = c->Km[1]; Kr = c->Kr[1]; Q(block, Kr, Km);
@@ -196,10 +194,10 @@ void __cast6_encrypt(const void *ctx, u8 *outbuf, const u8 *inbuf)
Km = c->Km[10]; Kr = c->Kr[10]; QBAR(block, Kr, Km);
Km = c->Km[11]; Kr = c->Kr[11]; QBAR(block, Kr, Km);
- dst[0] = cpu_to_be32(block[0]);
- dst[1] = cpu_to_be32(block[1]);
- dst[2] = cpu_to_be32(block[2]);
- dst[3] = cpu_to_be32(block[3]);
+ put_unaligned_be32(block[0], outbuf);
+ put_unaligned_be32(block[1], outbuf + 4);
+ put_unaligned_be32(block[2], outbuf + 8);
+ put_unaligned_be32(block[3], outbuf + 12);
}
EXPORT_SYMBOL_GPL(__cast6_encrypt);
@@ -211,16 +209,14 @@ static void cast6_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf)
void __cast6_decrypt(const void *ctx, u8 *outbuf, const u8 *inbuf)
{
const struct cast6_ctx *c = ctx;
- const __be32 *src = (const __be32 *)inbuf;
- __be32 *dst = (__be32 *)outbuf;
u32 block[4];
const u32 *Km;
const u8 *Kr;
- block[0] = be32_to_cpu(src[0]);
- block[1] = be32_to_cpu(src[1]);
- block[2] = be32_to_cpu(src[2]);
- block[3] = be32_to_cpu(src[3]);
+ block[0] = get_unaligned_be32(inbuf);
+ block[1] = get_unaligned_be32(inbuf + 4);
+ block[2] = get_unaligned_be32(inbuf + 8);
+ block[3] = get_unaligned_be32(inbuf + 12);
Km = c->Km[11]; Kr = c->Kr[11]; Q(block, Kr, Km);
Km = c->Km[10]; Kr = c->Kr[10]; Q(block, Kr, Km);
@@ -235,10 +231,10 @@ void __cast6_decrypt(const void *ctx, u8 *outbuf, const u8 *inbuf)
Km = c->Km[1]; Kr = c->Kr[1]; QBAR(block, Kr, Km);
Km = c->Km[0]; Kr = c->Kr[0]; QBAR(block, Kr, Km);
- dst[0] = cpu_to_be32(block[0]);
- dst[1] = cpu_to_be32(block[1]);
- dst[2] = cpu_to_be32(block[2]);
- dst[3] = cpu_to_be32(block[3]);
+ put_unaligned_be32(block[0], outbuf);
+ put_unaligned_be32(block[1], outbuf + 4);
+ put_unaligned_be32(block[2], outbuf + 8);
+ put_unaligned_be32(block[3], outbuf + 12);
}
EXPORT_SYMBOL_GPL(__cast6_decrypt);
@@ -254,7 +250,6 @@ static struct crypto_alg alg = {
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = CAST6_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct cast6_ctx),
- .cra_alignmask = 3,
.cra_module = THIS_MODULE,
.cra_u = {
.cipher = {
diff --git a/crypto/cbc.c b/crypto/cbc.c
index e6f6273a7d39..6c03e96b945f 100644
--- a/crypto/cbc.c
+++ b/crypto/cbc.c
@@ -6,7 +6,7 @@
*/
#include <crypto/algapi.h>
-#include <crypto/cbc.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/skcipher.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -14,34 +14,157 @@
#include <linux/log2.h>
#include <linux/module.h>
-static inline void crypto_cbc_encrypt_one(struct crypto_skcipher *tfm,
- const u8 *src, u8 *dst)
+static int crypto_cbc_encrypt_segment(struct skcipher_walk *walk,
+ struct crypto_skcipher *skcipher)
{
- crypto_cipher_encrypt_one(skcipher_cipher_simple(tfm), dst, src);
+ unsigned int bsize = crypto_skcipher_blocksize(skcipher);
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
+ unsigned int nbytes = walk->nbytes;
+ u8 *src = walk->src.virt.addr;
+ u8 *dst = walk->dst.virt.addr;
+ struct crypto_cipher *cipher;
+ struct crypto_tfm *tfm;
+ u8 *iv = walk->iv;
+
+ cipher = skcipher_cipher_simple(skcipher);
+ tfm = crypto_cipher_tfm(cipher);
+ fn = crypto_cipher_alg(cipher)->cia_encrypt;
+
+ do {
+ crypto_xor(iv, src, bsize);
+ fn(tfm, dst, iv);
+ memcpy(iv, dst, bsize);
+
+ src += bsize;
+ dst += bsize;
+ } while ((nbytes -= bsize) >= bsize);
+
+ return nbytes;
+}
+
+static int crypto_cbc_encrypt_inplace(struct skcipher_walk *walk,
+ struct crypto_skcipher *skcipher)
+{
+ unsigned int bsize = crypto_skcipher_blocksize(skcipher);
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
+ unsigned int nbytes = walk->nbytes;
+ u8 *src = walk->src.virt.addr;
+ struct crypto_cipher *cipher;
+ struct crypto_tfm *tfm;
+ u8 *iv = walk->iv;
+
+ cipher = skcipher_cipher_simple(skcipher);
+ tfm = crypto_cipher_tfm(cipher);
+ fn = crypto_cipher_alg(cipher)->cia_encrypt;
+
+ do {
+ crypto_xor(src, iv, bsize);
+ fn(tfm, src, src);
+ iv = src;
+
+ src += bsize;
+ } while ((nbytes -= bsize) >= bsize);
+
+ memcpy(walk->iv, iv, bsize);
+
+ return nbytes;
}
static int crypto_cbc_encrypt(struct skcipher_request *req)
{
- return crypto_cbc_encrypt_walk(req, crypto_cbc_encrypt_one);
+ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
+ struct skcipher_walk walk;
+ int err;
+
+ err = skcipher_walk_virt(&walk, req, false);
+
+ while (walk.nbytes) {
+ if (walk.src.virt.addr == walk.dst.virt.addr)
+ err = crypto_cbc_encrypt_inplace(&walk, skcipher);
+ else
+ err = crypto_cbc_encrypt_segment(&walk, skcipher);
+ err = skcipher_walk_done(&walk, err);
+ }
+
+ return err;
+}
+
+static int crypto_cbc_decrypt_segment(struct skcipher_walk *walk,
+ struct crypto_skcipher *skcipher)
+{
+ unsigned int bsize = crypto_skcipher_blocksize(skcipher);
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
+ unsigned int nbytes = walk->nbytes;
+ u8 *src = walk->src.virt.addr;
+ u8 *dst = walk->dst.virt.addr;
+ struct crypto_cipher *cipher;
+ struct crypto_tfm *tfm;
+ u8 *iv = walk->iv;
+
+ cipher = skcipher_cipher_simple(skcipher);
+ tfm = crypto_cipher_tfm(cipher);
+ fn = crypto_cipher_alg(cipher)->cia_decrypt;
+
+ do {
+ fn(tfm, dst, src);
+ crypto_xor(dst, iv, bsize);
+ iv = src;
+
+ src += bsize;
+ dst += bsize;
+ } while ((nbytes -= bsize) >= bsize);
+
+ memcpy(walk->iv, iv, bsize);
+
+ return nbytes;
}
-static inline void crypto_cbc_decrypt_one(struct crypto_skcipher *tfm,
- const u8 *src, u8 *dst)
+static int crypto_cbc_decrypt_inplace(struct skcipher_walk *walk,
+ struct crypto_skcipher *skcipher)
{
- crypto_cipher_decrypt_one(skcipher_cipher_simple(tfm), dst, src);
+ unsigned int bsize = crypto_skcipher_blocksize(skcipher);
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *);
+ unsigned int nbytes = walk->nbytes;
+ u8 *src = walk->src.virt.addr;
+ u8 last_iv[MAX_CIPHER_BLOCKSIZE];
+ struct crypto_cipher *cipher;
+ struct crypto_tfm *tfm;
+
+ cipher = skcipher_cipher_simple(skcipher);
+ tfm = crypto_cipher_tfm(cipher);
+ fn = crypto_cipher_alg(cipher)->cia_decrypt;
+
+ /* Start of the last block. */
+ src += nbytes - (nbytes & (bsize - 1)) - bsize;
+ memcpy(last_iv, src, bsize);
+
+ for (;;) {
+ fn(tfm, src, src);
+ if ((nbytes -= bsize) < bsize)
+ break;
+ crypto_xor(src, src - bsize, bsize);
+ src -= bsize;
+ }
+
+ crypto_xor(src, walk->iv, bsize);
+ memcpy(walk->iv, last_iv, bsize);
+
+ return nbytes;
}
static int crypto_cbc_decrypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
struct skcipher_walk walk;
int err;
err = skcipher_walk_virt(&walk, req, false);
while (walk.nbytes) {
- err = crypto_cbc_decrypt_blocks(&walk, tfm,
- crypto_cbc_decrypt_one);
+ if (walk.src.virt.addr == walk.dst.virt.addr)
+ err = crypto_cbc_decrypt_inplace(&walk, skcipher);
+ else
+ err = crypto_cbc_decrypt_segment(&walk, skcipher);
err = skcipher_walk_done(&walk, err);
}
diff --git a/crypto/ccm.c b/crypto/ccm.c
index 241ecdc5c4e0..6b815ece51c6 100644
--- a/crypto/ccm.c
+++ b/crypto/ccm.c
@@ -6,6 +6,7 @@
*/
#include <crypto/internal/aead.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/hash.h>
#include <crypto/internal/skcipher.h>
#include <crypto/scatterwalk.h>
@@ -447,7 +448,6 @@ static int crypto_ccm_create_common(struct crypto_template *tmpl,
const char *ctr_name,
const char *mac_name)
{
- struct crypto_attr_type *algt;
u32 mask;
struct aead_instance *inst;
struct ccm_instance_ctx *ictx;
@@ -455,14 +455,9 @@ static int crypto_ccm_create_common(struct crypto_template *tmpl,
struct hash_alg_common *mac;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
- return -EINVAL;
-
- mask = crypto_requires_sync(algt->type, algt->mask);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
+ if (err)
+ return err;
inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL);
if (!inst)
@@ -470,7 +465,7 @@ static int crypto_ccm_create_common(struct crypto_template *tmpl,
ictx = aead_instance_ctx(inst);
err = crypto_grab_ahash(&ictx->mac, aead_crypto_instance(inst),
- mac_name, 0, CRYPTO_ALG_ASYNC);
+ mac_name, 0, mask | CRYPTO_ALG_ASYNC);
if (err)
goto err_free_inst;
mac = crypto_spawn_ahash_alg(&ictx->mac);
@@ -507,7 +502,6 @@ static int crypto_ccm_create_common(struct crypto_template *tmpl,
mac->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
goto err_free_inst;
- inst->alg.base.cra_flags = ctr->base.cra_flags & CRYPTO_ALG_ASYNC;
inst->alg.base.cra_priority = (mac->base.cra_priority +
ctr->base.cra_priority) / 2;
inst->alg.base.cra_blocksize = 1;
@@ -712,26 +706,15 @@ static void crypto_rfc4309_free(struct aead_instance *inst)
static int crypto_rfc4309_create(struct crypto_template *tmpl,
struct rtattr **tb)
{
- struct crypto_attr_type *algt;
u32 mask;
struct aead_instance *inst;
struct crypto_aead_spawn *spawn;
struct aead_alg *alg;
- const char *ccm_name;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
- return -EINVAL;
-
- mask = crypto_requires_sync(algt->type, algt->mask);
-
- ccm_name = crypto_attr_alg_name(tb[1]);
- if (IS_ERR(ccm_name))
- return PTR_ERR(ccm_name);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
+ if (err)
+ return err;
inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
if (!inst)
@@ -739,9 +722,9 @@ static int crypto_rfc4309_create(struct crypto_template *tmpl,
spawn = aead_instance_ctx(inst);
err = crypto_grab_aead(spawn, aead_crypto_instance(inst),
- ccm_name, 0, mask);
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
- goto out_free_inst;
+ goto err_free_inst;
alg = crypto_spawn_aead_alg(spawn);
@@ -749,11 +732,11 @@ static int crypto_rfc4309_create(struct crypto_template *tmpl,
/* We only support 16-byte blocks. */
if (crypto_aead_alg_ivsize(alg) != 16)
- goto out_drop_alg;
+ goto err_free_inst;
/* Not a stream cipher? */
if (alg->base.cra_blocksize != 1)
- goto out_drop_alg;
+ goto err_free_inst;
err = -ENAMETOOLONG;
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
@@ -762,9 +745,8 @@ static int crypto_rfc4309_create(struct crypto_template *tmpl,
snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
"rfc4309(%s)", alg->base.cra_driver_name) >=
CRYPTO_MAX_ALG_NAME)
- goto out_drop_alg;
+ goto err_free_inst;
- 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 = 1;
inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
@@ -786,17 +768,11 @@ static int crypto_rfc4309_create(struct crypto_template *tmpl,
inst->free = crypto_rfc4309_free;
err = aead_register_instance(tmpl, inst);
- if (err)
- goto out_drop_alg;
-
-out:
+ if (err) {
+err_free_inst:
+ crypto_rfc4309_free(inst);
+ }
return err;
-
-out_drop_alg:
- crypto_drop_aead(spawn);
-out_free_inst:
- kfree(inst);
- goto out;
}
static int crypto_cbcmac_digest_setkey(struct crypto_shash *parent,
@@ -889,9 +865,10 @@ static int cbcmac_create(struct crypto_template *tmpl, struct rtattr **tb)
struct shash_instance *inst;
struct crypto_cipher_spawn *spawn;
struct crypto_alg *alg;
+ u32 mask;
int err;
- err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask);
if (err)
return err;
@@ -901,7 +878,7 @@ static int cbcmac_create(struct crypto_template *tmpl, struct rtattr **tb)
spawn = shash_instance_ctx(inst);
err = crypto_grab_cipher(spawn, shash_crypto_instance(inst),
- crypto_attr_alg_name(tb[1]), 0, 0);
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
goto err_free_inst;
alg = crypto_spawn_cipher_alg(spawn);
@@ -978,3 +955,4 @@ MODULE_ALIAS_CRYPTO("ccm_base");
MODULE_ALIAS_CRYPTO("rfc4309");
MODULE_ALIAS_CRYPTO("ccm");
MODULE_ALIAS_CRYPTO("cbcmac");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/cfb.c b/crypto/cfb.c
index 4e5219bbcd19..5c36b7b65e2a 100644
--- a/crypto/cfb.c
+++ b/crypto/cfb.c
@@ -1,4 +1,4 @@
-//SPDX-License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0
/*
* CFB: Cipher FeedBack mode
*
@@ -20,6 +20,7 @@
*/
#include <crypto/algapi.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/skcipher.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -250,3 +251,4 @@ module_exit(crypto_cfb_module_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("CFB block cipher mode of operation");
MODULE_ALIAS_CRYPTO("cfb");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/chacha20poly1305.c b/crypto/chacha20poly1305.c
index ccaea5cb66d1..97bbb135e9a6 100644
--- a/crypto/chacha20poly1305.c
+++ b/crypto/chacha20poly1305.c
@@ -555,7 +555,6 @@ static void chachapoly_free(struct aead_instance *inst)
static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
const char *name, unsigned int ivsize)
{
- struct crypto_attr_type *algt;
u32 mask;
struct aead_instance *inst;
struct chachapoly_instance_ctx *ctx;
@@ -566,14 +565,9 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
if (ivsize > CHACHAPOLY_IV_SIZE)
return -EINVAL;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
- return -EINVAL;
-
- mask = crypto_requires_sync(algt->type, algt->mask);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
+ if (err)
+ return err;
inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
if (!inst)
@@ -613,8 +607,6 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb,
poly->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
goto err_free_inst;
- inst->alg.base.cra_flags = (chacha->base.cra_flags |
- poly->base.cra_flags) & CRYPTO_ALG_ASYNC;
inst->alg.base.cra_priority = (chacha->base.cra_priority +
poly->base.cra_priority) / 2;
inst->alg.base.cra_blocksize = 1;
diff --git a/crypto/cipher.c b/crypto/cipher.c
index fd78150deb1c..b47141ed4a9f 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -9,6 +9,7 @@
*/
#include <crypto/algapi.h>
+#include <crypto/internal/cipher.h>
#include <linux/kernel.h>
#include <linux/crypto.h>
#include <linux/errno.h>
@@ -53,7 +54,7 @@ int crypto_cipher_setkey(struct crypto_cipher *tfm,
return cia->cia_setkey(crypto_cipher_tfm(tfm), key, keylen);
}
-EXPORT_SYMBOL_GPL(crypto_cipher_setkey);
+EXPORT_SYMBOL_NS_GPL(crypto_cipher_setkey, CRYPTO_INTERNAL);
static inline void cipher_crypt_one(struct crypto_cipher *tfm,
u8 *dst, const u8 *src, bool enc)
@@ -81,11 +82,11 @@ void crypto_cipher_encrypt_one(struct crypto_cipher *tfm,
{
cipher_crypt_one(tfm, dst, src, true);
}
-EXPORT_SYMBOL_GPL(crypto_cipher_encrypt_one);
+EXPORT_SYMBOL_NS_GPL(crypto_cipher_encrypt_one, CRYPTO_INTERNAL);
void crypto_cipher_decrypt_one(struct crypto_cipher *tfm,
u8 *dst, const u8 *src)
{
cipher_crypt_one(tfm, dst, src, false);
}
-EXPORT_SYMBOL_GPL(crypto_cipher_decrypt_one);
+EXPORT_SYMBOL_NS_GPL(crypto_cipher_decrypt_one, CRYPTO_INTERNAL);
diff --git a/crypto/cmac.c b/crypto/cmac.c
index 143a6544c873..f4a5d3bfb376 100644
--- a/crypto/cmac.c
+++ b/crypto/cmac.c
@@ -11,6 +11,7 @@
* Author: Kazunori Miyazawa <miyazawa@linux-ipv6.org>
*/
+#include <crypto/internal/cipher.h>
#include <crypto/internal/hash.h>
#include <linux/err.h>
#include <linux/kernel.h>
@@ -225,9 +226,10 @@ static int cmac_create(struct crypto_template *tmpl, struct rtattr **tb)
struct crypto_cipher_spawn *spawn;
struct crypto_alg *alg;
unsigned long alignmask;
+ u32 mask;
int err;
- err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask);
if (err)
return err;
@@ -237,7 +239,7 @@ static int cmac_create(struct crypto_template *tmpl, struct rtattr **tb)
spawn = shash_instance_ctx(inst);
err = crypto_grab_cipher(spawn, shash_crypto_instance(inst),
- crypto_attr_alg_name(tb[1]), 0, 0);
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
goto err_free_inst;
alg = crypto_spawn_cipher_alg(spawn);
@@ -312,3 +314,4 @@ module_exit(crypto_cmac_module_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("CMAC keyed hash algorithm");
MODULE_ALIAS_CRYPTO("cmac");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/crc32_generic.c b/crypto/crc32_generic.c
index 0e103fb5dd77..a989cb44fd16 100644
--- a/crypto/crc32_generic.c
+++ b/crypto/crc32_generic.c
@@ -1,26 +1,4 @@
-/* GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see http://www.gnu.org/licenses
- *
- * Please visit http://www.xyratex.com/contact if you need additional
- * information or have any questions.
- *
- * GPL HEADER END
- */
-
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright 2012 Xyratex Technology Limited
*/
diff --git a/crypto/crc32c_generic.c b/crypto/crc32c_generic.c
index 7fa9b0788685..768614738541 100644
--- a/crypto/crc32c_generic.c
+++ b/crypto/crc32c_generic.c
@@ -15,7 +15,7 @@
* pages = {},
* month = {June},
*}
- * Used by the iSCSI driver, possibly others, and derived from the
+ * Used by the iSCSI driver, possibly others, and derived from
* the iscsi-crc.c module of the linux-iscsi driver at
* http://linux-iscsi.sourceforge.net.
*
@@ -50,7 +50,7 @@ struct chksum_desc_ctx {
};
/*
- * Steps through buffer one byte at at time, calculates reflected
+ * Steps through buffer one byte at a time, calculates reflected
* crc using table.
*/
diff --git a/crypto/crc64_rocksoft_generic.c b/crypto/crc64_rocksoft_generic.c
new file mode 100644
index 000000000000..9e812bb26dba
--- /dev/null
+++ b/crypto/crc64_rocksoft_generic.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/crc64.h>
+#include <linux/module.h>
+#include <crypto/internal/hash.h>
+#include <asm/unaligned.h>
+
+static int chksum_init(struct shash_desc *desc)
+{
+ u64 *crc = shash_desc_ctx(desc);
+
+ *crc = 0;
+
+ return 0;
+}
+
+static int chksum_update(struct shash_desc *desc, const u8 *data,
+ unsigned int length)
+{
+ u64 *crc = shash_desc_ctx(desc);
+
+ *crc = crc64_rocksoft_generic(*crc, data, length);
+
+ return 0;
+}
+
+static int chksum_final(struct shash_desc *desc, u8 *out)
+{
+ u64 *crc = shash_desc_ctx(desc);
+
+ put_unaligned_le64(*crc, out);
+ return 0;
+}
+
+static int __chksum_finup(u64 crc, const u8 *data, unsigned int len, u8 *out)
+{
+ crc = crc64_rocksoft_generic(crc, data, len);
+ put_unaligned_le64(crc, out);
+ return 0;
+}
+
+static int chksum_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ u64 *crc = shash_desc_ctx(desc);
+
+ return __chksum_finup(*crc, data, len, out);
+}
+
+static int chksum_digest(struct shash_desc *desc, const u8 *data,
+ unsigned int length, u8 *out)
+{
+ return __chksum_finup(0, data, length, out);
+}
+
+static struct shash_alg alg = {
+ .digestsize = sizeof(u64),
+ .init = chksum_init,
+ .update = chksum_update,
+ .final = chksum_final,
+ .finup = chksum_finup,
+ .digest = chksum_digest,
+ .descsize = sizeof(u64),
+ .base = {
+ .cra_name = CRC64_ROCKSOFT_STRING,
+ .cra_driver_name = "crc64-rocksoft-generic",
+ .cra_priority = 200,
+ .cra_blocksize = 1,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+static int __init crc64_rocksoft_init(void)
+{
+ return crypto_register_shash(&alg);
+}
+
+static void __exit crc64_rocksoft_exit(void)
+{
+ crypto_unregister_shash(&alg);
+}
+
+module_init(crc64_rocksoft_init);
+module_exit(crc64_rocksoft_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Rocksoft model CRC64 calculation.");
+MODULE_ALIAS_CRYPTO("crc64-rocksoft");
+MODULE_ALIAS_CRYPTO("crc64-rocksoft-generic");
diff --git a/crypto/crct10dif_generic.c b/crypto/crct10dif_generic.c
index d90c0070710e..e843982073bb 100644
--- a/crypto/crct10dif_generic.c
+++ b/crypto/crct10dif_generic.c
@@ -35,7 +35,7 @@ struct chksum_desc_ctx {
};
/*
- * Steps through buffer one byte at at time, calculates reflected
+ * Steps through buffer one byte at a time, calculates reflected
* crc using table.
*/
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index d94c75c840a5..668095eca0fa 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -39,6 +39,10 @@ struct cryptd_cpu_queue {
};
struct cryptd_queue {
+ /*
+ * Protected by disabling BH to allow enqueueing from softinterrupt and
+ * dequeuing from kworker (cryptd_queue_worker()).
+ */
struct cryptd_cpu_queue __percpu *cpu_queue;
};
@@ -125,28 +129,28 @@ static void cryptd_fini_queue(struct cryptd_queue *queue)
static int cryptd_enqueue_request(struct cryptd_queue *queue,
struct crypto_async_request *request)
{
- int cpu, err;
+ int err;
struct cryptd_cpu_queue *cpu_queue;
refcount_t *refcnt;
- cpu = get_cpu();
+ local_bh_disable();
cpu_queue = this_cpu_ptr(queue->cpu_queue);
err = crypto_enqueue_request(&cpu_queue->queue, request);
refcnt = crypto_tfm_ctx(request->tfm);
if (err == -ENOSPC)
- goto out_put_cpu;
+ goto out;
- queue_work_on(cpu, cryptd_wq, &cpu_queue->work);
+ queue_work_on(smp_processor_id(), cryptd_wq, &cpu_queue->work);
if (!refcount_read(refcnt))
- goto out_put_cpu;
+ goto out;
refcount_inc(refcnt);
-out_put_cpu:
- put_cpu();
+out:
+ local_bh_enable();
return err;
}
@@ -162,15 +166,10 @@ static void cryptd_queue_worker(struct work_struct *work)
cpu_queue = container_of(work, struct cryptd_cpu_queue, work);
/*
* Only handle one request at a time to avoid hogging crypto workqueue.
- * preempt_disable/enable is used to prevent being preempted by
- * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent
- * cryptd_enqueue_request() being accessed from software interrupts.
*/
local_bh_disable();
- preempt_disable();
backlog = crypto_get_backlog(&cpu_queue->queue);
req = crypto_dequeue_request(&cpu_queue->queue);
- preempt_enable();
local_bh_enable();
if (!req)
@@ -191,17 +190,20 @@ static inline struct cryptd_queue *cryptd_get_queue(struct crypto_tfm *tfm)
return ictx->queue;
}
-static inline void cryptd_check_internal(struct rtattr **tb, u32 *type,
- u32 *mask)
+static void cryptd_type_and_mask(struct crypto_attr_type *algt,
+ u32 *type, u32 *mask)
{
- struct crypto_attr_type *algt;
+ /*
+ * cryptd is allowed to wrap internal algorithms, but in that case the
+ * resulting cryptd instance will be marked as internal as well.
+ */
+ *type = algt->type & CRYPTO_ALG_INTERNAL;
+ *mask = algt->mask & CRYPTO_ALG_INTERNAL;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return;
+ /* No point in cryptd wrapping an algorithm that's already async. */
+ *mask |= CRYPTO_ALG_ASYNC;
- *type |= algt->type & CRYPTO_ALG_INTERNAL;
- *mask |= algt->mask & CRYPTO_ALG_INTERNAL;
+ *mask |= crypto_algt_inherited_mask(algt);
}
static int cryptd_init_instance(struct crypto_instance *inst,
@@ -364,24 +366,17 @@ static void cryptd_skcipher_free(struct skcipher_instance *inst)
static int cryptd_create_skcipher(struct crypto_template *tmpl,
struct rtattr **tb,
+ struct crypto_attr_type *algt,
struct cryptd_queue *queue)
{
struct skcipherd_instance_ctx *ctx;
struct skcipher_instance *inst;
struct skcipher_alg *alg;
- const char *name;
u32 type;
u32 mask;
int err;
- type = 0;
- mask = CRYPTO_ALG_ASYNC;
-
- cryptd_check_internal(tb, &type, &mask);
-
- name = crypto_attr_alg_name(tb[1]);
- if (IS_ERR(name))
- return PTR_ERR(name);
+ cryptd_type_and_mask(algt, &type, &mask);
inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
if (!inst)
@@ -391,18 +386,17 @@ static int cryptd_create_skcipher(struct crypto_template *tmpl,
ctx->queue = queue;
err = crypto_grab_skcipher(&ctx->spawn, skcipher_crypto_instance(inst),
- name, type, mask);
+ crypto_attr_alg_name(tb[1]), type, mask);
if (err)
- goto out_free_inst;
+ goto err_free_inst;
alg = crypto_spawn_skcipher_alg(&ctx->spawn);
err = cryptd_init_instance(skcipher_crypto_instance(inst), &alg->base);
if (err)
- goto out_drop_skcipher;
-
- inst->alg.base.cra_flags = CRYPTO_ALG_ASYNC |
- (alg->base.cra_flags & CRYPTO_ALG_INTERNAL);
+ goto err_free_inst;
+ inst->alg.base.cra_flags |= CRYPTO_ALG_ASYNC |
+ (alg->base.cra_flags & CRYPTO_ALG_INTERNAL);
inst->alg.ivsize = crypto_skcipher_alg_ivsize(alg);
inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg);
inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg);
@@ -421,10 +415,8 @@ static int cryptd_create_skcipher(struct crypto_template *tmpl,
err = skcipher_register_instance(tmpl, inst);
if (err) {
-out_drop_skcipher:
- crypto_drop_skcipher(&ctx->spawn);
-out_free_inst:
- kfree(inst);
+err_free_inst:
+ cryptd_skcipher_free(inst);
}
return err;
}
@@ -640,16 +632,17 @@ static void cryptd_hash_free(struct ahash_instance *inst)
}
static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
+ struct crypto_attr_type *algt,
struct cryptd_queue *queue)
{
struct hashd_instance_ctx *ctx;
struct ahash_instance *inst;
struct shash_alg *alg;
- u32 type = 0;
- u32 mask = 0;
+ u32 type;
+ u32 mask;
int err;
- cryptd_check_internal(tb, &type, &mask);
+ cryptd_type_and_mask(algt, &type, &mask);
inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
if (!inst)
@@ -668,10 +661,9 @@ static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
if (err)
goto err_free_inst;
- inst->alg.halg.base.cra_flags = CRYPTO_ALG_ASYNC |
- (alg->base.cra_flags & (CRYPTO_ALG_INTERNAL |
+ inst->alg.halg.base.cra_flags |= CRYPTO_ALG_ASYNC |
+ (alg->base.cra_flags & (CRYPTO_ALG_INTERNAL|
CRYPTO_ALG_OPTIONAL_KEY));
-
inst->alg.halg.digestsize = alg->digestsize;
inst->alg.halg.statesize = alg->statesize;
inst->alg.halg.base.cra_ctxsize = sizeof(struct cryptd_hash_ctx);
@@ -694,8 +686,7 @@ static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
err = ahash_register_instance(tmpl, inst);
if (err) {
err_free_inst:
- crypto_drop_shash(&ctx->spawn);
- kfree(inst);
+ cryptd_hash_free(inst);
}
return err;
}
@@ -828,21 +819,17 @@ static void cryptd_aead_free(struct aead_instance *inst)
static int cryptd_create_aead(struct crypto_template *tmpl,
struct rtattr **tb,
+ struct crypto_attr_type *algt,
struct cryptd_queue *queue)
{
struct aead_instance_ctx *ctx;
struct aead_instance *inst;
struct aead_alg *alg;
- const char *name;
- u32 type = 0;
- u32 mask = CRYPTO_ALG_ASYNC;
+ u32 type;
+ u32 mask;
int err;
- cryptd_check_internal(tb, &type, &mask);
-
- name = crypto_attr_alg_name(tb[1]);
- if (IS_ERR(name))
- return PTR_ERR(name);
+ cryptd_type_and_mask(algt, &type, &mask);
inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
if (!inst)
@@ -852,17 +839,17 @@ static int cryptd_create_aead(struct crypto_template *tmpl,
ctx->queue = queue;
err = crypto_grab_aead(&ctx->aead_spawn, aead_crypto_instance(inst),
- name, type, mask);
+ crypto_attr_alg_name(tb[1]), type, mask);
if (err)
- goto out_free_inst;
+ goto err_free_inst;
alg = crypto_spawn_aead_alg(&ctx->aead_spawn);
err = cryptd_init_instance(aead_crypto_instance(inst), &alg->base);
if (err)
- goto out_drop_aead;
+ goto err_free_inst;
- inst->alg.base.cra_flags = CRYPTO_ALG_ASYNC |
- (alg->base.cra_flags & CRYPTO_ALG_INTERNAL);
+ inst->alg.base.cra_flags |= CRYPTO_ALG_ASYNC |
+ (alg->base.cra_flags & CRYPTO_ALG_INTERNAL);
inst->alg.base.cra_ctxsize = sizeof(struct cryptd_aead_ctx);
inst->alg.ivsize = crypto_aead_alg_ivsize(alg);
@@ -879,10 +866,8 @@ static int cryptd_create_aead(struct crypto_template *tmpl,
err = aead_register_instance(tmpl, inst);
if (err) {
-out_drop_aead:
- crypto_drop_aead(&ctx->aead_spawn);
-out_free_inst:
- kfree(inst);
+err_free_inst:
+ cryptd_aead_free(inst);
}
return err;
}
@@ -899,11 +884,11 @@ static int cryptd_create(struct crypto_template *tmpl, struct rtattr **tb)
switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) {
case CRYPTO_ALG_TYPE_SKCIPHER:
- return cryptd_create_skcipher(tmpl, tb, &queue);
+ return cryptd_create_skcipher(tmpl, tb, algt, &queue);
case CRYPTO_ALG_TYPE_HASH:
- return cryptd_create_hash(tmpl, tb, &queue);
+ return cryptd_create_hash(tmpl, tb, algt, &queue);
case CRYPTO_ALG_TYPE_AEAD:
- return cryptd_create_aead(tmpl, tb, &queue);
+ return cryptd_create_aead(tmpl, tb, algt, &queue);
}
return -EINVAL;
diff --git a/crypto/crypto_engine.c b/crypto/crypto_engine.c
index eb029ff1e05a..bb8e77077f02 100644
--- a/crypto/crypto_engine.c
+++ b/crypto/crypto_engine.c
@@ -9,6 +9,7 @@
#include <linux/err.h>
#include <linux/delay.h>
+#include <linux/device.h>
#include <crypto/engine.h>
#include <uapi/linux/sched/types.h>
#include "internal.h"
@@ -22,32 +23,37 @@
* @err: error number
*/
static void crypto_finalize_request(struct crypto_engine *engine,
- struct crypto_async_request *req, int err)
+ struct crypto_async_request *req, int err)
{
unsigned long flags;
- bool finalize_cur_req = false;
+ bool finalize_req = false;
int ret;
struct crypto_engine_ctx *enginectx;
- spin_lock_irqsave(&engine->queue_lock, flags);
- if (engine->cur_req == req)
- finalize_cur_req = true;
- spin_unlock_irqrestore(&engine->queue_lock, flags);
+ /*
+ * If hardware cannot enqueue more requests
+ * and retry mechanism is not supported
+ * make sure we are completing the current request
+ */
+ if (!engine->retry_support) {
+ spin_lock_irqsave(&engine->queue_lock, flags);
+ if (engine->cur_req == req) {
+ finalize_req = true;
+ engine->cur_req = NULL;
+ }
+ spin_unlock_irqrestore(&engine->queue_lock, flags);
+ }
- if (finalize_cur_req) {
+ if (finalize_req || engine->retry_support) {
enginectx = crypto_tfm_ctx(req->tfm);
- if (engine->cur_req_prepared &&
+ if (enginectx->op.prepare_request &&
enginectx->op.unprepare_request) {
ret = enginectx->op.unprepare_request(engine, req);
if (ret)
dev_err(engine->dev, "failed to unprepare request\n");
}
- spin_lock_irqsave(&engine->queue_lock, flags);
- engine->cur_req = NULL;
- engine->cur_req_prepared = false;
- spin_unlock_irqrestore(&engine->queue_lock, flags);
}
-
+ lockdep_assert_in_softirq();
req->complete(req, err);
kthread_queue_work(engine->kworker, &engine->pump_requests);
@@ -74,7 +80,7 @@ static void crypto_pump_requests(struct crypto_engine *engine,
spin_lock_irqsave(&engine->queue_lock, flags);
/* Make sure we are not already running a request */
- if (engine->cur_req)
+ if (!engine->retry_support && engine->cur_req)
goto out;
/* If another context is idling then defer */
@@ -108,13 +114,21 @@ static void crypto_pump_requests(struct crypto_engine *engine,
goto out;
}
+start_request:
/* Get the fist request from the engine queue to handle */
backlog = crypto_get_backlog(&engine->queue);
async_req = crypto_dequeue_request(&engine->queue);
if (!async_req)
goto out;
- engine->cur_req = async_req;
+ /*
+ * If hardware doesn't support the retry mechanism,
+ * keep track of the request we are processing now.
+ * We'll need it on completion (crypto_finalize_request).
+ */
+ if (!engine->retry_support)
+ engine->cur_req = async_req;
+
if (backlog)
backlog->complete(backlog, -EINPROGRESS);
@@ -130,7 +144,7 @@ static void crypto_pump_requests(struct crypto_engine *engine,
ret = engine->prepare_crypt_hardware(engine);
if (ret) {
dev_err(engine->dev, "failed to prepare crypt hardware\n");
- goto req_err;
+ goto req_err_2;
}
}
@@ -141,28 +155,90 @@ static void crypto_pump_requests(struct crypto_engine *engine,
if (ret) {
dev_err(engine->dev, "failed to prepare request: %d\n",
ret);
- goto req_err;
+ goto req_err_2;
}
- engine->cur_req_prepared = true;
}
if (!enginectx->op.do_one_request) {
dev_err(engine->dev, "failed to do request\n");
ret = -EINVAL;
- goto req_err;
+ goto req_err_1;
}
+
ret = enginectx->op.do_one_request(engine, async_req);
- if (ret) {
- dev_err(engine->dev, "Failed to do one request from queue: %d\n", ret);
- goto req_err;
+
+ /* Request unsuccessfully executed by hardware */
+ if (ret < 0) {
+ /*
+ * If hardware queue is full (-ENOSPC), requeue request
+ * regardless of backlog flag.
+ * Otherwise, unprepare and complete the request.
+ */
+ if (!engine->retry_support ||
+ (ret != -ENOSPC)) {
+ dev_err(engine->dev,
+ "Failed to do one request from queue: %d\n",
+ ret);
+ goto req_err_1;
+ }
+ /*
+ * If retry mechanism is supported,
+ * unprepare current request and
+ * enqueue it back into crypto-engine queue.
+ */
+ if (enginectx->op.unprepare_request) {
+ ret = enginectx->op.unprepare_request(engine,
+ async_req);
+ if (ret)
+ dev_err(engine->dev,
+ "failed to unprepare request\n");
+ }
+ spin_lock_irqsave(&engine->queue_lock, flags);
+ /*
+ * If hardware was unable to execute request, enqueue it
+ * back in front of crypto-engine queue, to keep the order
+ * of requests.
+ */
+ crypto_enqueue_request_head(&engine->queue, async_req);
+
+ kthread_queue_work(engine->kworker, &engine->pump_requests);
+ goto out;
}
- return;
-req_err:
- crypto_finalize_request(engine, async_req, ret);
+ goto retry;
+
+req_err_1:
+ if (enginectx->op.unprepare_request) {
+ ret = enginectx->op.unprepare_request(engine, async_req);
+ if (ret)
+ dev_err(engine->dev, "failed to unprepare request\n");
+ }
+
+req_err_2:
+ async_req->complete(async_req, ret);
+
+retry:
+ /* If retry mechanism is supported, send new requests to engine */
+ if (engine->retry_support) {
+ spin_lock_irqsave(&engine->queue_lock, flags);
+ goto start_request;
+ }
return;
out:
spin_unlock_irqrestore(&engine->queue_lock, flags);
+
+ /*
+ * Batch requests is possible only if
+ * hardware can enqueue multiple requests
+ */
+ if (engine->do_batch_requests) {
+ ret = engine->do_batch_requests(engine);
+ if (ret)
+ dev_err(engine->dev, "failed to do batch requests: %d\n",
+ ret);
+ }
+
+ return;
}
static void crypto_pump_work(struct kthread_work *work)
@@ -177,6 +253,7 @@ static void crypto_pump_work(struct kthread_work *work)
* crypto_transfer_request - transfer the new request into the engine queue
* @engine: the hardware engine
* @req: the request need to be listed into the engine queue
+ * @need_pump: indicates whether queue the pump of request to kthread_work
*/
static int crypto_transfer_request(struct crypto_engine *engine,
struct crypto_async_request *req,
@@ -253,6 +330,19 @@ int crypto_transfer_hash_request_to_engine(struct crypto_engine *engine,
EXPORT_SYMBOL_GPL(crypto_transfer_hash_request_to_engine);
/**
+ * crypto_transfer_kpp_request_to_engine - transfer one kpp_request to list
+ * into the engine queue
+ * @engine: the hardware engine
+ * @req: the request need to be listed into the engine queue
+ */
+int crypto_transfer_kpp_request_to_engine(struct crypto_engine *engine,
+ struct kpp_request *req)
+{
+ return crypto_transfer_request_to_engine(engine, &req->base);
+}
+EXPORT_SYMBOL_GPL(crypto_transfer_kpp_request_to_engine);
+
+/**
* crypto_transfer_skcipher_request_to_engine - transfer one skcipher_request
* to list into the engine queue
* @engine: the hardware engine
@@ -308,6 +398,19 @@ void crypto_finalize_hash_request(struct crypto_engine *engine,
EXPORT_SYMBOL_GPL(crypto_finalize_hash_request);
/**
+ * crypto_finalize_kpp_request - finalize one kpp_request if the request is done
+ * @engine: the hardware engine
+ * @req: the request need to be finalized
+ * @err: error number
+ */
+void crypto_finalize_kpp_request(struct crypto_engine *engine,
+ struct kpp_request *req, int err)
+{
+ return crypto_finalize_request(engine, &req->base, err);
+}
+EXPORT_SYMBOL_GPL(crypto_finalize_kpp_request);
+
+/**
* crypto_finalize_skcipher_request - finalize one skcipher_request if
* the request is done
* @engine: the hardware engine
@@ -386,17 +489,28 @@ int crypto_engine_stop(struct crypto_engine *engine)
EXPORT_SYMBOL_GPL(crypto_engine_stop);
/**
- * crypto_engine_alloc_init - allocate crypto hardware engine structure and
- * initialize it.
+ * crypto_engine_alloc_init_and_set - allocate crypto hardware engine structure
+ * and initialize it by setting the maximum number of entries in the software
+ * crypto-engine queue.
* @dev: the device attached with one hardware engine
+ * @retry_support: whether hardware has support for retry mechanism
+ * @cbk_do_batch: pointer to a callback function to be invoked when executing
+ * a batch of requests.
+ * This has the form:
+ * callback(struct crypto_engine *engine)
+ * where:
+ * @engine: the crypto engine structure.
* @rt: whether this queue is set to run as a realtime task
+ * @qlen: maximum size of the crypto-engine queue
*
* This must be called from context that can sleep.
* Return: the crypto engine structure on success, else NULL.
*/
-struct crypto_engine *crypto_engine_alloc_init(struct device *dev, bool rt)
+struct crypto_engine *crypto_engine_alloc_init_and_set(struct device *dev,
+ bool retry_support,
+ int (*cbk_do_batch)(struct crypto_engine *engine),
+ bool rt, int qlen)
{
- struct sched_param param = { .sched_priority = MAX_RT_PRIO / 2 };
struct crypto_engine *engine;
if (!dev)
@@ -411,12 +525,18 @@ struct crypto_engine *crypto_engine_alloc_init(struct device *dev, bool rt)
engine->running = false;
engine->busy = false;
engine->idling = false;
- engine->cur_req_prepared = false;
+ engine->retry_support = retry_support;
engine->priv_data = dev;
+ /*
+ * Batch requests is possible only if
+ * hardware has support for retry mechanism.
+ */
+ engine->do_batch_requests = retry_support ? cbk_do_batch : NULL;
+
snprintf(engine->name, sizeof(engine->name),
"%s-engine", dev_name(dev));
- crypto_init_queue(&engine->queue, CRYPTO_ENGINE_MAX_QLEN);
+ crypto_init_queue(&engine->queue, qlen);
spin_lock_init(&engine->queue_lock);
engine->kworker = kthread_create_worker(0, "%s", engine->name);
@@ -428,11 +548,27 @@ struct crypto_engine *crypto_engine_alloc_init(struct device *dev, bool rt)
if (engine->rt) {
dev_info(dev, "will run requests pump with realtime priority\n");
- sched_setscheduler(engine->kworker->task, SCHED_FIFO, &param);
+ sched_set_fifo(engine->kworker->task);
}
return engine;
}
+EXPORT_SYMBOL_GPL(crypto_engine_alloc_init_and_set);
+
+/**
+ * crypto_engine_alloc_init - allocate crypto hardware engine structure and
+ * initialize it.
+ * @dev: the device attached with one hardware engine
+ * @rt: whether this queue is set to run as a realtime task
+ *
+ * This must be called from context that can sleep.
+ * Return: the crypto engine structure on success, else NULL.
+ */
+struct crypto_engine *crypto_engine_alloc_init(struct device *dev, bool rt)
+{
+ return crypto_engine_alloc_init_and_set(dev, false, NULL, rt,
+ CRYPTO_ENGINE_MAX_QLEN);
+}
EXPORT_SYMBOL_GPL(crypto_engine_alloc_init);
/**
diff --git a/crypto/ctr.c b/crypto/ctr.c
index a8feab621c6c..23c698b22013 100644
--- a/crypto/ctr.c
+++ b/crypto/ctr.c
@@ -7,6 +7,7 @@
#include <crypto/algapi.h>
#include <crypto/ctr.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/skcipher.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -256,38 +257,24 @@ static void crypto_rfc3686_free(struct skcipher_instance *inst)
static int crypto_rfc3686_create(struct crypto_template *tmpl,
struct rtattr **tb)
{
- struct crypto_attr_type *algt;
struct skcipher_instance *inst;
struct skcipher_alg *alg;
struct crypto_skcipher_spawn *spawn;
- const char *cipher_name;
u32 mask;
-
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask)
- return -EINVAL;
-
- cipher_name = crypto_attr_alg_name(tb[1]);
- if (IS_ERR(cipher_name))
- return PTR_ERR(cipher_name);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
+ if (err)
+ return err;
inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
if (!inst)
return -ENOMEM;
- mask = crypto_requires_sync(algt->type, algt->mask) |
- crypto_requires_off(algt->type, algt->mask,
- CRYPTO_ALG_NEED_FALLBACK);
-
spawn = skcipher_instance_ctx(inst);
err = crypto_grab_skcipher(spawn, skcipher_crypto_instance(inst),
- cipher_name, 0, mask);
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
goto err_free_inst;
@@ -296,27 +283,25 @@ static int crypto_rfc3686_create(struct crypto_template *tmpl,
/* We only support 16-byte blocks. */
err = -EINVAL;
if (crypto_skcipher_alg_ivsize(alg) != CTR_RFC3686_BLOCK_SIZE)
- goto err_drop_spawn;
+ goto err_free_inst;
/* Not a stream cipher? */
if (alg->base.cra_blocksize != 1)
- goto err_drop_spawn;
+ goto err_free_inst;
err = -ENAMETOOLONG;
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
"rfc3686(%s)", alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
- goto err_drop_spawn;
+ goto err_free_inst;
if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
"rfc3686(%s)", alg->base.cra_driver_name) >=
CRYPTO_MAX_ALG_NAME)
- goto err_drop_spawn;
+ goto err_free_inst;
inst->alg.base.cra_priority = alg->base.cra_priority;
inst->alg.base.cra_blocksize = 1;
inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
- inst->alg.base.cra_flags = alg->base.cra_flags & CRYPTO_ALG_ASYNC;
-
inst->alg.ivsize = CTR_RFC3686_IV_SIZE;
inst->alg.chunksize = crypto_skcipher_alg_chunksize(alg);
inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg) +
@@ -336,17 +321,11 @@ static int crypto_rfc3686_create(struct crypto_template *tmpl,
inst->free = crypto_rfc3686_free;
err = skcipher_register_instance(tmpl, inst);
- if (err)
- goto err_drop_spawn;
-
-out:
- return err;
-
-err_drop_spawn:
- crypto_drop_skcipher(spawn);
+ if (err) {
err_free_inst:
- kfree(inst);
- goto out;
+ crypto_rfc3686_free(inst);
+ }
+ return err;
}
static struct crypto_template crypto_ctr_tmpls[] = {
@@ -380,3 +359,4 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("CTR block cipher mode of operation");
MODULE_ALIAS_CRYPTO("rfc3686");
MODULE_ALIAS_CRYPTO("ctr");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/cts.c b/crypto/cts.c
index 48188adc8e91..3766d47ebcc0 100644
--- a/crypto/cts.c
+++ b/crypto/cts.c
@@ -325,24 +325,13 @@ static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
{
struct crypto_skcipher_spawn *spawn;
struct skcipher_instance *inst;
- struct crypto_attr_type *algt;
struct skcipher_alg *alg;
- const char *cipher_name;
u32 mask;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask)
- return -EINVAL;
-
- mask = crypto_requires_sync(algt->type, algt->mask);
-
- cipher_name = crypto_attr_alg_name(tb[1]);
- if (IS_ERR(cipher_name))
- return PTR_ERR(cipher_name);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
+ if (err)
+ return err;
inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
if (!inst)
@@ -351,7 +340,7 @@ static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
spawn = skcipher_instance_ctx(inst);
err = crypto_grab_skcipher(spawn, skcipher_crypto_instance(inst),
- cipher_name, 0, mask);
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
goto err_free_inst;
@@ -359,17 +348,16 @@ static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
err = -EINVAL;
if (crypto_skcipher_alg_ivsize(alg) != alg->base.cra_blocksize)
- goto err_drop_spawn;
+ goto err_free_inst;
if (strncmp(alg->base.cra_name, "cbc(", 4))
- goto err_drop_spawn;
+ goto err_free_inst;
err = crypto_inst_setname(skcipher_crypto_instance(inst), "cts",
&alg->base);
if (err)
- goto err_drop_spawn;
+ goto err_free_inst;
- 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;
@@ -391,17 +379,11 @@ static int crypto_cts_create(struct crypto_template *tmpl, struct rtattr **tb)
inst->free = crypto_cts_free;
err = skcipher_register_instance(tmpl, inst);
- if (err)
- goto err_drop_spawn;
-
-out:
- return err;
-
-err_drop_spawn:
- crypto_drop_skcipher(spawn);
+ if (err) {
err_free_inst:
- kfree(inst);
- goto out;
+ crypto_cts_free(inst);
+ }
+ return err;
}
static struct crypto_template crypto_cts_tmpl = {
diff --git a/crypto/curve25519-generic.c b/crypto/curve25519-generic.c
index bd88fd571393..d055b0784c77 100644
--- a/crypto/curve25519-generic.c
+++ b/crypto/curve25519-generic.c
@@ -72,12 +72,12 @@ static struct kpp_alg curve25519_alg = {
.max_size = curve25519_max_size,
};
-static int curve25519_init(void)
+static int __init curve25519_init(void)
{
return crypto_register_kpp(&curve25519_alg);
}
-static void curve25519_exit(void)
+static void __exit curve25519_exit(void)
{
crypto_unregister_kpp(&curve25519_alg);
}
diff --git a/crypto/deflate.c b/crypto/deflate.c
index 4c0e6c9d942a..b2a46f6dc961 100644
--- a/crypto/deflate.c
+++ b/crypto/deflate.c
@@ -163,7 +163,7 @@ static void __deflate_exit(void *ctx)
static void deflate_free_ctx(struct crypto_scomp *tfm, void *ctx)
{
__deflate_exit(ctx);
- kzfree(ctx);
+ kfree_sensitive(ctx);
}
static void deflate_exit(struct crypto_tfm *tfm)
diff --git a/crypto/dh.c b/crypto/dh.c
index 566f624a2de2..99c3b2ef7adc 100644
--- a/crypto/dh.c
+++ b/crypto/dh.c
@@ -5,15 +5,16 @@
* Authors: Salvatore Benedetto <salvatore.benedetto@intel.com>
*/
+#include <linux/fips.h>
#include <linux/module.h>
#include <crypto/internal/kpp.h>
#include <crypto/kpp.h>
#include <crypto/dh.h>
+#include <crypto/rng.h>
#include <linux/mpi.h>
struct dh_ctx {
MPI p; /* Value is guaranteed to be set. */
- MPI q; /* Value is optional. */
MPI g; /* Value is guaranteed to be set. */
MPI xa; /* Value is guaranteed to be set. */
};
@@ -21,7 +22,6 @@ struct dh_ctx {
static void dh_clear_ctx(struct dh_ctx *ctx)
{
mpi_free(ctx->p);
- mpi_free(ctx->q);
mpi_free(ctx->g);
mpi_free(ctx->xa);
memset(ctx, 0, sizeof(*ctx));
@@ -46,6 +46,9 @@ static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
static int dh_check_params_length(unsigned int p_len)
{
+ if (fips_enabled)
+ return (p_len < 2048) ? -EINVAL : 0;
+
return (p_len < 1536) ? -EINVAL : 0;
}
@@ -58,12 +61,6 @@ static int dh_set_params(struct dh_ctx *ctx, struct dh *params)
if (!ctx->p)
return -EINVAL;
- if (params->q && params->q_size) {
- ctx->q = mpi_read_raw_data(params->q, params->q_size);
- if (!ctx->q)
- return -EINVAL;
- }
-
ctx->g = mpi_read_raw_data(params->g, params->g_size);
if (!ctx->g)
return -EINVAL;
@@ -100,11 +97,12 @@ err_clear_ctx:
/*
* SP800-56A public key verification:
*
- * * If Q is provided as part of the domain paramenters, a full validation
- * according to SP800-56A section 5.6.2.3.1 is performed.
+ * * For the safe-prime groups in FIPS mode, Q can be computed
+ * trivially from P and a full validation according to SP800-56A
+ * section 5.6.2.3.1 is performed.
*
- * * If Q is not provided, a partial validation according to SP800-56A section
- * 5.6.2.3.2 is performed.
+ * * For all other sets of group parameters, only a partial validation
+ * according to SP800-56A section 5.6.2.3.2 is performed.
*/
static int dh_is_pubkey_valid(struct dh_ctx *ctx, MPI y)
{
@@ -115,21 +113,40 @@ static int dh_is_pubkey_valid(struct dh_ctx *ctx, MPI y)
* Step 1: Verify that 2 <= y <= p - 2.
*
* The upper limit check is actually y < p instead of y < p - 1
- * as the mpi_sub_ui function is yet missing.
+ * in order to save one mpi_sub_ui() invocation here. Note that
+ * p - 1 is the non-trivial element of the subgroup of order 2 and
+ * thus, the check on y^q below would fail if y == p - 1.
*/
if (mpi_cmp_ui(y, 1) < 1 || mpi_cmp(y, ctx->p) >= 0)
return -EINVAL;
- /* Step 2: Verify that 1 = y^q mod p */
- if (ctx->q) {
- MPI val = mpi_alloc(0);
+ /*
+ * Step 2: Verify that 1 = y^q mod p
+ *
+ * For the safe-prime groups q = (p - 1)/2.
+ */
+ if (fips_enabled) {
+ MPI val, q;
int ret;
+ val = mpi_alloc(0);
if (!val)
return -ENOMEM;
- ret = mpi_powm(val, y, ctx->q, ctx->p);
+ q = mpi_alloc(mpi_get_nlimbs(ctx->p));
+ if (!q) {
+ mpi_free(val);
+ return -ENOMEM;
+ }
+
+ /*
+ * ->p is odd, so no need to explicitly subtract one
+ * from it before shifting to the right.
+ */
+ mpi_rshift(q, ctx->p, 1);
+ ret = mpi_powm(val, y, q, ctx->p);
+ mpi_free(q);
if (ret) {
mpi_free(val);
return ret;
@@ -179,6 +196,43 @@ static int dh_compute_value(struct kpp_request *req)
if (ret)
goto err_free_base;
+ if (fips_enabled) {
+ /* SP800-56A rev3 5.7.1.1 check: Validation of shared secret */
+ if (req->src) {
+ MPI pone;
+
+ /* z <= 1 */
+ if (mpi_cmp_ui(val, 1) < 1) {
+ ret = -EBADMSG;
+ goto err_free_base;
+ }
+
+ /* z == p - 1 */
+ pone = mpi_alloc(0);
+
+ if (!pone) {
+ ret = -ENOMEM;
+ goto err_free_base;
+ }
+
+ ret = mpi_sub_ui(pone, ctx->p, 1);
+ if (!ret && !mpi_cmp(pone, val))
+ ret = -EBADMSG;
+
+ mpi_free(pone);
+
+ if (ret)
+ goto err_free_base;
+
+ /* SP800-56A rev 3 5.6.2.1.3 key check */
+ } else {
+ if (dh_is_pubkey_valid(ctx, val)) {
+ ret = -EAGAIN;
+ goto err_free_val;
+ }
+ }
+ }
+
ret = mpi_write_to_sgl(val, req->dst, req->dst_len, &sign);
if (ret)
goto err_free_base;
@@ -222,13 +276,645 @@ static struct kpp_alg dh = {
},
};
-static int dh_init(void)
+
+struct dh_safe_prime {
+ unsigned int max_strength;
+ unsigned int p_size;
+ const char *p;
+};
+
+static const char safe_prime_g[] = { 2 };
+
+struct dh_safe_prime_instance_ctx {
+ struct crypto_kpp_spawn dh_spawn;
+ const struct dh_safe_prime *safe_prime;
+};
+
+struct dh_safe_prime_tfm_ctx {
+ struct crypto_kpp *dh_tfm;
+};
+
+static void dh_safe_prime_free_instance(struct kpp_instance *inst)
+{
+ struct dh_safe_prime_instance_ctx *ctx = kpp_instance_ctx(inst);
+
+ crypto_drop_kpp(&ctx->dh_spawn);
+ kfree(inst);
+}
+
+static inline struct dh_safe_prime_instance_ctx *dh_safe_prime_instance_ctx(
+ struct crypto_kpp *tfm)
+{
+ return kpp_instance_ctx(kpp_alg_instance(tfm));
+}
+
+static int dh_safe_prime_init_tfm(struct crypto_kpp *tfm)
+{
+ struct dh_safe_prime_instance_ctx *inst_ctx =
+ dh_safe_prime_instance_ctx(tfm);
+ struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
+
+ tfm_ctx->dh_tfm = crypto_spawn_kpp(&inst_ctx->dh_spawn);
+ if (IS_ERR(tfm_ctx->dh_tfm))
+ return PTR_ERR(tfm_ctx->dh_tfm);
+
+ return 0;
+}
+
+static void dh_safe_prime_exit_tfm(struct crypto_kpp *tfm)
+{
+ struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
+
+ crypto_free_kpp(tfm_ctx->dh_tfm);
+}
+
+static u64 __add_u64_to_be(__be64 *dst, unsigned int n, u64 val)
+{
+ unsigned int i;
+
+ for (i = n; val && i > 0; --i) {
+ u64 tmp = be64_to_cpu(dst[i - 1]);
+
+ tmp += val;
+ val = tmp >= val ? 0 : 1;
+ dst[i - 1] = cpu_to_be64(tmp);
+ }
+
+ return val;
+}
+
+static void *dh_safe_prime_gen_privkey(const struct dh_safe_prime *safe_prime,
+ unsigned int *key_size)
+{
+ unsigned int n, oversampling_size;
+ __be64 *key;
+ int err;
+ u64 h, o;
+
+ /*
+ * Generate a private key following NIST SP800-56Ar3,
+ * sec. 5.6.1.1.1 and 5.6.1.1.3 resp..
+ *
+ * 5.6.1.1.1: choose key length N such that
+ * 2 * ->max_strength <= N <= log2(q) + 1 = ->p_size * 8 - 1
+ * with q = (p - 1) / 2 for the safe-prime groups.
+ * Choose the lower bound's next power of two for N in order to
+ * avoid excessively large private keys while still
+ * maintaining some extra reserve beyond the bare minimum in
+ * most cases. Note that for each entry in safe_prime_groups[],
+ * the following holds for such N:
+ * - N >= 256, in particular it is a multiple of 2^6 = 64
+ * bits and
+ * - N < log2(q) + 1, i.e. N respects the upper bound.
+ */
+ n = roundup_pow_of_two(2 * safe_prime->max_strength);
+ WARN_ON_ONCE(n & ((1u << 6) - 1));
+ n >>= 6; /* Convert N into units of u64. */
+
+ /*
+ * Reserve one extra u64 to hold the extra random bits
+ * required as per 5.6.1.1.3.
+ */
+ oversampling_size = (n + 1) * sizeof(__be64);
+ key = kmalloc(oversampling_size, GFP_KERNEL);
+ if (!key)
+ return ERR_PTR(-ENOMEM);
+
+ /*
+ * 5.6.1.1.3, step 3 (and implicitly step 4): obtain N + 64
+ * random bits and interpret them as a big endian integer.
+ */
+ err = -EFAULT;
+ if (crypto_get_default_rng())
+ goto out_err;
+
+ err = crypto_rng_get_bytes(crypto_default_rng, (u8 *)key,
+ oversampling_size);
+ crypto_put_default_rng();
+ if (err)
+ goto out_err;
+
+ /*
+ * 5.6.1.1.3, step 5 is implicit: 2^N < q and thus,
+ * M = min(2^N, q) = 2^N.
+ *
+ * For step 6, calculate
+ * key = (key[] mod (M - 1)) + 1 = (key[] mod (2^N - 1)) + 1.
+ *
+ * In order to avoid expensive divisions, note that
+ * 2^N mod (2^N - 1) = 1 and thus, for any integer h,
+ * 2^N * h mod (2^N - 1) = h mod (2^N - 1) always holds.
+ * The big endian integer key[] composed of n + 1 64bit words
+ * may be written as key[] = h * 2^N + l, with h = key[0]
+ * representing the 64 most significant bits and l
+ * corresponding to the remaining 2^N bits. With the remark
+ * from above,
+ * h * 2^N + l mod (2^N - 1) = l + h mod (2^N - 1).
+ * As both, l and h are less than 2^N, their sum after
+ * this first reduction is guaranteed to be <= 2^(N + 1) - 2.
+ * Or equivalently, that their sum can again be written as
+ * h' * 2^N + l' with h' now either zero or one and if one,
+ * then l' <= 2^N - 2. Thus, all bits at positions >= N will
+ * be zero after a second reduction:
+ * h' * 2^N + l' mod (2^N - 1) = l' + h' mod (2^N - 1).
+ * At this point, it is still possible that
+ * l' + h' = 2^N - 1, i.e. that l' + h' mod (2^N - 1)
+ * is zero. This condition will be detected below by means of
+ * the final increment overflowing in this case.
+ */
+ h = be64_to_cpu(key[0]);
+ h = __add_u64_to_be(key + 1, n, h);
+ h = __add_u64_to_be(key + 1, n, h);
+ WARN_ON_ONCE(h);
+
+ /* Increment to obtain the final result. */
+ o = __add_u64_to_be(key + 1, n, 1);
+ /*
+ * The overflow bit o from the increment is either zero or
+ * one. If zero, key[1:n] holds the final result in big-endian
+ * order. If one, key[1:n] is zero now, but needs to be set to
+ * one, c.f. above.
+ */
+ if (o)
+ key[n] = cpu_to_be64(1);
+
+ /* n is in units of u64, convert to bytes. */
+ *key_size = n << 3;
+ /* Strip the leading extra __be64, which is (virtually) zero by now. */
+ memmove(key, &key[1], *key_size);
+
+ return key;
+
+out_err:
+ kfree_sensitive(key);
+ return ERR_PTR(err);
+}
+
+static int dh_safe_prime_set_secret(struct crypto_kpp *tfm, const void *buffer,
+ unsigned int len)
+{
+ struct dh_safe_prime_instance_ctx *inst_ctx =
+ dh_safe_prime_instance_ctx(tfm);
+ struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
+ struct dh params = {};
+ void *buf = NULL, *key = NULL;
+ unsigned int buf_size;
+ int err;
+
+ if (buffer) {
+ err = __crypto_dh_decode_key(buffer, len, &params);
+ if (err)
+ return err;
+ if (params.p_size || params.g_size)
+ return -EINVAL;
+ }
+
+ params.p = inst_ctx->safe_prime->p;
+ params.p_size = inst_ctx->safe_prime->p_size;
+ params.g = safe_prime_g;
+ params.g_size = sizeof(safe_prime_g);
+
+ if (!params.key_size) {
+ key = dh_safe_prime_gen_privkey(inst_ctx->safe_prime,
+ &params.key_size);
+ if (IS_ERR(key))
+ return PTR_ERR(key);
+ params.key = key;
+ }
+
+ buf_size = crypto_dh_key_len(&params);
+ buf = kmalloc(buf_size, GFP_KERNEL);
+ if (!buf) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ err = crypto_dh_encode_key(buf, buf_size, &params);
+ if (err)
+ goto out;
+
+ err = crypto_kpp_set_secret(tfm_ctx->dh_tfm, buf, buf_size);
+out:
+ kfree_sensitive(buf);
+ kfree_sensitive(key);
+ return err;
+}
+
+static void dh_safe_prime_complete_req(struct crypto_async_request *dh_req,
+ int err)
+{
+ struct kpp_request *req = dh_req->data;
+
+ kpp_request_complete(req, err);
+}
+
+static struct kpp_request *dh_safe_prime_prepare_dh_req(struct kpp_request *req)
+{
+ struct dh_safe_prime_tfm_ctx *tfm_ctx =
+ kpp_tfm_ctx(crypto_kpp_reqtfm(req));
+ struct kpp_request *dh_req = kpp_request_ctx(req);
+
+ kpp_request_set_tfm(dh_req, tfm_ctx->dh_tfm);
+ kpp_request_set_callback(dh_req, req->base.flags,
+ dh_safe_prime_complete_req, req);
+
+ kpp_request_set_input(dh_req, req->src, req->src_len);
+ kpp_request_set_output(dh_req, req->dst, req->dst_len);
+
+ return dh_req;
+}
+
+static int dh_safe_prime_generate_public_key(struct kpp_request *req)
+{
+ struct kpp_request *dh_req = dh_safe_prime_prepare_dh_req(req);
+
+ return crypto_kpp_generate_public_key(dh_req);
+}
+
+static int dh_safe_prime_compute_shared_secret(struct kpp_request *req)
+{
+ struct kpp_request *dh_req = dh_safe_prime_prepare_dh_req(req);
+
+ return crypto_kpp_compute_shared_secret(dh_req);
+}
+
+static unsigned int dh_safe_prime_max_size(struct crypto_kpp *tfm)
+{
+ struct dh_safe_prime_tfm_ctx *tfm_ctx = kpp_tfm_ctx(tfm);
+
+ return crypto_kpp_maxsize(tfm_ctx->dh_tfm);
+}
+
+static int __maybe_unused __dh_safe_prime_create(
+ struct crypto_template *tmpl, struct rtattr **tb,
+ const struct dh_safe_prime *safe_prime)
+{
+ struct kpp_instance *inst;
+ struct dh_safe_prime_instance_ctx *ctx;
+ const char *dh_name;
+ struct kpp_alg *dh_alg;
+ u32 mask;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_KPP, &mask);
+ if (err)
+ return err;
+
+ dh_name = crypto_attr_alg_name(tb[1]);
+ if (IS_ERR(dh_name))
+ return PTR_ERR(dh_name);
+
+ inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
+ if (!inst)
+ return -ENOMEM;
+
+ ctx = kpp_instance_ctx(inst);
+
+ err = crypto_grab_kpp(&ctx->dh_spawn, kpp_crypto_instance(inst),
+ dh_name, 0, mask);
+ if (err)
+ goto err_free_inst;
+
+ err = -EINVAL;
+ dh_alg = crypto_spawn_kpp_alg(&ctx->dh_spawn);
+ if (strcmp(dh_alg->base.cra_name, "dh"))
+ goto err_free_inst;
+
+ ctx->safe_prime = safe_prime;
+
+ err = crypto_inst_setname(kpp_crypto_instance(inst),
+ tmpl->name, &dh_alg->base);
+ if (err)
+ goto err_free_inst;
+
+ inst->alg.set_secret = dh_safe_prime_set_secret;
+ inst->alg.generate_public_key = dh_safe_prime_generate_public_key;
+ inst->alg.compute_shared_secret = dh_safe_prime_compute_shared_secret;
+ inst->alg.max_size = dh_safe_prime_max_size;
+ inst->alg.init = dh_safe_prime_init_tfm;
+ inst->alg.exit = dh_safe_prime_exit_tfm;
+ inst->alg.reqsize = sizeof(struct kpp_request) + dh_alg->reqsize;
+ inst->alg.base.cra_priority = dh_alg->base.cra_priority;
+ inst->alg.base.cra_module = THIS_MODULE;
+ inst->alg.base.cra_ctxsize = sizeof(struct dh_safe_prime_tfm_ctx);
+
+ inst->free = dh_safe_prime_free_instance;
+
+ err = kpp_register_instance(tmpl, inst);
+ if (err)
+ goto err_free_inst;
+
+ return 0;
+
+err_free_inst:
+ dh_safe_prime_free_instance(inst);
+
+ return err;
+}
+
+#ifdef CONFIG_CRYPTO_DH_RFC7919_GROUPS
+
+static const struct dh_safe_prime ffdhe2048_prime = {
+ .max_strength = 112,
+ .p_size = 256,
+ .p =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
+ "\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
+ "\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
+ "\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
+ "\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
+ "\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
+ "\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
+ "\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
+ "\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
+ "\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
+ "\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
+ "\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
+ "\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
+ "\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
+ "\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
+ "\x88\x6b\x42\x38\x61\x28\x5c\x97\xff\xff\xff\xff\xff\xff\xff\xff",
+};
+
+static const struct dh_safe_prime ffdhe3072_prime = {
+ .max_strength = 128,
+ .p_size = 384,
+ .p =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
+ "\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
+ "\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
+ "\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
+ "\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
+ "\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
+ "\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
+ "\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
+ "\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
+ "\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
+ "\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
+ "\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
+ "\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
+ "\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
+ "\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
+ "\x88\x6b\x42\x38\x61\x1f\xcf\xdc\xde\x35\x5b\x3b\x65\x19\x03\x5b"
+ "\xbc\x34\xf4\xde\xf9\x9c\x02\x38\x61\xb4\x6f\xc9\xd6\xe6\xc9\x07"
+ "\x7a\xd9\x1d\x26\x91\xf7\xf7\xee\x59\x8c\xb0\xfa\xc1\x86\xd9\x1c"
+ "\xae\xfe\x13\x09\x85\x13\x92\x70\xb4\x13\x0c\x93\xbc\x43\x79\x44"
+ "\xf4\xfd\x44\x52\xe2\xd7\x4d\xd3\x64\xf2\xe2\x1e\x71\xf5\x4b\xff"
+ "\x5c\xae\x82\xab\x9c\x9d\xf6\x9e\xe8\x6d\x2b\xc5\x22\x36\x3a\x0d"
+ "\xab\xc5\x21\x97\x9b\x0d\xea\xda\x1d\xbf\x9a\x42\xd5\xc4\x48\x4e"
+ "\x0a\xbc\xd0\x6b\xfa\x53\xdd\xef\x3c\x1b\x20\xee\x3f\xd5\x9d\x7c"
+ "\x25\xe4\x1d\x2b\x66\xc6\x2e\x37\xff\xff\xff\xff\xff\xff\xff\xff",
+};
+
+static const struct dh_safe_prime ffdhe4096_prime = {
+ .max_strength = 152,
+ .p_size = 512,
+ .p =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
+ "\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
+ "\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
+ "\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
+ "\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
+ "\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
+ "\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
+ "\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
+ "\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
+ "\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
+ "\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
+ "\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
+ "\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
+ "\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
+ "\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
+ "\x88\x6b\x42\x38\x61\x1f\xcf\xdc\xde\x35\x5b\x3b\x65\x19\x03\x5b"
+ "\xbc\x34\xf4\xde\xf9\x9c\x02\x38\x61\xb4\x6f\xc9\xd6\xe6\xc9\x07"
+ "\x7a\xd9\x1d\x26\x91\xf7\xf7\xee\x59\x8c\xb0\xfa\xc1\x86\xd9\x1c"
+ "\xae\xfe\x13\x09\x85\x13\x92\x70\xb4\x13\x0c\x93\xbc\x43\x79\x44"
+ "\xf4\xfd\x44\x52\xe2\xd7\x4d\xd3\x64\xf2\xe2\x1e\x71\xf5\x4b\xff"
+ "\x5c\xae\x82\xab\x9c\x9d\xf6\x9e\xe8\x6d\x2b\xc5\x22\x36\x3a\x0d"
+ "\xab\xc5\x21\x97\x9b\x0d\xea\xda\x1d\xbf\x9a\x42\xd5\xc4\x48\x4e"
+ "\x0a\xbc\xd0\x6b\xfa\x53\xdd\xef\x3c\x1b\x20\xee\x3f\xd5\x9d\x7c"
+ "\x25\xe4\x1d\x2b\x66\x9e\x1e\xf1\x6e\x6f\x52\xc3\x16\x4d\xf4\xfb"
+ "\x79\x30\xe9\xe4\xe5\x88\x57\xb6\xac\x7d\x5f\x42\xd6\x9f\x6d\x18"
+ "\x77\x63\xcf\x1d\x55\x03\x40\x04\x87\xf5\x5b\xa5\x7e\x31\xcc\x7a"
+ "\x71\x35\xc8\x86\xef\xb4\x31\x8a\xed\x6a\x1e\x01\x2d\x9e\x68\x32"
+ "\xa9\x07\x60\x0a\x91\x81\x30\xc4\x6d\xc7\x78\xf9\x71\xad\x00\x38"
+ "\x09\x29\x99\xa3\x33\xcb\x8b\x7a\x1a\x1d\xb9\x3d\x71\x40\x00\x3c"
+ "\x2a\x4e\xce\xa9\xf9\x8d\x0a\xcc\x0a\x82\x91\xcd\xce\xc9\x7d\xcf"
+ "\x8e\xc9\xb5\x5a\x7f\x88\xa4\x6b\x4d\xb5\xa8\x51\xf4\x41\x82\xe1"
+ "\xc6\x8a\x00\x7e\x5e\x65\x5f\x6a\xff\xff\xff\xff\xff\xff\xff\xff",
+};
+
+static const struct dh_safe_prime ffdhe6144_prime = {
+ .max_strength = 176,
+ .p_size = 768,
+ .p =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
+ "\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
+ "\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
+ "\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
+ "\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
+ "\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
+ "\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
+ "\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
+ "\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
+ "\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
+ "\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
+ "\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
+ "\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
+ "\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
+ "\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
+ "\x88\x6b\x42\x38\x61\x1f\xcf\xdc\xde\x35\x5b\x3b\x65\x19\x03\x5b"
+ "\xbc\x34\xf4\xde\xf9\x9c\x02\x38\x61\xb4\x6f\xc9\xd6\xe6\xc9\x07"
+ "\x7a\xd9\x1d\x26\x91\xf7\xf7\xee\x59\x8c\xb0\xfa\xc1\x86\xd9\x1c"
+ "\xae\xfe\x13\x09\x85\x13\x92\x70\xb4\x13\x0c\x93\xbc\x43\x79\x44"
+ "\xf4\xfd\x44\x52\xe2\xd7\x4d\xd3\x64\xf2\xe2\x1e\x71\xf5\x4b\xff"
+ "\x5c\xae\x82\xab\x9c\x9d\xf6\x9e\xe8\x6d\x2b\xc5\x22\x36\x3a\x0d"
+ "\xab\xc5\x21\x97\x9b\x0d\xea\xda\x1d\xbf\x9a\x42\xd5\xc4\x48\x4e"
+ "\x0a\xbc\xd0\x6b\xfa\x53\xdd\xef\x3c\x1b\x20\xee\x3f\xd5\x9d\x7c"
+ "\x25\xe4\x1d\x2b\x66\x9e\x1e\xf1\x6e\x6f\x52\xc3\x16\x4d\xf4\xfb"
+ "\x79\x30\xe9\xe4\xe5\x88\x57\xb6\xac\x7d\x5f\x42\xd6\x9f\x6d\x18"
+ "\x77\x63\xcf\x1d\x55\x03\x40\x04\x87\xf5\x5b\xa5\x7e\x31\xcc\x7a"
+ "\x71\x35\xc8\x86\xef\xb4\x31\x8a\xed\x6a\x1e\x01\x2d\x9e\x68\x32"
+ "\xa9\x07\x60\x0a\x91\x81\x30\xc4\x6d\xc7\x78\xf9\x71\xad\x00\x38"
+ "\x09\x29\x99\xa3\x33\xcb\x8b\x7a\x1a\x1d\xb9\x3d\x71\x40\x00\x3c"
+ "\x2a\x4e\xce\xa9\xf9\x8d\x0a\xcc\x0a\x82\x91\xcd\xce\xc9\x7d\xcf"
+ "\x8e\xc9\xb5\x5a\x7f\x88\xa4\x6b\x4d\xb5\xa8\x51\xf4\x41\x82\xe1"
+ "\xc6\x8a\x00\x7e\x5e\x0d\xd9\x02\x0b\xfd\x64\xb6\x45\x03\x6c\x7a"
+ "\x4e\x67\x7d\x2c\x38\x53\x2a\x3a\x23\xba\x44\x42\xca\xf5\x3e\xa6"
+ "\x3b\xb4\x54\x32\x9b\x76\x24\xc8\x91\x7b\xdd\x64\xb1\xc0\xfd\x4c"
+ "\xb3\x8e\x8c\x33\x4c\x70\x1c\x3a\xcd\xad\x06\x57\xfc\xcf\xec\x71"
+ "\x9b\x1f\x5c\x3e\x4e\x46\x04\x1f\x38\x81\x47\xfb\x4c\xfd\xb4\x77"
+ "\xa5\x24\x71\xf7\xa9\xa9\x69\x10\xb8\x55\x32\x2e\xdb\x63\x40\xd8"
+ "\xa0\x0e\xf0\x92\x35\x05\x11\xe3\x0a\xbe\xc1\xff\xf9\xe3\xa2\x6e"
+ "\x7f\xb2\x9f\x8c\x18\x30\x23\xc3\x58\x7e\x38\xda\x00\x77\xd9\xb4"
+ "\x76\x3e\x4e\x4b\x94\xb2\xbb\xc1\x94\xc6\x65\x1e\x77\xca\xf9\x92"
+ "\xee\xaa\xc0\x23\x2a\x28\x1b\xf6\xb3\xa7\x39\xc1\x22\x61\x16\x82"
+ "\x0a\xe8\xdb\x58\x47\xa6\x7c\xbe\xf9\xc9\x09\x1b\x46\x2d\x53\x8c"
+ "\xd7\x2b\x03\x74\x6a\xe7\x7f\x5e\x62\x29\x2c\x31\x15\x62\xa8\x46"
+ "\x50\x5d\xc8\x2d\xb8\x54\x33\x8a\xe4\x9f\x52\x35\xc9\x5b\x91\x17"
+ "\x8c\xcf\x2d\xd5\xca\xce\xf4\x03\xec\x9d\x18\x10\xc6\x27\x2b\x04"
+ "\x5b\x3b\x71\xf9\xdc\x6b\x80\xd6\x3f\xdd\x4a\x8e\x9a\xdb\x1e\x69"
+ "\x62\xa6\x95\x26\xd4\x31\x61\xc1\xa4\x1d\x57\x0d\x79\x38\xda\xd4"
+ "\xa4\x0e\x32\x9c\xd0\xe4\x0e\x65\xff\xff\xff\xff\xff\xff\xff\xff",
+};
+
+static const struct dh_safe_prime ffdhe8192_prime = {
+ .max_strength = 200,
+ .p_size = 1024,
+ .p =
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xad\xf8\x54\x58\xa2\xbb\x4a\x9a"
+ "\xaf\xdc\x56\x20\x27\x3d\x3c\xf1\xd8\xb9\xc5\x83\xce\x2d\x36\x95"
+ "\xa9\xe1\x36\x41\x14\x64\x33\xfb\xcc\x93\x9d\xce\x24\x9b\x3e\xf9"
+ "\x7d\x2f\xe3\x63\x63\x0c\x75\xd8\xf6\x81\xb2\x02\xae\xc4\x61\x7a"
+ "\xd3\xdf\x1e\xd5\xd5\xfd\x65\x61\x24\x33\xf5\x1f\x5f\x06\x6e\xd0"
+ "\x85\x63\x65\x55\x3d\xed\x1a\xf3\xb5\x57\x13\x5e\x7f\x57\xc9\x35"
+ "\x98\x4f\x0c\x70\xe0\xe6\x8b\x77\xe2\xa6\x89\xda\xf3\xef\xe8\x72"
+ "\x1d\xf1\x58\xa1\x36\xad\xe7\x35\x30\xac\xca\x4f\x48\x3a\x79\x7a"
+ "\xbc\x0a\xb1\x82\xb3\x24\xfb\x61\xd1\x08\xa9\x4b\xb2\xc8\xe3\xfb"
+ "\xb9\x6a\xda\xb7\x60\xd7\xf4\x68\x1d\x4f\x42\xa3\xde\x39\x4d\xf4"
+ "\xae\x56\xed\xe7\x63\x72\xbb\x19\x0b\x07\xa7\xc8\xee\x0a\x6d\x70"
+ "\x9e\x02\xfc\xe1\xcd\xf7\xe2\xec\xc0\x34\x04\xcd\x28\x34\x2f\x61"
+ "\x91\x72\xfe\x9c\xe9\x85\x83\xff\x8e\x4f\x12\x32\xee\xf2\x81\x83"
+ "\xc3\xfe\x3b\x1b\x4c\x6f\xad\x73\x3b\xb5\xfc\xbc\x2e\xc2\x20\x05"
+ "\xc5\x8e\xf1\x83\x7d\x16\x83\xb2\xc6\xf3\x4a\x26\xc1\xb2\xef\xfa"
+ "\x88\x6b\x42\x38\x61\x1f\xcf\xdc\xde\x35\x5b\x3b\x65\x19\x03\x5b"
+ "\xbc\x34\xf4\xde\xf9\x9c\x02\x38\x61\xb4\x6f\xc9\xd6\xe6\xc9\x07"
+ "\x7a\xd9\x1d\x26\x91\xf7\xf7\xee\x59\x8c\xb0\xfa\xc1\x86\xd9\x1c"
+ "\xae\xfe\x13\x09\x85\x13\x92\x70\xb4\x13\x0c\x93\xbc\x43\x79\x44"
+ "\xf4\xfd\x44\x52\xe2\xd7\x4d\xd3\x64\xf2\xe2\x1e\x71\xf5\x4b\xff"
+ "\x5c\xae\x82\xab\x9c\x9d\xf6\x9e\xe8\x6d\x2b\xc5\x22\x36\x3a\x0d"
+ "\xab\xc5\x21\x97\x9b\x0d\xea\xda\x1d\xbf\x9a\x42\xd5\xc4\x48\x4e"
+ "\x0a\xbc\xd0\x6b\xfa\x53\xdd\xef\x3c\x1b\x20\xee\x3f\xd5\x9d\x7c"
+ "\x25\xe4\x1d\x2b\x66\x9e\x1e\xf1\x6e\x6f\x52\xc3\x16\x4d\xf4\xfb"
+ "\x79\x30\xe9\xe4\xe5\x88\x57\xb6\xac\x7d\x5f\x42\xd6\x9f\x6d\x18"
+ "\x77\x63\xcf\x1d\x55\x03\x40\x04\x87\xf5\x5b\xa5\x7e\x31\xcc\x7a"
+ "\x71\x35\xc8\x86\xef\xb4\x31\x8a\xed\x6a\x1e\x01\x2d\x9e\x68\x32"
+ "\xa9\x07\x60\x0a\x91\x81\x30\xc4\x6d\xc7\x78\xf9\x71\xad\x00\x38"
+ "\x09\x29\x99\xa3\x33\xcb\x8b\x7a\x1a\x1d\xb9\x3d\x71\x40\x00\x3c"
+ "\x2a\x4e\xce\xa9\xf9\x8d\x0a\xcc\x0a\x82\x91\xcd\xce\xc9\x7d\xcf"
+ "\x8e\xc9\xb5\x5a\x7f\x88\xa4\x6b\x4d\xb5\xa8\x51\xf4\x41\x82\xe1"
+ "\xc6\x8a\x00\x7e\x5e\x0d\xd9\x02\x0b\xfd\x64\xb6\x45\x03\x6c\x7a"
+ "\x4e\x67\x7d\x2c\x38\x53\x2a\x3a\x23\xba\x44\x42\xca\xf5\x3e\xa6"
+ "\x3b\xb4\x54\x32\x9b\x76\x24\xc8\x91\x7b\xdd\x64\xb1\xc0\xfd\x4c"
+ "\xb3\x8e\x8c\x33\x4c\x70\x1c\x3a\xcd\xad\x06\x57\xfc\xcf\xec\x71"
+ "\x9b\x1f\x5c\x3e\x4e\x46\x04\x1f\x38\x81\x47\xfb\x4c\xfd\xb4\x77"
+ "\xa5\x24\x71\xf7\xa9\xa9\x69\x10\xb8\x55\x32\x2e\xdb\x63\x40\xd8"
+ "\xa0\x0e\xf0\x92\x35\x05\x11\xe3\x0a\xbe\xc1\xff\xf9\xe3\xa2\x6e"
+ "\x7f\xb2\x9f\x8c\x18\x30\x23\xc3\x58\x7e\x38\xda\x00\x77\xd9\xb4"
+ "\x76\x3e\x4e\x4b\x94\xb2\xbb\xc1\x94\xc6\x65\x1e\x77\xca\xf9\x92"
+ "\xee\xaa\xc0\x23\x2a\x28\x1b\xf6\xb3\xa7\x39\xc1\x22\x61\x16\x82"
+ "\x0a\xe8\xdb\x58\x47\xa6\x7c\xbe\xf9\xc9\x09\x1b\x46\x2d\x53\x8c"
+ "\xd7\x2b\x03\x74\x6a\xe7\x7f\x5e\x62\x29\x2c\x31\x15\x62\xa8\x46"
+ "\x50\x5d\xc8\x2d\xb8\x54\x33\x8a\xe4\x9f\x52\x35\xc9\x5b\x91\x17"
+ "\x8c\xcf\x2d\xd5\xca\xce\xf4\x03\xec\x9d\x18\x10\xc6\x27\x2b\x04"
+ "\x5b\x3b\x71\xf9\xdc\x6b\x80\xd6\x3f\xdd\x4a\x8e\x9a\xdb\x1e\x69"
+ "\x62\xa6\x95\x26\xd4\x31\x61\xc1\xa4\x1d\x57\x0d\x79\x38\xda\xd4"
+ "\xa4\x0e\x32\x9c\xcf\xf4\x6a\xaa\x36\xad\x00\x4c\xf6\x00\xc8\x38"
+ "\x1e\x42\x5a\x31\xd9\x51\xae\x64\xfd\xb2\x3f\xce\xc9\x50\x9d\x43"
+ "\x68\x7f\xeb\x69\xed\xd1\xcc\x5e\x0b\x8c\xc3\xbd\xf6\x4b\x10\xef"
+ "\x86\xb6\x31\x42\xa3\xab\x88\x29\x55\x5b\x2f\x74\x7c\x93\x26\x65"
+ "\xcb\x2c\x0f\x1c\xc0\x1b\xd7\x02\x29\x38\x88\x39\xd2\xaf\x05\xe4"
+ "\x54\x50\x4a\xc7\x8b\x75\x82\x82\x28\x46\xc0\xba\x35\xc3\x5f\x5c"
+ "\x59\x16\x0c\xc0\x46\xfd\x82\x51\x54\x1f\xc6\x8c\x9c\x86\xb0\x22"
+ "\xbb\x70\x99\x87\x6a\x46\x0e\x74\x51\xa8\xa9\x31\x09\x70\x3f\xee"
+ "\x1c\x21\x7e\x6c\x38\x26\xe5\x2c\x51\xaa\x69\x1e\x0e\x42\x3c\xfc"
+ "\x99\xe9\xe3\x16\x50\xc1\x21\x7b\x62\x48\x16\xcd\xad\x9a\x95\xf9"
+ "\xd5\xb8\x01\x94\x88\xd9\xc0\xa0\xa1\xfe\x30\x75\xa5\x77\xe2\x31"
+ "\x83\xf8\x1d\x4a\x3f\x2f\xa4\x57\x1e\xfc\x8c\xe0\xba\x8a\x4f\xe8"
+ "\xb6\x85\x5d\xfe\x72\xb0\xa6\x6e\xde\xd2\xfb\xab\xfb\xe5\x8a\x30"
+ "\xfa\xfa\xbe\x1c\x5d\x71\xa8\x7e\x2f\x74\x1e\xf8\xc1\xfe\x86\xfe"
+ "\xa6\xbb\xfd\xe5\x30\x67\x7f\x0d\x97\xd1\x1d\x49\xf7\xa8\x44\x3d"
+ "\x08\x22\xe5\x06\xa9\xf4\x61\x4e\x01\x1e\x2a\x94\x83\x8f\xf8\x8c"
+ "\xd6\x8c\x8b\xb7\xc5\xc6\x42\x4c\xff\xff\xff\xff\xff\xff\xff\xff",
+};
+
+static int dh_ffdhe2048_create(struct crypto_template *tmpl,
+ struct rtattr **tb)
+{
+ return __dh_safe_prime_create(tmpl, tb, &ffdhe2048_prime);
+}
+
+static int dh_ffdhe3072_create(struct crypto_template *tmpl,
+ struct rtattr **tb)
+{
+ return __dh_safe_prime_create(tmpl, tb, &ffdhe3072_prime);
+}
+
+static int dh_ffdhe4096_create(struct crypto_template *tmpl,
+ struct rtattr **tb)
+{
+ return __dh_safe_prime_create(tmpl, tb, &ffdhe4096_prime);
+}
+
+static int dh_ffdhe6144_create(struct crypto_template *tmpl,
+ struct rtattr **tb)
+{
+ return __dh_safe_prime_create(tmpl, tb, &ffdhe6144_prime);
+}
+
+static int dh_ffdhe8192_create(struct crypto_template *tmpl,
+ struct rtattr **tb)
+{
+ return __dh_safe_prime_create(tmpl, tb, &ffdhe8192_prime);
+}
+
+static struct crypto_template crypto_ffdhe_templates[] = {
+ {
+ .name = "ffdhe2048",
+ .create = dh_ffdhe2048_create,
+ .module = THIS_MODULE,
+ },
+ {
+ .name = "ffdhe3072",
+ .create = dh_ffdhe3072_create,
+ .module = THIS_MODULE,
+ },
+ {
+ .name = "ffdhe4096",
+ .create = dh_ffdhe4096_create,
+ .module = THIS_MODULE,
+ },
+ {
+ .name = "ffdhe6144",
+ .create = dh_ffdhe6144_create,
+ .module = THIS_MODULE,
+ },
+ {
+ .name = "ffdhe8192",
+ .create = dh_ffdhe8192_create,
+ .module = THIS_MODULE,
+ },
+};
+
+#else /* ! CONFIG_CRYPTO_DH_RFC7919_GROUPS */
+
+static struct crypto_template crypto_ffdhe_templates[] = {};
+
+#endif /* CONFIG_CRYPTO_DH_RFC7919_GROUPS */
+
+
+static int __init dh_init(void)
{
- return crypto_register_kpp(&dh);
+ int err;
+
+ err = crypto_register_kpp(&dh);
+ if (err)
+ return err;
+
+ err = crypto_register_templates(crypto_ffdhe_templates,
+ ARRAY_SIZE(crypto_ffdhe_templates));
+ if (err) {
+ crypto_unregister_kpp(&dh);
+ return err;
+ }
+
+ return 0;
}
-static void dh_exit(void)
+static void __exit dh_exit(void)
{
+ crypto_unregister_templates(crypto_ffdhe_templates,
+ ARRAY_SIZE(crypto_ffdhe_templates));
crypto_unregister_kpp(&dh);
}
diff --git a/crypto/dh_helper.c b/crypto/dh_helper.c
index 9fd5a42eea15..2d499879328b 100644
--- a/crypto/dh_helper.c
+++ b/crypto/dh_helper.c
@@ -10,7 +10,7 @@
#include <crypto/dh.h>
#include <crypto/kpp.h>
-#define DH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + 4 * sizeof(int))
+#define DH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + 3 * sizeof(int))
static inline u8 *dh_pack_data(u8 *dst, u8 *end, const void *src, size_t size)
{
@@ -28,7 +28,7 @@ static inline const u8 *dh_unpack_data(void *dst, const void *src, size_t size)
static inline unsigned int dh_data_size(const struct dh *p)
{
- return p->key_size + p->p_size + p->q_size + p->g_size;
+ return p->key_size + p->p_size + p->g_size;
}
unsigned int crypto_dh_key_len(const struct dh *p)
@@ -53,11 +53,9 @@ int crypto_dh_encode_key(char *buf, unsigned int len, const struct dh *params)
ptr = dh_pack_data(ptr, end, &params->key_size,
sizeof(params->key_size));
ptr = dh_pack_data(ptr, end, &params->p_size, sizeof(params->p_size));
- ptr = dh_pack_data(ptr, end, &params->q_size, sizeof(params->q_size));
ptr = dh_pack_data(ptr, end, &params->g_size, sizeof(params->g_size));
ptr = dh_pack_data(ptr, end, params->key, params->key_size);
ptr = dh_pack_data(ptr, end, params->p, params->p_size);
- ptr = dh_pack_data(ptr, end, params->q, params->q_size);
ptr = dh_pack_data(ptr, end, params->g, params->g_size);
if (ptr != end)
return -EINVAL;
@@ -65,7 +63,7 @@ int crypto_dh_encode_key(char *buf, unsigned int len, const struct dh *params)
}
EXPORT_SYMBOL_GPL(crypto_dh_encode_key);
-int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
+int __crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
{
const u8 *ptr = buf;
struct kpp_secret secret;
@@ -79,28 +77,36 @@ int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
ptr = dh_unpack_data(&params->key_size, ptr, sizeof(params->key_size));
ptr = dh_unpack_data(&params->p_size, ptr, sizeof(params->p_size));
- ptr = dh_unpack_data(&params->q_size, ptr, sizeof(params->q_size));
ptr = dh_unpack_data(&params->g_size, ptr, sizeof(params->g_size));
if (secret.len != crypto_dh_key_len(params))
return -EINVAL;
+ /* Don't allocate memory. Set pointers to data within
+ * the given buffer
+ */
+ params->key = (void *)ptr;
+ params->p = (void *)(ptr + params->key_size);
+ params->g = (void *)(ptr + params->key_size + params->p_size);
+
+ return 0;
+}
+
+int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
+{
+ int err;
+
+ err = __crypto_dh_decode_key(buf, len, params);
+ if (err)
+ return err;
+
/*
* Don't permit the buffer for 'key' or 'g' to be larger than 'p', since
* some drivers assume otherwise.
*/
if (params->key_size > params->p_size ||
- params->g_size > params->p_size || params->q_size > params->p_size)
+ params->g_size > params->p_size)
return -EINVAL;
- /* Don't allocate memory. Set pointers to data within
- * the given buffer
- */
- params->key = (void *)ptr;
- params->p = (void *)(ptr + params->key_size);
- params->q = (void *)(ptr + params->key_size + params->p_size);
- params->g = (void *)(ptr + params->key_size + params->p_size +
- params->q_size);
-
/*
* Don't permit 'p' to be 0. It's not a prime number, and it's subject
* to corner cases such as 'mod 0' being undefined or
@@ -109,10 +115,6 @@ int crypto_dh_decode_key(const char *buf, unsigned int len, struct dh *params)
if (memchr_inv(params->p, 0, params->p_size) == NULL)
return -EINVAL;
- /* It is permissible to not provide Q. */
- if (params->q_size == 0)
- params->q = NULL;
-
return 0;
}
EXPORT_SYMBOL_GPL(crypto_dh_decode_key);
diff --git a/crypto/drbg.c b/crypto/drbg.c
index b6929eb5f565..982d4ca4526d 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -98,7 +98,9 @@
*/
#include <crypto/drbg.h>
+#include <crypto/internal/cipher.h>
#include <linux/kernel.h>
+#include <linux/jiffies.h>
/***************************************************************
* Backend cipher definitions available to DRBG
@@ -177,16 +179,16 @@ static const struct drbg_core drbg_cores[] = {
.backend_cra_name = "hmac(sha384)",
}, {
.flags = DRBG_HMAC | DRBG_STRENGTH256,
- .statelen = 64, /* block length of cipher */
- .blocklen_bytes = 64,
- .cra_name = "hmac_sha512",
- .backend_cra_name = "hmac(sha512)",
- }, {
- .flags = DRBG_HMAC | DRBG_STRENGTH256,
.statelen = 32, /* block length of cipher */
.blocklen_bytes = 32,
.cra_name = "hmac_sha256",
.backend_cra_name = "hmac(sha256)",
+ }, {
+ .flags = DRBG_HMAC | DRBG_STRENGTH256,
+ .statelen = 64, /* block length of cipher */
+ .blocklen_bytes = 64,
+ .cra_name = "hmac_sha512",
+ .backend_cra_name = "hmac(sha512)",
},
#endif /* CONFIG_CRYPTO_DRBG_HMAC */
};
@@ -1035,17 +1037,39 @@ static const struct drbg_state_ops drbg_hash_ops = {
******************************************************************/
static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed,
- int reseed)
+ int reseed, enum drbg_seed_state new_seed_state)
{
int ret = drbg->d_ops->update(drbg, seed, reseed);
if (ret)
return ret;
- drbg->seeded = true;
+ drbg->seeded = new_seed_state;
+ drbg->last_seed_time = jiffies;
/* 10.1.1.2 / 10.1.1.3 step 5 */
drbg->reseed_ctr = 1;
+ switch (drbg->seeded) {
+ case DRBG_SEED_STATE_UNSEEDED:
+ /* Impossible, but handle it to silence compiler warnings. */
+ fallthrough;
+ case DRBG_SEED_STATE_PARTIAL:
+ /*
+ * Require frequent reseeds until the seed source is
+ * fully initialized.
+ */
+ drbg->reseed_threshold = 50;
+ break;
+
+ case DRBG_SEED_STATE_FULL:
+ /*
+ * Seed source has become fully initialized, frequent
+ * reseeds no longer required.
+ */
+ drbg->reseed_threshold = drbg_max_requests(drbg);
+ break;
+ }
+
return ret;
}
@@ -1065,12 +1089,10 @@ static inline int drbg_get_random_bytes(struct drbg_state *drbg,
return 0;
}
-static void drbg_async_seed(struct work_struct *work)
+static int drbg_seed_from_random(struct drbg_state *drbg)
{
struct drbg_string data;
LIST_HEAD(seedlist);
- struct drbg_state *drbg = container_of(work, struct drbg_state,
- seed_work);
unsigned int entropylen = drbg_sec_strength(drbg->core->flags);
unsigned char entropy[32];
int ret;
@@ -1081,30 +1103,35 @@ static void drbg_async_seed(struct work_struct *work)
drbg_string_fill(&data, entropy, entropylen);
list_add_tail(&data.list, &seedlist);
- mutex_lock(&drbg->drbg_mutex);
-
ret = drbg_get_random_bytes(drbg, entropy, entropylen);
if (ret)
- goto unlock;
-
- /* If nonblocking pool is initialized, deactivate Jitter RNG */
- crypto_free_rng(drbg->jent);
- drbg->jent = NULL;
+ goto out;
- /* Set seeded to false so that if __drbg_seed fails the
- * next generate call will trigger a reseed.
- */
- drbg->seeded = false;
+ ret = __drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL);
- __drbg_seed(drbg, &seedlist, true);
+out:
+ memzero_explicit(entropy, entropylen);
+ return ret;
+}
- if (drbg->seeded)
- drbg->reseed_threshold = drbg_max_requests(drbg);
+static bool drbg_nopr_reseed_interval_elapsed(struct drbg_state *drbg)
+{
+ unsigned long next_reseed;
-unlock:
- mutex_unlock(&drbg->drbg_mutex);
+ /* Don't ever reseed from get_random_bytes() in test mode. */
+ if (list_empty(&drbg->test_data.list))
+ return false;
- memzero_explicit(entropy, entropylen);
+ /*
+ * Obtain fresh entropy for the nopr DRBGs after 300s have
+ * elapsed in order to still achieve sort of partial
+ * prediction resistance over the time domain at least. Note
+ * that the period of 300s has been chosen to match the
+ * CRNG_RESEED_INTERVAL of the get_random_bytes()' chacha
+ * rngs.
+ */
+ next_reseed = drbg->last_seed_time + 300 * HZ;
+ return time_after(jiffies, next_reseed);
}
/*
@@ -1126,6 +1153,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
unsigned int entropylen = drbg_sec_strength(drbg->core->flags);
struct drbg_string data1;
LIST_HEAD(seedlist);
+ enum drbg_seed_state new_seed_state = DRBG_SEED_STATE_FULL;
/* 9.1 / 9.2 / 9.3.1 step 3 */
if (pers && pers->len > (drbg_max_addtl(drbg))) {
@@ -1153,6 +1181,9 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
BUG_ON((entropylen * 2) > sizeof(entropy));
/* Get seed from in-kernel /dev/urandom */
+ if (!rng_is_initialized())
+ new_seed_state = DRBG_SEED_STATE_PARTIAL;
+
ret = drbg_get_random_bytes(drbg, entropy, entropylen);
if (ret)
goto out;
@@ -1162,13 +1193,32 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
pr_devel("DRBG: (re)seeding with %u bytes of entropy\n",
entropylen);
} else {
- /* Get seed from Jitter RNG */
+ /*
+ * Get seed from Jitter RNG, failures are
+ * fatal only in FIPS mode.
+ */
ret = crypto_rng_get_bytes(drbg->jent,
entropy + entropylen,
entropylen);
- if (ret) {
+ if (fips_enabled && ret) {
pr_devel("DRBG: jent failed with %d\n", ret);
- goto out;
+
+ /*
+ * Do not treat the transient failure of the
+ * Jitter RNG as an error that needs to be
+ * reported. The combined number of the
+ * maximum reseed threshold times the maximum
+ * number of Jitter RNG transient errors is
+ * less than the reseed threshold required by
+ * SP800-90A allowing us to treat the
+ * transient errors as such.
+ *
+ * However, we mandate that at least the first
+ * seeding operation must succeed with the
+ * Jitter RNG.
+ */
+ if (!reseed || ret != -EAGAIN)
+ goto out;
}
drbg_string_fill(&data1, entropy, entropylen * 2);
@@ -1193,7 +1243,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
memset(drbg->C, 0, drbg_statelen(drbg));
}
- ret = __drbg_seed(drbg, &seedlist, reseed);
+ ret = __drbg_seed(drbg, &seedlist, reseed, new_seed_state);
out:
memzero_explicit(entropy, entropylen * 2);
@@ -1206,19 +1256,19 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg)
{
if (!drbg)
return;
- kzfree(drbg->Vbuf);
+ kfree_sensitive(drbg->Vbuf);
drbg->Vbuf = NULL;
drbg->V = NULL;
- kzfree(drbg->Cbuf);
+ kfree_sensitive(drbg->Cbuf);
drbg->Cbuf = NULL;
drbg->C = NULL;
- kzfree(drbg->scratchpadbuf);
+ kfree_sensitive(drbg->scratchpadbuf);
drbg->scratchpadbuf = NULL;
drbg->reseed_ctr = 0;
drbg->d_ops = NULL;
drbg->core = NULL;
if (IS_ENABLED(CONFIG_CRYPTO_FIPS)) {
- kzfree(drbg->prev);
+ kfree_sensitive(drbg->prev);
drbg->prev = NULL;
drbg->fips_primed = false;
}
@@ -1294,8 +1344,10 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
if (IS_ENABLED(CONFIG_CRYPTO_FIPS)) {
drbg->prev = kzalloc(drbg_sec_strength(drbg->core->flags),
GFP_KERNEL);
- if (!drbg->prev)
+ if (!drbg->prev) {
+ ret = -ENOMEM;
goto fini;
+ }
drbg->fips_primed = false;
}
@@ -1371,19 +1423,26 @@ static int drbg_generate(struct drbg_state *drbg,
* here. The spec is a bit convoluted here, we make it simpler.
*/
if (drbg->reseed_threshold < drbg->reseed_ctr)
- drbg->seeded = false;
+ drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
- if (drbg->pr || !drbg->seeded) {
+ if (drbg->pr || drbg->seeded == DRBG_SEED_STATE_UNSEEDED) {
pr_devel("DRBG: reseeding before generation (prediction "
"resistance: %s, state %s)\n",
drbg->pr ? "true" : "false",
- drbg->seeded ? "seeded" : "unseeded");
+ (drbg->seeded == DRBG_SEED_STATE_FULL ?
+ "seeded" : "unseeded"));
/* 9.3.1 steps 7.1 through 7.3 */
len = drbg_seed(drbg, addtl, true);
if (len)
goto err;
/* 9.3.1 step 7.4 */
addtl = NULL;
+ } else if (rng_is_initialized() &&
+ (drbg->seeded == DRBG_SEED_STATE_PARTIAL ||
+ drbg_nopr_reseed_interval_elapsed(drbg))) {
+ len = drbg_seed_from_random(drbg);
+ if (len)
+ goto err;
}
if (addtl && 0 < addtl->len)
@@ -1476,51 +1535,23 @@ static int drbg_generate_long(struct drbg_state *drbg,
return 0;
}
-static void drbg_schedule_async_seed(struct random_ready_callback *rdy)
-{
- struct drbg_state *drbg = container_of(rdy, struct drbg_state,
- random_ready);
-
- schedule_work(&drbg->seed_work);
-}
-
static int drbg_prepare_hrng(struct drbg_state *drbg)
{
- int err;
-
/* We do not need an HRNG in test mode. */
if (list_empty(&drbg->test_data.list))
return 0;
- INIT_WORK(&drbg->seed_work, drbg_async_seed);
-
- drbg->random_ready.owner = THIS_MODULE;
- drbg->random_ready.func = drbg_schedule_async_seed;
-
- err = add_random_ready_callback(&drbg->random_ready);
-
- switch (err) {
- case 0:
- break;
-
- case -EALREADY:
- err = 0;
- /* fall through */
-
- default:
- drbg->random_ready.func = NULL;
- return err;
- }
-
drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0);
+ if (IS_ERR(drbg->jent)) {
+ const int err = PTR_ERR(drbg->jent);
- /*
- * Require frequent reseeds until the seed source is fully
- * initialized.
- */
- drbg->reseed_threshold = 50;
+ drbg->jent = NULL;
+ if (fips_enabled || err != -ENOENT)
+ return err;
+ pr_info("DRBG: Continuing without Jitter RNG\n");
+ }
- return err;
+ return 0;
}
/*
@@ -1563,7 +1594,8 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
if (!drbg->core) {
drbg->core = &drbg_cores[coreref];
drbg->pr = pr;
- drbg->seeded = false;
+ drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
+ drbg->last_seed_time = 0;
drbg->reseed_threshold = drbg_max_requests(drbg);
ret = drbg_alloc_state(drbg);
@@ -1574,14 +1606,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
if (ret)
goto free_everything;
- if (IS_ERR(drbg->jent)) {
- ret = PTR_ERR(drbg->jent);
- drbg->jent = NULL;
- if (fips_enabled || ret != -ENOENT)
- goto free_everything;
- pr_info("DRBG: Continuing without Jitter RNG\n");
- }
-
reseed = false;
}
@@ -1614,12 +1638,9 @@ free_everything:
*/
static int drbg_uninstantiate(struct drbg_state *drbg)
{
- if (drbg->random_ready.func) {
- del_random_ready_callback(&drbg->random_ready);
- cancel_work_sync(&drbg->seed_work);
+ if (!IS_ERR_OR_NULL(drbg->jent))
crypto_free_rng(drbg->jent);
- drbg->jent = NULL;
- }
+ drbg->jent = NULL;
if (drbg->d_ops)
drbg->d_ops->crypto_fini(drbg);
@@ -1682,10 +1703,10 @@ static int drbg_init_hash_kernel(struct drbg_state *drbg)
static int drbg_fini_hash_kernel(struct drbg_state *drbg)
{
- struct sdesc *sdesc = (struct sdesc *)drbg->priv_data;
+ struct sdesc *sdesc = drbg->priv_data;
if (sdesc) {
crypto_free_shash(sdesc->shash.tfm);
- kzfree(sdesc);
+ kfree_sensitive(sdesc);
}
drbg->priv_data = NULL;
return 0;
@@ -1694,7 +1715,7 @@ static int drbg_fini_hash_kernel(struct drbg_state *drbg)
static void drbg_kcapi_hmacsetkey(struct drbg_state *drbg,
const unsigned char *key)
{
- struct sdesc *sdesc = (struct sdesc *)drbg->priv_data;
+ struct sdesc *sdesc = drbg->priv_data;
crypto_shash_setkey(sdesc->shash.tfm, key, drbg_statelen(drbg));
}
@@ -1702,7 +1723,7 @@ static void drbg_kcapi_hmacsetkey(struct drbg_state *drbg,
static int drbg_kcapi_hash(struct drbg_state *drbg, unsigned char *outval,
const struct list_head *in)
{
- struct sdesc *sdesc = (struct sdesc *)drbg->priv_data;
+ struct sdesc *sdesc = drbg->priv_data;
struct drbg_string *input = NULL;
crypto_shash_init(&sdesc->shash);
@@ -1797,8 +1818,7 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg)
static void drbg_kcapi_symsetkey(struct drbg_state *drbg,
const unsigned char *key)
{
- struct crypto_cipher *tfm =
- (struct crypto_cipher *)drbg->priv_data;
+ struct crypto_cipher *tfm = drbg->priv_data;
crypto_cipher_setkey(tfm, key, (drbg_keylen(drbg)));
}
@@ -1806,8 +1826,7 @@ static void drbg_kcapi_symsetkey(struct drbg_state *drbg,
static int drbg_kcapi_sym(struct drbg_state *drbg, unsigned char *outval,
const struct drbg_string *in)
{
- struct crypto_cipher *tfm =
- (struct crypto_cipher *)drbg->priv_data;
+ struct crypto_cipher *tfm = drbg->priv_data;
/* there is only component in *in */
BUG_ON(in->len < drbg_blocklen(drbg));
@@ -1986,7 +2005,7 @@ static inline int __init drbg_healthcheck_sanity(void)
#define OUTBUFLEN 16
unsigned char buf[OUTBUFLEN];
struct drbg_state *drbg = NULL;
- int ret = -EFAULT;
+ int ret;
int rc = -EFAULT;
bool pr = false;
int coreref = 0;
@@ -2145,3 +2164,4 @@ MODULE_DESCRIPTION("NIST SP800-90A Deterministic Random Bit Generator (DRBG) "
CRYPTO_DRBG_HMAC_STRING
CRYPTO_DRBG_CTR_STRING);
MODULE_ALIAS_CRYPTO("stdrng");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/ecb.c b/crypto/ecb.c
index 69a687cbdf21..71fbb0543d64 100644
--- a/crypto/ecb.c
+++ b/crypto/ecb.c
@@ -6,6 +6,7 @@
*/
#include <crypto/algapi.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/skcipher.h>
#include <linux/err.h>
#include <linux/init.h>
diff --git a/crypto/ecc.c b/crypto/ecc.c
index 02d35be7702b..7315217c8f73 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <crypto/ecc_curve.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/slab.h>
@@ -31,10 +32,10 @@
#include <linux/fips.h>
#include <crypto/ecdh.h>
#include <crypto/rng.h>
+#include <crypto/internal/ecc.h>
#include <asm/unaligned.h>
#include <linux/ratelimit.h>
-#include "ecc.h"
#include "ecc_curve_defs.h"
typedef struct {
@@ -42,7 +43,14 @@ typedef struct {
u64 m_high;
} uint128_t;
-static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
+/* Returns curv25519 curve param */
+const struct ecc_curve *ecc_get_curve25519(void)
+{
+ return &ecc_25519;
+}
+EXPORT_SYMBOL(ecc_get_curve25519);
+
+const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
{
switch (curve_id) {
/* In FIPS mode only allow P256 and higher */
@@ -50,10 +58,13 @@ static inline const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
return fips_enabled ? NULL : &nist_p192;
case ECC_CURVE_NIST_P256:
return &nist_p256;
+ case ECC_CURVE_NIST_P384:
+ return &nist_p384;
default:
return NULL;
}
}
+EXPORT_SYMBOL(ecc_get_curve);
static u64 *ecc_alloc_digits_space(unsigned int ndigits)
{
@@ -67,10 +78,10 @@ static u64 *ecc_alloc_digits_space(unsigned int ndigits)
static void ecc_free_digits_space(u64 *space)
{
- kzfree(space);
+ kfree_sensitive(space);
}
-static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
+struct ecc_point *ecc_alloc_point(unsigned int ndigits)
{
struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL);
@@ -95,16 +106,18 @@ err_alloc_x:
kfree(p);
return NULL;
}
+EXPORT_SYMBOL(ecc_alloc_point);
-static void ecc_free_point(struct ecc_point *p)
+void ecc_free_point(struct ecc_point *p)
{
if (!p)
return;
- kzfree(p->x);
- kzfree(p->y);
- kzfree(p);
+ kfree_sensitive(p->x);
+ kfree_sensitive(p->y);
+ kfree_sensitive(p);
}
+EXPORT_SYMBOL(ecc_free_point);
static void vli_clear(u64 *vli, unsigned int ndigits)
{
@@ -128,7 +141,7 @@ bool vli_is_zero(const u64 *vli, unsigned int ndigits)
}
EXPORT_SYMBOL(vli_is_zero);
-/* Returns nonzero if bit bit of vli is set. */
+/* Returns nonzero if bit of vli is set. */
static u64 vli_test_bit(const u64 *vli, unsigned int bit)
{
return (vli[bit / 64] & ((u64)1 << (bit % 64)));
@@ -154,7 +167,7 @@ static unsigned int vli_num_digits(const u64 *vli, unsigned int ndigits)
}
/* Counts the number of bits required for vli. */
-static unsigned int vli_num_bits(const u64 *vli, unsigned int ndigits)
+unsigned int vli_num_bits(const u64 *vli, unsigned int ndigits)
{
unsigned int i, num_digits;
u64 digit;
@@ -169,6 +182,7 @@ static unsigned int vli_num_bits(const u64 *vli, unsigned int ndigits)
return ((num_digits - 1) * 64 + i);
}
+EXPORT_SYMBOL(vli_num_bits);
/* Set dest from unaligned bit string src. */
void vli_from_be64(u64 *dest, const void *src, unsigned int ndigits)
@@ -775,18 +789,133 @@ static void vli_mmod_fast_256(u64 *result, const u64 *product,
}
}
+#define SL32OR32(x32, y32) (((u64)x32 << 32) | y32)
+#define AND64H(x64) (x64 & 0xffFFffFF00000000ull)
+#define AND64L(x64) (x64 & 0x00000000ffFFffFFull)
+
+/* Computes result = product % curve_prime
+ * from "Mathematical routines for the NIST prime elliptic curves"
+ */
+static void vli_mmod_fast_384(u64 *result, const u64 *product,
+ const u64 *curve_prime, u64 *tmp)
+{
+ int carry;
+ const unsigned int ndigits = 6;
+
+ /* t */
+ vli_set(result, product, ndigits);
+
+ /* s1 */
+ tmp[0] = 0; // 0 || 0
+ tmp[1] = 0; // 0 || 0
+ tmp[2] = SL32OR32(product[11], (product[10]>>32)); //a22||a21
+ tmp[3] = product[11]>>32; // 0 ||a23
+ tmp[4] = 0; // 0 || 0
+ tmp[5] = 0; // 0 || 0
+ carry = vli_lshift(tmp, tmp, 1, ndigits);
+ carry += vli_add(result, result, tmp, ndigits);
+
+ /* s2 */
+ tmp[0] = product[6]; //a13||a12
+ tmp[1] = product[7]; //a15||a14
+ tmp[2] = product[8]; //a17||a16
+ tmp[3] = product[9]; //a19||a18
+ tmp[4] = product[10]; //a21||a20
+ tmp[5] = product[11]; //a23||a22
+ carry += vli_add(result, result, tmp, ndigits);
+
+ /* s3 */
+ tmp[0] = SL32OR32(product[11], (product[10]>>32)); //a22||a21
+ tmp[1] = SL32OR32(product[6], (product[11]>>32)); //a12||a23
+ tmp[2] = SL32OR32(product[7], (product[6])>>32); //a14||a13
+ tmp[3] = SL32OR32(product[8], (product[7]>>32)); //a16||a15
+ tmp[4] = SL32OR32(product[9], (product[8]>>32)); //a18||a17
+ tmp[5] = SL32OR32(product[10], (product[9]>>32)); //a20||a19
+ carry += vli_add(result, result, tmp, ndigits);
+
+ /* s4 */
+ tmp[0] = AND64H(product[11]); //a23|| 0
+ tmp[1] = (product[10]<<32); //a20|| 0
+ tmp[2] = product[6]; //a13||a12
+ tmp[3] = product[7]; //a15||a14
+ tmp[4] = product[8]; //a17||a16
+ tmp[5] = product[9]; //a19||a18
+ carry += vli_add(result, result, tmp, ndigits);
+
+ /* s5 */
+ tmp[0] = 0; // 0|| 0
+ tmp[1] = 0; // 0|| 0
+ tmp[2] = product[10]; //a21||a20
+ tmp[3] = product[11]; //a23||a22
+ tmp[4] = 0; // 0|| 0
+ tmp[5] = 0; // 0|| 0
+ carry += vli_add(result, result, tmp, ndigits);
+
+ /* s6 */
+ tmp[0] = AND64L(product[10]); // 0 ||a20
+ tmp[1] = AND64H(product[10]); //a21|| 0
+ tmp[2] = product[11]; //a23||a22
+ tmp[3] = 0; // 0 || 0
+ tmp[4] = 0; // 0 || 0
+ tmp[5] = 0; // 0 || 0
+ carry += vli_add(result, result, tmp, ndigits);
+
+ /* d1 */
+ tmp[0] = SL32OR32(product[6], (product[11]>>32)); //a12||a23
+ tmp[1] = SL32OR32(product[7], (product[6]>>32)); //a14||a13
+ tmp[2] = SL32OR32(product[8], (product[7]>>32)); //a16||a15
+ tmp[3] = SL32OR32(product[9], (product[8]>>32)); //a18||a17
+ tmp[4] = SL32OR32(product[10], (product[9]>>32)); //a20||a19
+ tmp[5] = SL32OR32(product[11], (product[10]>>32)); //a22||a21
+ carry -= vli_sub(result, result, tmp, ndigits);
+
+ /* d2 */
+ tmp[0] = (product[10]<<32); //a20|| 0
+ tmp[1] = SL32OR32(product[11], (product[10]>>32)); //a22||a21
+ tmp[2] = (product[11]>>32); // 0 ||a23
+ tmp[3] = 0; // 0 || 0
+ tmp[4] = 0; // 0 || 0
+ tmp[5] = 0; // 0 || 0
+ carry -= vli_sub(result, result, tmp, ndigits);
+
+ /* d3 */
+ tmp[0] = 0; // 0 || 0
+ tmp[1] = AND64H(product[11]); //a23|| 0
+ tmp[2] = product[11]>>32; // 0 ||a23
+ tmp[3] = 0; // 0 || 0
+ tmp[4] = 0; // 0 || 0
+ tmp[5] = 0; // 0 || 0
+ carry -= vli_sub(result, result, tmp, ndigits);
+
+ if (carry < 0) {
+ do {
+ carry += vli_add(result, result, curve_prime, ndigits);
+ } while (carry < 0);
+ } else {
+ while (carry || vli_cmp(curve_prime, result, ndigits) != 1)
+ carry -= vli_sub(result, result, curve_prime, ndigits);
+ }
+
+}
+
+#undef SL32OR32
+#undef AND64H
+#undef AND64L
+
/* Computes result = product % curve_prime for different curve_primes.
*
* Note that curve_primes are distinguished just by heuristic check and
* not by complete conformance check.
*/
static bool vli_mmod_fast(u64 *result, u64 *product,
- const u64 *curve_prime, unsigned int ndigits)
+ const struct ecc_curve *curve)
{
u64 tmp[2 * ECC_MAX_DIGITS];
+ const u64 *curve_prime = curve->p;
+ const unsigned int ndigits = curve->g.ndigits;
- /* Currently, both NIST primes have -1 in lowest qword. */
- if (curve_prime[0] != -1ull) {
+ /* All NIST curves have name prefix 'nist_' */
+ if (strncmp(curve->name, "nist_", 5) != 0) {
/* Try to handle Pseudo-Marsenne primes. */
if (curve_prime[ndigits - 1] == -1ull) {
vli_mmod_special(result, product, curve_prime,
@@ -809,6 +938,9 @@ static bool vli_mmod_fast(u64 *result, u64 *product,
case 4:
vli_mmod_fast_256(result, product, curve_prime, tmp);
break;
+ case 6:
+ vli_mmod_fast_384(result, product, curve_prime, tmp);
+ break;
default:
pr_err_ratelimited("ecc: unsupported digits size!\n");
return false;
@@ -832,22 +964,22 @@ EXPORT_SYMBOL(vli_mod_mult_slow);
/* Computes result = (left * right) % curve_prime. */
static void vli_mod_mult_fast(u64 *result, const u64 *left, const u64 *right,
- const u64 *curve_prime, unsigned int ndigits)
+ const struct ecc_curve *curve)
{
u64 product[2 * ECC_MAX_DIGITS];
- vli_mult(product, left, right, ndigits);
- vli_mmod_fast(result, product, curve_prime, ndigits);
+ vli_mult(product, left, right, curve->g.ndigits);
+ vli_mmod_fast(result, product, curve);
}
/* Computes result = left^2 % curve_prime. */
static void vli_mod_square_fast(u64 *result, const u64 *left,
- const u64 *curve_prime, unsigned int ndigits)
+ const struct ecc_curve *curve)
{
u64 product[2 * ECC_MAX_DIGITS];
- vli_square(product, left, ndigits);
- vli_mmod_fast(result, product, curve_prime, ndigits);
+ vli_square(product, left, curve->g.ndigits);
+ vli_mmod_fast(result, product, curve);
}
#define EVEN(vli) (!(vli[0] & 1))
@@ -933,37 +1065,40 @@ EXPORT_SYMBOL(vli_mod_inv);
/* ------ Point operations ------ */
/* Returns true if p_point is the point at infinity, false otherwise. */
-static bool ecc_point_is_zero(const struct ecc_point *point)
+bool ecc_point_is_zero(const struct ecc_point *point)
{
return (vli_is_zero(point->x, point->ndigits) &&
vli_is_zero(point->y, point->ndigits));
}
+EXPORT_SYMBOL(ecc_point_is_zero);
/* Point multiplication algorithm using Montgomery's ladder with co-Z
- * coordinates. From http://eprint.iacr.org/2011/338.pdf
+ * coordinates. From https://eprint.iacr.org/2011/338.pdf
*/
/* Double in place */
static void ecc_point_double_jacobian(u64 *x1, u64 *y1, u64 *z1,
- u64 *curve_prime, unsigned int ndigits)
+ const struct ecc_curve *curve)
{
/* t1 = x, t2 = y, t3 = z */
u64 t4[ECC_MAX_DIGITS];
u64 t5[ECC_MAX_DIGITS];
+ const u64 *curve_prime = curve->p;
+ const unsigned int ndigits = curve->g.ndigits;
if (vli_is_zero(z1, ndigits))
return;
/* t4 = y1^2 */
- vli_mod_square_fast(t4, y1, curve_prime, ndigits);
+ vli_mod_square_fast(t4, y1, curve);
/* t5 = x1*y1^2 = A */
- vli_mod_mult_fast(t5, x1, t4, curve_prime, ndigits);
+ vli_mod_mult_fast(t5, x1, t4, curve);
/* t4 = y1^4 */
- vli_mod_square_fast(t4, t4, curve_prime, ndigits);
+ vli_mod_square_fast(t4, t4, curve);
/* t2 = y1*z1 = z3 */
- vli_mod_mult_fast(y1, y1, z1, curve_prime, ndigits);
+ vli_mod_mult_fast(y1, y1, z1, curve);
/* t3 = z1^2 */
- vli_mod_square_fast(z1, z1, curve_prime, ndigits);
+ vli_mod_square_fast(z1, z1, curve);
/* t1 = x1 + z1^2 */
vli_mod_add(x1, x1, z1, curve_prime, ndigits);
@@ -972,7 +1107,7 @@ static void ecc_point_double_jacobian(u64 *x1, u64 *y1, u64 *z1,
/* t3 = x1 - z1^2 */
vli_mod_sub(z1, x1, z1, curve_prime, ndigits);
/* t1 = x1^2 - z1^4 */
- vli_mod_mult_fast(x1, x1, z1, curve_prime, ndigits);
+ vli_mod_mult_fast(x1, x1, z1, curve);
/* t3 = 2*(x1^2 - z1^4) */
vli_mod_add(z1, x1, x1, curve_prime, ndigits);
@@ -989,7 +1124,7 @@ static void ecc_point_double_jacobian(u64 *x1, u64 *y1, u64 *z1,
/* t1 = 3/2*(x1^2 - z1^4) = B */
/* t3 = B^2 */
- vli_mod_square_fast(z1, x1, curve_prime, ndigits);
+ vli_mod_square_fast(z1, x1, curve);
/* t3 = B^2 - A */
vli_mod_sub(z1, z1, t5, curve_prime, ndigits);
/* t3 = B^2 - 2A = x3 */
@@ -997,7 +1132,7 @@ static void ecc_point_double_jacobian(u64 *x1, u64 *y1, u64 *z1,
/* t5 = A - x3 */
vli_mod_sub(t5, t5, z1, curve_prime, ndigits);
/* t1 = B * (A - x3) */
- vli_mod_mult_fast(x1, x1, t5, curve_prime, ndigits);
+ vli_mod_mult_fast(x1, x1, t5, curve);
/* t4 = B * (A - x3) - y1^4 = y3 */
vli_mod_sub(t4, x1, t4, curve_prime, ndigits);
@@ -1007,23 +1142,22 @@ static void ecc_point_double_jacobian(u64 *x1, u64 *y1, u64 *z1,
}
/* Modify (x1, y1) => (x1 * z^2, y1 * z^3) */
-static void apply_z(u64 *x1, u64 *y1, u64 *z, u64 *curve_prime,
- unsigned int ndigits)
+static void apply_z(u64 *x1, u64 *y1, u64 *z, const struct ecc_curve *curve)
{
u64 t1[ECC_MAX_DIGITS];
- vli_mod_square_fast(t1, z, curve_prime, ndigits); /* z^2 */
- vli_mod_mult_fast(x1, x1, t1, curve_prime, ndigits); /* x1 * z^2 */
- vli_mod_mult_fast(t1, t1, z, curve_prime, ndigits); /* z^3 */
- vli_mod_mult_fast(y1, y1, t1, curve_prime, ndigits); /* y1 * z^3 */
+ vli_mod_square_fast(t1, z, curve); /* z^2 */
+ vli_mod_mult_fast(x1, x1, t1, curve); /* x1 * z^2 */
+ vli_mod_mult_fast(t1, t1, z, curve); /* z^3 */
+ vli_mod_mult_fast(y1, y1, t1, curve); /* y1 * z^3 */
}
/* P = (x1, y1) => 2P, (x2, y2) => P' */
static void xycz_initial_double(u64 *x1, u64 *y1, u64 *x2, u64 *y2,
- u64 *p_initial_z, u64 *curve_prime,
- unsigned int ndigits)
+ u64 *p_initial_z, const struct ecc_curve *curve)
{
u64 z[ECC_MAX_DIGITS];
+ const unsigned int ndigits = curve->g.ndigits;
vli_set(x2, x1, ndigits);
vli_set(y2, y1, ndigits);
@@ -1034,35 +1168,37 @@ static void xycz_initial_double(u64 *x1, u64 *y1, u64 *x2, u64 *y2,
if (p_initial_z)
vli_set(z, p_initial_z, ndigits);
- apply_z(x1, y1, z, curve_prime, ndigits);
+ apply_z(x1, y1, z, curve);
- ecc_point_double_jacobian(x1, y1, z, curve_prime, ndigits);
+ ecc_point_double_jacobian(x1, y1, z, curve);
- apply_z(x2, y2, z, curve_prime, ndigits);
+ apply_z(x2, y2, z, curve);
}
/* Input P = (x1, y1, Z), Q = (x2, y2, Z)
* Output P' = (x1', y1', Z3), P + Q = (x3, y3, Z3)
* or P => P', Q => P + Q
*/
-static void xycz_add(u64 *x1, u64 *y1, u64 *x2, u64 *y2, u64 *curve_prime,
- unsigned int ndigits)
+static void xycz_add(u64 *x1, u64 *y1, u64 *x2, u64 *y2,
+ const struct ecc_curve *curve)
{
/* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
u64 t5[ECC_MAX_DIGITS];
+ const u64 *curve_prime = curve->p;
+ const unsigned int ndigits = curve->g.ndigits;
/* t5 = x2 - x1 */
vli_mod_sub(t5, x2, x1, curve_prime, ndigits);
/* t5 = (x2 - x1)^2 = A */
- vli_mod_square_fast(t5, t5, curve_prime, ndigits);
+ vli_mod_square_fast(t5, t5, curve);
/* t1 = x1*A = B */
- vli_mod_mult_fast(x1, x1, t5, curve_prime, ndigits);
+ vli_mod_mult_fast(x1, x1, t5, curve);
/* t3 = x2*A = C */
- vli_mod_mult_fast(x2, x2, t5, curve_prime, ndigits);
+ vli_mod_mult_fast(x2, x2, t5, curve);
/* t4 = y2 - y1 */
vli_mod_sub(y2, y2, y1, curve_prime, ndigits);
/* t5 = (y2 - y1)^2 = D */
- vli_mod_square_fast(t5, y2, curve_prime, ndigits);
+ vli_mod_square_fast(t5, y2, curve);
/* t5 = D - B */
vli_mod_sub(t5, t5, x1, curve_prime, ndigits);
@@ -1071,11 +1207,11 @@ static void xycz_add(u64 *x1, u64 *y1, u64 *x2, u64 *y2, u64 *curve_prime,
/* t3 = C - B */
vli_mod_sub(x2, x2, x1, curve_prime, ndigits);
/* t2 = y1*(C - B) */
- vli_mod_mult_fast(y1, y1, x2, curve_prime, ndigits);
+ vli_mod_mult_fast(y1, y1, x2, curve);
/* t3 = B - x3 */
vli_mod_sub(x2, x1, t5, curve_prime, ndigits);
/* t4 = (y2 - y1)*(B - x3) */
- vli_mod_mult_fast(y2, y2, x2, curve_prime, ndigits);
+ vli_mod_mult_fast(y2, y2, x2, curve);
/* t4 = y3 */
vli_mod_sub(y2, y2, y1, curve_prime, ndigits);
@@ -1086,22 +1222,24 @@ static void xycz_add(u64 *x1, u64 *y1, u64 *x2, u64 *y2, u64 *curve_prime,
* Output P + Q = (x3, y3, Z3), P - Q = (x3', y3', Z3)
* or P => P - Q, Q => P + Q
*/
-static void xycz_add_c(u64 *x1, u64 *y1, u64 *x2, u64 *y2, u64 *curve_prime,
- unsigned int ndigits)
+static void xycz_add_c(u64 *x1, u64 *y1, u64 *x2, u64 *y2,
+ const struct ecc_curve *curve)
{
/* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
u64 t5[ECC_MAX_DIGITS];
u64 t6[ECC_MAX_DIGITS];
u64 t7[ECC_MAX_DIGITS];
+ const u64 *curve_prime = curve->p;
+ const unsigned int ndigits = curve->g.ndigits;
/* t5 = x2 - x1 */
vli_mod_sub(t5, x2, x1, curve_prime, ndigits);
/* t5 = (x2 - x1)^2 = A */
- vli_mod_square_fast(t5, t5, curve_prime, ndigits);
+ vli_mod_square_fast(t5, t5, curve);
/* t1 = x1*A = B */
- vli_mod_mult_fast(x1, x1, t5, curve_prime, ndigits);
+ vli_mod_mult_fast(x1, x1, t5, curve);
/* t3 = x2*A = C */
- vli_mod_mult_fast(x2, x2, t5, curve_prime, ndigits);
+ vli_mod_mult_fast(x2, x2, t5, curve);
/* t4 = y2 + y1 */
vli_mod_add(t5, y2, y1, curve_prime, ndigits);
/* t4 = y2 - y1 */
@@ -1110,29 +1248,29 @@ static void xycz_add_c(u64 *x1, u64 *y1, u64 *x2, u64 *y2, u64 *curve_prime,
/* t6 = C - B */
vli_mod_sub(t6, x2, x1, curve_prime, ndigits);
/* t2 = y1 * (C - B) */
- vli_mod_mult_fast(y1, y1, t6, curve_prime, ndigits);
+ vli_mod_mult_fast(y1, y1, t6, curve);
/* t6 = B + C */
vli_mod_add(t6, x1, x2, curve_prime, ndigits);
/* t3 = (y2 - y1)^2 */
- vli_mod_square_fast(x2, y2, curve_prime, ndigits);
+ vli_mod_square_fast(x2, y2, curve);
/* t3 = x3 */
vli_mod_sub(x2, x2, t6, curve_prime, ndigits);
/* t7 = B - x3 */
vli_mod_sub(t7, x1, x2, curve_prime, ndigits);
/* t4 = (y2 - y1)*(B - x3) */
- vli_mod_mult_fast(y2, y2, t7, curve_prime, ndigits);
+ vli_mod_mult_fast(y2, y2, t7, curve);
/* t4 = y3 */
vli_mod_sub(y2, y2, y1, curve_prime, ndigits);
/* t7 = (y2 + y1)^2 = F */
- vli_mod_square_fast(t7, t5, curve_prime, ndigits);
+ vli_mod_square_fast(t7, t5, curve);
/* t7 = x3' */
vli_mod_sub(t7, t7, t6, curve_prime, ndigits);
/* t6 = x3' - B */
vli_mod_sub(t6, t7, x1, curve_prime, ndigits);
/* t6 = (y2 + y1)*(x3' - B) */
- vli_mod_mult_fast(t6, t6, t5, curve_prime, ndigits);
+ vli_mod_mult_fast(t6, t6, t5, curve);
/* t2 = y3' */
vli_mod_sub(y1, t6, y1, curve_prime, ndigits);
@@ -1162,41 +1300,37 @@ static void ecc_point_mult(struct ecc_point *result,
vli_set(rx[1], point->x, ndigits);
vli_set(ry[1], point->y, ndigits);
- xycz_initial_double(rx[1], ry[1], rx[0], ry[0], initial_z, curve_prime,
- ndigits);
+ xycz_initial_double(rx[1], ry[1], rx[0], ry[0], initial_z, curve);
for (i = num_bits - 2; i > 0; i--) {
nb = !vli_test_bit(scalar, i);
- xycz_add_c(rx[1 - nb], ry[1 - nb], rx[nb], ry[nb], curve_prime,
- ndigits);
- xycz_add(rx[nb], ry[nb], rx[1 - nb], ry[1 - nb], curve_prime,
- ndigits);
+ xycz_add_c(rx[1 - nb], ry[1 - nb], rx[nb], ry[nb], curve);
+ xycz_add(rx[nb], ry[nb], rx[1 - nb], ry[1 - nb], curve);
}
nb = !vli_test_bit(scalar, 0);
- xycz_add_c(rx[1 - nb], ry[1 - nb], rx[nb], ry[nb], curve_prime,
- ndigits);
+ xycz_add_c(rx[1 - nb], ry[1 - nb], rx[nb], ry[nb], curve);
/* Find final 1/Z value. */
/* X1 - X0 */
vli_mod_sub(z, rx[1], rx[0], curve_prime, ndigits);
/* Yb * (X1 - X0) */
- vli_mod_mult_fast(z, z, ry[1 - nb], curve_prime, ndigits);
+ vli_mod_mult_fast(z, z, ry[1 - nb], curve);
/* xP * Yb * (X1 - X0) */
- vli_mod_mult_fast(z, z, point->x, curve_prime, ndigits);
+ vli_mod_mult_fast(z, z, point->x, curve);
/* 1 / (xP * Yb * (X1 - X0)) */
vli_mod_inv(z, z, curve_prime, point->ndigits);
/* yP / (xP * Yb * (X1 - X0)) */
- vli_mod_mult_fast(z, z, point->y, curve_prime, ndigits);
+ vli_mod_mult_fast(z, z, point->y, curve);
/* Xb * yP / (xP * Yb * (X1 - X0)) */
- vli_mod_mult_fast(z, z, rx[1 - nb], curve_prime, ndigits);
+ vli_mod_mult_fast(z, z, rx[1 - nb], curve);
/* End 1/Z calculation */
- xycz_add(rx[nb], ry[nb], rx[1 - nb], ry[1 - nb], curve_prime, ndigits);
+ xycz_add(rx[nb], ry[nb], rx[1 - nb], ry[1 - nb], curve);
- apply_z(rx[0], ry[0], z, curve_prime, ndigits);
+ apply_z(rx[0], ry[0], z, curve);
vli_set(result->x, rx[0], ndigits);
vli_set(result->y, ry[0], ndigits);
@@ -1217,9 +1351,9 @@ static void ecc_point_add(const struct ecc_point *result,
vli_mod_sub(z, result->x, p->x, curve->p, ndigits);
vli_set(px, p->x, ndigits);
vli_set(py, p->y, ndigits);
- xycz_add(px, py, result->x, result->y, curve->p, ndigits);
+ xycz_add(px, py, result->x, result->y, curve);
vli_mod_inv(z, z, curve->p, ndigits);
- apply_z(result->x, result->y, z, curve->p, ndigits);
+ apply_z(result->x, result->y, z, curve);
}
/* Computes R = u1P + u2Q mod p using Shamir's trick.
@@ -1248,8 +1382,7 @@ void ecc_point_mult_shamir(const struct ecc_point *result,
points[2] = q;
points[3] = &sum;
- num_bits = max(vli_num_bits(u1, ndigits),
- vli_num_bits(u2, ndigits));
+ num_bits = max(vli_num_bits(u1, ndigits), vli_num_bits(u2, ndigits));
i = num_bits - 1;
idx = (!!vli_test_bit(u1, i)) | ((!!vli_test_bit(u2, i)) << 1);
point = points[idx];
@@ -1260,7 +1393,7 @@ void ecc_point_mult_shamir(const struct ecc_point *result,
z[0] = 1;
for (--i; i >= 0; i--) {
- ecc_point_double_jacobian(rx, ry, z, curve->p, ndigits);
+ ecc_point_double_jacobian(rx, ry, z, curve);
idx = (!!vli_test_bit(u1, i)) | ((!!vli_test_bit(u2, i)) << 1);
point = points[idx];
if (point) {
@@ -1270,27 +1403,17 @@ void ecc_point_mult_shamir(const struct ecc_point *result,
vli_set(tx, point->x, ndigits);
vli_set(ty, point->y, ndigits);
- apply_z(tx, ty, z, curve->p, ndigits);
+ apply_z(tx, ty, z, curve);
vli_mod_sub(tz, rx, tx, curve->p, ndigits);
- xycz_add(tx, ty, rx, ry, curve->p, ndigits);
- vli_mod_mult_fast(z, z, tz, curve->p, ndigits);
+ xycz_add(tx, ty, rx, ry, curve);
+ vli_mod_mult_fast(z, z, tz, curve);
}
}
vli_mod_inv(z, z, curve->p, ndigits);
- apply_z(rx, ry, z, curve->p, ndigits);
+ apply_z(rx, ry, z, curve);
}
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] = be64_to_cpu(src[ndigits - 1 - i]);
-}
-
static int __ecc_is_key_valid(const struct ecc_curve *curve,
const u64 *private_key, unsigned int ndigits)
{
@@ -1404,7 +1527,9 @@ int ecc_make_pub_key(unsigned int curve_id, unsigned int ndigits,
}
ecc_point_mult(pk, &curve->g, priv, NULL, curve, ndigits);
- if (ecc_point_is_zero(pk)) {
+
+ /* SP800-56A rev 3 5.6.2.1.3 key check */
+ if (ecc_is_pubkey_valid_full(curve, pk)) {
ret = -EAGAIN;
goto err_free_point;
}
@@ -1439,10 +1564,10 @@ int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
return -EINVAL;
/* Check 3: Verify that y^2 == (x^3 + a·x + b) mod p */
- vli_mod_square_fast(yy, pk->y, curve->p, pk->ndigits); /* y^2 */
- vli_mod_square_fast(xxx, pk->x, curve->p, pk->ndigits); /* x^2 */
- vli_mod_mult_fast(xxx, xxx, pk->x, curve->p, pk->ndigits); /* x^3 */
- vli_mod_mult_fast(w, curve->a, pk->x, curve->p, pk->ndigits); /* a·x */
+ vli_mod_square_fast(yy, pk->y, curve); /* y^2 */
+ vli_mod_square_fast(xxx, pk->x, curve); /* x^2 */
+ vli_mod_mult_fast(xxx, xxx, pk->x, curve); /* x^3 */
+ vli_mod_mult_fast(w, curve->a, pk->x, curve); /* a·x */
vli_mod_add(w, w, curve->b, curve->p, pk->ndigits); /* a·x + b */
vli_mod_add(w, w, xxx, curve->p, pk->ndigits); /* x^3 + a·x + b */
if (vli_cmp(yy, w, pk->ndigits) != 0) /* Equation */
@@ -1452,6 +1577,33 @@ int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
}
EXPORT_SYMBOL(ecc_is_pubkey_valid_partial);
+/* SP800-56A section 5.6.2.3.3 full verification */
+int ecc_is_pubkey_valid_full(const struct ecc_curve *curve,
+ struct ecc_point *pk)
+{
+ struct ecc_point *nQ;
+
+ /* Checks 1 through 3 */
+ int ret = ecc_is_pubkey_valid_partial(curve, pk);
+
+ if (ret)
+ return ret;
+
+ /* Check 4: Verify that nQ is the zero point. */
+ nQ = ecc_alloc_point(pk->ndigits);
+ if (!nQ)
+ return -ENOMEM;
+
+ ecc_point_mult(nQ, pk, curve->n, NULL, curve, pk->ndigits);
+ if (!ecc_point_is_zero(nQ))
+ ret = -EINVAL;
+
+ ecc_free_point(nQ);
+
+ return ret;
+}
+EXPORT_SYMBOL(ecc_is_pubkey_valid_full);
+
int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
const u64 *private_key, const u64 *public_key,
u64 *secret)
@@ -1495,11 +1647,16 @@ int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits,
ecc_point_mult(product, pk, priv, rand_z, curve, ndigits);
- ecc_swap_digits(product->x, secret, ndigits);
-
- if (ecc_point_is_zero(product))
+ if (ecc_point_is_zero(product)) {
ret = -EFAULT;
+ goto err_validity;
+ }
+
+ ecc_swap_digits(product->x, secret, ndigits);
+err_validity:
+ memzero_explicit(priv, sizeof(priv));
+ memzero_explicit(rand_z, sizeof(rand_z));
ecc_free_point(product);
err_alloc_product:
ecc_free_point(pk);
diff --git a/crypto/ecc_curve_defs.h b/crypto/ecc_curve_defs.h
index 69be6c7d228f..9719934c9428 100644
--- a/crypto/ecc_curve_defs.h
+++ b/crypto/ecc_curve_defs.h
@@ -54,4 +54,53 @@ static struct ecc_curve nist_p256 = {
.b = nist_p256_b
};
+/* NIST P-384 */
+static u64 nist_p384_g_x[] = { 0x3A545E3872760AB7ull, 0x5502F25DBF55296Cull,
+ 0x59F741E082542A38ull, 0x6E1D3B628BA79B98ull,
+ 0x8Eb1C71EF320AD74ull, 0xAA87CA22BE8B0537ull };
+static u64 nist_p384_g_y[] = { 0x7A431D7C90EA0E5Full, 0x0A60B1CE1D7E819Dull,
+ 0xE9DA3113B5F0B8C0ull, 0xF8F41DBD289A147Cull,
+ 0x5D9E98BF9292DC29ull, 0x3617DE4A96262C6Full };
+static u64 nist_p384_p[] = { 0x00000000FFFFFFFFull, 0xFFFFFFFF00000000ull,
+ 0xFFFFFFFFFFFFFFFEull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull };
+static u64 nist_p384_n[] = { 0xECEC196ACCC52973ull, 0x581A0DB248B0A77Aull,
+ 0xC7634D81F4372DDFull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull };
+static u64 nist_p384_a[] = { 0x00000000FFFFFFFCull, 0xFFFFFFFF00000000ull,
+ 0xFFFFFFFFFFFFFFFEull, 0xFFFFFFFFFFFFFFFFull,
+ 0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull };
+static u64 nist_p384_b[] = { 0x2a85c8edd3ec2aefull, 0xc656398d8a2ed19dull,
+ 0x0314088f5013875aull, 0x181d9c6efe814112ull,
+ 0x988e056be3f82d19ull, 0xb3312fa7e23ee7e4ull };
+static struct ecc_curve nist_p384 = {
+ .name = "nist_384",
+ .g = {
+ .x = nist_p384_g_x,
+ .y = nist_p384_g_y,
+ .ndigits = 6,
+ },
+ .p = nist_p384_p,
+ .n = nist_p384_n,
+ .a = nist_p384_a,
+ .b = nist_p384_b
+};
+
+/* curve25519 */
+static u64 curve25519_g_x[] = { 0x0000000000000009, 0x0000000000000000,
+ 0x0000000000000000, 0x0000000000000000 };
+static u64 curve25519_p[] = { 0xffffffffffffffed, 0xffffffffffffffff,
+ 0xffffffffffffffff, 0x7fffffffffffffff };
+static u64 curve25519_a[] = { 0x000000000001DB41, 0x0000000000000000,
+ 0x0000000000000000, 0x0000000000000000 };
+static const struct ecc_curve ecc_25519 = {
+ .name = "curve25519",
+ .g = {
+ .x = curve25519_g_x,
+ .ndigits = 4,
+ },
+ .p = curve25519_p,
+ .a = curve25519_a,
+};
+
#endif
diff --git a/crypto/ecdh.c b/crypto/ecdh.c
index bd599053a8c4..80afee3234fb 100644
--- a/crypto/ecdh.c
+++ b/crypto/ecdh.c
@@ -6,11 +6,11 @@
*/
#include <linux/module.h>
+#include <crypto/internal/ecc.h>
#include <crypto/internal/kpp.h>
#include <crypto/kpp.h>
#include <crypto/ecdh.h>
#include <linux/scatterlist.h>
-#include "ecc.h"
struct ecdh_ctx {
unsigned int curve_id;
@@ -23,42 +23,27 @@ static inline struct ecdh_ctx *ecdh_get_ctx(struct crypto_kpp *tfm)
return kpp_tfm_ctx(tfm);
}
-static unsigned int ecdh_supported_curve(unsigned int curve_id)
-{
- switch (curve_id) {
- case ECC_CURVE_NIST_P192: return ECC_CURVE_NIST_P192_DIGITS;
- case ECC_CURVE_NIST_P256: return ECC_CURVE_NIST_P256_DIGITS;
- default: return 0;
- }
-}
-
static int ecdh_set_secret(struct crypto_kpp *tfm, const void *buf,
unsigned int len)
{
struct ecdh_ctx *ctx = ecdh_get_ctx(tfm);
struct ecdh params;
- unsigned int ndigits;
- if (crypto_ecdh_decode_key(buf, len, &params) < 0)
+ if (crypto_ecdh_decode_key(buf, len, &params) < 0 ||
+ params.key_size > sizeof(u64) * ctx->ndigits)
return -EINVAL;
- ndigits = ecdh_supported_curve(params.curve_id);
- if (!ndigits)
- return -EINVAL;
-
- ctx->curve_id = params.curve_id;
- ctx->ndigits = ndigits;
-
if (!params.key || !params.key_size)
return ecc_gen_privkey(ctx->curve_id, ctx->ndigits,
ctx->private_key);
- if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits,
- (const u64 *)params.key, params.key_size) < 0)
- return -EINVAL;
-
memcpy(ctx->private_key, params.key, params.key_size);
+ if (ecc_is_key_valid(ctx->curve_id, ctx->ndigits,
+ ctx->private_key, params.key_size) < 0) {
+ memzero_explicit(ctx->private_key, params.key_size);
+ return -EINVAL;
+ }
return 0;
}
@@ -124,7 +109,7 @@ static int ecdh_compute_value(struct kpp_request *req)
/* fall through */
free_all:
- kzfree(shared_secret);
+ kfree_sensitive(shared_secret);
free_pubkey:
kfree(public_key);
return ret;
@@ -138,28 +123,116 @@ static unsigned int ecdh_max_size(struct crypto_kpp *tfm)
return ctx->ndigits << (ECC_DIGITS_TO_BYTES_SHIFT + 1);
}
-static struct kpp_alg ecdh = {
+static int ecdh_nist_p192_init_tfm(struct crypto_kpp *tfm)
+{
+ struct ecdh_ctx *ctx = ecdh_get_ctx(tfm);
+
+ ctx->curve_id = ECC_CURVE_NIST_P192;
+ ctx->ndigits = ECC_CURVE_NIST_P192_DIGITS;
+
+ return 0;
+}
+
+static struct kpp_alg ecdh_nist_p192 = {
+ .set_secret = ecdh_set_secret,
+ .generate_public_key = ecdh_compute_value,
+ .compute_shared_secret = ecdh_compute_value,
+ .max_size = ecdh_max_size,
+ .init = ecdh_nist_p192_init_tfm,
+ .base = {
+ .cra_name = "ecdh-nist-p192",
+ .cra_driver_name = "ecdh-nist-p192-generic",
+ .cra_priority = 100,
+ .cra_module = THIS_MODULE,
+ .cra_ctxsize = sizeof(struct ecdh_ctx),
+ },
+};
+
+static int ecdh_nist_p256_init_tfm(struct crypto_kpp *tfm)
+{
+ struct ecdh_ctx *ctx = ecdh_get_ctx(tfm);
+
+ ctx->curve_id = ECC_CURVE_NIST_P256;
+ ctx->ndigits = ECC_CURVE_NIST_P256_DIGITS;
+
+ return 0;
+}
+
+static struct kpp_alg ecdh_nist_p256 = {
.set_secret = ecdh_set_secret,
.generate_public_key = ecdh_compute_value,
.compute_shared_secret = ecdh_compute_value,
.max_size = ecdh_max_size,
+ .init = ecdh_nist_p256_init_tfm,
.base = {
- .cra_name = "ecdh",
- .cra_driver_name = "ecdh-generic",
+ .cra_name = "ecdh-nist-p256",
+ .cra_driver_name = "ecdh-nist-p256-generic",
.cra_priority = 100,
.cra_module = THIS_MODULE,
.cra_ctxsize = sizeof(struct ecdh_ctx),
},
};
-static int ecdh_init(void)
+static int ecdh_nist_p384_init_tfm(struct crypto_kpp *tfm)
{
- return crypto_register_kpp(&ecdh);
+ struct ecdh_ctx *ctx = ecdh_get_ctx(tfm);
+
+ ctx->curve_id = ECC_CURVE_NIST_P384;
+ ctx->ndigits = ECC_CURVE_NIST_P384_DIGITS;
+
+ return 0;
+}
+
+static struct kpp_alg ecdh_nist_p384 = {
+ .set_secret = ecdh_set_secret,
+ .generate_public_key = ecdh_compute_value,
+ .compute_shared_secret = ecdh_compute_value,
+ .max_size = ecdh_max_size,
+ .init = ecdh_nist_p384_init_tfm,
+ .base = {
+ .cra_name = "ecdh-nist-p384",
+ .cra_driver_name = "ecdh-nist-p384-generic",
+ .cra_priority = 100,
+ .cra_module = THIS_MODULE,
+ .cra_ctxsize = sizeof(struct ecdh_ctx),
+ },
+};
+
+static bool ecdh_nist_p192_registered;
+
+static int __init ecdh_init(void)
+{
+ int ret;
+
+ /* NIST p192 will fail to register in FIPS mode */
+ ret = crypto_register_kpp(&ecdh_nist_p192);
+ ecdh_nist_p192_registered = ret == 0;
+
+ ret = crypto_register_kpp(&ecdh_nist_p256);
+ if (ret)
+ goto nist_p256_error;
+
+ ret = crypto_register_kpp(&ecdh_nist_p384);
+ if (ret)
+ goto nist_p384_error;
+
+ return 0;
+
+nist_p384_error:
+ crypto_unregister_kpp(&ecdh_nist_p256);
+
+nist_p256_error:
+ if (ecdh_nist_p192_registered)
+ crypto_unregister_kpp(&ecdh_nist_p192);
+ return ret;
}
-static void ecdh_exit(void)
+static void __exit ecdh_exit(void)
{
- crypto_unregister_kpp(&ecdh);
+ if (ecdh_nist_p192_registered)
+ crypto_unregister_kpp(&ecdh_nist_p192);
+ crypto_unregister_kpp(&ecdh_nist_p256);
+ crypto_unregister_kpp(&ecdh_nist_p384);
}
subsys_initcall(ecdh_init);
diff --git a/crypto/ecdh_helper.c b/crypto/ecdh_helper.c
index 66fcb2ea8154..f18f9028f912 100644
--- a/crypto/ecdh_helper.c
+++ b/crypto/ecdh_helper.c
@@ -10,7 +10,7 @@
#include <crypto/ecdh.h>
#include <crypto/kpp.h>
-#define ECDH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + 2 * sizeof(short))
+#define ECDH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + sizeof(short))
static inline u8 *ecdh_pack_data(void *dst, const void *src, size_t sz)
{
@@ -46,7 +46,6 @@ int crypto_ecdh_encode_key(char *buf, unsigned int len,
return -EINVAL;
ptr = ecdh_pack_data(ptr, &secret, sizeof(secret));
- ptr = ecdh_pack_data(ptr, &params->curve_id, sizeof(params->curve_id));
ptr = ecdh_pack_data(ptr, &params->key_size, sizeof(params->key_size));
ecdh_pack_data(ptr, params->key, params->key_size);
@@ -67,7 +66,9 @@ int crypto_ecdh_decode_key(const char *buf, unsigned int len,
if (secret.type != CRYPTO_KPP_SECRET_TYPE_ECDH)
return -EINVAL;
- ptr = ecdh_unpack_data(&params->curve_id, ptr, sizeof(params->curve_id));
+ if (unlikely(len < secret.len))
+ return -EINVAL;
+
ptr = ecdh_unpack_data(&params->key_size, ptr, sizeof(params->key_size));
if (secret.len != crypto_ecdh_key_len(params))
return -EINVAL;
diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c
new file mode 100644
index 000000000000..fbd76498aba8
--- /dev/null
+++ b/crypto/ecdsa.c
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 IBM Corporation
+ */
+
+#include <linux/module.h>
+#include <crypto/internal/akcipher.h>
+#include <crypto/internal/ecc.h>
+#include <crypto/akcipher.h>
+#include <crypto/ecdh.h>
+#include <linux/asn1_decoder.h>
+#include <linux/scatterlist.h>
+
+#include "ecdsasignature.asn1.h"
+
+struct ecc_ctx {
+ unsigned int curve_id;
+ const struct ecc_curve *curve;
+
+ bool pub_key_set;
+ u64 x[ECC_MAX_DIGITS]; /* pub key x and y coordinates */
+ u64 y[ECC_MAX_DIGITS];
+ struct ecc_point pub_key;
+};
+
+struct ecdsa_signature_ctx {
+ const struct ecc_curve *curve;
+ u64 r[ECC_MAX_DIGITS];
+ u64 s[ECC_MAX_DIGITS];
+};
+
+/*
+ * Get the r and s components of a signature from the X509 certificate.
+ */
+static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen, unsigned int ndigits)
+{
+ size_t keylen = ndigits * sizeof(u64);
+ ssize_t diff = vlen - keylen;
+ const char *d = value;
+ u8 rs[ECC_MAX_BYTES];
+
+ if (!value || !vlen)
+ return -EINVAL;
+
+ /* diff = 0: 'value' has exacly the right size
+ * diff > 0: 'value' has too many bytes; one leading zero is allowed that
+ * makes the value a positive integer; error on more
+ * diff < 0: 'value' is missing leading zeros, which we add
+ */
+ if (diff > 0) {
+ /* skip over leading zeros that make 'value' a positive int */
+ if (*d == 0) {
+ vlen -= 1;
+ diff--;
+ d++;
+ }
+ if (diff)
+ return -EINVAL;
+ }
+ if (-diff >= keylen)
+ return -EINVAL;
+
+ if (diff) {
+ /* leading zeros not given in 'value' */
+ memset(rs, 0, -diff);
+ }
+
+ memcpy(&rs[-diff], d, vlen);
+
+ ecc_swap_digits((u64 *)rs, dest, ndigits);
+
+ return 0;
+}
+
+int ecdsa_get_signature_r(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct ecdsa_signature_ctx *sig = context;
+
+ return ecdsa_get_signature_rs(sig->r, hdrlen, tag, value, vlen,
+ sig->curve->g.ndigits);
+}
+
+int ecdsa_get_signature_s(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct ecdsa_signature_ctx *sig = context;
+
+ return ecdsa_get_signature_rs(sig->s, hdrlen, tag, value, vlen,
+ sig->curve->g.ndigits);
+}
+
+static int _ecdsa_verify(struct ecc_ctx *ctx, const u64 *hash, const u64 *r, const u64 *s)
+{
+ const struct ecc_curve *curve = ctx->curve;
+ unsigned int ndigits = curve->g.ndigits;
+ u64 s1[ECC_MAX_DIGITS];
+ u64 u1[ECC_MAX_DIGITS];
+ u64 u2[ECC_MAX_DIGITS];
+ u64 x1[ECC_MAX_DIGITS];
+ u64 y1[ECC_MAX_DIGITS];
+ struct ecc_point res = ECC_POINT_INIT(x1, y1, ndigits);
+
+ /* 0 < r < n and 0 < s < n */
+ if (vli_is_zero(r, ndigits) || vli_cmp(r, curve->n, ndigits) >= 0 ||
+ vli_is_zero(s, ndigits) || vli_cmp(s, curve->n, ndigits) >= 0)
+ return -EBADMSG;
+
+ /* hash is given */
+ pr_devel("hash : %016llx %016llx ... %016llx\n",
+ hash[ndigits - 1], hash[ndigits - 2], hash[0]);
+
+ /* s1 = (s^-1) mod n */
+ vli_mod_inv(s1, s, curve->n, ndigits);
+ /* u1 = (hash * s1) mod n */
+ vli_mod_mult_slow(u1, hash, s1, curve->n, ndigits);
+ /* u2 = (r * s1) mod n */
+ vli_mod_mult_slow(u2, r, s1, curve->n, ndigits);
+ /* res = u1*G + u2 * pub_key */
+ ecc_point_mult_shamir(&res, u1, &curve->g, u2, &ctx->pub_key, curve);
+
+ /* res.x = res.x mod n (if res.x > order) */
+ if (unlikely(vli_cmp(res.x, curve->n, ndigits) == 1))
+ /* faster alternative for NIST p384, p256 & p192 */
+ vli_sub(res.x, res.x, curve->n, ndigits);
+
+ if (!vli_cmp(res.x, r, ndigits))
+ return 0;
+
+ return -EKEYREJECTED;
+}
+
+/*
+ * Verify an ECDSA signature.
+ */
+static int ecdsa_verify(struct akcipher_request *req)
+{
+ struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+ struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
+ size_t keylen = ctx->curve->g.ndigits * sizeof(u64);
+ struct ecdsa_signature_ctx sig_ctx = {
+ .curve = ctx->curve,
+ };
+ u8 rawhash[ECC_MAX_BYTES];
+ u64 hash[ECC_MAX_DIGITS];
+ unsigned char *buffer;
+ ssize_t diff;
+ int ret;
+
+ if (unlikely(!ctx->pub_key_set))
+ return -EINVAL;
+
+ buffer = kmalloc(req->src_len + req->dst_len, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ sg_pcopy_to_buffer(req->src,
+ sg_nents_for_len(req->src, req->src_len + req->dst_len),
+ buffer, req->src_len + req->dst_len, 0);
+
+ ret = asn1_ber_decoder(&ecdsasignature_decoder, &sig_ctx,
+ buffer, req->src_len);
+ if (ret < 0)
+ goto error;
+
+ /* if the hash is shorter then we will add leading zeros to fit to ndigits */
+ diff = keylen - req->dst_len;
+ if (diff >= 0) {
+ if (diff)
+ memset(rawhash, 0, diff);
+ memcpy(&rawhash[diff], buffer + req->src_len, req->dst_len);
+ } else if (diff < 0) {
+ /* given hash is longer, we take the left-most bytes */
+ memcpy(&rawhash, buffer + req->src_len, keylen);
+ }
+
+ ecc_swap_digits((u64 *)rawhash, hash, ctx->curve->g.ndigits);
+
+ ret = _ecdsa_verify(ctx, hash, sig_ctx.r, sig_ctx.s);
+
+error:
+ kfree(buffer);
+
+ return ret;
+}
+
+static int ecdsa_ecc_ctx_init(struct ecc_ctx *ctx, unsigned int curve_id)
+{
+ ctx->curve_id = curve_id;
+ ctx->curve = ecc_get_curve(curve_id);
+ if (!ctx->curve)
+ return -EINVAL;
+
+ return 0;
+}
+
+
+static void ecdsa_ecc_ctx_deinit(struct ecc_ctx *ctx)
+{
+ ctx->pub_key_set = false;
+}
+
+static int ecdsa_ecc_ctx_reset(struct ecc_ctx *ctx)
+{
+ unsigned int curve_id = ctx->curve_id;
+ int ret;
+
+ ecdsa_ecc_ctx_deinit(ctx);
+ ret = ecdsa_ecc_ctx_init(ctx, curve_id);
+ if (ret == 0)
+ ctx->pub_key = ECC_POINT_INIT(ctx->x, ctx->y,
+ ctx->curve->g.ndigits);
+ return ret;
+}
+
+/*
+ * Set the public key given the raw uncompressed key data from an X509
+ * certificate. The key data contain the concatenated X and Y coordinates of
+ * the public key.
+ */
+static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen)
+{
+ struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
+ const unsigned char *d = key;
+ const u64 *digits = (const u64 *)&d[1];
+ unsigned int ndigits;
+ int ret;
+
+ ret = ecdsa_ecc_ctx_reset(ctx);
+ if (ret < 0)
+ return ret;
+
+ if (keylen < 1 || (((keylen - 1) >> 1) % sizeof(u64)) != 0)
+ return -EINVAL;
+ /* we only accept uncompressed format indicated by '4' */
+ if (d[0] != 4)
+ return -EINVAL;
+
+ keylen--;
+ ndigits = (keylen >> 1) / sizeof(u64);
+ if (ndigits != ctx->curve->g.ndigits)
+ return -EINVAL;
+
+ ecc_swap_digits(digits, ctx->pub_key.x, ndigits);
+ ecc_swap_digits(&digits[ndigits], ctx->pub_key.y, ndigits);
+ ret = ecc_is_pubkey_valid_full(ctx->curve, &ctx->pub_key);
+
+ ctx->pub_key_set = ret == 0;
+
+ return ret;
+}
+
+static void ecdsa_exit_tfm(struct crypto_akcipher *tfm)
+{
+ struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+ ecdsa_ecc_ctx_deinit(ctx);
+}
+
+static unsigned int ecdsa_max_size(struct crypto_akcipher *tfm)
+{
+ struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+ return ctx->pub_key.ndigits << ECC_DIGITS_TO_BYTES_SHIFT;
+}
+
+static int ecdsa_nist_p384_init_tfm(struct crypto_akcipher *tfm)
+{
+ struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+ return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P384);
+}
+
+static struct akcipher_alg ecdsa_nist_p384 = {
+ .verify = ecdsa_verify,
+ .set_pub_key = ecdsa_set_pub_key,
+ .max_size = ecdsa_max_size,
+ .init = ecdsa_nist_p384_init_tfm,
+ .exit = ecdsa_exit_tfm,
+ .base = {
+ .cra_name = "ecdsa-nist-p384",
+ .cra_driver_name = "ecdsa-nist-p384-generic",
+ .cra_priority = 100,
+ .cra_module = THIS_MODULE,
+ .cra_ctxsize = sizeof(struct ecc_ctx),
+ },
+};
+
+static int ecdsa_nist_p256_init_tfm(struct crypto_akcipher *tfm)
+{
+ struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+ return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P256);
+}
+
+static struct akcipher_alg ecdsa_nist_p256 = {
+ .verify = ecdsa_verify,
+ .set_pub_key = ecdsa_set_pub_key,
+ .max_size = ecdsa_max_size,
+ .init = ecdsa_nist_p256_init_tfm,
+ .exit = ecdsa_exit_tfm,
+ .base = {
+ .cra_name = "ecdsa-nist-p256",
+ .cra_driver_name = "ecdsa-nist-p256-generic",
+ .cra_priority = 100,
+ .cra_module = THIS_MODULE,
+ .cra_ctxsize = sizeof(struct ecc_ctx),
+ },
+};
+
+static int ecdsa_nist_p192_init_tfm(struct crypto_akcipher *tfm)
+{
+ struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
+
+ return ecdsa_ecc_ctx_init(ctx, ECC_CURVE_NIST_P192);
+}
+
+static struct akcipher_alg ecdsa_nist_p192 = {
+ .verify = ecdsa_verify,
+ .set_pub_key = ecdsa_set_pub_key,
+ .max_size = ecdsa_max_size,
+ .init = ecdsa_nist_p192_init_tfm,
+ .exit = ecdsa_exit_tfm,
+ .base = {
+ .cra_name = "ecdsa-nist-p192",
+ .cra_driver_name = "ecdsa-nist-p192-generic",
+ .cra_priority = 100,
+ .cra_module = THIS_MODULE,
+ .cra_ctxsize = sizeof(struct ecc_ctx),
+ },
+};
+static bool ecdsa_nist_p192_registered;
+
+static int __init ecdsa_init(void)
+{
+ int ret;
+
+ /* NIST p192 may not be available in FIPS mode */
+ ret = crypto_register_akcipher(&ecdsa_nist_p192);
+ ecdsa_nist_p192_registered = ret == 0;
+
+ ret = crypto_register_akcipher(&ecdsa_nist_p256);
+ if (ret)
+ goto nist_p256_error;
+
+ ret = crypto_register_akcipher(&ecdsa_nist_p384);
+ if (ret)
+ goto nist_p384_error;
+
+ return 0;
+
+nist_p384_error:
+ crypto_unregister_akcipher(&ecdsa_nist_p256);
+
+nist_p256_error:
+ if (ecdsa_nist_p192_registered)
+ crypto_unregister_akcipher(&ecdsa_nist_p192);
+ return ret;
+}
+
+static void __exit ecdsa_exit(void)
+{
+ if (ecdsa_nist_p192_registered)
+ crypto_unregister_akcipher(&ecdsa_nist_p192);
+ crypto_unregister_akcipher(&ecdsa_nist_p256);
+ crypto_unregister_akcipher(&ecdsa_nist_p384);
+}
+
+subsys_initcall(ecdsa_init);
+module_exit(ecdsa_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Stefan Berger <stefanb@linux.ibm.com>");
+MODULE_DESCRIPTION("ECDSA generic algorithm");
+MODULE_ALIAS_CRYPTO("ecdsa-generic");
diff --git a/crypto/ecdsasignature.asn1 b/crypto/ecdsasignature.asn1
new file mode 100644
index 000000000000..621ab754fb9f
--- /dev/null
+++ b/crypto/ecdsasignature.asn1
@@ -0,0 +1,4 @@
+ECDSASignature ::= SEQUENCE {
+ r INTEGER ({ ecdsa_get_signature_r }),
+ s INTEGER ({ ecdsa_get_signature_s })
+}
diff --git a/crypto/echainiv.c b/crypto/echainiv.c
index 4a2f02baba14..69686668625e 100644
--- a/crypto/echainiv.c
+++ b/crypto/echainiv.c
@@ -115,7 +115,7 @@ static int echainiv_aead_create(struct crypto_template *tmpl,
struct aead_instance *inst;
int err;
- inst = aead_geniv_alloc(tmpl, tb, 0, 0);
+ inst = aead_geniv_alloc(tmpl, tb);
if (IS_ERR(inst))
return PTR_ERR(inst);
diff --git a/crypto/ecrdsa.c b/crypto/ecrdsa.c
index 887ec21aee49..f3c6b5e15e75 100644
--- a/crypto/ecrdsa.c
+++ b/crypto/ecrdsa.c
@@ -20,11 +20,12 @@
#include <linux/crypto.h>
#include <crypto/streebog.h>
#include <crypto/internal/akcipher.h>
+#include <crypto/internal/ecc.h>
#include <crypto/akcipher.h>
#include <linux/oid_registry.h>
+#include <linux/scatterlist.h>
#include "ecrdsa_params.asn1.h"
#include "ecrdsa_pub_key.asn1.h"
-#include "ecc.h"
#include "ecrdsa_defs.h"
#define ECRDSA_MAX_SIG_SIZE (2 * 512 / 8)
@@ -112,15 +113,15 @@ static int ecrdsa_verify(struct akcipher_request *req)
/* Step 1: verify that 0 < r < q, 0 < s < q */
if (vli_is_zero(r, ndigits) ||
- vli_cmp(r, ctx->curve->n, ndigits) == 1 ||
+ vli_cmp(r, ctx->curve->n, ndigits) >= 0 ||
vli_is_zero(s, ndigits) ||
- vli_cmp(s, ctx->curve->n, ndigits) == 1)
+ vli_cmp(s, ctx->curve->n, ndigits) >= 0)
return -EKEYREJECTED;
/* Step 2: calculate hash (h) of the message (passed as input) */
/* Step 3: calculate e = h \mod q */
vli_from_le64(e, digest, ndigits);
- if (vli_cmp(e, ctx->curve->n, ndigits) == 1)
+ if (vli_cmp(e, ctx->curve->n, ndigits) >= 0)
vli_sub(e, e, ctx->curve->n, ndigits);
if (vli_is_zero(e, ndigits))
e[0] = 1;
@@ -136,7 +137,7 @@ static int ecrdsa_verify(struct akcipher_request *req)
/* Step 6: calculate point C = z_1P + z_2Q, and R = x_c \mod q */
ecc_point_mult_shamir(&cc, z1, &ctx->curve->g, z2, &ctx->pub_key,
ctx->curve);
- if (vli_cmp(cc.x, ctx->curve->n, ndigits) == 1)
+ if (vli_cmp(cc.x, ctx->curve->n, ndigits) >= 0)
vli_sub(cc.x, cc.x, ctx->curve->n, ndigits);
/* Step 7: if R == r signature is valid */
diff --git a/crypto/ecrdsa_defs.h b/crypto/ecrdsa_defs.h
index 170baf039007..0056335b9d03 100644
--- a/crypto/ecrdsa_defs.h
+++ b/crypto/ecrdsa_defs.h
@@ -13,7 +13,7 @@
#ifndef _CRYTO_ECRDSA_DEFS_H
#define _CRYTO_ECRDSA_DEFS_H
-#include "ecc.h"
+#include <crypto/internal/ecc.h>
#define ECRDSA_MAX_SIG_SIZE (2 * 512 / 8)
#define ECRDSA_MAX_DIGITS (512 / 64)
diff --git a/crypto/essiv.c b/crypto/essiv.c
index 465a89c9d1ef..e33369df9034 100644
--- a/crypto/essiv.c
+++ b/crypto/essiv.c
@@ -30,6 +30,7 @@
#include <crypto/authenc.h>
#include <crypto/internal/aead.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/hash.h>
#include <crypto/internal/skcipher.h>
#include <crypto/scatterwalk.h>
@@ -66,7 +67,6 @@ static int essiv_skcipher_setkey(struct crypto_skcipher *tfm,
const u8 *key, unsigned int keylen)
{
struct essiv_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
- SHASH_DESC_ON_STACK(desc, tctx->hash);
u8 salt[HASH_MAX_DIGESTSIZE];
int err;
@@ -78,8 +78,7 @@ static int essiv_skcipher_setkey(struct crypto_skcipher *tfm,
if (err)
return err;
- desc->tfm = tctx->hash;
- err = crypto_shash_digest(desc, key, keylen, salt);
+ err = crypto_shash_tfm_digest(tctx->hash, key, keylen, salt);
if (err)
return err;
@@ -468,7 +467,7 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
return PTR_ERR(shash_name);
type = algt->type & algt->mask;
- mask = crypto_requires_sync(algt->type, algt->mask);
+ mask = crypto_algt_inherited_mask(algt);
switch (type) {
case CRYPTO_ALG_TYPE_SKCIPHER:
@@ -527,7 +526,7 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
/* Synchronous hash, e.g., "sha256" */
_hash_alg = crypto_alg_mod_lookup(shash_name,
CRYPTO_ALG_TYPE_SHASH,
- CRYPTO_ALG_TYPE_MASK);
+ CRYPTO_ALG_TYPE_MASK | mask);
if (IS_ERR(_hash_alg)) {
err = PTR_ERR(_hash_alg);
goto out_drop_skcipher;
@@ -544,7 +543,7 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
}
/* record the driver name so we can instantiate this exact algo later */
- strlcpy(ictx->shash_driver_name, hash_alg->base.cra_driver_name,
+ strscpy(ictx->shash_driver_name, hash_alg->base.cra_driver_name,
CRYPTO_MAX_ALG_NAME);
/* Instance fields */
@@ -559,7 +558,12 @@ static int essiv_create(struct crypto_template *tmpl, struct rtattr **tb)
hash_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
goto out_free_hash;
- base->cra_flags = block_base->cra_flags & CRYPTO_ALG_ASYNC;
+ /*
+ * hash_alg wasn't gotten via crypto_grab*(), so we need to inherit its
+ * flags manually.
+ */
+ base->cra_flags |= (hash_alg->base.cra_flags &
+ CRYPTO_ALG_INHERITED_FLAGS);
base->cra_blocksize = block_base->cra_blocksize;
base->cra_ctxsize = sizeof(struct essiv_tfm_ctx);
base->cra_alignmask = block_base->cra_alignmask;
@@ -640,3 +644,4 @@ module_exit(essiv_module_exit);
MODULE_DESCRIPTION("ESSIV skcipher/aead wrapper for block encryption");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS_CRYPTO("essiv");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/fcrypt.c b/crypto/fcrypt.c
index 58f935315cf8..76a04d000c0d 100644
--- a/crypto/fcrypt.c
+++ b/crypto/fcrypt.c
@@ -63,10 +63,7 @@ do { \
} while (0)
/* Rotate right one 64 bit number as a 56 bit number */
-#define ror56_64(k, n) \
-do { \
- k = (k >> n) | ((k & ((1 << n) - 1)) << (56 - n)); \
-} while (0)
+#define ror56_64(k, n) (k = (k >> n) | ((k & ((1 << n) - 1)) << (56 - n)))
/*
* Sboxes for Feistel network derived from
@@ -396,7 +393,6 @@ static struct crypto_alg fcrypt_alg = {
.cra_blocksize = 8,
.cra_ctxsize = sizeof(struct fcrypt_ctx),
.cra_module = THIS_MODULE,
- .cra_alignmask = 3,
.cra_u = { .cipher = {
.cia_min_keysize = 8,
.cia_max_keysize = 8,
diff --git a/crypto/fips.c b/crypto/fips.c
index 7b1d8caee669..b05d3c7b3ca5 100644
--- a/crypto/fips.c
+++ b/crypto/fips.c
@@ -12,6 +12,7 @@
#include <linux/kernel.h>
#include <linux/sysctl.h>
#include <linux/notifier.h>
+#include <generated/utsrelease.h>
int fips_enabled;
EXPORT_SYMBOL_GPL(fips_enabled);
@@ -30,13 +31,37 @@ static int fips_enable(char *str)
__setup("fips=", fips_enable);
+#define FIPS_MODULE_NAME CONFIG_CRYPTO_FIPS_NAME
+#ifdef CONFIG_CRYPTO_FIPS_CUSTOM_VERSION
+#define FIPS_MODULE_VERSION CONFIG_CRYPTO_FIPS_VERSION
+#else
+#define FIPS_MODULE_VERSION UTS_RELEASE
+#endif
+
+static char fips_name[] = FIPS_MODULE_NAME;
+static char fips_version[] = FIPS_MODULE_VERSION;
+
static struct ctl_table crypto_sysctl_table[] = {
{
- .procname = "fips_enabled",
- .data = &fips_enabled,
- .maxlen = sizeof(int),
- .mode = 0444,
- .proc_handler = proc_dointvec
+ .procname = "fips_enabled",
+ .data = &fips_enabled,
+ .maxlen = sizeof(int),
+ .mode = 0444,
+ .proc_handler = proc_dointvec
+ },
+ {
+ .procname = "fips_name",
+ .data = &fips_name,
+ .maxlen = 64,
+ .mode = 0444,
+ .proc_handler = proc_dostring
+ },
+ {
+ .procname = "fips_version",
+ .data = &fips_version,
+ .maxlen = 64,
+ .mode = 0444,
+ .proc_handler = proc_dostring
},
{}
};
diff --git a/crypto/gcm.c b/crypto/gcm.c
index 8e5c0ac65661..338ee0769747 100644
--- a/crypto/gcm.c
+++ b/crypto/gcm.c
@@ -139,7 +139,7 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
CRYPTO_TFM_REQ_MASK);
err = crypto_ahash_setkey(ghash, (u8 *)&data->hash, sizeof(be128));
out:
- kzfree(data);
+ kfree_sensitive(data);
return err;
}
@@ -578,7 +578,6 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
const char *ctr_name,
const char *ghash_name)
{
- struct crypto_attr_type *algt;
u32 mask;
struct aead_instance *inst;
struct gcm_instance_ctx *ctx;
@@ -586,14 +585,9 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
struct hash_alg_common *ghash;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
- return -EINVAL;
-
- mask = crypto_requires_sync(algt->type, algt->mask);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
+ if (err)
+ return err;
inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
if (!inst)
@@ -635,8 +629,6 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
CRYPTO_MAX_ALG_NAME)
goto err_free_inst;
- inst->alg.base.cra_flags = (ghash->base.cra_flags |
- ctr->base.cra_flags) & CRYPTO_ALG_ASYNC;
inst->alg.base.cra_priority = (ghash->base.cra_priority +
ctr->base.cra_priority) / 2;
inst->alg.base.cra_blocksize = 1;
@@ -835,26 +827,15 @@ static void crypto_rfc4106_free(struct aead_instance *inst)
static int crypto_rfc4106_create(struct crypto_template *tmpl,
struct rtattr **tb)
{
- struct crypto_attr_type *algt;
u32 mask;
struct aead_instance *inst;
struct crypto_aead_spawn *spawn;
struct aead_alg *alg;
- const char *ccm_name;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
- return -EINVAL;
-
- mask = crypto_requires_sync(algt->type, algt->mask);
-
- ccm_name = crypto_attr_alg_name(tb[1]);
- if (IS_ERR(ccm_name))
- return PTR_ERR(ccm_name);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
+ if (err)
+ return err;
inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
if (!inst)
@@ -862,9 +843,9 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
spawn = aead_instance_ctx(inst);
err = crypto_grab_aead(spawn, aead_crypto_instance(inst),
- ccm_name, 0, mask);
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
- goto out_free_inst;
+ goto err_free_inst;
alg = crypto_spawn_aead_alg(spawn);
@@ -872,11 +853,11 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
/* Underlying IV size must be 12. */
if (crypto_aead_alg_ivsize(alg) != GCM_AES_IV_SIZE)
- goto out_drop_alg;
+ goto err_free_inst;
/* Not a stream cipher? */
if (alg->base.cra_blocksize != 1)
- goto out_drop_alg;
+ goto err_free_inst;
err = -ENAMETOOLONG;
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
@@ -885,9 +866,8 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
"rfc4106(%s)", alg->base.cra_driver_name) >=
CRYPTO_MAX_ALG_NAME)
- goto out_drop_alg;
+ goto err_free_inst;
- 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 = 1;
inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
@@ -909,17 +889,11 @@ static int crypto_rfc4106_create(struct crypto_template *tmpl,
inst->free = crypto_rfc4106_free;
err = aead_register_instance(tmpl, inst);
- if (err)
- goto out_drop_alg;
-
-out:
+ if (err) {
+err_free_inst:
+ crypto_rfc4106_free(inst);
+ }
return err;
-
-out_drop_alg:
- crypto_drop_aead(spawn);
-out_free_inst:
- kfree(inst);
- goto out;
}
static int crypto_rfc4543_setkey(struct crypto_aead *parent, const u8 *key,
@@ -1068,50 +1042,37 @@ static void crypto_rfc4543_free(struct aead_instance *inst)
static int crypto_rfc4543_create(struct crypto_template *tmpl,
struct rtattr **tb)
{
- struct crypto_attr_type *algt;
u32 mask;
struct aead_instance *inst;
- struct crypto_aead_spawn *spawn;
struct aead_alg *alg;
struct crypto_rfc4543_instance_ctx *ctx;
- const char *ccm_name;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & algt->mask)
- return -EINVAL;
-
- mask = crypto_requires_sync(algt->type, algt->mask);
-
- ccm_name = crypto_attr_alg_name(tb[1]);
- if (IS_ERR(ccm_name))
- return PTR_ERR(ccm_name);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
+ if (err)
+ return err;
inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
if (!inst)
return -ENOMEM;
ctx = aead_instance_ctx(inst);
- spawn = &ctx->aead;
- err = crypto_grab_aead(spawn, aead_crypto_instance(inst),
- ccm_name, 0, mask);
+ err = crypto_grab_aead(&ctx->aead, aead_crypto_instance(inst),
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
- goto out_free_inst;
+ goto err_free_inst;
- alg = crypto_spawn_aead_alg(spawn);
+ alg = crypto_spawn_aead_alg(&ctx->aead);
err = -EINVAL;
/* Underlying IV size must be 12. */
if (crypto_aead_alg_ivsize(alg) != GCM_AES_IV_SIZE)
- goto out_drop_alg;
+ goto err_free_inst;
/* Not a stream cipher? */
if (alg->base.cra_blocksize != 1)
- goto out_drop_alg;
+ goto err_free_inst;
err = -ENAMETOOLONG;
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
@@ -1120,9 +1081,8 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
"rfc4543(%s)", alg->base.cra_driver_name) >=
CRYPTO_MAX_ALG_NAME)
- goto out_drop_alg;
+ goto err_free_inst;
- 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 = 1;
inst->alg.base.cra_alignmask = alg->base.cra_alignmask;
@@ -1141,20 +1101,14 @@ static int crypto_rfc4543_create(struct crypto_template *tmpl,
inst->alg.encrypt = crypto_rfc4543_encrypt;
inst->alg.decrypt = crypto_rfc4543_decrypt;
- inst->free = crypto_rfc4543_free,
+ inst->free = crypto_rfc4543_free;
err = aead_register_instance(tmpl, inst);
- if (err)
- goto out_drop_alg;
-
-out:
+ if (err) {
+err_free_inst:
+ crypto_rfc4543_free(inst);
+ }
return err;
-
-out_drop_alg:
- crypto_drop_aead(spawn);
-out_free_inst:
- kfree(inst);
- goto out;
}
static struct crypto_template crypto_gcm_tmpls[] = {
diff --git a/crypto/geniv.c b/crypto/geniv.c
index dbcc640274cd..bee4621b4f12 100644
--- a/crypto/geniv.c
+++ b/crypto/geniv.c
@@ -39,27 +39,19 @@ static void aead_geniv_free(struct aead_instance *inst)
}
struct aead_instance *aead_geniv_alloc(struct crypto_template *tmpl,
- struct rtattr **tb, u32 type, u32 mask)
+ struct rtattr **tb)
{
- 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;
+ u32 mask;
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);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AEAD, &mask);
+ if (err)
+ return ERR_PTR(err);
inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
if (!inst)
@@ -67,11 +59,8 @@ struct aead_instance *aead_geniv_alloc(struct crypto_template *tmpl,
spawn = aead_instance_ctx(inst);
- /* Ignore async algorithms if necessary. */
- mask |= crypto_requires_sync(algt->type, algt->mask);
-
err = crypto_grab_aead(spawn, aead_crypto_instance(inst),
- name, type, mask);
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
goto err_free_inst;
@@ -82,19 +71,18 @@ struct aead_instance *aead_geniv_alloc(struct crypto_template *tmpl,
err = -EINVAL;
if (ivsize < sizeof(u64))
- goto err_drop_alg;
+ goto err_free_inst;
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;
+ goto err_free_inst;
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;
+ goto err_free_inst;
- 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;
@@ -111,10 +99,8 @@ struct aead_instance *aead_geniv_alloc(struct crypto_template *tmpl,
out:
return inst;
-err_drop_alg:
- crypto_drop_aead(spawn);
err_free_inst:
- kfree(inst);
+ aead_geniv_free(inst);
inst = ERR_PTR(err);
goto out;
}
diff --git a/crypto/gf128mul.c b/crypto/gf128mul.c
index a4b1c026aaee..a69ae3e6c16c 100644
--- a/crypto/gf128mul.c
+++ b/crypto/gf128mul.c
@@ -304,8 +304,8 @@ void gf128mul_free_64k(struct gf128mul_64k *t)
int i;
for (i = 0; i < 16; i++)
- kzfree(t->t[i]);
- kzfree(t);
+ kfree_sensitive(t->t[i]);
+ kfree_sensitive(t);
}
EXPORT_SYMBOL(gf128mul_free_64k);
diff --git a/crypto/hctr2.c b/crypto/hctr2.c
new file mode 100644
index 000000000000..7d00a3bcb667
--- /dev/null
+++ b/crypto/hctr2.c
@@ -0,0 +1,581 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * HCTR2 length-preserving encryption mode
+ *
+ * Copyright 2021 Google LLC
+ */
+
+
+/*
+ * HCTR2 is a length-preserving encryption mode that is efficient on
+ * processors with instructions to accelerate AES and carryless
+ * multiplication, e.g. x86 processors with AES-NI and CLMUL, and ARM
+ * processors with the ARMv8 crypto extensions.
+ *
+ * For more details, see the paper: "Length-preserving encryption with HCTR2"
+ * (https://eprint.iacr.org/2021/1441.pdf)
+ */
+
+#include <crypto/internal/cipher.h>
+#include <crypto/internal/hash.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/polyval.h>
+#include <crypto/scatterwalk.h>
+#include <linux/module.h>
+
+#define BLOCKCIPHER_BLOCK_SIZE 16
+
+/*
+ * The specification allows variable-length tweaks, but Linux's crypto API
+ * currently only allows algorithms to support a single length. The "natural"
+ * tweak length for HCTR2 is 16, since that fits into one POLYVAL block for
+ * the best performance. But longer tweaks are useful for fscrypt, to avoid
+ * needing to derive per-file keys. So instead we use two blocks, or 32 bytes.
+ */
+#define TWEAK_SIZE 32
+
+struct hctr2_instance_ctx {
+ struct crypto_cipher_spawn blockcipher_spawn;
+ struct crypto_skcipher_spawn xctr_spawn;
+ struct crypto_shash_spawn polyval_spawn;
+};
+
+struct hctr2_tfm_ctx {
+ struct crypto_cipher *blockcipher;
+ struct crypto_skcipher *xctr;
+ struct crypto_shash *polyval;
+ u8 L[BLOCKCIPHER_BLOCK_SIZE];
+ int hashed_tweak_offset;
+ /*
+ * This struct is allocated with extra space for two exported hash
+ * states. Since the hash state size is not known at compile-time, we
+ * can't add these to the struct directly.
+ *
+ * hashed_tweaklen_divisible;
+ * hashed_tweaklen_remainder;
+ */
+};
+
+struct hctr2_request_ctx {
+ u8 first_block[BLOCKCIPHER_BLOCK_SIZE];
+ u8 xctr_iv[BLOCKCIPHER_BLOCK_SIZE];
+ struct scatterlist *bulk_part_dst;
+ struct scatterlist *bulk_part_src;
+ struct scatterlist sg_src[2];
+ struct scatterlist sg_dst[2];
+ /*
+ * Sub-request sizes are unknown at compile-time, so they need to go
+ * after the members with known sizes.
+ */
+ union {
+ struct shash_desc hash_desc;
+ struct skcipher_request xctr_req;
+ } u;
+ /*
+ * This struct is allocated with extra space for one exported hash
+ * state. Since the hash state size is not known at compile-time, we
+ * can't add it to the struct directly.
+ *
+ * hashed_tweak;
+ */
+};
+
+static inline u8 *hctr2_hashed_tweaklen(const struct hctr2_tfm_ctx *tctx,
+ bool has_remainder)
+{
+ u8 *p = (u8 *)tctx + sizeof(*tctx);
+
+ if (has_remainder) /* For messages not a multiple of block length */
+ p += crypto_shash_statesize(tctx->polyval);
+ return p;
+}
+
+static inline u8 *hctr2_hashed_tweak(const struct hctr2_tfm_ctx *tctx,
+ struct hctr2_request_ctx *rctx)
+{
+ return (u8 *)rctx + tctx->hashed_tweak_offset;
+}
+
+/*
+ * The input data for each HCTR2 hash step begins with a 16-byte block that
+ * contains the tweak length and a flag that indicates whether the input is evenly
+ * divisible into blocks. Since this implementation only supports one tweak
+ * length, we precompute the two hash states resulting from hashing the two
+ * possible values of this initial block. This reduces by one block the amount of
+ * data that needs to be hashed for each encryption/decryption
+ *
+ * These precomputed hashes are stored in hctr2_tfm_ctx.
+ */
+static int hctr2_hash_tweaklen(struct hctr2_tfm_ctx *tctx, bool has_remainder)
+{
+ SHASH_DESC_ON_STACK(shash, tfm->polyval);
+ __le64 tweak_length_block[2];
+ int err;
+
+ shash->tfm = tctx->polyval;
+ memset(tweak_length_block, 0, sizeof(tweak_length_block));
+
+ tweak_length_block[0] = cpu_to_le64(TWEAK_SIZE * 8 * 2 + 2 + has_remainder);
+ err = crypto_shash_init(shash);
+ if (err)
+ return err;
+ err = crypto_shash_update(shash, (u8 *)tweak_length_block,
+ POLYVAL_BLOCK_SIZE);
+ if (err)
+ return err;
+ return crypto_shash_export(shash, hctr2_hashed_tweaklen(tctx, has_remainder));
+}
+
+static int hctr2_setkey(struct crypto_skcipher *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
+ u8 hbar[BLOCKCIPHER_BLOCK_SIZE];
+ int err;
+
+ crypto_cipher_clear_flags(tctx->blockcipher, CRYPTO_TFM_REQ_MASK);
+ crypto_cipher_set_flags(tctx->blockcipher,
+ crypto_skcipher_get_flags(tfm) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_cipher_setkey(tctx->blockcipher, key, keylen);
+ if (err)
+ return err;
+
+ crypto_skcipher_clear_flags(tctx->xctr, CRYPTO_TFM_REQ_MASK);
+ crypto_skcipher_set_flags(tctx->xctr,
+ crypto_skcipher_get_flags(tfm) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_skcipher_setkey(tctx->xctr, key, keylen);
+ if (err)
+ return err;
+
+ memset(hbar, 0, sizeof(hbar));
+ crypto_cipher_encrypt_one(tctx->blockcipher, hbar, hbar);
+
+ memset(tctx->L, 0, sizeof(tctx->L));
+ tctx->L[0] = 0x01;
+ crypto_cipher_encrypt_one(tctx->blockcipher, tctx->L, tctx->L);
+
+ crypto_shash_clear_flags(tctx->polyval, CRYPTO_TFM_REQ_MASK);
+ crypto_shash_set_flags(tctx->polyval, crypto_skcipher_get_flags(tfm) &
+ CRYPTO_TFM_REQ_MASK);
+ err = crypto_shash_setkey(tctx->polyval, hbar, BLOCKCIPHER_BLOCK_SIZE);
+ if (err)
+ return err;
+ memzero_explicit(hbar, sizeof(hbar));
+
+ return hctr2_hash_tweaklen(tctx, true) ?: hctr2_hash_tweaklen(tctx, false);
+}
+
+static int hctr2_hash_tweak(struct skcipher_request *req)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
+ struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
+ struct shash_desc *hash_desc = &rctx->u.hash_desc;
+ int err;
+ bool has_remainder = req->cryptlen % POLYVAL_BLOCK_SIZE;
+
+ hash_desc->tfm = tctx->polyval;
+ err = crypto_shash_import(hash_desc, hctr2_hashed_tweaklen(tctx, has_remainder));
+ if (err)
+ return err;
+ err = crypto_shash_update(hash_desc, req->iv, TWEAK_SIZE);
+ if (err)
+ return err;
+
+ // Store the hashed tweak, since we need it when computing both
+ // H(T || N) and H(T || V).
+ return crypto_shash_export(hash_desc, hctr2_hashed_tweak(tctx, rctx));
+}
+
+static int hctr2_hash_message(struct skcipher_request *req,
+ struct scatterlist *sgl,
+ u8 digest[POLYVAL_DIGEST_SIZE])
+{
+ static const u8 padding[BLOCKCIPHER_BLOCK_SIZE] = { 0x1 };
+ struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
+ struct shash_desc *hash_desc = &rctx->u.hash_desc;
+ const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
+ struct sg_mapping_iter miter;
+ unsigned int remainder = bulk_len % BLOCKCIPHER_BLOCK_SIZE;
+ int i;
+ int err = 0;
+ int n = 0;
+
+ sg_miter_start(&miter, sgl, sg_nents(sgl),
+ SG_MITER_FROM_SG | SG_MITER_ATOMIC);
+ for (i = 0; i < bulk_len; i += n) {
+ sg_miter_next(&miter);
+ n = min_t(unsigned int, miter.length, bulk_len - i);
+ err = crypto_shash_update(hash_desc, miter.addr, n);
+ if (err)
+ break;
+ }
+ sg_miter_stop(&miter);
+
+ if (err)
+ return err;
+
+ if (remainder) {
+ err = crypto_shash_update(hash_desc, padding,
+ BLOCKCIPHER_BLOCK_SIZE - remainder);
+ if (err)
+ return err;
+ }
+ return crypto_shash_final(hash_desc, digest);
+}
+
+static int hctr2_finish(struct skcipher_request *req)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
+ struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
+ u8 digest[POLYVAL_DIGEST_SIZE];
+ struct shash_desc *hash_desc = &rctx->u.hash_desc;
+ int err;
+
+ // U = UU ^ H(T || V)
+ // or M = MM ^ H(T || N)
+ hash_desc->tfm = tctx->polyval;
+ err = crypto_shash_import(hash_desc, hctr2_hashed_tweak(tctx, rctx));
+ if (err)
+ return err;
+ err = hctr2_hash_message(req, rctx->bulk_part_dst, digest);
+ if (err)
+ return err;
+ crypto_xor(rctx->first_block, digest, BLOCKCIPHER_BLOCK_SIZE);
+
+ // Copy U (or M) into dst scatterlist
+ scatterwalk_map_and_copy(rctx->first_block, req->dst,
+ 0, BLOCKCIPHER_BLOCK_SIZE, 1);
+ return 0;
+}
+
+static void hctr2_xctr_done(struct crypto_async_request *areq,
+ int err)
+{
+ struct skcipher_request *req = areq->data;
+
+ if (!err)
+ err = hctr2_finish(req);
+
+ skcipher_request_complete(req, err);
+}
+
+static int hctr2_crypt(struct skcipher_request *req, bool enc)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ const struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
+ struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
+ u8 digest[POLYVAL_DIGEST_SIZE];
+ int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
+ int err;
+
+ // Requests must be at least one block
+ if (req->cryptlen < BLOCKCIPHER_BLOCK_SIZE)
+ return -EINVAL;
+
+ // Copy M (or U) into a temporary buffer
+ scatterwalk_map_and_copy(rctx->first_block, req->src,
+ 0, BLOCKCIPHER_BLOCK_SIZE, 0);
+
+ // Create scatterlists for N and V
+ rctx->bulk_part_src = scatterwalk_ffwd(rctx->sg_src, req->src,
+ BLOCKCIPHER_BLOCK_SIZE);
+ rctx->bulk_part_dst = scatterwalk_ffwd(rctx->sg_dst, req->dst,
+ BLOCKCIPHER_BLOCK_SIZE);
+
+ // MM = M ^ H(T || N)
+ // or UU = U ^ H(T || V)
+ err = hctr2_hash_tweak(req);
+ if (err)
+ return err;
+ err = hctr2_hash_message(req, rctx->bulk_part_src, digest);
+ if (err)
+ return err;
+ crypto_xor(digest, rctx->first_block, BLOCKCIPHER_BLOCK_SIZE);
+
+ // UU = E(MM)
+ // or MM = D(UU)
+ if (enc)
+ crypto_cipher_encrypt_one(tctx->blockcipher, rctx->first_block,
+ digest);
+ else
+ crypto_cipher_decrypt_one(tctx->blockcipher, rctx->first_block,
+ digest);
+
+ // S = MM ^ UU ^ L
+ crypto_xor(digest, rctx->first_block, BLOCKCIPHER_BLOCK_SIZE);
+ crypto_xor_cpy(rctx->xctr_iv, digest, tctx->L, BLOCKCIPHER_BLOCK_SIZE);
+
+ // V = XCTR(S, N)
+ // or N = XCTR(S, V)
+ skcipher_request_set_tfm(&rctx->u.xctr_req, tctx->xctr);
+ skcipher_request_set_crypt(&rctx->u.xctr_req, rctx->bulk_part_src,
+ rctx->bulk_part_dst, bulk_len,
+ rctx->xctr_iv);
+ skcipher_request_set_callback(&rctx->u.xctr_req,
+ req->base.flags,
+ hctr2_xctr_done, req);
+ return crypto_skcipher_encrypt(&rctx->u.xctr_req) ?:
+ hctr2_finish(req);
+}
+
+static int hctr2_encrypt(struct skcipher_request *req)
+{
+ return hctr2_crypt(req, true);
+}
+
+static int hctr2_decrypt(struct skcipher_request *req)
+{
+ return hctr2_crypt(req, false);
+}
+
+static int hctr2_init_tfm(struct crypto_skcipher *tfm)
+{
+ struct skcipher_instance *inst = skcipher_alg_instance(tfm);
+ struct hctr2_instance_ctx *ictx = skcipher_instance_ctx(inst);
+ struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
+ struct crypto_skcipher *xctr;
+ struct crypto_cipher *blockcipher;
+ struct crypto_shash *polyval;
+ unsigned int subreq_size;
+ int err;
+
+ xctr = crypto_spawn_skcipher(&ictx->xctr_spawn);
+ if (IS_ERR(xctr))
+ return PTR_ERR(xctr);
+
+ blockcipher = crypto_spawn_cipher(&ictx->blockcipher_spawn);
+ if (IS_ERR(blockcipher)) {
+ err = PTR_ERR(blockcipher);
+ goto err_free_xctr;
+ }
+
+ polyval = crypto_spawn_shash(&ictx->polyval_spawn);
+ if (IS_ERR(polyval)) {
+ err = PTR_ERR(polyval);
+ goto err_free_blockcipher;
+ }
+
+ tctx->xctr = xctr;
+ tctx->blockcipher = blockcipher;
+ tctx->polyval = polyval;
+
+ BUILD_BUG_ON(offsetofend(struct hctr2_request_ctx, u) !=
+ sizeof(struct hctr2_request_ctx));
+ subreq_size = max(sizeof_field(struct hctr2_request_ctx, u.hash_desc) +
+ crypto_shash_descsize(polyval),
+ sizeof_field(struct hctr2_request_ctx, u.xctr_req) +
+ crypto_skcipher_reqsize(xctr));
+
+ tctx->hashed_tweak_offset = offsetof(struct hctr2_request_ctx, u) +
+ subreq_size;
+ crypto_skcipher_set_reqsize(tfm, tctx->hashed_tweak_offset +
+ crypto_shash_statesize(polyval));
+ return 0;
+
+err_free_blockcipher:
+ crypto_free_cipher(blockcipher);
+err_free_xctr:
+ crypto_free_skcipher(xctr);
+ return err;
+}
+
+static void hctr2_exit_tfm(struct crypto_skcipher *tfm)
+{
+ struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
+
+ crypto_free_cipher(tctx->blockcipher);
+ crypto_free_skcipher(tctx->xctr);
+ crypto_free_shash(tctx->polyval);
+}
+
+static void hctr2_free_instance(struct skcipher_instance *inst)
+{
+ struct hctr2_instance_ctx *ictx = skcipher_instance_ctx(inst);
+
+ crypto_drop_cipher(&ictx->blockcipher_spawn);
+ crypto_drop_skcipher(&ictx->xctr_spawn);
+ crypto_drop_shash(&ictx->polyval_spawn);
+ kfree(inst);
+}
+
+static int hctr2_create_common(struct crypto_template *tmpl,
+ struct rtattr **tb,
+ const char *xctr_name,
+ const char *polyval_name)
+{
+ u32 mask;
+ struct skcipher_instance *inst;
+ struct hctr2_instance_ctx *ictx;
+ struct skcipher_alg *xctr_alg;
+ struct crypto_alg *blockcipher_alg;
+ struct shash_alg *polyval_alg;
+ char blockcipher_name[CRYPTO_MAX_ALG_NAME];
+ int len;
+ int err;
+
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
+ if (err)
+ return err;
+
+ inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL);
+ if (!inst)
+ return -ENOMEM;
+ ictx = skcipher_instance_ctx(inst);
+
+ /* Stream cipher, xctr(block_cipher) */
+ err = crypto_grab_skcipher(&ictx->xctr_spawn,
+ skcipher_crypto_instance(inst),
+ xctr_name, 0, mask);
+ if (err)
+ goto err_free_inst;
+ xctr_alg = crypto_spawn_skcipher_alg(&ictx->xctr_spawn);
+
+ err = -EINVAL;
+ if (strncmp(xctr_alg->base.cra_name, "xctr(", 5))
+ goto err_free_inst;
+ len = strscpy(blockcipher_name, xctr_alg->base.cra_name + 5,
+ sizeof(blockcipher_name));
+ if (len < 1)
+ goto err_free_inst;
+ if (blockcipher_name[len - 1] != ')')
+ goto err_free_inst;
+ blockcipher_name[len - 1] = 0;
+
+ /* Block cipher, e.g. "aes" */
+ err = crypto_grab_cipher(&ictx->blockcipher_spawn,
+ skcipher_crypto_instance(inst),
+ blockcipher_name, 0, mask);
+ if (err)
+ goto err_free_inst;
+ blockcipher_alg = crypto_spawn_cipher_alg(&ictx->blockcipher_spawn);
+
+ /* Require blocksize of 16 bytes */
+ err = -EINVAL;
+ if (blockcipher_alg->cra_blocksize != BLOCKCIPHER_BLOCK_SIZE)
+ goto err_free_inst;
+
+ /* Polyval ε-∆U hash function */
+ err = crypto_grab_shash(&ictx->polyval_spawn,
+ skcipher_crypto_instance(inst),
+ polyval_name, 0, mask);
+ if (err)
+ goto err_free_inst;
+ polyval_alg = crypto_spawn_shash_alg(&ictx->polyval_spawn);
+
+ /* Ensure Polyval is being used */
+ err = -EINVAL;
+ if (strcmp(polyval_alg->base.cra_name, "polyval") != 0)
+ goto err_free_inst;
+
+ /* Instance fields */
+
+ err = -ENAMETOOLONG;
+ if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME, "hctr2(%s)",
+ blockcipher_alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
+ goto err_free_inst;
+ if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+ "hctr2_base(%s,%s)",
+ xctr_alg->base.cra_driver_name,
+ polyval_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
+ goto err_free_inst;
+
+ inst->alg.base.cra_blocksize = BLOCKCIPHER_BLOCK_SIZE;
+ inst->alg.base.cra_ctxsize = sizeof(struct hctr2_tfm_ctx) +
+ polyval_alg->statesize * 2;
+ inst->alg.base.cra_alignmask = xctr_alg->base.cra_alignmask |
+ polyval_alg->base.cra_alignmask;
+ /*
+ * The hash function is called twice, so it is weighted higher than the
+ * xctr and blockcipher.
+ */
+ inst->alg.base.cra_priority = (2 * xctr_alg->base.cra_priority +
+ 4 * polyval_alg->base.cra_priority +
+ blockcipher_alg->cra_priority) / 7;
+
+ inst->alg.setkey = hctr2_setkey;
+ inst->alg.encrypt = hctr2_encrypt;
+ inst->alg.decrypt = hctr2_decrypt;
+ inst->alg.init = hctr2_init_tfm;
+ inst->alg.exit = hctr2_exit_tfm;
+ inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(xctr_alg);
+ inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(xctr_alg);
+ inst->alg.ivsize = TWEAK_SIZE;
+
+ inst->free = hctr2_free_instance;
+
+ err = skcipher_register_instance(tmpl, inst);
+ if (err) {
+err_free_inst:
+ hctr2_free_instance(inst);
+ }
+ return err;
+}
+
+static int hctr2_create_base(struct crypto_template *tmpl, struct rtattr **tb)
+{
+ const char *xctr_name;
+ const char *polyval_name;
+
+ xctr_name = crypto_attr_alg_name(tb[1]);
+ if (IS_ERR(xctr_name))
+ return PTR_ERR(xctr_name);
+
+ polyval_name = crypto_attr_alg_name(tb[2]);
+ if (IS_ERR(polyval_name))
+ return PTR_ERR(polyval_name);
+
+ return hctr2_create_common(tmpl, tb, xctr_name, polyval_name);
+}
+
+static int hctr2_create(struct crypto_template *tmpl, struct rtattr **tb)
+{
+ const char *blockcipher_name;
+ char xctr_name[CRYPTO_MAX_ALG_NAME];
+
+ blockcipher_name = crypto_attr_alg_name(tb[1]);
+ if (IS_ERR(blockcipher_name))
+ return PTR_ERR(blockcipher_name);
+
+ if (snprintf(xctr_name, CRYPTO_MAX_ALG_NAME, "xctr(%s)",
+ blockcipher_name) >= CRYPTO_MAX_ALG_NAME)
+ return -ENAMETOOLONG;
+
+ return hctr2_create_common(tmpl, tb, xctr_name, "polyval");
+}
+
+static struct crypto_template hctr2_tmpls[] = {
+ {
+ /* hctr2_base(xctr_name, polyval_name) */
+ .name = "hctr2_base",
+ .create = hctr2_create_base,
+ .module = THIS_MODULE,
+ }, {
+ /* hctr2(blockcipher_name) */
+ .name = "hctr2",
+ .create = hctr2_create,
+ .module = THIS_MODULE,
+ }
+};
+
+static int __init hctr2_module_init(void)
+{
+ return crypto_register_templates(hctr2_tmpls, ARRAY_SIZE(hctr2_tmpls));
+}
+
+static void __exit hctr2_module_exit(void)
+{
+ return crypto_unregister_templates(hctr2_tmpls,
+ ARRAY_SIZE(hctr2_tmpls));
+}
+
+subsys_initcall(hctr2_module_init);
+module_exit(hctr2_module_exit);
+
+MODULE_DESCRIPTION("HCTR2 length-preserving encryption mode");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS_CRYPTO("hctr2");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/hmac.c b/crypto/hmac.c
index e38bfb948278..3610ff0b6739 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -15,6 +15,7 @@
#include <crypto/internal/hash.h>
#include <crypto/scatterwalk.h>
#include <linux/err.h>
+#include <linux/fips.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -51,6 +52,9 @@ static int hmac_setkey(struct crypto_shash *parent,
SHASH_DESC_ON_STACK(shash, hash);
unsigned int i;
+ if (fips_enabled && (keylen < 112 / 8))
+ return -EINVAL;
+
shash->tfm = hash;
if (keylen > bs) {
@@ -168,11 +172,12 @@ static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb)
struct crypto_shash_spawn *spawn;
struct crypto_alg *alg;
struct shash_alg *salg;
+ u32 mask;
int err;
int ds;
int ss;
- err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask);
if (err)
return err;
@@ -182,7 +187,7 @@ static int hmac_create(struct crypto_template *tmpl, struct rtattr **tb)
spawn = shash_instance_ctx(inst);
err = crypto_grab_shash(spawn, shash_crypto_instance(inst),
- crypto_attr_alg_name(tb[1]), 0, 0);
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
goto err_free_inst;
salg = crypto_spawn_shash_alg(spawn);
diff --git a/crypto/internal.h b/crypto/internal.h
index d5ebc60c5143..c08385571853 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -10,16 +10,15 @@
#include <crypto/algapi.h>
#include <linux/completion.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
+#include <linux/jump_label.h>
#include <linux/list.h>
#include <linux/module.h>
-#include <linux/kernel.h>
#include <linux/notifier.h>
+#include <linux/numa.h>
+#include <linux/refcount.h>
#include <linux/rwsem.h>
-#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/types.h>
struct crypto_instance;
struct crypto_template;
@@ -29,12 +28,27 @@ struct crypto_larval {
struct crypto_alg *adult;
struct completion completion;
u32 mask;
+ bool test_started;
};
+enum {
+ CRYPTOA_UNSPEC,
+ CRYPTOA_ALG,
+ CRYPTOA_TYPE,
+ __CRYPTOA_MAX,
+};
+
+#define CRYPTOA_MAX (__CRYPTOA_MAX - 1)
+
+/* Maximum number of (rtattr) parameters for each template. */
+#define CRYPTO_MAX_ATTRS 32
+
extern struct list_head crypto_alg_list;
extern struct rw_semaphore crypto_alg_sem;
extern struct blocking_notifier_head crypto_chain;
+DECLARE_STATIC_KEY_FALSE(crypto_boot_test_finished);
+
#ifdef CONFIG_PROC_FS
void __init crypto_init_proc(void);
void __exit crypto_exit_proc(void);
@@ -60,20 +74,37 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask);
struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask);
void crypto_larval_kill(struct crypto_alg *alg);
+void crypto_wait_for_test(struct crypto_larval *larval);
void crypto_alg_tested(const char *name, int err);
void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
struct crypto_alg *nalg);
void crypto_remove_final(struct list_head *list);
+void crypto_shoot_alg(struct crypto_alg *alg);
struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type,
u32 mask);
-void *crypto_create_tfm(struct crypto_alg *alg,
- const struct crypto_type *frontend);
+void *crypto_create_tfm_node(struct crypto_alg *alg,
+ const struct crypto_type *frontend, int node);
+
+static inline void *crypto_create_tfm(struct crypto_alg *alg,
+ const struct crypto_type *frontend)
+{
+ return crypto_create_tfm_node(alg, frontend, NUMA_NO_NODE);
+}
+
struct crypto_alg *crypto_find_alg(const char *alg_name,
const struct crypto_type *frontend,
u32 type, u32 mask);
-void *crypto_alloc_tfm(const char *alg_name,
- const struct crypto_type *frontend, u32 type, u32 mask);
+
+void *crypto_alloc_tfm_node(const char *alg_name,
+ const struct crypto_type *frontend, u32 type, u32 mask,
+ int node);
+
+static inline void *crypto_alloc_tfm(const char *alg_name,
+ const struct crypto_type *frontend, u32 type, u32 mask)
+{
+ return crypto_alloc_tfm_node(alg_name, frontend, type, mask, NUMA_NO_NODE);
+}
int crypto_probing_notify(unsigned long val, void *v);
@@ -124,5 +155,16 @@ static inline void crypto_notify(unsigned long val, void *v)
blocking_notifier_call_chain(&crypto_chain, val, v);
}
+static inline void crypto_yield(u32 flags)
+{
+ if (flags & CRYPTO_TFM_REQ_MAY_SLEEP)
+ cond_resched();
+}
+
+static inline int crypto_is_test_larval(struct crypto_larval *larval)
+{
+ return larval->alg.cra_driver_name[0];
+}
+
#endif /* _CRYPTO_INTERNAL_H */
diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index a5ce8f96790f..2d115bec15ae 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -37,11 +37,10 @@
* DAMAGE.
*/
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/fips.h>
#include <linux/time.h>
-#include <linux/crypto.h>
#include <crypto/internal/rng.h>
#include "jitterentropy.h"
@@ -57,12 +56,7 @@ void *jent_zalloc(unsigned int len)
void jent_zfree(void *ptr)
{
- kzfree(ptr);
-}
-
-int jent_fips_enabled(void)
-{
- return fips_enabled;
+ kfree_sensitive(ptr);
}
void jent_panic(char *s)
@@ -108,6 +102,7 @@ void jent_get_nstime(__u64 *out)
struct jitterentropy {
spinlock_t jent_lock;
struct rand_data *entropy_collector;
+ unsigned int reset_cnt;
};
static int jent_kcapi_init(struct crypto_tfm *tfm)
@@ -142,7 +137,33 @@ static int jent_kcapi_random(struct crypto_rng *tfm,
int ret = 0;
spin_lock(&rng->jent_lock);
+
+ /* Return a permanent error in case we had too many resets in a row. */
+ if (rng->reset_cnt > (1<<10)) {
+ ret = -EFAULT;
+ goto out;
+ }
+
ret = jent_read_entropy(rng->entropy_collector, rdata, dlen);
+
+ /* Reset RNG in case of health failures */
+ if (ret < -1) {
+ pr_warn_ratelimited("Reset Jitter RNG due to health test failure: %s failure\n",
+ (ret == -2) ? "Repetition Count Test" :
+ "Adaptive Proportion Test");
+
+ rng->reset_cnt++;
+
+ ret = -EAGAIN;
+ } else {
+ rng->reset_cnt = 0;
+
+ /* Convert the Jitter RNG error into a usable error code */
+ if (ret == -1)
+ ret = -EINVAL;
+ }
+
+out:
spin_unlock(&rng->jent_lock);
return ret;
diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c
index 042157f0d28b..93bff3213823 100644
--- a/crypto/jitterentropy.c
+++ b/crypto/jitterentropy.c
@@ -2,12 +2,12 @@
* Non-physical true random number generator based on timing jitter --
* Jitter RNG standalone code.
*
- * Copyright Stephan Mueller <smueller@chronox.de>, 2015 - 2019
+ * Copyright Stephan Mueller <smueller@chronox.de>, 2015 - 2020
*
* Design
* ======
*
- * See http://www.chronox.de/jent.html
+ * See https://www.chronox.de/jent.html
*
* License
* =======
@@ -47,7 +47,7 @@
/*
* This Jitterentropy RNG is based on the jitterentropy library
- * version 2.1.2 provided at http://www.chronox.de/jent.html
+ * version 2.2.0 provided at https://www.chronox.de/jent.html
*/
#ifdef __OPTIMIZE__
@@ -83,6 +83,22 @@ struct rand_data {
unsigned int memblocksize; /* Size of one memory block in bytes */
unsigned int memaccessloops; /* Number of memory accesses per random
* bit generation */
+
+ /* Repetition Count Test */
+ int rct_count; /* Number of stuck values */
+
+ /* Adaptive Proportion Test for a significance level of 2^-30 */
+#define JENT_APT_CUTOFF 325 /* Taken from SP800-90B sec 4.4.2 */
+#define JENT_APT_WINDOW_SIZE 512 /* Data window size */
+ /* LSB of time stamp to process */
+#define JENT_APT_LSB 16
+#define JENT_APT_WORD_MASK (JENT_APT_LSB - 1)
+ unsigned int apt_observations; /* Number of collected observations */
+ unsigned int apt_count; /* APT counter */
+ unsigned int apt_base; /* APT base reference */
+ unsigned int apt_base_set:1; /* APT base reference set? */
+
+ unsigned int health_failure:1; /* Permanent health failure */
};
/* Flags that can be used to initialize the RNG */
@@ -98,14 +114,214 @@ struct rand_data {
* variations (2nd derivation of time is
* zero). */
#define JENT_ESTUCK 8 /* Too many stuck results during init. */
+#define JENT_EHEALTH 9 /* Health test failed during initialization */
+#define JENT_ERCT 10 /* RCT failed during initialization */
+
+/*
+ * The output n bits can receive more than n bits of min entropy, of course,
+ * but the fixed output of the conditioning function can only asymptotically
+ * approach the output size bits of min entropy, not attain that bound. Random
+ * maps will tend to have output collisions, which reduces the creditable
+ * output entropy (that is what SP 800-90B Section 3.1.5.1.2 attempts to bound).
+ *
+ * The value "64" is justified in Appendix A.4 of the current 90C draft,
+ * and aligns with NIST's in "epsilon" definition in this document, which is
+ * that a string can be considered "full entropy" if you can bound the min
+ * entropy in each bit of output to at least 1-epsilon, where epsilon is
+ * required to be <= 2^(-32).
+ */
+#define JENT_ENTROPY_SAFETY_FACTOR 64
+
+#include <linux/fips.h>
+#include "jitterentropy.h"
/***************************************************************************
- * Helper functions
+ * Adaptive Proportion Test
+ *
+ * This test complies with SP800-90B section 4.4.2.
***************************************************************************/
-#include "jitterentropy.h"
+/*
+ * Reset the APT counter
+ *
+ * @ec [in] Reference to entropy collector
+ */
+static void jent_apt_reset(struct rand_data *ec, unsigned int delta_masked)
+{
+ /* Reset APT counter */
+ ec->apt_count = 0;
+ ec->apt_base = delta_masked;
+ ec->apt_observations = 0;
+}
+
+/*
+ * Insert a new entropy event into APT
+ *
+ * @ec [in] Reference to entropy collector
+ * @delta_masked [in] Masked time delta to process
+ */
+static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked)
+{
+ /* Initialize the base reference */
+ if (!ec->apt_base_set) {
+ ec->apt_base = delta_masked;
+ ec->apt_base_set = 1;
+ return;
+ }
+
+ if (delta_masked == ec->apt_base) {
+ ec->apt_count++;
+
+ if (ec->apt_count >= JENT_APT_CUTOFF)
+ ec->health_failure = 1;
+ }
+
+ ec->apt_observations++;
+
+ if (ec->apt_observations >= JENT_APT_WINDOW_SIZE)
+ jent_apt_reset(ec, delta_masked);
+}
+
+/***************************************************************************
+ * Stuck Test and its use as Repetition Count Test
+ *
+ * The Jitter RNG uses an enhanced version of the Repetition Count Test
+ * (RCT) specified in SP800-90B section 4.4.1. Instead of counting identical
+ * back-to-back values, the input to the RCT is the counting of the stuck
+ * values during the generation of one Jitter RNG output block.
+ *
+ * The RCT is applied with an alpha of 2^{-30} compliant to FIPS 140-2 IG 9.8.
+ *
+ * During the counting operation, the Jitter RNG always calculates the RCT
+ * cut-off value of C. If that value exceeds the allowed cut-off value,
+ * the Jitter RNG output block will be calculated completely but discarded at
+ * the end. The caller of the Jitter RNG is informed with an error code.
+ ***************************************************************************/
+
+/*
+ * Repetition Count Test as defined in SP800-90B section 4.4.1
+ *
+ * @ec [in] Reference to entropy collector
+ * @stuck [in] Indicator whether the value is stuck
+ */
+static void jent_rct_insert(struct rand_data *ec, int stuck)
+{
+ /*
+ * If we have a count less than zero, a previous RCT round identified
+ * a failure. We will not overwrite it.
+ */
+ if (ec->rct_count < 0)
+ return;
+
+ if (stuck) {
+ ec->rct_count++;
+
+ /*
+ * The cutoff value is based on the following consideration:
+ * alpha = 2^-30 as recommended in FIPS 140-2 IG 9.8.
+ * In addition, we require an entropy value H of 1/OSR as this
+ * is the minimum entropy required to provide full entropy.
+ * Note, we collect 64 * OSR deltas for inserting them into
+ * the entropy pool which should then have (close to) 64 bits
+ * of entropy.
+ *
+ * Note, ec->rct_count (which equals to value B in the pseudo
+ * code of SP800-90B section 4.4.1) starts with zero. Hence
+ * we need to subtract one from the cutoff value as calculated
+ * following SP800-90B.
+ */
+ if ((unsigned int)ec->rct_count >= (31 * ec->osr)) {
+ ec->rct_count = -1;
+ ec->health_failure = 1;
+ }
+ } else {
+ ec->rct_count = 0;
+ }
+}
+
+/*
+ * Is there an RCT health test failure?
+ *
+ * @ec [in] Reference to entropy collector
+ *
+ * @return
+ * 0 No health test failure
+ * 1 Permanent health test failure
+ */
+static int jent_rct_failure(struct rand_data *ec)
+{
+ if (ec->rct_count < 0)
+ return 1;
+ return 0;
+}
+
+static inline __u64 jent_delta(__u64 prev, __u64 next)
+{
+#define JENT_UINT64_MAX (__u64)(~((__u64) 0))
+ return (prev < next) ? (next - prev) :
+ (JENT_UINT64_MAX - prev + 1 + next);
+}
+
+/*
+ * Stuck test by checking the:
+ * 1st derivative of the jitter measurement (time delta)
+ * 2nd derivative of the jitter measurement (delta of time deltas)
+ * 3rd derivative of the jitter measurement (delta of delta of time deltas)
+ *
+ * All values must always be non-zero.
+ *
+ * @ec [in] Reference to entropy collector
+ * @current_delta [in] Jitter time delta
+ *
+ * @return
+ * 0 jitter measurement not stuck (good bit)
+ * 1 jitter measurement stuck (reject bit)
+ */
+static int jent_stuck(struct rand_data *ec, __u64 current_delta)
+{
+ __u64 delta2 = jent_delta(ec->last_delta, current_delta);
+ __u64 delta3 = jent_delta(ec->last_delta2, delta2);
+
+ ec->last_delta = current_delta;
+ ec->last_delta2 = delta2;
+
+ /*
+ * Insert the result of the comparison of two back-to-back time
+ * deltas.
+ */
+ jent_apt_insert(ec, current_delta);
+
+ if (!current_delta || !delta2 || !delta3) {
+ /* RCT with a stuck bit */
+ jent_rct_insert(ec, 1);
+ return 1;
+ }
+
+ /* RCT with a non-stuck bit */
+ jent_rct_insert(ec, 0);
+
+ return 0;
+}
-/**
+/*
+ * Report any health test failures
+ *
+ * @ec [in] Reference to entropy collector
+ *
+ * @return
+ * 0 No health test failure
+ * 1 Permanent health test failure
+ */
+static int jent_health_failure(struct rand_data *ec)
+{
+ return ec->health_failure;
+}
+
+/***************************************************************************
+ * Noise sources
+ ***************************************************************************/
+
+/*
* Update of the loop count used for the next round of
* an entropy collection.
*
@@ -148,11 +364,7 @@ static __u64 jent_loop_shuffle(struct rand_data *ec,
return (shuffle + (1<<min));
}
-/***************************************************************************
- * Noise sources
- ***************************************************************************/
-
-/**
+/*
* CPU Jitter noise source -- this is the noise source based on the CPU
* execution time jitter
*
@@ -166,18 +378,19 @@ static __u64 jent_loop_shuffle(struct rand_data *ec,
* the CPU execution time jitter. Any change to the loop in this function
* implies that careful retesting must be done.
*
- * Input:
- * @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
+ * @ec [in] entropy collector struct
+ * @time [in] time stamp to be injected
+ * @loop_cnt [in] if a value not equal to 0 is set, use the given value as
+ * number of loops to perform the folding
+ * @stuck [in] Is the time stamp identified as stuck?
*
* Output:
* updated ec->data
*
* @return Number of loops the folding operation is performed
*/
-static __u64 jent_lfsr_time(struct rand_data *ec, __u64 time, __u64 loop_cnt)
+static void jent_lfsr_time(struct rand_data *ec, __u64 time, __u64 loop_cnt,
+ int stuck)
{
unsigned int i;
__u64 j = 0;
@@ -220,12 +433,20 @@ static __u64 jent_lfsr_time(struct rand_data *ec, __u64 time, __u64 loop_cnt)
new ^= tmp;
}
}
- ec->data = new;
- return fold_loop_cnt;
+ /*
+ * If the time stamp is stuck, do not finally insert the value into
+ * the entropy pool. Although this operation should not do any harm
+ * even when the time stamp has no entropy, SP800-90B requires that
+ * any conditioning operation (SP800-90B considers the LFSR to be a
+ * conditioning operation) to have an identical amount of input
+ * data according to section 3.1.5.
+ */
+ if (!stuck)
+ ec->data = new;
}
-/**
+/*
* Memory Access noise source -- this is a noise source based on variations in
* memory access times
*
@@ -243,16 +464,13 @@ static __u64 jent_lfsr_time(struct rand_data *ec, __u64 time, __u64 loop_cnt)
* to reliably access either L3 or memory, the ec->mem memory must be quite
* large which is usually not desirable.
*
- * Input:
- * @ec Reference to the entropy collector with the memory access data -- if
- * the reference to the memory block to be accessed is NULL, this noise
- * source is disabled
- * @loop_cnt if a value not equal to 0 is set, use the given value as number of
- * loops to perform the folding
- *
- * @return Number of memory access operations
+ * @ec [in] Reference to the entropy collector with the memory access data -- if
+ * the reference to the memory block to be accessed is NULL, this noise
+ * source is disabled
+ * @loop_cnt [in] if a value not equal to 0 is set, use the given value
+ * number of loops to perform the LFSR
*/
-static unsigned int jent_memaccess(struct rand_data *ec, __u64 loop_cnt)
+static void jent_memaccess(struct rand_data *ec, __u64 loop_cnt)
{
unsigned int wrap = 0;
__u64 i = 0;
@@ -262,7 +480,7 @@ static unsigned int jent_memaccess(struct rand_data *ec, __u64 loop_cnt)
jent_loop_shuffle(ec, MAX_ACC_LOOP_BIT, MIN_ACC_LOOP_BIT);
if (NULL == ec || NULL == ec->mem)
- return 0;
+ return;
wrap = ec->memblocksize * ec->memblocks;
/*
@@ -288,44 +506,12 @@ static unsigned int jent_memaccess(struct rand_data *ec, __u64 loop_cnt)
ec->memlocation = ec->memlocation + ec->memblocksize - 1;
ec->memlocation = ec->memlocation % wrap;
}
- return i;
}
/***************************************************************************
* Start of entropy processing logic
***************************************************************************/
-
-/**
- * Stuck test by checking the:
- * 1st derivation of the jitter measurement (time delta)
- * 2nd derivation of the jitter measurement (delta of time deltas)
- * 3rd derivation of the jitter measurement (delta of delta of time deltas)
- *
- * All values must always be non-zero.
- *
- * Input:
- * @ec Reference to entropy collector
- * @current_delta Jitter time delta
- *
- * @return
- * 0 jitter measurement not stuck (good bit)
- * 1 jitter measurement stuck (reject bit)
- */
-static int jent_stuck(struct rand_data *ec, __u64 current_delta)
-{
- __s64 delta2 = ec->last_delta - current_delta;
- __s64 delta3 = delta2 - ec->last_delta2;
-
- ec->last_delta = current_delta;
- ec->last_delta2 = delta2;
-
- if (!current_delta || !delta2 || !delta3)
- return 1;
-
- return 0;
-}
-
-/**
+/*
* This is the heart of the entropy generation: calculate time deltas and
* use the CPU jitter in the time deltas. The jitter is injected into the
* entropy pool.
@@ -334,8 +520,7 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta)
* of this function! This can be done by calling this function
* and not using its result.
*
- * Input:
- * @entropy_collector Reference to entropy collector
+ * @ec [in] Reference to entropy collector
*
* @return result of stuck test
*/
@@ -343,6 +528,7 @@ static int jent_measure_jitter(struct rand_data *ec)
{
__u64 time = 0;
__u64 current_delta = 0;
+ int stuck;
/* Invoke one noise source before time measurement to add variations */
jent_memaccess(ec, 0);
@@ -352,31 +538,35 @@ static int jent_measure_jitter(struct rand_data *ec)
* invocation to measure the timing variations
*/
jent_get_nstime(&time);
- current_delta = time - ec->prev_time;
+ current_delta = jent_delta(ec->prev_time, time);
ec->prev_time = time;
+ /* Check whether we have a stuck measurement. */
+ stuck = jent_stuck(ec, current_delta);
+
/* Now call the next noise sources which also injects the data */
- jent_lfsr_time(ec, current_delta, 0);
+ jent_lfsr_time(ec, current_delta, 0, stuck);
- /* Check whether we have a stuck measurement. */
- return jent_stuck(ec, current_delta);
+ return stuck;
}
-/**
+/*
* Generator of one 64 bit random number
* Function fills rand_data->data
*
- * Input:
- * @ec Reference to entropy collector
+ * @ec [in] Reference to entropy collector
*/
static void jent_gen_entropy(struct rand_data *ec)
{
- unsigned int k = 0;
+ unsigned int k = 0, safety_factor = 0;
+
+ if (fips_enabled)
+ safety_factor = JENT_ENTROPY_SAFETY_FACTOR;
/* priming of the ->prev_time value */
jent_measure_jitter(ec);
- while (1) {
+ while (!jent_health_failure(ec)) {
/* If a stuck measurement is received, repeat measurement */
if (jent_measure_jitter(ec))
continue;
@@ -385,37 +575,12 @@ static void jent_gen_entropy(struct rand_data *ec)
* We multiply the loop value with ->osr to obtain the
* oversampling rate requested by the caller
*/
- if (++k >= (DATA_SIZE_BITS * ec->osr))
+ if (++k >= ((DATA_SIZE_BITS + safety_factor) * ec->osr))
break;
}
}
-/**
- * The continuous test required by FIPS 140-2 -- the function automatically
- * primes the test if needed.
- *
- * Return:
- * returns normally if FIPS test passed
- * panics the kernel if FIPS test failed
- */
-static void jent_fips_test(struct rand_data *ec)
-{
- if (!jent_fips_enabled())
- return;
-
- /* prime the FIPS test */
- if (!ec->old_data) {
- ec->old_data = ec->data;
- jent_gen_entropy(ec);
- }
-
- if (ec->data == ec->old_data)
- jent_panic("jitterentropy: Duplicate output detected\n");
-
- ec->old_data = ec->data;
-}
-
-/**
+/*
* Entry function: Obtain entropy for the caller.
*
* This function invokes the entropy gathering logic as often to generate
@@ -425,17 +590,18 @@ static void jent_fips_test(struct rand_data *ec)
* This function truncates the last 64 bit entropy value output to the exact
* size specified by the caller.
*
- * Input:
- * @ec Reference to entropy collector
- * @data pointer to buffer for storing random data -- buffer must already
- * exist
- * @len size of the buffer, specifying also the requested number of random
- * in bytes
+ * @ec [in] Reference to entropy collector
+ * @data [in] pointer to buffer for storing random data -- buffer must already
+ * exist
+ * @len [in] size of the buffer, specifying also the requested number of random
+ * in bytes
*
* @return 0 when request is fulfilled or an error
*
* The following error codes can occur:
* -1 entropy_collector is NULL
+ * -2 RCT failed
+ * -3 APT test failed
*/
int jent_read_entropy(struct rand_data *ec, unsigned char *data,
unsigned int len)
@@ -445,11 +611,46 @@ int jent_read_entropy(struct rand_data *ec, unsigned char *data,
if (!ec)
return -1;
- while (0 < len) {
+ while (len > 0) {
unsigned int tocopy;
jent_gen_entropy(ec);
- jent_fips_test(ec);
+
+ if (jent_health_failure(ec)) {
+ int ret;
+
+ if (jent_rct_failure(ec))
+ ret = -2;
+ else
+ ret = -3;
+
+ /*
+ * Re-initialize the noise source
+ *
+ * If the health test fails, the Jitter RNG remains
+ * in failure state and will return a health failure
+ * during next invocation.
+ */
+ if (jent_entropy_init())
+ return ret;
+
+ /* Set APT to initial state */
+ jent_apt_reset(ec, 0);
+ ec->apt_base_set = 0;
+
+ /* Set RCT to initial state */
+ ec->rct_count = 0;
+
+ /* Re-enable Jitter RNG */
+ ec->health_failure = 0;
+
+ /*
+ * Return the health test failure status to the
+ * caller as the generated value is not appropriate.
+ */
+ return ret;
+ }
+
if ((DATA_SIZE_BITS / 8) < len)
tocopy = (DATA_SIZE_BITS / 8);
else
@@ -491,7 +692,7 @@ struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
}
/* verify and set the oversampling rate */
- if (0 == osr)
+ if (osr == 0)
osr = 1; /* minimum sampling rate is 1 */
entropy_collector->osr = osr;
@@ -513,11 +714,15 @@ int jent_entropy_init(void)
int i;
__u64 delta_sum = 0;
__u64 old_delta = 0;
+ unsigned int nonstuck = 0;
int time_backwards = 0;
int count_mod = 0;
int count_stuck = 0;
struct rand_data ec = { 0 };
+ /* Required for RCT */
+ ec.osr = 1;
+
/* We could perform statistical tests here, but the problem is
* that we only have a few loop counts to do testing. These
* loop counts may show some slight skew and we produce
@@ -539,8 +744,10 @@ int jent_entropy_init(void)
/*
* TESTLOOPCOUNT needs some loops to identify edge systems. 100 is
* definitely too little.
+ *
+ * SP800-90B requires at least 1024 initial test cycles.
*/
-#define TESTLOOPCOUNT 300
+#define TESTLOOPCOUNT 1024
#define CLEARCACHE 100
for (i = 0; (TESTLOOPCOUNT + CLEARCACHE) > i; i++) {
__u64 time = 0;
@@ -552,13 +759,13 @@ int jent_entropy_init(void)
/* Invoke core entropy collection logic */
jent_get_nstime(&time);
ec.prev_time = time;
- jent_lfsr_time(&ec, time, 0);
+ jent_lfsr_time(&ec, time, 0, 0);
jent_get_nstime(&time2);
/* test whether timer works */
if (!time || !time2)
return JENT_ENOTIME;
- delta = time2 - time;
+ delta = jent_delta(time, time2);
/*
* test whether timer is fine grained enough to provide
* delta even when called shortly after each other -- this
@@ -576,11 +783,33 @@ int jent_entropy_init(void)
* etc. with the goal to clear it to get the worst case
* measurements.
*/
- if (CLEARCACHE > i)
+ if (i < CLEARCACHE)
continue;
if (stuck)
count_stuck++;
+ else {
+ nonstuck++;
+
+ /*
+ * Ensure that the APT succeeded.
+ *
+ * With the check below that count_stuck must be less
+ * than 10% of the overall generated raw entropy values
+ * it is guaranteed that the APT is invoked at
+ * floor((TESTLOOPCOUNT * 0.9) / 64) == 14 times.
+ */
+ if ((nonstuck % JENT_APT_WINDOW_SIZE) == 0) {
+ jent_apt_reset(&ec,
+ delta & JENT_APT_WORD_MASK);
+ if (jent_health_failure(&ec))
+ return JENT_EHEALTH;
+ }
+ }
+
+ /* Validate RCT */
+ if (jent_rct_failure(&ec))
+ return JENT_ERCT;
/* test whether we have an increasing timer */
if (!(time2 > time))
@@ -611,7 +840,7 @@ int jent_entropy_init(void)
* should not fail. The value of 3 should cover the NTP case being
* performed during our test run.
*/
- if (3 < time_backwards)
+ if (time_backwards > 3)
return JENT_ENOMONOTONIC;
/*
diff --git a/crypto/jitterentropy.h b/crypto/jitterentropy.h
index c83fff32d130..b7397b617ef0 100644
--- a/crypto/jitterentropy.h
+++ b/crypto/jitterentropy.h
@@ -2,7 +2,6 @@
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);
diff --git a/crypto/kdf_sp800108.c b/crypto/kdf_sp800108.c
new file mode 100644
index 000000000000..58edf7797abf
--- /dev/null
+++ b/crypto/kdf_sp800108.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * SP800-108 Key-derivation function
+ *
+ * Copyright (C) 2021, Stephan Mueller <smueller@chronox.de>
+ */
+
+#include <linux/fips.h>
+#include <linux/module.h>
+#include <crypto/kdf_sp800108.h>
+#include <crypto/internal/kdf_selftest.h>
+
+/*
+ * SP800-108 CTR KDF implementation
+ */
+int crypto_kdf108_ctr_generate(struct crypto_shash *kmd,
+ const struct kvec *info, unsigned int info_nvec,
+ u8 *dst, unsigned int dlen)
+{
+ SHASH_DESC_ON_STACK(desc, kmd);
+ __be32 counter = cpu_to_be32(1);
+ const unsigned int h = crypto_shash_digestsize(kmd), dlen_orig = dlen;
+ unsigned int i;
+ int err = 0;
+ u8 *dst_orig = dst;
+
+ desc->tfm = kmd;
+
+ while (dlen) {
+ err = crypto_shash_init(desc);
+ if (err)
+ goto out;
+
+ err = crypto_shash_update(desc, (u8 *)&counter, sizeof(__be32));
+ if (err)
+ goto out;
+
+ for (i = 0; i < info_nvec; i++) {
+ err = crypto_shash_update(desc, info[i].iov_base,
+ info[i].iov_len);
+ if (err)
+ goto out;
+ }
+
+ if (dlen < h) {
+ u8 tmpbuffer[HASH_MAX_DIGESTSIZE];
+
+ err = crypto_shash_final(desc, tmpbuffer);
+ if (err)
+ goto out;
+ memcpy(dst, tmpbuffer, dlen);
+ memzero_explicit(tmpbuffer, h);
+ goto out;
+ }
+
+ err = crypto_shash_final(desc, dst);
+ if (err)
+ goto out;
+
+ dlen -= h;
+ dst += h;
+ counter = cpu_to_be32(be32_to_cpu(counter) + 1);
+ }
+
+out:
+ if (err)
+ memzero_explicit(dst_orig, dlen_orig);
+ shash_desc_zero(desc);
+ return err;
+}
+EXPORT_SYMBOL(crypto_kdf108_ctr_generate);
+
+/*
+ * The seeding of the KDF
+ */
+int crypto_kdf108_setkey(struct crypto_shash *kmd,
+ const u8 *key, size_t keylen,
+ const u8 *ikm, size_t ikmlen)
+{
+ unsigned int ds = crypto_shash_digestsize(kmd);
+
+ /* SP800-108 does not support IKM */
+ if (ikm || ikmlen)
+ return -EINVAL;
+
+ /* Check according to SP800-108 section 7.2 */
+ if (ds > keylen)
+ return -EINVAL;
+
+ /* Set the key for the MAC used for the KDF. */
+ return crypto_shash_setkey(kmd, key, keylen);
+}
+EXPORT_SYMBOL(crypto_kdf108_setkey);
+
+/*
+ * Test vector obtained from
+ * http://csrc.nist.gov/groups/STM/cavp/documents/KBKDF800-108/CounterMode.zip
+ */
+static const struct kdf_testvec kdf_ctr_hmac_sha256_tv_template[] = {
+ {
+ .key = "\xdd\x1d\x91\xb7\xd9\x0b\x2b\xd3"
+ "\x13\x85\x33\xce\x92\xb2\x72\xfb"
+ "\xf8\xa3\x69\x31\x6a\xef\xe2\x42"
+ "\xe6\x59\xcc\x0a\xe2\x38\xaf\xe0",
+ .keylen = 32,
+ .ikm = NULL,
+ .ikmlen = 0,
+ .info = {
+ .iov_base = "\x01\x32\x2b\x96\xb3\x0a\xcd\x19"
+ "\x79\x79\x44\x4e\x46\x8e\x1c\x5c"
+ "\x68\x59\xbf\x1b\x1c\xf9\x51\xb7"
+ "\xe7\x25\x30\x3e\x23\x7e\x46\xb8"
+ "\x64\xa1\x45\xfa\xb2\x5e\x51\x7b"
+ "\x08\xf8\x68\x3d\x03\x15\xbb\x29"
+ "\x11\xd8\x0a\x0e\x8a\xba\x17\xf3"
+ "\xb4\x13\xfa\xac",
+ .iov_len = 60
+ },
+ .expected = "\x10\x62\x13\x42\xbf\xb0\xfd\x40"
+ "\x04\x6c\x0e\x29\xf2\xcf\xdb\xf0",
+ .expectedlen = 16
+ }
+};
+
+static int __init crypto_kdf108_init(void)
+{
+ int ret = kdf_test(&kdf_ctr_hmac_sha256_tv_template[0], "hmac(sha256)",
+ crypto_kdf108_setkey, crypto_kdf108_ctr_generate);
+
+ if (ret) {
+ if (fips_enabled)
+ panic("alg: self-tests for CTR-KDF (hmac(sha256)) failed (rc=%d)\n",
+ ret);
+
+ WARN(1,
+ "alg: self-tests for CTR-KDF (hmac(sha256)) failed (rc=%d)\n",
+ ret);
+ } else {
+ pr_info("alg: self-tests for CTR-KDF (hmac(sha256)) passed\n");
+ }
+
+ return ret;
+}
+
+static void __exit crypto_kdf108_exit(void) { }
+
+module_init(crypto_kdf108_init);
+module_exit(crypto_kdf108_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
+MODULE_DESCRIPTION("Key Derivation Function conformant to SP800-108");
diff --git a/crypto/keywrap.c b/crypto/keywrap.c
index 0355cce21b1e..054d9a216fc9 100644
--- a/crypto/keywrap.c
+++ b/crypto/keywrap.c
@@ -85,6 +85,7 @@
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <crypto/scatterwalk.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/skcipher.h>
struct crypto_kw_block {
@@ -113,9 +114,9 @@ static void crypto_kw_scatterlist_ff(struct scatter_walk *walk,
scatterwalk_start(walk, sg);
scatterwalk_advance(walk, skip);
break;
- } else
- skip -= sg->length;
+ }
+ skip -= sg->length;
sg = sg_next(sg);
}
}
@@ -316,3 +317,4 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>");
MODULE_DESCRIPTION("Key Wrapping (RFC3394 / NIST SP800-38F)");
MODULE_ALIAS_CRYPTO("kw");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/khazad.c b/crypto/khazad.c
index 14ca7f1631c7..f19339954c89 100644
--- a/crypto/khazad.c
+++ b/crypto/khazad.c
@@ -819,7 +819,7 @@ static void khazad_crypt(const u64 roundKey[KHAZAD_ROUNDS + 1],
T6[(int)(state >> 8) & 0xff] ^
T7[(int)(state ) & 0xff] ^
roundKey[r];
- }
+ }
state = (T0[(int)(state >> 56) ] & 0xff00000000000000ULL) ^
(T1[(int)(state >> 48) & 0xff] & 0x00ff000000000000ULL) ^
diff --git a/crypto/kpp.c b/crypto/kpp.c
index 313b2c699963..678e871ce418 100644
--- a/crypto/kpp.c
+++ b/crypto/kpp.c
@@ -68,9 +68,17 @@ static int crypto_kpp_init_tfm(struct crypto_tfm *tfm)
return 0;
}
+static void crypto_kpp_free_instance(struct crypto_instance *inst)
+{
+ struct kpp_instance *kpp = kpp_instance(inst);
+
+ kpp->free(kpp);
+}
+
static const struct crypto_type crypto_kpp_type = {
.extsize = crypto_alg_extsize,
.init_tfm = crypto_kpp_init_tfm,
+ .free = crypto_kpp_free_instance,
#ifdef CONFIG_PROC_FS
.show = crypto_kpp_show,
#endif
@@ -87,6 +95,21 @@ struct crypto_kpp *crypto_alloc_kpp(const char *alg_name, u32 type, u32 mask)
}
EXPORT_SYMBOL_GPL(crypto_alloc_kpp);
+int crypto_grab_kpp(struct crypto_kpp_spawn *spawn,
+ struct crypto_instance *inst,
+ const char *name, u32 type, u32 mask)
+{
+ spawn->base.frontend = &crypto_kpp_type;
+ return crypto_grab_spawn(&spawn->base, inst, name, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_grab_kpp);
+
+int crypto_has_kpp(const char *alg_name, u32 type, u32 mask)
+{
+ return crypto_type_has_alg(alg_name, &crypto_kpp_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_has_kpp);
+
static void kpp_prepare_alg(struct kpp_alg *alg)
{
struct crypto_alg *base = &alg->base;
@@ -111,5 +134,17 @@ void crypto_unregister_kpp(struct kpp_alg *alg)
}
EXPORT_SYMBOL_GPL(crypto_unregister_kpp);
+int kpp_register_instance(struct crypto_template *tmpl,
+ struct kpp_instance *inst)
+{
+ if (WARN_ON(!inst->free))
+ return -EINVAL;
+
+ kpp_prepare_alg(&inst->alg);
+
+ return crypto_register_instance(tmpl, kpp_crypto_instance(inst));
+}
+EXPORT_SYMBOL_GPL(kpp_register_instance);
+
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Key-agreement Protocol Primitives");
diff --git a/crypto/lrw.c b/crypto/lrw.c
index 63c485c0d8a6..8d59a66b6525 100644
--- a/crypto/lrw.c
+++ b/crypto/lrw.c
@@ -9,7 +9,7 @@
*/
/* This implementation is checked against the test vectors in the above
* document and by a test vector provided by Ken Buchanan at
- * http://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html
+ * https://www.mail-archive.com/stds-p1619@listserv.ieee.org/msg00173.html
*
* The test vectors are included in the testing module tcrypt.[ch] */
@@ -27,7 +27,7 @@
#define LRW_BLOCK_SIZE 16
-struct priv {
+struct lrw_tfm_ctx {
struct crypto_skcipher *child;
/*
@@ -49,12 +49,12 @@ struct priv {
be128 mulinc[128];
};
-struct rctx {
+struct lrw_request_ctx {
be128 t;
struct skcipher_request subreq;
};
-static inline void setbit128_bbe(void *b, int bit)
+static inline void lrw_setbit128_bbe(void *b, int bit)
{
__set_bit(bit ^ (0x80 -
#ifdef __BIG_ENDIAN
@@ -65,10 +65,10 @@ static inline void setbit128_bbe(void *b, int bit)
), b);
}
-static int setkey(struct crypto_skcipher *parent, const u8 *key,
- unsigned int keylen)
+static int lrw_setkey(struct crypto_skcipher *parent, const u8 *key,
+ unsigned int keylen)
{
- struct priv *ctx = crypto_skcipher_ctx(parent);
+ struct lrw_tfm_ctx *ctx = crypto_skcipher_ctx(parent);
struct crypto_skcipher *child = ctx->child;
int err, bsize = LRW_BLOCK_SIZE;
const u8 *tweak = key + keylen - bsize;
@@ -92,7 +92,7 @@ static int setkey(struct crypto_skcipher *parent, const u8 *key,
/* initialize optimization table */
for (i = 0; i < 128; i++) {
- setbit128_bbe(&tmp, i);
+ lrw_setbit128_bbe(&tmp, i);
ctx->mulinc[i] = tmp;
gf128mul_64k_bbe(&ctx->mulinc[i], ctx->table);
}
@@ -108,10 +108,10 @@ static int setkey(struct crypto_skcipher *parent, const u8 *key,
* For example:
*
* u32 counter[4] = { 0xFFFFFFFF, 0x1, 0x0, 0x0 };
- * int i = next_index(&counter);
+ * int i = lrw_next_index(&counter);
* // i == 33, counter == { 0x0, 0x2, 0x0, 0x0 }
*/
-static int next_index(u32 *counter)
+static int lrw_next_index(u32 *counter)
{
int i, res = 0;
@@ -135,14 +135,14 @@ static int next_index(u32 *counter)
* We compute the tweak masks twice (both before and after the ECB encryption or
* decryption) to avoid having to allocate a temporary buffer and/or make
* mutliple calls to the 'ecb(..)' instance, which usually would be slower than
- * just doing the next_index() calls again.
+ * just doing the lrw_next_index() calls again.
*/
-static int xor_tweak(struct skcipher_request *req, bool second_pass)
+static int lrw_xor_tweak(struct skcipher_request *req, bool second_pass)
{
const int bs = LRW_BLOCK_SIZE;
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct priv *ctx = crypto_skcipher_ctx(tfm);
- struct rctx *rctx = skcipher_request_ctx(req);
+ const struct lrw_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct lrw_request_ctx *rctx = skcipher_request_ctx(req);
be128 t = rctx->t;
struct skcipher_walk w;
__be32 *iv;
@@ -178,7 +178,8 @@ static int xor_tweak(struct skcipher_request *req, bool second_pass)
/* T <- I*Key2, using the optimization
* discussed in the specification */
- be128_xor(&t, &t, &ctx->mulinc[next_index(counter)]);
+ be128_xor(&t, &t,
+ &ctx->mulinc[lrw_next_index(counter)]);
} while ((avail -= bs) >= bs);
if (second_pass && w.nbytes == w.total) {
@@ -194,38 +195,40 @@ static int xor_tweak(struct skcipher_request *req, bool second_pass)
return err;
}
-static int xor_tweak_pre(struct skcipher_request *req)
+static int lrw_xor_tweak_pre(struct skcipher_request *req)
{
- return xor_tweak(req, false);
+ return lrw_xor_tweak(req, false);
}
-static int xor_tweak_post(struct skcipher_request *req)
+static int lrw_xor_tweak_post(struct skcipher_request *req)
{
- return xor_tweak(req, true);
+ return lrw_xor_tweak(req, true);
}
-static void crypt_done(struct crypto_async_request *areq, int err)
+static void lrw_crypt_done(struct crypto_async_request *areq, int err)
{
struct skcipher_request *req = areq->data;
if (!err) {
- struct rctx *rctx = skcipher_request_ctx(req);
+ struct lrw_request_ctx *rctx = skcipher_request_ctx(req);
rctx->subreq.base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
- err = xor_tweak_post(req);
+ err = lrw_xor_tweak_post(req);
}
skcipher_request_complete(req, err);
}
-static void init_crypt(struct skcipher_request *req)
+static void lrw_init_crypt(struct skcipher_request *req)
{
- struct priv *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
- struct rctx *rctx = skcipher_request_ctx(req);
+ const struct lrw_tfm_ctx *ctx =
+ crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
+ struct lrw_request_ctx *rctx = skcipher_request_ctx(req);
struct skcipher_request *subreq = &rctx->subreq;
skcipher_request_set_tfm(subreq, ctx->child);
- skcipher_request_set_callback(subreq, req->base.flags, crypt_done, req);
+ skcipher_request_set_callback(subreq, req->base.flags, lrw_crypt_done,
+ req);
/* pass req->iv as IV (will be used by xor_tweak, ECB will ignore it) */
skcipher_request_set_crypt(subreq, req->dst, req->dst,
req->cryptlen, req->iv);
@@ -237,33 +240,33 @@ static void init_crypt(struct skcipher_request *req)
gf128mul_64k_bbe(&rctx->t, ctx->table);
}
-static int encrypt(struct skcipher_request *req)
+static int lrw_encrypt(struct skcipher_request *req)
{
- struct rctx *rctx = skcipher_request_ctx(req);
+ struct lrw_request_ctx *rctx = skcipher_request_ctx(req);
struct skcipher_request *subreq = &rctx->subreq;
- init_crypt(req);
- return xor_tweak_pre(req) ?:
+ lrw_init_crypt(req);
+ return lrw_xor_tweak_pre(req) ?:
crypto_skcipher_encrypt(subreq) ?:
- xor_tweak_post(req);
+ lrw_xor_tweak_post(req);
}
-static int decrypt(struct skcipher_request *req)
+static int lrw_decrypt(struct skcipher_request *req)
{
- struct rctx *rctx = skcipher_request_ctx(req);
+ struct lrw_request_ctx *rctx = skcipher_request_ctx(req);
struct skcipher_request *subreq = &rctx->subreq;
- init_crypt(req);
- return xor_tweak_pre(req) ?:
+ lrw_init_crypt(req);
+ return lrw_xor_tweak_pre(req) ?:
crypto_skcipher_decrypt(subreq) ?:
- xor_tweak_post(req);
+ lrw_xor_tweak_post(req);
}
-static int init_tfm(struct crypto_skcipher *tfm)
+static int lrw_init_tfm(struct crypto_skcipher *tfm)
{
struct skcipher_instance *inst = skcipher_alg_instance(tfm);
struct crypto_skcipher_spawn *spawn = skcipher_instance_ctx(inst);
- struct priv *ctx = crypto_skcipher_ctx(tfm);
+ struct lrw_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
struct crypto_skcipher *cipher;
cipher = crypto_spawn_skcipher(spawn);
@@ -273,45 +276,39 @@ static int init_tfm(struct crypto_skcipher *tfm)
ctx->child = cipher;
crypto_skcipher_set_reqsize(tfm, crypto_skcipher_reqsize(cipher) +
- sizeof(struct rctx));
+ sizeof(struct lrw_request_ctx));
return 0;
}
-static void exit_tfm(struct crypto_skcipher *tfm)
+static void lrw_exit_tfm(struct crypto_skcipher *tfm)
{
- struct priv *ctx = crypto_skcipher_ctx(tfm);
+ struct lrw_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
if (ctx->table)
gf128mul_free_64k(ctx->table);
crypto_free_skcipher(ctx->child);
}
-static void free(struct skcipher_instance *inst)
+static void lrw_free_instance(struct skcipher_instance *inst)
{
crypto_drop_skcipher(skcipher_instance_ctx(inst));
kfree(inst);
}
-static int create(struct crypto_template *tmpl, struct rtattr **tb)
+static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb)
{
struct crypto_skcipher_spawn *spawn;
struct skcipher_instance *inst;
- struct crypto_attr_type *algt;
struct skcipher_alg *alg;
const char *cipher_name;
char ecb_name[CRYPTO_MAX_ALG_NAME];
u32 mask;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask)
- return -EINVAL;
-
- mask = crypto_requires_sync(algt->type, algt->mask);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
+ if (err)
+ return err;
cipher_name = crypto_attr_alg_name(tb[1]);
if (IS_ERR(cipher_name))
@@ -343,15 +340,15 @@ static int create(struct crypto_template *tmpl, struct rtattr **tb)
err = -EINVAL;
if (alg->base.cra_blocksize != LRW_BLOCK_SIZE)
- goto err_drop_spawn;
+ goto err_free_inst;
if (crypto_skcipher_alg_ivsize(alg))
- goto err_drop_spawn;
+ goto err_free_inst;
err = crypto_inst_setname(skcipher_crypto_instance(inst), "lrw",
&alg->base);
if (err)
- goto err_drop_spawn;
+ goto err_free_inst;
err = -EINVAL;
cipher_name = alg->base.cra_name;
@@ -364,22 +361,21 @@ static int create(struct crypto_template *tmpl, struct rtattr **tb)
len = strlcpy(ecb_name, cipher_name + 4, sizeof(ecb_name));
if (len < 2 || len >= sizeof(ecb_name))
- goto err_drop_spawn;
+ goto err_free_inst;
if (ecb_name[len - 1] != ')')
- goto err_drop_spawn;
+ goto err_free_inst;
ecb_name[len - 1] = 0;
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
"lrw(%s)", ecb_name) >= CRYPTO_MAX_ALG_NAME) {
err = -ENAMETOOLONG;
- goto err_drop_spawn;
+ goto err_free_inst;
}
} else
- goto err_drop_spawn;
+ goto err_free_inst;
- 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 = LRW_BLOCK_SIZE;
inst->alg.base.cra_alignmask = alg->base.cra_alignmask |
@@ -391,50 +387,45 @@ static int create(struct crypto_template *tmpl, struct rtattr **tb)
inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg) +
LRW_BLOCK_SIZE;
- inst->alg.base.cra_ctxsize = sizeof(struct priv);
+ inst->alg.base.cra_ctxsize = sizeof(struct lrw_tfm_ctx);
- inst->alg.init = init_tfm;
- inst->alg.exit = exit_tfm;
+ inst->alg.init = lrw_init_tfm;
+ inst->alg.exit = lrw_exit_tfm;
- inst->alg.setkey = setkey;
- inst->alg.encrypt = encrypt;
- inst->alg.decrypt = decrypt;
+ inst->alg.setkey = lrw_setkey;
+ inst->alg.encrypt = lrw_encrypt;
+ inst->alg.decrypt = lrw_decrypt;
- inst->free = free;
+ inst->free = lrw_free_instance;
err = skcipher_register_instance(tmpl, inst);
- if (err)
- goto err_drop_spawn;
-
-out:
- return err;
-
-err_drop_spawn:
- crypto_drop_skcipher(spawn);
+ if (err) {
err_free_inst:
- kfree(inst);
- goto out;
+ lrw_free_instance(inst);
+ }
+ return err;
}
-static struct crypto_template crypto_tmpl = {
+static struct crypto_template lrw_tmpl = {
.name = "lrw",
- .create = create,
+ .create = lrw_create,
.module = THIS_MODULE,
};
-static int __init crypto_module_init(void)
+static int __init lrw_module_init(void)
{
- return crypto_register_template(&crypto_tmpl);
+ return crypto_register_template(&lrw_tmpl);
}
-static void __exit crypto_module_exit(void)
+static void __exit lrw_module_exit(void)
{
- crypto_unregister_template(&crypto_tmpl);
+ crypto_unregister_template(&lrw_tmpl);
}
-subsys_initcall(crypto_module_init);
-module_exit(crypto_module_exit);
+subsys_initcall(lrw_module_init);
+module_exit(lrw_module_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LRW block cipher mode");
MODULE_ALIAS_CRYPTO("lrw");
+MODULE_SOFTDEP("pre: ecb");
diff --git a/crypto/md5.c b/crypto/md5.c
index 22dc60bc0437..72c0c46fb5ee 100644
--- a/crypto/md5.c
+++ b/crypto/md5.c
@@ -23,9 +23,6 @@
#include <linux/types.h>
#include <asm/byteorder.h>
-#define MD5_DIGEST_WORDS 4
-#define MD5_MESSAGE_BYTES 64
-
const u8 md5_zero_message_hash[MD5_DIGEST_SIZE] = {
0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e,
diff --git a/crypto/michael_mic.c b/crypto/michael_mic.c
index 63350c4ad461..f4c31049601c 100644
--- a/crypto/michael_mic.c
+++ b/crypto/michael_mic.c
@@ -7,7 +7,7 @@
* Copyright (c) 2004 Jouni Malinen <j@w1.fi>
*/
#include <crypto/internal/hash.h>
-#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/string.h>
@@ -19,7 +19,7 @@ struct michael_mic_ctx {
};
struct michael_mic_desc_ctx {
- u8 pending[4];
+ __le32 pending;
size_t pending_len;
u32 l, r;
@@ -60,13 +60,12 @@ static int michael_update(struct shash_desc *desc, const u8 *data,
unsigned int len)
{
struct michael_mic_desc_ctx *mctx = shash_desc_ctx(desc);
- const __le32 *src;
if (mctx->pending_len) {
int flen = 4 - mctx->pending_len;
if (flen > len)
flen = len;
- memcpy(&mctx->pending[mctx->pending_len], data, flen);
+ memcpy((u8 *)&mctx->pending + mctx->pending_len, data, flen);
mctx->pending_len += flen;
data += flen;
len -= flen;
@@ -74,23 +73,21 @@ static int michael_update(struct shash_desc *desc, const u8 *data,
if (mctx->pending_len < 4)
return 0;
- src = (const __le32 *)mctx->pending;
- mctx->l ^= le32_to_cpup(src);
+ mctx->l ^= le32_to_cpu(mctx->pending);
michael_block(mctx->l, mctx->r);
mctx->pending_len = 0;
}
- src = (const __le32 *)data;
-
while (len >= 4) {
- mctx->l ^= le32_to_cpup(src++);
+ mctx->l ^= get_unaligned_le32(data);
michael_block(mctx->l, mctx->r);
+ data += 4;
len -= 4;
}
if (len > 0) {
mctx->pending_len = len;
- memcpy(mctx->pending, src, len);
+ memcpy(&mctx->pending, data, len);
}
return 0;
@@ -100,8 +97,7 @@ static int michael_update(struct shash_desc *desc, const u8 *data,
static int michael_final(struct shash_desc *desc, u8 *out)
{
struct michael_mic_desc_ctx *mctx = shash_desc_ctx(desc);
- u8 *data = mctx->pending;
- __le32 *dst = (__le32 *)out;
+ u8 *data = (u8 *)&mctx->pending;
/* Last block and padding (0x5a, 4..7 x 0) */
switch (mctx->pending_len) {
@@ -123,8 +119,8 @@ static int michael_final(struct shash_desc *desc, u8 *out)
/* l ^= 0; */
michael_block(mctx->l, mctx->r);
- dst[0] = cpu_to_le32(mctx->l);
- dst[1] = cpu_to_le32(mctx->r);
+ put_unaligned_le32(mctx->l, out);
+ put_unaligned_le32(mctx->r, out + 4);
return 0;
}
@@ -135,13 +131,11 @@ static int michael_setkey(struct crypto_shash *tfm, const u8 *key,
{
struct michael_mic_ctx *mctx = crypto_shash_ctx(tfm);
- const __le32 *data = (const __le32 *)key;
-
if (keylen != 8)
return -EINVAL;
- mctx->l = le32_to_cpu(data[0]);
- mctx->r = le32_to_cpu(data[1]);
+ mctx->l = get_unaligned_le32(key);
+ mctx->r = get_unaligned_le32(key + 4);
return 0;
}
@@ -156,7 +150,6 @@ static struct shash_alg alg = {
.cra_name = "michael_mic",
.cra_driver_name = "michael_mic-generic",
.cra_blocksize = 8,
- .cra_alignmask = 3,
.cra_ctxsize = sizeof(struct michael_mic_ctx),
.cra_module = THIS_MODULE,
}
diff --git a/crypto/ofb.c b/crypto/ofb.c
index 2ec68e3f2c55..b630fdecceee 100644
--- a/crypto/ofb.c
+++ b/crypto/ofb.c
@@ -8,6 +8,7 @@
*/
#include <crypto/algapi.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/skcipher.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -102,3 +103,4 @@ module_exit(crypto_ofb_module_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("OFB block cipher mode of operation");
MODULE_ALIAS_CRYPTO("ofb");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/pcbc.c b/crypto/pcbc.c
index ae921fb74dc9..7030f59e46b6 100644
--- a/crypto/pcbc.c
+++ b/crypto/pcbc.c
@@ -10,6 +10,7 @@
*/
#include <crypto/algapi.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/skcipher.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -191,3 +192,4 @@ module_exit(crypto_pcbc_module_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PCBC block cipher mode of operation");
MODULE_ALIAS_CRYPTO("pcbc");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index 1b632139a8c1..9d10b846ccf7 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -78,12 +78,14 @@ static void pcrypt_aead_enc(struct padata_priv *padata)
{
struct pcrypt_request *preq = pcrypt_padata_request(padata);
struct aead_request *req = pcrypt_request_ctx(preq);
+ int ret;
- padata->info = crypto_aead_encrypt(req);
+ ret = crypto_aead_encrypt(req);
- if (padata->info == -EINPROGRESS)
+ if (ret == -EINPROGRESS)
return;
+ padata->info = ret;
padata_do_serial(padata);
}
@@ -123,12 +125,14 @@ static void pcrypt_aead_dec(struct padata_priv *padata)
{
struct pcrypt_request *preq = pcrypt_padata_request(padata);
struct aead_request *req = pcrypt_request_ctx(preq);
+ int ret;
- padata->info = crypto_aead_decrypt(req);
+ ret = crypto_aead_decrypt(req);
- if (padata->info == -EINPROGRESS)
+ if (ret == -EINPROGRESS)
return;
+ padata->info = ret;
padata_do_serial(padata);
}
@@ -226,23 +230,14 @@ static int pcrypt_init_instance(struct crypto_instance *inst,
}
static int pcrypt_create_aead(struct crypto_template *tmpl, struct rtattr **tb,
- u32 type, u32 mask)
+ struct crypto_attr_type *algt)
{
struct pcrypt_instance_ctx *ctx;
- struct crypto_attr_type *algt;
struct aead_instance *inst;
struct aead_alg *alg;
- const char *name;
+ u32 mask = crypto_algt_inherited_mask(algt);
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- name = crypto_attr_alg_name(tb[1]);
- if (IS_ERR(name))
- return PTR_ERR(name);
-
inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
if (!inst)
return -ENOMEM;
@@ -252,23 +247,23 @@ static int pcrypt_create_aead(struct crypto_template *tmpl, struct rtattr **tb,
ctx = aead_instance_ctx(inst);
ctx->psenc = padata_alloc_shell(pencrypt);
if (!ctx->psenc)
- goto out_free_inst;
+ goto err_free_inst;
ctx->psdec = padata_alloc_shell(pdecrypt);
if (!ctx->psdec)
- goto out_free_psenc;
+ goto err_free_inst;
err = crypto_grab_aead(&ctx->spawn, aead_crypto_instance(inst),
- name, 0, 0);
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
- goto out_free_psdec;
+ goto err_free_inst;
alg = crypto_spawn_aead_alg(&ctx->spawn);
err = pcrypt_init_instance(aead_crypto_instance(inst), &alg->base);
if (err)
- goto out_drop_aead;
+ goto err_free_inst;
- inst->alg.base.cra_flags = CRYPTO_ALG_ASYNC;
+ inst->alg.base.cra_flags |= CRYPTO_ALG_ASYNC;
inst->alg.ivsize = crypto_aead_alg_ivsize(alg);
inst->alg.maxauthsize = crypto_aead_alg_maxauthsize(alg);
@@ -286,21 +281,11 @@ static int pcrypt_create_aead(struct crypto_template *tmpl, struct rtattr **tb,
inst->free = pcrypt_free;
err = aead_register_instance(tmpl, inst);
- if (err)
- goto out_drop_aead;
-
-out:
+ if (err) {
+err_free_inst:
+ pcrypt_free(inst);
+ }
return err;
-
-out_drop_aead:
- crypto_drop_aead(&ctx->spawn);
-out_free_psdec:
- padata_free_shell(ctx->psdec);
-out_free_psenc:
- padata_free_shell(ctx->psenc);
-out_free_inst:
- kfree(inst);
- goto out;
}
static int pcrypt_create(struct crypto_template *tmpl, struct rtattr **tb)
@@ -313,7 +298,7 @@ static int pcrypt_create(struct crypto_template *tmpl, struct rtattr **tb)
switch (algt->type & algt->mask & CRYPTO_ALG_TYPE_MASK) {
case CRYPTO_ALG_TYPE_AEAD:
- return pcrypt_create_aead(tmpl, tb, algt->type, algt->mask);
+ return pcrypt_create_aead(tmpl, tb, algt);
}
return -EINVAL;
@@ -335,7 +320,7 @@ static int pcrypt_init_padata(struct padata_instance **pinst, const char *name)
{
int ret = -ENOMEM;
- *pinst = padata_alloc_possible(name);
+ *pinst = padata_alloc(name);
if (!*pinst)
return ret;
@@ -346,12 +331,6 @@ static int pcrypt_init_padata(struct padata_instance **pinst, const char *name)
return ret;
}
-static void pcrypt_fini_padata(struct padata_instance *pinst)
-{
- padata_stop(pinst);
- padata_free(pinst);
-}
-
static struct crypto_template pcrypt_tmpl = {
.name = "pcrypt",
.create = pcrypt_create,
@@ -374,13 +353,10 @@ static int __init pcrypt_init(void)
if (err)
goto err_deinit_pencrypt;
- padata_start(pencrypt);
- padata_start(pdecrypt);
-
return crypto_register_template(&pcrypt_tmpl);
err_deinit_pencrypt:
- pcrypt_fini_padata(pencrypt);
+ padata_free(pencrypt);
err_unreg_kset:
kset_unregister(pcrypt_kset);
err:
@@ -391,8 +367,8 @@ static void __exit pcrypt_exit(void)
{
crypto_unregister_template(&pcrypt_tmpl);
- pcrypt_fini_padata(pencrypt);
- pcrypt_fini_padata(pdecrypt);
+ padata_free(pencrypt);
+ padata_free(pdecrypt);
kset_unregister(pcrypt_kset);
}
diff --git a/crypto/polyval-generic.c b/crypto/polyval-generic.c
new file mode 100644
index 000000000000..16bfa6925b31
--- /dev/null
+++ b/crypto/polyval-generic.c
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * POLYVAL: hash function for HCTR2.
+ *
+ * Copyright (c) 2007 Nokia Siemens Networks - Mikko Herranen <mh1@iki.fi>
+ * Copyright (c) 2009 Intel Corp.
+ * Author: Huang Ying <ying.huang@intel.com>
+ * Copyright 2021 Google LLC
+ */
+
+/*
+ * Code based on crypto/ghash-generic.c
+ *
+ * POLYVAL is a keyed hash function similar to GHASH. POLYVAL uses a different
+ * modulus for finite field multiplication which makes hardware accelerated
+ * implementations on little-endian machines faster. POLYVAL is used in the
+ * kernel to implement HCTR2, but was originally specified for AES-GCM-SIV
+ * (RFC 8452).
+ *
+ * For more information see:
+ * Length-preserving encryption with HCTR2:
+ * https://eprint.iacr.org/2021/1441.pdf
+ * AES-GCM-SIV: Nonce Misuse-Resistant Authenticated Encryption:
+ * https://datatracker.ietf.org/doc/html/rfc8452
+ *
+ * Like GHASH, POLYVAL is not a cryptographic hash function and should
+ * not be used outside of crypto modes explicitly designed to use POLYVAL.
+ *
+ * This implementation uses a convenient trick involving the GHASH and POLYVAL
+ * fields. This trick allows multiplication in the POLYVAL field to be
+ * implemented by using multiplication in the GHASH field as a subroutine. An
+ * element of the POLYVAL field can be converted to an element of the GHASH
+ * field by computing x*REVERSE(a), where REVERSE reverses the byte-ordering of
+ * a. Similarly, an element of the GHASH field can be converted back to the
+ * POLYVAL field by computing REVERSE(x^{-1}*a). For more information, see:
+ * https://datatracker.ietf.org/doc/html/rfc8452#appendix-A
+ *
+ * By using this trick, we do not need to implement the POLYVAL field for the
+ * generic implementation.
+ *
+ * Warning: this generic implementation is not intended to be used in practice
+ * and is not constant time. For practical use, a hardware accelerated
+ * implementation of POLYVAL should be used instead.
+ *
+ */
+
+#include <asm/unaligned.h>
+#include <crypto/algapi.h>
+#include <crypto/gf128mul.h>
+#include <crypto/polyval.h>
+#include <crypto/internal/hash.h>
+#include <linux/crypto.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+struct polyval_tfm_ctx {
+ struct gf128mul_4k *gf128;
+};
+
+struct polyval_desc_ctx {
+ union {
+ u8 buffer[POLYVAL_BLOCK_SIZE];
+ be128 buffer128;
+ };
+ u32 bytes;
+};
+
+static void copy_and_reverse(u8 dst[POLYVAL_BLOCK_SIZE],
+ const u8 src[POLYVAL_BLOCK_SIZE])
+{
+ u64 a = get_unaligned((const u64 *)&src[0]);
+ u64 b = get_unaligned((const u64 *)&src[8]);
+
+ put_unaligned(swab64(a), (u64 *)&dst[8]);
+ put_unaligned(swab64(b), (u64 *)&dst[0]);
+}
+
+/*
+ * Performs multiplication in the POLYVAL field using the GHASH field as a
+ * subroutine. This function is used as a fallback for hardware accelerated
+ * implementations when simd registers are unavailable.
+ *
+ * Note: This function is not used for polyval-generic, instead we use the 4k
+ * lookup table implementation for finite field multiplication.
+ */
+void polyval_mul_non4k(u8 *op1, const u8 *op2)
+{
+ be128 a, b;
+
+ // Assume one argument is in Montgomery form and one is not.
+ copy_and_reverse((u8 *)&a, op1);
+ copy_and_reverse((u8 *)&b, op2);
+ gf128mul_x_lle(&a, &a);
+ gf128mul_lle(&a, &b);
+ copy_and_reverse(op1, (u8 *)&a);
+}
+EXPORT_SYMBOL_GPL(polyval_mul_non4k);
+
+/*
+ * Perform a POLYVAL update using non4k multiplication. This function is used
+ * as a fallback for hardware accelerated implementations when simd registers
+ * are unavailable.
+ *
+ * Note: This function is not used for polyval-generic, instead we use the 4k
+ * lookup table implementation of finite field multiplication.
+ */
+void polyval_update_non4k(const u8 *key, const u8 *in,
+ size_t nblocks, u8 *accumulator)
+{
+ while (nblocks--) {
+ crypto_xor(accumulator, in, POLYVAL_BLOCK_SIZE);
+ polyval_mul_non4k(accumulator, key);
+ in += POLYVAL_BLOCK_SIZE;
+ }
+}
+EXPORT_SYMBOL_GPL(polyval_update_non4k);
+
+static int polyval_setkey(struct crypto_shash *tfm,
+ const u8 *key, unsigned int keylen)
+{
+ struct polyval_tfm_ctx *ctx = crypto_shash_ctx(tfm);
+ be128 k;
+
+ if (keylen != POLYVAL_BLOCK_SIZE)
+ return -EINVAL;
+
+ gf128mul_free_4k(ctx->gf128);
+
+ BUILD_BUG_ON(sizeof(k) != POLYVAL_BLOCK_SIZE);
+ copy_and_reverse((u8 *)&k, key);
+ gf128mul_x_lle(&k, &k);
+
+ ctx->gf128 = gf128mul_init_4k_lle(&k);
+ memzero_explicit(&k, POLYVAL_BLOCK_SIZE);
+
+ if (!ctx->gf128)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int polyval_init(struct shash_desc *desc)
+{
+ struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+
+ memset(dctx, 0, sizeof(*dctx));
+
+ return 0;
+}
+
+static int polyval_update(struct shash_desc *desc,
+ const u8 *src, unsigned int srclen)
+{
+ struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+ const struct polyval_tfm_ctx *ctx = crypto_shash_ctx(desc->tfm);
+ u8 *pos;
+ u8 tmp[POLYVAL_BLOCK_SIZE];
+ int n;
+
+ if (dctx->bytes) {
+ n = min(srclen, dctx->bytes);
+ pos = dctx->buffer + dctx->bytes - 1;
+
+ dctx->bytes -= n;
+ srclen -= n;
+
+ while (n--)
+ *pos-- ^= *src++;
+
+ if (!dctx->bytes)
+ gf128mul_4k_lle(&dctx->buffer128, ctx->gf128);
+ }
+
+ while (srclen >= POLYVAL_BLOCK_SIZE) {
+ copy_and_reverse(tmp, src);
+ crypto_xor(dctx->buffer, tmp, POLYVAL_BLOCK_SIZE);
+ gf128mul_4k_lle(&dctx->buffer128, ctx->gf128);
+ src += POLYVAL_BLOCK_SIZE;
+ srclen -= POLYVAL_BLOCK_SIZE;
+ }
+
+ if (srclen) {
+ dctx->bytes = POLYVAL_BLOCK_SIZE - srclen;
+ pos = dctx->buffer + POLYVAL_BLOCK_SIZE - 1;
+ while (srclen--)
+ *pos-- ^= *src++;
+ }
+
+ return 0;
+}
+
+static int polyval_final(struct shash_desc *desc, u8 *dst)
+{
+ struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+ const struct polyval_tfm_ctx *ctx = crypto_shash_ctx(desc->tfm);
+
+ if (dctx->bytes)
+ gf128mul_4k_lle(&dctx->buffer128, ctx->gf128);
+ copy_and_reverse(dst, dctx->buffer);
+ return 0;
+}
+
+static void polyval_exit_tfm(struct crypto_tfm *tfm)
+{
+ struct polyval_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ gf128mul_free_4k(ctx->gf128);
+}
+
+static struct shash_alg polyval_alg = {
+ .digestsize = POLYVAL_DIGEST_SIZE,
+ .init = polyval_init,
+ .update = polyval_update,
+ .final = polyval_final,
+ .setkey = polyval_setkey,
+ .descsize = sizeof(struct polyval_desc_ctx),
+ .base = {
+ .cra_name = "polyval",
+ .cra_driver_name = "polyval-generic",
+ .cra_priority = 100,
+ .cra_blocksize = POLYVAL_BLOCK_SIZE,
+ .cra_ctxsize = sizeof(struct polyval_tfm_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_exit = polyval_exit_tfm,
+ },
+};
+
+static int __init polyval_mod_init(void)
+{
+ return crypto_register_shash(&polyval_alg);
+}
+
+static void __exit polyval_mod_exit(void)
+{
+ crypto_unregister_shash(&polyval_alg);
+}
+
+subsys_initcall(polyval_mod_init);
+module_exit(polyval_mod_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("POLYVAL hash function");
+MODULE_ALIAS_CRYPTO("polyval");
+MODULE_ALIAS_CRYPTO("polyval-generic");
diff --git a/crypto/proc.c b/crypto/proc.c
index 7b91557adccb..12fccb9c5205 100644
--- a/crypto/proc.c
+++ b/crypto/proc.c
@@ -36,7 +36,7 @@ static void c_stop(struct seq_file *m, void *p)
static int c_show(struct seq_file *m, void *p)
{
struct crypto_alg *alg = list_entry(p, struct crypto_alg, cra_list);
-
+
seq_printf(m, "name : %s\n", alg->cra_name);
seq_printf(m, "driver : %s\n", alg->cra_driver_name);
seq_printf(m, "module : %s\n", module_name(alg->cra_module));
@@ -59,8 +59,8 @@ static int c_show(struct seq_file *m, void *p)
alg->cra_type->show(m, alg);
goto out;
}
-
- switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) {
+
+ switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
case CRYPTO_ALG_TYPE_CIPHER:
seq_printf(m, "type : cipher\n");
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
diff --git a/crypto/ripemd.h b/crypto/ripemd.h
index 93edbf52197d..b977785e2a62 100644
--- a/crypto/ripemd.h
+++ b/crypto/ripemd.h
@@ -6,29 +6,15 @@
#ifndef _CRYPTO_RMD_H
#define _CRYPTO_RMD_H
-#define RMD128_DIGEST_SIZE 16
-#define RMD128_BLOCK_SIZE 64
-
#define RMD160_DIGEST_SIZE 20
#define RMD160_BLOCK_SIZE 64
-#define RMD256_DIGEST_SIZE 32
-#define RMD256_BLOCK_SIZE 64
-
-#define RMD320_DIGEST_SIZE 40
-#define RMD320_BLOCK_SIZE 64
-
/* initial values */
#define RMD_H0 0x67452301UL
#define RMD_H1 0xefcdab89UL
#define RMD_H2 0x98badcfeUL
#define RMD_H3 0x10325476UL
#define RMD_H4 0xc3d2e1f0UL
-#define RMD_H5 0x76543210UL
-#define RMD_H6 0xfedcba98UL
-#define RMD_H7 0x89abcdefUL
-#define RMD_H8 0x01234567UL
-#define RMD_H9 0x3c2d1e0fUL
/* constants */
#define RMD_K1 0x00000000UL
diff --git a/crypto/rmd128.c b/crypto/rmd128.c
deleted file mode 100644
index 29308fb97e7e..000000000000
--- a/crypto/rmd128.c
+++ /dev/null
@@ -1,323 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Cryptographic API.
- *
- * RIPEMD-128 - RACE Integrity Primitives Evaluation Message Digest.
- *
- * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC
- *
- * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch>
- */
-#include <crypto/internal/hash.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-#include "ripemd.h"
-
-struct rmd128_ctx {
- u64 byte_count;
- u32 state[4];
- __le32 buffer[16];
-};
-
-#define K1 RMD_K1
-#define K2 RMD_K2
-#define K3 RMD_K3
-#define K4 RMD_K4
-#define KK1 RMD_K6
-#define KK2 RMD_K7
-#define KK3 RMD_K8
-#define KK4 RMD_K1
-
-#define F1(x, y, z) (x ^ y ^ z) /* XOR */
-#define F2(x, y, z) (z ^ (x & (y ^ z))) /* x ? y : z */
-#define F3(x, y, z) ((x | ~y) ^ z)
-#define F4(x, y, z) (y ^ (z & (x ^ y))) /* z ? x : y */
-
-#define ROUND(a, b, c, d, f, k, x, s) { \
- (a) += f((b), (c), (d)) + le32_to_cpup(&(x)) + (k); \
- (a) = rol32((a), (s)); \
-}
-
-static void rmd128_transform(u32 *state, const __le32 *in)
-{
- u32 aa, bb, cc, dd, aaa, bbb, ccc, ddd;
-
- /* Initialize left lane */
- aa = state[0];
- bb = state[1];
- cc = state[2];
- dd = state[3];
-
- /* Initialize right lane */
- aaa = state[0];
- bbb = state[1];
- ccc = state[2];
- ddd = state[3];
-
- /* round 1: left lane */
- ROUND(aa, bb, cc, dd, F1, K1, in[0], 11);
- ROUND(dd, aa, bb, cc, F1, K1, in[1], 14);
- ROUND(cc, dd, aa, bb, F1, K1, in[2], 15);
- ROUND(bb, cc, dd, aa, F1, K1, in[3], 12);
- ROUND(aa, bb, cc, dd, F1, K1, in[4], 5);
- ROUND(dd, aa, bb, cc, F1, K1, in[5], 8);
- ROUND(cc, dd, aa, bb, F1, K1, in[6], 7);
- ROUND(bb, cc, dd, aa, F1, K1, in[7], 9);
- ROUND(aa, bb, cc, dd, F1, K1, in[8], 11);
- ROUND(dd, aa, bb, cc, F1, K1, in[9], 13);
- ROUND(cc, dd, aa, bb, F1, K1, in[10], 14);
- ROUND(bb, cc, dd, aa, F1, K1, in[11], 15);
- ROUND(aa, bb, cc, dd, F1, K1, in[12], 6);
- ROUND(dd, aa, bb, cc, F1, K1, in[13], 7);
- ROUND(cc, dd, aa, bb, F1, K1, in[14], 9);
- ROUND(bb, cc, dd, aa, F1, K1, in[15], 8);
-
- /* round 2: left lane */
- ROUND(aa, bb, cc, dd, F2, K2, in[7], 7);
- ROUND(dd, aa, bb, cc, F2, K2, in[4], 6);
- ROUND(cc, dd, aa, bb, F2, K2, in[13], 8);
- ROUND(bb, cc, dd, aa, F2, K2, in[1], 13);
- ROUND(aa, bb, cc, dd, F2, K2, in[10], 11);
- ROUND(dd, aa, bb, cc, F2, K2, in[6], 9);
- ROUND(cc, dd, aa, bb, F2, K2, in[15], 7);
- ROUND(bb, cc, dd, aa, F2, K2, in[3], 15);
- ROUND(aa, bb, cc, dd, F2, K2, in[12], 7);
- ROUND(dd, aa, bb, cc, F2, K2, in[0], 12);
- ROUND(cc, dd, aa, bb, F2, K2, in[9], 15);
- ROUND(bb, cc, dd, aa, F2, K2, in[5], 9);
- ROUND(aa, bb, cc, dd, F2, K2, in[2], 11);
- ROUND(dd, aa, bb, cc, F2, K2, in[14], 7);
- ROUND(cc, dd, aa, bb, F2, K2, in[11], 13);
- ROUND(bb, cc, dd, aa, F2, K2, in[8], 12);
-
- /* round 3: left lane */
- ROUND(aa, bb, cc, dd, F3, K3, in[3], 11);
- ROUND(dd, aa, bb, cc, F3, K3, in[10], 13);
- ROUND(cc, dd, aa, bb, F3, K3, in[14], 6);
- ROUND(bb, cc, dd, aa, F3, K3, in[4], 7);
- ROUND(aa, bb, cc, dd, F3, K3, in[9], 14);
- ROUND(dd, aa, bb, cc, F3, K3, in[15], 9);
- ROUND(cc, dd, aa, bb, F3, K3, in[8], 13);
- ROUND(bb, cc, dd, aa, F3, K3, in[1], 15);
- ROUND(aa, bb, cc, dd, F3, K3, in[2], 14);
- ROUND(dd, aa, bb, cc, F3, K3, in[7], 8);
- ROUND(cc, dd, aa, bb, F3, K3, in[0], 13);
- ROUND(bb, cc, dd, aa, F3, K3, in[6], 6);
- ROUND(aa, bb, cc, dd, F3, K3, in[13], 5);
- ROUND(dd, aa, bb, cc, F3, K3, in[11], 12);
- ROUND(cc, dd, aa, bb, F3, K3, in[5], 7);
- ROUND(bb, cc, dd, aa, F3, K3, in[12], 5);
-
- /* round 4: left lane */
- ROUND(aa, bb, cc, dd, F4, K4, in[1], 11);
- ROUND(dd, aa, bb, cc, F4, K4, in[9], 12);
- ROUND(cc, dd, aa, bb, F4, K4, in[11], 14);
- ROUND(bb, cc, dd, aa, F4, K4, in[10], 15);
- ROUND(aa, bb, cc, dd, F4, K4, in[0], 14);
- ROUND(dd, aa, bb, cc, F4, K4, in[8], 15);
- ROUND(cc, dd, aa, bb, F4, K4, in[12], 9);
- ROUND(bb, cc, dd, aa, F4, K4, in[4], 8);
- ROUND(aa, bb, cc, dd, F4, K4, in[13], 9);
- ROUND(dd, aa, bb, cc, F4, K4, in[3], 14);
- ROUND(cc, dd, aa, bb, F4, K4, in[7], 5);
- ROUND(bb, cc, dd, aa, F4, K4, in[15], 6);
- ROUND(aa, bb, cc, dd, F4, K4, in[14], 8);
- ROUND(dd, aa, bb, cc, F4, K4, in[5], 6);
- ROUND(cc, dd, aa, bb, F4, K4, in[6], 5);
- ROUND(bb, cc, dd, aa, F4, K4, in[2], 12);
-
- /* round 1: right lane */
- ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[5], 8);
- ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[14], 9);
- ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[7], 9);
- ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[0], 11);
- ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[9], 13);
- ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[2], 15);
- ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[11], 15);
- ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[4], 5);
- ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[13], 7);
- ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[6], 7);
- ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[15], 8);
- ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[8], 11);
- ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[1], 14);
- ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[10], 14);
- ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[3], 12);
- ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[12], 6);
-
- /* round 2: right lane */
- ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[6], 9);
- ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[11], 13);
- ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[3], 15);
- ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[7], 7);
- ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[0], 12);
- ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[13], 8);
- ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[5], 9);
- ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[10], 11);
- ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[14], 7);
- ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[15], 7);
- ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[8], 12);
- ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[12], 7);
- ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[4], 6);
- ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[9], 15);
- ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[1], 13);
- ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[2], 11);
-
- /* round 3: right lane */
- ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[15], 9);
- ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[5], 7);
- ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[1], 15);
- ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[3], 11);
- ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[7], 8);
- ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[14], 6);
- ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[6], 6);
- ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[9], 14);
- ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[11], 12);
- ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[8], 13);
- ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[12], 5);
- ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[2], 14);
- ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[10], 13);
- ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[0], 13);
- ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[4], 7);
- ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[13], 5);
-
- /* round 4: right lane */
- ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[8], 15);
- ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[6], 5);
- ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[4], 8);
- ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[1], 11);
- ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[3], 14);
- ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[11], 14);
- ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[15], 6);
- ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[0], 14);
- ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[5], 6);
- ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[12], 9);
- ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[2], 12);
- ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[13], 9);
- ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[9], 12);
- ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[7], 5);
- ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[10], 15);
- ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[14], 8);
-
- /* combine results */
- ddd += cc + state[1]; /* final result for state[0] */
- state[1] = state[2] + dd + aaa;
- state[2] = state[3] + aa + bbb;
- state[3] = state[0] + bb + ccc;
- state[0] = ddd;
-}
-
-static int rmd128_init(struct shash_desc *desc)
-{
- struct rmd128_ctx *rctx = shash_desc_ctx(desc);
-
- rctx->byte_count = 0;
-
- rctx->state[0] = RMD_H0;
- rctx->state[1] = RMD_H1;
- rctx->state[2] = RMD_H2;
- rctx->state[3] = RMD_H3;
-
- memset(rctx->buffer, 0, sizeof(rctx->buffer));
-
- return 0;
-}
-
-static int rmd128_update(struct shash_desc *desc, const u8 *data,
- unsigned int len)
-{
- struct rmd128_ctx *rctx = shash_desc_ctx(desc);
- const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f);
-
- rctx->byte_count += len;
-
- /* Enough space in buffer? If so copy and we're done */
- if (avail > len) {
- memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
- data, len);
- goto out;
- }
-
- memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
- data, avail);
-
- rmd128_transform(rctx->state, rctx->buffer);
- data += avail;
- len -= avail;
-
- while (len >= sizeof(rctx->buffer)) {
- memcpy(rctx->buffer, data, sizeof(rctx->buffer));
- rmd128_transform(rctx->state, rctx->buffer);
- data += sizeof(rctx->buffer);
- len -= sizeof(rctx->buffer);
- }
-
- memcpy(rctx->buffer, data, len);
-
-out:
- return 0;
-}
-
-/* Add padding and return the message digest. */
-static int rmd128_final(struct shash_desc *desc, u8 *out)
-{
- struct rmd128_ctx *rctx = shash_desc_ctx(desc);
- u32 i, index, padlen;
- __le64 bits;
- __le32 *dst = (__le32 *)out;
- static const u8 padding[64] = { 0x80, };
-
- bits = cpu_to_le64(rctx->byte_count << 3);
-
- /* Pad out to 56 mod 64 */
- index = rctx->byte_count & 0x3f;
- padlen = (index < 56) ? (56 - index) : ((64+56) - index);
- rmd128_update(desc, padding, padlen);
-
- /* Append length */
- rmd128_update(desc, (const u8 *)&bits, sizeof(bits));
-
- /* Store state in digest */
- for (i = 0; i < 4; i++)
- dst[i] = cpu_to_le32p(&rctx->state[i]);
-
- /* Wipe context */
- memset(rctx, 0, sizeof(*rctx));
-
- return 0;
-}
-
-static struct shash_alg alg = {
- .digestsize = RMD128_DIGEST_SIZE,
- .init = rmd128_init,
- .update = rmd128_update,
- .final = rmd128_final,
- .descsize = sizeof(struct rmd128_ctx),
- .base = {
- .cra_name = "rmd128",
- .cra_driver_name = "rmd128-generic",
- .cra_blocksize = RMD128_BLOCK_SIZE,
- .cra_module = THIS_MODULE,
- }
-};
-
-static int __init rmd128_mod_init(void)
-{
- return crypto_register_shash(&alg);
-}
-
-static void __exit rmd128_mod_fini(void)
-{
- crypto_unregister_shash(&alg);
-}
-
-subsys_initcall(rmd128_mod_init);
-module_exit(rmd128_mod_fini);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>");
-MODULE_DESCRIPTION("RIPEMD-128 Message Digest");
-MODULE_ALIAS_CRYPTO("rmd128");
diff --git a/crypto/rmd256.c b/crypto/rmd256.c
deleted file mode 100644
index 3c730e9de5fd..000000000000
--- a/crypto/rmd256.c
+++ /dev/null
@@ -1,342 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Cryptographic API.
- *
- * RIPEMD-256 - RACE Integrity Primitives Evaluation Message Digest.
- *
- * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC
- *
- * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch>
- */
-#include <crypto/internal/hash.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-#include "ripemd.h"
-
-struct rmd256_ctx {
- u64 byte_count;
- u32 state[8];
- __le32 buffer[16];
-};
-
-#define K1 RMD_K1
-#define K2 RMD_K2
-#define K3 RMD_K3
-#define K4 RMD_K4
-#define KK1 RMD_K6
-#define KK2 RMD_K7
-#define KK3 RMD_K8
-#define KK4 RMD_K1
-
-#define F1(x, y, z) (x ^ y ^ z) /* XOR */
-#define F2(x, y, z) (z ^ (x & (y ^ z))) /* x ? y : z */
-#define F3(x, y, z) ((x | ~y) ^ z)
-#define F4(x, y, z) (y ^ (z & (x ^ y))) /* z ? x : y */
-
-#define ROUND(a, b, c, d, f, k, x, s) { \
- (a) += f((b), (c), (d)) + le32_to_cpup(&(x)) + (k); \
- (a) = rol32((a), (s)); \
-}
-
-static void rmd256_transform(u32 *state, const __le32 *in)
-{
- u32 aa, bb, cc, dd, aaa, bbb, ccc, ddd;
-
- /* Initialize left lane */
- aa = state[0];
- bb = state[1];
- cc = state[2];
- dd = state[3];
-
- /* Initialize right lane */
- aaa = state[4];
- bbb = state[5];
- ccc = state[6];
- ddd = state[7];
-
- /* round 1: left lane */
- ROUND(aa, bb, cc, dd, F1, K1, in[0], 11);
- ROUND(dd, aa, bb, cc, F1, K1, in[1], 14);
- ROUND(cc, dd, aa, bb, F1, K1, in[2], 15);
- ROUND(bb, cc, dd, aa, F1, K1, in[3], 12);
- ROUND(aa, bb, cc, dd, F1, K1, in[4], 5);
- ROUND(dd, aa, bb, cc, F1, K1, in[5], 8);
- ROUND(cc, dd, aa, bb, F1, K1, in[6], 7);
- ROUND(bb, cc, dd, aa, F1, K1, in[7], 9);
- ROUND(aa, bb, cc, dd, F1, K1, in[8], 11);
- ROUND(dd, aa, bb, cc, F1, K1, in[9], 13);
- ROUND(cc, dd, aa, bb, F1, K1, in[10], 14);
- ROUND(bb, cc, dd, aa, F1, K1, in[11], 15);
- ROUND(aa, bb, cc, dd, F1, K1, in[12], 6);
- ROUND(dd, aa, bb, cc, F1, K1, in[13], 7);
- ROUND(cc, dd, aa, bb, F1, K1, in[14], 9);
- ROUND(bb, cc, dd, aa, F1, K1, in[15], 8);
-
- /* round 1: right lane */
- ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[5], 8);
- ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[14], 9);
- ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[7], 9);
- ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[0], 11);
- ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[9], 13);
- ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[2], 15);
- ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[11], 15);
- ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[4], 5);
- ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[13], 7);
- ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[6], 7);
- ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[15], 8);
- ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[8], 11);
- ROUND(aaa, bbb, ccc, ddd, F4, KK1, in[1], 14);
- ROUND(ddd, aaa, bbb, ccc, F4, KK1, in[10], 14);
- ROUND(ccc, ddd, aaa, bbb, F4, KK1, in[3], 12);
- ROUND(bbb, ccc, ddd, aaa, F4, KK1, in[12], 6);
-
- /* Swap contents of "a" registers */
- swap(aa, aaa);
-
- /* round 2: left lane */
- ROUND(aa, bb, cc, dd, F2, K2, in[7], 7);
- ROUND(dd, aa, bb, cc, F2, K2, in[4], 6);
- ROUND(cc, dd, aa, bb, F2, K2, in[13], 8);
- ROUND(bb, cc, dd, aa, F2, K2, in[1], 13);
- ROUND(aa, bb, cc, dd, F2, K2, in[10], 11);
- ROUND(dd, aa, bb, cc, F2, K2, in[6], 9);
- ROUND(cc, dd, aa, bb, F2, K2, in[15], 7);
- ROUND(bb, cc, dd, aa, F2, K2, in[3], 15);
- ROUND(aa, bb, cc, dd, F2, K2, in[12], 7);
- ROUND(dd, aa, bb, cc, F2, K2, in[0], 12);
- ROUND(cc, dd, aa, bb, F2, K2, in[9], 15);
- ROUND(bb, cc, dd, aa, F2, K2, in[5], 9);
- ROUND(aa, bb, cc, dd, F2, K2, in[2], 11);
- ROUND(dd, aa, bb, cc, F2, K2, in[14], 7);
- ROUND(cc, dd, aa, bb, F2, K2, in[11], 13);
- ROUND(bb, cc, dd, aa, F2, K2, in[8], 12);
-
- /* round 2: right lane */
- ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[6], 9);
- ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[11], 13);
- ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[3], 15);
- ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[7], 7);
- ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[0], 12);
- ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[13], 8);
- ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[5], 9);
- ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[10], 11);
- ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[14], 7);
- ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[15], 7);
- ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[8], 12);
- ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[12], 7);
- ROUND(aaa, bbb, ccc, ddd, F3, KK2, in[4], 6);
- ROUND(ddd, aaa, bbb, ccc, F3, KK2, in[9], 15);
- ROUND(ccc, ddd, aaa, bbb, F3, KK2, in[1], 13);
- ROUND(bbb, ccc, ddd, aaa, F3, KK2, in[2], 11);
-
- /* Swap contents of "b" registers */
- swap(bb, bbb);
-
- /* round 3: left lane */
- ROUND(aa, bb, cc, dd, F3, K3, in[3], 11);
- ROUND(dd, aa, bb, cc, F3, K3, in[10], 13);
- ROUND(cc, dd, aa, bb, F3, K3, in[14], 6);
- ROUND(bb, cc, dd, aa, F3, K3, in[4], 7);
- ROUND(aa, bb, cc, dd, F3, K3, in[9], 14);
- ROUND(dd, aa, bb, cc, F3, K3, in[15], 9);
- ROUND(cc, dd, aa, bb, F3, K3, in[8], 13);
- ROUND(bb, cc, dd, aa, F3, K3, in[1], 15);
- ROUND(aa, bb, cc, dd, F3, K3, in[2], 14);
- ROUND(dd, aa, bb, cc, F3, K3, in[7], 8);
- ROUND(cc, dd, aa, bb, F3, K3, in[0], 13);
- ROUND(bb, cc, dd, aa, F3, K3, in[6], 6);
- ROUND(aa, bb, cc, dd, F3, K3, in[13], 5);
- ROUND(dd, aa, bb, cc, F3, K3, in[11], 12);
- ROUND(cc, dd, aa, bb, F3, K3, in[5], 7);
- ROUND(bb, cc, dd, aa, F3, K3, in[12], 5);
-
- /* round 3: right lane */
- ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[15], 9);
- ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[5], 7);
- ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[1], 15);
- ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[3], 11);
- ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[7], 8);
- ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[14], 6);
- ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[6], 6);
- ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[9], 14);
- ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[11], 12);
- ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[8], 13);
- ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[12], 5);
- ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[2], 14);
- ROUND(aaa, bbb, ccc, ddd, F2, KK3, in[10], 13);
- ROUND(ddd, aaa, bbb, ccc, F2, KK3, in[0], 13);
- ROUND(ccc, ddd, aaa, bbb, F2, KK3, in[4], 7);
- ROUND(bbb, ccc, ddd, aaa, F2, KK3, in[13], 5);
-
- /* Swap contents of "c" registers */
- swap(cc, ccc);
-
- /* round 4: left lane */
- ROUND(aa, bb, cc, dd, F4, K4, in[1], 11);
- ROUND(dd, aa, bb, cc, F4, K4, in[9], 12);
- ROUND(cc, dd, aa, bb, F4, K4, in[11], 14);
- ROUND(bb, cc, dd, aa, F4, K4, in[10], 15);
- ROUND(aa, bb, cc, dd, F4, K4, in[0], 14);
- ROUND(dd, aa, bb, cc, F4, K4, in[8], 15);
- ROUND(cc, dd, aa, bb, F4, K4, in[12], 9);
- ROUND(bb, cc, dd, aa, F4, K4, in[4], 8);
- ROUND(aa, bb, cc, dd, F4, K4, in[13], 9);
- ROUND(dd, aa, bb, cc, F4, K4, in[3], 14);
- ROUND(cc, dd, aa, bb, F4, K4, in[7], 5);
- ROUND(bb, cc, dd, aa, F4, K4, in[15], 6);
- ROUND(aa, bb, cc, dd, F4, K4, in[14], 8);
- ROUND(dd, aa, bb, cc, F4, K4, in[5], 6);
- ROUND(cc, dd, aa, bb, F4, K4, in[6], 5);
- ROUND(bb, cc, dd, aa, F4, K4, in[2], 12);
-
- /* round 4: right lane */
- ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[8], 15);
- ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[6], 5);
- ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[4], 8);
- ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[1], 11);
- ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[3], 14);
- ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[11], 14);
- ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[15], 6);
- ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[0], 14);
- ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[5], 6);
- ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[12], 9);
- ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[2], 12);
- ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[13], 9);
- ROUND(aaa, bbb, ccc, ddd, F1, KK4, in[9], 12);
- ROUND(ddd, aaa, bbb, ccc, F1, KK4, in[7], 5);
- ROUND(ccc, ddd, aaa, bbb, F1, KK4, in[10], 15);
- ROUND(bbb, ccc, ddd, aaa, F1, KK4, in[14], 8);
-
- /* Swap contents of "d" registers */
- swap(dd, ddd);
-
- /* combine results */
- state[0] += aa;
- state[1] += bb;
- state[2] += cc;
- state[3] += dd;
- state[4] += aaa;
- state[5] += bbb;
- state[6] += ccc;
- state[7] += ddd;
-}
-
-static int rmd256_init(struct shash_desc *desc)
-{
- struct rmd256_ctx *rctx = shash_desc_ctx(desc);
-
- rctx->byte_count = 0;
-
- rctx->state[0] = RMD_H0;
- rctx->state[1] = RMD_H1;
- rctx->state[2] = RMD_H2;
- rctx->state[3] = RMD_H3;
- rctx->state[4] = RMD_H5;
- rctx->state[5] = RMD_H6;
- rctx->state[6] = RMD_H7;
- rctx->state[7] = RMD_H8;
-
- memset(rctx->buffer, 0, sizeof(rctx->buffer));
-
- return 0;
-}
-
-static int rmd256_update(struct shash_desc *desc, const u8 *data,
- unsigned int len)
-{
- struct rmd256_ctx *rctx = shash_desc_ctx(desc);
- const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f);
-
- rctx->byte_count += len;
-
- /* Enough space in buffer? If so copy and we're done */
- if (avail > len) {
- memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
- data, len);
- goto out;
- }
-
- memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
- data, avail);
-
- rmd256_transform(rctx->state, rctx->buffer);
- data += avail;
- len -= avail;
-
- while (len >= sizeof(rctx->buffer)) {
- memcpy(rctx->buffer, data, sizeof(rctx->buffer));
- rmd256_transform(rctx->state, rctx->buffer);
- data += sizeof(rctx->buffer);
- len -= sizeof(rctx->buffer);
- }
-
- memcpy(rctx->buffer, data, len);
-
-out:
- return 0;
-}
-
-/* Add padding and return the message digest. */
-static int rmd256_final(struct shash_desc *desc, u8 *out)
-{
- struct rmd256_ctx *rctx = shash_desc_ctx(desc);
- u32 i, index, padlen;
- __le64 bits;
- __le32 *dst = (__le32 *)out;
- static const u8 padding[64] = { 0x80, };
-
- bits = cpu_to_le64(rctx->byte_count << 3);
-
- /* Pad out to 56 mod 64 */
- index = rctx->byte_count & 0x3f;
- padlen = (index < 56) ? (56 - index) : ((64+56) - index);
- rmd256_update(desc, padding, padlen);
-
- /* Append length */
- rmd256_update(desc, (const u8 *)&bits, sizeof(bits));
-
- /* Store state in digest */
- for (i = 0; i < 8; i++)
- dst[i] = cpu_to_le32p(&rctx->state[i]);
-
- /* Wipe context */
- memset(rctx, 0, sizeof(*rctx));
-
- return 0;
-}
-
-static struct shash_alg alg = {
- .digestsize = RMD256_DIGEST_SIZE,
- .init = rmd256_init,
- .update = rmd256_update,
- .final = rmd256_final,
- .descsize = sizeof(struct rmd256_ctx),
- .base = {
- .cra_name = "rmd256",
- .cra_driver_name = "rmd256-generic",
- .cra_blocksize = RMD256_BLOCK_SIZE,
- .cra_module = THIS_MODULE,
- }
-};
-
-static int __init rmd256_mod_init(void)
-{
- return crypto_register_shash(&alg);
-}
-
-static void __exit rmd256_mod_fini(void)
-{
- crypto_unregister_shash(&alg);
-}
-
-subsys_initcall(rmd256_mod_init);
-module_exit(rmd256_mod_fini);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>");
-MODULE_DESCRIPTION("RIPEMD-256 Message Digest");
-MODULE_ALIAS_CRYPTO("rmd256");
diff --git a/crypto/rmd320.c b/crypto/rmd320.c
deleted file mode 100644
index c919ad6c4705..000000000000
--- a/crypto/rmd320.c
+++ /dev/null
@@ -1,391 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Cryptographic API.
- *
- * RIPEMD-320 - RACE Integrity Primitives Evaluation Message Digest.
- *
- * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC
- *
- * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch>
- */
-#include <crypto/internal/hash.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-#include "ripemd.h"
-
-struct rmd320_ctx {
- u64 byte_count;
- u32 state[10];
- __le32 buffer[16];
-};
-
-#define K1 RMD_K1
-#define K2 RMD_K2
-#define K3 RMD_K3
-#define K4 RMD_K4
-#define K5 RMD_K5
-#define KK1 RMD_K6
-#define KK2 RMD_K7
-#define KK3 RMD_K8
-#define KK4 RMD_K9
-#define KK5 RMD_K1
-
-#define F1(x, y, z) (x ^ y ^ z) /* XOR */
-#define F2(x, y, z) (z ^ (x & (y ^ z))) /* x ? y : z */
-#define F3(x, y, z) ((x | ~y) ^ z)
-#define F4(x, y, z) (y ^ (z & (x ^ y))) /* z ? x : y */
-#define F5(x, y, z) (x ^ (y | ~z))
-
-#define ROUND(a, b, c, d, e, f, k, x, s) { \
- (a) += f((b), (c), (d)) + le32_to_cpup(&(x)) + (k); \
- (a) = rol32((a), (s)) + (e); \
- (c) = rol32((c), 10); \
-}
-
-static void rmd320_transform(u32 *state, const __le32 *in)
-{
- u32 aa, bb, cc, dd, ee, aaa, bbb, ccc, ddd, eee;
-
- /* Initialize left lane */
- aa = state[0];
- bb = state[1];
- cc = state[2];
- dd = state[3];
- ee = state[4];
-
- /* Initialize right lane */
- aaa = state[5];
- bbb = state[6];
- ccc = state[7];
- ddd = state[8];
- eee = state[9];
-
- /* round 1: left lane */
- ROUND(aa, bb, cc, dd, ee, F1, K1, in[0], 11);
- ROUND(ee, aa, bb, cc, dd, F1, K1, in[1], 14);
- ROUND(dd, ee, aa, bb, cc, F1, K1, in[2], 15);
- ROUND(cc, dd, ee, aa, bb, F1, K1, in[3], 12);
- ROUND(bb, cc, dd, ee, aa, F1, K1, in[4], 5);
- ROUND(aa, bb, cc, dd, ee, F1, K1, in[5], 8);
- ROUND(ee, aa, bb, cc, dd, F1, K1, in[6], 7);
- ROUND(dd, ee, aa, bb, cc, F1, K1, in[7], 9);
- ROUND(cc, dd, ee, aa, bb, F1, K1, in[8], 11);
- ROUND(bb, cc, dd, ee, aa, F1, K1, in[9], 13);
- ROUND(aa, bb, cc, dd, ee, F1, K1, in[10], 14);
- ROUND(ee, aa, bb, cc, dd, F1, K1, in[11], 15);
- ROUND(dd, ee, aa, bb, cc, F1, K1, in[12], 6);
- ROUND(cc, dd, ee, aa, bb, F1, K1, in[13], 7);
- ROUND(bb, cc, dd, ee, aa, F1, K1, in[14], 9);
- ROUND(aa, bb, cc, dd, ee, F1, K1, in[15], 8);
-
- /* round 1: right lane */
- ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[5], 8);
- ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[14], 9);
- ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[7], 9);
- ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[0], 11);
- ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[9], 13);
- ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[2], 15);
- ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[11], 15);
- ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[4], 5);
- ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[13], 7);
- ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[6], 7);
- ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[15], 8);
- ROUND(eee, aaa, bbb, ccc, ddd, F5, KK1, in[8], 11);
- ROUND(ddd, eee, aaa, bbb, ccc, F5, KK1, in[1], 14);
- ROUND(ccc, ddd, eee, aaa, bbb, F5, KK1, in[10], 14);
- ROUND(bbb, ccc, ddd, eee, aaa, F5, KK1, in[3], 12);
- ROUND(aaa, bbb, ccc, ddd, eee, F5, KK1, in[12], 6);
-
- /* Swap contents of "a" registers */
- swap(aa, aaa);
-
- /* round 2: left lane" */
- ROUND(ee, aa, bb, cc, dd, F2, K2, in[7], 7);
- ROUND(dd, ee, aa, bb, cc, F2, K2, in[4], 6);
- ROUND(cc, dd, ee, aa, bb, F2, K2, in[13], 8);
- ROUND(bb, cc, dd, ee, aa, F2, K2, in[1], 13);
- ROUND(aa, bb, cc, dd, ee, F2, K2, in[10], 11);
- ROUND(ee, aa, bb, cc, dd, F2, K2, in[6], 9);
- ROUND(dd, ee, aa, bb, cc, F2, K2, in[15], 7);
- ROUND(cc, dd, ee, aa, bb, F2, K2, in[3], 15);
- ROUND(bb, cc, dd, ee, aa, F2, K2, in[12], 7);
- ROUND(aa, bb, cc, dd, ee, F2, K2, in[0], 12);
- ROUND(ee, aa, bb, cc, dd, F2, K2, in[9], 15);
- ROUND(dd, ee, aa, bb, cc, F2, K2, in[5], 9);
- ROUND(cc, dd, ee, aa, bb, F2, K2, in[2], 11);
- ROUND(bb, cc, dd, ee, aa, F2, K2, in[14], 7);
- ROUND(aa, bb, cc, dd, ee, F2, K2, in[11], 13);
- ROUND(ee, aa, bb, cc, dd, F2, K2, in[8], 12);
-
- /* round 2: right lane */
- ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[6], 9);
- ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[11], 13);
- ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[3], 15);
- ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[7], 7);
- ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[0], 12);
- ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[13], 8);
- ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[5], 9);
- ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[10], 11);
- ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[14], 7);
- ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[15], 7);
- ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[8], 12);
- ROUND(ddd, eee, aaa, bbb, ccc, F4, KK2, in[12], 7);
- ROUND(ccc, ddd, eee, aaa, bbb, F4, KK2, in[4], 6);
- ROUND(bbb, ccc, ddd, eee, aaa, F4, KK2, in[9], 15);
- ROUND(aaa, bbb, ccc, ddd, eee, F4, KK2, in[1], 13);
- ROUND(eee, aaa, bbb, ccc, ddd, F4, KK2, in[2], 11);
-
- /* Swap contents of "b" registers */
- swap(bb, bbb);
-
- /* round 3: left lane" */
- ROUND(dd, ee, aa, bb, cc, F3, K3, in[3], 11);
- ROUND(cc, dd, ee, aa, bb, F3, K3, in[10], 13);
- ROUND(bb, cc, dd, ee, aa, F3, K3, in[14], 6);
- ROUND(aa, bb, cc, dd, ee, F3, K3, in[4], 7);
- ROUND(ee, aa, bb, cc, dd, F3, K3, in[9], 14);
- ROUND(dd, ee, aa, bb, cc, F3, K3, in[15], 9);
- ROUND(cc, dd, ee, aa, bb, F3, K3, in[8], 13);
- ROUND(bb, cc, dd, ee, aa, F3, K3, in[1], 15);
- ROUND(aa, bb, cc, dd, ee, F3, K3, in[2], 14);
- ROUND(ee, aa, bb, cc, dd, F3, K3, in[7], 8);
- ROUND(dd, ee, aa, bb, cc, F3, K3, in[0], 13);
- ROUND(cc, dd, ee, aa, bb, F3, K3, in[6], 6);
- ROUND(bb, cc, dd, ee, aa, F3, K3, in[13], 5);
- ROUND(aa, bb, cc, dd, ee, F3, K3, in[11], 12);
- ROUND(ee, aa, bb, cc, dd, F3, K3, in[5], 7);
- ROUND(dd, ee, aa, bb, cc, F3, K3, in[12], 5);
-
- /* round 3: right lane */
- ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[15], 9);
- ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[5], 7);
- ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[1], 15);
- ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[3], 11);
- ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[7], 8);
- ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[14], 6);
- ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[6], 6);
- ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[9], 14);
- ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[11], 12);
- ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[8], 13);
- ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[12], 5);
- ROUND(ccc, ddd, eee, aaa, bbb, F3, KK3, in[2], 14);
- ROUND(bbb, ccc, ddd, eee, aaa, F3, KK3, in[10], 13);
- ROUND(aaa, bbb, ccc, ddd, eee, F3, KK3, in[0], 13);
- ROUND(eee, aaa, bbb, ccc, ddd, F3, KK3, in[4], 7);
- ROUND(ddd, eee, aaa, bbb, ccc, F3, KK3, in[13], 5);
-
- /* Swap contents of "c" registers */
- swap(cc, ccc);
-
- /* round 4: left lane" */
- ROUND(cc, dd, ee, aa, bb, F4, K4, in[1], 11);
- ROUND(bb, cc, dd, ee, aa, F4, K4, in[9], 12);
- ROUND(aa, bb, cc, dd, ee, F4, K4, in[11], 14);
- ROUND(ee, aa, bb, cc, dd, F4, K4, in[10], 15);
- ROUND(dd, ee, aa, bb, cc, F4, K4, in[0], 14);
- ROUND(cc, dd, ee, aa, bb, F4, K4, in[8], 15);
- ROUND(bb, cc, dd, ee, aa, F4, K4, in[12], 9);
- ROUND(aa, bb, cc, dd, ee, F4, K4, in[4], 8);
- ROUND(ee, aa, bb, cc, dd, F4, K4, in[13], 9);
- ROUND(dd, ee, aa, bb, cc, F4, K4, in[3], 14);
- ROUND(cc, dd, ee, aa, bb, F4, K4, in[7], 5);
- ROUND(bb, cc, dd, ee, aa, F4, K4, in[15], 6);
- ROUND(aa, bb, cc, dd, ee, F4, K4, in[14], 8);
- ROUND(ee, aa, bb, cc, dd, F4, K4, in[5], 6);
- ROUND(dd, ee, aa, bb, cc, F4, K4, in[6], 5);
- ROUND(cc, dd, ee, aa, bb, F4, K4, in[2], 12);
-
- /* round 4: right lane */
- ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[8], 15);
- ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[6], 5);
- ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[4], 8);
- ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[1], 11);
- ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[3], 14);
- ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[11], 14);
- ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[15], 6);
- ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[0], 14);
- ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[5], 6);
- ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[12], 9);
- ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[2], 12);
- ROUND(bbb, ccc, ddd, eee, aaa, F2, KK4, in[13], 9);
- ROUND(aaa, bbb, ccc, ddd, eee, F2, KK4, in[9], 12);
- ROUND(eee, aaa, bbb, ccc, ddd, F2, KK4, in[7], 5);
- ROUND(ddd, eee, aaa, bbb, ccc, F2, KK4, in[10], 15);
- ROUND(ccc, ddd, eee, aaa, bbb, F2, KK4, in[14], 8);
-
- /* Swap contents of "d" registers */
- swap(dd, ddd);
-
- /* round 5: left lane" */
- ROUND(bb, cc, dd, ee, aa, F5, K5, in[4], 9);
- ROUND(aa, bb, cc, dd, ee, F5, K5, in[0], 15);
- ROUND(ee, aa, bb, cc, dd, F5, K5, in[5], 5);
- ROUND(dd, ee, aa, bb, cc, F5, K5, in[9], 11);
- ROUND(cc, dd, ee, aa, bb, F5, K5, in[7], 6);
- ROUND(bb, cc, dd, ee, aa, F5, K5, in[12], 8);
- ROUND(aa, bb, cc, dd, ee, F5, K5, in[2], 13);
- ROUND(ee, aa, bb, cc, dd, F5, K5, in[10], 12);
- ROUND(dd, ee, aa, bb, cc, F5, K5, in[14], 5);
- ROUND(cc, dd, ee, aa, bb, F5, K5, in[1], 12);
- ROUND(bb, cc, dd, ee, aa, F5, K5, in[3], 13);
- ROUND(aa, bb, cc, dd, ee, F5, K5, in[8], 14);
- ROUND(ee, aa, bb, cc, dd, F5, K5, in[11], 11);
- ROUND(dd, ee, aa, bb, cc, F5, K5, in[6], 8);
- ROUND(cc, dd, ee, aa, bb, F5, K5, in[15], 5);
- ROUND(bb, cc, dd, ee, aa, F5, K5, in[13], 6);
-
- /* round 5: right lane */
- ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[12], 8);
- ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[15], 5);
- ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[10], 12);
- ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[4], 9);
- ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[1], 12);
- ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[5], 5);
- ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[8], 14);
- ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[7], 6);
- ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[6], 8);
- ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[2], 13);
- ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[13], 6);
- ROUND(aaa, bbb, ccc, ddd, eee, F1, KK5, in[14], 5);
- ROUND(eee, aaa, bbb, ccc, ddd, F1, KK5, in[0], 15);
- ROUND(ddd, eee, aaa, bbb, ccc, F1, KK5, in[3], 13);
- ROUND(ccc, ddd, eee, aaa, bbb, F1, KK5, in[9], 11);
- ROUND(bbb, ccc, ddd, eee, aaa, F1, KK5, in[11], 11);
-
- /* Swap contents of "e" registers */
- swap(ee, eee);
-
- /* combine results */
- state[0] += aa;
- state[1] += bb;
- state[2] += cc;
- state[3] += dd;
- state[4] += ee;
- state[5] += aaa;
- state[6] += bbb;
- state[7] += ccc;
- state[8] += ddd;
- state[9] += eee;
-}
-
-static int rmd320_init(struct shash_desc *desc)
-{
- struct rmd320_ctx *rctx = shash_desc_ctx(desc);
-
- rctx->byte_count = 0;
-
- rctx->state[0] = RMD_H0;
- rctx->state[1] = RMD_H1;
- rctx->state[2] = RMD_H2;
- rctx->state[3] = RMD_H3;
- rctx->state[4] = RMD_H4;
- rctx->state[5] = RMD_H5;
- rctx->state[6] = RMD_H6;
- rctx->state[7] = RMD_H7;
- rctx->state[8] = RMD_H8;
- rctx->state[9] = RMD_H9;
-
- memset(rctx->buffer, 0, sizeof(rctx->buffer));
-
- return 0;
-}
-
-static int rmd320_update(struct shash_desc *desc, const u8 *data,
- unsigned int len)
-{
- struct rmd320_ctx *rctx = shash_desc_ctx(desc);
- const u32 avail = sizeof(rctx->buffer) - (rctx->byte_count & 0x3f);
-
- rctx->byte_count += len;
-
- /* Enough space in buffer? If so copy and we're done */
- if (avail > len) {
- memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
- data, len);
- goto out;
- }
-
- memcpy((char *)rctx->buffer + (sizeof(rctx->buffer) - avail),
- data, avail);
-
- rmd320_transform(rctx->state, rctx->buffer);
- data += avail;
- len -= avail;
-
- while (len >= sizeof(rctx->buffer)) {
- memcpy(rctx->buffer, data, sizeof(rctx->buffer));
- rmd320_transform(rctx->state, rctx->buffer);
- data += sizeof(rctx->buffer);
- len -= sizeof(rctx->buffer);
- }
-
- memcpy(rctx->buffer, data, len);
-
-out:
- return 0;
-}
-
-/* Add padding and return the message digest. */
-static int rmd320_final(struct shash_desc *desc, u8 *out)
-{
- struct rmd320_ctx *rctx = shash_desc_ctx(desc);
- u32 i, index, padlen;
- __le64 bits;
- __le32 *dst = (__le32 *)out;
- static const u8 padding[64] = { 0x80, };
-
- bits = cpu_to_le64(rctx->byte_count << 3);
-
- /* Pad out to 56 mod 64 */
- index = rctx->byte_count & 0x3f;
- padlen = (index < 56) ? (56 - index) : ((64+56) - index);
- rmd320_update(desc, padding, padlen);
-
- /* Append length */
- rmd320_update(desc, (const u8 *)&bits, sizeof(bits));
-
- /* Store state in digest */
- for (i = 0; i < 10; i++)
- dst[i] = cpu_to_le32p(&rctx->state[i]);
-
- /* Wipe context */
- memset(rctx, 0, sizeof(*rctx));
-
- return 0;
-}
-
-static struct shash_alg alg = {
- .digestsize = RMD320_DIGEST_SIZE,
- .init = rmd320_init,
- .update = rmd320_update,
- .final = rmd320_final,
- .descsize = sizeof(struct rmd320_ctx),
- .base = {
- .cra_name = "rmd320",
- .cra_driver_name = "rmd320-generic",
- .cra_blocksize = RMD320_BLOCK_SIZE,
- .cra_module = THIS_MODULE,
- }
-};
-
-static int __init rmd320_mod_init(void)
-{
- return crypto_register_shash(&alg);
-}
-
-static void __exit rmd320_mod_fini(void)
-{
- crypto_unregister_shash(&alg);
-}
-
-subsys_initcall(rmd320_mod_init);
-module_exit(rmd320_mod_fini);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>");
-MODULE_DESCRIPTION("RIPEMD-320 Message Digest");
-MODULE_ALIAS_CRYPTO("rmd320");
diff --git a/crypto/rng.c b/crypto/rng.c
index 1e21231f71c9..fea082b25fe4 100644
--- a/crypto/rng.c
+++ b/crypto/rng.c
@@ -34,7 +34,6 @@ int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen)
u8 *buf = NULL;
int err;
- crypto_stats_get(alg);
if (!seed && slen) {
buf = kmalloc(slen, GFP_KERNEL);
if (!buf)
@@ -46,10 +45,11 @@ int crypto_rng_reset(struct crypto_rng *tfm, const u8 *seed, unsigned int slen)
seed = buf;
}
+ crypto_stats_get(alg);
err = crypto_rng_alg(tfm)->seed(tfm, seed, slen);
crypto_stats_rng_seed(alg, err);
out:
- kzfree(buf);
+ kfree_sensitive(buf);
return err;
}
EXPORT_SYMBOL_GPL(crypto_rng_reset);
diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
index 176b63afec8d..3285e3af43e1 100644
--- a/crypto/rsa-pkcs1pad.c
+++ b/crypto/rsa-pkcs1pad.c
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/random.h>
+#include <linux/scatterlist.h>
/*
* Hash algorithm OIDs plus ASN.1 DER wrappings [RFC4880 sec 5.2.2].
@@ -199,7 +200,7 @@ static int pkcs1pad_encrypt_sign_complete(struct akcipher_request *req, int err)
sg_copy_from_buffer(req->dst,
sg_nents_for_len(req->dst, ctx->key_size),
out_buf, ctx->key_size);
- kzfree(out_buf);
+ kfree_sensitive(out_buf);
out:
req->dst_len = ctx->key_size;
@@ -322,7 +323,7 @@ static int pkcs1pad_decrypt_complete(struct akcipher_request *req, int err)
out_buf + pos, req->dst_len);
done:
- kzfree(req_ctx->out_buf);
+ kfree_sensitive(req_ctx->out_buf);
return err;
}
@@ -384,15 +385,15 @@ static int pkcs1pad_sign(struct akcipher_request *req)
struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
const struct rsa_asn1_template *digest_info = ictx->digest_info;
int err;
- unsigned int ps_end, digest_size = 0;
+ unsigned int ps_end, digest_info_size = 0;
if (!ctx->key_size)
return -EINVAL;
if (digest_info)
- digest_size = digest_info->size;
+ digest_info_size = digest_info->size;
- if (req->src_len + digest_size > ctx->key_size - 11)
+ if (req->src_len + digest_info_size > ctx->key_size - 11)
return -EOVERFLOW;
if (req->dst_len < ctx->key_size) {
@@ -405,7 +406,7 @@ static int pkcs1pad_sign(struct akcipher_request *req)
if (!req_ctx->in_buf)
return -ENOMEM;
- ps_end = ctx->key_size - digest_size - req->src_len - 2;
+ ps_end = ctx->key_size - digest_info_size - req->src_len - 2;
req_ctx->in_buf[0] = 0x01;
memset(req_ctx->in_buf + 1, 0xff, ps_end - 1);
req_ctx->in_buf[ps_end] = 0x00;
@@ -440,6 +441,8 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err)
struct akcipher_instance *inst = akcipher_alg_instance(tfm);
struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst);
const struct rsa_asn1_template *digest_info = ictx->digest_info;
+ const unsigned int sig_size = req->src_len;
+ const unsigned int digest_size = req->dst_len;
unsigned int dst_len;
unsigned int pos;
u8 *out_buf;
@@ -475,6 +478,8 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err)
pos++;
if (digest_info) {
+ if (digest_info->size > dst_len - pos)
+ goto done;
if (crypto_memneq(out_buf + pos, digest_info->data,
digest_info->size))
goto done;
@@ -484,23 +489,22 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err)
err = 0;
- if (req->dst_len != dst_len - pos) {
+ if (digest_size != dst_len - pos) {
err = -EKEYREJECTED;
req->dst_len = dst_len - pos;
goto done;
}
/* Extract appended digest. */
sg_pcopy_to_buffer(req->src,
- sg_nents_for_len(req->src,
- req->src_len + req->dst_len),
+ sg_nents_for_len(req->src, sig_size + digest_size),
req_ctx->out_buf + ctx->key_size,
- req->dst_len, ctx->key_size);
+ digest_size, sig_size);
/* Do the actual verification step. */
if (memcmp(req_ctx->out_buf + ctx->key_size, out_buf + pos,
- req->dst_len) != 0)
+ digest_size) != 0)
err = -EKEYREJECTED;
done:
- kzfree(req_ctx->out_buf);
+ kfree_sensitive(req_ctx->out_buf);
return err;
}
@@ -533,14 +537,15 @@ static int pkcs1pad_verify(struct akcipher_request *req)
struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm);
struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req);
+ const unsigned int sig_size = req->src_len;
+ const unsigned int digest_size = req->dst_len;
int err;
- if (WARN_ON(req->dst) ||
- WARN_ON(!req->dst_len) ||
- !ctx->key_size || req->src_len < ctx->key_size)
+ if (WARN_ON(req->dst) || WARN_ON(!digest_size) ||
+ !ctx->key_size || sig_size != ctx->key_size)
return -EINVAL;
- req_ctx->out_buf = kmalloc(ctx->key_size + req->dst_len, GFP_KERNEL);
+ req_ctx->out_buf = kmalloc(ctx->key_size + digest_size, GFP_KERNEL);
if (!req_ctx->out_buf)
return -ENOMEM;
@@ -553,8 +558,7 @@ static int pkcs1pad_verify(struct akcipher_request *req)
/* Reuse input buffer, output to a new buffer */
akcipher_request_set_crypt(&req_ctx->child_req, req->src,
- req_ctx->out_sg, req->src_len,
- ctx->key_size);
+ req_ctx->out_sg, sig_size, ctx->key_size);
err = crypto_akcipher_encrypt(&req_ctx->child_req);
if (err != -EINPROGRESS && err != -EBUSY)
@@ -596,83 +600,67 @@ static void pkcs1pad_free(struct akcipher_instance *inst)
static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
{
- const struct rsa_asn1_template *digest_info;
- struct crypto_attr_type *algt;
u32 mask;
struct akcipher_instance *inst;
struct pkcs1pad_inst_ctx *ctx;
- struct crypto_akcipher_spawn *spawn;
struct akcipher_alg *rsa_alg;
- const char *rsa_alg_name;
const char *hash_name;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_AKCIPHER) & algt->mask)
- return -EINVAL;
-
- mask = crypto_requires_sync(algt->type, algt->mask);
-
- rsa_alg_name = crypto_attr_alg_name(tb[1]);
- if (IS_ERR(rsa_alg_name))
- return PTR_ERR(rsa_alg_name);
-
- hash_name = crypto_attr_alg_name(tb[2]);
- if (IS_ERR(hash_name))
- hash_name = NULL;
-
- if (hash_name) {
- digest_info = rsa_lookup_asn1(hash_name);
- if (!digest_info)
- return -EINVAL;
- } else
- digest_info = NULL;
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_AKCIPHER, &mask);
+ if (err)
+ return err;
inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL);
if (!inst)
return -ENOMEM;
ctx = akcipher_instance_ctx(inst);
- spawn = &ctx->spawn;
- ctx->digest_info = digest_info;
- err = crypto_grab_akcipher(spawn, akcipher_crypto_instance(inst),
- rsa_alg_name, 0, mask);
+ err = crypto_grab_akcipher(&ctx->spawn, akcipher_crypto_instance(inst),
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
- goto out_free_inst;
+ goto err_free_inst;
- rsa_alg = crypto_spawn_akcipher_alg(spawn);
+ rsa_alg = crypto_spawn_akcipher_alg(&ctx->spawn);
- err = -ENAMETOOLONG;
+ if (strcmp(rsa_alg->base.cra_name, "rsa") != 0) {
+ err = -EINVAL;
+ goto err_free_inst;
+ }
- if (!hash_name) {
+ err = -ENAMETOOLONG;
+ hash_name = crypto_attr_alg_name(tb[2]);
+ if (IS_ERR(hash_name)) {
if (snprintf(inst->alg.base.cra_name,
CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)",
rsa_alg->base.cra_name) >= CRYPTO_MAX_ALG_NAME)
- goto out_drop_alg;
+ goto err_free_inst;
if (snprintf(inst->alg.base.cra_driver_name,
CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)",
rsa_alg->base.cra_driver_name) >=
CRYPTO_MAX_ALG_NAME)
- goto out_drop_alg;
+ goto err_free_inst;
} else {
+ ctx->digest_info = rsa_lookup_asn1(hash_name);
+ if (!ctx->digest_info) {
+ err = -EINVAL;
+ goto err_free_inst;
+ }
+
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
"pkcs1pad(%s,%s)", rsa_alg->base.cra_name,
hash_name) >= CRYPTO_MAX_ALG_NAME)
- goto out_drop_alg;
+ goto err_free_inst;
if (snprintf(inst->alg.base.cra_driver_name,
CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s,%s)",
rsa_alg->base.cra_driver_name,
hash_name) >= CRYPTO_MAX_ALG_NAME)
- goto out_drop_alg;
+ goto err_free_inst;
}
- inst->alg.base.cra_flags = rsa_alg->base.cra_flags & CRYPTO_ALG_ASYNC;
inst->alg.base.cra_priority = rsa_alg->base.cra_priority;
inst->alg.base.cra_ctxsize = sizeof(struct pkcs1pad_ctx);
@@ -691,15 +679,10 @@ static int pkcs1pad_create(struct crypto_template *tmpl, struct rtattr **tb)
inst->free = pkcs1pad_free;
err = akcipher_register_instance(tmpl, inst);
- if (err)
- goto out_drop_alg;
-
- return 0;
-
-out_drop_alg:
- crypto_drop_akcipher(spawn);
-out_free_inst:
- kfree(inst);
+ if (err) {
+err_free_inst:
+ pkcs1pad_free(inst);
+ }
return err;
}
diff --git a/crypto/rsa.c b/crypto/rsa.c
index 4cdbec95d077..c50f2d2a4d06 100644
--- a/crypto/rsa.c
+++ b/crypto/rsa.c
@@ -5,6 +5,7 @@
* Authors: Tadeusz Struk <tadeusz.struk@intel.com>
*/
+#include <linux/fips.h>
#include <linux/module.h>
#include <linux/mpi.h>
#include <crypto/internal/rsa.h>
@@ -16,6 +17,11 @@ struct rsa_mpi_key {
MPI n;
MPI e;
MPI d;
+ MPI p;
+ MPI q;
+ MPI dp;
+ MPI dq;
+ MPI qinv;
};
/*
@@ -34,16 +40,49 @@ static int _rsa_enc(const struct rsa_mpi_key *key, MPI c, MPI m)
/*
* RSADP function [RFC3447 sec 5.1.2]
- * m = c^d mod n;
+ * m_1 = c^dP mod p;
+ * m_2 = c^dQ mod q;
+ * h = (m_1 - m_2) * qInv mod p;
+ * m = m_2 + q * h;
*/
-static int _rsa_dec(const struct rsa_mpi_key *key, MPI m, MPI c)
+static int _rsa_dec_crt(const struct rsa_mpi_key *key, MPI m_or_m1_or_h, MPI c)
{
+ MPI m2, m12_or_qh;
+ int ret = -ENOMEM;
+
/* (1) Validate 0 <= c < n */
if (mpi_cmp_ui(c, 0) < 0 || mpi_cmp(c, key->n) >= 0)
return -EINVAL;
- /* (2) m = c^d mod n */
- return mpi_powm(m, c, key->d, key->n);
+ m2 = mpi_alloc(0);
+ m12_or_qh = mpi_alloc(0);
+ if (!m2 || !m12_or_qh)
+ goto err_free_mpi;
+
+ /* (2i) m_1 = c^dP mod p */
+ ret = mpi_powm(m_or_m1_or_h, c, key->dp, key->p);
+ if (ret)
+ goto err_free_mpi;
+
+ /* (2i) m_2 = c^dQ mod q */
+ ret = mpi_powm(m2, c, key->dq, key->q);
+ if (ret)
+ goto err_free_mpi;
+
+ /* (2iii) h = (m_1 - m_2) * qInv mod p */
+ mpi_sub(m12_or_qh, m_or_m1_or_h, m2);
+ mpi_mulm(m_or_m1_or_h, m12_or_qh, key->qinv, key->p);
+
+ /* (2iv) m = m_2 + q * h */
+ mpi_mul(m12_or_qh, key->q, m_or_m1_or_h);
+ mpi_addm(m_or_m1_or_h, m2, m12_or_qh, key->n);
+
+ ret = 0;
+
+err_free_mpi:
+ mpi_free(m12_or_qh);
+ mpi_free(m2);
+ return ret;
}
static inline struct rsa_mpi_key *rsa_get_key(struct crypto_akcipher *tfm)
@@ -111,7 +150,7 @@ static int rsa_dec(struct akcipher_request *req)
if (!c)
goto err_free_m;
- ret = _rsa_dec(pkey, m, c);
+ ret = _rsa_dec_crt(pkey, m, c);
if (ret)
goto err_free_c;
@@ -133,9 +172,19 @@ static void rsa_free_mpi_key(struct rsa_mpi_key *key)
mpi_free(key->d);
mpi_free(key->e);
mpi_free(key->n);
+ mpi_free(key->p);
+ mpi_free(key->q);
+ mpi_free(key->dp);
+ mpi_free(key->dq);
+ mpi_free(key->qinv);
key->d = NULL;
key->e = NULL;
key->n = NULL;
+ key->p = NULL;
+ key->q = NULL;
+ key->dp = NULL;
+ key->dq = NULL;
+ key->qinv = NULL;
}
static int rsa_check_key_length(unsigned int len)
@@ -144,6 +193,9 @@ static int rsa_check_key_length(unsigned int len)
case 512:
case 1024:
case 1536:
+ if (fips_enabled)
+ return -EINVAL;
+ fallthrough;
case 2048:
case 3072:
case 4096:
@@ -213,6 +265,26 @@ static int rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
if (!mpi_key->n)
goto err;
+ mpi_key->p = mpi_read_raw_data(raw_key.p, raw_key.p_sz);
+ if (!mpi_key->p)
+ goto err;
+
+ mpi_key->q = mpi_read_raw_data(raw_key.q, raw_key.q_sz);
+ if (!mpi_key->q)
+ goto err;
+
+ mpi_key->dp = mpi_read_raw_data(raw_key.dp, raw_key.dp_sz);
+ if (!mpi_key->dp)
+ goto err;
+
+ mpi_key->dq = mpi_read_raw_data(raw_key.dq, raw_key.dq_sz);
+ if (!mpi_key->dq)
+ goto err;
+
+ mpi_key->qinv = mpi_read_raw_data(raw_key.qinv, raw_key.qinv_sz);
+ if (!mpi_key->qinv)
+ goto err;
+
if (rsa_check_key_length(mpi_get_size(mpi_key->n) << 3)) {
rsa_free_mpi_key(mpi_key);
return -EINVAL;
@@ -255,7 +327,7 @@ static struct akcipher_alg rsa = {
},
};
-static int rsa_init(void)
+static int __init rsa_init(void)
{
int err;
@@ -272,7 +344,7 @@ static int rsa_init(void)
return 0;
}
-static void rsa_exit(void)
+static void __exit rsa_exit(void)
{
crypto_unregister_template(&rsa_pkcs1pad_tmpl);
crypto_unregister_akcipher(&rsa);
diff --git a/crypto/salsa20_generic.c b/crypto/salsa20_generic.c
deleted file mode 100644
index c81a44404086..000000000000
--- a/crypto/salsa20_generic.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Salsa20: Salsa20 stream cipher algorithm
- *
- * Copyright (c) 2007 Tan Swee Heng <thesweeheng@gmail.com>
- *
- * Derived from:
- * - salsa20.c: Public domain C code by Daniel J. Bernstein <djb@cr.yp.to>
- *
- * Salsa20 is a stream cipher candidate in eSTREAM, the ECRYPT Stream
- * Cipher Project. It is designed by Daniel J. Bernstein <djb@cr.yp.to>.
- * More information about eSTREAM and Salsa20 can be found here:
- * http://www.ecrypt.eu.org/stream/
- * http://cr.yp.to/snuffle.html
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- */
-
-#include <asm/unaligned.h>
-#include <crypto/internal/skcipher.h>
-#include <linux/module.h>
-
-#define SALSA20_IV_SIZE 8
-#define SALSA20_MIN_KEY_SIZE 16
-#define SALSA20_MAX_KEY_SIZE 32
-#define SALSA20_BLOCK_SIZE 64
-
-struct salsa20_ctx {
- u32 initial_state[16];
-};
-
-static void salsa20_block(u32 *state, __le32 *stream)
-{
- u32 x[16];
- int i;
-
- memcpy(x, state, sizeof(x));
-
- for (i = 0; i < 20; i += 2) {
- x[ 4] ^= rol32((x[ 0] + x[12]), 7);
- x[ 8] ^= rol32((x[ 4] + x[ 0]), 9);
- x[12] ^= rol32((x[ 8] + x[ 4]), 13);
- x[ 0] ^= rol32((x[12] + x[ 8]), 18);
- x[ 9] ^= rol32((x[ 5] + x[ 1]), 7);
- x[13] ^= rol32((x[ 9] + x[ 5]), 9);
- x[ 1] ^= rol32((x[13] + x[ 9]), 13);
- x[ 5] ^= rol32((x[ 1] + x[13]), 18);
- x[14] ^= rol32((x[10] + x[ 6]), 7);
- x[ 2] ^= rol32((x[14] + x[10]), 9);
- x[ 6] ^= rol32((x[ 2] + x[14]), 13);
- x[10] ^= rol32((x[ 6] + x[ 2]), 18);
- x[ 3] ^= rol32((x[15] + x[11]), 7);
- x[ 7] ^= rol32((x[ 3] + x[15]), 9);
- x[11] ^= rol32((x[ 7] + x[ 3]), 13);
- x[15] ^= rol32((x[11] + x[ 7]), 18);
- x[ 1] ^= rol32((x[ 0] + x[ 3]), 7);
- x[ 2] ^= rol32((x[ 1] + x[ 0]), 9);
- x[ 3] ^= rol32((x[ 2] + x[ 1]), 13);
- x[ 0] ^= rol32((x[ 3] + x[ 2]), 18);
- x[ 6] ^= rol32((x[ 5] + x[ 4]), 7);
- x[ 7] ^= rol32((x[ 6] + x[ 5]), 9);
- x[ 4] ^= rol32((x[ 7] + x[ 6]), 13);
- x[ 5] ^= rol32((x[ 4] + x[ 7]), 18);
- x[11] ^= rol32((x[10] + x[ 9]), 7);
- x[ 8] ^= rol32((x[11] + x[10]), 9);
- x[ 9] ^= rol32((x[ 8] + x[11]), 13);
- x[10] ^= rol32((x[ 9] + x[ 8]), 18);
- x[12] ^= rol32((x[15] + x[14]), 7);
- x[13] ^= rol32((x[12] + x[15]), 9);
- x[14] ^= rol32((x[13] + x[12]), 13);
- x[15] ^= rol32((x[14] + x[13]), 18);
- }
-
- for (i = 0; i < 16; i++)
- stream[i] = cpu_to_le32(x[i] + state[i]);
-
- if (++state[8] == 0)
- state[9]++;
-}
-
-static void salsa20_docrypt(u32 *state, u8 *dst, const u8 *src,
- unsigned int bytes)
-{
- __le32 stream[SALSA20_BLOCK_SIZE / sizeof(__le32)];
-
- while (bytes >= SALSA20_BLOCK_SIZE) {
- salsa20_block(state, stream);
- crypto_xor_cpy(dst, src, (const u8 *)stream,
- SALSA20_BLOCK_SIZE);
- bytes -= SALSA20_BLOCK_SIZE;
- dst += SALSA20_BLOCK_SIZE;
- src += SALSA20_BLOCK_SIZE;
- }
- if (bytes) {
- salsa20_block(state, stream);
- crypto_xor_cpy(dst, src, (const u8 *)stream, bytes);
- }
-}
-
-static void salsa20_init(u32 *state, const struct salsa20_ctx *ctx,
- const u8 *iv)
-{
- memcpy(state, ctx->initial_state, sizeof(ctx->initial_state));
- state[6] = get_unaligned_le32(iv + 0);
- state[7] = get_unaligned_le32(iv + 4);
-}
-
-static int salsa20_setkey(struct crypto_skcipher *tfm, const u8 *key,
- unsigned int keysize)
-{
- static const char sigma[16] = "expand 32-byte k";
- static const char tau[16] = "expand 16-byte k";
- struct salsa20_ctx *ctx = crypto_skcipher_ctx(tfm);
- const char *constants;
-
- if (keysize != SALSA20_MIN_KEY_SIZE &&
- keysize != SALSA20_MAX_KEY_SIZE)
- return -EINVAL;
-
- ctx->initial_state[1] = get_unaligned_le32(key + 0);
- ctx->initial_state[2] = get_unaligned_le32(key + 4);
- ctx->initial_state[3] = get_unaligned_le32(key + 8);
- ctx->initial_state[4] = get_unaligned_le32(key + 12);
- if (keysize == 32) { /* recommended */
- key += 16;
- constants = sigma;
- } else { /* keysize == 16 */
- constants = tau;
- }
- ctx->initial_state[11] = get_unaligned_le32(key + 0);
- ctx->initial_state[12] = get_unaligned_le32(key + 4);
- ctx->initial_state[13] = get_unaligned_le32(key + 8);
- ctx->initial_state[14] = get_unaligned_le32(key + 12);
- ctx->initial_state[0] = get_unaligned_le32(constants + 0);
- ctx->initial_state[5] = get_unaligned_le32(constants + 4);
- ctx->initial_state[10] = get_unaligned_le32(constants + 8);
- ctx->initial_state[15] = get_unaligned_le32(constants + 12);
-
- /* space for the nonce; it will be overridden for each request */
- ctx->initial_state[6] = 0;
- ctx->initial_state[7] = 0;
-
- /* initial block number */
- ctx->initial_state[8] = 0;
- ctx->initial_state[9] = 0;
-
- return 0;
-}
-
-static int salsa20_crypt(struct skcipher_request *req)
-{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- const struct salsa20_ctx *ctx = crypto_skcipher_ctx(tfm);
- struct skcipher_walk walk;
- u32 state[16];
- int err;
-
- err = skcipher_walk_virt(&walk, req, false);
-
- salsa20_init(state, ctx, req->iv);
-
- while (walk.nbytes > 0) {
- unsigned int nbytes = walk.nbytes;
-
- if (nbytes < walk.total)
- nbytes = round_down(nbytes, walk.stride);
-
- salsa20_docrypt(state, walk.dst.virt.addr, walk.src.virt.addr,
- nbytes);
- err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
- }
-
- return err;
-}
-
-static struct skcipher_alg alg = {
- .base.cra_name = "salsa20",
- .base.cra_driver_name = "salsa20-generic",
- .base.cra_priority = 100,
- .base.cra_blocksize = 1,
- .base.cra_ctxsize = sizeof(struct salsa20_ctx),
- .base.cra_module = THIS_MODULE,
-
- .min_keysize = SALSA20_MIN_KEY_SIZE,
- .max_keysize = SALSA20_MAX_KEY_SIZE,
- .ivsize = SALSA20_IV_SIZE,
- .chunksize = SALSA20_BLOCK_SIZE,
- .setkey = salsa20_setkey,
- .encrypt = salsa20_crypt,
- .decrypt = salsa20_crypt,
-};
-
-static int __init salsa20_generic_mod_init(void)
-{
- return crypto_register_skcipher(&alg);
-}
-
-static void __exit salsa20_generic_mod_fini(void)
-{
- crypto_unregister_skcipher(&alg);
-}
-
-subsys_initcall(salsa20_generic_mod_init);
-module_exit(salsa20_generic_mod_fini);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION ("Salsa20 stream cipher algorithm");
-MODULE_ALIAS_CRYPTO("salsa20");
-MODULE_ALIAS_CRYPTO("salsa20-generic");
diff --git a/crypto/seed.c b/crypto/seed.c
index 5e3bef3a617d..27720140820e 100644
--- a/crypto/seed.c
+++ b/crypto/seed.c
@@ -322,7 +322,7 @@ static const u32 KC[SEED_NUM_KCONSTANTS] = {
SS2[byte(t1, 2)] ^ SS3[byte(t1, 3)]; \
t0 += t1; \
X1 ^= t0; \
- X2 ^= t1;
+ X2 ^= t1
static int seed_set_key(struct crypto_tfm *tfm, const u8 *in_key,
unsigned int key_len)
diff --git a/crypto/seqiv.c b/crypto/seqiv.c
index f124b9b54e15..0899d527c284 100644
--- a/crypto/seqiv.c
+++ b/crypto/seqiv.c
@@ -33,7 +33,7 @@ static void seqiv_aead_encrypt_complete2(struct aead_request *req, int err)
memcpy(req->iv, subreq->iv, crypto_aead_ivsize(geniv));
out:
- kzfree(subreq->iv);
+ kfree_sensitive(subreq->iv);
}
static void seqiv_aead_encrypt_complete(struct crypto_async_request *base,
@@ -138,7 +138,7 @@ static int seqiv_aead_create(struct crypto_template *tmpl, struct rtattr **tb)
struct aead_instance *inst;
int err;
- inst = aead_geniv_alloc(tmpl, tb, 0, 0);
+ inst = aead_geniv_alloc(tmpl, tb);
if (IS_ERR(inst))
return PTR_ERR(inst);
@@ -164,23 +164,9 @@ free_inst:
return err;
}
-static int seqiv_create(struct crypto_template *tmpl, struct rtattr **tb)
-{
- struct crypto_attr_type *algt;
-
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
- return -EINVAL;
-
- return seqiv_aead_create(tmpl, tb);
-}
-
static struct crypto_template seqiv_tmpl = {
.name = "seqiv",
- .create = seqiv_create,
+ .create = seqiv_aead_create,
.module = THIS_MODULE,
};
diff --git a/crypto/serpent_generic.c b/crypto/serpent_generic.c
index 492c1d0bfe06..45f98b750053 100644
--- a/crypto/serpent_generic.c
+++ b/crypto/serpent_generic.c
@@ -5,17 +5,12 @@
* Serpent Cipher Algorithm.
*
* Copyright (C) 2002 Dag Arne Osvik <osvik@ii.uib.no>
- * 2003 Herbert Valerio Riedel <hvr@gnu.org>
- *
- * Added tnepres support:
- * Ruben Jesus Garcia Hernandez <ruben@ugr.es>, 18.10.2004
- * Based on code by hvr
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
-#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <linux/crypto.h>
#include <linux/types.h>
#include <crypto/serpent.h>
@@ -277,6 +272,7 @@ int __serpent_setkey(struct serpent_ctx *ctx, const u8 *key,
u32 *k = ctx->expkey;
u8 *k8 = (u8 *)k;
u32 r0, r1, r2, r3, r4;
+ __le32 *lk;
int i;
/* Copy key, add padding */
@@ -288,22 +284,32 @@ int __serpent_setkey(struct serpent_ctx *ctx, const u8 *key,
while (i < SERPENT_MAX_KEY_SIZE)
k8[i++] = 0;
+ lk = (__le32 *)k;
+ k[0] = le32_to_cpu(lk[0]);
+ k[1] = le32_to_cpu(lk[1]);
+ k[2] = le32_to_cpu(lk[2]);
+ k[3] = le32_to_cpu(lk[3]);
+ k[4] = le32_to_cpu(lk[4]);
+ k[5] = le32_to_cpu(lk[5]);
+ k[6] = le32_to_cpu(lk[6]);
+ k[7] = le32_to_cpu(lk[7]);
+
/* Expand key using polynomial */
- r0 = le32_to_cpu(k[3]);
- r1 = le32_to_cpu(k[4]);
- r2 = le32_to_cpu(k[5]);
- r3 = le32_to_cpu(k[6]);
- r4 = le32_to_cpu(k[7]);
-
- keyiter(le32_to_cpu(k[0]), r0, r4, r2, 0, 0);
- keyiter(le32_to_cpu(k[1]), r1, r0, r3, 1, 1);
- keyiter(le32_to_cpu(k[2]), r2, r1, r4, 2, 2);
- keyiter(le32_to_cpu(k[3]), r3, r2, r0, 3, 3);
- keyiter(le32_to_cpu(k[4]), r4, r3, r1, 4, 4);
- keyiter(le32_to_cpu(k[5]), r0, r4, r2, 5, 5);
- keyiter(le32_to_cpu(k[6]), r1, r0, r3, 6, 6);
- keyiter(le32_to_cpu(k[7]), r2, r1, r4, 7, 7);
+ r0 = k[3];
+ r1 = k[4];
+ r2 = k[5];
+ r3 = k[6];
+ r4 = k[7];
+
+ keyiter(k[0], r0, r4, r2, 0, 0);
+ keyiter(k[1], r1, r0, r3, 1, 1);
+ keyiter(k[2], r2, r1, r4, 2, 2);
+ keyiter(k[3], r3, r2, r0, 3, 3);
+ keyiter(k[4], r4, r3, r1, 4, 4);
+ keyiter(k[5], r0, r4, r2, 5, 5);
+ keyiter(k[6], r1, r0, r3, 6, 6);
+ keyiter(k[7], r2, r1, r4, 7, 7);
keyiter(k[0], r3, r2, r0, 8, 8);
keyiter(k[1], r4, r3, r1, 9, 9);
@@ -453,19 +459,12 @@ void __serpent_encrypt(const void *c, u8 *dst, const u8 *src)
{
const struct serpent_ctx *ctx = c;
const u32 *k = ctx->expkey;
- const __le32 *s = (const __le32 *)src;
- __le32 *d = (__le32 *)dst;
u32 r0, r1, r2, r3, r4;
-/*
- * Note: The conversions between u8* and u32* might cause trouble
- * on architectures with stricter alignment rules than x86
- */
-
- r0 = le32_to_cpu(s[0]);
- r1 = le32_to_cpu(s[1]);
- r2 = le32_to_cpu(s[2]);
- r3 = le32_to_cpu(s[3]);
+ r0 = get_unaligned_le32(src);
+ r1 = get_unaligned_le32(src + 4);
+ r2 = get_unaligned_le32(src + 8);
+ r3 = get_unaligned_le32(src + 12);
K(r0, r1, r2, r3, 0);
S0(r0, r1, r2, r3, r4); LK(r2, r1, r3, r0, r4, 1);
@@ -501,10 +500,10 @@ void __serpent_encrypt(const void *c, u8 *dst, const u8 *src)
S6(r0, r1, r3, r2, r4); LK(r3, r4, r1, r2, r0, 31);
S7(r3, r4, r1, r2, r0); K(r0, r1, r2, r3, 32);
- d[0] = cpu_to_le32(r0);
- d[1] = cpu_to_le32(r1);
- d[2] = cpu_to_le32(r2);
- d[3] = cpu_to_le32(r3);
+ put_unaligned_le32(r0, dst);
+ put_unaligned_le32(r1, dst + 4);
+ put_unaligned_le32(r2, dst + 8);
+ put_unaligned_le32(r3, dst + 12);
}
EXPORT_SYMBOL_GPL(__serpent_encrypt);
@@ -519,14 +518,12 @@ void __serpent_decrypt(const void *c, u8 *dst, const u8 *src)
{
const struct serpent_ctx *ctx = c;
const u32 *k = ctx->expkey;
- const __le32 *s = (const __le32 *)src;
- __le32 *d = (__le32 *)dst;
u32 r0, r1, r2, r3, r4;
- r0 = le32_to_cpu(s[0]);
- r1 = le32_to_cpu(s[1]);
- r2 = le32_to_cpu(s[2]);
- r3 = le32_to_cpu(s[3]);
+ r0 = get_unaligned_le32(src);
+ r1 = get_unaligned_le32(src + 4);
+ r2 = get_unaligned_le32(src + 8);
+ r3 = get_unaligned_le32(src + 12);
K(r0, r1, r2, r3, 32);
SI7(r0, r1, r2, r3, r4); KL(r1, r3, r0, r4, r2, 31);
@@ -562,10 +559,10 @@ void __serpent_decrypt(const void *c, u8 *dst, const u8 *src)
SI1(r3, r1, r2, r0, r4); KL(r4, r1, r2, r0, r3, 1);
SI0(r4, r1, r2, r0, r3); K(r2, r3, r1, r4, 0);
- d[0] = cpu_to_le32(r2);
- d[1] = cpu_to_le32(r3);
- d[2] = cpu_to_le32(r1);
- d[3] = cpu_to_le32(r4);
+ put_unaligned_le32(r2, dst);
+ put_unaligned_le32(r3, dst + 4);
+ put_unaligned_le32(r1, dst + 8);
+ put_unaligned_le32(r4, dst + 12);
}
EXPORT_SYMBOL_GPL(__serpent_decrypt);
@@ -576,66 +573,13 @@ static void serpent_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
__serpent_decrypt(ctx, dst, src);
}
-static int tnepres_setkey(struct crypto_tfm *tfm, const u8 *key,
- unsigned int keylen)
-{
- u8 rev_key[SERPENT_MAX_KEY_SIZE];
- int i;
-
- for (i = 0; i < keylen; ++i)
- rev_key[keylen - i - 1] = key[i];
-
- return serpent_setkey(tfm, rev_key, keylen);
-}
-
-static void tnepres_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
-{
- const u32 * const s = (const u32 * const)src;
- u32 * const d = (u32 * const)dst;
-
- u32 rs[4], rd[4];
-
- rs[0] = swab32(s[3]);
- rs[1] = swab32(s[2]);
- rs[2] = swab32(s[1]);
- rs[3] = swab32(s[0]);
-
- serpent_encrypt(tfm, (u8 *)rd, (u8 *)rs);
-
- d[0] = swab32(rd[3]);
- d[1] = swab32(rd[2]);
- d[2] = swab32(rd[1]);
- d[3] = swab32(rd[0]);
-}
-
-static void tnepres_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
-{
- const u32 * const s = (const u32 * const)src;
- u32 * const d = (u32 * const)dst;
-
- u32 rs[4], rd[4];
-
- rs[0] = swab32(s[3]);
- rs[1] = swab32(s[2]);
- rs[2] = swab32(s[1]);
- rs[3] = swab32(s[0]);
-
- serpent_decrypt(tfm, (u8 *)rd, (u8 *)rs);
-
- d[0] = swab32(rd[3]);
- d[1] = swab32(rd[2]);
- d[2] = swab32(rd[1]);
- d[3] = swab32(rd[0]);
-}
-
-static struct crypto_alg srp_algs[2] = { {
+static struct crypto_alg srp_alg = {
.cra_name = "serpent",
.cra_driver_name = "serpent-generic",
.cra_priority = 100,
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = SERPENT_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct serpent_ctx),
- .cra_alignmask = 3,
.cra_module = THIS_MODULE,
.cra_u = { .cipher = {
.cia_min_keysize = SERPENT_MIN_KEY_SIZE,
@@ -643,38 +587,23 @@ static struct crypto_alg srp_algs[2] = { {
.cia_setkey = serpent_setkey,
.cia_encrypt = serpent_encrypt,
.cia_decrypt = serpent_decrypt } }
-}, {
- .cra_name = "tnepres",
- .cra_driver_name = "tnepres-generic",
- .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
- .cra_blocksize = SERPENT_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct serpent_ctx),
- .cra_alignmask = 3,
- .cra_module = THIS_MODULE,
- .cra_u = { .cipher = {
- .cia_min_keysize = SERPENT_MIN_KEY_SIZE,
- .cia_max_keysize = SERPENT_MAX_KEY_SIZE,
- .cia_setkey = tnepres_setkey,
- .cia_encrypt = tnepres_encrypt,
- .cia_decrypt = tnepres_decrypt } }
-} };
+};
static int __init serpent_mod_init(void)
{
- return crypto_register_algs(srp_algs, ARRAY_SIZE(srp_algs));
+ return crypto_register_alg(&srp_alg);
}
static void __exit serpent_mod_fini(void)
{
- crypto_unregister_algs(srp_algs, ARRAY_SIZE(srp_algs));
+ crypto_unregister_alg(&srp_alg);
}
subsys_initcall(serpent_mod_init);
module_exit(serpent_mod_fini);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Serpent and tnepres (kerneli compatible serpent reversed) Cipher Algorithm");
+MODULE_DESCRIPTION("Serpent Cipher Algorithm");
MODULE_AUTHOR("Dag Arne Osvik <osvik@ii.uib.no>");
-MODULE_ALIAS_CRYPTO("tnepres");
MODULE_ALIAS_CRYPTO("serpent");
MODULE_ALIAS_CRYPTO("serpent-generic");
diff --git a/crypto/sha1_generic.c b/crypto/sha1_generic.c
index 7c57b844c382..325b57fe28dc 100644
--- a/crypto/sha1_generic.c
+++ b/crypto/sha1_generic.c
@@ -15,9 +15,8 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>
-#include <linux/cryptohash.h>
#include <linux/types.h>
-#include <crypto/sha.h>
+#include <crypto/sha1.h>
#include <crypto/sha1_base.h>
#include <asm/byteorder.h>
@@ -31,10 +30,10 @@ EXPORT_SYMBOL_GPL(sha1_zero_message_hash);
static void sha1_generic_block_fn(struct sha1_state *sst, u8 const *src,
int blocks)
{
- u32 temp[SHA_WORKSPACE_WORDS];
+ u32 temp[SHA1_WORKSPACE_WORDS];
while (blocks--) {
- sha_transform(sst->state, src, temp);
+ sha1_transform(sst->state, src, temp);
src += SHA1_BLOCK_SIZE;
}
memzero_explicit(temp, sizeof(temp));
diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c
index f2d7095d4f2d..bf147b01e313 100644
--- a/crypto/sha256_generic.c
+++ b/crypto/sha256_generic.c
@@ -12,7 +12,7 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/types.h>
-#include <crypto/sha.h>
+#include <crypto/sha2.h>
#include <crypto/sha256_base.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
@@ -33,29 +33,21 @@ const u8 sha256_zero_message_hash[SHA256_DIGEST_SIZE] = {
};
EXPORT_SYMBOL_GPL(sha256_zero_message_hash);
-static int crypto_sha256_init(struct shash_desc *desc)
-{
- return sha256_init(shash_desc_ctx(desc));
-}
-
-static int crypto_sha224_init(struct shash_desc *desc)
-{
- return sha224_init(shash_desc_ctx(desc));
-}
-
int crypto_sha256_update(struct shash_desc *desc, const u8 *data,
unsigned int len)
{
- return sha256_update(shash_desc_ctx(desc), data, len);
+ sha256_update(shash_desc_ctx(desc), data, len);
+ return 0;
}
EXPORT_SYMBOL(crypto_sha256_update);
static int crypto_sha256_final(struct shash_desc *desc, u8 *out)
{
if (crypto_shash_digestsize(desc->tfm) == SHA224_DIGEST_SIZE)
- return sha224_final(shash_desc_ctx(desc), out);
+ sha224_final(shash_desc_ctx(desc), out);
else
- return sha256_final(shash_desc_ctx(desc), out);
+ sha256_final(shash_desc_ctx(desc), out);
+ return 0;
}
int crypto_sha256_finup(struct shash_desc *desc, const u8 *data,
@@ -68,7 +60,7 @@ EXPORT_SYMBOL(crypto_sha256_finup);
static struct shash_alg sha256_algs[2] = { {
.digestsize = SHA256_DIGEST_SIZE,
- .init = crypto_sha256_init,
+ .init = sha256_base_init,
.update = crypto_sha256_update,
.final = crypto_sha256_final,
.finup = crypto_sha256_finup,
@@ -82,7 +74,7 @@ static struct shash_alg sha256_algs[2] = { {
}
}, {
.digestsize = SHA224_DIGEST_SIZE,
- .init = crypto_sha224_init,
+ .init = sha224_base_init,
.update = crypto_sha256_update,
.final = crypto_sha256_final,
.finup = crypto_sha256_finup,
diff --git a/crypto/sha3_generic.c b/crypto/sha3_generic.c
index 44e263e25599..3e4069935b53 100644
--- a/crypto/sha3_generic.c
+++ b/crypto/sha3_generic.c
@@ -3,7 +3,7 @@
* Cryptographic API.
*
* SHA-3, as specified in
- * http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
+ * https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
*
* SHA-3 code by Jeff Garzik <jeff@garzik.org>
* Ard Biesheuvel <ard.biesheuvel@linaro.org>
diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c
index e34d09dd9971..be70e76d6d86 100644
--- a/crypto/sha512_generic.c
+++ b/crypto/sha512_generic.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/crypto.h>
#include <linux/types.h>
-#include <crypto/sha.h>
+#include <crypto/sha2.h>
#include <crypto/sha512_base.h>
#include <linux/percpu.h>
#include <asm/byteorder.h>
@@ -143,9 +143,6 @@ sha512_transform(u64 *state, const u8 *input)
state[0] += a; state[1] += b; state[2] += c; state[3] += d;
state[4] += e; state[5] += f; state[6] += g; state[7] += h;
-
- /* erase our data */
- a = b = c = d = e = f = g = h = t1 = t2 = 0;
}
static void sha512_generic_block_fn(struct sha512_state *sst, u8 const *src,
diff --git a/crypto/shash.c b/crypto/shash.c
index c075b26c2a1d..4c88e63b3350 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -20,12 +20,24 @@
static const struct crypto_type crypto_shash_type;
-int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
- unsigned int keylen)
+static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key,
+ unsigned int keylen)
{
return -ENOSYS;
}
-EXPORT_SYMBOL_GPL(shash_no_setkey);
+
+/*
+ * Check whether an shash algorithm has a setkey function.
+ *
+ * For CFI compatibility, this must not be an inline function. This is because
+ * when CFI is enabled, modules won't get the same address for shash_no_setkey
+ * (if it were exported, which inlining would require) as the core kernel will.
+ */
+bool crypto_shash_alg_has_setkey(struct shash_alg *alg)
+{
+ return alg->setkey != shash_no_setkey;
+}
+EXPORT_SYMBOL_GPL(crypto_shash_alg_has_setkey);
static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
unsigned int keylen)
@@ -44,7 +56,7 @@ static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key,
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen);
err = shash->setkey(tfm, alignbuffer, keylen);
- kzfree(buffer);
+ kfree_sensitive(buffer);
return err;
}
@@ -206,6 +218,22 @@ int crypto_shash_digest(struct shash_desc *desc, const u8 *data,
}
EXPORT_SYMBOL_GPL(crypto_shash_digest);
+int crypto_shash_tfm_digest(struct crypto_shash *tfm, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ SHASH_DESC_ON_STACK(desc, tfm);
+ int err;
+
+ desc->tfm = tfm;
+
+ err = crypto_shash_digest(desc, data, len, out);
+
+ shash_desc_zero(desc);
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(crypto_shash_tfm_digest);
+
static int shash_default_export(struct shash_desc *desc, void *out)
{
memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(desc->tfm));
@@ -493,6 +521,12 @@ struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type,
}
EXPORT_SYMBOL_GPL(crypto_alloc_shash);
+int crypto_has_shash(const char *alg_name, u32 type, u32 mask)
+{
+ return crypto_type_has_alg(alg_name, &crypto_shash_type, type, mask);
+}
+EXPORT_SYMBOL_GPL(crypto_has_shash);
+
static int shash_prepare_alg(struct shash_alg *alg)
{
struct crypto_alg *base = &alg->base;
diff --git a/crypto/simd.c b/crypto/simd.c
index 56885af49c24..edaa479a1ec5 100644
--- a/crypto/simd.c
+++ b/crypto/simd.c
@@ -171,7 +171,8 @@ struct simd_skcipher_alg *simd_skcipher_create_compat(const char *algname,
drvname) >= CRYPTO_MAX_ALG_NAME)
goto out_free_salg;
- alg->base.cra_flags = CRYPTO_ALG_ASYNC;
+ alg->base.cra_flags = CRYPTO_ALG_ASYNC |
+ (ialg->base.cra_flags & CRYPTO_ALG_INHERITED_FLAGS);
alg->base.cra_priority = ialg->base.cra_priority;
alg->base.cra_blocksize = ialg->base.cra_blocksize;
alg->base.cra_alignmask = ialg->base.cra_alignmask;
@@ -417,7 +418,8 @@ struct simd_aead_alg *simd_aead_create_compat(const char *algname,
drvname) >= CRYPTO_MAX_ALG_NAME)
goto out_free_salg;
- alg->base.cra_flags = CRYPTO_ALG_ASYNC;
+ alg->base.cra_flags = CRYPTO_ALG_ASYNC |
+ (ialg->base.cra_flags & CRYPTO_ALG_INHERITED_FLAGS);
alg->base.cra_priority = ialg->base.cra_priority;
alg->base.cra_blocksize = ialg->base.cra_blocksize;
alg->base.cra_alignmask = ialg->base.cra_alignmask;
diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index 7221def7b9a7..418211180cee 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -10,6 +10,7 @@
*/
#include <crypto/internal/aead.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/skcipher.h>
#include <crypto/scatterwalk.h>
#include <linux/bug.h>
@@ -430,7 +431,7 @@ static int skcipher_copy_iv(struct skcipher_walk *walk)
static int skcipher_walk_first(struct skcipher_walk *walk)
{
- if (WARN_ON_ONCE(in_irq()))
+ if (WARN_ON_ONCE(in_hardirq()))
return -EDEADLK;
walk->buffer = NULL;
@@ -490,12 +491,6 @@ int skcipher_walk_virt(struct skcipher_walk *walk,
}
EXPORT_SYMBOL_GPL(skcipher_walk_virt);
-void skcipher_walk_atomise(struct skcipher_walk *walk)
-{
- walk->flags &= ~SKCIPHER_WALK_SLEEP;
-}
-EXPORT_SYMBOL_GPL(skcipher_walk_atomise);
-
int skcipher_walk_async(struct skcipher_walk *walk,
struct skcipher_request *req)
{
@@ -592,7 +587,7 @@ static int skcipher_setkey_unaligned(struct crypto_skcipher *tfm,
alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen);
ret = cipher->setkey(tfm, alignbuffer, keylen);
- kzfree(buffer);
+ kfree_sensitive(buffer);
return ret;
}
@@ -934,22 +929,15 @@ static void skcipher_free_instance_simple(struct skcipher_instance *inst)
struct skcipher_instance *skcipher_alloc_instance_simple(
struct crypto_template *tmpl, struct rtattr **tb)
{
- struct crypto_attr_type *algt;
u32 mask;
struct skcipher_instance *inst;
struct crypto_cipher_spawn *spawn;
struct crypto_alg *cipher_alg;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return ERR_CAST(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask)
- return ERR_PTR(-EINVAL);
-
- mask = crypto_requires_off(algt->type, algt->mask,
- CRYPTO_ALG_NEED_FALLBACK);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
+ if (err)
+ return ERR_PTR(err);
inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
if (!inst)
@@ -993,3 +981,4 @@ EXPORT_SYMBOL_GPL(skcipher_alloc_instance_simple);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Symmetric key cipher type");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/sm2.c b/crypto/sm2.c
new file mode 100644
index 000000000000..ed9307dac3d1
--- /dev/null
+++ b/crypto/sm2.c
@@ -0,0 +1,460 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * SM2 asymmetric public-key algorithm
+ * as specified by OSCCA GM/T 0003.1-2012 -- 0003.5-2012 SM2 and
+ * described at https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02
+ *
+ * Copyright (c) 2020, Alibaba Group.
+ * Authors: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+ */
+
+#include <linux/module.h>
+#include <linux/mpi.h>
+#include <crypto/internal/akcipher.h>
+#include <crypto/akcipher.h>
+#include <crypto/hash.h>
+#include <crypto/sm3.h>
+#include <crypto/rng.h>
+#include <crypto/sm2.h>
+#include "sm2signature.asn1.h"
+
+#define MPI_NBYTES(m) ((mpi_get_nbits(m) + 7) / 8)
+
+struct ecc_domain_parms {
+ const char *desc; /* Description of the curve. */
+ unsigned int nbits; /* Number of bits. */
+ unsigned int fips:1; /* True if this is a FIPS140-2 approved curve */
+
+ /* The model describing this curve. This is mainly used to select
+ * the group equation.
+ */
+ enum gcry_mpi_ec_models model;
+
+ /* The actual ECC dialect used. This is used for curve specific
+ * optimizations and to select encodings etc.
+ */
+ enum ecc_dialects dialect;
+
+ const char *p; /* The prime defining the field. */
+ const char *a, *b; /* The coefficients. For Twisted Edwards
+ * Curves b is used for d. For Montgomery
+ * Curves (a,b) has ((A-2)/4,B^-1).
+ */
+ const char *n; /* The order of the base point. */
+ const char *g_x, *g_y; /* Base point. */
+ unsigned int h; /* Cofactor. */
+};
+
+static const struct ecc_domain_parms sm2_ecp = {
+ .desc = "sm2p256v1",
+ .nbits = 256,
+ .fips = 0,
+ .model = MPI_EC_WEIERSTRASS,
+ .dialect = ECC_DIALECT_STANDARD,
+ .p = "0xfffffffeffffffffffffffffffffffffffffffff00000000ffffffffffffffff",
+ .a = "0xfffffffeffffffffffffffffffffffffffffffff00000000fffffffffffffffc",
+ .b = "0x28e9fa9e9d9f5e344d5a9e4bcf6509a7f39789f515ab8f92ddbcbd414d940e93",
+ .n = "0xfffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123",
+ .g_x = "0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7",
+ .g_y = "0xbc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0",
+ .h = 1
+};
+
+static int sm2_ec_ctx_init(struct mpi_ec_ctx *ec)
+{
+ const struct ecc_domain_parms *ecp = &sm2_ecp;
+ MPI p, a, b;
+ MPI x, y;
+ int rc = -EINVAL;
+
+ p = mpi_scanval(ecp->p);
+ a = mpi_scanval(ecp->a);
+ b = mpi_scanval(ecp->b);
+ if (!p || !a || !b)
+ goto free_p;
+
+ x = mpi_scanval(ecp->g_x);
+ y = mpi_scanval(ecp->g_y);
+ if (!x || !y)
+ goto free;
+
+ rc = -ENOMEM;
+
+ ec->Q = mpi_point_new(0);
+ if (!ec->Q)
+ goto free;
+
+ /* mpi_ec_setup_elliptic_curve */
+ ec->G = mpi_point_new(0);
+ if (!ec->G) {
+ mpi_point_release(ec->Q);
+ goto free;
+ }
+
+ mpi_set(ec->G->x, x);
+ mpi_set(ec->G->y, y);
+ mpi_set_ui(ec->G->z, 1);
+
+ rc = -EINVAL;
+ ec->n = mpi_scanval(ecp->n);
+ if (!ec->n) {
+ mpi_point_release(ec->Q);
+ mpi_point_release(ec->G);
+ goto free;
+ }
+
+ ec->h = ecp->h;
+ ec->name = ecp->desc;
+ mpi_ec_init(ec, ecp->model, ecp->dialect, 0, p, a, b);
+
+ rc = 0;
+
+free:
+ mpi_free(x);
+ mpi_free(y);
+free_p:
+ mpi_free(p);
+ mpi_free(a);
+ mpi_free(b);
+
+ return rc;
+}
+
+static void sm2_ec_ctx_deinit(struct mpi_ec_ctx *ec)
+{
+ mpi_ec_deinit(ec);
+
+ memset(ec, 0, sizeof(*ec));
+}
+
+/* RESULT must have been initialized and is set on success to the
+ * point given by VALUE.
+ */
+static int sm2_ecc_os2ec(MPI_POINT result, MPI value)
+{
+ int rc;
+ size_t n;
+ unsigned char *buf;
+ MPI x, y;
+
+ n = MPI_NBYTES(value);
+ buf = kmalloc(n, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ rc = mpi_print(GCRYMPI_FMT_USG, buf, n, &n, value);
+ if (rc)
+ goto err_freebuf;
+
+ rc = -EINVAL;
+ if (n < 1 || ((n - 1) % 2))
+ goto err_freebuf;
+ /* No support for point compression */
+ if (*buf != 0x4)
+ goto err_freebuf;
+
+ rc = -ENOMEM;
+ n = (n - 1) / 2;
+ x = mpi_read_raw_data(buf + 1, n);
+ if (!x)
+ goto err_freebuf;
+ y = mpi_read_raw_data(buf + 1 + n, n);
+ if (!y)
+ goto err_freex;
+
+ mpi_normalize(x);
+ mpi_normalize(y);
+ mpi_set(result->x, x);
+ mpi_set(result->y, y);
+ mpi_set_ui(result->z, 1);
+
+ rc = 0;
+
+ mpi_free(y);
+err_freex:
+ mpi_free(x);
+err_freebuf:
+ kfree(buf);
+ return rc;
+}
+
+struct sm2_signature_ctx {
+ MPI sig_r;
+ MPI sig_s;
+};
+
+int sm2_get_signature_r(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct sm2_signature_ctx *sig = context;
+
+ if (!value || !vlen)
+ return -EINVAL;
+
+ sig->sig_r = mpi_read_raw_data(value, vlen);
+ if (!sig->sig_r)
+ return -ENOMEM;
+
+ return 0;
+}
+
+int sm2_get_signature_s(void *context, size_t hdrlen, unsigned char tag,
+ const void *value, size_t vlen)
+{
+ struct sm2_signature_ctx *sig = context;
+
+ if (!value || !vlen)
+ return -EINVAL;
+
+ sig->sig_s = mpi_read_raw_data(value, vlen);
+ if (!sig->sig_s)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int sm2_z_digest_update(struct sm3_state *sctx,
+ MPI m, unsigned int pbytes)
+{
+ static const unsigned char zero[32];
+ unsigned char *in;
+ unsigned int inlen;
+
+ in = mpi_get_buffer(m, &inlen, NULL);
+ if (!in)
+ return -EINVAL;
+
+ if (inlen < pbytes) {
+ /* padding with zero */
+ sm3_update(sctx, zero, pbytes - inlen);
+ sm3_update(sctx, in, inlen);
+ } else if (inlen > pbytes) {
+ /* skip the starting zero */
+ sm3_update(sctx, in + inlen - pbytes, pbytes);
+ } else {
+ sm3_update(sctx, in, inlen);
+ }
+
+ kfree(in);
+ return 0;
+}
+
+static int sm2_z_digest_update_point(struct sm3_state *sctx,
+ MPI_POINT point, struct mpi_ec_ctx *ec, unsigned int pbytes)
+{
+ MPI x, y;
+ int ret = -EINVAL;
+
+ x = mpi_new(0);
+ y = mpi_new(0);
+
+ if (!mpi_ec_get_affine(x, y, point, ec) &&
+ !sm2_z_digest_update(sctx, x, pbytes) &&
+ !sm2_z_digest_update(sctx, y, pbytes))
+ ret = 0;
+
+ mpi_free(x);
+ mpi_free(y);
+ return ret;
+}
+
+int sm2_compute_z_digest(struct crypto_akcipher *tfm,
+ const unsigned char *id, size_t id_len,
+ unsigned char dgst[SM3_DIGEST_SIZE])
+{
+ struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm);
+ uint16_t bits_len;
+ unsigned char entl[2];
+ struct sm3_state sctx;
+ unsigned int pbytes;
+
+ if (id_len > (USHRT_MAX / 8) || !ec->Q)
+ return -EINVAL;
+
+ bits_len = (uint16_t)(id_len * 8);
+ entl[0] = bits_len >> 8;
+ entl[1] = bits_len & 0xff;
+
+ pbytes = MPI_NBYTES(ec->p);
+
+ /* ZA = H256(ENTLA | IDA | a | b | xG | yG | xA | yA) */
+ sm3_init(&sctx);
+ sm3_update(&sctx, entl, 2);
+ sm3_update(&sctx, id, id_len);
+
+ if (sm2_z_digest_update(&sctx, ec->a, pbytes) ||
+ sm2_z_digest_update(&sctx, ec->b, pbytes) ||
+ sm2_z_digest_update_point(&sctx, ec->G, ec, pbytes) ||
+ sm2_z_digest_update_point(&sctx, ec->Q, ec, pbytes))
+ return -EINVAL;
+
+ sm3_final(&sctx, dgst);
+ return 0;
+}
+EXPORT_SYMBOL(sm2_compute_z_digest);
+
+static int _sm2_verify(struct mpi_ec_ctx *ec, MPI hash, MPI sig_r, MPI sig_s)
+{
+ int rc = -EINVAL;
+ struct gcry_mpi_point sG, tP;
+ MPI t = NULL;
+ MPI x1 = NULL, y1 = NULL;
+
+ mpi_point_init(&sG);
+ mpi_point_init(&tP);
+ x1 = mpi_new(0);
+ y1 = mpi_new(0);
+ t = mpi_new(0);
+
+ /* r, s in [1, n-1] */
+ if (mpi_cmp_ui(sig_r, 1) < 0 || mpi_cmp(sig_r, ec->n) > 0 ||
+ mpi_cmp_ui(sig_s, 1) < 0 || mpi_cmp(sig_s, ec->n) > 0) {
+ goto leave;
+ }
+
+ /* t = (r + s) % n, t == 0 */
+ mpi_addm(t, sig_r, sig_s, ec->n);
+ if (mpi_cmp_ui(t, 0) == 0)
+ goto leave;
+
+ /* sG + tP = (x1, y1) */
+ rc = -EBADMSG;
+ mpi_ec_mul_point(&sG, sig_s, ec->G, ec);
+ mpi_ec_mul_point(&tP, t, ec->Q, ec);
+ mpi_ec_add_points(&sG, &sG, &tP, ec);
+ if (mpi_ec_get_affine(x1, y1, &sG, ec))
+ goto leave;
+
+ /* R = (e + x1) % n */
+ mpi_addm(t, hash, x1, ec->n);
+
+ /* check R == r */
+ rc = -EKEYREJECTED;
+ if (mpi_cmp(t, sig_r))
+ goto leave;
+
+ rc = 0;
+
+leave:
+ mpi_point_free_parts(&sG);
+ mpi_point_free_parts(&tP);
+ mpi_free(x1);
+ mpi_free(y1);
+ mpi_free(t);
+
+ return rc;
+}
+
+static int sm2_verify(struct akcipher_request *req)
+{
+ struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
+ struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm);
+ unsigned char *buffer;
+ struct sm2_signature_ctx sig;
+ MPI hash;
+ int ret;
+
+ if (unlikely(!ec->Q))
+ return -EINVAL;
+
+ buffer = kmalloc(req->src_len + req->dst_len, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ sg_pcopy_to_buffer(req->src,
+ sg_nents_for_len(req->src, req->src_len + req->dst_len),
+ buffer, req->src_len + req->dst_len, 0);
+
+ sig.sig_r = NULL;
+ sig.sig_s = NULL;
+ ret = asn1_ber_decoder(&sm2signature_decoder, &sig,
+ buffer, req->src_len);
+ if (ret)
+ goto error;
+
+ ret = -ENOMEM;
+ hash = mpi_read_raw_data(buffer + req->src_len, req->dst_len);
+ if (!hash)
+ goto error;
+
+ ret = _sm2_verify(ec, hash, sig.sig_r, sig.sig_s);
+
+ mpi_free(hash);
+error:
+ mpi_free(sig.sig_r);
+ mpi_free(sig.sig_s);
+ kfree(buffer);
+ return ret;
+}
+
+static int sm2_set_pub_key(struct crypto_akcipher *tfm,
+ const void *key, unsigned int keylen)
+{
+ struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm);
+ MPI a;
+ int rc;
+
+ /* include the uncompressed flag '0x04' */
+ a = mpi_read_raw_data(key, keylen);
+ if (!a)
+ return -ENOMEM;
+
+ mpi_normalize(a);
+ rc = sm2_ecc_os2ec(ec->Q, a);
+ mpi_free(a);
+
+ return rc;
+}
+
+static unsigned int sm2_max_size(struct crypto_akcipher *tfm)
+{
+ /* Unlimited max size */
+ return PAGE_SIZE;
+}
+
+static int sm2_init_tfm(struct crypto_akcipher *tfm)
+{
+ struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm);
+
+ return sm2_ec_ctx_init(ec);
+}
+
+static void sm2_exit_tfm(struct crypto_akcipher *tfm)
+{
+ struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm);
+
+ sm2_ec_ctx_deinit(ec);
+}
+
+static struct akcipher_alg sm2 = {
+ .verify = sm2_verify,
+ .set_pub_key = sm2_set_pub_key,
+ .max_size = sm2_max_size,
+ .init = sm2_init_tfm,
+ .exit = sm2_exit_tfm,
+ .base = {
+ .cra_name = "sm2",
+ .cra_driver_name = "sm2-generic",
+ .cra_priority = 100,
+ .cra_module = THIS_MODULE,
+ .cra_ctxsize = sizeof(struct mpi_ec_ctx),
+ },
+};
+
+static int __init sm2_init(void)
+{
+ return crypto_register_akcipher(&sm2);
+}
+
+static void __exit sm2_exit(void)
+{
+ crypto_unregister_akcipher(&sm2);
+}
+
+subsys_initcall(sm2_init);
+module_exit(sm2_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tianjia Zhang <tianjia.zhang@linux.alibaba.com>");
+MODULE_DESCRIPTION("SM2 generic algorithm");
+MODULE_ALIAS_CRYPTO("sm2-generic");
diff --git a/crypto/sm2signature.asn1 b/crypto/sm2signature.asn1
new file mode 100644
index 000000000000..ab8c0b754d21
--- /dev/null
+++ b/crypto/sm2signature.asn1
@@ -0,0 +1,4 @@
+Sm2Signature ::= SEQUENCE {
+ sig_r INTEGER ({ sm2_get_signature_r }),
+ sig_s INTEGER ({ sm2_get_signature_s })
+}
diff --git a/crypto/sm3.c b/crypto/sm3.c
new file mode 100644
index 000000000000..d473e358a873
--- /dev/null
+++ b/crypto/sm3.c
@@ -0,0 +1,246 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * SM3 secure hash, as specified by OSCCA GM/T 0004-2012 SM3 and described
+ * at https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02
+ *
+ * Copyright (C) 2017 ARM Limited or its affiliates.
+ * Copyright (C) 2017 Gilad Ben-Yossef <gilad@benyossef.com>
+ * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+ */
+
+#include <linux/module.h>
+#include <asm/unaligned.h>
+#include <crypto/sm3.h>
+
+static const u32 ____cacheline_aligned K[64] = {
+ 0x79cc4519, 0xf3988a32, 0xe7311465, 0xce6228cb,
+ 0x9cc45197, 0x3988a32f, 0x7311465e, 0xe6228cbc,
+ 0xcc451979, 0x988a32f3, 0x311465e7, 0x6228cbce,
+ 0xc451979c, 0x88a32f39, 0x11465e73, 0x228cbce6,
+ 0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
+ 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
+ 0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
+ 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5,
+ 0x7a879d8a, 0xf50f3b14, 0xea1e7629, 0xd43cec53,
+ 0xa879d8a7, 0x50f3b14f, 0xa1e7629e, 0x43cec53d,
+ 0x879d8a7a, 0x0f3b14f5, 0x1e7629ea, 0x3cec53d4,
+ 0x79d8a7a8, 0xf3b14f50, 0xe7629ea1, 0xcec53d43,
+ 0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
+ 0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
+ 0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
+ 0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5
+};
+
+/*
+ * Transform the message X which consists of 16 32-bit-words. See
+ * GM/T 004-2012 for details.
+ */
+#define R(i, a, b, c, d, e, f, g, h, t, w1, w2) \
+ do { \
+ ss1 = rol32((rol32((a), 12) + (e) + (t)), 7); \
+ ss2 = ss1 ^ rol32((a), 12); \
+ d += FF ## i(a, b, c) + ss2 + ((w1) ^ (w2)); \
+ h += GG ## i(e, f, g) + ss1 + (w1); \
+ b = rol32((b), 9); \
+ f = rol32((f), 19); \
+ h = P0((h)); \
+ } while (0)
+
+#define R1(a, b, c, d, e, f, g, h, t, w1, w2) \
+ R(1, a, b, c, d, e, f, g, h, t, w1, w2)
+#define R2(a, b, c, d, e, f, g, h, t, w1, w2) \
+ R(2, a, b, c, d, e, f, g, h, t, w1, w2)
+
+#define FF1(x, y, z) (x ^ y ^ z)
+#define FF2(x, y, z) ((x & y) | (x & z) | (y & z))
+
+#define GG1(x, y, z) FF1(x, y, z)
+#define GG2(x, y, z) ((x & y) | (~x & z))
+
+/* Message expansion */
+#define P0(x) ((x) ^ rol32((x), 9) ^ rol32((x), 17))
+#define P1(x) ((x) ^ rol32((x), 15) ^ rol32((x), 23))
+#define I(i) (W[i] = get_unaligned_be32(data + i * 4))
+#define W1(i) (W[i & 0x0f])
+#define W2(i) (W[i & 0x0f] = \
+ P1(W[i & 0x0f] \
+ ^ W[(i-9) & 0x0f] \
+ ^ rol32(W[(i-3) & 0x0f], 15)) \
+ ^ rol32(W[(i-13) & 0x0f], 7) \
+ ^ W[(i-6) & 0x0f])
+
+static void sm3_transform(struct sm3_state *sctx, u8 const *data, u32 W[16])
+{
+ u32 a, b, c, d, e, f, g, h, ss1, ss2;
+
+ a = sctx->state[0];
+ b = sctx->state[1];
+ c = sctx->state[2];
+ d = sctx->state[3];
+ e = sctx->state[4];
+ f = sctx->state[5];
+ g = sctx->state[6];
+ h = sctx->state[7];
+
+ R1(a, b, c, d, e, f, g, h, K[0], I(0), I(4));
+ R1(d, a, b, c, h, e, f, g, K[1], I(1), I(5));
+ R1(c, d, a, b, g, h, e, f, K[2], I(2), I(6));
+ R1(b, c, d, a, f, g, h, e, K[3], I(3), I(7));
+ R1(a, b, c, d, e, f, g, h, K[4], W1(4), I(8));
+ R1(d, a, b, c, h, e, f, g, K[5], W1(5), I(9));
+ R1(c, d, a, b, g, h, e, f, K[6], W1(6), I(10));
+ R1(b, c, d, a, f, g, h, e, K[7], W1(7), I(11));
+ R1(a, b, c, d, e, f, g, h, K[8], W1(8), I(12));
+ R1(d, a, b, c, h, e, f, g, K[9], W1(9), I(13));
+ R1(c, d, a, b, g, h, e, f, K[10], W1(10), I(14));
+ R1(b, c, d, a, f, g, h, e, K[11], W1(11), I(15));
+ R1(a, b, c, d, e, f, g, h, K[12], W1(12), W2(16));
+ R1(d, a, b, c, h, e, f, g, K[13], W1(13), W2(17));
+ R1(c, d, a, b, g, h, e, f, K[14], W1(14), W2(18));
+ R1(b, c, d, a, f, g, h, e, K[15], W1(15), W2(19));
+
+ R2(a, b, c, d, e, f, g, h, K[16], W1(16), W2(20));
+ R2(d, a, b, c, h, e, f, g, K[17], W1(17), W2(21));
+ R2(c, d, a, b, g, h, e, f, K[18], W1(18), W2(22));
+ R2(b, c, d, a, f, g, h, e, K[19], W1(19), W2(23));
+ R2(a, b, c, d, e, f, g, h, K[20], W1(20), W2(24));
+ R2(d, a, b, c, h, e, f, g, K[21], W1(21), W2(25));
+ R2(c, d, a, b, g, h, e, f, K[22], W1(22), W2(26));
+ R2(b, c, d, a, f, g, h, e, K[23], W1(23), W2(27));
+ R2(a, b, c, d, e, f, g, h, K[24], W1(24), W2(28));
+ R2(d, a, b, c, h, e, f, g, K[25], W1(25), W2(29));
+ R2(c, d, a, b, g, h, e, f, K[26], W1(26), W2(30));
+ R2(b, c, d, a, f, g, h, e, K[27], W1(27), W2(31));
+ R2(a, b, c, d, e, f, g, h, K[28], W1(28), W2(32));
+ R2(d, a, b, c, h, e, f, g, K[29], W1(29), W2(33));
+ R2(c, d, a, b, g, h, e, f, K[30], W1(30), W2(34));
+ R2(b, c, d, a, f, g, h, e, K[31], W1(31), W2(35));
+
+ R2(a, b, c, d, e, f, g, h, K[32], W1(32), W2(36));
+ R2(d, a, b, c, h, e, f, g, K[33], W1(33), W2(37));
+ R2(c, d, a, b, g, h, e, f, K[34], W1(34), W2(38));
+ R2(b, c, d, a, f, g, h, e, K[35], W1(35), W2(39));
+ R2(a, b, c, d, e, f, g, h, K[36], W1(36), W2(40));
+ R2(d, a, b, c, h, e, f, g, K[37], W1(37), W2(41));
+ R2(c, d, a, b, g, h, e, f, K[38], W1(38), W2(42));
+ R2(b, c, d, a, f, g, h, e, K[39], W1(39), W2(43));
+ R2(a, b, c, d, e, f, g, h, K[40], W1(40), W2(44));
+ R2(d, a, b, c, h, e, f, g, K[41], W1(41), W2(45));
+ R2(c, d, a, b, g, h, e, f, K[42], W1(42), W2(46));
+ R2(b, c, d, a, f, g, h, e, K[43], W1(43), W2(47));
+ R2(a, b, c, d, e, f, g, h, K[44], W1(44), W2(48));
+ R2(d, a, b, c, h, e, f, g, K[45], W1(45), W2(49));
+ R2(c, d, a, b, g, h, e, f, K[46], W1(46), W2(50));
+ R2(b, c, d, a, f, g, h, e, K[47], W1(47), W2(51));
+
+ R2(a, b, c, d, e, f, g, h, K[48], W1(48), W2(52));
+ R2(d, a, b, c, h, e, f, g, K[49], W1(49), W2(53));
+ R2(c, d, a, b, g, h, e, f, K[50], W1(50), W2(54));
+ R2(b, c, d, a, f, g, h, e, K[51], W1(51), W2(55));
+ R2(a, b, c, d, e, f, g, h, K[52], W1(52), W2(56));
+ R2(d, a, b, c, h, e, f, g, K[53], W1(53), W2(57));
+ R2(c, d, a, b, g, h, e, f, K[54], W1(54), W2(58));
+ R2(b, c, d, a, f, g, h, e, K[55], W1(55), W2(59));
+ R2(a, b, c, d, e, f, g, h, K[56], W1(56), W2(60));
+ R2(d, a, b, c, h, e, f, g, K[57], W1(57), W2(61));
+ R2(c, d, a, b, g, h, e, f, K[58], W1(58), W2(62));
+ R2(b, c, d, a, f, g, h, e, K[59], W1(59), W2(63));
+ R2(a, b, c, d, e, f, g, h, K[60], W1(60), W2(64));
+ R2(d, a, b, c, h, e, f, g, K[61], W1(61), W2(65));
+ R2(c, d, a, b, g, h, e, f, K[62], W1(62), W2(66));
+ R2(b, c, d, a, f, g, h, e, K[63], W1(63), W2(67));
+
+ sctx->state[0] ^= a;
+ sctx->state[1] ^= b;
+ sctx->state[2] ^= c;
+ sctx->state[3] ^= d;
+ sctx->state[4] ^= e;
+ sctx->state[5] ^= f;
+ sctx->state[6] ^= g;
+ sctx->state[7] ^= h;
+}
+#undef R
+#undef R1
+#undef R2
+#undef I
+#undef W1
+#undef W2
+
+static inline void sm3_block(struct sm3_state *sctx,
+ u8 const *data, int blocks, u32 W[16])
+{
+ while (blocks--) {
+ sm3_transform(sctx, data, W);
+ data += SM3_BLOCK_SIZE;
+ }
+}
+
+void sm3_update(struct sm3_state *sctx, const u8 *data, unsigned int len)
+{
+ unsigned int partial = sctx->count % SM3_BLOCK_SIZE;
+ u32 W[16];
+
+ sctx->count += len;
+
+ if ((partial + len) >= SM3_BLOCK_SIZE) {
+ int blocks;
+
+ if (partial) {
+ int p = SM3_BLOCK_SIZE - partial;
+
+ memcpy(sctx->buffer + partial, data, p);
+ data += p;
+ len -= p;
+
+ sm3_block(sctx, sctx->buffer, 1, W);
+ }
+
+ blocks = len / SM3_BLOCK_SIZE;
+ len %= SM3_BLOCK_SIZE;
+
+ if (blocks) {
+ sm3_block(sctx, data, blocks, W);
+ data += blocks * SM3_BLOCK_SIZE;
+ }
+
+ memzero_explicit(W, sizeof(W));
+
+ partial = 0;
+ }
+ if (len)
+ memcpy(sctx->buffer + partial, data, len);
+}
+EXPORT_SYMBOL_GPL(sm3_update);
+
+void sm3_final(struct sm3_state *sctx, u8 *out)
+{
+ const int bit_offset = SM3_BLOCK_SIZE - sizeof(u64);
+ __be64 *bits = (__be64 *)(sctx->buffer + bit_offset);
+ __be32 *digest = (__be32 *)out;
+ unsigned int partial = sctx->count % SM3_BLOCK_SIZE;
+ u32 W[16];
+ int i;
+
+ sctx->buffer[partial++] = 0x80;
+ if (partial > bit_offset) {
+ memset(sctx->buffer + partial, 0, SM3_BLOCK_SIZE - partial);
+ partial = 0;
+
+ sm3_block(sctx, sctx->buffer, 1, W);
+ }
+
+ memset(sctx->buffer + partial, 0, bit_offset - partial);
+ *bits = cpu_to_be64(sctx->count << 3);
+ sm3_block(sctx, sctx->buffer, 1, W);
+
+ for (i = 0; i < 8; i++)
+ put_unaligned_be32(sctx->state[i], digest++);
+
+ /* Zeroize sensitive information. */
+ memzero_explicit(W, sizeof(W));
+ memzero_explicit(sctx, sizeof(*sctx));
+}
+EXPORT_SYMBOL_GPL(sm3_final);
+
+MODULE_DESCRIPTION("Generic SM3 library");
+MODULE_LICENSE("GPL v2");
diff --git a/crypto/sm3_generic.c b/crypto/sm3_generic.c
index 3468975215ca..a215c1c37e73 100644
--- a/crypto/sm3_generic.c
+++ b/crypto/sm3_generic.c
@@ -5,6 +5,7 @@
*
* Copyright (C) 2017 ARM Limited or its affiliates.
* Written by Gilad Ben-Yossef <gilad@benyossef.com>
+ * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
*/
#include <crypto/internal/hash.h>
@@ -26,153 +27,41 @@ const u8 sm3_zero_message_hash[SM3_DIGEST_SIZE] = {
};
EXPORT_SYMBOL_GPL(sm3_zero_message_hash);
-static inline u32 p0(u32 x)
-{
- return x ^ rol32(x, 9) ^ rol32(x, 17);
-}
-
-static inline u32 p1(u32 x)
-{
- return x ^ rol32(x, 15) ^ rol32(x, 23);
-}
-
-static inline u32 ff(unsigned int n, u32 a, u32 b, u32 c)
-{
- return (n < 16) ? (a ^ b ^ c) : ((a & b) | (a & c) | (b & c));
-}
-
-static inline u32 gg(unsigned int n, u32 e, u32 f, u32 g)
-{
- return (n < 16) ? (e ^ f ^ g) : ((e & f) | ((~e) & g));
-}
-
-static inline u32 t(unsigned int n)
-{
- return (n < 16) ? SM3_T1 : SM3_T2;
-}
-
-static void sm3_expand(u32 *t, u32 *w, u32 *wt)
-{
- int i;
- unsigned int tmp;
-
- /* load the input */
- for (i = 0; i <= 15; i++)
- w[i] = get_unaligned_be32((__u32 *)t + i);
-
- for (i = 16; i <= 67; i++) {
- tmp = w[i - 16] ^ w[i - 9] ^ rol32(w[i - 3], 15);
- w[i] = p1(tmp) ^ (rol32(w[i - 13], 7)) ^ w[i - 6];
- }
-
- for (i = 0; i <= 63; i++)
- wt[i] = w[i] ^ w[i + 4];
-}
-
-static void sm3_compress(u32 *w, u32 *wt, u32 *m)
-{
- u32 ss1;
- u32 ss2;
- u32 tt1;
- u32 tt2;
- u32 a, b, c, d, e, f, g, h;
- int i;
-
- a = m[0];
- b = m[1];
- c = m[2];
- d = m[3];
- e = m[4];
- f = m[5];
- g = m[6];
- h = m[7];
-
- for (i = 0; i <= 63; i++) {
-
- ss1 = rol32((rol32(a, 12) + e + rol32(t(i), i & 31)), 7);
-
- ss2 = ss1 ^ rol32(a, 12);
-
- tt1 = ff(i, a, b, c) + d + ss2 + *wt;
- wt++;
-
- tt2 = gg(i, e, f, g) + h + ss1 + *w;
- w++;
-
- d = c;
- c = rol32(b, 9);
- b = a;
- a = tt1;
- h = g;
- g = rol32(f, 19);
- f = e;
- e = p0(tt2);
- }
-
- m[0] = a ^ m[0];
- m[1] = b ^ m[1];
- m[2] = c ^ m[2];
- m[3] = d ^ m[3];
- m[4] = e ^ m[4];
- m[5] = f ^ m[5];
- m[6] = g ^ m[6];
- m[7] = h ^ m[7];
-
- a = b = c = d = e = f = g = h = ss1 = ss2 = tt1 = tt2 = 0;
-}
-
-static void sm3_transform(struct sm3_state *sst, u8 const *src)
-{
- unsigned int w[68];
- unsigned int wt[64];
-
- sm3_expand((u32 *)src, w, wt);
- sm3_compress(w, wt, sst->state);
-
- memzero_explicit(w, sizeof(w));
- memzero_explicit(wt, sizeof(wt));
-}
-
-static void sm3_generic_block_fn(struct sm3_state *sst, u8 const *src,
- int blocks)
-{
- while (blocks--) {
- sm3_transform(sst, src);
- src += SM3_BLOCK_SIZE;
- }
-}
-
-int crypto_sm3_update(struct shash_desc *desc, const u8 *data,
+static int crypto_sm3_update(struct shash_desc *desc, const u8 *data,
unsigned int len)
{
- return sm3_base_do_update(desc, data, len, sm3_generic_block_fn);
+ sm3_update(shash_desc_ctx(desc), data, len);
+ return 0;
}
-EXPORT_SYMBOL(crypto_sm3_update);
-static int sm3_final(struct shash_desc *desc, u8 *out)
+static int crypto_sm3_final(struct shash_desc *desc, u8 *out)
{
- sm3_base_do_finalize(desc, sm3_generic_block_fn);
- return sm3_base_finish(desc, out);
+ sm3_final(shash_desc_ctx(desc), out);
+ return 0;
}
-int crypto_sm3_finup(struct shash_desc *desc, const u8 *data,
+static int crypto_sm3_finup(struct shash_desc *desc, const u8 *data,
unsigned int len, u8 *hash)
{
- sm3_base_do_update(desc, data, len, sm3_generic_block_fn);
- return sm3_final(desc, hash);
+ struct sm3_state *sctx = shash_desc_ctx(desc);
+
+ if (len)
+ sm3_update(sctx, data, len);
+ sm3_final(sctx, hash);
+ return 0;
}
-EXPORT_SYMBOL(crypto_sm3_finup);
static struct shash_alg sm3_alg = {
.digestsize = SM3_DIGEST_SIZE,
.init = sm3_base_init,
.update = crypto_sm3_update,
- .final = sm3_final,
+ .final = crypto_sm3_final,
.finup = crypto_sm3_finup,
.descsize = sizeof(struct sm3_state),
.base = {
.cra_name = "sm3",
.cra_driver_name = "sm3-generic",
+ .cra_priority = 100,
.cra_blocksize = SM3_BLOCK_SIZE,
.cra_module = THIS_MODULE,
}
diff --git a/crypto/sm4.c b/crypto/sm4.c
new file mode 100644
index 000000000000..2c44193bc27e
--- /dev/null
+++ b/crypto/sm4.c
@@ -0,0 +1,184 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * SM4, as specified in
+ * https://tools.ietf.org/id/draft-ribose-cfrg-sm4-10.html
+ *
+ * Copyright (C) 2018 ARM Limited or its affiliates.
+ * Copyright (c) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+ */
+
+#include <linux/module.h>
+#include <asm/unaligned.h>
+#include <crypto/sm4.h>
+
+static const u32 ____cacheline_aligned fk[4] = {
+ 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc
+};
+
+static const u32 ____cacheline_aligned ck[32] = {
+ 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
+ 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
+ 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
+ 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
+ 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
+ 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
+ 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
+ 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
+};
+
+static const u8 ____cacheline_aligned sbox[256] = {
+ 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
+ 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
+ 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
+ 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
+ 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
+ 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
+ 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
+ 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
+ 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
+ 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
+ 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
+ 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
+ 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
+ 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
+ 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
+ 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
+ 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
+ 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
+ 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
+ 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
+ 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
+ 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
+ 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
+ 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
+ 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
+ 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
+ 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
+ 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
+ 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
+ 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
+ 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
+ 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
+};
+
+extern const u32 crypto_sm4_fk[4] __alias(fk);
+extern const u32 crypto_sm4_ck[32] __alias(ck);
+extern const u8 crypto_sm4_sbox[256] __alias(sbox);
+
+EXPORT_SYMBOL(crypto_sm4_fk);
+EXPORT_SYMBOL(crypto_sm4_ck);
+EXPORT_SYMBOL(crypto_sm4_sbox);
+
+static inline u32 sm4_t_non_lin_sub(u32 x)
+{
+ u32 out;
+
+ out = (u32)sbox[x & 0xff];
+ out |= (u32)sbox[(x >> 8) & 0xff] << 8;
+ out |= (u32)sbox[(x >> 16) & 0xff] << 16;
+ out |= (u32)sbox[(x >> 24) & 0xff] << 24;
+
+ return out;
+}
+
+static inline u32 sm4_key_lin_sub(u32 x)
+{
+ return x ^ rol32(x, 13) ^ rol32(x, 23);
+}
+
+static inline u32 sm4_enc_lin_sub(u32 x)
+{
+ return x ^ rol32(x, 2) ^ rol32(x, 10) ^ rol32(x, 18) ^ rol32(x, 24);
+}
+
+static inline u32 sm4_key_sub(u32 x)
+{
+ return sm4_key_lin_sub(sm4_t_non_lin_sub(x));
+}
+
+static inline u32 sm4_enc_sub(u32 x)
+{
+ return sm4_enc_lin_sub(sm4_t_non_lin_sub(x));
+}
+
+static inline u32 sm4_round(u32 x0, u32 x1, u32 x2, u32 x3, u32 rk)
+{
+ return x0 ^ sm4_enc_sub(x1 ^ x2 ^ x3 ^ rk);
+}
+
+
+/**
+ * sm4_expandkey - Expands the SM4 key as described in GB/T 32907-2016
+ * @ctx: The location where the computed key will be stored.
+ * @in_key: The supplied key.
+ * @key_len: The length of the supplied key.
+ *
+ * Returns 0 on success. The function fails only if an invalid key size (or
+ * pointer) is supplied.
+ */
+int sm4_expandkey(struct sm4_ctx *ctx, const u8 *in_key,
+ unsigned int key_len)
+{
+ u32 rk[4];
+ const u32 *key = (u32 *)in_key;
+ int i;
+
+ if (key_len != SM4_KEY_SIZE)
+ return -EINVAL;
+
+ rk[0] = get_unaligned_be32(&key[0]) ^ fk[0];
+ rk[1] = get_unaligned_be32(&key[1]) ^ fk[1];
+ rk[2] = get_unaligned_be32(&key[2]) ^ fk[2];
+ rk[3] = get_unaligned_be32(&key[3]) ^ fk[3];
+
+ for (i = 0; i < 32; i += 4) {
+ rk[0] ^= sm4_key_sub(rk[1] ^ rk[2] ^ rk[3] ^ ck[i + 0]);
+ rk[1] ^= sm4_key_sub(rk[2] ^ rk[3] ^ rk[0] ^ ck[i + 1]);
+ rk[2] ^= sm4_key_sub(rk[3] ^ rk[0] ^ rk[1] ^ ck[i + 2]);
+ rk[3] ^= sm4_key_sub(rk[0] ^ rk[1] ^ rk[2] ^ ck[i + 3]);
+
+ ctx->rkey_enc[i + 0] = rk[0];
+ ctx->rkey_enc[i + 1] = rk[1];
+ ctx->rkey_enc[i + 2] = rk[2];
+ ctx->rkey_enc[i + 3] = rk[3];
+ ctx->rkey_dec[31 - 0 - i] = rk[0];
+ ctx->rkey_dec[31 - 1 - i] = rk[1];
+ ctx->rkey_dec[31 - 2 - i] = rk[2];
+ ctx->rkey_dec[31 - 3 - i] = rk[3];
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sm4_expandkey);
+
+/**
+ * sm4_crypt_block - Encrypt or decrypt a single SM4 block
+ * @rk: The rkey_enc for encrypt or rkey_dec for decrypt
+ * @out: Buffer to store output data
+ * @in: Buffer containing the input data
+ */
+void sm4_crypt_block(const u32 *rk, u8 *out, const u8 *in)
+{
+ u32 x[4], i;
+
+ x[0] = get_unaligned_be32(in + 0 * 4);
+ x[1] = get_unaligned_be32(in + 1 * 4);
+ x[2] = get_unaligned_be32(in + 2 * 4);
+ x[3] = get_unaligned_be32(in + 3 * 4);
+
+ for (i = 0; i < 32; i += 4) {
+ x[0] = sm4_round(x[0], x[1], x[2], x[3], rk[i + 0]);
+ x[1] = sm4_round(x[1], x[2], x[3], x[0], rk[i + 1]);
+ x[2] = sm4_round(x[2], x[3], x[0], x[1], rk[i + 2]);
+ x[3] = sm4_round(x[3], x[0], x[1], x[2], rk[i + 3]);
+ }
+
+ put_unaligned_be32(x[3 - 0], out + 0 * 4);
+ put_unaligned_be32(x[3 - 1], out + 1 * 4);
+ put_unaligned_be32(x[3 - 2], out + 2 * 4);
+ put_unaligned_be32(x[3 - 3], out + 3 * 4);
+}
+EXPORT_SYMBOL_GPL(sm4_crypt_block);
+
+MODULE_DESCRIPTION("Generic SM4 library");
+MODULE_LICENSE("GPL v2");
diff --git a/crypto/sm4_generic.c b/crypto/sm4_generic.c
index 016dbc595705..4a6480a27fee 100644
--- a/crypto/sm4_generic.c
+++ b/crypto/sm4_generic.c
@@ -16,191 +16,43 @@
#include <asm/byteorder.h>
#include <asm/unaligned.h>
-static const u32 fk[4] = {
- 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc
-};
-
-static const u8 sbox[256] = {
- 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
- 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
- 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
- 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
- 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
- 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
- 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
- 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
- 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
- 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
- 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
- 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
- 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
- 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
- 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
- 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
- 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
- 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
- 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
- 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
- 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
- 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
- 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
- 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
- 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
- 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
- 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
- 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
- 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
- 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
- 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
- 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
-};
-
-static const u32 ck[] = {
- 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
- 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
- 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
- 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
- 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
- 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
- 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
- 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
-};
-
-static u32 sm4_t_non_lin_sub(u32 x)
-{
- int i;
- u8 *b = (u8 *)&x;
-
- for (i = 0; i < 4; ++i)
- b[i] = sbox[b[i]];
-
- return x;
-}
-
-static u32 sm4_key_lin_sub(u32 x)
-{
- return x ^ rol32(x, 13) ^ rol32(x, 23);
-
-}
-
-static u32 sm4_enc_lin_sub(u32 x)
-{
- return x ^ rol32(x, 2) ^ rol32(x, 10) ^ rol32(x, 18) ^ rol32(x, 24);
-}
-
-static u32 sm4_key_sub(u32 x)
-{
- return sm4_key_lin_sub(sm4_t_non_lin_sub(x));
-}
-
-static u32 sm4_enc_sub(u32 x)
-{
- return sm4_enc_lin_sub(sm4_t_non_lin_sub(x));
-}
-
-static u32 sm4_round(const u32 *x, const u32 rk)
-{
- return x[0] ^ sm4_enc_sub(x[1] ^ x[2] ^ x[3] ^ rk);
-}
-
-
/**
- * crypto_sm4_expand_key - Expands the SM4 key as described in GB/T 32907-2016
- * @ctx: The location where the computed key will be stored.
- * @in_key: The supplied key.
- * @key_len: The length of the supplied key.
- *
- * Returns 0 on success. The function fails only if an invalid key size (or
- * pointer) is supplied.
- */
-int crypto_sm4_expand_key(struct crypto_sm4_ctx *ctx, const u8 *in_key,
- unsigned int key_len)
-{
- u32 rk[4], t;
- const u32 *key = (u32 *)in_key;
- int i;
-
- if (key_len != SM4_KEY_SIZE)
- return -EINVAL;
-
- for (i = 0; i < 4; ++i)
- rk[i] = get_unaligned_be32(&key[i]) ^ fk[i];
-
- for (i = 0; i < 32; ++i) {
- t = rk[0] ^ sm4_key_sub(rk[1] ^ rk[2] ^ rk[3] ^ ck[i]);
- ctx->rkey_enc[i] = t;
- rk[0] = rk[1];
- rk[1] = rk[2];
- rk[2] = rk[3];
- rk[3] = t;
- }
-
- for (i = 0; i < 32; ++i)
- ctx->rkey_dec[i] = ctx->rkey_enc[31 - i];
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(crypto_sm4_expand_key);
-
-/**
- * crypto_sm4_set_key - Set the SM4 key.
+ * sm4_setkey - Set the SM4 key.
* @tfm: The %crypto_tfm that is used in the context.
* @in_key: The input key.
* @key_len: The size of the key.
*
- * This function uses crypto_sm4_expand_key() to expand the key.
- * &crypto_sm4_ctx _must_ be the private data embedded in @tfm which is
+ * This function uses sm4_expandkey() to expand the key.
+ * &sm4_ctx _must_ be the private data embedded in @tfm which is
* retrieved with crypto_tfm_ctx().
*
* Return: 0 on success; -EINVAL on failure (only happens for bad key lengths)
*/
-int crypto_sm4_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+static int sm4_setkey(struct crypto_tfm *tfm, const u8 *in_key,
unsigned int key_len)
{
- struct crypto_sm4_ctx *ctx = crypto_tfm_ctx(tfm);
-
- return crypto_sm4_expand_key(ctx, in_key, key_len);
-}
-EXPORT_SYMBOL_GPL(crypto_sm4_set_key);
-
-static void sm4_do_crypt(const u32 *rk, u32 *out, const u32 *in)
-{
- u32 x[4], i, t;
-
- for (i = 0; i < 4; ++i)
- x[i] = get_unaligned_be32(&in[i]);
-
- for (i = 0; i < 32; ++i) {
- t = sm4_round(x, rk[i]);
- x[0] = x[1];
- x[1] = x[2];
- x[2] = x[3];
- x[3] = t;
- }
+ struct sm4_ctx *ctx = crypto_tfm_ctx(tfm);
- for (i = 0; i < 4; ++i)
- put_unaligned_be32(x[3 - i], &out[i]);
+ return sm4_expandkey(ctx, in_key, key_len);
}
/* encrypt a block of text */
-void crypto_sm4_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+static void sm4_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
- const struct crypto_sm4_ctx *ctx = crypto_tfm_ctx(tfm);
+ const struct sm4_ctx *ctx = crypto_tfm_ctx(tfm);
- sm4_do_crypt(ctx->rkey_enc, (u32 *)out, (u32 *)in);
+ sm4_crypt_block(ctx->rkey_enc, out, in);
}
-EXPORT_SYMBOL_GPL(crypto_sm4_encrypt);
/* decrypt a block of text */
-void crypto_sm4_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
+static void sm4_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
- const struct crypto_sm4_ctx *ctx = crypto_tfm_ctx(tfm);
+ const struct sm4_ctx *ctx = crypto_tfm_ctx(tfm);
- sm4_do_crypt(ctx->rkey_dec, (u32 *)out, (u32 *)in);
+ sm4_crypt_block(ctx->rkey_dec, out, in);
}
-EXPORT_SYMBOL_GPL(crypto_sm4_decrypt);
static struct crypto_alg sm4_alg = {
.cra_name = "sm4",
@@ -208,15 +60,15 @@ static struct crypto_alg sm4_alg = {
.cra_priority = 100,
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = SM4_BLOCK_SIZE,
- .cra_ctxsize = sizeof(struct crypto_sm4_ctx),
+ .cra_ctxsize = sizeof(struct sm4_ctx),
.cra_module = THIS_MODULE,
.cra_u = {
.cipher = {
.cia_min_keysize = SM4_KEY_SIZE,
.cia_max_keysize = SM4_KEY_SIZE,
- .cia_setkey = crypto_sm4_set_key,
- .cia_encrypt = crypto_sm4_encrypt,
- .cia_decrypt = crypto_sm4_decrypt
+ .cia_setkey = sm4_setkey,
+ .cia_encrypt = sm4_encrypt,
+ .cia_decrypt = sm4_decrypt
}
}
};
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index f42f486e90e8..a82679b576bb 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -58,26 +58,16 @@
*/
static unsigned int sec;
-static char *alg = NULL;
+static char *alg;
static u32 type;
static u32 mask;
static int mode;
static u32 num_mb = 8;
+static unsigned int klen;
static char *tvmem[TVMEMSIZE];
-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",
- "khazad", "wp512", "wp384", "wp256", "tnepres", "xeta", "fcrypt",
- "camellia", "seed", "salsa20", "rmd128", "rmd160", "rmd256", "rmd320",
- "lzo", "lzo-rle", "cts", "sha3-224", "sha3-256", "sha3-384",
- "sha3-512", "streebog256", "streebog512",
- NULL
-};
-
-static u32 block_sizes[] = { 16, 64, 256, 1024, 1472, 8192, 0 };
-static u32 aead_sizes[] = { 16, 64, 256, 512, 1024, 2048, 4096, 8192, 0 };
+static const int block_sizes[] = { 16, 64, 128, 256, 1024, 1420, 4096, 0 };
+static const int aead_sizes[] = { 16, 64, 256, 512, 1024, 1420, 4096, 8192, 0 };
#define XBUFSIZE 8
#define MAX_IVLEN 32
@@ -198,8 +188,8 @@ static int test_mb_aead_jiffies(struct test_mb_aead_data *data, int enc,
goto out;
}
- pr_cont("%d operations in %d seconds (%ld bytes)\n",
- bcount * num_mb, secs, (long)bcount * blen * num_mb);
+ pr_cont("%d operations in %d seconds (%llu bytes)\n",
+ bcount * num_mb, secs, (u64)bcount * blen * num_mb);
out:
kfree(rc);
@@ -255,10 +245,10 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs,
struct test_mb_aead_data *data;
struct crypto_aead *tfm;
unsigned int i, j, iv_len;
+ const int *b_size;
const char *key;
const char *e;
void *assoc;
- u32 *b_size;
char *iv;
int ret;
@@ -289,6 +279,11 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs,
}
ret = crypto_aead_setauthsize(tfm, authsize);
+ if (ret) {
+ pr_err("alg: aead: Failed to setauthsize for %s: %d\n", algo,
+ ret);
+ goto out_free_tfm;
+ }
for (i = 0; i < num_mb; ++i)
if (testmgr_alloc_buf(data[i].xbuf)) {
@@ -314,7 +309,7 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs,
for (i = 0; i < num_mb; ++i) {
data[i].req = aead_request_alloc(tfm, GFP_KERNEL);
if (!data[i].req) {
- pr_err("alg: skcipher: Failed to allocate request for %s\n",
+ pr_err("alg: aead: Failed to allocate request for %s\n",
algo);
while (i--)
aead_request_free(data[i].req);
@@ -336,15 +331,17 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs,
do {
b_size = aead_sizes;
do {
- if (*b_size + authsize > XBUFSIZE * PAGE_SIZE) {
+ int bs = round_up(*b_size, crypto_aead_blocksize(tfm));
+
+ if (bs + authsize > XBUFSIZE * PAGE_SIZE) {
pr_err("template (%u) too big for buffer (%lu)\n",
- authsize + *b_size,
+ authsize + bs,
XBUFSIZE * PAGE_SIZE);
goto out;
}
pr_info("test %u (%d bit key, %d byte blocks): ", i,
- *keysize * 8, *b_size);
+ *keysize * 8, bs);
/* Set up tfm global state, i.e. the key */
@@ -379,11 +376,11 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs,
memset(assoc, 0xff, aad_size);
sg_init_aead(cur->sg, cur->xbuf,
- *b_size + (enc ? 0 : authsize),
+ bs + (enc ? 0 : authsize),
assoc, aad_size);
sg_init_aead(cur->sgout, cur->xoutbuf,
- *b_size + (enc ? authsize : 0),
+ bs + (enc ? authsize : 0),
assoc, aad_size);
aead_request_set_ad(cur->req, aad_size);
@@ -393,30 +390,30 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs,
aead_request_set_crypt(cur->req,
cur->sgout,
cur->sg,
- *b_size, iv);
+ bs, iv);
ret = crypto_aead_encrypt(cur->req);
ret = do_one_aead_op(cur->req, ret);
if (ret) {
- pr_err("calculating auth failed failed (%d)\n",
+ pr_err("calculating auth failed (%d)\n",
ret);
break;
}
}
aead_request_set_crypt(cur->req, cur->sg,
- cur->sgout, *b_size +
+ cur->sgout, bs +
(enc ? 0 : authsize),
iv);
}
if (secs) {
- ret = test_mb_aead_jiffies(data, enc, *b_size,
+ ret = test_mb_aead_jiffies(data, enc, bs,
secs, num_mb);
cond_resched();
} else {
- ret = test_mb_aead_cycles(data, enc, *b_size,
+ ret = test_mb_aead_cycles(data, enc, bs,
num_mb);
}
@@ -468,8 +465,8 @@ static int test_aead_jiffies(struct aead_request *req, int enc,
return ret;
}
- printk("%d operations in %d seconds (%ld bytes)\n",
- bcount, secs, (long)bcount * blen);
+ pr_cont("%d operations in %d seconds (%llu bytes)\n",
+ bcount, secs, (u64)bcount * blen);
return 0;
}
@@ -533,7 +530,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
char *xbuf[XBUFSIZE];
char *xoutbuf[XBUFSIZE];
char *axbuf[XBUFSIZE];
- unsigned int *b_size;
+ const int *b_size;
unsigned int iv_len;
struct crypto_wait wait;
@@ -564,13 +561,19 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
sgout = &sg[9];
tfm = crypto_alloc_aead(algo, 0, 0);
-
if (IS_ERR(tfm)) {
pr_err("alg: aead: Failed to load transform for %s: %ld\n", algo,
PTR_ERR(tfm));
goto out_notfm;
}
+ ret = crypto_aead_setauthsize(tfm, authsize);
+ if (ret) {
+ pr_err("alg: aead: Failed to setauthsize for %s: %d\n", algo,
+ ret);
+ goto out_noreq;
+ }
+
crypto_init_wait(&wait);
printk(KERN_INFO "\ntesting speed of %s (%s) %s\n", algo,
get_driver_name(crypto_aead, tfm), e);
@@ -589,12 +592,14 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
do {
b_size = aead_sizes;
do {
+ u32 bs = round_up(*b_size, crypto_aead_blocksize(tfm));
+
assoc = axbuf[0];
memset(assoc, 0xff, aad_size);
- if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) {
+ if ((*keysize + bs) > TVMEMSIZE * PAGE_SIZE) {
pr_err("template (%u) too big for tvmem (%lu)\n",
- *keysize + *b_size,
+ *keysize + bs,
TVMEMSIZE * PAGE_SIZE);
goto out;
}
@@ -606,8 +611,13 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
break;
}
}
+
ret = crypto_aead_setkey(tfm, key, *keysize);
- ret = crypto_aead_setauthsize(tfm, authsize);
+ if (ret) {
+ pr_err("setkey() failed flags=%x: %d\n",
+ crypto_aead_get_flags(tfm), ret);
+ goto out;
+ }
iv_len = crypto_aead_ivsize(tfm);
if (iv_len)
@@ -615,22 +625,15 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
crypto_aead_clear_flags(tfm, ~0);
printk(KERN_INFO "test %u (%d bit key, %d byte blocks): ",
- i, *keysize * 8, *b_size);
-
+ i, *keysize * 8, bs);
memset(tvmem[0], 0xff, PAGE_SIZE);
- if (ret) {
- pr_err("setkey() failed flags=%x\n",
- crypto_aead_get_flags(tfm));
- goto out;
- }
-
- sg_init_aead(sg, xbuf, *b_size + (enc ? 0 : authsize),
+ sg_init_aead(sg, xbuf, bs + (enc ? 0 : authsize),
assoc, aad_size);
sg_init_aead(sgout, xoutbuf,
- *b_size + (enc ? authsize : 0), assoc,
+ bs + (enc ? authsize : 0), assoc,
aad_size);
aead_request_set_ad(req, aad_size);
@@ -643,27 +646,27 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs,
* reversed (input <-> output) to calculate it
*/
aead_request_set_crypt(req, sgout, sg,
- *b_size, iv);
+ bs, iv);
ret = do_one_aead_op(req,
crypto_aead_encrypt(req));
if (ret) {
- pr_err("calculating auth failed failed (%d)\n",
+ pr_err("calculating auth failed (%d)\n",
ret);
break;
}
}
aead_request_set_crypt(req, sg, sgout,
- *b_size + (enc ? 0 : authsize),
+ bs + (enc ? 0 : authsize),
iv);
if (secs) {
- ret = test_aead_jiffies(req, enc, *b_size,
+ ret = test_aead_jiffies(req, enc, bs,
secs);
cond_resched();
} else {
- ret = test_aead_cycles(req, enc, *b_size);
+ ret = test_aead_cycles(req, enc, bs);
}
if (ret) {
@@ -710,200 +713,6 @@ static inline int do_one_ahash_op(struct ahash_request *req, int ret)
return crypto_wait_req(ret, wait);
}
-struct test_mb_ahash_data {
- struct scatterlist sg[XBUFSIZE];
- char result[64];
- struct ahash_request *req;
- struct crypto_wait wait;
- char *xbuf[XBUFSIZE];
-};
-
-static inline int do_mult_ahash_op(struct test_mb_ahash_data *data, u32 num_mb,
- int *rc)
-{
- int i, err = 0;
-
- /* Fire up a bunch of concurrent requests */
- for (i = 0; i < num_mb; i++)
- rc[i] = crypto_ahash_digest(data[i].req);
-
- /* Wait for all requests to finish */
- for (i = 0; i < num_mb; i++) {
- rc[i] = crypto_wait_req(rc[i], &data[i].wait);
-
- if (rc[i]) {
- pr_info("concurrent request %d error %d\n", i, rc[i]);
- err = rc[i];
- }
- }
-
- return err;
-}
-
-static int test_mb_ahash_jiffies(struct test_mb_ahash_data *data, int blen,
- int secs, u32 num_mb)
-{
- unsigned long start, end;
- int bcount;
- int ret = 0;
- int *rc;
-
- rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL);
- if (!rc)
- return -ENOMEM;
-
- for (start = jiffies, end = start + secs * HZ, bcount = 0;
- time_before(jiffies, end); bcount++) {
- ret = do_mult_ahash_op(data, num_mb, rc);
- if (ret)
- goto out;
- }
-
- pr_cont("%d operations in %d seconds (%ld bytes)\n",
- bcount * num_mb, secs, (long)bcount * blen * num_mb);
-
-out:
- kfree(rc);
- return ret;
-}
-
-static int test_mb_ahash_cycles(struct test_mb_ahash_data *data, int blen,
- u32 num_mb)
-{
- unsigned long cycles = 0;
- int ret = 0;
- int i;
- int *rc;
-
- rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL);
- if (!rc)
- return -ENOMEM;
-
- /* Warm-up run. */
- for (i = 0; i < 4; i++) {
- ret = do_mult_ahash_op(data, num_mb, rc);
- if (ret)
- goto out;
- }
-
- /* The real thing. */
- for (i = 0; i < 8; i++) {
- cycles_t start, end;
-
- start = get_cycles();
- ret = do_mult_ahash_op(data, num_mb, rc);
- end = get_cycles();
-
- if (ret)
- goto out;
-
- cycles += end - start;
- }
-
- pr_cont("1 operation in %lu cycles (%d bytes)\n",
- (cycles + 4) / (8 * num_mb), blen);
-
-out:
- kfree(rc);
- return ret;
-}
-
-static void test_mb_ahash_speed(const char *algo, unsigned int secs,
- struct hash_speed *speed, u32 num_mb)
-{
- struct test_mb_ahash_data *data;
- struct crypto_ahash *tfm;
- unsigned int i, j, k;
- int ret;
-
- data = kcalloc(num_mb, sizeof(*data), GFP_KERNEL);
- if (!data)
- return;
-
- tfm = crypto_alloc_ahash(algo, 0, 0);
- if (IS_ERR(tfm)) {
- pr_err("failed to load transform for %s: %ld\n",
- algo, PTR_ERR(tfm));
- goto free_data;
- }
-
- for (i = 0; i < num_mb; ++i) {
- if (testmgr_alloc_buf(data[i].xbuf))
- goto out;
-
- crypto_init_wait(&data[i].wait);
-
- data[i].req = ahash_request_alloc(tfm, GFP_KERNEL);
- if (!data[i].req) {
- pr_err("alg: hash: Failed to allocate request for %s\n",
- algo);
- goto out;
- }
-
- ahash_request_set_callback(data[i].req, 0, crypto_req_done,
- &data[i].wait);
-
- sg_init_table(data[i].sg, XBUFSIZE);
- for (j = 0; j < XBUFSIZE; j++) {
- sg_set_buf(data[i].sg + j, data[i].xbuf[j], PAGE_SIZE);
- memset(data[i].xbuf[j], 0xff, PAGE_SIZE);
- }
- }
-
- pr_info("\ntesting speed of multibuffer %s (%s)\n", algo,
- get_driver_name(crypto_ahash, tfm));
-
- for (i = 0; speed[i].blen != 0; i++) {
- /* For some reason this only tests digests. */
- if (speed[i].blen != speed[i].plen)
- continue;
-
- if (speed[i].blen > XBUFSIZE * PAGE_SIZE) {
- pr_err("template (%u) too big for tvmem (%lu)\n",
- speed[i].blen, XBUFSIZE * PAGE_SIZE);
- goto out;
- }
-
- if (speed[i].klen)
- crypto_ahash_setkey(tfm, tvmem[0], speed[i].klen);
-
- for (k = 0; k < num_mb; k++)
- ahash_request_set_crypt(data[k].req, data[k].sg,
- data[k].result, speed[i].blen);
-
- pr_info("test%3u "
- "(%5u byte blocks,%5u bytes per update,%4u updates): ",
- i, speed[i].blen, speed[i].plen,
- speed[i].blen / speed[i].plen);
-
- if (secs) {
- ret = test_mb_ahash_jiffies(data, speed[i].blen, secs,
- num_mb);
- cond_resched();
- } else {
- ret = test_mb_ahash_cycles(data, speed[i].blen, num_mb);
- }
-
-
- if (ret) {
- pr_err("At least one hashing failed ret=%d\n", ret);
- break;
- }
- }
-
-out:
- for (k = 0; k < num_mb; ++k)
- ahash_request_free(data[k].req);
-
- for (k = 0; k < num_mb; ++k)
- testmgr_free_buf(data[k].xbuf);
-
- crypto_free_ahash(tfm);
-
-free_data:
- kfree(data);
-}
-
static int test_ahash_jiffies_digest(struct ahash_request *req, int blen,
char *out, int secs)
{
@@ -1099,8 +908,8 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs,
break;
}
- if (speed[i].klen)
- crypto_ahash_setkey(tfm, tvmem[0], speed[i].klen);
+ if (klen)
+ crypto_ahash_setkey(tfm, tvmem[0], klen);
pr_info("test%3u "
"(%5u byte blocks,%5u bytes per update,%4u updates): ",
@@ -1196,8 +1005,8 @@ static int test_mb_acipher_jiffies(struct test_mb_skcipher_data *data, int enc,
goto out;
}
- pr_cont("%d operations in %d seconds (%ld bytes)\n",
- bcount * num_mb, secs, (long)bcount * blen * num_mb);
+ pr_cont("%d operations in %d seconds (%llu bytes)\n",
+ bcount * num_mb, secs, (u64)bcount * blen * num_mb);
out:
kfree(rc);
@@ -1252,9 +1061,9 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs,
struct test_mb_skcipher_data *data;
struct crypto_skcipher *tfm;
unsigned int i, j, iv_len;
+ const int *b_size;
const char *key;
const char *e;
- u32 *b_size;
char iv[128];
int ret;
@@ -1315,14 +1124,16 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs,
do {
b_size = block_sizes;
do {
- if (*b_size > XBUFSIZE * PAGE_SIZE) {
+ u32 bs = round_up(*b_size, crypto_skcipher_blocksize(tfm));
+
+ if (bs > XBUFSIZE * PAGE_SIZE) {
pr_err("template (%u) too big for buffer (%lu)\n",
- *b_size, XBUFSIZE * PAGE_SIZE);
+ bs, XBUFSIZE * PAGE_SIZE);
goto out;
}
pr_info("test %u (%d bit key, %d byte blocks): ", i,
- *keysize * 8, *b_size);
+ *keysize * 8, bs);
/* Set up tfm global state, i.e. the key */
@@ -1352,7 +1163,7 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs,
for (j = 0; j < num_mb; ++j) {
struct test_mb_skcipher_data *cur = &data[j];
- unsigned int k = *b_size;
+ unsigned int k = bs;
unsigned int pages = DIV_ROUND_UP(k, PAGE_SIZE);
unsigned int p = 0;
@@ -1370,18 +1181,17 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs,
memset(cur->xbuf[p], 0xff, k);
skcipher_request_set_crypt(cur->req, cur->sg,
- cur->sg, *b_size,
- iv);
+ cur->sg, bs, iv);
}
if (secs) {
ret = test_mb_acipher_jiffies(data, enc,
- *b_size, secs,
+ bs, secs,
num_mb);
cond_resched();
} else {
ret = test_mb_acipher_cycles(data, enc,
- *b_size, num_mb);
+ bs, num_mb);
}
if (ret) {
@@ -1434,8 +1244,8 @@ static int test_acipher_jiffies(struct skcipher_request *req, int enc,
return ret;
}
- pr_cont("%d operations in %d seconds (%ld bytes)\n",
- bcount, secs, (long)bcount * blen);
+ pr_cont("%d operations in %d seconds (%llu bytes)\n",
+ bcount, secs, (u64)bcount * blen);
return 0;
}
@@ -1496,8 +1306,8 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
char iv[128];
struct skcipher_request *req;
struct crypto_skcipher *tfm;
+ const int *b_size;
const char *e;
- u32 *b_size;
if (enc == ENCRYPT)
e = "encryption";
@@ -1514,8 +1324,8 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
return;
}
- pr_info("\ntesting speed of async %s (%s) %s\n", algo,
- get_driver_name(crypto_skcipher, tfm), e);
+ pr_info("\ntesting speed of %s %s (%s) %s\n", async ? "async" : "sync",
+ algo, get_driver_name(crypto_skcipher, tfm), e);
req = skcipher_request_alloc(tfm, GFP_KERNEL);
if (!req) {
@@ -1532,17 +1342,18 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
b_size = block_sizes;
do {
+ u32 bs = round_up(*b_size, crypto_skcipher_blocksize(tfm));
struct scatterlist sg[TVMEMSIZE];
- if ((*keysize + *b_size) > TVMEMSIZE * PAGE_SIZE) {
+ if ((*keysize + bs) > TVMEMSIZE * PAGE_SIZE) {
pr_err("template (%u) too big for "
- "tvmem (%lu)\n", *keysize + *b_size,
+ "tvmem (%lu)\n", *keysize + bs,
TVMEMSIZE * PAGE_SIZE);
goto out_free_req;
}
pr_info("test %u (%d bit key, %d byte blocks): ", i,
- *keysize * 8, *b_size);
+ *keysize * 8, bs);
memset(tvmem[0], 0xff, PAGE_SIZE);
@@ -1564,7 +1375,7 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
goto out_free_req;
}
- k = *keysize + *b_size;
+ k = *keysize + bs;
sg_init_table(sg, DIV_ROUND_UP(k, PAGE_SIZE));
if (k > PAGE_SIZE) {
@@ -1581,22 +1392,22 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs,
sg_set_buf(sg + j, tvmem[j], k);
memset(tvmem[j], 0xff, k);
} else {
- sg_set_buf(sg, tvmem[0] + *keysize, *b_size);
+ sg_set_buf(sg, tvmem[0] + *keysize, bs);
}
iv_len = crypto_skcipher_ivsize(tfm);
if (iv_len)
memset(&iv, 0xff, iv_len);
- skcipher_request_set_crypt(req, sg, sg, *b_size, iv);
+ skcipher_request_set_crypt(req, sg, sg, bs, iv);
if (secs) {
ret = test_acipher_jiffies(req, enc,
- *b_size, secs);
+ bs, secs);
cond_resched();
} else {
ret = test_acipher_cycles(req, enc,
- *b_size);
+ bs);
}
if (ret) {
@@ -1632,18 +1443,6 @@ static void test_cipher_speed(const char *algo, int enc, unsigned int secs,
false);
}
-static void test_available(void)
-{
- const char **name = check;
-
- while (*name) {
- printk("alg %s ", *name);
- printk(crypto_has_alg(*name, 0, 0) ?
- "found\n" : "not found\n");
- name++;
- }
-}
-
static inline int tcrypt_test(const char *alg)
{
int ret;
@@ -1651,8 +1450,8 @@ static inline int tcrypt_test(const char *alg)
pr_debug("testing %s\n", alg);
ret = alg_test(alg, alg, 0, 0);
- /* non-fips algs return -EINVAL in fips mode */
- if (fips_enabled && ret == -EINVAL)
+ /* non-fips algs return -EINVAL or -ECANCELED in fips mode */
+ if (fips_enabled && (ret == -EINVAL || ret == -ECANCELED))
ret = 0;
return ret;
}
@@ -1734,6 +1533,7 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
ret += tcrypt_test("rfc3686(ctr(aes))");
ret += tcrypt_test("ofb(aes)");
ret += tcrypt_test("cfb(aes)");
+ ret += tcrypt_test("xctr(aes)");
break;
case 11:
@@ -1798,27 +1598,11 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
ret += tcrypt_test("wp256");
break;
- case 25:
- ret += tcrypt_test("ecb(tnepres)");
- break;
-
case 26:
ret += tcrypt_test("ecb(anubis)");
ret += tcrypt_test("cbc(anubis)");
break;
- case 27:
- ret += tcrypt_test("tgr192");
- break;
-
- case 28:
- ret += tcrypt_test("tgr160");
- break;
-
- case 29:
- ret += tcrypt_test("tgr128");
- break;
-
case 30:
ret += tcrypt_test("ecb(xeta)");
break;
@@ -1839,10 +1623,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
ret += tcrypt_test("sha224");
break;
- case 34:
- ret += tcrypt_test("salsa20");
- break;
-
case 35:
ret += tcrypt_test("gcm(aes)");
break;
@@ -1860,19 +1640,15 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
break;
case 39:
- ret += tcrypt_test("rmd128");
+ ret += tcrypt_test("xxhash64");
break;
case 40:
ret += tcrypt_test("rmd160");
break;
- case 41:
- ret += tcrypt_test("rmd256");
- break;
-
case 42:
- ret += tcrypt_test("rmd320");
+ ret += tcrypt_test("blake2b-512");
break;
case 43:
@@ -1919,6 +1695,22 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
ret += tcrypt_test("streebog512");
break;
+ case 55:
+ ret += tcrypt_test("gcm(sm4)");
+ break;
+
+ case 56:
+ ret += tcrypt_test("ccm(sm4)");
+ break;
+
+ case 57:
+ ret += tcrypt_test("polyval");
+ break;
+
+ case 58:
+ ret += tcrypt_test("gcm(aria)");
+ break;
+
case 100:
ret += tcrypt_test("hmac(md5)");
break;
@@ -1947,10 +1739,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
ret += tcrypt_test("xcbc(aes)");
break;
- case 107:
- ret += tcrypt_test("hmac(rmd128)");
- break;
-
case 108:
ret += tcrypt_test("hmac(rmd160)");
break;
@@ -2014,6 +1802,15 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
case 157:
ret += tcrypt_test("authenc(hmac(sha1),ecb(cipher_null))");
break;
+
+ case 158:
+ ret += tcrypt_test("cbcmac(sm4)");
+ break;
+
+ case 159:
+ ret += tcrypt_test("cmac(sm4)");
+ break;
+
case 181:
ret += tcrypt_test("authenc(hmac(sha1),cbc(des))");
break;
@@ -2047,8 +1844,15 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
case 191:
ret += tcrypt_test("ecb(sm4)");
ret += tcrypt_test("cbc(sm4)");
+ ret += tcrypt_test("cfb(sm4)");
ret += tcrypt_test("ctr(sm4)");
break;
+ case 192:
+ ret += tcrypt_test("ecb(aria)");
+ ret += tcrypt_test("cbc(aria)");
+ ret += tcrypt_test("cfb(aria)");
+ ret += tcrypt_test("ctr(aria)");
+ break;
case 200:
test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
speed_template_16_24_32);
@@ -2173,11 +1977,6 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
speed_template_32_48_64);
break;
- case 206:
- test_cipher_speed("salsa20", ENCRYPT, sec, NULL, 0,
- speed_template_16_32);
- break;
-
case 207:
test_cipher_speed("ecb(serpent)", ENCRYPT, sec, NULL, 0,
speed_template_16_32);
@@ -2310,6 +2109,10 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
speed_template_16);
test_cipher_speed("cbc(sm4)", DECRYPT, sec, NULL, 0,
speed_template_16);
+ test_cipher_speed("cfb(sm4)", ENCRYPT, sec, NULL, 0,
+ speed_template_16);
+ test_cipher_speed("cfb(sm4)", DECRYPT, sec, NULL, 0,
+ speed_template_16);
test_cipher_speed("ctr(sm4)", ENCRYPT, sec, NULL, 0,
speed_template_16);
test_cipher_speed("ctr(sm4)", DECRYPT, sec, NULL, 0,
@@ -2343,126 +2146,177 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
NULL, 0, 16, 8, speed_template_16);
break;
+ case 222:
+ test_aead_speed("gcm(sm4)", ENCRYPT, sec,
+ NULL, 0, 16, 8, speed_template_16);
+ test_aead_speed("gcm(sm4)", DECRYPT, sec,
+ NULL, 0, 16, 8, speed_template_16);
+ break;
+
+ case 223:
+ test_aead_speed("rfc4309(ccm(sm4))", ENCRYPT, sec,
+ NULL, 0, 16, 16, aead_speed_template_19);
+ test_aead_speed("rfc4309(ccm(sm4))", DECRYPT, sec,
+ NULL, 0, 16, 16, aead_speed_template_19);
+ break;
+
+ case 224:
+ test_mb_aead_speed("gcm(sm4)", ENCRYPT, sec, NULL, 0, 16, 8,
+ speed_template_16, num_mb);
+ test_mb_aead_speed("gcm(sm4)", DECRYPT, sec, NULL, 0, 16, 8,
+ speed_template_16, num_mb);
+ break;
+
+ case 225:
+ test_mb_aead_speed("rfc4309(ccm(sm4))", ENCRYPT, sec, NULL, 0,
+ 16, 16, aead_speed_template_19, num_mb);
+ test_mb_aead_speed("rfc4309(ccm(sm4))", DECRYPT, sec, NULL, 0,
+ 16, 16, aead_speed_template_19, num_mb);
+ break;
+
+ case 226:
+ test_cipher_speed("hctr2(aes)", ENCRYPT, sec, NULL,
+ 0, speed_template_32);
+ break;
+
+ case 227:
+ test_cipher_speed("ecb(aria)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("ecb(aria)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("cbc(aria)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("cbc(aria)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("cfb(aria)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("cfb(aria)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("ctr(aria)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_cipher_speed("ctr(aria)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ break;
+
+ case 228:
+ test_aead_speed("gcm(aria)", ENCRYPT, sec,
+ NULL, 0, 16, 8, speed_template_16_24_32);
+ test_aead_speed("gcm(aria)", DECRYPT, sec,
+ NULL, 0, 16, 8, speed_template_16_24_32);
+ break;
+
+ case 229:
+ test_mb_aead_speed("gcm(aria)", ENCRYPT, sec, NULL, 0, 16, 8,
+ speed_template_16, num_mb);
+ test_mb_aead_speed("gcm(aria)", DECRYPT, sec, NULL, 0, 16, 8,
+ speed_template_16, num_mb);
+ break;
+
case 300:
if (alg) {
test_hash_speed(alg, sec, generic_hash_speed_template);
break;
}
- /* fall through */
+ fallthrough;
case 301:
test_hash_speed("md4", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 302:
test_hash_speed("md5", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 303:
test_hash_speed("sha1", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 304:
test_hash_speed("sha256", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 305:
test_hash_speed("sha384", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 306:
test_hash_speed("sha512", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 307:
test_hash_speed("wp256", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 308:
test_hash_speed("wp384", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 309:
test_hash_speed("wp512", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
- case 310:
- test_hash_speed("tgr128", sec, generic_hash_speed_template);
- if (mode > 300 && mode < 400) break;
- /* fall through */
- case 311:
- test_hash_speed("tgr160", sec, generic_hash_speed_template);
- if (mode > 300 && mode < 400) break;
- /* fall through */
- case 312:
- test_hash_speed("tgr192", sec, generic_hash_speed_template);
- if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 313:
test_hash_speed("sha224", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 314:
- test_hash_speed("rmd128", sec, generic_hash_speed_template);
+ test_hash_speed("xxhash64", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 315:
test_hash_speed("rmd160", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
- case 316:
- test_hash_speed("rmd256", sec, generic_hash_speed_template);
- if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 317:
- test_hash_speed("rmd320", sec, generic_hash_speed_template);
+ test_hash_speed("blake2b-512", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 318:
- test_hash_speed("ghash-generic", sec, hash_speed_template_16);
+ klen = 16;
+ test_hash_speed("ghash", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 319:
test_hash_speed("crc32c", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 320:
test_hash_speed("crct10dif", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 321:
test_hash_speed("poly1305", sec, poly1305_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 322:
test_hash_speed("sha3-224", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 323:
test_hash_speed("sha3-256", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 324:
test_hash_speed("sha3-384", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 325:
test_hash_speed("sha3-512", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 326:
test_hash_speed("sm3", sec, generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 327:
test_hash_speed("streebog256", sec,
generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 328:
test_hash_speed("streebog512", sec,
generic_hash_speed_template);
if (mode > 300 && mode < 400) break;
- /* fall through */
+ fallthrough;
case 399:
break;
@@ -2471,121 +2325,79 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
test_ahash_speed(alg, sec, generic_hash_speed_template);
break;
}
- /* fall through */
+ fallthrough;
case 401:
test_ahash_speed("md4", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 402:
test_ahash_speed("md5", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 403:
test_ahash_speed("sha1", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 404:
test_ahash_speed("sha256", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 405:
test_ahash_speed("sha384", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 406:
test_ahash_speed("sha512", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 407:
test_ahash_speed("wp256", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 408:
test_ahash_speed("wp384", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 409:
test_ahash_speed("wp512", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
- case 410:
- test_ahash_speed("tgr128", sec, generic_hash_speed_template);
- if (mode > 400 && mode < 500) break;
- /* fall through */
- case 411:
- test_ahash_speed("tgr160", sec, generic_hash_speed_template);
- if (mode > 400 && mode < 500) break;
- /* fall through */
- case 412:
- test_ahash_speed("tgr192", sec, generic_hash_speed_template);
- if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 413:
test_ahash_speed("sha224", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 414:
- test_ahash_speed("rmd128", sec, generic_hash_speed_template);
+ test_ahash_speed("xxhash64", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 415:
test_ahash_speed("rmd160", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
- case 416:
- test_ahash_speed("rmd256", sec, generic_hash_speed_template);
- if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 417:
- test_ahash_speed("rmd320", sec, generic_hash_speed_template);
+ test_ahash_speed("blake2b-512", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 418:
test_ahash_speed("sha3-224", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 419:
test_ahash_speed("sha3-256", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 420:
test_ahash_speed("sha3-384", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 421:
test_ahash_speed("sha3-512", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 422:
- test_mb_ahash_speed("sha1", sec, generic_hash_speed_template,
- num_mb);
- if (mode > 400 && mode < 500) break;
- /* fall through */
- case 423:
- test_mb_ahash_speed("sha256", sec, generic_hash_speed_template,
- num_mb);
- if (mode > 400 && mode < 500) break;
- /* fall through */
- case 424:
- test_mb_ahash_speed("sha512", sec, generic_hash_speed_template,
- num_mb);
+ test_ahash_speed("sm3", sec, generic_hash_speed_template);
if (mode > 400 && mode < 500) break;
- /* fall through */
- case 425:
- test_mb_ahash_speed("sm3", sec, generic_hash_speed_template,
- num_mb);
- if (mode > 400 && mode < 500) break;
- /* fall through */
- case 426:
- test_mb_ahash_speed("streebog256", sec,
- generic_hash_speed_template, num_mb);
- if (mode > 400 && mode < 500) break;
- /* fall through */
- case 427:
- test_mb_ahash_speed("streebog512", sec,
- generic_hash_speed_template, num_mb);
- if (mode > 400 && mode < 500) break;
- /* fall through */
+ fallthrough;
case 499:
break;
@@ -2801,6 +2613,36 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
speed_template_8_32);
break;
+ case 518:
+ test_acipher_speed("ecb(sm4)", ENCRYPT, sec, NULL, 0,
+ speed_template_16);
+ test_acipher_speed("ecb(sm4)", DECRYPT, sec, NULL, 0,
+ speed_template_16);
+ test_acipher_speed("cbc(sm4)", ENCRYPT, sec, NULL, 0,
+ speed_template_16);
+ test_acipher_speed("cbc(sm4)", DECRYPT, sec, NULL, 0,
+ speed_template_16);
+ test_acipher_speed("cfb(sm4)", ENCRYPT, sec, NULL, 0,
+ speed_template_16);
+ test_acipher_speed("cfb(sm4)", DECRYPT, sec, NULL, 0,
+ speed_template_16);
+ test_acipher_speed("ctr(sm4)", ENCRYPT, sec, NULL, 0,
+ speed_template_16);
+ test_acipher_speed("ctr(sm4)", DECRYPT, sec, NULL, 0,
+ speed_template_16);
+ break;
+
+ case 519:
+ test_acipher_speed("ecb(aria)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_acipher_speed("ecb(aria)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_acipher_speed("ctr(aria)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ test_acipher_speed("ctr(aria)", DECRYPT, sec, NULL, 0,
+ speed_template_16_24_32);
+ break;
+
case 600:
test_mb_skcipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0,
speed_template_16_24_32, num_mb);
@@ -3013,9 +2855,17 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
speed_template_8_32, num_mb);
break;
- case 1000:
- test_available();
+ case 610:
+ test_mb_skcipher_speed("ecb(aria)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32, num_mb);
+ test_mb_skcipher_speed("ecb(aria)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32, num_mb);
+ test_mb_skcipher_speed("ctr(aria)", ENCRYPT, sec, NULL, 0,
+ speed_template_16_32, num_mb);
+ test_mb_skcipher_speed("ctr(aria)", DECRYPT, sec, NULL, 0,
+ speed_template_16_32, num_mb);
break;
+
}
return ret;
@@ -3064,7 +2914,7 @@ err_free_tv:
*/
static void __exit tcrypt_mod_fini(void) { }
-subsys_initcall(tcrypt_mod_init);
+late_initcall(tcrypt_mod_init);
module_exit(tcrypt_mod_fini);
module_param(alg, charp, 0);
@@ -3076,6 +2926,8 @@ MODULE_PARM_DESC(sec, "Length in seconds of speed tests "
"(defaults to zero which uses CPU cycles instead)");
module_param(num_mb, uint, 0000);
MODULE_PARM_DESC(num_mb, "Number of concurrent requests to be used in mb speed tests (defaults to 8)");
+module_param(klen, uint, 0);
+MODULE_PARM_DESC(klen, "Key length (defaults to 0)");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Quick & dirty crypto testing module");
diff --git a/crypto/tcrypt.h b/crypto/tcrypt.h
index 7e5fea811670..9f654677172a 100644
--- a/crypto/tcrypt.h
+++ b/crypto/tcrypt.h
@@ -25,7 +25,6 @@ struct aead_speed_template {
struct hash_speed {
unsigned int blen; /* buffer length */
unsigned int plen; /* per-update length */
- unsigned int klen; /* key length */
};
/*
@@ -97,34 +96,6 @@ static struct hash_speed generic_hash_speed_template[] = {
{ .blen = 0, .plen = 0, }
};
-static struct hash_speed hash_speed_template_16[] = {
- { .blen = 16, .plen = 16, .klen = 16, },
- { .blen = 64, .plen = 16, .klen = 16, },
- { .blen = 64, .plen = 64, .klen = 16, },
- { .blen = 256, .plen = 16, .klen = 16, },
- { .blen = 256, .plen = 64, .klen = 16, },
- { .blen = 256, .plen = 256, .klen = 16, },
- { .blen = 1024, .plen = 16, .klen = 16, },
- { .blen = 1024, .plen = 256, .klen = 16, },
- { .blen = 1024, .plen = 1024, .klen = 16, },
- { .blen = 2048, .plen = 16, .klen = 16, },
- { .blen = 2048, .plen = 256, .klen = 16, },
- { .blen = 2048, .plen = 1024, .klen = 16, },
- { .blen = 2048, .plen = 2048, .klen = 16, },
- { .blen = 4096, .plen = 16, .klen = 16, },
- { .blen = 4096, .plen = 256, .klen = 16, },
- { .blen = 4096, .plen = 1024, .klen = 16, },
- { .blen = 4096, .plen = 4096, .klen = 16, },
- { .blen = 8192, .plen = 16, .klen = 16, },
- { .blen = 8192, .plen = 256, .klen = 16, },
- { .blen = 8192, .plen = 1024, .klen = 16, },
- { .blen = 8192, .plen = 4096, .klen = 16, },
- { .blen = 8192, .plen = 8192, .klen = 16, },
-
- /* End marker */
- { .blen = 0, .plen = 0, .klen = 0, }
-};
-
static struct hash_speed poly1305_speed_template[] = {
{ .blen = 96, .plen = 16, },
{ .blen = 96, .plen = 32, },
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index ccb3d60729fc..bcd059caa1c8 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -27,15 +27,19 @@
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/uio.h>
#include <crypto/rng.h>
#include <crypto/drbg.h>
#include <crypto/akcipher.h>
#include <crypto/kpp.h>
#include <crypto/acompress.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/simd.h>
#include "internal.h"
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
+
static bool notests;
module_param(notests, bool, 0644);
MODULE_PARM_DESC(notests, "disable crypto self-tests");
@@ -51,9 +55,6 @@ MODULE_PARM_DESC(noextratests, "disable expensive crypto self-tests");
static unsigned int fuzz_iterations = 100;
module_param(fuzz_iterations, uint, 0644);
MODULE_PARM_DESC(fuzz_iterations, "number of fuzz test iterations");
-
-DEFINE_PER_CPU(bool, crypto_simd_disabled_for_test);
-EXPORT_PER_CPU_SYMBOL_GPL(crypto_simd_disabled_for_test);
#endif
#ifdef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS
@@ -91,10 +92,11 @@ struct aead_test_suite {
unsigned int einval_allowed : 1;
/*
- * Set if the algorithm intentionally ignores the last 8 bytes of the
- * AAD buffer during decryption.
+ * Set if this algorithm requires that the IV be located at the end of
+ * the AAD buffer, in addition to being given in the normal way. The
+ * behavior when the two IV copies differ is implementation-defined.
*/
- unsigned int esp_aad : 1;
+ unsigned int aad_iv : 1;
};
struct cipher_test_suite {
@@ -230,6 +232,20 @@ enum finalization_type {
FINALIZATION_TYPE_DIGEST, /* use digest() */
};
+/*
+ * Whether the crypto operation will occur in-place, and if so whether the
+ * source and destination scatterlist pointers will coincide (req->src ==
+ * req->dst), or whether they'll merely point to two separate scatterlists
+ * (req->src != req->dst) that reference the same underlying memory.
+ *
+ * This is only relevant for algorithm types that support in-place operation.
+ */
+enum inplace_mode {
+ OUT_OF_PLACE,
+ INPLACE_ONE_SGLIST,
+ INPLACE_TWO_SGLISTS,
+};
+
#define TEST_SG_TOTAL 10000
/**
@@ -263,7 +279,7 @@ struct test_sg_division {
* crypto test vector can be tested.
*
* @name: name of this config, logged for debugging purposes if a test fails
- * @inplace: operate on the data in-place, if applicable for the algorithm type?
+ * @inplace_mode: whether and how to operate on the data in-place, if applicable
* @req_flags: extra request_flags, e.g. CRYPTO_TFM_REQ_MAY_SLEEP
* @src_divs: description of how to arrange the source scatterlist
* @dst_divs: description of how to arrange the dst scatterlist, if applicable
@@ -280,7 +296,7 @@ struct test_sg_division {
*/
struct testvec_config {
const char *name;
- bool inplace;
+ enum inplace_mode inplace_mode;
u32 req_flags;
struct test_sg_division src_divs[XBUFSIZE];
struct test_sg_division dst_divs[XBUFSIZE];
@@ -305,11 +321,16 @@ struct testvec_config {
/* Configs for skciphers and aeads */
static const struct testvec_config default_cipher_testvec_configs[] = {
{
- .name = "in-place",
- .inplace = true,
+ .name = "in-place (one sglist)",
+ .inplace_mode = INPLACE_ONE_SGLIST,
+ .src_divs = { { .proportion_of_total = 10000 } },
+ }, {
+ .name = "in-place (two sglists)",
+ .inplace_mode = INPLACE_TWO_SGLISTS,
.src_divs = { { .proportion_of_total = 10000 } },
}, {
.name = "out-of-place",
+ .inplace_mode = OUT_OF_PLACE,
.src_divs = { { .proportion_of_total = 10000 } },
}, {
.name = "unaligned buffer, offset=1",
@@ -347,7 +368,7 @@ static const struct testvec_config default_cipher_testvec_configs[] = {
.key_offset = 3,
}, {
.name = "misaligned splits crossing pages, inplace",
- .inplace = true,
+ .inplace_mode = INPLACE_ONE_SGLIST,
.src_divs = {
{
.proportion_of_total = 7500,
@@ -747,18 +768,39 @@ static int build_cipher_test_sglists(struct cipher_test_sglists *tsgls,
iov_iter_kvec(&input, WRITE, inputs, nr_inputs, src_total_len);
err = build_test_sglist(&tsgls->src, cfg->src_divs, alignmask,
- cfg->inplace ?
+ cfg->inplace_mode != OUT_OF_PLACE ?
max(dst_total_len, src_total_len) :
src_total_len,
&input, NULL);
if (err)
return err;
- if (cfg->inplace) {
+ /*
+ * In-place crypto operations can use the same scatterlist for both the
+ * source and destination (req->src == req->dst), or can use separate
+ * scatterlists (req->src != req->dst) which point to the same
+ * underlying memory. Make sure to test both cases.
+ */
+ if (cfg->inplace_mode == INPLACE_ONE_SGLIST) {
tsgls->dst.sgl_ptr = tsgls->src.sgl;
tsgls->dst.nents = tsgls->src.nents;
return 0;
}
+ if (cfg->inplace_mode == INPLACE_TWO_SGLISTS) {
+ /*
+ * For now we keep it simple and only test the case where the
+ * two scatterlists have identical entries, rather than
+ * different entries that split up the same memory differently.
+ */
+ memcpy(tsgls->dst.sgl, tsgls->src.sgl,
+ tsgls->src.nents * sizeof(tsgls->src.sgl[0]));
+ memcpy(tsgls->dst.sgl_saved, tsgls->src.sgl,
+ tsgls->src.nents * sizeof(tsgls->src.sgl[0]));
+ tsgls->dst.sgl_ptr = tsgls->dst.sgl;
+ tsgls->dst.nents = tsgls->src.nents;
+ return 0;
+ }
+ /* Out of place */
return build_test_sglist(&tsgls->dst,
cfg->dst_divs[0].proportion_of_total ?
cfg->dst_divs : cfg->src_divs,
@@ -813,9 +855,9 @@ static int prepare_keybuf(const u8 *key, unsigned int ksize,
/* Generate a random length in range [0, max_len], but prefer smaller values */
static unsigned int generate_random_length(unsigned int max_len)
{
- unsigned int len = prandom_u32() % (max_len + 1);
+ unsigned int len = prandom_u32_max(max_len + 1);
- switch (prandom_u32() % 4) {
+ switch (prandom_u32_max(4)) {
case 0:
return len % 64;
case 1:
@@ -832,14 +874,14 @@ static void flip_random_bit(u8 *buf, size_t size)
{
size_t bitpos;
- bitpos = prandom_u32() % (size * 8);
+ bitpos = prandom_u32_max(size * 8);
buf[bitpos / 8] ^= 1 << (bitpos % 8);
}
/* Flip a random byte in the given nonempty data buffer */
static void flip_random_byte(u8 *buf, size_t size)
{
- buf[prandom_u32() % size] ^= 0xff;
+ buf[prandom_u32_max(size)] ^= 0xff;
}
/* Sometimes make some random changes to the given nonempty data buffer */
@@ -849,15 +891,15 @@ static void mutate_buffer(u8 *buf, size_t size)
size_t i;
/* Sometimes flip some bits */
- if (prandom_u32() % 4 == 0) {
- num_flips = min_t(size_t, 1 << (prandom_u32() % 8), size * 8);
+ if (prandom_u32_max(4) == 0) {
+ num_flips = min_t(size_t, 1 << prandom_u32_max(8), size * 8);
for (i = 0; i < num_flips; i++)
flip_random_bit(buf, size);
}
/* Sometimes flip some bytes */
- if (prandom_u32() % 4 == 0) {
- num_flips = min_t(size_t, 1 << (prandom_u32() % 8), size);
+ if (prandom_u32_max(4) == 0) {
+ num_flips = min_t(size_t, 1 << prandom_u32_max(8), size);
for (i = 0; i < num_flips; i++)
flip_random_byte(buf, size);
}
@@ -873,11 +915,11 @@ static void generate_random_bytes(u8 *buf, size_t count)
if (count == 0)
return;
- switch (prandom_u32() % 8) { /* Choose a generation strategy */
+ switch (prandom_u32_max(8)) { /* Choose a generation strategy */
case 0:
case 1:
/* All the same byte, plus optional mutations */
- switch (prandom_u32() % 4) {
+ switch (prandom_u32_max(4)) {
case 0:
b = 0x00;
break;
@@ -885,7 +927,7 @@ static void generate_random_bytes(u8 *buf, size_t count)
b = 0xff;
break;
default:
- b = (u8)prandom_u32();
+ b = get_random_u8();
break;
}
memset(buf, b, count);
@@ -893,8 +935,8 @@ static void generate_random_bytes(u8 *buf, size_t count)
break;
case 2:
/* Ascending or descending bytes, plus optional mutations */
- increment = (u8)prandom_u32();
- b = (u8)prandom_u32();
+ increment = get_random_u8();
+ b = get_random_u8();
for (i = 0; i < count; i++, b += increment)
buf[i] = b;
mutate_buffer(buf, count);
@@ -902,7 +944,7 @@ static void generate_random_bytes(u8 *buf, size_t count)
default:
/* Fully random bytes */
for (i = 0; i < count; i++)
- buf[i] = (u8)prandom_u32();
+ buf[i] = get_random_u8();
}
}
@@ -917,24 +959,24 @@ static char *generate_random_sgl_divisions(struct test_sg_division *divs,
unsigned int this_len;
const char *flushtype_str;
- if (div == &divs[max_divs - 1] || prandom_u32() % 2 == 0)
+ if (div == &divs[max_divs - 1] || prandom_u32_max(2) == 0)
this_len = remaining;
else
- this_len = 1 + (prandom_u32() % remaining);
+ this_len = 1 + prandom_u32_max(remaining);
div->proportion_of_total = this_len;
- if (prandom_u32() % 4 == 0)
- div->offset = (PAGE_SIZE - 128) + (prandom_u32() % 128);
- else if (prandom_u32() % 2 == 0)
- div->offset = prandom_u32() % 32;
+ if (prandom_u32_max(4) == 0)
+ div->offset = (PAGE_SIZE - 128) + prandom_u32_max(128);
+ else if (prandom_u32_max(2) == 0)
+ div->offset = prandom_u32_max(32);
else
- div->offset = prandom_u32() % PAGE_SIZE;
- if (prandom_u32() % 8 == 0)
+ div->offset = prandom_u32_max(PAGE_SIZE);
+ if (prandom_u32_max(8) == 0)
div->offset_relative_to_alignmask = true;
div->flush_type = FLUSH_TYPE_NONE;
if (gen_flushes) {
- switch (prandom_u32() % 4) {
+ switch (prandom_u32_max(4)) {
case 0:
div->flush_type = FLUSH_TYPE_REIMPORT;
break;
@@ -946,7 +988,7 @@ static char *generate_random_sgl_divisions(struct test_sg_division *divs,
if (div->flush_type != FLUSH_TYPE_NONE &&
!(req_flags & CRYPTO_TFM_REQ_MAY_SLEEP) &&
- prandom_u32() % 2 == 0)
+ prandom_u32_max(2) == 0)
div->nosimd = true;
switch (div->flush_type) {
@@ -993,17 +1035,27 @@ static void generate_random_testvec_config(struct testvec_config *cfg,
p += scnprintf(p, end - p, "random:");
- if (prandom_u32() % 2 == 0) {
- cfg->inplace = true;
- p += scnprintf(p, end - p, " inplace");
+ switch (prandom_u32_max(4)) {
+ case 0:
+ case 1:
+ cfg->inplace_mode = OUT_OF_PLACE;
+ break;
+ case 2:
+ cfg->inplace_mode = INPLACE_ONE_SGLIST;
+ p += scnprintf(p, end - p, " inplace_one_sglist");
+ break;
+ default:
+ cfg->inplace_mode = INPLACE_TWO_SGLISTS;
+ p += scnprintf(p, end - p, " inplace_two_sglists");
+ break;
}
- if (prandom_u32() % 2 == 0) {
+ if (prandom_u32_max(2) == 0) {
cfg->req_flags |= CRYPTO_TFM_REQ_MAY_SLEEP;
p += scnprintf(p, end - p, " may_sleep");
}
- switch (prandom_u32() % 4) {
+ switch (prandom_u32_max(4)) {
case 0:
cfg->finalization_type = FINALIZATION_TYPE_FINAL;
p += scnprintf(p, end - p, " use_final");
@@ -1019,7 +1071,7 @@ static void generate_random_testvec_config(struct testvec_config *cfg,
}
if (!(cfg->req_flags & CRYPTO_TFM_REQ_MAY_SLEEP) &&
- prandom_u32() % 2 == 0) {
+ prandom_u32_max(2) == 0) {
cfg->nosimd = true;
p += scnprintf(p, end - p, " nosimd");
}
@@ -1032,7 +1084,7 @@ static void generate_random_testvec_config(struct testvec_config *cfg,
cfg->req_flags);
p += scnprintf(p, end - p, "]");
- if (!cfg->inplace && prandom_u32() % 2 == 0) {
+ if (cfg->inplace_mode == OUT_OF_PLACE && prandom_u32_max(2) == 0) {
p += scnprintf(p, end - p, " dst_divs=[");
p = generate_random_sgl_divisions(cfg->dst_divs,
ARRAY_SIZE(cfg->dst_divs),
@@ -1041,13 +1093,13 @@ static void generate_random_testvec_config(struct testvec_config *cfg,
p += scnprintf(p, end - p, "]");
}
- if (prandom_u32() % 2 == 0) {
- cfg->iv_offset = 1 + (prandom_u32() % MAX_ALGAPI_ALIGNMASK);
+ if (prandom_u32_max(2) == 0) {
+ cfg->iv_offset = 1 + prandom_u32_max(MAX_ALGAPI_ALIGNMASK);
p += scnprintf(p, end - p, " iv_offset=%u", cfg->iv_offset);
}
- if (prandom_u32() % 2 == 0) {
- cfg->key_offset = 1 + (prandom_u32() % MAX_ALGAPI_ALIGNMASK);
+ if (prandom_u32_max(2) == 0) {
+ cfg->key_offset = 1 + prandom_u32_max(MAX_ALGAPI_ALIGNMASK);
p += scnprintf(p, end - p, " key_offset=%u", cfg->key_offset);
}
@@ -1056,14 +1108,14 @@ static void generate_random_testvec_config(struct testvec_config *cfg,
static void crypto_disable_simd_for_test(void)
{
- preempt_disable();
+ migrate_disable();
__this_cpu_write(crypto_simd_disabled_for_test, true);
}
static void crypto_reenable_simd_for_test(void)
{
__this_cpu_write(crypto_simd_disabled_for_test, false);
- preempt_enable();
+ migrate_enable();
}
/*
@@ -1163,14 +1215,8 @@ static inline int check_shash_op(const char *op, int err,
return err;
}
-static inline const void *sg_data(struct scatterlist *sg)
-{
- return page_address(sg_page(sg)) + sg->offset;
-}
-
/* Test one hash test vector in one configuration, using the shash API */
-static int test_shash_vec_cfg(const char *driver,
- const struct hash_testvec *vec,
+static int test_shash_vec_cfg(const struct hash_testvec *vec,
const char *vec_name,
const struct testvec_config *cfg,
struct shash_desc *desc,
@@ -1181,6 +1227,7 @@ static int test_shash_vec_cfg(const char *driver,
const unsigned int alignmask = crypto_shash_alignmask(tfm);
const unsigned int digestsize = crypto_shash_digestsize(tfm);
const unsigned int statesize = crypto_shash_statesize(tfm);
+ const char *driver = crypto_shash_driver_name(tfm);
const struct test_sg_division *divs[XBUFSIZE];
unsigned int i;
u8 result[HASH_MAX_DIGESTSIZE + TESTMGR_POISON_LEN];
@@ -1225,7 +1272,7 @@ static int test_shash_vec_cfg(const char *driver,
return 0;
if (cfg->nosimd)
crypto_disable_simd_for_test();
- err = crypto_shash_digest(desc, sg_data(&tsgl->sgl[0]),
+ err = crypto_shash_digest(desc, sg_virt(&tsgl->sgl[0]),
tsgl->sgl[0].length, result);
if (cfg->nosimd)
crypto_reenable_simd_for_test();
@@ -1261,7 +1308,7 @@ static int test_shash_vec_cfg(const char *driver,
cfg->finalization_type == FINALIZATION_TYPE_FINUP) {
if (divs[i]->nosimd)
crypto_disable_simd_for_test();
- err = crypto_shash_finup(desc, sg_data(&tsgl->sgl[i]),
+ err = crypto_shash_finup(desc, sg_virt(&tsgl->sgl[i]),
tsgl->sgl[i].length, result);
if (divs[i]->nosimd)
crypto_reenable_simd_for_test();
@@ -1273,7 +1320,7 @@ static int test_shash_vec_cfg(const char *driver,
}
if (divs[i]->nosimd)
crypto_disable_simd_for_test();
- err = crypto_shash_update(desc, sg_data(&tsgl->sgl[i]),
+ err = crypto_shash_update(desc, sg_virt(&tsgl->sgl[i]),
tsgl->sgl[i].length);
if (divs[i]->nosimd)
crypto_reenable_simd_for_test();
@@ -1353,8 +1400,7 @@ static int check_nonfinal_ahash_op(const char *op, int err,
}
/* Test one hash test vector in one configuration, using the ahash API */
-static int test_ahash_vec_cfg(const char *driver,
- const struct hash_testvec *vec,
+static int test_ahash_vec_cfg(const struct hash_testvec *vec,
const char *vec_name,
const struct testvec_config *cfg,
struct ahash_request *req,
@@ -1365,6 +1411,7 @@ static int test_ahash_vec_cfg(const char *driver,
const unsigned int alignmask = crypto_ahash_alignmask(tfm);
const unsigned int digestsize = crypto_ahash_digestsize(tfm);
const unsigned int statesize = crypto_ahash_statesize(tfm);
+ const char *driver = crypto_ahash_driver_name(tfm);
const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags;
const struct test_sg_division *divs[XBUFSIZE];
DECLARE_CRYPTO_WAIT(wait);
@@ -1519,8 +1566,7 @@ result_ready:
driver, cfg);
}
-static int test_hash_vec_cfg(const char *driver,
- const struct hash_testvec *vec,
+static int test_hash_vec_cfg(const struct hash_testvec *vec,
const char *vec_name,
const struct testvec_config *cfg,
struct ahash_request *req,
@@ -1537,20 +1583,18 @@ static int test_hash_vec_cfg(const char *driver,
*/
if (desc) {
- err = test_shash_vec_cfg(driver, vec, vec_name, cfg, desc, tsgl,
+ err = test_shash_vec_cfg(vec, vec_name, cfg, desc, tsgl,
hashstate);
if (err)
return err;
}
- return test_ahash_vec_cfg(driver, vec, vec_name, cfg, req, tsgl,
- hashstate);
+ return test_ahash_vec_cfg(vec, vec_name, cfg, req, tsgl, hashstate);
}
-static int test_hash_vec(const char *driver, const struct hash_testvec *vec,
- unsigned int vec_num, struct ahash_request *req,
- struct shash_desc *desc, struct test_sglist *tsgl,
- u8 *hashstate)
+static int test_hash_vec(const struct hash_testvec *vec, unsigned int vec_num,
+ struct ahash_request *req, struct shash_desc *desc,
+ struct test_sglist *tsgl, u8 *hashstate)
{
char vec_name[16];
unsigned int i;
@@ -1559,7 +1603,7 @@ static int test_hash_vec(const char *driver, const struct hash_testvec *vec,
sprintf(vec_name, "%u", vec_num);
for (i = 0; i < ARRAY_SIZE(default_hash_testvec_configs); i++) {
- err = test_hash_vec_cfg(driver, vec, vec_name,
+ err = test_hash_vec_cfg(vec, vec_name,
&default_hash_testvec_configs[i],
req, desc, tsgl, hashstate);
if (err)
@@ -1574,7 +1618,7 @@ static int test_hash_vec(const char *driver, const struct hash_testvec *vec,
for (i = 0; i < fuzz_iterations; i++) {
generate_random_testvec_config(&cfg, cfgname,
sizeof(cfgname));
- err = test_hash_vec_cfg(driver, vec, vec_name, &cfg,
+ err = test_hash_vec_cfg(vec, vec_name, &cfg,
req, desc, tsgl, hashstate);
if (err)
return err;
@@ -1608,8 +1652,8 @@ static void generate_random_hash_testvec(struct shash_desc *desc,
vec->ksize = 0;
if (maxkeysize) {
vec->ksize = maxkeysize;
- if (prandom_u32() % 4 == 0)
- vec->ksize = 1 + (prandom_u32() % maxkeysize);
+ if (prandom_u32_max(4) == 0)
+ vec->ksize = 1 + prandom_u32_max(maxkeysize);
generate_random_bytes((u8 *)vec->key, vec->ksize);
vec->setkey_error = crypto_shash_setkey(desc->tfm, vec->key,
@@ -1631,8 +1675,7 @@ done:
* Test the hash algorithm represented by @req against the corresponding generic
* implementation, if one is available.
*/
-static int test_hash_vs_generic_impl(const char *driver,
- const char *generic_driver,
+static int test_hash_vs_generic_impl(const char *generic_driver,
unsigned int maxkeysize,
struct ahash_request *req,
struct shash_desc *desc,
@@ -1644,6 +1687,7 @@ static int test_hash_vs_generic_impl(const char *driver,
const unsigned int blocksize = crypto_ahash_blocksize(tfm);
const unsigned int maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN;
const char *algname = crypto_hash_alg_common(tfm)->base.cra_name;
+ const char *driver = crypto_ahash_driver_name(tfm);
char _generic_driver[CRYPTO_MAX_ALG_NAME];
struct crypto_shash *generic_tfm = NULL;
struct shash_desc *generic_desc = NULL;
@@ -1730,7 +1774,7 @@ static int test_hash_vs_generic_impl(const char *driver,
vec_name, sizeof(vec_name));
generate_random_testvec_config(cfg, cfgname, sizeof(cfgname));
- err = test_hash_vec_cfg(driver, &vec, vec_name, cfg,
+ err = test_hash_vec_cfg(&vec, vec_name, cfg,
req, desc, tsgl, hashstate);
if (err)
goto out;
@@ -1743,12 +1787,11 @@ out:
kfree(vec.plaintext);
kfree(vec.digest);
crypto_free_shash(generic_tfm);
- kzfree(generic_desc);
+ kfree_sensitive(generic_desc);
return err;
}
#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
-static int test_hash_vs_generic_impl(const char *driver,
- const char *generic_driver,
+static int test_hash_vs_generic_impl(const char *generic_driver,
unsigned int maxkeysize,
struct ahash_request *req,
struct shash_desc *desc,
@@ -1818,6 +1861,7 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
driver, PTR_ERR(atfm));
return PTR_ERR(atfm);
}
+ driver = crypto_ahash_driver_name(atfm);
req = ahash_request_alloc(atfm, GFP_KERNEL);
if (!req) {
@@ -1857,13 +1901,15 @@ static int __alg_test_hash(const struct hash_testvec *vecs,
}
for (i = 0; i < num_vecs; i++) {
- err = test_hash_vec(driver, &vecs[i], i, req, desc, tsgl,
- hashstate);
+ if (fips_enabled && vecs[i].fips_skip)
+ continue;
+
+ err = test_hash_vec(&vecs[i], i, req, desc, tsgl, hashstate);
if (err)
goto out;
cond_resched();
}
- err = test_hash_vs_generic_impl(driver, generic_driver, maxkeysize, req,
+ err = test_hash_vs_generic_impl(generic_driver, maxkeysize, req,
desc, tsgl, hashstate);
out:
kfree(hashstate);
@@ -1921,8 +1967,7 @@ static int alg_test_hash(const struct alg_test_desc *desc, const char *driver,
return err;
}
-static int test_aead_vec_cfg(const char *driver, int enc,
- const struct aead_testvec *vec,
+static int test_aead_vec_cfg(int enc, const struct aead_testvec *vec,
const char *vec_name,
const struct testvec_config *cfg,
struct aead_request *req,
@@ -1932,6 +1977,7 @@ static int test_aead_vec_cfg(const char *driver, int enc,
const unsigned int alignmask = crypto_aead_alignmask(tfm);
const unsigned int ivsize = crypto_aead_ivsize(tfm);
const unsigned int authsize = vec->clen - vec->plen;
+ const char *driver = crypto_aead_driver_name(tfm);
const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags;
const char *op = enc ? "encryption" : "decryption";
DECLARE_CRYPTO_WAIT(wait);
@@ -2089,7 +2135,8 @@ static int test_aead_vec_cfg(const char *driver, int enc,
/* Check for the correct output (ciphertext or plaintext) */
err = verify_correct_output(&tsgls->dst, enc ? vec->ctext : vec->ptext,
enc ? vec->clen : vec->plen,
- vec->alen, enc || !cfg->inplace);
+ vec->alen,
+ enc || cfg->inplace_mode == OUT_OF_PLACE);
if (err == -EOVERFLOW) {
pr_err("alg: aead: %s %s overran dst buffer on test vector %s, cfg=\"%s\"\n",
driver, op, vec_name, cfg->name);
@@ -2104,9 +2151,8 @@ static int test_aead_vec_cfg(const char *driver, int enc,
return 0;
}
-static int test_aead_vec(const char *driver, int enc,
- const struct aead_testvec *vec, unsigned int vec_num,
- struct aead_request *req,
+static int test_aead_vec(int enc, const struct aead_testvec *vec,
+ unsigned int vec_num, struct aead_request *req,
struct cipher_test_sglists *tsgls)
{
char vec_name[16];
@@ -2119,7 +2165,7 @@ static int test_aead_vec(const char *driver, int enc,
sprintf(vec_name, "%u", vec_num);
for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) {
- err = test_aead_vec_cfg(driver, enc, vec, vec_name,
+ err = test_aead_vec_cfg(enc, vec, vec_name,
&default_cipher_testvec_configs[i],
req, tsgls);
if (err)
@@ -2134,7 +2180,7 @@ static int test_aead_vec(const char *driver, int enc,
for (i = 0; i < fuzz_iterations; i++) {
generate_random_testvec_config(&cfg, cfgname,
sizeof(cfgname));
- err = test_aead_vec_cfg(driver, enc, vec, vec_name,
+ err = test_aead_vec_cfg(enc, vec, vec_name,
&cfg, req, tsgls);
if (err)
return err;
@@ -2150,7 +2196,6 @@ static int test_aead_vec(const char *driver, int enc,
struct aead_extra_tests_ctx {
struct aead_request *req;
struct crypto_aead *tfm;
- const char *driver;
const struct alg_test_desc *test_desc;
struct cipher_test_sglists *tsgls;
unsigned int maxdatasize;
@@ -2167,18 +2212,19 @@ struct aead_extra_tests_ctx {
* here means the full ciphertext including the authentication tag. The
* authentication tag (and hence also the ciphertext) is assumed to be nonempty.
*/
-static void mutate_aead_message(struct aead_testvec *vec, bool esp_aad)
+static void mutate_aead_message(struct aead_testvec *vec, bool aad_iv,
+ unsigned int ivsize)
{
- const unsigned int aad_tail_size = esp_aad ? 8 : 0;
+ const unsigned int aad_tail_size = aad_iv ? ivsize : 0;
const unsigned int authsize = vec->clen - vec->plen;
- if (prandom_u32() % 2 == 0 && vec->alen > aad_tail_size) {
+ if (prandom_u32_max(2) == 0 && vec->alen > aad_tail_size) {
/* Mutate the AAD */
flip_random_bit((u8 *)vec->assoc, vec->alen - aad_tail_size);
- if (prandom_u32() % 2 == 0)
+ if (prandom_u32_max(2) == 0)
return;
}
- if (prandom_u32() % 2 == 0) {
+ if (prandom_u32_max(2) == 0) {
/* Mutate auth tag (assuming it's at the end of ciphertext) */
flip_random_bit((u8 *)vec->ctext + vec->plen, authsize);
} else {
@@ -2203,12 +2249,15 @@ static void generate_aead_message(struct aead_request *req,
const unsigned int ivsize = crypto_aead_ivsize(tfm);
const unsigned int authsize = vec->clen - vec->plen;
const bool inauthentic = (authsize >= MIN_COLLISION_FREE_AUTHSIZE) &&
- (prefer_inauthentic || prandom_u32() % 4 == 0);
+ (prefer_inauthentic || prandom_u32_max(4) == 0);
/* Generate the AAD. */
generate_random_bytes((u8 *)vec->assoc, vec->alen);
+ if (suite->aad_iv && vec->alen >= ivsize)
+ /* Avoid implementation-defined behavior. */
+ memcpy((u8 *)vec->assoc + vec->alen - ivsize, vec->iv, ivsize);
- if (inauthentic && prandom_u32() % 2 == 0) {
+ if (inauthentic && prandom_u32_max(2) == 0) {
/* Generate a random ciphertext. */
generate_random_bytes((u8 *)vec->ctext, vec->clen);
} else {
@@ -2242,7 +2291,7 @@ static void generate_aead_message(struct aead_request *req,
* Mutate the authentic (ciphertext, AAD) pair to get an
* inauthentic one.
*/
- mutate_aead_message(vec, suite->esp_aad);
+ mutate_aead_message(vec, suite->aad_iv, ivsize);
}
vec->novrfy = 1;
if (suite->einval_allowed)
@@ -2272,8 +2321,8 @@ static void generate_random_aead_testvec(struct aead_request *req,
/* Key: length in [0, maxkeysize], but usually choose maxkeysize */
vec->klen = maxkeysize;
- if (prandom_u32() % 4 == 0)
- vec->klen = prandom_u32() % (maxkeysize + 1);
+ if (prandom_u32_max(4) == 0)
+ vec->klen = prandom_u32_max(maxkeysize + 1);
generate_random_bytes((u8 *)vec->key, vec->klen);
vec->setkey_error = crypto_aead_setkey(tfm, vec->key, vec->klen);
@@ -2282,8 +2331,8 @@ static void generate_random_aead_testvec(struct aead_request *req,
/* Tag length: in [0, maxauthsize], but usually choose maxauthsize */
authsize = maxauthsize;
- if (prandom_u32() % 4 == 0)
- authsize = prandom_u32() % (maxauthsize + 1);
+ if (prandom_u32_max(4) == 0)
+ authsize = prandom_u32_max(maxauthsize + 1);
if (prefer_inauthentic && authsize < MIN_COLLISION_FREE_AUTHSIZE)
authsize = MIN_COLLISION_FREE_AUTHSIZE;
if (WARN_ON(authsize > maxdatasize))
@@ -2293,7 +2342,7 @@ static void generate_random_aead_testvec(struct aead_request *req,
/* AAD, plaintext, and ciphertext lengths */
total_len = generate_random_length(maxdatasize);
- if (prandom_u32() % 4 == 0)
+ if (prandom_u32_max(4) == 0)
vec->alen = 0;
else
vec->alen = generate_random_length(total_len);
@@ -2352,7 +2401,7 @@ static int test_aead_inauthentic_inputs(struct aead_extra_tests_ctx *ctx)
if (ctx->vec.novrfy) {
generate_random_testvec_config(&ctx->cfg, ctx->cfgname,
sizeof(ctx->cfgname));
- err = test_aead_vec_cfg(ctx->driver, DECRYPT, &ctx->vec,
+ err = test_aead_vec_cfg(DECRYPT, &ctx->vec,
ctx->vec_name, &ctx->cfg,
ctx->req, ctx->tsgls);
if (err)
@@ -2371,7 +2420,7 @@ static int test_aead_vs_generic_impl(struct aead_extra_tests_ctx *ctx)
{
struct crypto_aead *tfm = ctx->tfm;
const char *algname = crypto_aead_alg(tfm)->base.cra_name;
- const char *driver = ctx->driver;
+ const char *driver = crypto_aead_driver_name(tfm);
const char *generic_driver = ctx->test_desc->generic_driver;
char _generic_driver[CRYPTO_MAX_ALG_NAME];
struct crypto_aead *generic_tfm = NULL;
@@ -2448,14 +2497,14 @@ static int test_aead_vs_generic_impl(struct aead_extra_tests_ctx *ctx)
generate_random_testvec_config(&ctx->cfg, ctx->cfgname,
sizeof(ctx->cfgname));
if (!ctx->vec.novrfy) {
- err = test_aead_vec_cfg(driver, ENCRYPT, &ctx->vec,
+ err = test_aead_vec_cfg(ENCRYPT, &ctx->vec,
ctx->vec_name, &ctx->cfg,
ctx->req, ctx->tsgls);
if (err)
goto out;
}
if (ctx->vec.crypt_error == 0 || ctx->vec.novrfy) {
- err = test_aead_vec_cfg(driver, DECRYPT, &ctx->vec,
+ err = test_aead_vec_cfg(DECRYPT, &ctx->vec,
ctx->vec_name, &ctx->cfg,
ctx->req, ctx->tsgls);
if (err)
@@ -2470,8 +2519,7 @@ out:
return err;
}
-static int test_aead_extra(const char *driver,
- const struct alg_test_desc *test_desc,
+static int test_aead_extra(const struct alg_test_desc *test_desc,
struct aead_request *req,
struct cipher_test_sglists *tsgls)
{
@@ -2487,7 +2535,6 @@ static int test_aead_extra(const char *driver,
return -ENOMEM;
ctx->req = req;
ctx->tfm = crypto_aead_reqtfm(req);
- ctx->driver = driver;
ctx->test_desc = test_desc;
ctx->tsgls = tsgls;
ctx->maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN;
@@ -2507,11 +2554,11 @@ static int test_aead_extra(const char *driver,
goto out;
}
- err = test_aead_inauthentic_inputs(ctx);
+ err = test_aead_vs_generic_impl(ctx);
if (err)
goto out;
- err = test_aead_vs_generic_impl(ctx);
+ err = test_aead_inauthentic_inputs(ctx);
out:
kfree(ctx->vec.key);
kfree(ctx->vec.iv);
@@ -2522,8 +2569,7 @@ out:
return err;
}
#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
-static int test_aead_extra(const char *driver,
- const struct alg_test_desc *test_desc,
+static int test_aead_extra(const struct alg_test_desc *test_desc,
struct aead_request *req,
struct cipher_test_sglists *tsgls)
{
@@ -2531,8 +2577,7 @@ static int test_aead_extra(const char *driver,
}
#endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
-static int test_aead(const char *driver, int enc,
- const struct aead_test_suite *suite,
+static int test_aead(int enc, const struct aead_test_suite *suite,
struct aead_request *req,
struct cipher_test_sglists *tsgls)
{
@@ -2540,8 +2585,7 @@ static int test_aead(const char *driver, int enc,
int err;
for (i = 0; i < suite->count; i++) {
- err = test_aead_vec(driver, enc, &suite->vecs[i], i, req,
- tsgls);
+ err = test_aead_vec(enc, &suite->vecs[i], i, req, tsgls);
if (err)
return err;
cond_resched();
@@ -2569,6 +2613,7 @@ static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
driver, PTR_ERR(tfm));
return PTR_ERR(tfm);
}
+ driver = crypto_aead_driver_name(tfm);
req = aead_request_alloc(tfm, GFP_KERNEL);
if (!req) {
@@ -2586,15 +2631,15 @@ static int alg_test_aead(const struct alg_test_desc *desc, const char *driver,
goto out;
}
- err = test_aead(driver, ENCRYPT, suite, req, tsgls);
+ err = test_aead(ENCRYPT, suite, req, tsgls);
if (err)
goto out;
- err = test_aead(driver, DECRYPT, suite, req, tsgls);
+ err = test_aead(DECRYPT, suite, req, tsgls);
if (err)
goto out;
- err = test_aead_extra(driver, desc, req, tsgls);
+ err = test_aead_extra(desc, req, tsgls);
out:
free_cipher_test_sglists(tsgls);
aead_request_free(req);
@@ -2689,8 +2734,7 @@ out_nobuf:
return ret;
}
-static int test_skcipher_vec_cfg(const char *driver, int enc,
- const struct cipher_testvec *vec,
+static int test_skcipher_vec_cfg(int enc, const struct cipher_testvec *vec,
const char *vec_name,
const struct testvec_config *cfg,
struct skcipher_request *req,
@@ -2699,6 +2743,7 @@ static int test_skcipher_vec_cfg(const char *driver, int enc,
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
const unsigned int alignmask = crypto_skcipher_alignmask(tfm);
const unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+ const char *driver = crypto_skcipher_driver_name(tfm);
const u32 req_flags = CRYPTO_TFM_REQ_MAY_BACKLOG | cfg->req_flags;
const char *op = enc ? "encryption" : "decryption";
DECLARE_CRYPTO_WAIT(wait);
@@ -2853,8 +2898,7 @@ static int test_skcipher_vec_cfg(const char *driver, int enc,
return 0;
}
-static int test_skcipher_vec(const char *driver, int enc,
- const struct cipher_testvec *vec,
+static int test_skcipher_vec(int enc, const struct cipher_testvec *vec,
unsigned int vec_num,
struct skcipher_request *req,
struct cipher_test_sglists *tsgls)
@@ -2869,7 +2913,7 @@ static int test_skcipher_vec(const char *driver, int enc,
sprintf(vec_name, "%u", vec_num);
for (i = 0; i < ARRAY_SIZE(default_cipher_testvec_configs); i++) {
- err = test_skcipher_vec_cfg(driver, enc, vec, vec_name,
+ err = test_skcipher_vec_cfg(enc, vec, vec_name,
&default_cipher_testvec_configs[i],
req, tsgls);
if (err)
@@ -2884,7 +2928,7 @@ static int test_skcipher_vec(const char *driver, int enc,
for (i = 0; i < fuzz_iterations; i++) {
generate_random_testvec_config(&cfg, cfgname,
sizeof(cfgname));
- err = test_skcipher_vec_cfg(driver, enc, vec, vec_name,
+ err = test_skcipher_vec_cfg(enc, vec, vec_name,
&cfg, req, tsgls);
if (err)
return err;
@@ -2914,8 +2958,8 @@ static void generate_random_cipher_testvec(struct skcipher_request *req,
/* Key: length in [0, maxkeysize], but usually choose maxkeysize */
vec->klen = maxkeysize;
- if (prandom_u32() % 4 == 0)
- vec->klen = prandom_u32() % (maxkeysize + 1);
+ if (prandom_u32_max(4) == 0)
+ vec->klen = prandom_u32_max(maxkeysize + 1);
generate_random_bytes((u8 *)vec->key, vec->klen);
vec->setkey_error = crypto_skcipher_setkey(tfm, vec->key, vec->klen);
@@ -2955,8 +2999,7 @@ done:
* Test the skcipher algorithm represented by @req against the corresponding
* generic implementation, if one is available.
*/
-static int test_skcipher_vs_generic_impl(const char *driver,
- const char *generic_driver,
+static int test_skcipher_vs_generic_impl(const char *generic_driver,
struct skcipher_request *req,
struct cipher_test_sglists *tsgls)
{
@@ -2966,6 +3009,7 @@ static int test_skcipher_vs_generic_impl(const char *driver,
const unsigned int blocksize = crypto_skcipher_blocksize(tfm);
const unsigned int maxdatasize = (2 * PAGE_SIZE) - TESTMGR_POISON_LEN;
const char *algname = crypto_skcipher_alg(tfm)->base.cra_name;
+ const char *driver = crypto_skcipher_driver_name(tfm);
char _generic_driver[CRYPTO_MAX_ALG_NAME];
struct crypto_skcipher *generic_tfm = NULL;
struct skcipher_request *generic_req = NULL;
@@ -3071,11 +3115,11 @@ static int test_skcipher_vs_generic_impl(const char *driver,
vec_name, sizeof(vec_name));
generate_random_testvec_config(cfg, cfgname, sizeof(cfgname));
- err = test_skcipher_vec_cfg(driver, ENCRYPT, &vec, vec_name,
+ err = test_skcipher_vec_cfg(ENCRYPT, &vec, vec_name,
cfg, req, tsgls);
if (err)
goto out;
- err = test_skcipher_vec_cfg(driver, DECRYPT, &vec, vec_name,
+ err = test_skcipher_vec_cfg(DECRYPT, &vec, vec_name,
cfg, req, tsgls);
if (err)
goto out;
@@ -3093,8 +3137,7 @@ out:
return err;
}
#else /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
-static int test_skcipher_vs_generic_impl(const char *driver,
- const char *generic_driver,
+static int test_skcipher_vs_generic_impl(const char *generic_driver,
struct skcipher_request *req,
struct cipher_test_sglists *tsgls)
{
@@ -3102,8 +3145,7 @@ static int test_skcipher_vs_generic_impl(const char *driver,
}
#endif /* !CONFIG_CRYPTO_MANAGER_EXTRA_TESTS */
-static int test_skcipher(const char *driver, int enc,
- const struct cipher_test_suite *suite,
+static int test_skcipher(int enc, const struct cipher_test_suite *suite,
struct skcipher_request *req,
struct cipher_test_sglists *tsgls)
{
@@ -3111,8 +3153,7 @@ static int test_skcipher(const char *driver, int enc,
int err;
for (i = 0; i < suite->count; i++) {
- err = test_skcipher_vec(driver, enc, &suite->vecs[i], i, req,
- tsgls);
+ err = test_skcipher_vec(enc, &suite->vecs[i], i, req, tsgls);
if (err)
return err;
cond_resched();
@@ -3140,6 +3181,7 @@ static int alg_test_skcipher(const struct alg_test_desc *desc,
driver, PTR_ERR(tfm));
return PTR_ERR(tfm);
}
+ driver = crypto_skcipher_driver_name(tfm);
req = skcipher_request_alloc(tfm, GFP_KERNEL);
if (!req) {
@@ -3157,16 +3199,15 @@ static int alg_test_skcipher(const struct alg_test_desc *desc,
goto out;
}
- err = test_skcipher(driver, ENCRYPT, suite, req, tsgls);
+ err = test_skcipher(ENCRYPT, suite, req, tsgls);
if (err)
goto out;
- err = test_skcipher(driver, DECRYPT, suite, req, tsgls);
+ err = test_skcipher(DECRYPT, suite, req, tsgls);
if (err)
goto out;
- err = test_skcipher_vs_generic_impl(driver, desc->generic_driver, req,
- tsgls);
+ err = test_skcipher_vs_generic_impl(desc->generic_driver, req, tsgls);
out:
free_cipher_test_sglists(tsgls);
skcipher_request_free(req);
@@ -3281,7 +3322,7 @@ out:
}
static int test_acomp(struct crypto_acomp *tfm,
- const struct comp_testvec *ctemplate,
+ const struct comp_testvec *ctemplate,
const struct comp_testvec *dtemplate,
int ctcount, int dtcount)
{
@@ -3376,6 +3417,21 @@ static int test_acomp(struct crypto_acomp *tfm,
goto out;
}
+#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
+ crypto_init_wait(&wait);
+ sg_init_one(&src, input_vec, ilen);
+ acomp_request_set_params(req, &src, NULL, ilen, 0);
+
+ ret = crypto_wait_req(crypto_acomp_compress(req), &wait);
+ if (ret) {
+ pr_err("alg: acomp: compression failed on NULL dst buffer test %d for %s: ret=%d\n",
+ i + 1, algo, -ret);
+ kfree(input_vec);
+ acomp_request_free(req);
+ goto out;
+ }
+#endif
+
kfree(input_vec);
acomp_request_free(req);
}
@@ -3437,6 +3493,20 @@ static int test_acomp(struct crypto_acomp *tfm,
goto out;
}
+#ifdef CONFIG_CRYPTO_MANAGER_EXTRA_TESTS
+ crypto_init_wait(&wait);
+ acomp_request_set_params(req, &src, NULL, ilen, 0);
+
+ ret = crypto_wait_req(crypto_acomp_decompress(req), &wait);
+ if (ret) {
+ pr_err("alg: acomp: decompression failed on NULL dst buffer test %d for %s: ret=%d\n",
+ i + 1, algo, -ret);
+ kfree(input_vec);
+ acomp_request_free(req);
+ goto out;
+ }
+#endif
+
kfree(input_vec);
acomp_request_free(req);
}
@@ -3596,6 +3666,7 @@ static int alg_test_crc32c(const struct alg_test_desc *desc,
"%ld\n", driver, PTR_ERR(tfm));
return PTR_ERR(tfm);
}
+ driver = crypto_shash_driver_name(tfm);
do {
SHASH_DESC_ON_STACK(shash, tfm);
@@ -3660,7 +3731,7 @@ static int drbg_cavs_test(const struct drbg_testvec *test, int pr,
if (IS_ERR(drng)) {
printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for "
"%s\n", driver);
- kzfree(buf);
+ kfree_sensitive(buf);
return -ENOMEM;
}
@@ -3707,7 +3778,7 @@ static int drbg_cavs_test(const struct drbg_testvec *test, int pr,
outbuf:
crypto_free_rng(drng);
- kzfree(buf);
+ kfree_sensitive(buf);
return ret;
}
@@ -3949,7 +4020,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
key = kmalloc(vecs->key_len + sizeof(u32) * 2 + vecs->param_len,
GFP_KERNEL);
if (!key)
- goto free_xbuf;
+ goto free_req;
memcpy(key, vecs->key, vecs->key_len);
ptr = key + vecs->key_len;
ptr = test_pack_u32(ptr, vecs->algo);
@@ -3961,7 +4032,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
else
err = crypto_akcipher_set_priv_key(tfm, key, vecs->key_len);
if (err)
- goto free_req;
+ goto free_key;
/*
* First run test which do not require a private key, such as
@@ -3971,7 +4042,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
out_len_max = crypto_akcipher_maxsize(tfm);
outbuf_enc = kzalloc(out_len_max, GFP_KERNEL);
if (!outbuf_enc)
- goto free_req;
+ goto free_key;
if (!vecs->siggen_sigver_test) {
m = vecs->m;
@@ -3990,6 +4061,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
op = "verify";
}
+ err = -E2BIG;
if (WARN_ON(m_size > PAGE_SIZE))
goto free_all;
memcpy(xbuf[0], m, m_size);
@@ -4020,7 +4092,7 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
pr_err("alg: akcipher: %s test failed. err %d\n", op, err);
goto free_all;
}
- if (!vecs->siggen_sigver_test) {
+ if (!vecs->siggen_sigver_test && c) {
if (req->dst_len != c_size) {
pr_err("alg: akcipher: %s test failed. Invalid output len\n",
op);
@@ -4051,6 +4123,12 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
goto free_all;
}
+ if (!vecs->siggen_sigver_test && !c) {
+ c = outbuf_enc;
+ c_size = req->dst_len;
+ }
+
+ err = -E2BIG;
op = vecs->siggen_sigver_test ? "sign" : "decrypt";
if (WARN_ON(c_size > PAGE_SIZE))
goto free_all;
@@ -4087,9 +4165,10 @@ static int test_akcipher_one(struct crypto_akcipher *tfm,
free_all:
kfree(outbuf_dec);
kfree(outbuf_enc);
+free_key:
+ kfree(key);
free_req:
akcipher_request_free(req);
- kfree(key);
free_xbuf:
testmgr_free_buf(xbuf);
return err;
@@ -4194,7 +4273,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "authenc(hmac(sha1),cbc(des3_ede))",
.test = alg_test_aead,
- .fips_allowed = 1,
.suite = {
.aead = __VECS(hmac_sha1_des3_ede_cbc_tv_temp)
}
@@ -4221,7 +4299,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "authenc(hmac(sha224),cbc(des3_ede))",
.test = alg_test_aead,
- .fips_allowed = 1,
.suite = {
.aead = __VECS(hmac_sha224_des3_ede_cbc_tv_temp)
}
@@ -4241,7 +4318,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "authenc(hmac(sha256),cbc(des3_ede))",
.test = alg_test_aead,
- .fips_allowed = 1,
.suite = {
.aead = __VECS(hmac_sha256_des3_ede_cbc_tv_temp)
}
@@ -4262,7 +4338,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "authenc(hmac(sha384),cbc(des3_ede))",
.test = alg_test_aead,
- .fips_allowed = 1,
.suite = {
.aead = __VECS(hmac_sha384_des3_ede_cbc_tv_temp)
}
@@ -4290,7 +4365,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "authenc(hmac(sha512),cbc(des3_ede))",
.test = alg_test_aead,
- .fips_allowed = 1,
.suite = {
.aead = __VECS(hmac_sha512_des3_ede_cbc_tv_temp)
}
@@ -4331,30 +4405,6 @@ static const struct alg_test_desc alg_test_descs[] = {
.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,
.fips_allowed = 1,
@@ -4368,6 +4418,12 @@ static const struct alg_test_desc alg_test_descs[] = {
.cipher = __VECS(anubis_cbc_tv_template)
},
}, {
+ .alg = "cbc(aria)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = __VECS(aria_cbc_tv_template)
+ },
+ }, {
.alg = "cbc(blowfish)",
.test = alg_test_skcipher,
.suite = {
@@ -4400,7 +4456,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "cbc(des3_ede)",
.test = alg_test_skcipher,
- .fips_allowed = 1,
.suite = {
.cipher = __VECS(des3_ede_cbc_tv_template)
},
@@ -4452,6 +4507,12 @@ static const struct alg_test_desc alg_test_descs[] = {
.hash = __VECS(aes_cbcmac_tv_template)
}
}, {
+ .alg = "cbcmac(sm4)",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = __VECS(sm4_cbcmac_tv_template)
+ }
+ }, {
.alg = "ccm(aes)",
.generic_driver = "ccm_base(ctr(aes-generic),cbcmac(aes-generic))",
.test = alg_test_aead,
@@ -4463,6 +4524,16 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}
}, {
+ .alg = "ccm(sm4)",
+ .generic_driver = "ccm_base(ctr(sm4-generic),cbcmac(sm4-generic))",
+ .test = alg_test_aead,
+ .suite = {
+ .aead = {
+ ____VECS(sm4_ccm_tv_template),
+ .einval_allowed = 1,
+ }
+ }
+ }, {
.alg = "cfb(aes)",
.test = alg_test_skcipher,
.fips_allowed = 1,
@@ -4470,6 +4541,12 @@ static const struct alg_test_desc alg_test_descs[] = {
.cipher = __VECS(aes_cfb_tv_template)
},
}, {
+ .alg = "cfb(aria)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = __VECS(aria_cfb_tv_template)
+ },
+ }, {
.alg = "cfb(sm4)",
.test = alg_test_skcipher,
.suite = {
@@ -4490,12 +4567,17 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}, {
.alg = "cmac(des3_ede)",
- .fips_allowed = 1,
.test = alg_test_hash,
.suite = {
.hash = __VECS(des3_ede_cmac64_tv_template)
}
}, {
+ .alg = "cmac(sm4)",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = __VECS(sm4_cmac128_tv_template)
+ }
+ }, {
.alg = "compress_null",
.test = alg_test_null,
}, {
@@ -4513,6 +4595,13 @@ static const struct alg_test_desc alg_test_descs[] = {
.hash = __VECS(crc32c_tv_template)
}
}, {
+ .alg = "crc64-rocksoft",
+ .test = alg_test_hash,
+ .fips_allowed = 1,
+ .suite = {
+ .hash = __VECS(crc64_rocksoft_tv_template)
+ }
+ }, {
.alg = "crct10dif",
.test = alg_test_hash,
.fips_allowed = 1,
@@ -4527,6 +4616,12 @@ static const struct alg_test_desc alg_test_descs[] = {
.cipher = __VECS(aes_ctr_tv_template)
}
}, {
+ .alg = "ctr(aria)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = __VECS(aria_ctr_tv_template)
+ }
+ }, {
.alg = "ctr(blowfish)",
.test = alg_test_skcipher,
.suite = {
@@ -4559,7 +4654,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "ctr(des3_ede)",
.test = alg_test_skcipher,
- .fips_allowed = 1,
.suite = {
.cipher = __VECS(des3_ede_ctr_tv_template)
}
@@ -4637,7 +4731,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "dh",
.test = alg_test_kpp,
- .fips_allowed = 1,
.suite = {
.kpp = __VECS(dh_tv_template)
}
@@ -4687,8 +4780,11 @@ static const struct alg_test_desc alg_test_descs[] = {
.test = alg_test_null,
}, {
.alg = "drbg_nopr_hmac_sha512",
- .test = alg_test_null,
+ .test = alg_test_drbg,
.fips_allowed = 1,
+ .suite = {
+ .drbg = __VECS(drbg_nopr_hmac_sha512_tv_template)
+ }
}, {
.alg = "drbg_nopr_sha1",
.fips_allowed = 1,
@@ -4786,6 +4882,12 @@ static const struct alg_test_desc alg_test_descs[] = {
.cipher = __VECS(arc4_tv_template)
}
}, {
+ .alg = "ecb(aria)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = __VECS(aria_tv_template)
+ }
+ }, {
.alg = "ecb(blowfish)",
.test = alg_test_skcipher,
.suite = {
@@ -4822,7 +4924,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, {
.alg = "ecb(des3_ede)",
.test = alg_test_skcipher,
- .fips_allowed = 1,
.suite = {
.cipher = __VECS(des3_ede_tv_template)
}
@@ -4873,12 +4974,6 @@ static const struct alg_test_desc alg_test_descs[] = {
.cipher = __VECS(tea_tv_template)
}
}, {
- .alg = "ecb(tnepres)",
- .test = alg_test_skcipher,
- .suite = {
- .cipher = __VECS(tnepres_tv_template)
- }
- }, {
.alg = "ecb(twofish)",
.test = alg_test_skcipher,
.suite = {
@@ -4906,11 +5001,42 @@ static const struct alg_test_desc alg_test_descs[] = {
}
}, {
#endif
- .alg = "ecdh",
+ .alg = "ecdh-nist-p192",
+ .test = alg_test_kpp,
+ .suite = {
+ .kpp = __VECS(ecdh_p192_tv_template)
+ }
+ }, {
+ .alg = "ecdh-nist-p256",
.test = alg_test_kpp,
.fips_allowed = 1,
.suite = {
- .kpp = __VECS(ecdh_tv_template)
+ .kpp = __VECS(ecdh_p256_tv_template)
+ }
+ }, {
+ .alg = "ecdh-nist-p384",
+ .test = alg_test_kpp,
+ .fips_allowed = 1,
+ .suite = {
+ .kpp = __VECS(ecdh_p384_tv_template)
+ }
+ }, {
+ .alg = "ecdsa-nist-p192",
+ .test = alg_test_akcipher,
+ .suite = {
+ .akcipher = __VECS(ecdsa_nist_p192_tv_template)
+ }
+ }, {
+ .alg = "ecdsa-nist-p256",
+ .test = alg_test_akcipher,
+ .suite = {
+ .akcipher = __VECS(ecdsa_nist_p256_tv_template)
+ }
+ }, {
+ .alg = "ecdsa-nist-p384",
+ .test = alg_test_akcipher,
+ .suite = {
+ .akcipher = __VECS(ecdsa_nist_p384_tv_template)
}
}, {
.alg = "ecrdsa",
@@ -4933,6 +5059,43 @@ static const struct alg_test_desc alg_test_descs[] = {
.cipher = __VECS(essiv_aes_cbc_tv_template)
}
}, {
+#if IS_ENABLED(CONFIG_CRYPTO_DH_RFC7919_GROUPS)
+ .alg = "ffdhe2048(dh)",
+ .test = alg_test_kpp,
+ .fips_allowed = 1,
+ .suite = {
+ .kpp = __VECS(ffdhe2048_dh_tv_template)
+ }
+ }, {
+ .alg = "ffdhe3072(dh)",
+ .test = alg_test_kpp,
+ .fips_allowed = 1,
+ .suite = {
+ .kpp = __VECS(ffdhe3072_dh_tv_template)
+ }
+ }, {
+ .alg = "ffdhe4096(dh)",
+ .test = alg_test_kpp,
+ .fips_allowed = 1,
+ .suite = {
+ .kpp = __VECS(ffdhe4096_dh_tv_template)
+ }
+ }, {
+ .alg = "ffdhe6144(dh)",
+ .test = alg_test_kpp,
+ .fips_allowed = 1,
+ .suite = {
+ .kpp = __VECS(ffdhe6144_dh_tv_template)
+ }
+ }, {
+ .alg = "ffdhe8192(dh)",
+ .test = alg_test_kpp,
+ .fips_allowed = 1,
+ .suite = {
+ .kpp = __VECS(ffdhe8192_dh_tv_template)
+ }
+ }, {
+#endif /* CONFIG_CRYPTO_DH_RFC7919_GROUPS */
.alg = "gcm(aes)",
.generic_driver = "gcm_base(ctr(aes-generic),ghash-generic)",
.test = alg_test_aead,
@@ -4941,6 +5104,20 @@ static const struct alg_test_desc alg_test_descs[] = {
.aead = __VECS(aes_gcm_tv_template)
}
}, {
+ .alg = "gcm(aria)",
+ .generic_driver = "gcm_base(ctr(aria-generic),ghash-generic)",
+ .test = alg_test_aead,
+ .suite = {
+ .aead = __VECS(aria_gcm_tv_template)
+ }
+ }, {
+ .alg = "gcm(sm4)",
+ .generic_driver = "gcm_base(ctr(sm4-generic),ghash-generic)",
+ .test = alg_test_aead,
+ .suite = {
+ .aead = __VECS(sm4_gcm_tv_template)
+ }
+ }, {
.alg = "ghash",
.test = alg_test_hash,
.fips_allowed = 1,
@@ -4948,16 +5125,18 @@ static const struct alg_test_desc alg_test_descs[] = {
.hash = __VECS(ghash_tv_template)
}
}, {
- .alg = "hmac(md5)",
- .test = alg_test_hash,
+ .alg = "hctr2(aes)",
+ .generic_driver =
+ "hctr2_base(xctr(aes-generic),polyval-generic)",
+ .test = alg_test_skcipher,
.suite = {
- .hash = __VECS(hmac_md5_tv_template)
+ .cipher = __VECS(aes_hctr2_tv_template)
}
}, {
- .alg = "hmac(rmd128)",
+ .alg = "hmac(md5)",
.test = alg_test_hash,
.suite = {
- .hash = __VECS(hmac_rmd128_tv_template)
+ .hash = __VECS(hmac_md5_tv_template)
}
}, {
.alg = "hmac(rmd160)",
@@ -5208,6 +5387,12 @@ static const struct alg_test_desc alg_test_descs[] = {
.hash = __VECS(poly1305_tv_template)
}
}, {
+ .alg = "polyval",
+ .test = alg_test_hash,
+ .suite = {
+ .hash = __VECS(polyval_tv_template)
+ }
+ }, {
.alg = "rfc3686(ctr(aes))",
.test = alg_test_skcipher,
.fips_allowed = 1,
@@ -5229,7 +5414,7 @@ static const struct alg_test_desc alg_test_descs[] = {
.aead = {
____VECS(aes_gcm_rfc4106_tv_template),
.einval_allowed = 1,
- .esp_aad = 1,
+ .aad_iv = 1,
}
}
}, {
@@ -5241,7 +5426,7 @@ static const struct alg_test_desc alg_test_descs[] = {
.aead = {
____VECS(aes_ccm_rfc4309_tv_template),
.einval_allowed = 1,
- .esp_aad = 1,
+ .aad_iv = 1,
}
}
}, {
@@ -5252,6 +5437,7 @@ static const struct alg_test_desc alg_test_descs[] = {
.aead = {
____VECS(aes_gcm_rfc4543_tv_template),
.einval_allowed = 1,
+ .aad_iv = 1,
}
}
}, {
@@ -5267,34 +5453,16 @@ static const struct alg_test_desc alg_test_descs[] = {
.aead = {
____VECS(rfc7539esp_tv_template),
.einval_allowed = 1,
- .esp_aad = 1,
+ .aad_iv = 1,
}
}
}, {
- .alg = "rmd128",
- .test = alg_test_hash,
- .suite = {
- .hash = __VECS(rmd128_tv_template)
- }
- }, {
.alg = "rmd160",
.test = alg_test_hash,
.suite = {
.hash = __VECS(rmd160_tv_template)
}
}, {
- .alg = "rmd256",
- .test = alg_test_hash,
- .suite = {
- .hash = __VECS(rmd256_tv_template)
- }
- }, {
- .alg = "rmd320",
- .test = alg_test_hash,
- .suite = {
- .hash = __VECS(rmd320_tv_template)
- }
- }, {
.alg = "rsa",
.test = alg_test_akcipher,
.fips_allowed = 1,
@@ -5302,12 +5470,6 @@ static const struct alg_test_desc alg_test_descs[] = {
.akcipher = __VECS(rsa_tv_template)
}
}, {
- .alg = "salsa20",
- .test = alg_test_skcipher,
- .suite = {
- .cipher = __VECS(salsa20_stream_tv_template)
- }
- }, {
.alg = "sha1",
.test = alg_test_hash,
.fips_allowed = 1,
@@ -5371,6 +5533,12 @@ static const struct alg_test_desc alg_test_descs[] = {
.hash = __VECS(sha512_tv_template)
}
}, {
+ .alg = "sm2",
+ .test = alg_test_akcipher,
+ .suite = {
+ .akcipher = __VECS(sm2_tv_template)
+ }
+ }, {
.alg = "sm3",
.test = alg_test_hash,
.suite = {
@@ -5389,24 +5557,6 @@ static const struct alg_test_desc alg_test_descs[] = {
.hash = __VECS(streebog512_tv_template)
}
}, {
- .alg = "tgr128",
- .test = alg_test_hash,
- .suite = {
- .hash = __VECS(tgr128_tv_template)
- }
- }, {
- .alg = "tgr160",
- .test = alg_test_hash,
- .suite = {
- .hash = __VECS(tgr160_tv_template)
- }
- }, {
- .alg = "tgr192",
- .test = alg_test_hash,
- .suite = {
- .hash = __VECS(tgr192_tv_template)
- }
- }, {
.alg = "vmac64(aes)",
.test = alg_test_hash,
.suite = {
@@ -5449,6 +5599,12 @@ static const struct alg_test_desc alg_test_descs[] = {
.cipher = __VECS(xchacha20_tv_template)
},
}, {
+ .alg = "xctr(aes)",
+ .test = alg_test_skcipher,
+ .suite = {
+ .cipher = __VECS(aes_xctr_tv_template)
+ }
+ }, {
.alg = "xts(aes)",
.generic_driver = "xts(ecb(aes-generic))",
.test = alg_test_skcipher,
@@ -5607,6 +5763,13 @@ static int alg_find_test(const char *alg)
return -1;
}
+static int alg_fips_disabled(const char *driver, const char *alg)
+{
+ pr_info("alg: %s (%s) is disabled due to FIPS\n", alg, driver);
+
+ return -ECANCELED;
+}
+
int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
{
int i;
@@ -5643,9 +5806,13 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
if (i < 0 && j < 0)
goto notest;
- if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
- (j >= 0 && !alg_test_descs[j].fips_allowed)))
- goto non_fips_alg;
+ if (fips_enabled) {
+ if (j >= 0 && !alg_test_descs[j].fips_allowed)
+ return -EINVAL;
+
+ if (i >= 0 && !alg_test_descs[i].fips_allowed)
+ goto non_fips_alg;
+ }
rc = 0;
if (i >= 0)
@@ -5656,22 +5823,35 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask)
type, mask);
test_done:
- if (rc && (fips_enabled || panic_on_fail)) {
- fips_fail_notify();
- panic("alg: self-tests for %s (%s) failed in %s mode!\n",
- driver, alg, fips_enabled ? "fips" : "panic_on_fail");
+ if (rc) {
+ if (fips_enabled || panic_on_fail) {
+ fips_fail_notify();
+ panic("alg: self-tests for %s (%s) failed in %s mode!\n",
+ driver, alg,
+ fips_enabled ? "fips" : "panic_on_fail");
+ }
+ pr_warn("alg: self-tests for %s using %s failed (rc=%d)",
+ alg, driver, rc);
+ WARN(rc != -ENOENT,
+ "alg: self-tests for %s using %s failed (rc=%d)",
+ alg, driver, rc);
+ } else {
+ if (fips_enabled)
+ pr_info("alg: self-tests for %s (%s) passed\n",
+ driver, alg);
}
- if (fips_enabled && !rc)
- pr_info("alg: self-tests for %s (%s) passed\n", driver, alg);
-
return rc;
notest:
printk(KERN_INFO "alg: No test for %s (%s)\n", alg, driver);
+
+ if (type & CRYPTO_ALG_FIPS_INTERNAL)
+ return alg_fips_disabled(driver, alg);
+
return 0;
non_fips_alg:
- return -EINVAL;
+ return alg_fips_disabled(driver, alg);
}
#endif /* CONFIG_CRYPTO_MANAGER_DISABLE_TESTS */
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index d29983908c38..d6088e26f326 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -33,6 +33,7 @@
* @ksize: Length of @key in bytes (0 if no key)
* @setkey_error: Expected error from setkey()
* @digest_error: Expected error from digest()
+ * @fips_skip: Skip the test vector in FIPS mode
*/
struct hash_testvec {
const char *key;
@@ -42,6 +43,7 @@ struct hash_testvec {
unsigned short ksize;
int setkey_error;
int digest_error;
+ bool fips_skip;
};
/*
@@ -183,8 +185,8 @@ static const struct akcipher_testvec rsa_tv_template[] = {
{
#ifndef CONFIG_CRYPTO_FIPS
.key =
- "\x30\x81\x9A" /* sequence of 154 bytes */
- "\x02\x01\x01" /* version - integer of 1 byte */
+ "\x30\x82\x01\x38" /* sequence of 312 bytes */
+ "\x02\x01\x00" /* version - integer of 1 byte */
"\x02\x41" /* modulus - integer of 65 bytes */
"\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
"\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
@@ -197,24 +199,37 @@ static const struct akcipher_testvec rsa_tv_template[] = {
"\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64"
"\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9"
"\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51"
- "\x02\x01\x00" /* prime1 - integer of 1 byte */
- "\x02\x01\x00" /* prime2 - integer of 1 byte */
- "\x02\x01\x00" /* exponent1 - integer of 1 byte */
- "\x02\x01\x00" /* exponent2 - integer of 1 byte */
- "\x02\x01\x00", /* coefficient - integer of 1 byte */
+ "\x02\x21" /* prime1 - integer of 33 bytes */
+ "\x00\xD8\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
+ "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x12"
+ "\x0D"
+ "\x02\x21" /* prime2 - integer of 33 bytes */
+ "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
+ "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
+ "\x89"
+ "\x02\x20" /* exponent1 - integer of 32 bytes */
+ "\x59\x0B\x95\x72\xA2\xC2\xA9\xC4\x06\x05\x9D\xC2\xAB\x2F\x1D\xAF"
+ "\xEB\x7E\x8B\x4F\x10\xA7\x54\x9E\x8E\xED\xF5\xB4\xFC\xE0\x9E\x05"
+ "\x02\x21" /* exponent2 - integer of 33 bytes */
+ "\x00\x8E\x3C\x05\x21\xFE\x15\xE0\xEA\x06\xA3\x6F\xF0\xF1\x0C\x99"
+ "\x52\xC3\x5B\x7A\x75\x14\xFD\x32\x38\xB8\x0A\xAD\x52\x98\x62\x8D"
+ "\x51"
+ "\x02\x20" /* coefficient - integer of 32 bytes */
+ "\x36\x3F\xF7\x18\x9D\xA8\xE9\x0B\x1D\x34\x1F\x71\xD0\x9B\x76\xA8"
+ "\xA9\x43\xE1\x1D\x10\xB2\x4D\x24\x9F\x2D\xEA\xFE\xF8\x0C\x18\x26",
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
.c =
"\x63\x1c\xcd\x7b\xe1\x7e\xe4\xde\xc9\xa8\x89\xa1\x74\xcb\x3c\x63"
"\x7d\x24\xec\x83\xc3\x15\xe4\x7f\x73\x05\x34\xd1\xec\x22\xbb\x8a"
"\x5e\x32\x39\x6d\xc1\x1d\x7d\x50\x3b\x9f\x7a\xad\xf0\x2e\x25\x53"
"\x9f\x6e\xbd\x4c\x55\x84\x0c\x9b\xcf\x1a\x4b\x51\x1e\x9e\x0c\x06",
- .key_len = 157,
+ .key_len = 316,
.m_size = 8,
.c_size = 64,
}, {
.key =
- "\x30\x82\x01\x1D" /* sequence of 285 bytes */
- "\x02\x01\x01" /* version - integer of 1 byte */
+ "\x30\x82\x02\x5B" /* sequence of 603 bytes */
+ "\x02\x01\x00" /* version - integer of 1 byte */
"\x02\x81\x81" /* modulus - integer of 129 bytes */
"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
@@ -236,12 +251,35 @@ static const struct akcipher_testvec rsa_tv_template[] = {
"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
"\xC1"
- "\x02\x01\x00" /* prime1 - integer of 1 byte */
- "\x02\x01\x00" /* prime2 - integer of 1 byte */
- "\x02\x01\x00" /* exponent1 - integer of 1 byte */
- "\x02\x01\x00" /* exponent2 - integer of 1 byte */
- "\x02\x01\x00", /* coefficient - integer of 1 byte */
- .key_len = 289,
+ "\x02\x41" /* prime1 - integer of 65 bytes */
+ "\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60"
+ "\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6"
+ "\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A"
+ "\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65"
+ "\x99"
+ "\x02\x41" /* prime2 - integer of 65 bytes */
+ "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
+ "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
+ "\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
+ "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15"
+ "\x03"
+ "\x02\x40" /* exponent1 - integer of 64 bytes */
+ "\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A"
+ "\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E"
+ "\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E"
+ "\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81"
+ "\x02\x40" /* exponent2 - integer of 64 bytes */
+ "\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9"
+ "\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7"
+ "\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D"
+ "\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D"
+ "\x02\x41" /* coefficient - integer of 65 bytes */
+ "\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23"
+ "\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11"
+ "\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E"
+ "\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
+ "\xF7",
+ .key_len = 607,
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
.c =
"\x74\x1b\x55\xac\x47\xb5\x08\x0a\x6e\x2b\x2d\xf7\x94\xb8\x8a\x95"
@@ -257,9 +295,9 @@ static const struct akcipher_testvec rsa_tv_template[] = {
}, {
#endif
.key =
- "\x30\x82\x02\x1F" /* sequence of 543 bytes */
- "\x02\x01\x01" /* version - integer of 1 byte */
- "\x02\x82\x01\x00" /* modulus - integer of 256 bytes */
+ "\x30\x82\x04\xA3" /* sequence of 1187 bytes */
+ "\x02\x01\x00" /* version - integer of 1 byte */
+ "\x02\x82\x01\x01\x00" /* modulus - integer of 256 bytes */
"\xDB\x10\x1A\xC2\xA3\xF1\xDC\xFF\x13\x6B\xED\x44\xDF\xF0\x02\x6D"
"\x13\xC7\x88\xDA\x70\x6B\x54\xF1\xE8\x27\xDC\xC3\x0F\x99\x6A\xFA"
"\xC6\x67\xFF\x1D\x1E\x3C\x1D\xC1\xB5\x5F\x6C\xC0\xB2\x07\x3A\x6D"
@@ -294,12 +332,55 @@ static const struct akcipher_testvec rsa_tv_template[] = {
"\x62\xFF\xE9\x46\xB8\xD8\x44\xDB\xA5\xCC\x31\x54\x34\xCE\x3E\x82"
"\xD6\xBF\x7A\x0B\x64\x21\x6D\x88\x7E\x5B\x45\x12\x1E\x63\x8D\x49"
"\xA7\x1D\xD9\x1E\x06\xCD\xE8\xBA\x2C\x8C\x69\x32\xEA\xBE\x60\x71"
- "\x02\x01\x00" /* prime1 - integer of 1 byte */
- "\x02\x01\x00" /* prime2 - integer of 1 byte */
- "\x02\x01\x00" /* exponent1 - integer of 1 byte */
- "\x02\x01\x00" /* exponent2 - integer of 1 byte */
- "\x02\x01\x00", /* coefficient - integer of 1 byte */
- .key_len = 547,
+ "\x02\x81\x81" /* prime1 - integer of 129 bytes */
+ "\x00\xFA\xAC\xE1\x37\x5E\x32\x11\x34\xC6\x72\x58\x2D\x91\x06\x3E"
+ "\x77\xE7\x11\x21\xCD\x4A\xF8\xA4\x3F\x0F\xEF\x31\xE3\xF3\x55\xA0"
+ "\xB9\xAC\xB6\xCB\xBB\x41\xD0\x32\x81\x9A\x8F\x7A\x99\x30\x77\x6C"
+ "\x68\x27\xE2\x96\xB5\x72\xC9\xC3\xD4\x42\xAA\xAA\xCA\x95\x8F\xFF"
+ "\xC9\x9B\x52\x34\x30\x1D\xCF\xFE\xCF\x3C\x56\x68\x6E\xEF\xE7\x6C"
+ "\xD7\xFB\x99\xF5\x4A\xA5\x21\x1F\x2B\xEA\x93\xE8\x98\x26\xC4\x6E"
+ "\x42\x21\x5E\xA0\xA1\x2A\x58\x35\xBB\x10\xE7\xBA\x27\x0A\x3B\xB3"
+ "\xAF\xE2\x75\x36\x04\xAC\x56\xA0\xAB\x52\xDE\xCE\xDD\x2C\x28\x77"
+ "\x03"
+ "\x02\x81\x81" /* prime2 - integer of 129 bytes */
+ "\x00\xDF\xB7\x52\xB6\xD7\xC0\xE2\x96\xE7\xC9\xFE\x5D\x71\x5A\xC4"
+ "\x40\x96\x2F\xE5\x87\xEA\xF3\xA5\x77\x11\x67\x3C\x8D\x56\x08\xA7"
+ "\xB5\x67\xFA\x37\xA8\xB8\xCF\x61\xE8\x63\xD8\x38\x06\x21\x2B\x92"
+ "\x09\xA6\x39\x3A\xEA\xA8\xB4\x45\x4B\x36\x10\x4C\xE4\x00\x66\x71"
+ "\x65\xF8\x0B\x94\x59\x4F\x8C\xFD\xD5\x34\xA2\xE7\x62\x84\x0A\xA7"
+ "\xBB\xDB\xD9\x8A\xCD\x05\xE1\xCC\x57\x7B\xF1\xF1\x1F\x11\x9D\xBA"
+ "\x3E\x45\x18\x99\x1B\x41\x64\x43\xEE\x97\x5D\x77\x13\x5B\x74\x69"
+ "\x73\x87\x95\x05\x07\xBE\x45\x07\x17\x7E\x4A\x69\x22\xF3\xDB\x05"
+ "\x39"
+ "\x02\x81\x80" /* exponent1 - integer of 128 bytes */
+ "\x5E\xD8\xDC\xDA\x53\x44\xC4\x67\xE0\x92\x51\x34\xE4\x83\xA5\x4D"
+ "\x3E\xDB\xA7\x9B\x82\xBB\x73\x81\xFC\xE8\x77\x4B\x15\xBE\x17\x73"
+ "\x49\x9B\x5C\x98\xBC\xBD\x26\xEF\x0C\xE9\x2E\xED\x19\x7E\x86\x41"
+ "\x1E\x9E\x48\x81\xDD\x2D\xE4\x6F\xC2\xCD\xCA\x93\x9E\x65\x7E\xD5"
+ "\xEC\x73\xFD\x15\x1B\xA2\xA0\x7A\x0F\x0D\x6E\xB4\x53\x07\x90\x92"
+ "\x64\x3B\x8B\xA9\x33\xB3\xC5\x94\x9B\x4C\x5D\x9C\x7C\x46\xA4\xA5"
+ "\x56\xF4\xF3\xF8\x27\x0A\x7B\x42\x0D\x92\x70\x47\xE7\x42\x51\xA9"
+ "\xC2\x18\xB1\x58\xB1\x50\x91\xB8\x61\x41\xB6\xA9\xCE\xD4\x7C\xBB"
+ "\x02\x81\x80" /* exponent2 - integer of 128 bytes */
+ "\x54\x09\x1F\x0F\x03\xD8\xB6\xC5\x0C\xE8\xB9\x9E\x0C\x38\x96\x43"
+ "\xD4\xA6\xC5\x47\xDB\x20\x0E\xE5\xBD\x29\xD4\x7B\x1A\xF8\x41\x57"
+ "\x49\x69\x9A\x82\xCC\x79\x4A\x43\xEB\x4D\x8B\x2D\xF2\x43\xD5\xA5"
+ "\xBE\x44\xFD\x36\xAC\x8C\x9B\x02\xF7\x9A\x03\xE8\x19\xA6\x61\xAE"
+ "\x76\x10\x93\x77\x41\x04\xAB\x4C\xED\x6A\xCC\x14\x1B\x99\x8D\x0C"
+ "\x6A\x37\x3B\x86\x6C\x51\x37\x5B\x1D\x79\xF2\xA3\x43\x10\xC6\xA7"
+ "\x21\x79\x6D\xF9\xE9\x04\x6A\xE8\x32\xFF\xAE\xFD\x1C\x7B\x8C\x29"
+ "\x13\xA3\x0C\xB2\xAD\xEC\x6C\x0F\x8D\x27\x12\x7B\x48\xB2\xDB\x31"
+ "\x02\x81\x81" /* coefficient - integer of 129 bytes */
+ "\x00\x8D\x1B\x05\xCA\x24\x1F\x0C\x53\x19\x52\x74\x63\x21\xFA\x78"
+ "\x46\x79\xAF\x5C\xDE\x30\xA4\x6C\x20\x38\xE6\x97\x39\xB8\x7A\x70"
+ "\x0D\x8B\x6C\x6D\x13\x74\xD5\x1C\xDE\xA9\xF4\x60\x37\xFE\x68\x77"
+ "\x5E\x0B\x4E\x5E\x03\x31\x30\xDF\xD6\xAE\x85\xD0\x81\xBB\x61\xC7"
+ "\xB1\x04\x5A\xC4\x6D\x56\x1C\xD9\x64\xE7\x85\x7F\x88\x91\xC9\x60"
+ "\x28\x05\xE2\xC6\x24\x8F\xDD\x61\x64\xD8\x09\xDE\x7E\xD3\x4A\x61"
+ "\x1A\xD3\x73\x58\x4B\xD8\xA0\x54\x25\x48\x83\x6F\x82\x6C\xAF\x36"
+ "\x51\x2A\x5D\x14\x2F\x41\x25\x00\xDD\xF8\xF3\x95\xFE\x31\x25\x50"
+ "\x12",
+ .key_len = 1191,
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
.c =
"\xb2\x97\x76\xb4\xae\x3e\x38\x3c\x7e\x64\x1f\xcc\xa2\x7f\xf6\xbe"
@@ -567,6 +648,430 @@ static const struct akcipher_testvec rsa_tv_template[] = {
};
/*
+ * ECDSA test vectors.
+ */
+static const struct akcipher_testvec ecdsa_nist_p192_tv_template[] = {
+ {
+ .key =
+ "\x04\xf7\x46\xf8\x2f\x15\xf6\x22\x8e\xd7\x57\x4f\xcc\xe7\xbb\xc1"
+ "\xd4\x09\x73\xcf\xea\xd0\x15\x07\x3d\xa5\x8a\x8a\x95\x43\xe4\x68"
+ "\xea\xc6\x25\xc1\xc1\x01\x25\x4c\x7e\xc3\x3c\xa6\x04\x0a\xe7\x08"
+ "\x98",
+ .key_len = 49,
+ .params =
+ "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+ "\xce\x3d\x03\x01\x01",
+ .param_len = 21,
+ .m =
+ "\xcd\xb9\xd2\x1c\xb7\x6f\xcd\x44\xb3\xfd\x63\xea\xa3\x66\x7f\xae"
+ "\x63\x85\xe7\x82",
+ .m_size = 20,
+ .algo = OID_id_ecdsa_with_sha1,
+ .c =
+ "\x30\x35\x02\x19\x00\xba\xe5\x93\x83\x6e\xb6\x3b\x63\xa0\x27\x91"
+ "\xc6\xf6\x7f\xc3\x09\xad\x59\xad\x88\x27\xd6\x92\x6b\x02\x18\x10"
+ "\x68\x01\x9d\xba\xce\x83\x08\xef\x95\x52\x7b\xa0\x0f\xe4\x18\x86"
+ "\x80\x6f\xa5\x79\x77\xda\xd0",
+ .c_size = 55,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ }, {
+ .key =
+ "\x04\xb6\x4b\xb1\xd1\xac\xba\x24\x8f\x65\xb2\x60\x00\x90\xbf\xbd"
+ "\x78\x05\x73\xe9\x79\x1d\x6f\x7c\x0b\xd2\xc3\x93\xa7\x28\xe1\x75"
+ "\xf7\xd5\x95\x1d\x28\x10\xc0\x75\x50\x5c\x1a\x4f\x3f\x8f\xa5\xee"
+ "\xa3",
+ .key_len = 49,
+ .params =
+ "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+ "\xce\x3d\x03\x01\x01",
+ .param_len = 21,
+ .m =
+ "\x8d\xd6\xb8\x3e\xe5\xff\x23\xf6\x25\xa2\x43\x42\x74\x45\xa7\x40"
+ "\x3a\xff\x2f\xe1\xd3\xf6\x9f\xe8\x33\xcb\x12\x11",
+ .m_size = 28,
+ .algo = OID_id_ecdsa_with_sha224,
+ .c =
+ "\x30\x34\x02\x18\x5a\x8b\x82\x69\x7e\x8a\x0a\x09\x14\xf8\x11\x2b"
+ "\x55\xdc\xae\x37\x83\x7b\x12\xe6\xb6\x5b\xcb\xd4\x02\x18\x6a\x14"
+ "\x4f\x53\x75\xc8\x02\x48\xeb\xc3\x92\x0f\x1e\x72\xee\xc4\xa3\xe3"
+ "\x5c\x99\xdb\x92\x5b\x36",
+ .c_size = 54,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ }, {
+ .key =
+ "\x04\xe2\x51\x24\x9b\xf7\xb6\x32\x82\x39\x66\x3d\x5b\xec\x3b\xae"
+ "\x0c\xd5\xf2\x67\xd1\xc7\xe1\x02\xe4\xbf\x90\x62\xb8\x55\x75\x56"
+ "\x69\x20\x5e\xcb\x4e\xca\x33\xd6\xcb\x62\x6b\x94\xa9\xa2\xe9\x58"
+ "\x91",
+ .key_len = 49,
+ .params =
+ "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+ "\xce\x3d\x03\x01\x01",
+ .param_len = 21,
+ .m =
+ "\x35\xec\xa1\xa0\x9e\x14\xde\x33\x03\xb6\xf6\xbd\x0c\x2f\xb2\xfd"
+ "\x1f\x27\x82\xa5\xd7\x70\x3f\xef\xa0\x82\x69\x8e\x73\x31\x8e\xd7",
+ .m_size = 32,
+ .algo = OID_id_ecdsa_with_sha256,
+ .c =
+ "\x30\x35\x02\x18\x3f\x72\x3f\x1f\x42\xd2\x3f\x1d\x6b\x1a\x58\x56"
+ "\xf1\x8f\xf7\xfd\x01\x48\xfb\x5f\x72\x2a\xd4\x8f\x02\x19\x00\xb3"
+ "\x69\x43\xfd\x48\x19\x86\xcf\x32\xdd\x41\x74\x6a\x51\xc7\xd9\x7d"
+ "\x3a\x97\xd9\xcd\x1a\x6a\x49",
+ .c_size = 55,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ }, {
+ .key =
+ "\x04\x5a\x13\xfe\x68\x86\x4d\xf4\x17\xc7\xa4\xe5\x8c\x65\x57\xb7"
+ "\x03\x73\x26\x57\xfb\xe5\x58\x40\xd8\xfd\x49\x05\xab\xf1\x66\x1f"
+ "\xe2\x9d\x93\x9e\xc2\x22\x5a\x8b\x4f\xf3\x77\x22\x59\x7e\xa6\x4e"
+ "\x8b",
+ .key_len = 49,
+ .params =
+ "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+ "\xce\x3d\x03\x01\x01",
+ .param_len = 21,
+ .m =
+ "\x9d\x2e\x1a\x8f\xed\x6c\x4b\x61\xae\xac\xd5\x19\x79\xce\x67\xf9"
+ "\xa0\x34\xeb\xb0\x81\xf9\xd9\xdc\x6e\xb3\x5c\xa8\x69\xfc\x8a\x61"
+ "\x39\x81\xfb\xfd\x5c\x30\x6b\xa8\xee\xed\x89\xaf\xa3\x05\xe4\x78",
+ .m_size = 48,
+ .algo = OID_id_ecdsa_with_sha384,
+ .c =
+ "\x30\x35\x02\x19\x00\xf0\xa3\x38\xce\x2b\xf8\x9d\x1a\xcf\x7f\x34"
+ "\xb4\xb4\xe5\xc5\x00\xdd\x15\xbb\xd6\x8c\xa7\x03\x78\x02\x18\x64"
+ "\xbc\x5a\x1f\x82\x96\x61\xd7\xd1\x01\x77\x44\x5d\x53\xa4\x7c\x93"
+ "\x12\x3b\x3b\x28\xfb\x6d\xe1",
+ .c_size = 55,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ }, {
+ .key =
+ "\x04\xd5\xf2\x6e\xc3\x94\x5c\x52\xbc\xdf\x86\x6c\x14\xd1\xca\xea"
+ "\xcc\x72\x3a\x8a\xf6\x7a\x3a\x56\x36\x3b\xca\xc6\x94\x0e\x17\x1d"
+ "\x9e\xa0\x58\x28\xf9\x4b\xe6\xd1\xa5\x44\x91\x35\x0d\xe7\xf5\x11"
+ "\x57",
+ .key_len = 49,
+ .params =
+ "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+ "\xce\x3d\x03\x01\x01",
+ .param_len = 21,
+ .m =
+ "\xd5\x4b\xe9\x36\xda\xd8\x6e\xc0\x50\x03\xbe\x00\x43\xff\xf0\x23"
+ "\xac\xa2\x42\xe7\x37\x77\x79\x52\x8f\x3e\xc0\x16\xc1\xfc\x8c\x67"
+ "\x16\xbc\x8a\x5d\x3b\xd3\x13\xbb\xb6\xc0\x26\x1b\xeb\x33\xcc\x70"
+ "\x4a\xf2\x11\x37\xe8\x1b\xba\x55\xac\x69\xe1\x74\x62\x7c\x6e\xb5",
+ .m_size = 64,
+ .algo = OID_id_ecdsa_with_sha512,
+ .c =
+ "\x30\x35\x02\x19\x00\x88\x5b\x8f\x59\x43\xbf\xcf\xc6\xdd\x3f\x07"
+ "\x87\x12\xa0\xd4\xac\x2b\x11\x2d\x1c\xb6\x06\xc9\x6c\x02\x18\x73"
+ "\xb4\x22\x9a\x98\x73\x3c\x83\xa9\x14\x2a\x5e\xf5\xe5\xfb\x72\x28"
+ "\x6a\xdf\x97\xfd\x82\x76\x24",
+ .c_size = 55,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ },
+};
+
+static const struct akcipher_testvec ecdsa_nist_p256_tv_template[] = {
+ {
+ .key =
+ "\x04\xb9\x7b\xbb\xd7\x17\x64\xd2\x7e\xfc\x81\x5d\x87\x06\x83\x41"
+ "\x22\xd6\x9a\xaa\x87\x17\xec\x4f\x63\x55\x2f\x94\xba\xdd\x83\xe9"
+ "\x34\x4b\xf3\xe9\x91\x13\x50\xb6\xcb\xca\x62\x08\xe7\x3b\x09\xdc"
+ "\xc3\x63\x4b\x2d\xb9\x73\x53\xe4\x45\xe6\x7c\xad\xe7\x6b\xb0\xe8"
+ "\xaf",
+ .key_len = 65,
+ .params =
+ "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+ "\xce\x3d\x03\x01\x07",
+ .param_len = 21,
+ .m =
+ "\xc2\x2b\x5f\x91\x78\x34\x26\x09\x42\x8d\x6f\x51\xb2\xc5\xaf\x4c"
+ "\x0b\xde\x6a\x42",
+ .m_size = 20,
+ .algo = OID_id_ecdsa_with_sha1,
+ .c =
+ "\x30\x46\x02\x21\x00\xf9\x25\xce\x9f\x3a\xa6\x35\x81\xcf\xd4\xe7"
+ "\xb7\xf0\x82\x56\x41\xf7\xd4\xad\x8d\x94\x5a\x69\x89\xee\xca\x6a"
+ "\x52\x0e\x48\x4d\xcc\x02\x21\x00\xd7\xe4\xef\x52\x66\xd3\x5b\x9d"
+ "\x8a\xfa\x54\x93\x29\xa7\x70\x86\xf1\x03\x03\xf3\x3b\xe2\x73\xf7"
+ "\xfb\x9d\x8b\xde\xd4\x8d\x6f\xad",
+ .c_size = 72,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ }, {
+ .key =
+ "\x04\x8b\x6d\xc0\x33\x8e\x2d\x8b\x67\xf5\xeb\xc4\x7f\xa0\xf5\xd9"
+ "\x7b\x03\xa5\x78\x9a\xb5\xea\x14\xe4\x23\xd0\xaf\xd7\x0e\x2e\xa0"
+ "\xc9\x8b\xdb\x95\xf8\xb3\xaf\xac\x00\x2c\x2c\x1f\x7a\xfd\x95\x88"
+ "\x43\x13\xbf\xf3\x1c\x05\x1a\x14\x18\x09\x3f\xd6\x28\x3e\xc5\xa0"
+ "\xd4",
+ .key_len = 65,
+ .params =
+ "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+ "\xce\x3d\x03\x01\x07",
+ .param_len = 21,
+ .m =
+ "\x1a\x15\xbc\xa3\xe4\xed\x3a\xb8\x23\x67\xc6\xc4\x34\xf8\x6c\x41"
+ "\x04\x0b\xda\xc5\x77\xfa\x1c\x2d\xe6\x2c\x3b\xe0",
+ .m_size = 28,
+ .algo = OID_id_ecdsa_with_sha224,
+ .c =
+ "\x30\x44\x02\x20\x20\x43\xfa\xc0\x9f\x9d\x7b\xe7\xae\xce\x77\x59"
+ "\x1a\xdb\x59\xd5\x34\x62\x79\xcb\x6a\x91\x67\x2e\x7d\x25\xd8\x25"
+ "\xf5\x81\xd2\x1e\x02\x20\x5f\xf8\x74\xf8\x57\xd0\x5e\x54\x76\x20"
+ "\x4a\x77\x22\xec\xc8\x66\xbf\x50\x05\x58\x39\x0e\x26\x92\xce\xd5"
+ "\x2e\x8b\xde\x5a\x04\x0e",
+ .c_size = 70,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ }, {
+ .key =
+ "\x04\xf1\xea\xc4\x53\xf3\xb9\x0e\x9f\x7e\xad\xe3\xea\xd7\x0e\x0f"
+ "\xd6\x98\x9a\xca\x92\x4d\x0a\x80\xdb\x2d\x45\xc7\xec\x4b\x97\x00"
+ "\x2f\xe9\x42\x6c\x29\xdc\x55\x0e\x0b\x53\x12\x9b\x2b\xad\x2c\xe9"
+ "\x80\xe6\xc5\x43\xc2\x1d\x5e\xbb\x65\x21\x50\xb6\x37\xb0\x03\x8e"
+ "\xb8",
+ .key_len = 65,
+ .params =
+ "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+ "\xce\x3d\x03\x01\x07",
+ .param_len = 21,
+ .m =
+ "\x8f\x43\x43\x46\x64\x8f\x6b\x96\xdf\x89\xdd\xa9\x01\xc5\x17\x6b"
+ "\x10\xa6\xd8\x39\x61\xdd\x3c\x1a\xc8\x8b\x59\xb2\xdc\x32\x7a\xa4",
+ .m_size = 32,
+ .algo = OID_id_ecdsa_with_sha256,
+ .c =
+ "\x30\x45\x02\x20\x08\x31\xfa\x74\x0d\x1d\x21\x5d\x09\xdc\x29\x63"
+ "\xa8\x1a\xad\xfc\xac\x44\xc3\xe8\x24\x11\x2d\xa4\x91\xdc\x02\x67"
+ "\xdc\x0c\xd0\x82\x02\x21\x00\xbd\xff\xce\xee\x42\xc3\x97\xff\xf9"
+ "\xa9\x81\xac\x4a\x50\xd0\x91\x0a\x6e\x1b\xc4\xaf\xe1\x83\xc3\x4f"
+ "\x2a\x65\x35\x23\xe3\x1d\xfa",
+ .c_size = 71,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ }, {
+ .key =
+ "\x04\xc5\xc6\xea\x60\xc9\xce\xad\x02\x8d\xf5\x3e\x24\xe3\x52\x1d"
+ "\x28\x47\x3b\xc3\x6b\xa4\x99\x35\x99\x11\x88\x88\xc8\xf4\xee\x7e"
+ "\x8c\x33\x8f\x41\x03\x24\x46\x2b\x1a\x82\xf9\x9f\xe1\x97\x1b\x00"
+ "\xda\x3b\x24\x41\xf7\x66\x33\x58\x3d\x3a\x81\xad\xcf\x16\xe9\xe2"
+ "\x7c",
+ .key_len = 65,
+ .params =
+ "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+ "\xce\x3d\x03\x01\x07",
+ .param_len = 21,
+ .m =
+ "\x3e\x78\x70\xfb\xcd\x66\xba\x91\xa1\x79\xff\x1e\x1c\x6b\x78\xe6"
+ "\xc0\x81\x3a\x65\x97\x14\x84\x36\x14\x1a\x9a\xb7\xc5\xab\x84\x94"
+ "\x5e\xbb\x1b\x34\x71\xcb\x41\xe1\xf6\xfc\x92\x7b\x34\xbb\x86\xbb",
+ .m_size = 48,
+ .algo = OID_id_ecdsa_with_sha384,
+ .c =
+ "\x30\x46\x02\x21\x00\x8e\xf3\x6f\xdc\xf8\x69\xa6\x2e\xd0\x2e\x95"
+ "\x54\xd1\x95\x64\x93\x08\xb2\x6b\x24\x94\x48\x46\x5e\xf2\xe4\x6c"
+ "\xc7\x94\xb1\xd5\xfe\x02\x21\x00\xeb\xa7\x80\x26\xdc\xf9\x3a\x44"
+ "\x19\xfb\x5f\x92\xf4\xc9\x23\x37\x69\xf4\x3b\x4f\x47\xcf\x9b\x16"
+ "\xc0\x60\x11\x92\xdc\x17\x89\x12",
+ .c_size = 72,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ }, {
+ .key =
+ "\x04\xd7\x27\x46\x49\xf6\x26\x85\x12\x40\x76\x8e\xe2\xe6\x2a\x7a"
+ "\x83\xb1\x4e\x7a\xeb\x3b\x5c\x67\x4a\xb5\xa4\x92\x8c\x69\xff\x38"
+ "\xee\xd9\x4e\x13\x29\x59\xad\xde\x6b\xbb\x45\x31\xee\xfd\xd1\x1b"
+ "\x64\xd3\xb5\xfc\xaf\x9b\x4b\x88\x3b\x0e\xb7\xd6\xdf\xf1\xd5\x92"
+ "\xbf",
+ .key_len = 65,
+ .params =
+ "\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+ "\xce\x3d\x03\x01\x07",
+ .param_len = 21,
+ .m =
+ "\x57\xb7\x9e\xe9\x05\x0a\x8c\x1b\xc9\x13\xe5\x4a\x24\xc7\xe2\xe9"
+ "\x43\xc3\xd1\x76\x62\xf4\x98\x1a\x9c\x13\xb0\x20\x1b\xe5\x39\xca"
+ "\x4f\xd9\x85\x34\x95\xa2\x31\xbc\xbb\xde\xdd\x76\xbb\x61\xe3\xcf"
+ "\x9d\xc0\x49\x7a\xf3\x7a\xc4\x7d\xa8\x04\x4b\x8d\xb4\x4d\x5b\xd6",
+ .m_size = 64,
+ .algo = OID_id_ecdsa_with_sha512,
+ .c =
+ "\x30\x45\x02\x21\x00\xb8\x6d\x87\x81\x43\xdf\xfb\x9f\x40\xea\x44"
+ "\x81\x00\x4e\x29\x08\xed\x8c\x73\x30\x6c\x22\xb3\x97\x76\xf6\x04"
+ "\x99\x09\x37\x4d\xfa\x02\x20\x1e\xb9\x75\x31\xf6\x04\xa5\x4d\xf8"
+ "\x00\xdd\xab\xd4\xc0\x2b\xe6\x5c\xad\xc3\x78\x1c\xc2\xc1\x19\x76"
+ "\x31\x79\x4a\xe9\x81\x6a\xee",
+ .c_size = 71,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ },
+};
+
+static const struct akcipher_testvec ecdsa_nist_p384_tv_template[] = {
+ {
+ .key = /* secp384r1(sha1) */
+ "\x04\x89\x25\xf3\x97\x88\xcb\xb0\x78\xc5\x72\x9a\x14\x6e\x7a\xb1"
+ "\x5a\xa5\x24\xf1\x95\x06\x9e\x28\xfb\xc4\xb9\xbe\x5a\x0d\xd9\x9f"
+ "\xf3\xd1\x4d\x2d\x07\x99\xbd\xda\xa7\x66\xec\xbb\xea\xba\x79\x42"
+ "\xc9\x34\x89\x6a\xe7\x0b\xc3\xf2\xfe\x32\x30\xbe\xba\xf9\xdf\x7e"
+ "\x4b\x6a\x07\x8e\x26\x66\x3f\x1d\xec\xa2\x57\x91\x51\xdd\x17\x0e"
+ "\x0b\x25\xd6\x80\x5c\x3b\xe6\x1a\x98\x48\x91\x45\x7a\x73\xb0\xc3"
+ "\xf1",
+ .key_len = 97,
+ .params =
+ "\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04"
+ "\x00\x22",
+ .param_len = 18,
+ .m =
+ "\x12\x55\x28\xf0\x77\xd5\xb6\x21\x71\x32\x48\xcd\x28\xa8\x25\x22"
+ "\x3a\x69\xc1\x93",
+ .m_size = 20,
+ .algo = OID_id_ecdsa_with_sha1,
+ .c =
+ "\x30\x66\x02\x31\x00\xf5\x0f\x24\x4c\x07\x93\x6f\x21\x57\x55\x07"
+ "\x20\x43\x30\xde\xa0\x8d\x26\x8e\xae\x63\x3f\xbc\x20\x3a\xc6\xf1"
+ "\x32\x3c\xce\x70\x2b\x78\xf1\x4c\x26\xe6\x5b\x86\xcf\xec\x7c\x7e"
+ "\xd0\x87\xd7\xd7\x6e\x02\x31\x00\xcd\xbb\x7e\x81\x5d\x8f\x63\xc0"
+ "\x5f\x63\xb1\xbe\x5e\x4c\x0e\xa1\xdf\x28\x8c\x1b\xfa\xf9\x95\x88"
+ "\x74\xa0\x0f\xbf\xaf\xc3\x36\x76\x4a\xa1\x59\xf1\x1c\xa4\x58\x26"
+ "\x79\x12\x2a\xb7\xc5\x15\x92\xc5",
+ .c_size = 104,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ }, {
+ .key = /* secp384r1(sha224) */
+ "\x04\x69\x6c\xcf\x62\xee\xd0\x0d\xe5\xb5\x2f\x70\x54\xcf\x26\xa0"
+ "\xd9\x98\x8d\x92\x2a\xab\x9b\x11\xcb\x48\x18\xa1\xa9\x0d\xd5\x18"
+ "\x3e\xe8\x29\x6e\xf6\xe4\xb5\x8e\xc7\x4a\xc2\x5f\x37\x13\x99\x05"
+ "\xb6\xa4\x9d\xf9\xfb\x79\x41\xe7\xd7\x96\x9f\x73\x3b\x39\x43\xdc"
+ "\xda\xf4\x06\xb9\xa5\x29\x01\x9d\x3b\xe1\xd8\x68\x77\x2a\xf4\x50"
+ "\x6b\x93\x99\x6c\x66\x4c\x42\x3f\x65\x60\x6c\x1c\x0b\x93\x9b\x9d"
+ "\xe0",
+ .key_len = 97,
+ .params =
+ "\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04"
+ "\x00\x22",
+ .param_len = 18,
+ .m =
+ "\x12\x80\xb6\xeb\x25\xe2\x3d\xf0\x21\x32\x96\x17\x3a\x38\x39\xfd"
+ "\x1f\x05\x34\x7b\xb8\xf9\x71\x66\x03\x4f\xd5\xe5",
+ .m_size = 28,
+ .algo = OID_id_ecdsa_with_sha224,
+ .c =
+ "\x30\x66\x02\x31\x00\x8a\x51\x84\xce\x13\x1e\xd2\xdc\xec\xcb\xe4"
+ "\x89\x47\xb2\xf7\xbc\x97\xf1\xc8\x72\x26\xcf\x5a\x5e\xc5\xda\xb4"
+ "\xe3\x93\x07\xe0\x99\xc9\x9c\x11\xb8\x10\x01\xc5\x41\x3f\xdd\x15"
+ "\x1b\x68\x2b\x9d\x8b\x02\x31\x00\x8b\x03\x2c\xfc\x1f\xd1\xa9\xa4"
+ "\x4b\x00\x08\x31\x6c\xf5\xd5\xf6\xdf\xd8\x68\xa2\x64\x42\x65\xf3"
+ "\x4d\xd0\xc6\x6e\xb0\xe9\xfc\x14\x9f\x19\xd0\x42\x8b\x93\xc2\x11"
+ "\x88\x2b\x82\x26\x5e\x1c\xda\xfb",
+ .c_size = 104,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ }, {
+ .key = /* secp384r1(sha256) */
+ "\x04\xee\xd6\xda\x3e\x94\x90\x00\x27\xed\xf8\x64\x55\xd6\x51\x9a"
+ "\x1f\x52\x00\x63\x78\xf1\xa9\xfd\x75\x4c\x9e\xb2\x20\x1a\x91\x5a"
+ "\xba\x7a\xa3\xe5\x6c\xb6\x25\x68\x4b\xe8\x13\xa6\x54\x87\x2c\x0e"
+ "\xd0\x83\x95\xbc\xbf\xc5\x28\x4f\x77\x1c\x46\xa6\xf0\xbc\xd4\xa4"
+ "\x8d\xc2\x8f\xb3\x32\x37\x40\xd6\xca\xf8\xae\x07\x34\x52\x39\x52"
+ "\x17\xc3\x34\x29\xd6\x40\xea\x5c\xb9\x3f\xfb\x32\x2e\x12\x33\xbc"
+ "\xab",
+ .key_len = 97,
+ .params =
+ "\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04"
+ "\x00\x22",
+ .param_len = 18,
+ .m =
+ "\xaa\xe7\xfd\x03\x26\xcb\x94\x71\xe4\xce\x0f\xc5\xff\xa6\x29\xa3"
+ "\xe1\xcc\x4c\x35\x4e\xde\xca\x80\xab\x26\x0c\x25\xe6\x68\x11\xc2",
+ .m_size = 32,
+ .algo = OID_id_ecdsa_with_sha256,
+ .c =
+ "\x30\x64\x02\x30\x08\x09\x12\x9d\x6e\x96\x64\xa6\x8e\x3f\x7e\xce"
+ "\x0a\x9b\xaa\x59\xcc\x47\x53\x87\xbc\xbd\x83\x3f\xaf\x06\x3f\x84"
+ "\x04\xe2\xf9\x67\xb6\xc6\xfc\x70\x2e\x66\x3c\x77\xc8\x8d\x2c\x79"
+ "\x3a\x8e\x32\xc4\x02\x30\x40\x34\xb8\x90\xa9\x80\xab\x47\x26\xa2"
+ "\xb0\x89\x42\x0a\xda\xd9\xdd\xce\xbc\xb2\x97\xf4\x9c\xf3\x15\x68"
+ "\xc0\x75\x3e\x23\x5e\x36\x4f\x8d\xde\x1e\x93\x8d\x95\xbb\x10\x0e"
+ "\xf4\x1f\x39\xca\x4d\x43",
+ .c_size = 102,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ }, {
+ .key = /* secp384r1(sha384) */
+ "\x04\x3a\x2f\x62\xe7\x1a\xcf\x24\xd0\x0b\x7c\xe0\xed\x46\x0a\x4f"
+ "\x74\x16\x43\xe9\x1a\x25\x7c\x55\xff\xf0\x29\x68\x66\x20\x91\xf9"
+ "\xdb\x2b\xf6\xb3\x6c\x54\x01\xca\xc7\x6a\x5c\x0d\xeb\x68\xd9\x3c"
+ "\xf1\x01\x74\x1f\xf9\x6c\xe5\x5b\x60\xe9\x7f\x5d\xb3\x12\x80\x2a"
+ "\xd8\x67\x92\xc9\x0e\x4c\x4c\x6b\xa1\xb2\xa8\x1e\xac\x1c\x97\xd9"
+ "\x21\x67\xe5\x1b\x5a\x52\x31\x68\xd6\xee\xf0\x19\xb0\x55\xed\x89"
+ "\x9e",
+ .key_len = 97,
+ .params =
+ "\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04"
+ "\x00\x22",
+ .param_len = 18,
+ .m =
+ "\x8d\xf2\xc0\xe9\xa8\xf3\x8e\x44\xc4\x8c\x1a\xa0\xb8\xd7\x17\xdf"
+ "\xf2\x37\x1b\xc6\xe3\xf5\x62\xcc\x68\xf5\xd5\x0b\xbf\x73\x2b\xb1"
+ "\xb0\x4c\x04\x00\x31\xab\xfe\xc8\xd6\x09\xc8\xf2\xea\xd3\x28\xff",
+ .m_size = 48,
+ .algo = OID_id_ecdsa_with_sha384,
+ .c =
+ "\x30\x66\x02\x31\x00\x9b\x28\x68\xc0\xa1\xea\x8c\x50\xee\x2e\x62"
+ "\x35\x46\xfa\x00\xd8\x2d\x7a\x91\x5f\x49\x2d\x22\x08\x29\xe6\xfb"
+ "\xca\x8c\xd6\xb6\xb4\x3b\x1f\x07\x8f\x15\x02\xfe\x1d\xa2\xa4\xc8"
+ "\xf2\xea\x9d\x11\x1f\x02\x31\x00\xfc\x50\xf6\x43\xbd\x50\x82\x0e"
+ "\xbf\xe3\x75\x24\x49\xac\xfb\xc8\x71\xcd\x8f\x18\x99\xf0\x0f\x13"
+ "\x44\x92\x8c\x86\x99\x65\xb3\x97\x96\x17\x04\xc9\x05\x77\xf1\x8e"
+ "\xab\x8d\x4e\xde\xe6\x6d\x9b\x66",
+ .c_size = 104,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ }, {
+ .key = /* secp384r1(sha512) */
+ "\x04\xb4\xe7\xc1\xeb\x64\x25\x22\x46\xc3\x86\x61\x80\xbe\x1e\x46"
+ "\xcb\xf6\x05\xc2\xee\x73\x83\xbc\xea\x30\x61\x4d\x40\x05\x41\xf4"
+ "\x8c\xe3\x0e\x5c\xf0\x50\xf2\x07\x19\xe8\x4f\x25\xbe\xee\x0c\x95"
+ "\x54\x36\x86\xec\xc2\x20\x75\xf3\x89\xb5\x11\xa1\xb7\xf5\xaf\xbe"
+ "\x81\xe4\xc3\x39\x06\xbd\xe4\xfe\x68\x1c\x6d\x99\x2b\x1b\x63\xfa"
+ "\xdf\x42\x5c\xc2\x5a\xc7\x0c\xf4\x15\xf7\x1b\xa3\x2e\xd7\x00\xac"
+ "\xa3",
+ .key_len = 97,
+ .params =
+ "\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04"
+ "\x00\x22",
+ .param_len = 18,
+ .m =
+ "\xe8\xb7\x52\x7d\x1a\x44\x20\x05\x53\x6b\x3a\x68\xf2\xe7\x6c\xa1"
+ "\xae\x9d\x84\xbb\xba\x52\x43\x3e\x2c\x42\x78\x49\xbf\x78\xb2\x71"
+ "\xeb\xe1\xe0\xe8\x42\x7b\x11\xad\x2b\x99\x05\x1d\x36\xe6\xac\xfc"
+ "\x55\x73\xf0\x15\x63\x39\xb8\x6a\x6a\xc5\x91\x5b\xca\x6a\xa8\x0e",
+ .m_size = 64,
+ .algo = OID_id_ecdsa_with_sha512,
+ .c =
+ "\x30\x63\x02\x2f\x1d\x20\x94\x77\xfe\x31\xfa\x4d\xc6\xef\xda\x02"
+ "\xe7\x0f\x52\x9a\x02\xde\x93\xe8\x83\xe4\x84\x4c\xfc\x6f\x80\xe3"
+ "\xaf\xb3\xd9\xdc\x2b\x43\x0e\x6a\xb3\x53\x6f\x3e\xb3\xc7\xa8\xb3"
+ "\x17\x77\xd1\x02\x30\x63\xf6\xf0\x3d\x5f\x5f\x99\x3f\xde\x3a\x3d"
+ "\x16\xaf\xb4\x52\x6a\xec\x63\xe3\x0c\xec\x50\xdc\xcc\xc4\x6a\x03"
+ "\x5f\x8d\x7a\xf9\xfb\x34\xe4\x8b\x80\xa5\xb6\xda\x2c\x4e\x45\xcf"
+ "\x3c\x93\xff\x50\x5d",
+ .c_size = 101,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ },
+};
+
+/*
* EC-RDSA test vectors are generated by gost-engine.
*/
static const struct akcipher_testvec ecrdsa_tv_template[] = {
@@ -726,7 +1231,7 @@ static const struct akcipher_testvec ecrdsa_tv_template[] = {
static const struct akcipher_testvec pkcs1pad_rsa_tv_template[] = {
{
.key =
- "\x30\x82\x03\x1f\x02\x01\x00\x02\x82\x01\x01\x00\xd7\x1e\x77\x82"
+ "\x30\x82\x04\xa5\x02\x01\x00\x02\x82\x01\x01\x00\xd7\x1e\x77\x82"
"\x8c\x92\x31\xe7\x69\x02\xa2\xd5\x5c\x78\xde\xa2\x0c\x8f\xfe\x28"
"\x59\x31\xdf\x40\x9c\x60\x61\x06\xb9\x2f\x62\x40\x80\x76\xcb\x67"
"\x4a\xb5\x59\x56\x69\x17\x07\xfa\xf9\x4c\xbd\x6c\x37\x7a\x46\x7d"
@@ -742,42 +1247,66 @@ static const struct akcipher_testvec pkcs1pad_rsa_tv_template[] = {
"\x9e\x49\x63\x6e\x02\xc1\xc9\x3a\x9b\xa5\x22\x1b\x07\x95\xd6\x10"
"\x02\x50\xfd\xfd\xd1\x9b\xbe\xab\xc2\xc0\x74\xd7\xec\x00\xfb\x11"
"\x71\xcb\x7a\xdc\x81\x79\x9f\x86\x68\x46\x63\x82\x4d\xb7\xf1\xe6"
- "\x16\x6f\x42\x63\xf4\x94\xa0\xca\x33\xcc\x75\x13\x02\x82\x01\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01"
- "\x02\x82\x01\x00\x62\xb5\x60\x31\x4f\x3f\x66\x16\xc1\x60\xac\x47"
- "\x2a\xff\x6b\x69\x00\x4a\xb2\x5c\xe1\x50\xb9\x18\x74\xa8\xe4\xdc"
- "\xa8\xec\xcd\x30\xbb\xc1\xc6\xe3\xc6\xac\x20\x2a\x3e\x5e\x8b\x12"
- "\xe6\x82\x08\x09\x38\x0b\xab\x7c\xb3\xcc\x9c\xce\x97\x67\xdd\xef"
- "\x95\x40\x4e\x92\xe2\x44\xe9\x1d\xc1\x14\xfd\xa9\xb1\xdc\x71\x9c"
- "\x46\x21\xbd\x58\x88\x6e\x22\x15\x56\xc1\xef\xe0\xc9\x8d\xe5\x80"
- "\x3e\xda\x7e\x93\x0f\x52\xf6\xf5\xc1\x91\x90\x9e\x42\x49\x4f\x8d"
- "\x9c\xba\x38\x83\xe9\x33\xc2\x50\x4f\xec\xc2\xf0\xa8\xb7\x6e\x28"
- "\x25\x56\x6b\x62\x67\xfe\x08\xf1\x56\xe5\x6f\x0e\x99\xf1\xe5\x95"
- "\x7b\xef\xeb\x0a\x2c\x92\x97\x57\x23\x33\x36\x07\xdd\xfb\xae\xf1"
- "\xb1\xd8\x33\xb7\x96\x71\x42\x36\xc5\xa4\xa9\x19\x4b\x1b\x52\x4c"
- "\x50\x69\x91\xf0\x0e\xfa\x80\x37\x4b\xb5\xd0\x2f\xb7\x44\x0d\xd4"
- "\xf8\x39\x8d\xab\x71\x67\x59\x05\x88\x3d\xeb\x48\x48\x33\x88\x4e"
- "\xfe\xf8\x27\x1b\xd6\x55\x60\x5e\x48\xb7\x6d\x9a\xa8\x37\xf9\x7a"
- "\xde\x1b\xcd\x5d\x1a\x30\xd4\xe9\x9e\x5b\x3c\x15\xf8\x9c\x1f\xda"
- "\xd1\x86\x48\x55\xce\x83\xee\x8e\x51\xc7\xde\x32\x12\x47\x7d\x46"
- "\xb8\x35\xdf\x41\x02\x01\x00\x02\x01\x00\x02\x01\x00\x02\x01\x00"
- "\x02\x01\x00",
- .key_len = 804,
+ "\x16\x6f\x42\x63\xf4\x94\xa0\xca\x33\xcc\x75\x13\x02\x03\x01\x00"
+ "\x01\x02\x82\x01\x00\x62\xb5\x60\x31\x4f\x3f\x66\x16\xc1\x60\xac"
+ "\x47\x2a\xff\x6b\x69\x00\x4a\xb2\x5c\xe1\x50\xb9\x18\x74\xa8\xe4"
+ "\xdc\xa8\xec\xcd\x30\xbb\xc1\xc6\xe3\xc6\xac\x20\x2a\x3e\x5e\x8b"
+ "\x12\xe6\x82\x08\x09\x38\x0b\xab\x7c\xb3\xcc\x9c\xce\x97\x67\xdd"
+ "\xef\x95\x40\x4e\x92\xe2\x44\xe9\x1d\xc1\x14\xfd\xa9\xb1\xdc\x71"
+ "\x9c\x46\x21\xbd\x58\x88\x6e\x22\x15\x56\xc1\xef\xe0\xc9\x8d\xe5"
+ "\x80\x3e\xda\x7e\x93\x0f\x52\xf6\xf5\xc1\x91\x90\x9e\x42\x49\x4f"
+ "\x8d\x9c\xba\x38\x83\xe9\x33\xc2\x50\x4f\xec\xc2\xf0\xa8\xb7\x6e"
+ "\x28\x25\x56\x6b\x62\x67\xfe\x08\xf1\x56\xe5\x6f\x0e\x99\xf1\xe5"
+ "\x95\x7b\xef\xeb\x0a\x2c\x92\x97\x57\x23\x33\x36\x07\xdd\xfb\xae"
+ "\xf1\xb1\xd8\x33\xb7\x96\x71\x42\x36\xc5\xa4\xa9\x19\x4b\x1b\x52"
+ "\x4c\x50\x69\x91\xf0\x0e\xfa\x80\x37\x4b\xb5\xd0\x2f\xb7\x44\x0d"
+ "\xd4\xf8\x39\x8d\xab\x71\x67\x59\x05\x88\x3d\xeb\x48\x48\x33\x88"
+ "\x4e\xfe\xf8\x27\x1b\xd6\x55\x60\x5e\x48\xb7\x6d\x9a\xa8\x37\xf9"
+ "\x7a\xde\x1b\xcd\x5d\x1a\x30\xd4\xe9\x9e\x5b\x3c\x15\xf8\x9c\x1f"
+ "\xda\xd1\x86\x48\x55\xce\x83\xee\x8e\x51\xc7\xde\x32\x12\x47\x7d"
+ "\x46\xb8\x35\xdf\x41\x02\x81\x81\x00\xe4\x4c\xae\xde\x16\xfd\x9f"
+ "\x83\x55\x5b\x84\x4a\xcf\x1c\xf1\x37\x95\xad\xca\x29\x7f\x2d\x6e"
+ "\x32\x81\xa4\x2b\x26\x14\x96\x1d\x40\x05\xec\x0c\xaf\x3f\x2c\x6f"
+ "\x2c\xe8\xbf\x1d\xee\xd0\xb3\xef\x7c\x5b\x9e\x88\x4f\x2a\x8b\x0e"
+ "\x4a\xbd\xb7\x8c\xfa\x10\x0e\x3b\xda\x68\xad\x41\x2b\xe4\x96\xfa"
+ "\x7f\x80\x52\x5f\x07\x9f\x0e\x3b\x5e\x96\x45\x1a\x13\x2b\x94\xce"
+ "\x1f\x07\x69\x85\x35\xfc\x69\x63\x5b\xf8\xf8\x3f\xce\x9d\x40\x1e"
+ "\x7c\xad\xfb\x9e\xce\xe0\x01\xf8\xef\x59\x5d\xdc\x00\x79\xab\x8a"
+ "\x3f\x80\xa2\x76\x32\x94\xa9\xea\x65\x02\x81\x81\x00\xf1\x38\x60"
+ "\x90\x0d\x0c\x2e\x3d\x34\xe5\x90\xea\x21\x43\x1f\x68\x63\x16\x7b"
+ "\x25\x8d\xde\x82\x2b\x52\xf8\xa3\xfd\x0f\x39\xe7\xe9\x5e\x32\x75"
+ "\x15\x7d\xd0\xc9\xce\x06\xe5\xfb\xa9\xcb\x22\xe5\xdb\x49\x09\xf2"
+ "\xe6\xb7\xa5\xa7\x75\x2e\x91\x2d\x2b\x5d\xf1\x48\x61\x45\x43\xd7"
+ "\xbd\xfc\x11\x73\xb5\x11\x9f\xb2\x18\x3a\x6f\x36\xa7\xc2\xd3\x18"
+ "\x4d\xf0\xc5\x1f\x70\x8c\x9b\xc5\x1d\x95\xa8\x5a\x9e\x8c\xb1\x4b"
+ "\x6a\x2a\x84\x76\x2c\xd8\x4f\x47\xb0\x81\x84\x02\x45\xf0\x85\xf8"
+ "\x0c\x6d\xa7\x0c\x4d\x2c\xb2\x5b\x81\x70\xfd\x6e\x17\x02\x81\x81"
+ "\x00\x8d\x07\xc5\xfa\x92\x4f\x48\xcb\xd3\xdd\xfe\x02\x4c\xa1\x7f"
+ "\x6d\xab\xfc\x38\xe7\x9b\x95\xcf\xfe\x49\x51\xc6\x09\xf7\x2b\xa8"
+ "\x94\x15\x54\x75\x9d\x88\xb4\x05\x55\xc3\xcd\xd4\x4a\xe4\x08\x53"
+ "\xc8\x09\xbd\x0c\x4d\x83\x65\x75\x85\xbc\x5e\xf8\x2a\xbd\xe2\x5d"
+ "\x1d\x16\x0e\xf9\x34\x89\x38\xaf\x34\x36\x6c\x2c\x22\x44\x22\x81"
+ "\x90\x73\xd9\xea\x3a\xaf\x70\x74\x48\x7c\xc6\xb5\xb0\xdc\xe5\xa9"
+ "\xa8\x76\x4b\xbc\xf7\x00\xf3\x4c\x22\x0f\x44\x62\x1d\x40\x0a\x57"
+ "\xe2\x5b\xdd\x7c\x7b\x9a\xad\xda\x70\x52\x21\x8a\x4c\xc2\xc3\x98"
+ "\x75\x02\x81\x81\x00\xed\x24\x5c\xa2\x21\x81\xa1\x0f\xa1\x2a\x33"
+ "\x0e\x49\xc7\x00\x60\x92\x51\x6e\x9d\x9b\xdc\x6d\x22\x04\x7e\xd6"
+ "\x51\x19\x9f\xf6\xe3\x91\x2c\x8f\xb8\xa2\x29\x19\xcc\x47\x31\xdf"
+ "\xf8\xab\xf0\xd2\x02\x83\xca\x99\x16\xc2\xe2\xc3\x3f\x4b\x99\x83"
+ "\xcb\x87\x9e\x86\x66\xc2\x3e\x91\x21\x80\x66\xf3\xd6\xc5\xcd\xb6"
+ "\xbb\x64\xef\x22\xcf\x48\x94\x58\xe7\x7e\xd5\x7c\x34\x1c\xb7\xa2"
+ "\xd0\x93\xe9\x9f\xb5\x11\x61\xd7\x5f\x37\x0f\x64\x52\x70\x11\x78"
+ "\xcc\x08\x77\xeb\xf8\x30\x1e\xb4\x9e\x1b\x4a\xc7\xa8\x33\x51\xe0"
+ "\xed\xdf\x53\xf6\xdf\x02\x81\x81\x00\x86\xd9\x4c\xee\x65\x61\xc1"
+ "\x19\xa9\xd5\x74\x9b\xd5\xca\xf6\x83\x2b\x06\xb4\x20\xfe\x45\x29"
+ "\xe8\xe3\xfa\xe1\x4f\x28\x8e\x63\x2f\x74\xc3\x3a\x5c\x9a\xf5\x9e"
+ "\x0e\x0d\xc5\xfe\xa0\x4c\x00\xce\x7b\xa4\x19\x17\x59\xaf\x13\x3a"
+ "\x03\x8f\x54\xf5\x60\x39\x2e\xd9\x06\xb3\x7c\xd6\x90\x06\x41\x77"
+ "\xf3\x93\xe1\x7a\x01\x41\xc1\x8f\xfe\x4c\x88\x39\xdb\xde\x71\x9e"
+ "\x58\xd1\x49\x50\x80\xb2\x5a\x4f\x69\x8b\xb8\xfe\x63\xd4\x42\x3d"
+ "\x37\x61\xa8\x4c\xff\xb6\x99\x4c\xf4\x51\xe0\x44\xaa\x69\x79\x3f"
+ "\x81\xa4\x61\x3d\x26\xe9\x04\x52\x64",
+ .key_len = 1193,
/*
* m is SHA256 hash of following message:
* "\x49\x41\xbe\x0a\x0c\xc9\xf6\x35\x51\xe4\x27\x56\x13\x71\x4b\xd0"
@@ -820,17 +1349,15 @@ static const struct kpp_testvec dh_tv_template[] = {
.secret =
#ifdef __LITTLE_ENDIAN
"\x01\x00" /* type */
- "\x15\x02" /* len */
+ "\x11\x02" /* len */
"\x00\x01\x00\x00" /* key_size */
"\x00\x01\x00\x00" /* p_size */
- "\x00\x00\x00\x00" /* q_size */
"\x01\x00\x00\x00" /* g_size */
#else
"\x00\x01" /* type */
- "\x02\x15" /* len */
+ "\x02\x11" /* len */
"\x00\x00\x01\x00" /* key_size */
"\x00\x00\x01\x00" /* p_size */
- "\x00\x00\x00\x00" /* q_size */
"\x00\x00\x00\x01" /* g_size */
#endif
/* xa */
@@ -920,7 +1447,7 @@ static const struct kpp_testvec dh_tv_template[] = {
"\xd3\x34\x49\xad\x64\xa6\xb1\xc0\x59\x28\x75\x60\xa7\x8a\xb0\x11"
"\x56\x89\x42\x74\x11\xf5\xf6\x5e\x6f\x16\x54\x6a\xb1\x76\x4d\x50"
"\x8a\x68\xc1\x5b\x82\xb9\x0d\x00\x32\x50\xed\x88\x87\x48\x92\x17",
- .secret_size = 533,
+ .secret_size = 529,
.b_public_size = 256,
.expected_a_public_size = 256,
.expected_ss_size = 256,
@@ -929,17 +1456,15 @@ static const struct kpp_testvec dh_tv_template[] = {
.secret =
#ifdef __LITTLE_ENDIAN
"\x01\x00" /* type */
- "\x15\x02" /* len */
+ "\x11\x02" /* len */
"\x00\x01\x00\x00" /* key_size */
"\x00\x01\x00\x00" /* p_size */
- "\x00\x00\x00\x00" /* q_size */
"\x01\x00\x00\x00" /* g_size */
#else
"\x00\x01" /* type */
- "\x02\x15" /* len */
+ "\x02\x11" /* len */
"\x00\x00\x01\x00" /* key_size */
"\x00\x00\x01\x00" /* p_size */
- "\x00\x00\x00\x00" /* q_size */
"\x00\x00\x00\x01" /* g_size */
#endif
/* xa */
@@ -1029,13 +1554,1442 @@ static const struct kpp_testvec dh_tv_template[] = {
"\x5e\x5a\x64\xbd\xf6\x85\x04\xe8\x28\x6a\xac\xef\xce\x19\x8e\x9a"
"\xfe\x75\xc0\x27\x69\xe3\xb3\x7b\x21\xa7\xb1\x16\xa4\x85\x23\xee"
"\xb0\x1b\x04\x6e\xbd\xab\x16\xde\xfd\x86\x6b\xa9\x95\xd7\x0b\xfd",
- .secret_size = 533,
+ .secret_size = 529,
.b_public_size = 256,
.expected_a_public_size = 256,
.expected_ss_size = 256,
}
};
+static const struct kpp_testvec ffdhe2048_dh_tv_template[] __maybe_unused = {
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x01" /* len */
+ "\x00\x01\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x01\x10" /* len */
+ "\x00\x00\x01\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x23\x7d\xd0\x06\xfd\x7a\xe5\x7a\x08\xda\x98\x31\xc0\xb3\xd5\x85"
+ "\xe2\x0d\x2a\x91\x5f\x78\x4b\xa6\x62\xd0\xa6\x35\xd4\xef\x86\x39"
+ "\xf1\xdb\x71\x5e\xb0\x11\x2e\xee\x91\x3a\xaa\xf9\xe3\xdf\x8d\x8b"
+ "\x48\x41\xde\xe8\x78\x53\xc5\x5f\x93\xd2\x79\x0d\xbe\x8d\x83\xe8"
+ "\x8f\x00\xd2\xde\x13\x18\x04\x05\x20\x6d\xda\xfa\x1d\x0b\x24\x52"
+ "\x3a\x18\x2b\xe1\x1e\xae\x15\x3b\x0f\xaa\x09\x09\xf6\x01\x98\xe9"
+ "\x81\x5d\x6b\x83\x6e\x55\xf1\x5d\x6f\x6f\x0d\x9d\xa8\x72\x32\x63"
+ "\x60\xe6\x0b\xc5\x22\xe2\xf9\x46\x58\xa2\x1c\x2a\xb0\xd5\xaf\xe3"
+ "\x5b\x03\xb7\x36\xb7\xba\x55\x20\x08\x7c\x51\xd4\x89\x42\x9c\x14"
+ "\x23\xe2\x71\x3e\x15\x2a\x0d\x34\x8a\xde\xad\x84\x11\x15\x72\x18"
+ "\x42\x43\x0a\xe2\x58\x29\xb3\x90\x0f\x56\xd8\x8a\x0f\x0e\xbc\x0e"
+ "\x9c\xe7\xd5\xe6\x5b\xbf\x06\x64\x38\x12\xa5\x8d\x5b\x68\x34\xdd"
+ "\x75\x48\xc9\xa7\xa3\x58\x5a\x1c\xe1\xb2\xc5\xe3\x39\x03\xcf\xab"
+ "\xc2\x14\x07\xaf\x55\x80\xc7\x63\xe4\x03\xeb\xe9\x0a\x25\x61\x85"
+ "\x1d\x0e\x81\x52\x7b\xbc\x4a\x0c\xc8\x59\x6a\xac\x18\xfb\x8c\x0c"
+ "\xb4\x79\xbd\xa1\x4c\xbb\x02\xc9\xd5\x13\x88\x3d\x25\xaa\x77\x49",
+ .b_public =
+ "\x5c\x00\x6f\xda\xfe\x4c\x0c\xc2\x18\xff\xa9\xec\x7a\xbe\x8a\x51"
+ "\x64\x6b\x57\xf8\xed\xe2\x36\x77\xc1\x23\xbf\x56\xa6\x48\x76\x34"
+ "\x0e\xf3\x68\x05\x45\x6a\x98\x5b\x9e\x8b\xc0\x11\x29\xcb\x5b\x66"
+ "\x2d\xc2\xeb\x4c\xf1\x7d\x85\x30\xaa\xd5\xf5\xb8\xd3\x62\x1e\x97"
+ "\x1e\x34\x18\xf8\x76\x8c\x10\xca\x1f\xe4\x5d\x62\xe1\xbe\x61\xef"
+ "\xaf\x2c\x8d\x97\x15\xa5\x86\xd5\xd3\x12\x6f\xec\xe2\xa4\xb2\x5a"
+ "\x35\x1d\xd4\x91\xa6\xef\x13\x09\x65\x9c\x45\xc0\x12\xad\x7f\xee"
+ "\x93\x5d\xfa\x89\x26\x7d\xae\xee\xea\x8c\xa3\xcf\x04\x2d\xa0\xc7"
+ "\xd9\x14\x62\xaf\xdf\xa0\x33\xd7\x5e\x83\xa2\xe6\x0e\x0e\x5d\x77"
+ "\xce\xe6\x72\xe4\xec\x9d\xff\x72\x9f\x38\x95\x19\x96\xba\x4c\xe3"
+ "\x5f\xb8\x46\x4a\x1d\xe9\x62\x7b\xa8\xdc\xe7\x61\x90\x6b\xb9\xd4"
+ "\xad\x0b\xa3\x06\xb3\x70\xfa\xea\x2b\xc4\x2c\xde\x43\x37\xf6\x8d"
+ "\x72\xf0\x86\x9a\xbb\x3b\x8e\x7a\x71\x03\x30\x30\x2a\x5d\xcd\x1e"
+ "\xe4\xd3\x08\x07\x75\x17\x17\x72\x1e\x77\x6c\x98\x0d\x29\x7f\xac"
+ "\xe7\xb2\xee\xa9\x1c\x33\x9d\x08\x39\xe1\xd8\x5b\xe5\xbc\x48\xb2"
+ "\xb6\xdf\xcd\xa0\x42\x06\xcc\xfb\xed\x60\x6f\xbc\x57\xac\x09\x45",
+ .expected_a_public =
+ "\x8b\xdb\xc1\xf7\xc6\xba\xa1\x38\x95\x6a\xa1\xb6\x04\x5e\xae\x52"
+ "\x72\xfc\xef\x2d\x9d\x71\x05\x9c\xd3\x02\xa9\xfb\x55\x0f\xfa\xc9"
+ "\xb4\x34\x51\xa3\x28\x89\x8d\x93\x92\xcb\xd9\xb5\xb9\x66\xfc\x67"
+ "\x15\x92\x6f\x73\x85\x15\xe2\xfc\x11\x6b\x97\x8c\x4b\x0f\x12\xfa"
+ "\x8d\x72\x76\x9b\x8f\x3b\xfe\x31\xbe\x42\x88\x4c\xd2\xb2\x70\xa6"
+ "\xa5\xe3\x7e\x73\x07\x12\x36\xaa\xc9\x5c\x83\xe1\xf1\x46\x41\x4f"
+ "\x7c\x52\xaf\xdc\xa4\xe6\x82\xa3\x86\x83\x47\x5a\x12\x3a\x0c\xe3"
+ "\xdd\xdb\x94\x03\x2a\x59\x91\xa0\x19\xe5\xf8\x07\xdd\x54\x6a\x22"
+ "\x43\xb7\xf3\x74\xd7\xb9\x30\xfe\x9c\xe8\xd1\xcf\x06\x43\x68\xb9"
+ "\x54\x8f\x54\xa2\xe5\x3c\xf2\xc3\x4c\xee\xd4\x7c\x5d\x0e\xb1\x7b"
+ "\x16\x68\xb5\xb3\x7d\xd4\x11\x83\x5c\x77\x17\xc4\xf0\x59\x76\x7a"
+ "\x83\x40\xe5\xd9\x4c\x76\x23\x5b\x17\x6d\xee\x4a\x92\x68\x4b\x89"
+ "\xa0\x6d\x23\x8c\x80\x31\x33\x3a\x12\xf4\x50\xa6\xcb\x13\x97\x01"
+ "\xb8\x2c\xe6\xd2\x38\xdf\xd0\x7f\xc6\x27\x19\x0e\xb2\x07\xfd\x1f"
+ "\x1b\x9c\x1b\x87\xf9\x73\x6a\x3f\x7f\xb0\xf9\x2f\x3c\x19\x9f\xc9"
+ "\x8f\x97\x21\x0e\x8e\xbb\x1a\x17\x20\x15\xdd\xc6\x42\x60\xae\x4d",
+ .expected_ss =
+ "\xf3\x0e\x64\x7b\x66\xd7\x82\x7e\xab\x7e\x4a\xbe\x13\x6f\x43\x3d"
+ "\xea\x4f\x1f\x8b\x9d\x41\x56\x71\xe1\x06\x96\x02\x68\xfa\x44\x6e"
+ "\xe7\xf2\x26\xd4\x01\x4a\xf0\x28\x25\x76\xad\xd7\xe0\x17\x74\xfe"
+ "\xf9\xe1\x6d\xd3\xf7\xc7\xdf\xc0\x62\xa5\xf3\x4e\x1b\x5c\x77\x2a"
+ "\xfb\x0b\x87\xc3\xde\x1e\xc1\xe0\xd3\x7a\xb8\x02\x02\xec\x9c\x97"
+ "\xfb\x34\xa0\x20\x10\x23\x87\xb2\x9a\x72\xe3\x3d\xb2\x18\x50\xf3"
+ "\x6a\xd3\xd3\x19\xc4\x36\xd5\x59\xd6\xd6\xa7\x5c\xc3\xf9\x09\x33"
+ "\xa1\xf5\xb9\x4b\xf3\x0b\xe1\x4f\x79\x6b\x45\xf2\xec\x8b\xe5\x69"
+ "\x9f\xc6\x05\x01\xfe\x3a\x13\xfd\x6d\xea\x03\x83\x29\x7c\x7f\xf5"
+ "\x41\x55\x95\xde\x7e\x62\xae\xaf\x28\xdb\x7c\xa9\x90\x1e\xb2\xb1"
+ "\x1b\xef\xf1\x2e\xde\x47\xaa\xa8\x92\x9a\x49\x3d\xc0\xe0\x8d\xbb"
+ "\x0c\x42\x86\xaf\x00\xce\xb0\xab\x22\x7c\xe9\xbe\xb9\x72\x2f\xcf"
+ "\x5e\x5d\x62\x52\x2a\xd1\xfe\xcc\xa2\xf3\x40\xfd\x01\xa7\x54\x0a"
+ "\xa1\xfb\x1c\xf2\x44\xa6\x47\x30\x5a\xba\x2a\x05\xff\xd0\x6c\xab"
+ "\xeb\xe6\x8f\xf6\xd7\x73\xa3\x0e\x6c\x0e\xcf\xfd\x8e\x16\x5d\xe0"
+ "\x2c\x11\x05\x82\x3c\x22\x16\x6c\x52\x61\xcf\xbb\xff\xf8\x06\xd0",
+ .secret_size = 272,
+ .b_public_size = 256,
+ .expected_a_public_size = 256,
+ .expected_ss_size = 256,
+ },
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x00" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x00\x10" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#endif
+ .b_secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x01" /* len */
+ "\x00\x01\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x01\x10" /* len */
+ "\x00\x00\x01\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x23\x7d\xd0\x06\xfd\x7a\xe5\x7a\x08\xda\x98\x31\xc0\xb3\xd5\x85"
+ "\xe2\x0d\x2a\x91\x5f\x78\x4b\xa6\x62\xd0\xa6\x35\xd4\xef\x86\x39"
+ "\xf1\xdb\x71\x5e\xb0\x11\x2e\xee\x91\x3a\xaa\xf9\xe3\xdf\x8d\x8b"
+ "\x48\x41\xde\xe8\x78\x53\xc5\x5f\x93\xd2\x79\x0d\xbe\x8d\x83\xe8"
+ "\x8f\x00\xd2\xde\x13\x18\x04\x05\x20\x6d\xda\xfa\x1d\x0b\x24\x52"
+ "\x3a\x18\x2b\xe1\x1e\xae\x15\x3b\x0f\xaa\x09\x09\xf6\x01\x98\xe9"
+ "\x81\x5d\x6b\x83\x6e\x55\xf1\x5d\x6f\x6f\x0d\x9d\xa8\x72\x32\x63"
+ "\x60\xe6\x0b\xc5\x22\xe2\xf9\x46\x58\xa2\x1c\x2a\xb0\xd5\xaf\xe3"
+ "\x5b\x03\xb7\x36\xb7\xba\x55\x20\x08\x7c\x51\xd4\x89\x42\x9c\x14"
+ "\x23\xe2\x71\x3e\x15\x2a\x0d\x34\x8a\xde\xad\x84\x11\x15\x72\x18"
+ "\x42\x43\x0a\xe2\x58\x29\xb3\x90\x0f\x56\xd8\x8a\x0f\x0e\xbc\x0e"
+ "\x9c\xe7\xd5\xe6\x5b\xbf\x06\x64\x38\x12\xa5\x8d\x5b\x68\x34\xdd"
+ "\x75\x48\xc9\xa7\xa3\x58\x5a\x1c\xe1\xb2\xc5\xe3\x39\x03\xcf\xab"
+ "\xc2\x14\x07\xaf\x55\x80\xc7\x63\xe4\x03\xeb\xe9\x0a\x25\x61\x85"
+ "\x1d\x0e\x81\x52\x7b\xbc\x4a\x0c\xc8\x59\x6a\xac\x18\xfb\x8c\x0c"
+ "\xb4\x79\xbd\xa1\x4c\xbb\x02\xc9\xd5\x13\x88\x3d\x25\xaa\x77\x49",
+ .b_public =
+ "\x8b\xdb\xc1\xf7\xc6\xba\xa1\x38\x95\x6a\xa1\xb6\x04\x5e\xae\x52"
+ "\x72\xfc\xef\x2d\x9d\x71\x05\x9c\xd3\x02\xa9\xfb\x55\x0f\xfa\xc9"
+ "\xb4\x34\x51\xa3\x28\x89\x8d\x93\x92\xcb\xd9\xb5\xb9\x66\xfc\x67"
+ "\x15\x92\x6f\x73\x85\x15\xe2\xfc\x11\x6b\x97\x8c\x4b\x0f\x12\xfa"
+ "\x8d\x72\x76\x9b\x8f\x3b\xfe\x31\xbe\x42\x88\x4c\xd2\xb2\x70\xa6"
+ "\xa5\xe3\x7e\x73\x07\x12\x36\xaa\xc9\x5c\x83\xe1\xf1\x46\x41\x4f"
+ "\x7c\x52\xaf\xdc\xa4\xe6\x82\xa3\x86\x83\x47\x5a\x12\x3a\x0c\xe3"
+ "\xdd\xdb\x94\x03\x2a\x59\x91\xa0\x19\xe5\xf8\x07\xdd\x54\x6a\x22"
+ "\x43\xb7\xf3\x74\xd7\xb9\x30\xfe\x9c\xe8\xd1\xcf\x06\x43\x68\xb9"
+ "\x54\x8f\x54\xa2\xe5\x3c\xf2\xc3\x4c\xee\xd4\x7c\x5d\x0e\xb1\x7b"
+ "\x16\x68\xb5\xb3\x7d\xd4\x11\x83\x5c\x77\x17\xc4\xf0\x59\x76\x7a"
+ "\x83\x40\xe5\xd9\x4c\x76\x23\x5b\x17\x6d\xee\x4a\x92\x68\x4b\x89"
+ "\xa0\x6d\x23\x8c\x80\x31\x33\x3a\x12\xf4\x50\xa6\xcb\x13\x97\x01"
+ "\xb8\x2c\xe6\xd2\x38\xdf\xd0\x7f\xc6\x27\x19\x0e\xb2\x07\xfd\x1f"
+ "\x1b\x9c\x1b\x87\xf9\x73\x6a\x3f\x7f\xb0\xf9\x2f\x3c\x19\x9f\xc9"
+ "\x8f\x97\x21\x0e\x8e\xbb\x1a\x17\x20\x15\xdd\xc6\x42\x60\xae\x4d",
+ .secret_size = 16,
+ .b_secret_size = 272,
+ .b_public_size = 256,
+ .expected_a_public_size = 256,
+ .expected_ss_size = 256,
+ .genkey = true,
+ },
+};
+
+static const struct kpp_testvec ffdhe3072_dh_tv_template[] __maybe_unused = {
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x90\x01" /* len */
+ "\x80\x01\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x01\x90" /* len */
+ "\x00\x00\x01\x80" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x6b\xb4\x97\x23\xfa\xc8\x5e\xa9\x7b\x63\xe7\x3e\x0e\x99\xc3\xb9"
+ "\xda\xb7\x48\x0d\xc3\xb1\xbf\x4f\x17\xc7\xa9\x51\xf6\x64\xff\xc4"
+ "\x31\x58\x87\x25\x83\x2c\x00\xf0\x41\x29\xf7\xee\xf9\xe6\x36\x76"
+ "\xd6\x3a\x24\xbe\xa7\x07\x0b\x93\xc7\x9f\x6c\x75\x0a\x26\x75\x76"
+ "\xe3\x0c\x42\xe0\x00\x04\x69\xd9\xec\x0b\x59\x54\x28\x8f\xd7\x9a"
+ "\x63\xf4\x5b\xdf\x85\x65\xc4\xe1\x95\x27\x4a\x42\xad\x36\x47\xa9"
+ "\x0a\xf8\x14\x1c\xf3\x94\x3b\x7e\x47\x99\x35\xa8\x18\xec\x70\x10"
+ "\xdf\xcb\xd2\x78\x88\xc1\x2d\x59\x93\xc1\xa4\x6d\xd7\x1d\xb9\xd5"
+ "\xf8\x30\x06\x7f\x98\x90\x0c\x74\x5e\x89\x2f\x64\x5a\xad\x5f\x53"
+ "\xb2\xa3\xa8\x83\xbf\xfc\x37\xef\xb8\x36\x0a\x5c\x62\x81\x64\x74"
+ "\x16\x2f\x45\x39\x2a\x91\x26\x87\xc0\x12\xcc\x75\x11\xa3\xa1\xc5"
+ "\xae\x20\xcf\xcb\x20\x25\x6b\x7a\x31\x93\x9d\x38\xb9\x57\x72\x46"
+ "\xd4\x84\x65\x87\xf1\xb5\xd3\xab\xfc\xc3\x4d\x40\x92\x94\x1e\xcd"
+ "\x1c\x87\xec\x3f\xcd\xbe\xd0\x95\x6b\x40\x02\xdd\x62\xeb\x0a\xda"
+ "\x4f\xbe\x8e\x32\x48\x8b\x6d\x83\xa0\x96\x62\x23\xec\x83\x91\x44"
+ "\xf9\x72\x01\xac\xa0\xe4\x72\x1d\x5a\x75\x05\x57\x90\xae\x7e\xb4"
+ "\x71\x39\x01\x05\xdc\xe9\xee\xcb\xf0\x61\x28\x91\x69\x8c\x31\x03"
+ "\x7a\x92\x15\xa1\x58\x67\x3d\x70\x82\xa6\x2c\xfe\x10\x56\x58\xd3"
+ "\x94\x67\xe1\xbe\xee\xc1\x64\x5c\x4b\xc8\x28\x3d\xc5\x66\x3a\xab"
+ "\x22\xc1\x7e\xa1\xbb\xf3\x19\x3b\xda\x46\x82\x45\xd4\x3c\x7c\xc6"
+ "\xce\x1f\x7f\x95\xa2\x17\xff\x88\xba\xd6\x4d\xdb\xd2\xea\xde\x39"
+ "\xd6\xa5\x18\x73\xbb\x64\x6e\x79\xe9\xdc\x3f\x92\x7f\xda\x1f\x49"
+ "\x33\x70\x65\x73\xa2\xd9\x06\xb8\x1b\x29\x29\x1a\xe0\xa3\xe6\x05"
+ "\x9a\xa8\xc2\x4e\x7a\x78\x1d\x22\x57\x21\xc8\xa3\x8d\x66\x3e\x23",
+ .b_public =
+ "\x73\x40\x8b\xce\xe8\x6a\x1c\x03\x50\x54\x42\x36\x22\xc6\x1d\xe8"
+ "\xe1\xef\x5c\x89\xa5\x55\xc1\xc4\x1c\xd7\x4f\xee\x5d\xba\x62\x60"
+ "\xfe\x93\x2f\xfd\x93\x2c\x8f\x70\xc6\x47\x17\x25\xb2\x95\xd7\x7d"
+ "\x41\x81\x4d\x52\x1c\xbe\x4d\x57\x3e\x26\x51\x28\x03\x8f\x67\xf5"
+ "\x22\x16\x1c\x67\xf7\x62\xcb\xfd\xa3\xee\x8d\xe0\xfa\x15\x9a\x53"
+ "\xbe\x7b\x9f\xc0\x12\x7a\xfc\x5e\x77\x2d\x60\x06\xba\x71\xc5\xca"
+ "\xd7\x26\xaf\x3b\xba\x6f\xd3\xc4\x82\x57\x19\x26\xb0\x16\x7b\xbd"
+ "\x83\xf2\x21\x03\x79\xff\x0a\x6f\xc5\x7b\x00\x15\xad\x5b\xf4\x42"
+ "\x1f\xcb\x7f\x3d\x34\x77\x3c\xc3\xe0\x38\xa5\x40\x51\xbe\x6f\xd9"
+ "\xc9\x77\x9c\xfc\x0d\xc1\x8e\xef\x0f\xaa\x5e\xa8\xbb\x16\x4a\x3e"
+ "\x26\x55\xae\xc1\xb6\x3e\xfd\x73\xf7\x59\xd2\xe5\x4b\x91\x8e\x28"
+ "\x77\x1e\x5a\xe2\xcd\xce\x92\x35\xbb\x1e\xbb\xcf\x79\x94\xdf\x31"
+ "\xde\x31\xa8\x75\xf6\xe0\xaa\x2e\xe9\x4f\x44\xc8\xba\xb9\xab\x80"
+ "\x29\xa1\xea\x58\x2e\x40\x96\xa0\x1a\xf5\x2c\x38\x47\x43\x5d\x26"
+ "\x2c\xd8\xad\xea\xd3\xad\xe8\x51\x49\xad\x45\x2b\x25\x7c\xde\xe4"
+ "\xaf\x03\x2a\x39\x26\x86\x66\x10\xbc\xa8\x71\xda\xe0\xe8\xf1\xdd"
+ "\x50\xff\x44\xb2\xd3\xc7\xff\x66\x63\xf6\x42\xe3\x97\x9d\x9e\xf4"
+ "\xa6\x89\xb9\xab\x12\x17\xf2\x85\x56\x9c\x6b\x24\x71\x83\x57\x7d"
+ "\x3c\x7b\x2b\x88\x92\x19\xd7\x1a\x00\xd5\x38\x94\x43\x60\x4d\xa7"
+ "\x12\x9e\x0d\xf6\x5c\x9a\xd3\xe2\x9e\xb1\x21\xe8\xe2\x9e\xe9\x1e"
+ "\x9d\xa5\x94\x95\xa6\x3d\x12\x15\xd8\x8b\xac\xe0\x8c\xde\xe6\x40"
+ "\x98\xaa\x5e\x55\x4f\x3d\x86\x87\x0d\xe3\xc6\x68\x15\xe6\xde\x17"
+ "\x78\x21\xc8\x6c\x06\xc7\x94\x56\xb4\xaf\xa2\x35\x0b\x0c\x97\xd7"
+ "\xa4\x12\xee\xf4\xd2\xef\x80\x28\xb3\xee\xe9\x15\x8b\x01\x32\x79",
+ .expected_a_public =
+ "\x1b\x6a\xba\xea\xa3\xcc\x50\x69\xa9\x41\x89\xaf\x04\xe1\x44\x22"
+ "\x97\x20\xd1\xf6\x1e\xcb\x64\x36\x6f\xee\x0b\x16\xc1\xd9\x91\xbe"
+ "\x57\xc8\xd9\xf2\xa1\x96\x91\xec\x41\xc7\x79\x00\x1a\x48\x25\x55"
+ "\xbe\xf3\x20\x8c\x38\xc6\x7b\xf2\x8b\x5a\xc3\xb5\x87\x0a\x86\x3d"
+ "\xb7\xd6\xce\xb0\x96\x2e\x5d\xc4\x00\x5e\x42\xe4\xe5\x50\x4f\xb8"
+ "\x6f\x18\xa4\xe1\xd3\x20\xfc\x3c\xf5\x0a\xff\x23\xa6\x5b\xb4\x17"
+ "\x3e\x7b\xdf\xb9\xb5\x3c\x1b\x76\x29\xcd\xb4\x46\x4f\x27\x8f\xd2"
+ "\xe8\x27\x66\xdb\xe8\xb3\xf5\xe1\xd0\x04\xcd\x89\xff\xba\x76\x67"
+ "\xe8\x4d\xcf\x86\x1c\x8a\xd1\xcf\x99\x27\xfb\xa9\x78\xcc\x94\xaf"
+ "\x3d\x04\xfd\x25\xc0\x47\xfa\x29\x80\x05\xf4\xde\xad\xdb\xab\x12"
+ "\xb0\x2b\x8e\xca\x02\x06\x6d\xad\x3e\x09\xb1\x22\xa3\xf5\x4c\x6d"
+ "\x69\x99\x58\x8b\xd8\x45\x2e\xe0\xc9\x3c\xf7\x92\xce\x21\x90\x6b"
+ "\x3b\x65\x9f\x64\x79\x8d\x67\x22\x1a\x37\xd3\xee\x51\xe2\xe7\x5a"
+ "\x93\x51\xaa\x3c\x4b\x04\x16\x32\xef\xe3\x66\xbe\x18\x94\x88\x64"
+ "\x79\xce\x06\x3f\xb8\xd6\xee\xdc\x13\x79\x6f\x20\x14\xc2\x6b\xce"
+ "\xc8\xda\x42\xa5\x93\x5b\xe4\x7f\x1a\xe6\xda\x0f\xb3\xc1\x5f\x30"
+ "\x50\x76\xe8\x37\x3d\xca\x77\x2c\xa8\xe4\x3b\xf9\x6f\xe0\x17\xed"
+ "\x0e\xef\xb7\x31\x14\xb5\xea\xd9\x39\x22\x89\xb6\x40\x57\xcc\x84"
+ "\xef\x73\xa7\xe9\x27\x21\x85\x89\xfa\xaf\x03\xda\x9c\x8b\xfd\x52"
+ "\x7d\xb0\xa4\xe4\xf9\xd8\x90\x55\xc4\x39\xd6\x9d\xaf\x3b\xce\xac"
+ "\xaa\x36\x14\x7a\x9b\x8b\x12\x43\xe1\xca\x61\xae\x46\x5b\xe7\xe5"
+ "\x88\x32\x80\xa0\x2d\x51\xbb\x2f\xea\xeb\x3c\x71\xb2\xae\xce\xca"
+ "\x61\xd2\x76\xe0\x45\x46\x78\x4e\x09\x2d\xc2\x54\xc2\xa9\xc7\xa8"
+ "\x55\x8e\x72\xa4\x8b\x8a\xc9\x01\xdb\xe9\x58\x11\xa1\xc4\xe7\x12",
+ .expected_ss =
+ "\x47\x8e\xb2\x19\x09\xf0\x46\x99\x6b\x41\x86\xf7\x34\xad\xbf\x2a"
+ "\x18\x1b\x7d\xec\xa9\xb2\x47\x2f\x40\xfb\x9a\x64\x30\x44\xf3\x4c"
+ "\x01\x67\xad\x57\x5a\xbc\xd4\xc8\xef\x7e\x8a\x14\x74\x1d\x6d\x8c"
+ "\x7b\xce\xc5\x57\x5f\x95\xe8\x72\xba\xdf\xa3\xcd\x00\xbe\x09\x4c"
+ "\x06\x72\xe7\x17\xb0\xe5\xe5\xb7\x20\xa5\xcb\xd9\x68\x99\xad\x3f"
+ "\xde\xf3\xde\x1d\x1c\x00\x74\xd2\xd1\x57\x55\x5d\xce\x76\x0c\xc4"
+ "\x7a\xc4\x65\x7c\x19\x17\x0a\x09\x66\x7d\x3a\xab\xf7\x61\x3a\xe3"
+ "\x5b\xac\xcf\x69\xb0\x8b\xee\x5d\x28\x36\xbb\x3f\x74\xce\x6e\x38"
+ "\x1e\x39\xab\x26\xca\x89\xdc\x58\x59\xcb\x95\xe4\xbc\xd6\x19\x48"
+ "\xd0\x55\x68\x7b\xb4\x27\x95\x3c\xd9\x58\x10\x4f\x8f\x55\x1c\x3f"
+ "\x04\xce\x89\x1f\x82\x28\xe9\x48\x17\x47\x8f\xee\xb7\x8f\xeb\xb1"
+ "\x29\xa8\x23\x18\x73\x33\x9f\x83\x08\xca\xcd\x54\x6e\xca\xec\x78"
+ "\x7b\x16\x83\x3f\xdb\x0a\xef\xfd\x87\x94\x19\x08\x6e\x6e\x22\x57"
+ "\xd7\xd2\x79\xf9\xf6\xeb\xe0\x6c\x93\x9d\x95\xfa\x41\x7a\xa9\xd6"
+ "\x2a\xa3\x26\x9b\x24\x1b\x8b\xa0\xed\x04\xb2\xe4\x6c\x4e\xc4\x3f"
+ "\x61\xe5\xe0\x4d\x09\x28\xaf\x58\x35\x25\x0b\xd5\x38\x18\x69\x51"
+ "\x18\x51\x73\x7b\x28\x19\x9f\xe4\x69\xfc\x2c\x25\x08\x99\x8f\x62"
+ "\x65\x62\xa5\x28\xf1\xf4\xfb\x02\x29\x27\xb0\x5e\xbb\x4f\xf9\x1a"
+ "\xa7\xc4\x38\x63\x5b\x01\xfe\x00\x66\xe3\x47\x77\x21\x85\x17\xd5"
+ "\x34\x19\xd3\x87\xab\x44\x62\x08\x59\xb2\x6b\x1f\x21\x0c\x23\x84"
+ "\xf7\xba\x92\x67\xf9\x16\x85\x6a\xe0\xeb\xe7\x4f\x06\x80\x81\x81"
+ "\x28\x9c\xe8\x2e\x71\x97\x48\xe0\xd1\xbc\xce\xe9\x42\x2c\x89\xdf"
+ "\x0b\xa9\xa1\x07\x84\x33\x78\x7f\x49\x2f\x1c\x55\xc3\x7f\xc3\x37"
+ "\x40\xdf\x13\xf4\xa0\x21\x79\x6e\x3a\xe3\xb8\x23\x9e\x8a\x6e\x9c",
+ .secret_size = 400,
+ .b_public_size = 384,
+ .expected_a_public_size = 384,
+ .expected_ss_size = 384,
+ },
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x00" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x00\x10" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#endif
+ .b_secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x90\x01" /* len */
+ "\x80\x01\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x01\x90" /* len */
+ "\x00\x00\x01\x80" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x6b\xb4\x97\x23\xfa\xc8\x5e\xa9\x7b\x63\xe7\x3e\x0e\x99\xc3\xb9"
+ "\xda\xb7\x48\x0d\xc3\xb1\xbf\x4f\x17\xc7\xa9\x51\xf6\x64\xff\xc4"
+ "\x31\x58\x87\x25\x83\x2c\x00\xf0\x41\x29\xf7\xee\xf9\xe6\x36\x76"
+ "\xd6\x3a\x24\xbe\xa7\x07\x0b\x93\xc7\x9f\x6c\x75\x0a\x26\x75\x76"
+ "\xe3\x0c\x42\xe0\x00\x04\x69\xd9\xec\x0b\x59\x54\x28\x8f\xd7\x9a"
+ "\x63\xf4\x5b\xdf\x85\x65\xc4\xe1\x95\x27\x4a\x42\xad\x36\x47\xa9"
+ "\x0a\xf8\x14\x1c\xf3\x94\x3b\x7e\x47\x99\x35\xa8\x18\xec\x70\x10"
+ "\xdf\xcb\xd2\x78\x88\xc1\x2d\x59\x93\xc1\xa4\x6d\xd7\x1d\xb9\xd5"
+ "\xf8\x30\x06\x7f\x98\x90\x0c\x74\x5e\x89\x2f\x64\x5a\xad\x5f\x53"
+ "\xb2\xa3\xa8\x83\xbf\xfc\x37\xef\xb8\x36\x0a\x5c\x62\x81\x64\x74"
+ "\x16\x2f\x45\x39\x2a\x91\x26\x87\xc0\x12\xcc\x75\x11\xa3\xa1\xc5"
+ "\xae\x20\xcf\xcb\x20\x25\x6b\x7a\x31\x93\x9d\x38\xb9\x57\x72\x46"
+ "\xd4\x84\x65\x87\xf1\xb5\xd3\xab\xfc\xc3\x4d\x40\x92\x94\x1e\xcd"
+ "\x1c\x87\xec\x3f\xcd\xbe\xd0\x95\x6b\x40\x02\xdd\x62\xeb\x0a\xda"
+ "\x4f\xbe\x8e\x32\x48\x8b\x6d\x83\xa0\x96\x62\x23\xec\x83\x91\x44"
+ "\xf9\x72\x01\xac\xa0\xe4\x72\x1d\x5a\x75\x05\x57\x90\xae\x7e\xb4"
+ "\x71\x39\x01\x05\xdc\xe9\xee\xcb\xf0\x61\x28\x91\x69\x8c\x31\x03"
+ "\x7a\x92\x15\xa1\x58\x67\x3d\x70\x82\xa6\x2c\xfe\x10\x56\x58\xd3"
+ "\x94\x67\xe1\xbe\xee\xc1\x64\x5c\x4b\xc8\x28\x3d\xc5\x66\x3a\xab"
+ "\x22\xc1\x7e\xa1\xbb\xf3\x19\x3b\xda\x46\x82\x45\xd4\x3c\x7c\xc6"
+ "\xce\x1f\x7f\x95\xa2\x17\xff\x88\xba\xd6\x4d\xdb\xd2\xea\xde\x39"
+ "\xd6\xa5\x18\x73\xbb\x64\x6e\x79\xe9\xdc\x3f\x92\x7f\xda\x1f\x49"
+ "\x33\x70\x65\x73\xa2\xd9\x06\xb8\x1b\x29\x29\x1a\xe0\xa3\xe6\x05"
+ "\x9a\xa8\xc2\x4e\x7a\x78\x1d\x22\x57\x21\xc8\xa3\x8d\x66\x3e\x23",
+ .b_public =
+ "\x1b\x6a\xba\xea\xa3\xcc\x50\x69\xa9\x41\x89\xaf\x04\xe1\x44\x22"
+ "\x97\x20\xd1\xf6\x1e\xcb\x64\x36\x6f\xee\x0b\x16\xc1\xd9\x91\xbe"
+ "\x57\xc8\xd9\xf2\xa1\x96\x91\xec\x41\xc7\x79\x00\x1a\x48\x25\x55"
+ "\xbe\xf3\x20\x8c\x38\xc6\x7b\xf2\x8b\x5a\xc3\xb5\x87\x0a\x86\x3d"
+ "\xb7\xd6\xce\xb0\x96\x2e\x5d\xc4\x00\x5e\x42\xe4\xe5\x50\x4f\xb8"
+ "\x6f\x18\xa4\xe1\xd3\x20\xfc\x3c\xf5\x0a\xff\x23\xa6\x5b\xb4\x17"
+ "\x3e\x7b\xdf\xb9\xb5\x3c\x1b\x76\x29\xcd\xb4\x46\x4f\x27\x8f\xd2"
+ "\xe8\x27\x66\xdb\xe8\xb3\xf5\xe1\xd0\x04\xcd\x89\xff\xba\x76\x67"
+ "\xe8\x4d\xcf\x86\x1c\x8a\xd1\xcf\x99\x27\xfb\xa9\x78\xcc\x94\xaf"
+ "\x3d\x04\xfd\x25\xc0\x47\xfa\x29\x80\x05\xf4\xde\xad\xdb\xab\x12"
+ "\xb0\x2b\x8e\xca\x02\x06\x6d\xad\x3e\x09\xb1\x22\xa3\xf5\x4c\x6d"
+ "\x69\x99\x58\x8b\xd8\x45\x2e\xe0\xc9\x3c\xf7\x92\xce\x21\x90\x6b"
+ "\x3b\x65\x9f\x64\x79\x8d\x67\x22\x1a\x37\xd3\xee\x51\xe2\xe7\x5a"
+ "\x93\x51\xaa\x3c\x4b\x04\x16\x32\xef\xe3\x66\xbe\x18\x94\x88\x64"
+ "\x79\xce\x06\x3f\xb8\xd6\xee\xdc\x13\x79\x6f\x20\x14\xc2\x6b\xce"
+ "\xc8\xda\x42\xa5\x93\x5b\xe4\x7f\x1a\xe6\xda\x0f\xb3\xc1\x5f\x30"
+ "\x50\x76\xe8\x37\x3d\xca\x77\x2c\xa8\xe4\x3b\xf9\x6f\xe0\x17\xed"
+ "\x0e\xef\xb7\x31\x14\xb5\xea\xd9\x39\x22\x89\xb6\x40\x57\xcc\x84"
+ "\xef\x73\xa7\xe9\x27\x21\x85\x89\xfa\xaf\x03\xda\x9c\x8b\xfd\x52"
+ "\x7d\xb0\xa4\xe4\xf9\xd8\x90\x55\xc4\x39\xd6\x9d\xaf\x3b\xce\xac"
+ "\xaa\x36\x14\x7a\x9b\x8b\x12\x43\xe1\xca\x61\xae\x46\x5b\xe7\xe5"
+ "\x88\x32\x80\xa0\x2d\x51\xbb\x2f\xea\xeb\x3c\x71\xb2\xae\xce\xca"
+ "\x61\xd2\x76\xe0\x45\x46\x78\x4e\x09\x2d\xc2\x54\xc2\xa9\xc7\xa8"
+ "\x55\x8e\x72\xa4\x8b\x8a\xc9\x01\xdb\xe9\x58\x11\xa1\xc4\xe7\x12",
+ .secret_size = 16,
+ .b_secret_size = 400,
+ .b_public_size = 384,
+ .expected_a_public_size = 384,
+ .expected_ss_size = 384,
+ .genkey = true,
+ },
+};
+
+static const struct kpp_testvec ffdhe4096_dh_tv_template[] __maybe_unused = {
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x02" /* len */
+ "\x00\x02\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x02\x10" /* len */
+ "\x00\x00\x02\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x1a\x48\xf3\x6c\x61\x03\x42\x43\xd7\x42\x3b\xfa\xdb\x55\x6f\xa2"
+ "\xe1\x79\x52\x0b\x47\xc5\x03\x60\x2f\x26\xb9\x1a\x14\x15\x1a\xd9"
+ "\xe0\xbb\xa7\x82\x63\x41\xec\x26\x55\x00\xab\xe5\x21\x9d\x31\x14"
+ "\x0e\xe2\xc2\xb2\xb8\x37\xe6\xc3\x5a\xab\xae\x25\xdb\x71\x1e\xed"
+ "\xe8\x75\x9a\x04\xa7\x92\x2a\x99\x7e\xc0\x5b\x64\x75\x7f\xe5\xb5"
+ "\xdb\x6c\x95\x4f\xe9\xdc\x39\x76\x79\xb0\xf7\x00\x30\x8e\x86\xe7"
+ "\x36\xd1\xd2\x0c\x68\x7b\x94\xe9\x91\x85\x08\x86\xbc\x64\x87\xd2"
+ "\xf5\x5b\xaf\x03\xf6\x5f\x28\x25\xf1\xa3\x20\x5c\x1b\xb5\x26\x45"
+ "\x9a\x47\xab\xd6\xad\x49\xab\x92\x8e\x62\x6f\x48\x31\xea\xf6\x76"
+ "\xff\xa2\xb6\x28\x78\xef\x59\xc3\x71\x5d\xa8\xd9\x70\x89\xcc\xe2"
+ "\x63\x58\x5e\x3a\xa2\xa2\x88\xbf\x77\x20\x84\x33\x65\x64\x4e\x73"
+ "\xe5\x08\xd5\x89\x23\xd6\x07\xac\x29\x65\x2e\x02\xa8\x35\x96\x48"
+ "\xe7\x5d\x43\x6a\x42\xcc\xda\x98\xc4\x75\x90\x2e\xf6\xc4\xbf\xd4"
+ "\xbc\x31\x14\x0d\x54\x30\x11\xb2\xc9\xcf\xbb\xba\xbc\xc6\xf2\xcf"
+ "\xfe\x4a\x9d\xf3\xec\x78\x5d\x5d\xb4\x99\xd0\x67\x0f\x5a\x21\x1c"
+ "\x7b\x95\x2b\xcf\x49\x44\x94\x05\x1a\x21\x81\x25\x7f\xe3\x8a\x2a"
+ "\xdd\x88\xac\x44\x94\x23\x20\x3b\x75\xf6\x2a\x8a\x45\xf8\xb5\x1f"
+ "\xb9\x8b\xeb\xab\x9b\x38\x23\x26\xf1\x0f\x34\x47\x4f\x7f\xe1\x9e"
+ "\x84\x84\x78\xe5\xe3\x49\xeb\xcc\x2f\x02\x85\xa4\x18\x91\xde\x1a"
+ "\x60\x54\x33\x81\xd5\xae\xdb\x23\x9c\x4d\xa4\xdb\x22\x5b\xdf\xf4"
+ "\x8e\x05\x2b\x60\xba\xe8\x75\xfc\x34\x99\xcf\x35\xe1\x06\xba\xdc"
+ "\x79\x2a\x5e\xec\x1c\xbe\x79\x33\x63\x1c\xe7\x5f\x1e\x30\xd6\x1b"
+ "\xdb\x11\xb8\xea\x63\xff\xfe\x1a\x3c\x24\xf4\x78\x9c\xcc\x5d\x9a"
+ "\xc9\x2d\xc4\x9a\xd4\xa7\x65\x84\x98\xdb\x66\x76\xf0\x34\x31\x9f"
+ "\xce\xb5\xfb\x28\x07\xde\x1e\x0d\x9b\x01\x64\xeb\x2a\x37\x2f\x20"
+ "\xa5\x95\x72\x2b\x54\x51\x59\x91\xea\x50\x54\x0f\x2e\xb0\x1d\xf6"
+ "\xb9\x46\x43\xf9\xd0\x13\x21\x20\x47\x61\x1a\x1c\x30\xc6\x9e\x75"
+ "\x22\xe4\xf2\xb1\xab\x01\xdc\x5b\x3c\x1e\xa2\x6d\xc0\xb9\x9a\x2a"
+ "\x84\x61\xea\x85\x63\xa0\x77\xd0\xeb\x20\x68\xd5\x95\x6a\x1b\x8f"
+ "\x1f\x9a\xba\x44\x49\x8c\x77\xa6\xd9\xa0\x14\xf8\x7d\x9b\x4e\xfa"
+ "\xdc\x4f\x1c\x4d\x60\x50\x26\x7f\xd6\xc1\x91\x2b\xa6\x37\x5d\x94"
+ "\x69\xb2\x47\x59\xd6\xc3\x59\xbb\xd6\x9b\x71\x52\x85\x7a\xcb\x2d",
+ .b_public =
+ "\x24\x38\x02\x02\x2f\xeb\x54\xdd\x73\x21\x91\x4a\xd8\xa4\x0a\xbf"
+ "\xf4\xf5\x9a\x45\xb5\xcd\x42\xa3\x57\xcc\x65\x4a\x23\x2e\xee\x59"
+ "\xba\x6f\x14\x89\xae\x2e\x14\x0a\x72\x77\x23\x7f\x6c\x2e\xba\x52"
+ "\x3f\x71\xbf\xe4\x60\x03\x16\xaa\x61\xf5\x80\x1d\x8a\x45\x9e\x53"
+ "\x7b\x07\xd9\x7e\xfe\xaf\xcb\xda\xff\x20\x71\xba\x89\x39\x75\xc3"
+ "\xb3\x65\x0c\xb1\xa7\xfa\x4a\xe7\xe0\x85\xc5\x4e\x91\x47\x41\xf4"
+ "\xdd\xcd\xc5\x3d\x17\x12\xed\xee\xc0\x31\xb1\xaf\xc1\xd5\x3c\x07"
+ "\xa1\x5a\xc4\x05\x45\xe3\x10\x0c\xc3\x14\xae\x65\xca\x40\xae\x31"
+ "\x5c\x13\x0d\x32\x85\xa7\x6e\xf4\x5e\x29\x3d\x4e\xd3\xd7\x49\x58"
+ "\xe1\x73\xbb\x0a\x7b\xd6\x13\xea\x49\xd7\x20\x3d\x31\xaa\x77\xab"
+ "\x21\x74\xe9\x2f\xe9\x5e\xbe\x2f\xb4\xa2\x79\xf2\xbc\xcc\x51\x94"
+ "\xd2\x1d\xb2\xe6\xc5\x39\x66\xd7\xe5\x46\x75\x53\x76\xed\x49\xea"
+ "\x3b\xdd\x01\x27\xdb\x83\xa5\x9f\xd2\xee\xc8\xde\x9e\xde\xd2\xe7"
+ "\x99\xad\x9c\xe0\x71\x66\x29\xd8\x0d\xfe\xdc\xd1\xbc\xc7\x9a\xbe"
+ "\x8b\x26\x46\x57\xb6\x79\xfa\xad\x8b\x45\x2e\xb5\xe5\x89\x34\x01"
+ "\x93\x00\x9d\xe9\x58\x74\x8b\xda\x07\x92\xb5\x01\x4a\xe1\x44\x36"
+ "\xc7\x6c\xde\xc8\x7a\x17\xd0\xde\xee\x68\x92\xb5\xde\x21\x2b\x1c"
+ "\xbc\x65\x30\x1e\xae\x15\x3d\x9a\xaf\x20\xa3\xc4\x21\x70\xfb\x2f"
+ "\x36\x72\x31\xc0\xe8\x85\xdf\xc5\x50\x4c\x90\x10\x32\xa4\xc7\xee"
+ "\x59\x5a\x21\xf4\xf1\x33\xcf\xbe\xac\x67\xb1\x40\x7c\x0b\x3f\x64"
+ "\xe5\xd2\x2d\xb7\x7d\x0f\xce\xf7\x9b\x05\xee\x37\x61\xd2\x61\x9e"
+ "\x1a\x80\x2e\x79\xe6\x1b\x25\xb3\x61\x3d\x53\xe7\xe5\x97\x9a\xc2"
+ "\x39\xb1\xe3\x91\xc6\xee\x96\x2e\xa9\xb4\xb8\xad\xd8\x04\x3e\x11"
+ "\x31\x67\xb8\x6a\xcb\x6e\x1a\x4c\x7f\x74\xc7\x1f\x09\xd1\xd0\x6b"
+ "\x17\xde\xea\xe8\x0b\xe6\x6a\xee\x2f\xe3\x5b\x9c\x59\x5d\x00\x57"
+ "\xbf\x24\x25\xba\x22\x34\xb9\xc5\x3c\xc4\x57\x26\xd0\x6d\x89\xee"
+ "\x67\x79\x3c\x70\xf9\xc3\xb4\x30\xf0\x2e\xca\xfa\x74\x00\xd1\x00"
+ "\x6d\x03\x97\xd5\x08\x3f\x0b\x8e\xb8\x1d\xa3\x91\x7f\xa9\x3a\xf0"
+ "\x37\x57\x46\x87\x82\xa3\xb5\x8f\x51\xaa\xc7\x7b\xfe\x86\x26\xb9"
+ "\xfa\xe6\x1e\xee\x92\x9d\x3a\xed\x5b\x5e\x3f\xe5\xca\x5e\x13\x01"
+ "\xdd\x4c\x8d\x85\xf0\x60\x61\xb7\x60\x24\x83\x9f\xbe\x72\x21\x81"
+ "\x55\x7e\x7e\x6d\xf3\x28\xc8\x77\x5a\xae\x5a\x32\x86\xd5\x61\xad",
+ .expected_a_public =
+ "\x1f\xff\xd6\xc4\x59\xf3\x4a\x9e\x81\x74\x4d\x27\xa7\xc6\x6b\x35"
+ "\xd8\xf5\xb3\x24\x97\x82\xe7\x2e\xf3\x21\x91\x23\x2f\x3d\x57\x7f"
+ "\x15\x8c\x84\x71\xe7\x25\x35\xe8\x07\x14\x06\x4c\x83\xdc\x55\x4a"
+ "\xf8\x45\xc5\xe9\xfa\x6e\xae\x6e\xcf\x4d\x11\x91\x26\x16\x6f\x86"
+ "\x89\x78\xaa\xb4\x25\x54\xb2\x74\x07\xe5\x26\x26\x0c\xad\xa4\x57"
+ "\x59\x61\x66\x71\x43\x22\xff\x49\x51\xa4\x76\x0e\x55\x7b\x60\x45"
+ "\x4f\xaf\xbd\x9c\xec\x64\x3f\x80\x0b\x0c\x31\x41\xf0\xfe\x2c\xb7"
+ "\x0a\xbe\xa5\x71\x08\x0d\x8d\x1e\x8a\x77\x9a\xd2\x90\x31\x96\xd0"
+ "\x3b\x31\xdc\xc6\x18\x59\x43\xa1\x19\x5a\x84\x68\x29\xad\x5e\x58"
+ "\xa2\x50\x3e\x83\xf5\x7a\xbd\x88\x17\x60\x89\x98\x9c\x19\x89\x27"
+ "\x89\xfc\x33\x87\x42\xd5\xde\x19\x14\xf2\x95\x82\x10\x87\xad\x82"
+ "\xdd\x6b\x51\x2d\x8d\x0e\x81\x4b\xde\xb3\x35\x6c\x0f\x4b\x56\x45"
+ "\x48\x87\xe9\x5a\xf9\x70\x10\x30\x8e\xa1\xbb\xa4\x70\xbf\xa0\xab"
+ "\x10\x31\x3c\x2c\xdc\xc4\xed\xe3\x51\xdc\xee\xd2\xa5\x5c\x4e\x6e"
+ "\xf6\xed\x60\x5a\xeb\xf3\x02\x19\x2a\x95\xe9\x46\xff\x37\x1b\xf0"
+ "\x1d\x10\x4a\x8f\x4f\x3a\x6e\xf5\xfc\x02\x6d\x09\x7d\xea\x69\x7b"
+ "\x13\xb0\xb6\x80\x5c\x15\x20\xa8\x4d\x15\x56\x11\x72\x49\xdb\x48"
+ "\x54\x40\x66\xd5\xcd\x17\x3a\x26\x95\xf6\xd7\xf2\x59\xa3\xda\xbb"
+ "\x26\xd0\xe5\x46\xbf\xee\x0e\x7d\xf1\xe0\x11\x02\x4d\xd3\xdc\xe2"
+ "\x3f\xc2\x51\x7e\xc7\x90\x33\x3c\x1c\xa0\x4c\x69\xcc\x1e\xc7\xac"
+ "\x17\xe0\xe5\xf4\x8c\x05\x64\x34\xfe\x84\x70\xd7\x6b\xed\xab\xf5"
+ "\x88\x9d\x3e\x4c\x5a\x9e\xd4\x74\xfd\xdd\x91\xd5\xd4\xcb\xbf\xf8"
+ "\xb7\x56\xb5\xe9\x22\xa6\x6d\x7a\x44\x05\x41\xbf\xdb\x61\x28\xc6"
+ "\x99\x49\x87\x3d\x28\x77\xf8\x83\x23\x7e\xa9\xa7\xee\x20\xdb\x6d"
+ "\x21\x50\xb7\xc9\x52\x57\x53\xa3\xcf\xdf\xd0\xf9\xb9\x62\x96\x89"
+ "\xf5\x5c\xa9\x8a\x11\x95\x01\x25\xc9\x81\x15\x76\xae\xf0\xc7\xc5"
+ "\x50\xae\x6f\xb5\xd2\x8a\x8e\x9a\xd4\x30\x55\xc6\xe9\x2c\x81\x6e"
+ "\x95\xf6\x45\x89\x55\x28\x34\x7b\xe5\x72\x9a\x2a\xe2\x98\x09\x35"
+ "\xe0\xe9\x75\x94\xe9\x34\x95\xb9\x13\x6e\xd5\xa1\x62\x5a\x1c\x94"
+ "\x28\xed\x84\x46\x76\x6d\x10\x37\x71\xa3\x31\x46\x64\xe4\x59\x44"
+ "\x17\x70\x1c\x23\xc9\x7e\xf6\xab\x8a\x24\xae\x25\xe2\xb2\x5f\x33"
+ "\xe4\xd7\xd3\x34\x2a\x49\x22\x16\x15\x9b\x90\x40\xda\x99\xd5\xaf",
+ .expected_ss =
+ "\xe2\xce\x0e\x4b\x64\xf3\x84\x62\x38\xfd\xe3\x6f\x69\x40\x22\xb0"
+ "\x73\x27\x03\x12\x82\xa4\x6e\x03\x57\xec\x3d\xa0\xc1\x4f\x4b\x09"
+ "\xa1\xd4\xe0\x1a\x5d\x91\x2e\x08\xad\x57\xfa\xcc\x55\x90\x5f\xa0"
+ "\x52\x27\x62\x8d\xe5\x2d\xa1\x5f\xf0\x30\x43\x77\x4e\x3f\x02\x58"
+ "\xcb\xa0\x51\xae\x1d\x24\xf9\x0a\xd1\x36\x0b\x95\x0f\x07\xd9\xf7"
+ "\xe2\x36\x14\x2f\xf0\x11\xc2\xc9\xaf\x66\x4e\x0d\xb4\x60\x01\x4e"
+ "\xa8\x49\xc6\xec\x5f\xb2\xbc\x05\x48\x91\x4e\xe1\xc3\x99\x9f\xeb"
+ "\x4a\xc1\xde\x05\x9a\x65\x39\x7d\x2f\x89\x85\xb2\xcf\xec\x25\x27"
+ "\x5f\x1c\x11\x63\xcf\x7b\x86\x98\x39\xae\xc2\x16\x8f\x79\xd1\x20"
+ "\xd0\xb4\xa0\xba\x44\xd8\xf5\x3a\x0a\x08\x4c\xd1\xb9\xdd\x0a\x5b"
+ "\x9e\x62\xf3\x52\x0c\x84\x12\x43\x9b\xd7\xdf\x86\x71\x03\xdd\x04"
+ "\x98\x55\x0c\x7b\xe2\xe8\x03\x17\x25\x84\xd9\xbd\xe1\xce\x64\xbe"
+ "\xca\x55\xd4\x5b\xef\x61\x5b\x68\x4b\x80\x37\x40\xae\x28\x87\x81"
+ "\x55\x34\x96\x50\x21\x47\x49\xc0\xda\x26\x46\xb8\xe8\xcc\x5a\x27"
+ "\x9c\x9d\x0a\x3d\xcc\x4c\x63\x27\x81\x82\x2e\xf4\xa8\x91\x37\x3e"
+ "\xa7\x34\x6a\x0f\x60\x44\xdd\x2e\xdc\xf9\x19\xf2\x2e\x81\x05\x51"
+ "\x16\xbc\xc0\x85\xa5\xd5\x08\x09\x1f\xcd\xed\xa4\xc5\xdb\x16\x43"
+ "\xb5\x7a\x71\x66\x19\x2e\xef\x13\xbc\x40\x39\x0a\x00\x45\x7e\x61"
+ "\xe9\x68\x60\x83\x00\x70\xd1\x71\xd3\xa2\x61\x3e\x00\x46\x93\x0d"
+ "\xbf\xe6\xa2\x07\xe6\x40\x1a\xf4\x57\xc6\x67\x39\xd8\xd7\x6b\xc5"
+ "\xa5\xd8\x38\x78\x12\xb4\x97\x12\xbe\x97\x13\xef\xe4\x74\x0c\xe0"
+ "\x75\x89\x64\xf4\xe8\x85\xda\x84\x7b\x1d\xfe\xdd\x21\xba\xda\x01"
+ "\x52\xdc\x59\xe5\x47\x50\x7e\x15\x20\xd0\x43\x37\x6e\x48\x39\x00"
+ "\xee\xd9\x54\x6d\x00\x65\xc9\x4b\x85\xa2\x8a\x40\x55\xd0\x63\x0c"
+ "\xb5\x7a\x0d\x37\x67\x27\x73\x18\x7f\x5a\xf5\x0e\x22\xb9\xb0\x3f"
+ "\xda\xf1\xec\x7c\x24\x01\x49\xa9\x09\x0e\x0f\xc4\xa9\xef\xc8\x2b"
+ "\x13\xd1\x0a\x6f\xf8\x92\x4b\x1d\xdd\x6c\x9c\x35\xde\x75\x46\x32"
+ "\xe6\xfb\xda\x58\xba\x81\x08\xca\xa9\xb6\x69\x71\x96\x2a\x1f\x2e"
+ "\x25\xe0\x37\xfe\xee\x4d\x27\xaa\x04\xda\x95\xbb\x93\xcf\x8f\xa2"
+ "\x1d\x67\x35\xe3\x51\x8f\x87\x3b\xa9\x62\x05\xee\x44\xb7\x2e\xd0"
+ "\x07\x63\x32\xf5\xcd\x64\x18\x20\xcf\x22\x42\x28\x22\x1a\xa8\xbb"
+ "\x74\x8a\x6f\x2a\xea\x8a\x48\x0a\xad\xd7\xed\xba\xa3\x89\x37\x01",
+ .secret_size = 528,
+ .b_public_size = 512,
+ .expected_a_public_size = 512,
+ .expected_ss_size = 512,
+ },
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x00" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x00\x10" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#endif
+ .b_secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x02" /* len */
+ "\x00\x02\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x02\x10" /* len */
+ "\x00\x00\x02\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x1a\x48\xf3\x6c\x61\x03\x42\x43\xd7\x42\x3b\xfa\xdb\x55\x6f\xa2"
+ "\xe1\x79\x52\x0b\x47\xc5\x03\x60\x2f\x26\xb9\x1a\x14\x15\x1a\xd9"
+ "\xe0\xbb\xa7\x82\x63\x41\xec\x26\x55\x00\xab\xe5\x21\x9d\x31\x14"
+ "\x0e\xe2\xc2\xb2\xb8\x37\xe6\xc3\x5a\xab\xae\x25\xdb\x71\x1e\xed"
+ "\xe8\x75\x9a\x04\xa7\x92\x2a\x99\x7e\xc0\x5b\x64\x75\x7f\xe5\xb5"
+ "\xdb\x6c\x95\x4f\xe9\xdc\x39\x76\x79\xb0\xf7\x00\x30\x8e\x86\xe7"
+ "\x36\xd1\xd2\x0c\x68\x7b\x94\xe9\x91\x85\x08\x86\xbc\x64\x87\xd2"
+ "\xf5\x5b\xaf\x03\xf6\x5f\x28\x25\xf1\xa3\x20\x5c\x1b\xb5\x26\x45"
+ "\x9a\x47\xab\xd6\xad\x49\xab\x92\x8e\x62\x6f\x48\x31\xea\xf6\x76"
+ "\xff\xa2\xb6\x28\x78\xef\x59\xc3\x71\x5d\xa8\xd9\x70\x89\xcc\xe2"
+ "\x63\x58\x5e\x3a\xa2\xa2\x88\xbf\x77\x20\x84\x33\x65\x64\x4e\x73"
+ "\xe5\x08\xd5\x89\x23\xd6\x07\xac\x29\x65\x2e\x02\xa8\x35\x96\x48"
+ "\xe7\x5d\x43\x6a\x42\xcc\xda\x98\xc4\x75\x90\x2e\xf6\xc4\xbf\xd4"
+ "\xbc\x31\x14\x0d\x54\x30\x11\xb2\xc9\xcf\xbb\xba\xbc\xc6\xf2\xcf"
+ "\xfe\x4a\x9d\xf3\xec\x78\x5d\x5d\xb4\x99\xd0\x67\x0f\x5a\x21\x1c"
+ "\x7b\x95\x2b\xcf\x49\x44\x94\x05\x1a\x21\x81\x25\x7f\xe3\x8a\x2a"
+ "\xdd\x88\xac\x44\x94\x23\x20\x3b\x75\xf6\x2a\x8a\x45\xf8\xb5\x1f"
+ "\xb9\x8b\xeb\xab\x9b\x38\x23\x26\xf1\x0f\x34\x47\x4f\x7f\xe1\x9e"
+ "\x84\x84\x78\xe5\xe3\x49\xeb\xcc\x2f\x02\x85\xa4\x18\x91\xde\x1a"
+ "\x60\x54\x33\x81\xd5\xae\xdb\x23\x9c\x4d\xa4\xdb\x22\x5b\xdf\xf4"
+ "\x8e\x05\x2b\x60\xba\xe8\x75\xfc\x34\x99\xcf\x35\xe1\x06\xba\xdc"
+ "\x79\x2a\x5e\xec\x1c\xbe\x79\x33\x63\x1c\xe7\x5f\x1e\x30\xd6\x1b"
+ "\xdb\x11\xb8\xea\x63\xff\xfe\x1a\x3c\x24\xf4\x78\x9c\xcc\x5d\x9a"
+ "\xc9\x2d\xc4\x9a\xd4\xa7\x65\x84\x98\xdb\x66\x76\xf0\x34\x31\x9f"
+ "\xce\xb5\xfb\x28\x07\xde\x1e\x0d\x9b\x01\x64\xeb\x2a\x37\x2f\x20"
+ "\xa5\x95\x72\x2b\x54\x51\x59\x91\xea\x50\x54\x0f\x2e\xb0\x1d\xf6"
+ "\xb9\x46\x43\xf9\xd0\x13\x21\x20\x47\x61\x1a\x1c\x30\xc6\x9e\x75"
+ "\x22\xe4\xf2\xb1\xab\x01\xdc\x5b\x3c\x1e\xa2\x6d\xc0\xb9\x9a\x2a"
+ "\x84\x61\xea\x85\x63\xa0\x77\xd0\xeb\x20\x68\xd5\x95\x6a\x1b\x8f"
+ "\x1f\x9a\xba\x44\x49\x8c\x77\xa6\xd9\xa0\x14\xf8\x7d\x9b\x4e\xfa"
+ "\xdc\x4f\x1c\x4d\x60\x50\x26\x7f\xd6\xc1\x91\x2b\xa6\x37\x5d\x94"
+ "\x69\xb2\x47\x59\xd6\xc3\x59\xbb\xd6\x9b\x71\x52\x85\x7a\xcb\x2d",
+ .b_public =
+ "\x1f\xff\xd6\xc4\x59\xf3\x4a\x9e\x81\x74\x4d\x27\xa7\xc6\x6b\x35"
+ "\xd8\xf5\xb3\x24\x97\x82\xe7\x2e\xf3\x21\x91\x23\x2f\x3d\x57\x7f"
+ "\x15\x8c\x84\x71\xe7\x25\x35\xe8\x07\x14\x06\x4c\x83\xdc\x55\x4a"
+ "\xf8\x45\xc5\xe9\xfa\x6e\xae\x6e\xcf\x4d\x11\x91\x26\x16\x6f\x86"
+ "\x89\x78\xaa\xb4\x25\x54\xb2\x74\x07\xe5\x26\x26\x0c\xad\xa4\x57"
+ "\x59\x61\x66\x71\x43\x22\xff\x49\x51\xa4\x76\x0e\x55\x7b\x60\x45"
+ "\x4f\xaf\xbd\x9c\xec\x64\x3f\x80\x0b\x0c\x31\x41\xf0\xfe\x2c\xb7"
+ "\x0a\xbe\xa5\x71\x08\x0d\x8d\x1e\x8a\x77\x9a\xd2\x90\x31\x96\xd0"
+ "\x3b\x31\xdc\xc6\x18\x59\x43\xa1\x19\x5a\x84\x68\x29\xad\x5e\x58"
+ "\xa2\x50\x3e\x83\xf5\x7a\xbd\x88\x17\x60\x89\x98\x9c\x19\x89\x27"
+ "\x89\xfc\x33\x87\x42\xd5\xde\x19\x14\xf2\x95\x82\x10\x87\xad\x82"
+ "\xdd\x6b\x51\x2d\x8d\x0e\x81\x4b\xde\xb3\x35\x6c\x0f\x4b\x56\x45"
+ "\x48\x87\xe9\x5a\xf9\x70\x10\x30\x8e\xa1\xbb\xa4\x70\xbf\xa0\xab"
+ "\x10\x31\x3c\x2c\xdc\xc4\xed\xe3\x51\xdc\xee\xd2\xa5\x5c\x4e\x6e"
+ "\xf6\xed\x60\x5a\xeb\xf3\x02\x19\x2a\x95\xe9\x46\xff\x37\x1b\xf0"
+ "\x1d\x10\x4a\x8f\x4f\x3a\x6e\xf5\xfc\x02\x6d\x09\x7d\xea\x69\x7b"
+ "\x13\xb0\xb6\x80\x5c\x15\x20\xa8\x4d\x15\x56\x11\x72\x49\xdb\x48"
+ "\x54\x40\x66\xd5\xcd\x17\x3a\x26\x95\xf6\xd7\xf2\x59\xa3\xda\xbb"
+ "\x26\xd0\xe5\x46\xbf\xee\x0e\x7d\xf1\xe0\x11\x02\x4d\xd3\xdc\xe2"
+ "\x3f\xc2\x51\x7e\xc7\x90\x33\x3c\x1c\xa0\x4c\x69\xcc\x1e\xc7\xac"
+ "\x17\xe0\xe5\xf4\x8c\x05\x64\x34\xfe\x84\x70\xd7\x6b\xed\xab\xf5"
+ "\x88\x9d\x3e\x4c\x5a\x9e\xd4\x74\xfd\xdd\x91\xd5\xd4\xcb\xbf\xf8"
+ "\xb7\x56\xb5\xe9\x22\xa6\x6d\x7a\x44\x05\x41\xbf\xdb\x61\x28\xc6"
+ "\x99\x49\x87\x3d\x28\x77\xf8\x83\x23\x7e\xa9\xa7\xee\x20\xdb\x6d"
+ "\x21\x50\xb7\xc9\x52\x57\x53\xa3\xcf\xdf\xd0\xf9\xb9\x62\x96\x89"
+ "\xf5\x5c\xa9\x8a\x11\x95\x01\x25\xc9\x81\x15\x76\xae\xf0\xc7\xc5"
+ "\x50\xae\x6f\xb5\xd2\x8a\x8e\x9a\xd4\x30\x55\xc6\xe9\x2c\x81\x6e"
+ "\x95\xf6\x45\x89\x55\x28\x34\x7b\xe5\x72\x9a\x2a\xe2\x98\x09\x35"
+ "\xe0\xe9\x75\x94\xe9\x34\x95\xb9\x13\x6e\xd5\xa1\x62\x5a\x1c\x94"
+ "\x28\xed\x84\x46\x76\x6d\x10\x37\x71\xa3\x31\x46\x64\xe4\x59\x44"
+ "\x17\x70\x1c\x23\xc9\x7e\xf6\xab\x8a\x24\xae\x25\xe2\xb2\x5f\x33"
+ "\xe4\xd7\xd3\x34\x2a\x49\x22\x16\x15\x9b\x90\x40\xda\x99\xd5\xaf",
+ .secret_size = 16,
+ .b_secret_size = 528,
+ .b_public_size = 512,
+ .expected_a_public_size = 512,
+ .expected_ss_size = 512,
+ .genkey = true,
+ },
+};
+
+static const struct kpp_testvec ffdhe6144_dh_tv_template[] __maybe_unused = {
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x03" /* len */
+ "\x00\x03\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x03\x10" /* len */
+ "\x00\x00\x03\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x63\x3e\x6f\xe0\xfe\x9f\x4a\x01\x62\x77\xce\xf1\xc7\xcc\x49\x4d"
+ "\x92\x53\x56\xe3\x39\x15\x81\xb2\xcd\xdc\xaf\x5e\xbf\x31\x1f\x69"
+ "\xce\x41\x35\x24\xaa\x46\x53\xb5\xb7\x3f\x2b\xad\x95\x14\xfb\xe4"
+ "\x9a\x61\xcd\x0f\x1f\x02\xee\xa4\x79\x2c\x9d\x1a\x7c\x62\x82\x39"
+ "\xdd\x43\xcc\x58\x9f\x62\x47\x56\x1d\x0f\xc2\x67\xbc\x24\xd0\xf9"
+ "\x0a\x50\x1b\x10\xe7\xbb\xd1\xc2\x01\xbb\xc4\x4c\xda\x12\x60\x0e"
+ "\x95\x2b\xde\x09\xd6\x67\xe1\xbc\x4c\xb9\x67\xdf\xd0\x1f\x97\xb4"
+ "\xde\xcb\x6b\x78\x83\x51\x74\x33\x01\x7f\xf6\x0a\x95\x69\x93\x00"
+ "\x2a\xc3\x75\x8e\xef\xbe\x53\x11\x6d\xc4\xd0\x9f\x6d\x63\x48\xc1"
+ "\x91\x1f\x7d\x88\xa7\x90\x78\xd1\x7e\x52\x42\x10\x01\xb4\x27\x95"
+ "\x91\x43\xcc\x82\x91\x86\x62\xa0\x9d\xef\x65\x6e\x67\xcf\x19\x11"
+ "\x35\x37\x5e\x94\x97\x83\xa6\x83\x1c\x7e\x8a\x3e\x32\xb0\xce\xff"
+ "\x20\xdc\x7b\x6e\x18\xd9\x6b\x27\x31\xfc\xc3\xef\x47\x8d\xbe\x34"
+ "\x2b\xc7\x60\x74\x3c\x93\xb3\x8e\x54\x77\x4e\x73\xe6\x40\x72\x35"
+ "\xb0\xf0\x06\x53\x43\xbe\xd0\xc3\x87\xcc\x38\x96\xa9\x10\xa0\xd6"
+ "\x17\xed\xa5\x6a\xf4\xf6\xaa\x77\x40\xed\x7d\x2e\x58\x0f\x5b\x04"
+ "\x5a\x41\x12\x95\x22\xcb\xa3\xce\x8b\x6d\x6d\x89\xec\x7c\x1d\x25"
+ "\x27\x52\x50\xa0\x5b\x93\x8c\x5d\x3f\x56\xb9\xa6\x5e\xe5\xf7\x9b"
+ "\xc7\x9a\x4a\x2e\x79\xb5\xca\x29\x58\x52\xa0\x63\xe4\x9d\xeb\x4c"
+ "\x4c\xa8\x37\x0b\xe9\xa0\x18\xf1\x86\xf6\x4d\x32\xfb\x9e\x4f\xb3"
+ "\x7b\x5d\x58\x78\x70\xbd\x56\xac\x99\x75\x25\x71\x66\x76\x4e\x5e"
+ "\x67\x4f\xb1\x17\xa7\x8b\x55\x12\x87\x01\x4e\xd1\x66\xef\xd0\x70"
+ "\xaf\x14\x34\xee\x2a\x76\x49\x25\xa6\x2e\x43\x37\x75\x7d\x1a\xad"
+ "\x08\xd5\x01\x85\x9c\xe1\x20\xd8\x38\x5c\x57\xa5\xed\x9d\x46\x3a"
+ "\xb7\x46\x60\x29\x8b\xc4\x21\x50\x0a\x30\x9c\x57\x42\xe4\x35\xf8"
+ "\x12\x5c\x4f\xa2\x20\xc2\xc9\x43\xe3\x6d\x20\xbc\xdf\xb8\x37\x33"
+ "\x45\x43\x06\x4e\x08\x6f\x8a\xcd\x61\xc3\x1b\x05\x28\x82\xbe\xf0"
+ "\x48\x33\xe5\x93\xc9\x1a\x61\x16\x67\x03\x9d\x47\x9d\x74\xeb\xae"
+ "\x13\xf2\xb4\x1b\x09\x11\xf5\x15\xcb\x28\xfd\x50\xe0\xbc\x58\x36"
+ "\x38\x91\x2c\x07\x27\x1f\x49\x68\xf4\xce\xad\xf7\xba\xec\x5d\x3d"
+ "\xfd\x27\xe2\xcf\xf4\x56\xfe\x08\xa6\x11\x61\xcb\x6c\x9f\xf9\x3c"
+ "\x57\x0b\x8b\xaa\x00\x16\x18\xba\x1f\xe8\x4f\x01\xe2\x79\x2a\x0b"
+ "\xc1\xbd\x52\xef\xe6\xf7\x5a\x66\xfe\x07\x3b\x50\x6b\xbb\xcb\x39"
+ "\x3c\x94\xf6\x21\x0d\x68\x69\xa4\xed\x2e\xb5\x85\x03\x11\x38\x79"
+ "\xec\xb5\x22\x23\xdf\x9e\xad\xb4\xbe\xd7\xc7\xdf\xea\x30\x23\x8a"
+ "\xb7\x21\x0a\x9d\xbd\x99\x13\x7d\x5f\x7e\xaf\x28\x54\x3f\xca\x5e"
+ "\xf4\xfc\x05\x0d\x65\x67\xd8\xf6\x8e\x90\x9d\x0d\xcf\x62\x82\xd6"
+ "\x9f\x02\xf8\xca\xfa\x42\x24\x7f\x4d\xb7\xfc\x92\xa6\x4a\x51\xc4"
+ "\xd8\xae\x19\x87\xc6\xa3\x83\xbe\x7b\x6d\xc3\xf5\xb8\xad\x4a\x05"
+ "\x78\x84\x3a\x15\x2e\x40\xbe\x79\xa9\xc0\x12\xa1\x48\x39\xc3\xdb"
+ "\x47\x4f\x7d\xea\x6d\xc7\xfa\x2c\x4e\xe9\xa5\x85\x81\xea\x6c\xcd"
+ "\x8a\xe5\x74\x17\x76\x31\x31\x75\x96\x83\xca\x81\xbb\x5c\xa9\x79"
+ "\x2c\xbd\x09\xfe\xe4\x86\x0d\x8c\x76\x9c\xbc\xe8\x93\xe4\xd0\xe4"
+ "\x0f\xf8\xff\x24\x7e\x66\x61\x69\xfb\xe4\x46\x08\x94\x99\xa5\x53"
+ "\xd7\xe4\x29\x72\x86\x86\xe8\x1d\x37\xfa\xcb\xd0\x8d\x51\xd0\xbf"
+ "\x81\xcf\x55\xb9\xc5\x78\x8c\x74\xa0\x16\x3a\xd2\x19\x94\x29\x6a"
+ "\x5e\xec\xd3\x20\xa0\xb2\xfd\xce\xd4\x14\xa3\x39\x10\xa9\xf4\x4e"
+ "\xba\x21\x09\x5c\xe6\x61\x43\x51\xae\xc4\x71\xd7\x21\xef\x98\x39",
+ .b_public =
+ "\x30\x31\xbe\x43\xd0\x14\x22\x6b\x4b\x8c\x9a\xca\xc6\xdd\xe5\x99"
+ "\xce\xb8\x30\x23\xb6\xa8\x8c\x4d\xfa\xef\xad\xa6\x6a\x21\x50\xa6"
+ "\x45\x2d\x19\x2a\x29\x81\xc5\xac\xb4\xa8\x5f\x6d\x5b\xc8\x5f\x12"
+ "\x35\x21\xfb\x37\xaa\x0c\x79\xeb\xd4\x83\x01\xda\xa3\xf3\x51\x6e"
+ "\x17\xf9\xef\x3f\xbd\x2f\xd2\x43\x82\x12\x48\xeb\x61\x4c\x8e\xf2"
+ "\x6c\x76\xf9\x6d\x42\x2a\xcb\x10\x13\x3b\xf6\x9b\xcd\x46\x1e\xa2"
+ "\xa7\x2c\x08\x56\xd2\x42\xf5\x03\xf0\x3e\xef\xa2\xa2\xf2\x4c\xf2"
+ "\xdb\x4f\xeb\x40\x15\x53\x27\xf7\xd4\x8e\x58\x23\xf5\x2c\x88\x04"
+ "\x1e\xb1\xb6\xe3\xd6\x9c\x49\x08\xa1\x4b\xb8\x33\xe4\x75\x85\xa1"
+ "\x86\x97\xce\x1d\xe9\x9f\xe2\xd8\xf2\x7e\xad\xdc\x8a\x4d\xbd\x06"
+ "\x52\x00\x9a\x2c\x69\xdd\x02\x0c\x69\x5a\xf9\x1d\xfd\xdc\xfb\x82"
+ "\xb2\xe5\xf3\x24\xba\xd1\x09\x76\x90\xb5\x7a\x92\xa6\x6b\x97\xc0"
+ "\xce\x13\x9b\x4b\xbc\x30\x91\xb2\x13\x8b\x57\x6c\x8b\x66\x6e\x58"
+ "\x3e\x91\x50\xc7\x6c\xe1\x18\xec\xbf\x69\xcd\xcb\xa0\xbc\x0d\x05"
+ "\xc4\xf8\x45\x92\xe0\x05\xd3\x08\xb3\x30\x19\xc8\x80\xf8\x17\x9f"
+ "\x1e\x6a\x49\x8e\x43\xef\x7a\x49\xa5\x93\xd9\xed\xd1\x07\x03\xe4"
+ "\xa3\x55\xeb\x1e\x2f\x69\xd7\x40\x8f\x6e\x1c\xb6\x94\xfb\xba\x4e"
+ "\x46\xd0\x38\x71\x00\x88\x93\x6a\x55\xfc\x16\x95\x1f\xb1\xf6\x2f"
+ "\x26\x45\x50\x54\x30\x62\x62\xe8\x80\xe5\x24\x0b\xe4\x15\x6b\x32"
+ "\x16\xc2\x30\x9b\x56\xb4\xc9\x5e\x50\xb4\x27\x82\x86\x01\xda\x68"
+ "\x44\x4b\x15\x81\x31\x13\x52\xd8\x08\xbc\xae\xf3\xa5\x94\x1c\x81"
+ "\xe8\x42\xd6\x42\xd6\xff\x99\x58\x0f\x61\x3e\x82\x9e\x2d\x13\x03"
+ "\x54\x02\x74\xf4\x6b\x43\x43\xce\x54\x44\x36\x3f\x55\xfa\xb2\x56"
+ "\xdc\xac\xb5\x65\x89\xbe\x36\xd2\x58\x65\x79\x4c\xf3\xe2\x01\xf1"
+ "\x69\x96\x29\x20\x5d\xee\xf5\x8a\x8b\x9f\x72\xf7\x27\x02\xde\x3b"
+ "\xc7\x52\x19\xdc\x8e\x22\x36\x09\x14\x59\x07\xbb\x1e\x49\x69\x4f"
+ "\x00\x7b\x9a\x5d\x23\xe9\xbe\x0d\x52\x90\xa3\x0d\xde\xe7\x80\x57"
+ "\x53\x69\x39\xe6\xf8\x33\xeb\x92\x0d\x9e\x04\x8b\x16\x16\x16\x1c"
+ "\xa9\xe6\xe3\x0e\x0a\xc6\xf6\x61\xd1\x44\x2b\x3e\x5e\x02\xfe\xaa"
+ "\xe3\xf3\x8f\xf9\xc8\x20\x37\xad\xbc\x95\xb8\xc5\xe7\x95\xda\xfb"
+ "\x80\x5b\xf6\x40\x28\xae\xc1\x4c\x09\xde\xff\x1e\xbf\x51\xd2\xfe"
+ "\x08\xdc\xb0\x48\x21\xf5\x4c\x43\xdc\x7b\x69\x83\xc8\x69\x5c\xc4"
+ "\xa9\x98\x76\x4b\xc4\x4a\xac\x1d\xa5\x52\xe3\x35\x43\xdd\x30\xd4"
+ "\xa0\x51\x9c\xc2\x62\x4c\x7e\xa5\xfb\xd3\x2c\x8a\x09\x7f\x53\xa3"
+ "\xcd\xca\x58\x1b\x4c\xaf\xba\x21\x8b\x88\x1d\xc0\xe9\x0a\x17\x30"
+ "\x33\xd6\xa2\xa5\x49\x50\x61\x3b\xff\x37\x71\x66\xef\x61\xbc\xb2"
+ "\x53\x82\xe5\x70\xef\x32\xff\x9d\x97\xe0\x82\xe0\xbb\x49\xc2\x29"
+ "\x58\x89\xdd\xe9\x62\x52\xfb\xba\x22\xa6\xd9\x16\xfa\x55\xb3\x06"
+ "\xed\x6d\x70\x6e\xdc\x47\x7c\x67\x1a\xcc\x27\x98\xd4\xd7\xe6\xf0"
+ "\xf8\x9f\x51\x3e\xf0\xee\xad\xb6\x78\x69\x71\xb5\xcb\x09\xa3\xa6"
+ "\x3f\x29\x24\x46\xe0\x65\xbc\x9f\x6c\xe9\xf9\x49\x49\x96\x75\xe5"
+ "\xe1\xff\x82\x70\xf4\x7e\xff\x8f\xec\x47\x98\x6d\x5b\x88\x60\xee"
+ "\x43\xb1\xe2\x14\xc1\x49\x95\x74\x46\xd3\x3f\x73\xb2\xe9\x88\xe0"
+ "\xd3\xb1\xc4\x2c\xef\xee\xdd\x6c\xc5\xa1\x29\xef\x86\xd2\x36\x8a"
+ "\x2f\x7c\x9d\x28\x0a\x6d\xc9\x5a\xdb\xd4\x04\x06\x36\x96\x09\x03"
+ "\x71\x5d\x38\x67\xa2\x08\x2a\x04\xe7\xd6\x51\x5a\x19\x9d\xe7\xf1"
+ "\x5d\x6f\xe2\xff\x48\x37\xb7\x8b\xb1\x14\xb4\x96\xcd\xf0\xa7\xbd"
+ "\xef\x20\xff\x0a\x8d\x08\xb7\x15\x98\x5a\x13\xd2\xda\x2a\x27\x75",
+ .expected_a_public =
+ "\x45\x96\x5a\xb7\x78\x5c\xa4\x4d\x39\xb2\x5f\xc8\xc2\xaa\x1a\xf4"
+ "\xa6\x68\xf6\x6f\x7e\xa8\x4a\x5b\x0e\xba\x0a\x99\x85\xf9\x63\xd4"
+ "\x58\x21\x6d\xa8\x3c\xf4\x05\x10\xb0\x0d\x6f\x1c\xa0\x17\x85\xae"
+ "\x68\xbf\xcc\x00\xc8\x86\x1b\x24\x31\xc9\x49\x23\x91\xe0\x71\x29"
+ "\x06\x39\x39\x93\x49\x9c\x75\x18\x1a\x8b\x61\x73\x1c\x7f\x37\xd5"
+ "\xf1\xab\x20\x5e\x62\x25\xeb\x58\xd5\xfa\xc9\x7f\xad\x57\xd5\xcc"
+ "\x0d\xc1\x7a\x2b\x33\x2a\x76\x84\x33\x26\x97\xcf\x47\x9d\x72\x2a"
+ "\xc9\x39\xde\xa8\x42\x27\x2d\xdc\xee\x00\x60\xd2\x4f\x13\xe0\xde"
+ "\xd5\xc7\xf6\x7d\x8b\x2a\x43\x49\x40\x99\xc2\x61\x84\x8e\x57\x09"
+ "\x7c\xcc\x19\x46\xbd\x4c\xd2\x7c\x7d\x02\x4d\x88\xdf\x58\x24\x80"
+ "\xeb\x19\x3b\x2a\x13\x2b\x19\x85\x3c\xd8\x31\x03\x00\xa4\xd4\x57"
+ "\x23\x2c\x24\x37\xb3\x62\xea\x35\x29\xd0\x2c\xac\xfd\xbd\xdf\x3d"
+ "\xa6\xce\xfa\x0d\x5b\xb6\x15\x8b\xe3\x58\xe9\xad\x99\x87\x29\x51"
+ "\x8d\x97\xd7\xa9\x55\xf0\x72\x6e\x4e\x58\xcb\x2b\x4d\xbd\xd0\x48"
+ "\x7d\x14\x86\xdb\x3f\xa2\x5f\x6e\x35\x4a\xe1\x70\xb1\x53\x72\xb7"
+ "\xbc\xe9\x3d\x1b\x33\xc0\x54\x6f\x43\x55\x76\x85\x7f\x9b\xa5\xb3"
+ "\xc1\x1d\xd3\xfe\xe2\xd5\x96\x3d\xdd\x92\x04\xb1\xad\x75\xdb\x13"
+ "\x4e\x49\xfc\x35\x34\xc5\xda\x13\x98\xb8\x12\xbe\xda\x90\x55\x7c"
+ "\x11\x6c\xbe\x2b\x8c\x51\x29\x23\xc1\x51\xbc\x0c\x1c\xe2\x20\xfc"
+ "\xfe\xf2\xaa\x71\x9b\x21\xdf\x25\x1f\x68\x21\x7e\xe1\xc9\x87\xa0"
+ "\x20\xf6\x8d\x4f\x27\x8c\x3c\x0f\x9d\xf4\x69\x25\xaa\x49\xab\x94"
+ "\x22\x5a\x92\x3a\xba\xb4\xc2\x8c\x5a\xaa\x04\xbf\x46\xc5\xaa\x93"
+ "\xab\x0d\xe9\x54\x6c\x3a\x64\xa6\xa2\x21\x66\xee\x1c\x10\x21\x84"
+ "\xf2\x9e\xcc\x57\xac\xc2\x25\x62\xad\xbb\x59\xef\x25\x61\x6c\x81"
+ "\x38\x8a\xdc\x8c\xeb\x7b\x18\x1d\xaf\xa9\xc5\x9a\xf4\x49\x26\x8a"
+ "\x25\xc4\x3e\x31\x95\x28\xef\xf7\x72\xe9\xc5\xaa\x59\x72\x2b\x67"
+ "\x47\xe8\x6b\x51\x05\x24\xb8\x18\xb3\x34\x0f\x8c\x2b\x80\xba\x61"
+ "\x1c\xbe\x9e\x9a\x7c\xe3\x60\x5e\x49\x02\xff\x50\x8a\x64\x28\x64"
+ "\x46\x7b\x83\x14\x72\x6e\x59\x9b\x56\x09\xb4\xf0\xde\x52\xc3\xf3"
+ "\x58\x17\x6a\xae\xb1\x0f\xf4\x39\xcc\xd8\xce\x4d\xe1\x51\x17\x88"
+ "\xe4\x98\xd9\xd1\xa9\x55\xbc\xbf\x7e\xc4\x51\x96\xdb\x44\x1d\xcd"
+ "\x8d\x74\xad\xa7\x8f\x87\x83\x75\xfc\x36\xb7\xd2\xd4\x89\x16\x97"
+ "\xe4\xc6\x2a\xe9\x65\xc8\xca\x1c\xbd\x86\xaf\x57\x80\xf7\xdd\x42"
+ "\xc0\x3b\x3f\x87\x51\x02\x2f\xf8\xd8\x68\x0f\x3d\x95\x2d\xf1\x67"
+ "\x09\xa6\x5d\x0b\x7e\x01\xb4\xb2\x32\x01\xa8\xd0\x58\x0d\xe6\xa2"
+ "\xd8\x4b\x22\x10\x7d\x11\xf3\xc2\x4e\xb8\x43\x8e\x31\x79\x59\xe2"
+ "\xc4\x96\x29\x17\x40\x06\x0d\xdf\xdf\xc3\x02\x30\x2a\xd1\x8e\xf2"
+ "\xee\x2d\xd2\x12\x63\x5a\x1d\x3c\xba\x4a\xc4\x56\x90\xc6\x12\x0b"
+ "\xe0\x04\x3f\x35\x59\x8e\x40\x75\xf4\x4c\x10\x61\xb9\x30\x89\x7c"
+ "\x8d\x0e\x25\xb7\x5a\x6b\x97\x05\xc6\x37\x80\x6e\x94\x56\xa8\x5f"
+ "\x03\x94\x59\xc8\xc5\x3e\xdc\x23\xe5\x68\x4f\xd7\xbb\x6d\x7e\xc1"
+ "\x8d\xf9\xcc\x3f\x38\xad\x77\xb3\x18\x61\xed\x04\xc0\x71\xa7\x96"
+ "\xb1\xaf\x1d\x69\x78\xda\x6d\x89\x8b\x50\x75\x99\x44\xb3\xb2\x75"
+ "\xd1\xc8\x14\x40\xa1\x0a\xbf\xc4\x45\xc4\xee\x12\x90\x76\x26\x64"
+ "\xb7\x73\x2e\x0b\x0c\xfa\xc3\x55\x29\x24\x1b\x7a\x00\x27\x07\x26"
+ "\x36\xf0\x38\x1a\xe3\xb7\xc4\x8d\x1c\x9c\xa9\xc0\xc1\x45\x91\x9e"
+ "\x86\xdd\x82\x94\x45\xfa\xcd\x5a\x19\x12\x7d\xef\xda\x17\xad\x21"
+ "\x17\x89\x8b\x45\xa7\xf5\xed\x51\x9e\x58\x13\xdc\x84\xa4\xe6\x37",
+ .expected_ss =
+ "\x9a\x9c\x1c\xb7\x73\x2f\xf2\x12\xed\x59\x01\xbb\x75\xf7\xf5\xe4"
+ "\xa0\xa8\xbc\x3f\x3f\xb6\xf7\x74\x6e\xc4\xba\x6d\x6c\x4d\x93\x31"
+ "\x2b\xa7\xa4\xb3\x47\x8f\x77\x04\xb5\xa5\xab\xca\x6b\x5a\xe2\x86"
+ "\x02\x60\xca\xb4\xd7\x5e\xe0\x0f\x73\xdd\xa2\x38\x7c\xae\x0f\x5a"
+ "\x1a\xd7\xfd\xb6\xc8\x6f\xdd\xe0\x98\xd5\x07\xea\x1f\x2a\xbb\x9e"
+ "\xef\x01\x24\x04\xee\xf5\x89\xb1\x12\x26\x54\x95\xef\xcb\x84\xe9"
+ "\xae\x05\xef\x63\x25\x15\x65\x79\x79\x79\x91\xc3\x76\x72\xb4\x85"
+ "\x86\xd9\xd3\x03\xb0\xff\x04\x96\x05\x3c\xde\xbf\x47\x34\x76\x70"
+ "\x17\xd2\x24\x83\xb9\xbb\xcf\x70\x7c\xb8\xc6\x7b\x4e\x01\x86\x36"
+ "\xc7\xc5\xe5\x8b\x7c\x69\x74\x9a\xfe\x1f\x58\x85\x0f\x00\xf8\x4e"
+ "\xf1\x56\xdc\xd1\x11\x28\x2c\xcf\x6c\xb9\xc9\x57\x17\x2e\x19\x19"
+ "\x55\xb3\x4c\xd8\xfb\xe7\x6f\x70\x63\xf9\x53\x45\xdd\xd5\x62\x95"
+ "\xd3\x7d\x7e\xa0\x00\x1a\x62\x9f\x96\x0a\x5d\x0a\x25\x02\xbb\xff"
+ "\x5a\xe8\x9e\x5a\x66\x08\x93\xbc\x92\xaf\xd2\x28\x04\x97\xc1\x54"
+ "\xfe\xcc\x0a\x25\xa2\xf4\x1d\x5a\x9a\xb1\x3e\x9c\xba\x78\xe2\xcf"
+ "\x71\x70\xe3\x40\xea\xba\x69\x9b\x03\xdd\x99\x26\x09\x84\x9d\x69"
+ "\x4d\x3d\x0b\xe9\x3f\x51\xcd\x05\xe5\x00\xaf\x2c\xd3\xf6\xc0\x68"
+ "\xb5\x23\x53\x33\x14\xbd\x39\x1c\xbd\x1b\xe6\x72\x90\xcc\xc2\x86"
+ "\x1a\x42\x83\x55\xb3\xed\x0b\x62\x6d\x0e\xbb\x9e\x2a\x42\x32\x05"
+ "\x3f\xf2\x2c\xc8\x9f\x3c\xd2\xb1\x0b\xb6\x4c\xa0\x22\x36\xee\xb9"
+ "\x55\x23\x3e\x80\xc7\x28\x7c\x39\x11\xd3\x4a\x96\x2e\xef\x52\x34"
+ "\xf2\xda\xb1\xc6\xf5\x02\x10\xbf\x56\x6b\x50\x56\xcd\x2c\xfe\xe1"
+ "\x94\x14\x19\x24\x6e\x9a\xdf\x0c\xb8\xe2\xb8\xd5\xa3\xc1\x22\x8e"
+ "\x84\x92\x00\x16\xf1\x3f\x83\xf6\x36\x31\xa5\x38\xc6\xcf\xf8\x9b"
+ "\x03\xc7\x6f\xb9\xa1\x04\xdf\x20\x0f\x0b\x0f\x70\xff\x57\x36\x7f"
+ "\xb3\x6b\xcb\x8f\x48\xf7\xb2\xdb\x85\x05\xd1\xfe\x34\x05\xf6\x57"
+ "\xb4\x5b\xcc\x3f\x0e\xba\x36\x59\xb0\xfd\x4d\xf6\xf4\x5e\xd2\x65"
+ "\x1d\x98\x87\xb4\x5e\xff\x29\xaa\x84\x9b\x44\x0f\x06\x36\x61\xbd"
+ "\xdb\x51\xda\x56\xc2\xd6\x19\xe2\x57\x4f\xd0\x29\x71\xc8\xe4\xd6"
+ "\xfb\x8c\xd0\xfc\x4f\x25\x09\xa6\xfc\x67\xe2\xb8\xac\xd3\x88\x8f"
+ "\x1f\xf6\xa1\xe3\x45\xa6\x34\xe3\xb1\x6b\xb7\x37\x0e\x06\xc7\x63"
+ "\xde\xac\x3b\xac\x07\x91\x64\xcc\x12\x10\x46\x85\x14\x0b\x6b\x03"
+ "\xba\x4a\x85\xae\xc5\x8c\xa5\x9d\x36\x38\x33\xca\x42\x9c\x4b\x0c"
+ "\x46\xe1\x77\xe9\x1f\x80\xfe\xb7\x1d\x5a\xf4\xc6\x11\x26\x78\xea"
+ "\x81\x25\x77\x47\xed\x8b\x59\xc2\x6b\x49\xff\x83\x56\xec\xa5\xf0"
+ "\xe0\x8b\x15\xd4\x99\x40\x2a\x65\x2a\x98\xf4\x71\x35\x63\x84\x08"
+ "\x4d\xcd\x71\x85\x55\xbc\xa4\x1c\x90\x93\x03\x41\xde\xed\x78\x62"
+ "\x07\x30\x50\xac\x60\x21\x06\xc3\xab\xa4\x04\xc0\xc2\x32\x07\xc4"
+ "\x1f\x2f\xec\xe2\x32\xbf\xbe\x5e\x50\x5b\x2a\x19\x71\x44\x37\x76"
+ "\x8b\xbc\xdb\x73\x98\x65\x78\xc9\x33\x97\x7e\xdc\x60\xa8\x87\xf2"
+ "\xb5\x96\x55\x7f\x44\x07\xcb\x3b\xf3\xd7\x82\xfd\x77\x21\x82\x21"
+ "\x1a\x8b\xa2\xf5\x1f\x66\xd0\x57\x00\x4f\xa9\xa5\x33\xb8\x69\x91"
+ "\xe8\x2e\xf7\x73\x47\x89\x30\x9b\xb1\xfd\xe1\x5d\x11\xfd\x84\xd9"
+ "\xa2\x91\x1f\x8a\xa7\x7a\x77\x8e\x3b\x10\x1d\x0a\x59\x50\x34\xb0"
+ "\xc3\x90\x9f\x56\xb7\x43\xeb\x51\x99\x2b\x8e\x6d\x7b\x58\xe7\xc0"
+ "\x7f\x3d\xa0\x27\x50\xf2\x6e\xc8\x1e\x7f\x84\xb3\xe1\xf7\x09\x85"
+ "\xd2\x9b\x56\x6b\xba\xa5\x19\x2e\xec\xd8\x5c\xf5\x4e\x43\x36\x2e"
+ "\x89\x85\x41\x7f\x9c\x91\x2e\x62\xc3\x41\xcf\x0e\xa1\x7f\xeb\x50",
+ .secret_size = 784,
+ .b_public_size = 768,
+ .expected_a_public_size = 768,
+ .expected_ss_size = 768,
+ },
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x00" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x00\x10" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#endif
+ .b_secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x03" /* len */
+ "\x00\x03\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x03\x10" /* len */
+ "\x00\x00\x03\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x63\x3e\x6f\xe0\xfe\x9f\x4a\x01\x62\x77\xce\xf1\xc7\xcc\x49\x4d"
+ "\x92\x53\x56\xe3\x39\x15\x81\xb2\xcd\xdc\xaf\x5e\xbf\x31\x1f\x69"
+ "\xce\x41\x35\x24\xaa\x46\x53\xb5\xb7\x3f\x2b\xad\x95\x14\xfb\xe4"
+ "\x9a\x61\xcd\x0f\x1f\x02\xee\xa4\x79\x2c\x9d\x1a\x7c\x62\x82\x39"
+ "\xdd\x43\xcc\x58\x9f\x62\x47\x56\x1d\x0f\xc2\x67\xbc\x24\xd0\xf9"
+ "\x0a\x50\x1b\x10\xe7\xbb\xd1\xc2\x01\xbb\xc4\x4c\xda\x12\x60\x0e"
+ "\x95\x2b\xde\x09\xd6\x67\xe1\xbc\x4c\xb9\x67\xdf\xd0\x1f\x97\xb4"
+ "\xde\xcb\x6b\x78\x83\x51\x74\x33\x01\x7f\xf6\x0a\x95\x69\x93\x00"
+ "\x2a\xc3\x75\x8e\xef\xbe\x53\x11\x6d\xc4\xd0\x9f\x6d\x63\x48\xc1"
+ "\x91\x1f\x7d\x88\xa7\x90\x78\xd1\x7e\x52\x42\x10\x01\xb4\x27\x95"
+ "\x91\x43\xcc\x82\x91\x86\x62\xa0\x9d\xef\x65\x6e\x67\xcf\x19\x11"
+ "\x35\x37\x5e\x94\x97\x83\xa6\x83\x1c\x7e\x8a\x3e\x32\xb0\xce\xff"
+ "\x20\xdc\x7b\x6e\x18\xd9\x6b\x27\x31\xfc\xc3\xef\x47\x8d\xbe\x34"
+ "\x2b\xc7\x60\x74\x3c\x93\xb3\x8e\x54\x77\x4e\x73\xe6\x40\x72\x35"
+ "\xb0\xf0\x06\x53\x43\xbe\xd0\xc3\x87\xcc\x38\x96\xa9\x10\xa0\xd6"
+ "\x17\xed\xa5\x6a\xf4\xf6\xaa\x77\x40\xed\x7d\x2e\x58\x0f\x5b\x04"
+ "\x5a\x41\x12\x95\x22\xcb\xa3\xce\x8b\x6d\x6d\x89\xec\x7c\x1d\x25"
+ "\x27\x52\x50\xa0\x5b\x93\x8c\x5d\x3f\x56\xb9\xa6\x5e\xe5\xf7\x9b"
+ "\xc7\x9a\x4a\x2e\x79\xb5\xca\x29\x58\x52\xa0\x63\xe4\x9d\xeb\x4c"
+ "\x4c\xa8\x37\x0b\xe9\xa0\x18\xf1\x86\xf6\x4d\x32\xfb\x9e\x4f\xb3"
+ "\x7b\x5d\x58\x78\x70\xbd\x56\xac\x99\x75\x25\x71\x66\x76\x4e\x5e"
+ "\x67\x4f\xb1\x17\xa7\x8b\x55\x12\x87\x01\x4e\xd1\x66\xef\xd0\x70"
+ "\xaf\x14\x34\xee\x2a\x76\x49\x25\xa6\x2e\x43\x37\x75\x7d\x1a\xad"
+ "\x08\xd5\x01\x85\x9c\xe1\x20\xd8\x38\x5c\x57\xa5\xed\x9d\x46\x3a"
+ "\xb7\x46\x60\x29\x8b\xc4\x21\x50\x0a\x30\x9c\x57\x42\xe4\x35\xf8"
+ "\x12\x5c\x4f\xa2\x20\xc2\xc9\x43\xe3\x6d\x20\xbc\xdf\xb8\x37\x33"
+ "\x45\x43\x06\x4e\x08\x6f\x8a\xcd\x61\xc3\x1b\x05\x28\x82\xbe\xf0"
+ "\x48\x33\xe5\x93\xc9\x1a\x61\x16\x67\x03\x9d\x47\x9d\x74\xeb\xae"
+ "\x13\xf2\xb4\x1b\x09\x11\xf5\x15\xcb\x28\xfd\x50\xe0\xbc\x58\x36"
+ "\x38\x91\x2c\x07\x27\x1f\x49\x68\xf4\xce\xad\xf7\xba\xec\x5d\x3d"
+ "\xfd\x27\xe2\xcf\xf4\x56\xfe\x08\xa6\x11\x61\xcb\x6c\x9f\xf9\x3c"
+ "\x57\x0b\x8b\xaa\x00\x16\x18\xba\x1f\xe8\x4f\x01\xe2\x79\x2a\x0b"
+ "\xc1\xbd\x52\xef\xe6\xf7\x5a\x66\xfe\x07\x3b\x50\x6b\xbb\xcb\x39"
+ "\x3c\x94\xf6\x21\x0d\x68\x69\xa4\xed\x2e\xb5\x85\x03\x11\x38\x79"
+ "\xec\xb5\x22\x23\xdf\x9e\xad\xb4\xbe\xd7\xc7\xdf\xea\x30\x23\x8a"
+ "\xb7\x21\x0a\x9d\xbd\x99\x13\x7d\x5f\x7e\xaf\x28\x54\x3f\xca\x5e"
+ "\xf4\xfc\x05\x0d\x65\x67\xd8\xf6\x8e\x90\x9d\x0d\xcf\x62\x82\xd6"
+ "\x9f\x02\xf8\xca\xfa\x42\x24\x7f\x4d\xb7\xfc\x92\xa6\x4a\x51\xc4"
+ "\xd8\xae\x19\x87\xc6\xa3\x83\xbe\x7b\x6d\xc3\xf5\xb8\xad\x4a\x05"
+ "\x78\x84\x3a\x15\x2e\x40\xbe\x79\xa9\xc0\x12\xa1\x48\x39\xc3\xdb"
+ "\x47\x4f\x7d\xea\x6d\xc7\xfa\x2c\x4e\xe9\xa5\x85\x81\xea\x6c\xcd"
+ "\x8a\xe5\x74\x17\x76\x31\x31\x75\x96\x83\xca\x81\xbb\x5c\xa9\x79"
+ "\x2c\xbd\x09\xfe\xe4\x86\x0d\x8c\x76\x9c\xbc\xe8\x93\xe4\xd0\xe4"
+ "\x0f\xf8\xff\x24\x7e\x66\x61\x69\xfb\xe4\x46\x08\x94\x99\xa5\x53"
+ "\xd7\xe4\x29\x72\x86\x86\xe8\x1d\x37\xfa\xcb\xd0\x8d\x51\xd0\xbf"
+ "\x81\xcf\x55\xb9\xc5\x78\x8c\x74\xa0\x16\x3a\xd2\x19\x94\x29\x6a"
+ "\x5e\xec\xd3\x20\xa0\xb2\xfd\xce\xd4\x14\xa3\x39\x10\xa9\xf4\x4e"
+ "\xba\x21\x09\x5c\xe6\x61\x43\x51\xae\xc4\x71\xd7\x21\xef\x98\x39",
+ .b_public =
+ "\x45\x96\x5a\xb7\x78\x5c\xa4\x4d\x39\xb2\x5f\xc8\xc2\xaa\x1a\xf4"
+ "\xa6\x68\xf6\x6f\x7e\xa8\x4a\x5b\x0e\xba\x0a\x99\x85\xf9\x63\xd4"
+ "\x58\x21\x6d\xa8\x3c\xf4\x05\x10\xb0\x0d\x6f\x1c\xa0\x17\x85\xae"
+ "\x68\xbf\xcc\x00\xc8\x86\x1b\x24\x31\xc9\x49\x23\x91\xe0\x71\x29"
+ "\x06\x39\x39\x93\x49\x9c\x75\x18\x1a\x8b\x61\x73\x1c\x7f\x37\xd5"
+ "\xf1\xab\x20\x5e\x62\x25\xeb\x58\xd5\xfa\xc9\x7f\xad\x57\xd5\xcc"
+ "\x0d\xc1\x7a\x2b\x33\x2a\x76\x84\x33\x26\x97\xcf\x47\x9d\x72\x2a"
+ "\xc9\x39\xde\xa8\x42\x27\x2d\xdc\xee\x00\x60\xd2\x4f\x13\xe0\xde"
+ "\xd5\xc7\xf6\x7d\x8b\x2a\x43\x49\x40\x99\xc2\x61\x84\x8e\x57\x09"
+ "\x7c\xcc\x19\x46\xbd\x4c\xd2\x7c\x7d\x02\x4d\x88\xdf\x58\x24\x80"
+ "\xeb\x19\x3b\x2a\x13\x2b\x19\x85\x3c\xd8\x31\x03\x00\xa4\xd4\x57"
+ "\x23\x2c\x24\x37\xb3\x62\xea\x35\x29\xd0\x2c\xac\xfd\xbd\xdf\x3d"
+ "\xa6\xce\xfa\x0d\x5b\xb6\x15\x8b\xe3\x58\xe9\xad\x99\x87\x29\x51"
+ "\x8d\x97\xd7\xa9\x55\xf0\x72\x6e\x4e\x58\xcb\x2b\x4d\xbd\xd0\x48"
+ "\x7d\x14\x86\xdb\x3f\xa2\x5f\x6e\x35\x4a\xe1\x70\xb1\x53\x72\xb7"
+ "\xbc\xe9\x3d\x1b\x33\xc0\x54\x6f\x43\x55\x76\x85\x7f\x9b\xa5\xb3"
+ "\xc1\x1d\xd3\xfe\xe2\xd5\x96\x3d\xdd\x92\x04\xb1\xad\x75\xdb\x13"
+ "\x4e\x49\xfc\x35\x34\xc5\xda\x13\x98\xb8\x12\xbe\xda\x90\x55\x7c"
+ "\x11\x6c\xbe\x2b\x8c\x51\x29\x23\xc1\x51\xbc\x0c\x1c\xe2\x20\xfc"
+ "\xfe\xf2\xaa\x71\x9b\x21\xdf\x25\x1f\x68\x21\x7e\xe1\xc9\x87\xa0"
+ "\x20\xf6\x8d\x4f\x27\x8c\x3c\x0f\x9d\xf4\x69\x25\xaa\x49\xab\x94"
+ "\x22\x5a\x92\x3a\xba\xb4\xc2\x8c\x5a\xaa\x04\xbf\x46\xc5\xaa\x93"
+ "\xab\x0d\xe9\x54\x6c\x3a\x64\xa6\xa2\x21\x66\xee\x1c\x10\x21\x84"
+ "\xf2\x9e\xcc\x57\xac\xc2\x25\x62\xad\xbb\x59\xef\x25\x61\x6c\x81"
+ "\x38\x8a\xdc\x8c\xeb\x7b\x18\x1d\xaf\xa9\xc5\x9a\xf4\x49\x26\x8a"
+ "\x25\xc4\x3e\x31\x95\x28\xef\xf7\x72\xe9\xc5\xaa\x59\x72\x2b\x67"
+ "\x47\xe8\x6b\x51\x05\x24\xb8\x18\xb3\x34\x0f\x8c\x2b\x80\xba\x61"
+ "\x1c\xbe\x9e\x9a\x7c\xe3\x60\x5e\x49\x02\xff\x50\x8a\x64\x28\x64"
+ "\x46\x7b\x83\x14\x72\x6e\x59\x9b\x56\x09\xb4\xf0\xde\x52\xc3\xf3"
+ "\x58\x17\x6a\xae\xb1\x0f\xf4\x39\xcc\xd8\xce\x4d\xe1\x51\x17\x88"
+ "\xe4\x98\xd9\xd1\xa9\x55\xbc\xbf\x7e\xc4\x51\x96\xdb\x44\x1d\xcd"
+ "\x8d\x74\xad\xa7\x8f\x87\x83\x75\xfc\x36\xb7\xd2\xd4\x89\x16\x97"
+ "\xe4\xc6\x2a\xe9\x65\xc8\xca\x1c\xbd\x86\xaf\x57\x80\xf7\xdd\x42"
+ "\xc0\x3b\x3f\x87\x51\x02\x2f\xf8\xd8\x68\x0f\x3d\x95\x2d\xf1\x67"
+ "\x09\xa6\x5d\x0b\x7e\x01\xb4\xb2\x32\x01\xa8\xd0\x58\x0d\xe6\xa2"
+ "\xd8\x4b\x22\x10\x7d\x11\xf3\xc2\x4e\xb8\x43\x8e\x31\x79\x59\xe2"
+ "\xc4\x96\x29\x17\x40\x06\x0d\xdf\xdf\xc3\x02\x30\x2a\xd1\x8e\xf2"
+ "\xee\x2d\xd2\x12\x63\x5a\x1d\x3c\xba\x4a\xc4\x56\x90\xc6\x12\x0b"
+ "\xe0\x04\x3f\x35\x59\x8e\x40\x75\xf4\x4c\x10\x61\xb9\x30\x89\x7c"
+ "\x8d\x0e\x25\xb7\x5a\x6b\x97\x05\xc6\x37\x80\x6e\x94\x56\xa8\x5f"
+ "\x03\x94\x59\xc8\xc5\x3e\xdc\x23\xe5\x68\x4f\xd7\xbb\x6d\x7e\xc1"
+ "\x8d\xf9\xcc\x3f\x38\xad\x77\xb3\x18\x61\xed\x04\xc0\x71\xa7\x96"
+ "\xb1\xaf\x1d\x69\x78\xda\x6d\x89\x8b\x50\x75\x99\x44\xb3\xb2\x75"
+ "\xd1\xc8\x14\x40\xa1\x0a\xbf\xc4\x45\xc4\xee\x12\x90\x76\x26\x64"
+ "\xb7\x73\x2e\x0b\x0c\xfa\xc3\x55\x29\x24\x1b\x7a\x00\x27\x07\x26"
+ "\x36\xf0\x38\x1a\xe3\xb7\xc4\x8d\x1c\x9c\xa9\xc0\xc1\x45\x91\x9e"
+ "\x86\xdd\x82\x94\x45\xfa\xcd\x5a\x19\x12\x7d\xef\xda\x17\xad\x21"
+ "\x17\x89\x8b\x45\xa7\xf5\xed\x51\x9e\x58\x13\xdc\x84\xa4\xe6\x37",
+ .secret_size = 16,
+ .b_secret_size = 784,
+ .b_public_size = 768,
+ .expected_a_public_size = 768,
+ .expected_ss_size = 768,
+ .genkey = true,
+ },
+};
+
+static const struct kpp_testvec ffdhe8192_dh_tv_template[] __maybe_unused = {
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x04" /* len */
+ "\x00\x04\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x04\x10" /* len */
+ "\x00\x00\x04\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x76\x6e\xeb\xf9\xeb\x76\xae\x37\xcb\x19\x49\x8b\xeb\xaf\xb0\x4b"
+ "\x6d\xe9\x15\xad\xda\xf2\xef\x58\xe9\xd6\xdd\x4c\xb3\x56\xd0\x3b"
+ "\x00\xb0\x65\xed\xae\xe0\x2e\xdf\x8f\x45\x3f\x3c\x5d\x2f\xfa\x96"
+ "\x36\x33\xb2\x01\x8b\x0f\xe8\x46\x15\x6d\x60\x5b\xec\x32\xc3\x3b"
+ "\x06\xf3\xb4\x1b\x9a\xef\x3c\x03\x0e\xcc\xce\x1d\x24\xa0\xc9\x08"
+ "\x65\xf9\x45\xe5\xd2\x43\x08\x88\x58\xd6\x46\xe7\xbb\x25\xac\xed"
+ "\x3b\xac\x6f\x5e\xfb\xd6\x19\xa6\x20\x3a\x1d\x0c\xe8\x00\x72\x54"
+ "\xd7\xd9\xc9\x26\x49\x18\xc6\xb8\xbc\xdd\xf3\xce\xf3\x7b\x69\x04"
+ "\x5c\x6f\x11\xdb\x44\x42\x72\xb6\xb7\x84\x17\x86\x47\x3f\xc5\xa1"
+ "\xd8\x86\xef\xe2\x27\x49\x2b\x8f\x3e\x91\x12\xd9\x45\x96\xf7\xe6"
+ "\x77\x76\x36\x58\x71\x9a\xb1\xdb\xcf\x24\x9e\x7e\xad\xce\x45\xba"
+ "\xb5\xec\x8e\xb9\xd6\x7b\x3d\x76\xa4\x85\xad\xd8\x49\x9b\x80\x9d"
+ "\x7f\x9f\x85\x09\x9e\x86\x5b\x6b\xf3\x8d\x39\x5e\x6f\xe4\x30\xc8"
+ "\xa5\xf3\xdf\x68\x73\x6b\x2e\x9a\xcb\xac\x0a\x0d\x44\xc1\xaf\xb2"
+ "\x11\x1b\x7c\x43\x08\x44\x43\xe2\x4e\xfd\x93\x30\x99\x09\x12\xbb"
+ "\xf6\x31\x34\xa5\x3d\x45\x98\xee\xd7\x2a\x1a\x89\xf5\x37\x92\x33"
+ "\xa0\xdd\xf5\xfb\x1f\x90\x42\x55\x5a\x0b\x82\xff\xf0\x96\x92\x15"
+ "\x65\x5a\x55\x96\xca\x1b\xd5\xe5\xb5\x94\xde\x2e\xa6\x03\x57\x9e"
+ "\x15\xe4\x32\x2b\x1f\xb2\x22\x21\xe9\xa0\x05\xd3\x65\x6c\x11\x66"
+ "\x25\x38\xbb\xa3\x6c\xc2\x0b\x2b\xd0\x7a\x20\x26\x29\x37\x5d\x5f"
+ "\xd8\xff\x2a\xcd\x46\x6c\xd6\x6e\xe5\x77\x1a\xe6\x33\xf1\x8e\xc8"
+ "\x10\x30\x11\x00\x27\xf9\x7d\x0e\x28\x43\xa7\x67\x38\x7f\x16\xda"
+ "\xd0\x01\x8e\xa4\xe8\x6f\xcd\x23\xaf\x77\x52\x34\xad\x7e\xc3\xed"
+ "\x2d\x10\x0a\x33\xdc\xcf\x1b\x88\x0f\xcc\x48\x7f\x42\xf0\x9e\x13"
+ "\x1f\xf5\xd1\xe9\x90\x87\xbd\xfa\x5f\x1d\x77\x55\xcb\xc3\x05\xaf"
+ "\x71\xd0\xe0\xab\x46\x31\xd7\xea\x89\x54\x2d\x39\xaf\xf6\x4f\x74"
+ "\xaf\x46\x58\x89\x78\x95\x2e\xe6\x90\xb7\xaa\x00\x73\x9f\xed\xb9"
+ "\x00\xd6\xf6\x6d\x26\x59\xcd\x56\xdb\xf7\x3d\x5f\xeb\x6e\x46\x33"
+ "\xb1\x23\xed\x9f\x8d\x58\xdc\xb4\x28\x3b\x90\x09\xc4\x61\x02\x1f"
+ "\xf8\x62\xf2\x6e\xc1\x94\x71\x66\x93\x11\xdf\xaa\x3e\xd7\xb5\xe5"
+ "\xc1\x78\xe9\x14\xcd\x55\x16\x51\xdf\x8d\xd0\x94\x8c\x43\xe9\xb8"
+ "\x1d\x42\x7f\x76\xbc\x6f\x87\x42\x88\xde\xd7\x52\x78\x00\x4f\x18"
+ "\x02\xe7\x7b\xe2\x8a\xc3\xd1\x43\xa5\xac\xda\xb0\x8d\x19\x96\xd4"
+ "\x81\xe0\x75\xe9\xca\x41\x7e\x1f\x93\x0b\x26\x24\xb3\xaa\xdd\x10"
+ "\x20\xd3\xf2\x9f\x3f\xdf\x65\xde\x67\x79\xdc\x76\x9f\x3c\x72\x75"
+ "\x65\x8a\x30\xcc\xd2\xcc\x06\xb1\xab\x62\x86\x78\x5d\xb8\xce\x72"
+ "\xb3\x12\xc7\x9f\x07\xd0\x6b\x98\x82\x9b\x6c\xbb\x15\xe5\xcc\xf4"
+ "\xc8\xf4\x60\x81\xdc\xd3\x09\x1b\x5e\xd4\xf3\x55\xcf\x1c\x16\x83"
+ "\x61\xb4\x2e\xcc\x08\x67\x58\xfd\x46\x64\xbc\x29\x4b\xdd\xda\xec"
+ "\xdc\xc6\xa9\xa5\x73\xfb\xf8\xf3\xaf\x89\xa8\x9e\x25\x14\xfa\xac"
+ "\xeb\x1c\x7c\x80\x96\x66\x4d\x41\x67\x9b\x07\x4f\x0a\x97\x17\x1c"
+ "\x4d\x61\xc7\x2e\x6f\x36\x98\x29\x50\x39\x6d\xe7\x70\xda\xf0\xc8"
+ "\x05\x80\x7b\x32\xff\xfd\x12\xde\x61\x0d\xf9\x4c\x21\xf1\x56\x72"
+ "\x3d\x61\x46\xc0\x2d\x07\xd1\x6c\xd3\xbe\x9a\x21\x83\x85\xf7\xed"
+ "\x53\x95\x44\x40\x8f\x75\x12\x18\xc2\x9a\xfd\x5e\xce\x66\xa6\x7f"
+ "\x57\xc0\xd7\x73\x76\xb3\x13\xda\x2e\x58\xc6\x27\x40\xb2\x2d\xef"
+ "\x7d\x72\xb4\xa8\x75\x6f\xcc\x5f\x42\x3e\x2c\x90\x36\x59\xa0\x34"
+ "\xaa\xce\xbc\x04\x4c\xe6\x56\xc2\xcd\xa6\x1c\x59\x04\x56\x53\xcf"
+ "\x6d\xd7\xf0\xb1\x4f\x91\xfa\x84\xcf\x4b\x8d\x50\x4c\xf8\x2a\x31"
+ "\x5f\xe3\xba\x79\xb4\xcc\x59\x64\xe3\x7a\xfa\xf6\x06\x9d\x04\xbb"
+ "\xce\x61\xbf\x9e\x59\x0a\x09\x51\x6a\xbb\x0b\x80\xe0\x91\xc1\x51"
+ "\x04\x58\x67\x67\x4b\x42\x4f\x95\x68\x75\xe2\x1f\x9c\x14\x70\xfd"
+ "\x3a\x8a\xce\x8b\x04\xa1\x89\xe7\xb4\xbf\x70\xfe\xf3\x0c\x48\x04"
+ "\x3a\xd2\x85\x68\x03\xe7\xfa\xec\x5b\x55\xb7\x95\xfd\x5b\x19\x35"
+ "\xad\xcb\x4a\x63\x03\x44\x64\x2a\x48\x59\x9a\x26\x43\x96\x8c\xe6"
+ "\xbd\xb7\x90\xd4\x5f\x8d\x08\x28\xa8\xc5\x89\x70\xb9\x6e\xd3\x3b"
+ "\x76\x0e\x37\x98\x15\x27\xca\xc9\xb0\xe0\xfd\xf3\xc6\xdf\x69\xce"
+ "\xe1\x5f\x6a\x3e\x5c\x86\xe2\x58\x41\x11\xf0\x7e\x56\xec\xe4\xc9"
+ "\x0d\x87\x91\xfb\xb9\xc8\x0d\x34\xab\xb0\xc6\xf2\xa6\x00\x7b\x18"
+ "\x92\xf4\x43\x7f\x01\x85\x2e\xef\x8c\x72\x50\x10\xdb\xf1\x37\x62"
+ "\x16\x85\x71\x01\xa8\x2b\xf0\x13\xd3\x7c\x0b\xaf\xf1\xf3\xd1\xee"
+ "\x90\x41\x5f\x7d\x5b\xa9\x83\x4b\xfa\x80\x59\x50\x73\xe1\xc4\xf9"
+ "\x5e\x4b\xde\xd9\xf5\x22\x68\x5e\x65\xd9\x37\xe4\x1a\x08\x0e\xb1"
+ "\x28\x2f\x40\x9e\x37\xa8\x12\x56\xb7\xb8\x64\x94\x68\x94\xff\x9f",
+ .b_public =
+ "\x26\xa8\x3a\x97\xe0\x52\x76\x07\x26\xa7\xbb\x21\xfd\xe5\x69\xde"
+ "\xe6\xe0\xb5\xa0\xf1\xaa\x51\x2b\x56\x1c\x3c\x6c\xe5\x9f\x8f\x75"
+ "\x71\x04\x86\xf6\x43\x2f\x20\x7f\x45\x4f\x5c\xb9\xf3\x90\xbe\xa9"
+ "\xa0\xd7\xe8\x03\x0e\xfe\x99\x9b\x8a\x1c\xbe\xa7\x63\xe8\x2b\x45"
+ "\xd4\x2c\x65\x25\x4c\x33\xda\xc5\x85\x77\x5d\x62\xea\x93\xe4\x45"
+ "\x59\xff\xa1\xd2\xf1\x73\x11\xed\x02\x64\x8a\x1a\xfb\xe1\x88\xa6"
+ "\x50\x6f\xff\x87\x12\xbb\xfc\x10\xcf\x19\x41\xb0\x35\x44\x7d\x51"
+ "\xe9\xc0\x77\xf2\x73\x21\x2e\x62\xbf\x65\xa5\xd1\x3b\xb1\x3e\x19"
+ "\x75\x4b\xb7\x8e\x03\xc3\xdf\xc8\xb2\xe6\xec\x2d\x7d\xa5\x6a\xba"
+ "\x93\x47\x50\xeb\x6e\xdb\x88\x05\x45\xad\x03\x8c\xf7\x9a\xe1\xc9"
+ "\x1e\x16\x96\x37\xa5\x3e\xe9\xb9\xa8\xdc\xb9\xa9\xf6\xa1\x3d\xed"
+ "\xbe\x12\x29\x8a\x3d\x3d\x90\xfc\x94\xfe\x66\x28\x1c\x1b\xa4\x89"
+ "\x47\x66\x4f\xac\x14\x00\x22\x2d\x5c\x03\xea\x71\x4d\x19\x7d\xd6"
+ "\x58\x39\x4c\x3d\x06\x2b\x30\xa6\xdc\x2c\x8d\xd1\xde\x79\x77\xfa"
+ "\x9c\x6b\x72\x11\x8a\x7f\x7d\x37\x28\x2a\x88\xbf\x0a\xdb\xac\x3b"
+ "\xc5\xa5\xd5\x7e\x25\xec\xa6\x7f\x5b\x53\x75\x83\x49\xd4\x77\xcc"
+ "\x7d\x7e\xd3\x3d\x30\x2c\x98\x3f\x18\x9a\x11\x8a\x37\xda\x99\x0f"
+ "\x3b\x06\xe1\x87\xd5\xe9\x4e\xe0\x9c\x0e\x39\x34\xe2\xdd\xf6\x58"
+ "\x60\x63\xa6\xea\xe8\xc0\xb4\xde\xdf\xa0\xbc\x21\xc3\x2d\xf4\xa4"
+ "\xc8\x6f\x62\x6c\x0f\x71\x88\xf9\xda\x2d\x30\xd5\x95\xe1\xfc\x6d"
+ "\x88\xc5\xc3\x95\x51\x83\xde\x41\x46\x6f\x7e\x1b\x10\x48\xad\x2b"
+ "\x82\x88\xa2\x6f\x57\x4d\x4a\xbd\x90\xc8\x06\x8f\x52\x5d\x6e\xee"
+ "\x09\xe6\xa3\xcb\x30\x9c\x14\xf6\xac\x66\x9b\x81\x0a\x75\x42\x6b"
+ "\xab\x27\xec\x76\xfb\x8d\xc5\xbf\x0e\x93\x81\x7b\x81\xd4\x85\xa6"
+ "\x90\x5a\xa6\xa2\x8b\xa9\xb7\x34\xe6\x15\x36\x93\x8b\xe2\x99\xc7"
+ "\xad\x66\x7e\xd6\x89\xa9\xc8\x15\xcb\xc5\xeb\x06\x85\xd4\x2f\x6e"
+ "\x9b\x95\x7a\x06\x6c\xfa\x31\x1d\xc4\xe5\x7d\xfb\x10\x35\x88\xc2"
+ "\xbe\x1c\x16\x5d\xc2\xf4\x0d\xf3\xc9\x94\xb2\x7e\xa7\xbd\x9c\x03"
+ "\x32\xaf\x8b\x1a\xc8\xcc\x82\xd8\x87\x96\x6e\x3d\xcc\x93\xd2\x43"
+ "\x73\xf9\xde\xec\x49\x49\xf4\x56\x2a\xc8\x6e\x32\x70\x48\xf8\x70"
+ "\xa3\x96\x31\xf4\xf2\x08\xc5\x12\xd2\xeb\xb6\xea\xa3\x07\x05\x61"
+ "\x74\xa3\x04\x2f\x17\x82\x40\x5e\x4c\xd1\x51\xb8\x10\x5b\xc8\x9f"
+ "\x87\x73\x80\x0d\x6f\xc6\xb9\xf6\x7c\x31\x0a\xcc\xd9\x03\x0f\x7a"
+ "\x47\x69\xb1\x55\xab\xe9\xb5\x75\x62\x9e\x95\xbe\x7b\xa9\x53\x6e"
+ "\x28\x73\xdc\xb3\xa4\x8a\x1c\x91\xf5\x8a\xf9\x32\x2b\xbd\xa5\xdc"
+ "\x07\xb5\xaf\x49\xdb\x9c\x35\xc9\x69\xde\xac\xb1\xd0\x86\xcb\x31"
+ "\x0b\xc4\x4f\x63\x4e\x70\xa7\x80\xe3\xbc\x0b\x73\x0e\xf2\x8c\x87"
+ "\x88\x7b\xa9\x6d\xde\x8a\x73\x14\xb9\x80\x55\x03\x2b\x29\x64\x6a"
+ "\xda\x48\x0e\x78\x07\x40\x48\x46\x58\xa9\x4e\x68\x1d\xd1\xc1\xc8"
+ "\x3b\x35\x53\x61\xd5\xe3\x0d\x4c\x42\x74\x10\x67\x85\x9f\x66\x2a"
+ "\xf7\x2b\x7b\x77\x8b\x6e\xda\x2c\xc1\x5a\x20\x34\x3f\xf5\x8b\x6f"
+ "\xe4\x61\xf5\x58\xab\x72\x1a\xf1\x8d\x28\xcc\xa5\x30\x68\xb5\x50"
+ "\x7b\x81\x43\x89\x8e\xa9\xac\x63\x3a\x4a\x78\x7b\xd2\x45\xe6\xe0"
+ "\xdc\x5d\xf2\x1a\x2b\x54\x50\xa5\x9d\xf6\xe7\x9f\x25\xaf\x56\x6a"
+ "\x84\x2a\x75\xa3\x9a\xc7\xfa\x94\xec\x83\xab\xa5\xaa\xe1\xf9\x89"
+ "\x29\xa9\xf6\x53\x24\x24\xae\x4a\xe8\xbc\xe8\x9e\x5c\xd7\x54\x7c"
+ "\x65\x20\x97\x28\x94\x76\xf9\x9e\x81\xcf\x98\x6a\x3a\x7b\xec\xf3"
+ "\x09\x60\x2e\x43\x18\xb5\xf6\x8c\x44\x0f\xf2\x0a\x17\x5b\xac\x98"
+ "\x30\xab\x6e\xd5\xb3\xef\x25\x68\x50\xb6\xe1\xc0\xe4\x5a\x63\x43"
+ "\xea\xca\xda\x23\xc1\xc2\xe9\x30\xec\xb3\x9f\xbf\x1f\x09\x76\xaf"
+ "\x65\xbc\xb5\xab\x30\xac\x0b\x05\xef\x5c\xa3\x65\x77\x33\x1c\xc5"
+ "\xdf\xc9\x39\xab\xca\xf4\x3b\x88\x25\x6d\x50\x87\xb1\x79\xc2\x23"
+ "\x9d\xb5\x21\x01\xaa\xa3\xb7\x61\xa3\x48\x91\x72\x3d\x54\x85\x86"
+ "\x91\x81\x35\x78\xbf\x8f\x27\x57\xcb\x9b\x34\xab\x63\x40\xf1\xbc"
+ "\x23\x5a\x26\x6a\xba\x57\xe2\x8f\x2a\xdc\x82\xe0\x3b\x7f\xec\xd3"
+ "\xd8\x9d\xd3\x13\x54\x70\x64\xc3\xfd\xbf\xa3\x46\xa7\x53\x42\x7f"
+ "\xc1\xbd\x7b\xb3\x13\x47\x2a\x45\x1e\x76\x2c\x0d\x6d\x46\x26\x24"
+ "\xa8\xc7\x00\x2b\x10\x7f\x2a\x6c\xfc\x68\x4e\x6e\x85\x53\x00\xaf"
+ "\xd5\xfb\x59\x64\xc7\x9b\x24\xd1\x05\xdc\x34\x53\x6d\x27\xa9\x79"
+ "\xff\xd7\x5e\x7a\x40\x81\x8e\xc3\xf2\x38\xc9\x8d\x87\xb5\x38\xda"
+ "\x43\x64\x1b\x59\x62\x88\xc1\x6e\x85\x84\x33\xcd\x6d\x7b\x62\x1d"
+ "\x60\xf9\x98\xf7\xd1\xb1\xd4\xbe\x56\x6e\xa8\x6f\xff\xe7\x8b\x60"
+ "\x53\x80\xc7\x7c\xe0\x78\x89\xa9\xab\x42\x8f\x8e\x4d\x92\xac\xa7"
+ "\xfd\x47\x11\xc7\xdb\x7c\x77\xfb\xa4\x1d\x70\xaf\x56\x14\x52\xb0",
+ .expected_a_public =
+ "\xa1\x6c\x9e\xda\x45\x4d\xf6\x59\x04\x00\xc1\xc6\x8b\x12\x3b\xcd"
+ "\x07\xe4\x3e\xec\xac\x9b\xfc\xf7\x6d\x73\x39\x9e\x52\xf8\xbe\x33"
+ "\xe2\xca\xea\x99\x76\xc7\xc9\x94\x5c\xf3\x1b\xea\x6b\x66\x4b\x51"
+ "\x90\xf6\x4f\x75\xd5\x85\xf4\x28\xfd\x74\xa5\x57\xb1\x71\x0c\xb6"
+ "\xb6\x95\x70\x2d\xfa\x4b\x56\xe0\x56\x10\x21\xe5\x60\xa6\x18\xa4"
+ "\x78\x8c\x07\xc0\x2b\x59\x9c\x84\x5b\xe9\xb9\x74\xbf\xbc\x65\x48"
+ "\x27\x82\x40\x53\x46\x32\xa2\x92\x91\x9d\xf6\xd1\x07\x0e\x1d\x07"
+ "\x1b\x41\x04\xb1\xd4\xce\xae\x6e\x46\xf1\x72\x50\x7f\xff\xa8\xa2"
+ "\xbc\x3a\xc1\xbb\x28\xd7\x7d\xcd\x7a\x22\x01\xaf\x57\xb0\xa9\x02"
+ "\xd4\x8a\x92\xd5\xe6\x8e\x6f\x11\x39\xfe\x36\x87\x89\x42\x25\x42"
+ "\xd9\xbe\x67\x15\xe1\x82\x8a\x5e\x98\xc2\xd5\xde\x9e\x13\x1a\xe7"
+ "\xf9\x9f\x8e\x2d\x49\xdc\x4d\x98\x8c\xdd\xfd\x24\x7c\x46\xa9\x69"
+ "\x3b\x31\xb3\x12\xce\x54\xf6\x65\x75\x40\xc2\xf1\x04\x92\xe3\x83"
+ "\xeb\x02\x3d\x79\xc0\xf9\x7c\x28\xb3\x97\x03\xf7\x61\x1c\xce\x95"
+ "\x1a\xa0\xb3\x77\x1b\xc1\x9f\xf8\xf6\x3f\x4d\x0a\xfb\xfa\x64\x1c"
+ "\xcb\x37\x5b\xc3\x28\x60\x9f\xd1\xf2\xc4\xee\x77\xaa\x1f\xe9\xa2"
+ "\x89\x4c\xc6\xb7\xb3\xe4\xa5\xed\xa7\xe8\xac\x90\xdc\xc3\xfb\x56"
+ "\x9c\xda\x2c\x1d\x1a\x9a\x8c\x82\x92\xee\xdc\xa0\xa4\x01\x6e\x7f"
+ "\xc7\x0e\xc2\x73\x7d\xa6\xac\x12\x01\xc0\xc0\xc8\x7c\x84\x86\xc7"
+ "\xa5\x94\xe5\x33\x84\x71\x6e\x36\xe3\x3b\x81\x30\xe0\xc8\x51\x52"
+ "\x2b\x9e\x68\xa2\x6e\x09\x95\x8c\x7f\x78\x82\xbd\x53\x26\xe7\x95"
+ "\xe0\x03\xda\xc0\xc3\x6e\xcf\xdc\xb3\x14\xfc\xe9\x5b\x9b\x70\x6c"
+ "\x93\x04\xab\x13\xf7\x17\x6d\xee\xad\x32\x48\xe9\xa0\x94\x1b\x14"
+ "\x64\x4f\xa1\xb3\x8d\x6a\xca\x28\xfe\x4a\xf4\xf0\xc5\xb7\xf9\x8a"
+ "\x8e\xff\xfe\x57\x6f\x20\xdb\x04\xab\x02\x31\x22\x42\xfd\xbd\x77"
+ "\xea\xce\xe8\xc7\x5d\xe0\x8e\xd6\x66\xd0\xe4\x04\x2f\x5f\x71\xc7"
+ "\x61\x2d\xa5\x3f\x2f\x46\xf2\xd8\x5b\x25\x82\xf0\x52\x88\xc0\x59"
+ "\xd3\xa3\x90\x17\xc2\x04\x13\xc3\x13\x69\x4f\x17\xb1\xb3\x46\x4f"
+ "\xa7\xe6\x8b\x5e\x3e\x95\x0e\xf5\x42\x17\x7f\x4d\x1f\x1b\x7d\x65"
+ "\x86\xc5\xc8\xae\xae\xd8\x4f\xe7\x89\x41\x69\xfd\x06\xce\x5d\xed"
+ "\x44\x55\xad\x51\x98\x15\x78\x8d\x68\xfc\x93\x72\x9d\x22\xe5\x1d"
+ "\x21\xc3\xbe\x3a\x44\x34\xc0\xa3\x1f\xca\xdf\x45\xd0\x5c\xcd\xb7"
+ "\x72\xeb\xae\x7a\xad\x3f\x05\xa0\xe3\x6e\x5a\xd8\x52\xa7\xf1\x1e"
+ "\xb4\xf2\xcf\xe7\xdf\xa7\xf2\x22\x00\xb2\xc4\x17\x3d\x2c\x15\x04"
+ "\x71\x28\x69\x5c\x69\x21\xc8\xf1\x9b\xd8\xc7\xbc\x27\xa3\x85\xe9"
+ "\x53\x77\xd3\x65\xc3\x86\xdd\xb3\x76\x13\xfb\xa1\xd4\xee\x9d\xe4"
+ "\x51\x3f\x83\x59\xe4\x47\xa8\xa6\x0d\x68\xd5\xf6\xf4\xca\x31\xcd"
+ "\x30\x48\x34\x90\x11\x8e\x87\xe9\xea\xc9\xd0\xc3\xba\x28\xf9\xc0"
+ "\xc9\x8e\x23\xe5\xc2\xee\xf2\x47\x9c\x41\x1c\x10\x33\x27\x23\x49"
+ "\xe5\x0d\x18\xbe\x19\xc1\xba\x6c\xdc\xb7\xa1\xe7\xc5\x0d\x6f\xf0"
+ "\x8c\x62\x6e\x0d\x14\xef\xef\xf2\x8e\x01\xd2\x76\xf5\xc1\xe1\x92"
+ "\x3c\xb3\x76\xcd\xd8\xdd\x9b\xe0\x8e\xdc\x24\x34\x13\x65\x0f\x11"
+ "\xaf\x99\x7a\x2f\xe6\x1f\x7d\x17\x3e\x8a\x68\x9a\x37\xc8\x8d\x3e"
+ "\xa3\xfe\xfe\x57\x22\xe6\x0e\x50\xb5\x98\x0b\x71\xd8\x01\xa2\x8d"
+ "\x51\x96\x50\xc2\x41\x31\xd8\x23\x98\xfc\xd1\x9d\x7e\x27\xbb\x69"
+ "\x78\xe0\x87\xf7\xe4\xdd\x58\x13\x9d\xec\x00\xe4\xb9\x70\xa2\x94"
+ "\x5d\x52\x4e\xf2\x5c\xd1\xbc\xfd\xee\x9b\xb9\xe5\xc4\xc0\xa8\x77"
+ "\x67\xa4\xd1\x95\x34\xe4\x6d\x5f\x25\x02\x8d\x65\xdd\x11\x63\x55"
+ "\x04\x01\x21\x60\xc1\x5c\xef\x77\x33\x01\x1c\xa2\x11\x2b\xdd\x2b"
+ "\x74\x99\x23\x38\x05\x1b\x7e\x2e\x01\x52\xfe\x9c\x23\xde\x3e\x1a"
+ "\x72\xf4\xff\x7b\x02\xaa\x08\xcf\xe0\x5b\x83\xbe\x85\x5a\xe8\x9d"
+ "\x11\x3e\xff\x2f\xc6\x97\x67\x36\x6c\x0f\x81\x9c\x26\x29\xb1\x0f"
+ "\xbb\x53\xbd\xf4\xec\x2a\x84\x41\x28\x3b\x86\x40\x95\x69\x55\x5f"
+ "\x30\xee\xda\x1e\x6c\x4b\x25\xd6\x2f\x2c\x0e\x3c\x1a\x26\xa0\x3e"
+ "\xef\x09\xc6\x2b\xe5\xa1\x0c\x03\xa8\xf5\x39\x70\x31\xc4\x32\x79"
+ "\xd1\xd9\xc2\xcc\x32\x4a\xf1\x2f\x57\x5a\xcc\xe5\xc3\xc5\xd5\x4e"
+ "\x86\x56\xca\x64\xdb\xab\x61\x85\x8f\xf9\x20\x02\x40\x66\x76\x9e"
+ "\x5e\xd4\xac\xf0\x47\xa6\x50\x5f\xc2\xaf\x55\x9b\xa3\xc9\x8b\xf8"
+ "\x42\xd5\xcf\x1a\x95\x22\xd9\xd1\x0b\x92\x51\xca\xde\x46\x02\x0d"
+ "\x8b\xee\xd9\xa0\x04\x74\xf5\x0e\xb0\x3a\x62\xec\x3c\x91\x29\x33"
+ "\xa7\x78\x22\x92\xac\x27\xe6\x2d\x6f\x56\x8a\x5d\x72\xc2\xf1\x5c"
+ "\x54\x11\x97\x24\x61\xcb\x0c\x52\xd4\x57\x56\x22\x86\xf0\x19\x27"
+ "\x76\x30\x04\xf4\x39\x7b\x1a\x5a\x04\x0d\xec\x59\x9a\x31\x4c\x40"
+ "\x19\x6d\x3c\x41\x1b\x0c\xca\xeb\x25\x39\x6c\x96\xf8\x55\xd0\xec",
+ .expected_ss =
+ "\xf9\x55\x4f\x48\x38\x74\xb7\x46\xa3\xc4\x2e\x88\xf0\x34\xab\x1d"
+ "\xcd\xa5\x58\xa7\x95\x88\x36\x62\x6f\x8a\xbd\xf2\xfb\x6f\x3e\xb9"
+ "\x91\x65\x58\xef\x70\x2f\xd5\xc2\x97\x70\xcb\xce\x8b\x78\x1c\xe0"
+ "\xb9\xfa\x77\x34\xd2\x4a\x19\x58\x11\xfd\x93\x84\x40\xc0\x8c\x19"
+ "\x8b\x98\x50\x83\xba\xfb\xe2\xad\x8b\x81\x84\x63\x90\x41\x4b\xf8"
+ "\xe8\x78\x86\x04\x09\x8d\x84\xd1\x43\xfd\xa3\x58\x21\x2a\x3b\xb1"
+ "\xa2\x5b\x48\x74\x3c\xa9\x16\x34\x28\xf0\x8e\xde\xe2\xcf\x8e\x68"
+ "\x53\xab\x65\x06\xb7\x86\xb1\x08\x4f\x73\x97\x00\x10\x95\xd1\x84"
+ "\x72\xcf\x14\xdb\xff\xa7\x80\xd8\xe5\xf2\x2c\x89\x37\xb0\x81\x2c"
+ "\xf5\xd6\x7d\x1b\xb0\xe2\x8e\x87\x32\x3d\x37\x6a\x79\xaa\xe7\x08"
+ "\xc9\x67\x55\x5f\x1c\xae\xa6\xf5\xef\x79\x3a\xaf\x3f\x82\x14\xe2"
+ "\xf3\x69\x91\xed\xb7\x9e\xc9\xde\xd0\x29\x70\xd9\xeb\x0f\xf5\xc7"
+ "\xf6\x7c\xa7\x7f\xec\xed\xe1\xbd\x13\xe1\x43\xe4\x42\x30\xe3\x5f"
+ "\xe0\xf3\x15\x55\x2f\x7a\x42\x17\x67\xcb\xc2\x4f\xd0\x85\xfc\x6c"
+ "\xec\xe8\xfc\x25\x78\x4b\xe4\x0f\xd4\x3d\x78\x28\xd3\x53\x79\xcb"
+ "\x2c\x82\x67\x9a\xdc\x32\x55\xd2\xda\xae\xd8\x61\xce\xd6\x59\x0b"
+ "\xc5\x44\xeb\x08\x81\x8c\x65\xb2\xb7\xa6\xff\xf7\xbf\x99\xc6\x8a"
+ "\xbe\xde\xc2\x17\x56\x05\x6e\xd2\xf1\x1e\xa2\x04\xeb\x02\x74\xaa"
+ "\x04\xfc\xf0\x6b\xd4\xfc\xf0\x7a\x5f\xfe\xe2\x74\x7f\xeb\x9b\x6a"
+ "\x8a\x09\x96\x5d\xe1\x91\xb6\x9e\x37\xd7\x63\xd7\xb3\x5c\xb5\xa3"
+ "\x5f\x62\x00\xdf\xc5\xbf\x85\xba\xa7\xa9\xb6\x1f\x76\x78\x65\x01"
+ "\xfe\x1d\x6c\xfe\x15\x9e\xf4\xb1\xbc\x8d\xad\x3c\xec\x69\x27\x57"
+ "\xa4\x89\x77\x46\xe1\x49\xc7\x22\xde\x79\xe0\xf7\x3a\xa1\x59\x8b"
+ "\x59\x71\xcc\xd6\x18\x24\xc1\x8a\x2f\xe3\xdf\xdd\x6c\xf7\x62\xaa"
+ "\x15\xaa\x39\x37\x3b\xaf\x7d\x6e\x88\xeb\x19\xa8\xa0\x26\xd3\xaa"
+ "\x2d\xcc\x5f\x56\x99\x86\xa9\xed\x4d\x02\x31\x40\x97\x70\x83\xa7"
+ "\x08\x98\x7e\x49\x46\xd9\x75\xb5\x7a\x6a\x40\x69\xa0\x6d\xb2\x18"
+ "\xc0\xad\x88\x05\x02\x95\x6f\xf7\x8f\xcb\xa2\xe4\x7b\xab\x4a\x0f"
+ "\x9a\x1b\xef\xcc\xd1\x6a\x5d\x1e\x6a\x2a\x8b\x5b\x80\xbc\x5f\x38"
+ "\xdd\xaf\xad\x44\x15\xb4\xaf\x26\x1c\x1a\x4d\xa7\x4b\xec\x88\x33"
+ "\x24\x42\xb5\x0c\x9c\x56\xd4\xba\xa7\xb9\x65\xd5\x76\xb2\xbc\x16"
+ "\x8e\xfa\x0c\x7a\xc0\xa2\x2c\x5a\x39\x56\x7d\xe6\xf8\xa9\xf4\x49"
+ "\xd0\x50\xf2\x5e\x4b\x0a\x43\xe4\x9a\xbb\xea\x35\x28\x99\x84\x83"
+ "\xec\xc1\xa0\x68\x15\x9a\x2b\x01\x04\x48\x09\x11\x1b\xb6\xa4\xd8"
+ "\x03\xad\xb6\x4c\x9e\x1d\x90\xae\x88\x0f\x75\x95\x25\xa0\x27\x13"
+ "\xb7\x4f\xe2\x3e\xd5\x59\x1a\x7c\xde\x95\x14\x28\xd1\xde\x84\xe4"
+ "\x07\x7c\x5b\x06\xd6\xe6\x9c\x8a\xbe\xd2\xb4\x62\xd1\x67\x8a\x9c"
+ "\xac\x4f\xfa\x70\xd6\xc8\xc0\xeb\x5e\xf6\x3e\xdc\x48\x8e\xce\x3f"
+ "\x92\x3e\x60\x77\x63\x60\x6b\x76\x04\xa5\xba\xc9\xab\x92\x4e\x0d"
+ "\xdc\xca\x82\x44\x5f\x3a\x42\xeb\x01\xe7\xe0\x33\xb3\x32\xaf\x4b"
+ "\x81\x35\x2d\xb6\x57\x15\xfe\x52\xc7\x54\x2e\x41\x3b\x22\x6b\x12"
+ "\x72\xdb\x5c\x66\xd0\xb6\xb4\xfe\x90\xc0\x20\x34\x95\xf9\xe4\xc7"
+ "\x7e\x71\x89\x4f\x6f\xfb\x2a\xf3\xdf\x3f\xe3\xcf\x0e\x1a\xd9\xf2"
+ "\xc1\x02\x67\x5d\xdc\xf1\x7d\xe8\xcf\x64\x77\x4d\x12\x03\x77\x2c"
+ "\xfb\xe1\x59\xf7\x2c\x96\x9c\xaf\x46\x9c\xc7\x67\xcf\xee\x94\x50"
+ "\xc7\xa1\x23\xe6\x9f\x4d\x73\x92\xad\xf9\x4a\xce\xdb\x44\xd5\xe3"
+ "\x17\x05\x37\xdb\x9c\x6c\xc5\x7e\xb7\xd4\x11\x4a\x8c\x51\x03\xaa"
+ "\x73\x4b\x16\xd9\x79\xf5\xf1\x67\x20\x9b\x25\xe5\x41\x52\x59\x06"
+ "\x8b\xf2\x23\x2f\x6e\xea\xf3\x24\x0a\x94\xbb\xb8\x7e\xd9\x23\x4a"
+ "\x9f\x1f\xe1\x13\xb5\xfe\x85\x2f\x4c\xbe\x6a\x66\x02\x1d\x90\xd2"
+ "\x01\x25\x8a\xfd\x78\x3a\x28\xb8\x18\xc1\x38\x16\x21\x6b\xb4\xf9"
+ "\x64\x0f\xf1\x73\xc4\x5c\xd1\x41\xf2\xfe\xe7\x26\xad\x79\x12\x75"
+ "\x49\x48\xdb\x21\x71\x35\xf7\xb7\x46\x5a\xa1\x81\x25\x47\x31\xea"
+ "\x1d\x76\xbb\x32\x5a\x90\xb0\x42\x1a\x47\xe8\x0c\x82\x92\x43\x1c"
+ "\x0b\xdd\xe5\x25\xce\xd3\x06\xcc\x59\x5a\xc9\xa0\x01\xac\x29\x12"
+ "\x31\x2e\x3d\x1a\xed\x3b\xf3\xa7\xef\x52\xc2\x0d\x18\x1f\x03\x28"
+ "\xc9\x2b\x38\x61\xa4\x01\xc9\x3c\x11\x08\x14\xd4\xe5\x31\xe9\x3c"
+ "\x1d\xad\xf8\x76\xc4\x84\x9f\xea\x16\x61\x3d\x6d\xa3\x32\x31\xcd"
+ "\x1c\xca\xb8\x74\xc2\x45\xf3\x01\x9c\x7a\xaf\xfd\xe7\x1e\x5a\x18"
+ "\xb1\x9d\xbb\x7a\x2d\x34\x40\x17\x49\xad\x1f\xeb\x2d\xa2\x26\xb8"
+ "\x16\x28\x4b\x72\xdd\xd0\x8d\x85\x4c\xdd\xf8\x57\x48\xd5\x1d\xfb"
+ "\xbd\xec\x11\x5d\x1e\x9c\x26\x81\xbf\xf1\x16\x12\x32\xc3\xf3\x07"
+ "\x0e\x6e\x7f\x17\xec\xfb\xf4\x5d\xe2\xb1\xca\x97\xca\x46\x20\x2d"
+ "\x09\x85\x19\x25\x89\xa8\x9b\x51\x74\xae\xc9\x1b\x4c\xb6\x80\x62",
+ .secret_size = 1040,
+ .b_public_size = 1024,
+ .expected_a_public_size = 1024,
+ .expected_ss_size = 1024,
+ },
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x00" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x00\x10" /* len */
+ "\x00\x00\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00", /* g_size */
+#endif
+ .b_secret =
+#ifdef __LITTLE_ENDIAN
+ "\x01\x00" /* type */
+ "\x10\x04" /* len */
+ "\x00\x04\x00\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#else
+ "\x00\x01" /* type */
+ "\x04\x10" /* len */
+ "\x00\x00\x04\x00" /* key_size */
+ "\x00\x00\x00\x00" /* p_size */
+ "\x00\x00\x00\x00" /* g_size */
+#endif
+ /* xa */
+ "\x76\x6e\xeb\xf9\xeb\x76\xae\x37\xcb\x19\x49\x8b\xeb\xaf\xb0\x4b"
+ "\x6d\xe9\x15\xad\xda\xf2\xef\x58\xe9\xd6\xdd\x4c\xb3\x56\xd0\x3b"
+ "\x00\xb0\x65\xed\xae\xe0\x2e\xdf\x8f\x45\x3f\x3c\x5d\x2f\xfa\x96"
+ "\x36\x33\xb2\x01\x8b\x0f\xe8\x46\x15\x6d\x60\x5b\xec\x32\xc3\x3b"
+ "\x06\xf3\xb4\x1b\x9a\xef\x3c\x03\x0e\xcc\xce\x1d\x24\xa0\xc9\x08"
+ "\x65\xf9\x45\xe5\xd2\x43\x08\x88\x58\xd6\x46\xe7\xbb\x25\xac\xed"
+ "\x3b\xac\x6f\x5e\xfb\xd6\x19\xa6\x20\x3a\x1d\x0c\xe8\x00\x72\x54"
+ "\xd7\xd9\xc9\x26\x49\x18\xc6\xb8\xbc\xdd\xf3\xce\xf3\x7b\x69\x04"
+ "\x5c\x6f\x11\xdb\x44\x42\x72\xb6\xb7\x84\x17\x86\x47\x3f\xc5\xa1"
+ "\xd8\x86\xef\xe2\x27\x49\x2b\x8f\x3e\x91\x12\xd9\x45\x96\xf7\xe6"
+ "\x77\x76\x36\x58\x71\x9a\xb1\xdb\xcf\x24\x9e\x7e\xad\xce\x45\xba"
+ "\xb5\xec\x8e\xb9\xd6\x7b\x3d\x76\xa4\x85\xad\xd8\x49\x9b\x80\x9d"
+ "\x7f\x9f\x85\x09\x9e\x86\x5b\x6b\xf3\x8d\x39\x5e\x6f\xe4\x30\xc8"
+ "\xa5\xf3\xdf\x68\x73\x6b\x2e\x9a\xcb\xac\x0a\x0d\x44\xc1\xaf\xb2"
+ "\x11\x1b\x7c\x43\x08\x44\x43\xe2\x4e\xfd\x93\x30\x99\x09\x12\xbb"
+ "\xf6\x31\x34\xa5\x3d\x45\x98\xee\xd7\x2a\x1a\x89\xf5\x37\x92\x33"
+ "\xa0\xdd\xf5\xfb\x1f\x90\x42\x55\x5a\x0b\x82\xff\xf0\x96\x92\x15"
+ "\x65\x5a\x55\x96\xca\x1b\xd5\xe5\xb5\x94\xde\x2e\xa6\x03\x57\x9e"
+ "\x15\xe4\x32\x2b\x1f\xb2\x22\x21\xe9\xa0\x05\xd3\x65\x6c\x11\x66"
+ "\x25\x38\xbb\xa3\x6c\xc2\x0b\x2b\xd0\x7a\x20\x26\x29\x37\x5d\x5f"
+ "\xd8\xff\x2a\xcd\x46\x6c\xd6\x6e\xe5\x77\x1a\xe6\x33\xf1\x8e\xc8"
+ "\x10\x30\x11\x00\x27\xf9\x7d\x0e\x28\x43\xa7\x67\x38\x7f\x16\xda"
+ "\xd0\x01\x8e\xa4\xe8\x6f\xcd\x23\xaf\x77\x52\x34\xad\x7e\xc3\xed"
+ "\x2d\x10\x0a\x33\xdc\xcf\x1b\x88\x0f\xcc\x48\x7f\x42\xf0\x9e\x13"
+ "\x1f\xf5\xd1\xe9\x90\x87\xbd\xfa\x5f\x1d\x77\x55\xcb\xc3\x05\xaf"
+ "\x71\xd0\xe0\xab\x46\x31\xd7\xea\x89\x54\x2d\x39\xaf\xf6\x4f\x74"
+ "\xaf\x46\x58\x89\x78\x95\x2e\xe6\x90\xb7\xaa\x00\x73\x9f\xed\xb9"
+ "\x00\xd6\xf6\x6d\x26\x59\xcd\x56\xdb\xf7\x3d\x5f\xeb\x6e\x46\x33"
+ "\xb1\x23\xed\x9f\x8d\x58\xdc\xb4\x28\x3b\x90\x09\xc4\x61\x02\x1f"
+ "\xf8\x62\xf2\x6e\xc1\x94\x71\x66\x93\x11\xdf\xaa\x3e\xd7\xb5\xe5"
+ "\xc1\x78\xe9\x14\xcd\x55\x16\x51\xdf\x8d\xd0\x94\x8c\x43\xe9\xb8"
+ "\x1d\x42\x7f\x76\xbc\x6f\x87\x42\x88\xde\xd7\x52\x78\x00\x4f\x18"
+ "\x02\xe7\x7b\xe2\x8a\xc3\xd1\x43\xa5\xac\xda\xb0\x8d\x19\x96\xd4"
+ "\x81\xe0\x75\xe9\xca\x41\x7e\x1f\x93\x0b\x26\x24\xb3\xaa\xdd\x10"
+ "\x20\xd3\xf2\x9f\x3f\xdf\x65\xde\x67\x79\xdc\x76\x9f\x3c\x72\x75"
+ "\x65\x8a\x30\xcc\xd2\xcc\x06\xb1\xab\x62\x86\x78\x5d\xb8\xce\x72"
+ "\xb3\x12\xc7\x9f\x07\xd0\x6b\x98\x82\x9b\x6c\xbb\x15\xe5\xcc\xf4"
+ "\xc8\xf4\x60\x81\xdc\xd3\x09\x1b\x5e\xd4\xf3\x55\xcf\x1c\x16\x83"
+ "\x61\xb4\x2e\xcc\x08\x67\x58\xfd\x46\x64\xbc\x29\x4b\xdd\xda\xec"
+ "\xdc\xc6\xa9\xa5\x73\xfb\xf8\xf3\xaf\x89\xa8\x9e\x25\x14\xfa\xac"
+ "\xeb\x1c\x7c\x80\x96\x66\x4d\x41\x67\x9b\x07\x4f\x0a\x97\x17\x1c"
+ "\x4d\x61\xc7\x2e\x6f\x36\x98\x29\x50\x39\x6d\xe7\x70\xda\xf0\xc8"
+ "\x05\x80\x7b\x32\xff\xfd\x12\xde\x61\x0d\xf9\x4c\x21\xf1\x56\x72"
+ "\x3d\x61\x46\xc0\x2d\x07\xd1\x6c\xd3\xbe\x9a\x21\x83\x85\xf7\xed"
+ "\x53\x95\x44\x40\x8f\x75\x12\x18\xc2\x9a\xfd\x5e\xce\x66\xa6\x7f"
+ "\x57\xc0\xd7\x73\x76\xb3\x13\xda\x2e\x58\xc6\x27\x40\xb2\x2d\xef"
+ "\x7d\x72\xb4\xa8\x75\x6f\xcc\x5f\x42\x3e\x2c\x90\x36\x59\xa0\x34"
+ "\xaa\xce\xbc\x04\x4c\xe6\x56\xc2\xcd\xa6\x1c\x59\x04\x56\x53\xcf"
+ "\x6d\xd7\xf0\xb1\x4f\x91\xfa\x84\xcf\x4b\x8d\x50\x4c\xf8\x2a\x31"
+ "\x5f\xe3\xba\x79\xb4\xcc\x59\x64\xe3\x7a\xfa\xf6\x06\x9d\x04\xbb"
+ "\xce\x61\xbf\x9e\x59\x0a\x09\x51\x6a\xbb\x0b\x80\xe0\x91\xc1\x51"
+ "\x04\x58\x67\x67\x4b\x42\x4f\x95\x68\x75\xe2\x1f\x9c\x14\x70\xfd"
+ "\x3a\x8a\xce\x8b\x04\xa1\x89\xe7\xb4\xbf\x70\xfe\xf3\x0c\x48\x04"
+ "\x3a\xd2\x85\x68\x03\xe7\xfa\xec\x5b\x55\xb7\x95\xfd\x5b\x19\x35"
+ "\xad\xcb\x4a\x63\x03\x44\x64\x2a\x48\x59\x9a\x26\x43\x96\x8c\xe6"
+ "\xbd\xb7\x90\xd4\x5f\x8d\x08\x28\xa8\xc5\x89\x70\xb9\x6e\xd3\x3b"
+ "\x76\x0e\x37\x98\x15\x27\xca\xc9\xb0\xe0\xfd\xf3\xc6\xdf\x69\xce"
+ "\xe1\x5f\x6a\x3e\x5c\x86\xe2\x58\x41\x11\xf0\x7e\x56\xec\xe4\xc9"
+ "\x0d\x87\x91\xfb\xb9\xc8\x0d\x34\xab\xb0\xc6\xf2\xa6\x00\x7b\x18"
+ "\x92\xf4\x43\x7f\x01\x85\x2e\xef\x8c\x72\x50\x10\xdb\xf1\x37\x62"
+ "\x16\x85\x71\x01\xa8\x2b\xf0\x13\xd3\x7c\x0b\xaf\xf1\xf3\xd1\xee"
+ "\x90\x41\x5f\x7d\x5b\xa9\x83\x4b\xfa\x80\x59\x50\x73\xe1\xc4\xf9"
+ "\x5e\x4b\xde\xd9\xf5\x22\x68\x5e\x65\xd9\x37\xe4\x1a\x08\x0e\xb1"
+ "\x28\x2f\x40\x9e\x37\xa8\x12\x56\xb7\xb8\x64\x94\x68\x94\xff\x9f",
+ .b_public =
+ "\xa1\x6c\x9e\xda\x45\x4d\xf6\x59\x04\x00\xc1\xc6\x8b\x12\x3b\xcd"
+ "\x07\xe4\x3e\xec\xac\x9b\xfc\xf7\x6d\x73\x39\x9e\x52\xf8\xbe\x33"
+ "\xe2\xca\xea\x99\x76\xc7\xc9\x94\x5c\xf3\x1b\xea\x6b\x66\x4b\x51"
+ "\x90\xf6\x4f\x75\xd5\x85\xf4\x28\xfd\x74\xa5\x57\xb1\x71\x0c\xb6"
+ "\xb6\x95\x70\x2d\xfa\x4b\x56\xe0\x56\x10\x21\xe5\x60\xa6\x18\xa4"
+ "\x78\x8c\x07\xc0\x2b\x59\x9c\x84\x5b\xe9\xb9\x74\xbf\xbc\x65\x48"
+ "\x27\x82\x40\x53\x46\x32\xa2\x92\x91\x9d\xf6\xd1\x07\x0e\x1d\x07"
+ "\x1b\x41\x04\xb1\xd4\xce\xae\x6e\x46\xf1\x72\x50\x7f\xff\xa8\xa2"
+ "\xbc\x3a\xc1\xbb\x28\xd7\x7d\xcd\x7a\x22\x01\xaf\x57\xb0\xa9\x02"
+ "\xd4\x8a\x92\xd5\xe6\x8e\x6f\x11\x39\xfe\x36\x87\x89\x42\x25\x42"
+ "\xd9\xbe\x67\x15\xe1\x82\x8a\x5e\x98\xc2\xd5\xde\x9e\x13\x1a\xe7"
+ "\xf9\x9f\x8e\x2d\x49\xdc\x4d\x98\x8c\xdd\xfd\x24\x7c\x46\xa9\x69"
+ "\x3b\x31\xb3\x12\xce\x54\xf6\x65\x75\x40\xc2\xf1\x04\x92\xe3\x83"
+ "\xeb\x02\x3d\x79\xc0\xf9\x7c\x28\xb3\x97\x03\xf7\x61\x1c\xce\x95"
+ "\x1a\xa0\xb3\x77\x1b\xc1\x9f\xf8\xf6\x3f\x4d\x0a\xfb\xfa\x64\x1c"
+ "\xcb\x37\x5b\xc3\x28\x60\x9f\xd1\xf2\xc4\xee\x77\xaa\x1f\xe9\xa2"
+ "\x89\x4c\xc6\xb7\xb3\xe4\xa5\xed\xa7\xe8\xac\x90\xdc\xc3\xfb\x56"
+ "\x9c\xda\x2c\x1d\x1a\x9a\x8c\x82\x92\xee\xdc\xa0\xa4\x01\x6e\x7f"
+ "\xc7\x0e\xc2\x73\x7d\xa6\xac\x12\x01\xc0\xc0\xc8\x7c\x84\x86\xc7"
+ "\xa5\x94\xe5\x33\x84\x71\x6e\x36\xe3\x3b\x81\x30\xe0\xc8\x51\x52"
+ "\x2b\x9e\x68\xa2\x6e\x09\x95\x8c\x7f\x78\x82\xbd\x53\x26\xe7\x95"
+ "\xe0\x03\xda\xc0\xc3\x6e\xcf\xdc\xb3\x14\xfc\xe9\x5b\x9b\x70\x6c"
+ "\x93\x04\xab\x13\xf7\x17\x6d\xee\xad\x32\x48\xe9\xa0\x94\x1b\x14"
+ "\x64\x4f\xa1\xb3\x8d\x6a\xca\x28\xfe\x4a\xf4\xf0\xc5\xb7\xf9\x8a"
+ "\x8e\xff\xfe\x57\x6f\x20\xdb\x04\xab\x02\x31\x22\x42\xfd\xbd\x77"
+ "\xea\xce\xe8\xc7\x5d\xe0\x8e\xd6\x66\xd0\xe4\x04\x2f\x5f\x71\xc7"
+ "\x61\x2d\xa5\x3f\x2f\x46\xf2\xd8\x5b\x25\x82\xf0\x52\x88\xc0\x59"
+ "\xd3\xa3\x90\x17\xc2\x04\x13\xc3\x13\x69\x4f\x17\xb1\xb3\x46\x4f"
+ "\xa7\xe6\x8b\x5e\x3e\x95\x0e\xf5\x42\x17\x7f\x4d\x1f\x1b\x7d\x65"
+ "\x86\xc5\xc8\xae\xae\xd8\x4f\xe7\x89\x41\x69\xfd\x06\xce\x5d\xed"
+ "\x44\x55\xad\x51\x98\x15\x78\x8d\x68\xfc\x93\x72\x9d\x22\xe5\x1d"
+ "\x21\xc3\xbe\x3a\x44\x34\xc0\xa3\x1f\xca\xdf\x45\xd0\x5c\xcd\xb7"
+ "\x72\xeb\xae\x7a\xad\x3f\x05\xa0\xe3\x6e\x5a\xd8\x52\xa7\xf1\x1e"
+ "\xb4\xf2\xcf\xe7\xdf\xa7\xf2\x22\x00\xb2\xc4\x17\x3d\x2c\x15\x04"
+ "\x71\x28\x69\x5c\x69\x21\xc8\xf1\x9b\xd8\xc7\xbc\x27\xa3\x85\xe9"
+ "\x53\x77\xd3\x65\xc3\x86\xdd\xb3\x76\x13\xfb\xa1\xd4\xee\x9d\xe4"
+ "\x51\x3f\x83\x59\xe4\x47\xa8\xa6\x0d\x68\xd5\xf6\xf4\xca\x31\xcd"
+ "\x30\x48\x34\x90\x11\x8e\x87\xe9\xea\xc9\xd0\xc3\xba\x28\xf9\xc0"
+ "\xc9\x8e\x23\xe5\xc2\xee\xf2\x47\x9c\x41\x1c\x10\x33\x27\x23\x49"
+ "\xe5\x0d\x18\xbe\x19\xc1\xba\x6c\xdc\xb7\xa1\xe7\xc5\x0d\x6f\xf0"
+ "\x8c\x62\x6e\x0d\x14\xef\xef\xf2\x8e\x01\xd2\x76\xf5\xc1\xe1\x92"
+ "\x3c\xb3\x76\xcd\xd8\xdd\x9b\xe0\x8e\xdc\x24\x34\x13\x65\x0f\x11"
+ "\xaf\x99\x7a\x2f\xe6\x1f\x7d\x17\x3e\x8a\x68\x9a\x37\xc8\x8d\x3e"
+ "\xa3\xfe\xfe\x57\x22\xe6\x0e\x50\xb5\x98\x0b\x71\xd8\x01\xa2\x8d"
+ "\x51\x96\x50\xc2\x41\x31\xd8\x23\x98\xfc\xd1\x9d\x7e\x27\xbb\x69"
+ "\x78\xe0\x87\xf7\xe4\xdd\x58\x13\x9d\xec\x00\xe4\xb9\x70\xa2\x94"
+ "\x5d\x52\x4e\xf2\x5c\xd1\xbc\xfd\xee\x9b\xb9\xe5\xc4\xc0\xa8\x77"
+ "\x67\xa4\xd1\x95\x34\xe4\x6d\x5f\x25\x02\x8d\x65\xdd\x11\x63\x55"
+ "\x04\x01\x21\x60\xc1\x5c\xef\x77\x33\x01\x1c\xa2\x11\x2b\xdd\x2b"
+ "\x74\x99\x23\x38\x05\x1b\x7e\x2e\x01\x52\xfe\x9c\x23\xde\x3e\x1a"
+ "\x72\xf4\xff\x7b\x02\xaa\x08\xcf\xe0\x5b\x83\xbe\x85\x5a\xe8\x9d"
+ "\x11\x3e\xff\x2f\xc6\x97\x67\x36\x6c\x0f\x81\x9c\x26\x29\xb1\x0f"
+ "\xbb\x53\xbd\xf4\xec\x2a\x84\x41\x28\x3b\x86\x40\x95\x69\x55\x5f"
+ "\x30\xee\xda\x1e\x6c\x4b\x25\xd6\x2f\x2c\x0e\x3c\x1a\x26\xa0\x3e"
+ "\xef\x09\xc6\x2b\xe5\xa1\x0c\x03\xa8\xf5\x39\x70\x31\xc4\x32\x79"
+ "\xd1\xd9\xc2\xcc\x32\x4a\xf1\x2f\x57\x5a\xcc\xe5\xc3\xc5\xd5\x4e"
+ "\x86\x56\xca\x64\xdb\xab\x61\x85\x8f\xf9\x20\x02\x40\x66\x76\x9e"
+ "\x5e\xd4\xac\xf0\x47\xa6\x50\x5f\xc2\xaf\x55\x9b\xa3\xc9\x8b\xf8"
+ "\x42\xd5\xcf\x1a\x95\x22\xd9\xd1\x0b\x92\x51\xca\xde\x46\x02\x0d"
+ "\x8b\xee\xd9\xa0\x04\x74\xf5\x0e\xb0\x3a\x62\xec\x3c\x91\x29\x33"
+ "\xa7\x78\x22\x92\xac\x27\xe6\x2d\x6f\x56\x8a\x5d\x72\xc2\xf1\x5c"
+ "\x54\x11\x97\x24\x61\xcb\x0c\x52\xd4\x57\x56\x22\x86\xf0\x19\x27"
+ "\x76\x30\x04\xf4\x39\x7b\x1a\x5a\x04\x0d\xec\x59\x9a\x31\x4c\x40"
+ "\x19\x6d\x3c\x41\x1b\x0c\xca\xeb\x25\x39\x6c\x96\xf8\x55\xd0\xec",
+ .secret_size = 16,
+ .b_secret_size = 1040,
+ .b_public_size = 1024,
+ .expected_a_public_size = 1024,
+ .expected_ss_size = 1024,
+ .genkey = true,
+ },
+};
+
static const struct kpp_testvec curve25519_tv_template[] = {
{
.secret = (u8[32]){ 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d,
@@ -2261,19 +4215,16 @@ static const struct kpp_testvec curve25519_tv_template[] = {
}
};
-static const struct kpp_testvec ecdh_tv_template[] = {
+static const struct kpp_testvec ecdh_p192_tv_template[] = {
{
-#ifndef CONFIG_CRYPTO_FIPS
.secret =
#ifdef __LITTLE_ENDIAN
"\x02\x00" /* type */
- "\x20\x00" /* len */
- "\x01\x00" /* curve_id */
+ "\x1e\x00" /* len */
"\x18\x00" /* key_size */
#else
"\x00\x02" /* type */
- "\x00\x20" /* len */
- "\x00\x01" /* curve_id */
+ "\x00\x1e" /* len */
"\x00\x18" /* key_size */
#endif
"\xb5\x05\xb1\x71\x1e\xbf\x8c\xda"
@@ -2297,22 +4248,23 @@ static const struct kpp_testvec ecdh_tv_template[] = {
"\xf4\x57\xcc\x4f\x1f\x4e\x31\xcc"
"\xe3\x40\x60\xc8\x06\x93\xc6\x2e"
"\x99\x80\x81\x28\xaf\xc5\x51\x74",
- .secret_size = 32,
+ .secret_size = 30,
.b_public_size = 48,
.expected_a_public_size = 48,
.expected_ss_size = 24
- }, {
-#endif
+ }
+};
+
+static const struct kpp_testvec ecdh_p256_tv_template[] = {
+ {
.secret =
#ifdef __LITTLE_ENDIAN
"\x02\x00" /* type */
- "\x28\x00" /* len */
- "\x02\x00" /* curve_id */
+ "\x26\x00" /* len */
"\x20\x00" /* key_size */
#else
"\x00\x02" /* type */
- "\x00\x28" /* len */
- "\x00\x02" /* curve_id */
+ "\x00\x26" /* len */
"\x00\x20" /* key_size */
#endif
"\x24\xd1\x21\xeb\xe5\xcf\x2d\x83"
@@ -2342,7 +4294,7 @@ static const struct kpp_testvec ecdh_tv_template[] = {
"\x9f\x4a\x38\xcc\xc0\x2c\x49\x2f"
"\xb1\x32\xbb\xaf\x22\x61\xda\xcb"
"\x6f\xdb\xa9\xaa\xfc\x77\x81\xf3",
- .secret_size = 40,
+ .secret_size = 38,
.b_public_size = 64,
.expected_a_public_size = 64,
.expected_ss_size = 32
@@ -2350,25 +4302,21 @@ static const struct kpp_testvec ecdh_tv_template[] = {
.secret =
#ifdef __LITTLE_ENDIAN
"\x02\x00" /* type */
- "\x08\x00" /* len */
- "\x02\x00" /* curve_id */
+ "\x06\x00" /* len */
"\x00\x00", /* key_size */
#else
"\x00\x02" /* type */
- "\x00\x08" /* len */
- "\x00\x02" /* curve_id */
+ "\x00\x06" /* len */
"\x00\x00", /* key_size */
#endif
.b_secret =
#ifdef __LITTLE_ENDIAN
"\x02\x00" /* type */
- "\x28\x00" /* len */
- "\x02\x00" /* curve_id */
+ "\x26\x00" /* len */
"\x20\x00" /* key_size */
#else
"\x00\x02" /* type */
- "\x00\x28" /* len */
- "\x00\x02" /* curve_id */
+ "\x00\x26" /* len */
"\x00\x20" /* key_size */
#endif
"\x24\xd1\x21\xeb\xe5\xcf\x2d\x83"
@@ -2384,8 +4332,8 @@ static const struct kpp_testvec ecdh_tv_template[] = {
"\x37\x08\xcc\x40\x5e\x7a\xfd\x6a"
"\x6a\x02\x6e\x41\x87\x68\x38\x77"
"\xfa\xa9\x44\x43\x2d\xef\x09\xdf",
- .secret_size = 8,
- .b_secret_size = 40,
+ .secret_size = 6,
+ .b_secret_size = 38,
.b_public_size = 64,
.expected_a_public_size = 64,
.expected_ss_size = 32,
@@ -2394,6 +4342,67 @@ static const struct kpp_testvec ecdh_tv_template[] = {
};
/*
+ * NIST P384 test vectors from RFC5903
+ */
+static const struct kpp_testvec ecdh_p384_tv_template[] = {
+ {
+ .secret =
+#ifdef __LITTLE_ENDIAN
+ "\x02\x00" /* type */
+ "\x36\x00" /* len */
+ "\x30\x00" /* key_size */
+#else
+ "\x00\x02" /* type */
+ "\x00\x36" /* len */
+ "\x00\x30" /* key_size */
+#endif
+ "\x09\x9F\x3C\x70\x34\xD4\xA2\xC6"
+ "\x99\x88\x4D\x73\xA3\x75\xA6\x7F"
+ "\x76\x24\xEF\x7C\x6B\x3C\x0F\x16"
+ "\x06\x47\xB6\x74\x14\xDC\xE6\x55"
+ "\xE3\x5B\x53\x80\x41\xE6\x49\xEE"
+ "\x3F\xAE\xF8\x96\x78\x3A\xB1\x94",
+ .b_public =
+ "\xE5\x58\xDB\xEF\x53\xEE\xCD\xE3"
+ "\xD3\xFC\xCF\xC1\xAE\xA0\x8A\x89"
+ "\xA9\x87\x47\x5D\x12\xFD\x95\x0D"
+ "\x83\xCF\xA4\x17\x32\xBC\x50\x9D"
+ "\x0D\x1A\xC4\x3A\x03\x36\xDE\xF9"
+ "\x6F\xDA\x41\xD0\x77\x4A\x35\x71"
+ "\xDC\xFB\xEC\x7A\xAC\xF3\x19\x64"
+ "\x72\x16\x9E\x83\x84\x30\x36\x7F"
+ "\x66\xEE\xBE\x3C\x6E\x70\xC4\x16"
+ "\xDD\x5F\x0C\x68\x75\x9D\xD1\xFF"
+ "\xF8\x3F\xA4\x01\x42\x20\x9D\xFF"
+ "\x5E\xAA\xD9\x6D\xB9\xE6\x38\x6C",
+ .expected_a_public =
+ "\x66\x78\x42\xD7\xD1\x80\xAC\x2C"
+ "\xDE\x6F\x74\xF3\x75\x51\xF5\x57"
+ "\x55\xC7\x64\x5C\x20\xEF\x73\xE3"
+ "\x16\x34\xFE\x72\xB4\xC5\x5E\xE6"
+ "\xDE\x3A\xC8\x08\xAC\xB4\xBD\xB4"
+ "\xC8\x87\x32\xAE\xE9\x5F\x41\xAA"
+ "\x94\x82\xED\x1F\xC0\xEE\xB9\xCA"
+ "\xFC\x49\x84\x62\x5C\xCF\xC2\x3F"
+ "\x65\x03\x21\x49\xE0\xE1\x44\xAD"
+ "\xA0\x24\x18\x15\x35\xA0\xF3\x8E"
+ "\xEB\x9F\xCF\xF3\xC2\xC9\x47\xDA"
+ "\xE6\x9B\x4C\x63\x45\x73\xA8\x1C",
+ .expected_ss =
+ "\x11\x18\x73\x31\xC2\x79\x96\x2D"
+ "\x93\xD6\x04\x24\x3F\xD5\x92\xCB"
+ "\x9D\x0A\x92\x6F\x42\x2E\x47\x18"
+ "\x75\x21\x28\x7E\x71\x56\xC5\xC4"
+ "\xD6\x03\x13\x55\x69\xB9\xE9\xD0"
+ "\x9C\xF5\xD4\xA2\x70\xF5\x97\x46",
+ .secret_size = 54,
+ .b_public_size = 96,
+ .expected_a_public_size = 96,
+ .expected_ss_size = 48
+ }
+};
+
+/*
* MD4 test vectors from RFC1320
*/
static const struct hash_testvec md4_tv_template[] = {
@@ -3141,66 +5150,6 @@ static const struct hash_testvec md5_tv_template[] = {
};
/*
- * RIPEMD-128 test vectors from ISO/IEC 10118-3:2004(E)
- */
-static const struct hash_testvec rmd128_tv_template[] = {
- {
- .digest = "\xcd\xf2\x62\x13\xa1\x50\xdc\x3e"
- "\xcb\x61\x0f\x18\xf6\xb3\x8b\x46",
- }, {
- .plaintext = "a",
- .psize = 1,
- .digest = "\x86\xbe\x7a\xfa\x33\x9d\x0f\xc7"
- "\xcf\xc7\x85\xe7\x2f\x57\x8d\x33",
- }, {
- .plaintext = "abc",
- .psize = 3,
- .digest = "\xc1\x4a\x12\x19\x9c\x66\xe4\xba"
- "\x84\x63\x6b\x0f\x69\x14\x4c\x77",
- }, {
- .plaintext = "message digest",
- .psize = 14,
- .digest = "\x9e\x32\x7b\x3d\x6e\x52\x30\x62"
- "\xaf\xc1\x13\x2d\x7d\xf9\xd1\xb8",
- }, {
- .plaintext = "abcdefghijklmnopqrstuvwxyz",
- .psize = 26,
- .digest = "\xfd\x2a\xa6\x07\xf7\x1d\xc8\xf5"
- "\x10\x71\x49\x22\xb3\x71\x83\x4e",
- }, {
- .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
- "fghijklmnopqrstuvwxyz0123456789",
- .psize = 62,
- .digest = "\xd1\xe9\x59\xeb\x17\x9c\x91\x1f"
- "\xae\xa4\x62\x4c\x60\xc5\xc7\x02",
- }, {
- .plaintext = "1234567890123456789012345678901234567890"
- "1234567890123456789012345678901234567890",
- .psize = 80,
- .digest = "\x3f\x45\xef\x19\x47\x32\xc2\xdb"
- "\xb2\xc4\xa2\xc7\x69\x79\x5f\xa3",
- }, {
- .plaintext = "abcdbcdecdefdefgefghfghighij"
- "hijkijkljklmklmnlmnomnopnopq",
- .psize = 56,
- .digest = "\xa1\xaa\x06\x89\xd0\xfa\xfa\x2d"
- "\xdc\x22\xe8\x8b\x49\x13\x3a\x06",
- }, {
- .plaintext = "abcdefghbcdefghicdefghijdefghijkefghijklfghi"
- "jklmghijklmnhijklmnoijklmnopjklmnopqklmnopqr"
- "lmnopqrsmnopqrstnopqrstu",
- .psize = 112,
- .digest = "\xd4\xec\xc9\x13\xe1\xdf\x77\x6b"
- "\xf4\x8d\xe9\xd5\x5b\x1f\x25\x46",
- }, {
- .plaintext = "abcdbcdecdefdefgefghfghighijhijk",
- .psize = 32,
- .digest = "\x13\xfc\x13\xe8\xef\xff\x34\x7d"
- "\xe1\x93\xff\x46\xdb\xac\xcf\xd4",
- }
-};
-
-/*
* RIPEMD-160 test vectors from ISO/IEC 10118-3:2004(E)
*/
static const struct hash_testvec rmd160_tv_template[] = {
@@ -3260,131 +5209,18 @@ static const struct hash_testvec rmd160_tv_template[] = {
}
};
-/*
- * RIPEMD-256 test vectors
- */
-static const struct hash_testvec rmd256_tv_template[] = {
- {
- .digest = "\x02\xba\x4c\x4e\x5f\x8e\xcd\x18"
- "\x77\xfc\x52\xd6\x4d\x30\xe3\x7a"
- "\x2d\x97\x74\xfb\x1e\x5d\x02\x63"
- "\x80\xae\x01\x68\xe3\xc5\x52\x2d",
- }, {
- .plaintext = "a",
- .psize = 1,
- .digest = "\xf9\x33\x3e\x45\xd8\x57\xf5\xd9"
- "\x0a\x91\xba\xb7\x0a\x1e\xba\x0c"
- "\xfb\x1b\xe4\xb0\x78\x3c\x9a\xcf"
- "\xcd\x88\x3a\x91\x34\x69\x29\x25",
- }, {
- .plaintext = "abc",
- .psize = 3,
- .digest = "\xaf\xbd\x6e\x22\x8b\x9d\x8c\xbb"
- "\xce\xf5\xca\x2d\x03\xe6\xdb\xa1"
- "\x0a\xc0\xbc\x7d\xcb\xe4\x68\x0e"
- "\x1e\x42\xd2\xe9\x75\x45\x9b\x65",
- }, {
- .plaintext = "message digest",
- .psize = 14,
- .digest = "\x87\xe9\x71\x75\x9a\x1c\xe4\x7a"
- "\x51\x4d\x5c\x91\x4c\x39\x2c\x90"
- "\x18\xc7\xc4\x6b\xc1\x44\x65\x55"
- "\x4a\xfc\xdf\x54\xa5\x07\x0c\x0e",
- }, {
- .plaintext = "abcdefghijklmnopqrstuvwxyz",
- .psize = 26,
- .digest = "\x64\x9d\x30\x34\x75\x1e\xa2\x16"
- "\x77\x6b\xf9\xa1\x8a\xcc\x81\xbc"
- "\x78\x96\x11\x8a\x51\x97\x96\x87"
- "\x82\xdd\x1f\xd9\x7d\x8d\x51\x33",
- }, {
- .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
- "fghijklmnopqrstuvwxyz0123456789",
- .psize = 62,
- .digest = "\x57\x40\xa4\x08\xac\x16\xb7\x20"
- "\xb8\x44\x24\xae\x93\x1c\xbb\x1f"
- "\xe3\x63\xd1\xd0\xbf\x40\x17\xf1"
- "\xa8\x9f\x7e\xa6\xde\x77\xa0\xb8",
- }, {
- .plaintext = "1234567890123456789012345678901234567890"
- "1234567890123456789012345678901234567890",
- .psize = 80,
- .digest = "\x06\xfd\xcc\x7a\x40\x95\x48\xaa"
- "\xf9\x13\x68\xc0\x6a\x62\x75\xb5"
- "\x53\xe3\xf0\x99\xbf\x0e\xa4\xed"
- "\xfd\x67\x78\xdf\x89\xa8\x90\xdd",
- }, {
- .plaintext = "abcdbcdecdefdefgefghfghighij"
- "hijkijkljklmklmnlmnomnopnopq",
- .psize = 56,
- .digest = "\x38\x43\x04\x55\x83\xaa\xc6\xc8"
- "\xc8\xd9\x12\x85\x73\xe7\xa9\x80"
- "\x9a\xfb\x2a\x0f\x34\xcc\xc3\x6e"
- "\xa9\xe7\x2f\x16\xf6\x36\x8e\x3f",
- }
-};
+static const u8 zeroes[4096] = { [0 ... 4095] = 0 };
+static const u8 ones[4096] = { [0 ... 4095] = 0xff };
-/*
- * RIPEMD-320 test vectors
- */
-static const struct hash_testvec rmd320_tv_template[] = {
+static const struct hash_testvec crc64_rocksoft_tv_template[] = {
{
- .digest = "\x22\xd6\x5d\x56\x61\x53\x6c\xdc\x75\xc1"
- "\xfd\xf5\xc6\xde\x7b\x41\xb9\xf2\x73\x25"
- "\xeb\xc6\x1e\x85\x57\x17\x7d\x70\x5a\x0e"
- "\xc8\x80\x15\x1c\x3a\x32\xa0\x08\x99\xb8",
- }, {
- .plaintext = "a",
- .psize = 1,
- .digest = "\xce\x78\x85\x06\x38\xf9\x26\x58\xa5\xa5"
- "\x85\x09\x75\x79\x92\x6d\xda\x66\x7a\x57"
- "\x16\x56\x2c\xfc\xf6\xfb\xe7\x7f\x63\x54"
- "\x2f\x99\xb0\x47\x05\xd6\x97\x0d\xff\x5d",
- }, {
- .plaintext = "abc",
- .psize = 3,
- .digest = "\xde\x4c\x01\xb3\x05\x4f\x89\x30\xa7\x9d"
- "\x09\xae\x73\x8e\x92\x30\x1e\x5a\x17\x08"
- "\x5b\xef\xfd\xc1\xb8\xd1\x16\x71\x3e\x74"
- "\xf8\x2f\xa9\x42\xd6\x4c\xdb\xc4\x68\x2d",
- }, {
- .plaintext = "message digest",
- .psize = 14,
- .digest = "\x3a\x8e\x28\x50\x2e\xd4\x5d\x42\x2f\x68"
- "\x84\x4f\x9d\xd3\x16\xe7\xb9\x85\x33\xfa"
- "\x3f\x2a\x91\xd2\x9f\x84\xd4\x25\xc8\x8d"
- "\x6b\x4e\xff\x72\x7d\xf6\x6a\x7c\x01\x97",
- }, {
- .plaintext = "abcdefghijklmnopqrstuvwxyz",
- .psize = 26,
- .digest = "\xca\xbd\xb1\x81\x0b\x92\x47\x0a\x20\x93"
- "\xaa\x6b\xce\x05\x95\x2c\x28\x34\x8c\xf4"
- "\x3f\xf6\x08\x41\x97\x51\x66\xbb\x40\xed"
- "\x23\x40\x04\xb8\x82\x44\x63\xe6\xb0\x09",
- }, {
- .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
- "fghijklmnopqrstuvwxyz0123456789",
- .psize = 62,
- .digest = "\xed\x54\x49\x40\xc8\x6d\x67\xf2\x50\xd2"
- "\x32\xc3\x0b\x7b\x3e\x57\x70\xe0\xc6\x0c"
- "\x8c\xb9\xa4\xca\xfe\x3b\x11\x38\x8a\xf9"
- "\x92\x0e\x1b\x99\x23\x0b\x84\x3c\x86\xa4",
- }, {
- .plaintext = "1234567890123456789012345678901234567890"
- "1234567890123456789012345678901234567890",
- .psize = 80,
- .digest = "\x55\x78\x88\xaf\x5f\x6d\x8e\xd6\x2a\xb6"
- "\x69\x45\xc6\xd2\xa0\xa4\x7e\xcd\x53\x41"
- "\xe9\x15\xeb\x8f\xea\x1d\x05\x24\x95\x5f"
- "\x82\x5d\xc7\x17\xe4\xa0\x08\xab\x2d\x42",
+ .plaintext = zeroes,
+ .psize = 4096,
+ .digest = "\x4e\xb6\x22\xeb\x67\xd3\x82\x64",
}, {
- .plaintext = "abcdbcdecdefdefgefghfghighij"
- "hijkijkljklmklmnlmnomnopnopq",
- .psize = 56,
- .digest = "\xd0\x34\xa7\x95\x0c\xf7\x22\x02\x1b\xa4"
- "\xb8\x4d\xf7\x69\xa5\xde\x20\x60\xe2\x59"
- "\xdf\x4c\x9b\xb4\xa4\x26\x8c\x0e\x93\x5b"
- "\xbc\x74\x70\xa9\x69\xc9\xd0\x72\xa1\xac",
+ .plaintext = ones,
+ .psize = 4096,
+ .digest = "\xac\xa3\xec\x02\x73\xba\xdd\xc0",
}
};
@@ -3792,6 +5628,65 @@ static const struct hash_testvec hmac_streebog512_tv_template[] = {
},
};
+/*
+ * SM2 test vectors.
+ */
+static const struct akcipher_testvec sm2_tv_template[] = {
+ { /* Generated from openssl */
+ .key =
+ "\x04"
+ "\x8e\xa0\x33\x69\x91\x7e\x3d\xec\xad\x8e\xf0\x45\x5e\x13\x3e\x68"
+ "\x5b\x8c\xab\x5c\xc6\xc8\x50\xdf\x91\x00\xe0\x24\x73\x4d\x31\xf2"
+ "\x2e\xc0\xd5\x6b\xee\xda\x98\x93\xec\xd8\x36\xaa\xb9\xcf\x63\x82"
+ "\xef\xa7\x1a\x03\xed\x16\xba\x74\xb8\x8b\xf9\xe5\x70\x39\xa4\x70",
+ .key_len = 65,
+ .param_len = 0,
+ .c =
+ "\x30\x45"
+ "\x02\x20"
+ "\x70\xab\xb6\x7d\xd6\x54\x80\x64\x42\x7e\x2d\x05\x08\x36\xc9\x96"
+ "\x25\xc2\xbb\xff\x08\xe5\x43\x15\x5e\xf3\x06\xd9\x2b\x2f\x0a\x9f"
+ "\x02\x21"
+ "\x00"
+ "\xbf\x21\x5f\x7e\x5d\x3f\x1a\x4d\x8f\x84\xc2\xe9\xa6\x4c\xa4\x18"
+ "\xb2\xb8\x46\xf4\x32\x96\xfa\x57\xc6\x29\xd4\x89\xae\xcc\xda\xdb",
+ .c_size = 71,
+ .algo = OID_SM2_with_SM3,
+ .m =
+ "\x47\xa7\xbf\xd3\xda\xc4\x79\xee\xda\x8b\x4f\xe8\x40\x94\xd4\x32"
+ "\x8f\xf1\xcd\x68\x4d\xbd\x9b\x1d\xe0\xd8\x9a\x5d\xad\x85\x47\x5c",
+ .m_size = 32,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ },
+ { /* From libgcrypt */
+ .key =
+ "\x04"
+ "\x87\x59\x38\x9a\x34\xaa\xad\x07\xec\xf4\xe0\xc8\xc2\x65\x0a\x44"
+ "\x59\xc8\xd9\x26\xee\x23\x78\x32\x4e\x02\x61\xc5\x25\x38\xcb\x47"
+ "\x75\x28\x10\x6b\x1e\x0b\x7c\x8d\xd5\xff\x29\xa9\xc8\x6a\x89\x06"
+ "\x56\x56\xeb\x33\x15\x4b\xc0\x55\x60\x91\xef\x8a\xc9\xd1\x7d\x78",
+ .key_len = 65,
+ .param_len = 0,
+ .c =
+ "\x30\x44"
+ "\x02\x20"
+ "\xd9\xec\xef\xe8\x5f\xee\x3c\x59\x57\x8e\x5b\xab\xb3\x02\xe1\x42"
+ "\x4b\x67\x2c\x0b\x26\xb6\x51\x2c\x3e\xfc\xc6\x49\xec\xfe\x89\xe5"
+ "\x02\x20"
+ "\x43\x45\xd0\xa5\xff\xe5\x13\x27\x26\xd0\xec\x37\xad\x24\x1e\x9a"
+ "\x71\x9a\xa4\x89\xb0\x7e\x0f\xc4\xbb\x2d\x50\xd0\xe5\x7f\x7a\x68",
+ .c_size = 70,
+ .algo = OID_SM2_with_SM3,
+ .m =
+ "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x00"
+ "\x12\x34\x56\x78\x9a\xbc\xde\xf0\x12\x34\x56\x78\x9a\xbc\xde\xf0",
+ .m_size = 32,
+ .public_key_vec = true,
+ .siggen_sigver_test = true,
+ },
+};
+
/* Example vectors below taken from
* http://www.oscca.gov.cn/UpFile/20101222141857786.pdf
*
@@ -3916,7 +5811,7 @@ static const struct hash_testvec hmac_sm3_tv_template[] = {
};
/*
- * SHA1 test vectors from from FIPS PUB 180-1
+ * SHA1 test vectors from FIPS PUB 180-1
* Long vector from CAVS 5.0
*/
static const struct hash_testvec sha1_tv_template[] = {
@@ -4103,7 +5998,7 @@ static const struct hash_testvec sha1_tv_template[] = {
/*
- * SHA224 test vectors from from FIPS PUB 180-2
+ * SHA224 test vectors from FIPS PUB 180-2
*/
static const struct hash_testvec sha224_tv_template[] = {
{
@@ -4273,7 +6168,7 @@ static const struct hash_testvec sha224_tv_template[] = {
};
/*
- * SHA256 test vectors from from NIST
+ * SHA256 test vectors from NIST
*/
static const struct hash_testvec sha256_tv_template[] = {
{
@@ -4442,7 +6337,7 @@ static const struct hash_testvec sha256_tv_template[] = {
};
/*
- * SHA384 test vectors from from NIST and kerneli
+ * SHA384 test vectors from NIST and kerneli
*/
static const struct hash_testvec sha384_tv_template[] = {
{
@@ -4632,7 +6527,7 @@ static const struct hash_testvec sha384_tv_template[] = {
};
/*
- * SHA512 test vectors from from NIST and kerneli
+ * SHA512 test vectors from NIST and kerneli
*/
static const struct hash_testvec sha512_tv_template[] = {
{
@@ -5079,132 +6974,6 @@ static const struct hash_testvec wp256_tv_template[] = {
},
};
-/*
- * TIGER test vectors from Tiger website
- */
-static const struct hash_testvec tgr192_tv_template[] = {
- {
- .plaintext = "",
- .psize = 0,
- .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
- "\x16\x16\x6e\x76\xb1\xbb\x92\x5f"
- "\xf3\x73\xde\x2d\x49\x58\x4e\x7a",
- }, {
- .plaintext = "abc",
- .psize = 3,
- .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
- "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf"
- "\x93\x5f\x7b\x95\x1c\x13\x29\x51",
- }, {
- .plaintext = "Tiger",
- .psize = 5,
- .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
- "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec"
- "\x37\x79\x0c\x11\x6f\x9d\x2b\xdf",
- }, {
- .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
- .psize = 64,
- .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
- "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e"
- "\xb5\x86\x44\x50\x34\xa5\xa3\x86",
- }, {
- .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
- .psize = 64,
- .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
- "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9"
- "\x57\x89\x65\x65\x97\x5f\x91\x97",
- }, {
- .plaintext = "Tiger - A Fast New Hash Function, "
- "by Ross Anderson and Eli Biham, "
- "proceedings of Fast Software Encryption 3, "
- "Cambridge, 1996.",
- .psize = 125,
- .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
- "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24"
- "\xdd\x68\x15\x1d\x50\x39\x74\xfc",
- },
-};
-
-static const struct hash_testvec tgr160_tv_template[] = {
- {
- .plaintext = "",
- .psize = 0,
- .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
- "\x16\x16\x6e\x76\xb1\xbb\x92\x5f"
- "\xf3\x73\xde\x2d",
- }, {
- .plaintext = "abc",
- .psize = 3,
- .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
- "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf"
- "\x93\x5f\x7b\x95",
- }, {
- .plaintext = "Tiger",
- .psize = 5,
- .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
- "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec"
- "\x37\x79\x0c\x11",
- }, {
- .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
- .psize = 64,
- .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
- "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e"
- "\xb5\x86\x44\x50",
- }, {
- .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
- .psize = 64,
- .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
- "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9"
- "\x57\x89\x65\x65",
- }, {
- .plaintext = "Tiger - A Fast New Hash Function, "
- "by Ross Anderson and Eli Biham, "
- "proceedings of Fast Software Encryption 3, "
- "Cambridge, 1996.",
- .psize = 125,
- .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
- "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24"
- "\xdd\x68\x15\x1d",
- },
-};
-
-static const struct hash_testvec tgr128_tv_template[] = {
- {
- .plaintext = "",
- .psize = 0,
- .digest = "\x24\xf0\x13\x0c\x63\xac\x93\x32"
- "\x16\x16\x6e\x76\xb1\xbb\x92\x5f",
- }, {
- .plaintext = "abc",
- .psize = 3,
- .digest = "\xf2\x58\xc1\xe8\x84\x14\xab\x2a"
- "\x52\x7a\xb5\x41\xff\xc5\xb8\xbf",
- }, {
- .plaintext = "Tiger",
- .psize = 5,
- .digest = "\x9f\x00\xf5\x99\x07\x23\x00\xdd"
- "\x27\x6a\xbb\x38\xc8\xeb\x6d\xec",
- }, {
- .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
- .psize = 64,
- .digest = "\x87\xfb\x2a\x90\x83\x85\x1c\xf7"
- "\x47\x0d\x2c\xf8\x10\xe6\xdf\x9e",
- }, {
- .plaintext = "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789",
- .psize = 64,
- .digest = "\x46\x7d\xb8\x08\x63\xeb\xce\x48"
- "\x8d\xf1\xcd\x12\x61\x65\x5d\xe9",
- }, {
- .plaintext = "Tiger - A Fast New Hash Function, "
- "by Ross Anderson and Eli Biham, "
- "proceedings of Fast Software Encryption 3, "
- "Cambridge, 1996.",
- .psize = 125,
- .digest = "\x3d\x9a\xeb\x03\xd1\xbd\x1a\x63"
- "\x57\xb2\x77\x4d\xfd\x6d\x5b\x24",
- },
-};
-
static const struct hash_testvec ghash_tv_template[] =
{
{
@@ -5394,83 +7163,6 @@ static const struct hash_testvec hmac_md5_tv_template[] =
};
/*
- * HMAC-RIPEMD128 test vectors from RFC2286
- */
-static const struct hash_testvec hmac_rmd128_tv_template[] = {
- {
- .key = "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
- .ksize = 16,
- .plaintext = "Hi There",
- .psize = 8,
- .digest = "\xfb\xf6\x1f\x94\x92\xaa\x4b\xbf"
- "\x81\xc1\x72\xe8\x4e\x07\x34\xdb",
- }, {
- .key = "Jefe",
- .ksize = 4,
- .plaintext = "what do ya want for nothing?",
- .psize = 28,
- .digest = "\x87\x5f\x82\x88\x62\xb6\xb3\x34"
- "\xb4\x27\xc5\x5f\x9f\x7f\xf0\x9b",
- }, {
- .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
- .ksize = 16,
- .plaintext = "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
- "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
- "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
- "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd",
- .psize = 50,
- .digest = "\x09\xf0\xb2\x84\x6d\x2f\x54\x3d"
- "\xa3\x63\xcb\xec\x8d\x62\xa3\x8d",
- }, {
- .key = "\x01\x02\x03\x04\x05\x06\x07\x08"
- "\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
- "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
- .ksize = 25,
- .plaintext = "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
- "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
- "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
- "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
- .psize = 50,
- .digest = "\xbd\xbb\xd7\xcf\x03\xe4\x4b\x5a"
- "\xa6\x0a\xf8\x15\xbe\x4d\x22\x94",
- }, {
- .key = "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
- .ksize = 16,
- .plaintext = "Test With Truncation",
- .psize = 20,
- .digest = "\xe7\x98\x08\xf2\x4b\x25\xfd\x03"
- "\x1c\x15\x5f\x0d\x55\x1d\x9a\x3a",
- }, {
- .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa",
- .ksize = 80,
- .plaintext = "Test Using Larger Than Block-Size Key - Hash Key First",
- .psize = 54,
- .digest = "\xdc\x73\x29\x28\xde\x98\x10\x4a"
- "\x1f\x59\xd3\x73\xc1\x50\xac\xbb",
- }, {
- .key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
- "\xaa\xaa",
- .ksize = 80,
- .plaintext = "Test Using Larger Than Block-Size Key and Larger Than One "
- "Block-Size Data",
- .psize = 73,
- .digest = "\x5c\x6b\xec\x96\x79\x3e\x16\xd4"
- "\x06\x90\xc2\x37\x63\x5f\x30\xc5",
- },
-};
-
-/*
* HMAC-RIPEMD160 test vectors from RFC2286
*/
static const struct hash_testvec hmac_rmd160_tv_template[] = {
@@ -5566,6 +7258,7 @@ static const struct hash_testvec hmac_sha1_tv_template[] = {
.psize = 28,
.digest = "\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74"
"\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
.ksize = 20,
@@ -5655,6 +7348,7 @@ static const struct hash_testvec hmac_sha224_tv_template[] = {
"\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f"
"\x8b\xbe\xa2\xa3\x9e\x61\x48\x00"
"\x8f\xd0\x5e\x44",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -5798,6 +7492,7 @@ static const struct hash_testvec hmac_sha256_tv_template[] = {
"\x6a\x04\x24\x26\x08\x95\x75\xc7"
"\x5a\x00\x3f\x08\x9d\x27\x39\x83"
"\x9d\xec\x58\xb9\x64\xec\x38\x43",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -6296,6 +7991,7 @@ static const struct hash_testvec hmac_sha384_tv_template[] = {
"\xe4\x2e\xc3\x73\x63\x22\x44\x5e"
"\x8e\x22\x40\xca\x5e\x69\xe2\xc7"
"\x8b\x32\x39\xec\xfa\xb2\x16\x49",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -6396,6 +8092,7 @@ static const struct hash_testvec hmac_sha512_tv_template[] = {
"\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd"
"\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b"
"\x63\x6e\x07\x0a\x38\xbc\xe7\x37",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -6491,6 +8188,7 @@ static const struct hash_testvec hmac_sha3_224_tv_template[] = {
"\x1b\x79\x86\x34\xad\x38\x68\x11"
"\xc2\xcf\xc8\x5b\xfa\xf5\xd5\x2b"
"\xba\xce\x5e\x66",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -6578,6 +8276,7 @@ static const struct hash_testvec hmac_sha3_256_tv_template[] = {
"\x35\x96\xbb\xb0\xda\x73\xb8\x87"
"\xc9\x17\x1f\x93\x09\x5b\x29\x4a"
"\xe8\x57\xfb\xe2\x64\x5e\x1b\xa5",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -6669,6 +8368,7 @@ static const struct hash_testvec hmac_sha3_384_tv_template[] = {
"\x3c\xa1\x35\x08\xa9\x32\x43\xce"
"\x48\xc0\x45\xdc\x00\x7f\x26\xa2"
"\x1b\x3f\x5e\x0e\x9d\xf4\xc2\x0a",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -6768,6 +8468,7 @@ static const struct hash_testvec hmac_sha3_512_tv_template[] = {
"\xee\x7a\x0c\x31\xd0\x22\xa9\x5e"
"\x1f\xc9\x2b\xa9\xd7\x7d\xf8\x83"
"\x96\x02\x75\xbe\xb4\xe6\x20\x24",
+ .fips_skip = 1,
}, {
.key = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
@@ -11747,85 +13448,6 @@ static const struct cipher_testvec serpent_tv_template[] = {
},
};
-static const struct cipher_testvec tnepres_tv_template[] = {
- { /* KeySize=0 */
- .ptext = "\x00\x01\x02\x03\x04\x05\x06\x07"
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
- .ctext = "\x41\xcc\x6b\x31\x59\x31\x45\x97"
- "\x6d\x6f\xbb\x38\x4b\x37\x21\x28",
- .len = 16,
- },
- { /* KeySize=128, PT=0, I=1 */
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00",
- .key = "\x80\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00",
- .klen = 16,
- .ctext = "\x49\xaf\xbf\xad\x9d\x5a\x34\x05"
- "\x2c\xd8\xff\xa5\x98\x6b\xd2\xdd",
- .len = 16,
- }, { /* KeySize=128 */
- .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
- .klen = 16,
- .ptext = "\x00\x01\x02\x03\x04\x05\x06\x07"
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
- .ctext = "\xea\xf4\xd7\xfc\xd8\x01\x34\x47"
- "\x81\x45\x0b\xfa\x0c\xd6\xad\x6e",
- .len = 16,
- }, { /* KeySize=128, I=121 */
- .key = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80",
- .klen = 16,
- .ptext = zeroed_string,
- .ctext = "\x3d\xda\xbf\xc0\x06\xda\xab\x06"
- "\x46\x2a\xf4\xef\x81\x54\x4e\x26",
- .len = 16,
- }, { /* KeySize=192, PT=0, I=1 */
- .key = "\x80\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00",
- .klen = 24,
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00",
- .ctext = "\xe7\x8e\x54\x02\xc7\x19\x55\x68"
- "\xac\x36\x78\xf7\xa3\xf6\x0c\x66",
- .len = 16,
- }, { /* KeySize=256, PT=0, I=1 */
- .key = "\x80\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00",
- .klen = 32,
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00",
- .ctext = "\xab\xed\x96\xe7\x66\xbf\x28\xcb"
- "\xc0\xeb\xd2\x1a\x82\xef\x08\x19",
- .len = 16,
- }, { /* KeySize=256, I=257 */
- .key = "\x1f\x1e\x1d\x1c\x1b\x1a\x19\x18"
- "\x17\x16\x15\x14\x13\x12\x11\x10"
- "\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08"
- "\x07\x06\x05\x04\x03\x02\x01\x00",
- .klen = 32,
- .ptext = "\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08"
- "\x07\x06\x05\x04\x03\x02\x01\x00",
- .ctext = "\x5c\xe7\x1c\x70\xd2\x88\x2e\x5b"
- "\xb8\x32\xe4\x33\xf8\x9f\x26\xde",
- .len = 16,
- }, { /* KeySize=256 */
- .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
- "\x10\x11\x12\x13\x14\x15\x16\x17"
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
- .klen = 32,
- .ptext = "\x00\x01\x02\x03\x04\x05\x06\x07"
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
- .ctext = "\x64\xa9\x1a\x37\xed\x9f\xe7\x49"
- "\xa8\x4e\x76\xd6\xf5\x0d\x78\xee",
- .len = 16,
- }
-};
-
static const struct cipher_testvec serpent_cbc_tv_template[] = {
{ /* Generated with Crypto++ */
.key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9"
@@ -13260,6 +14882,154 @@ static const struct cipher_testvec sm4_cfb_tv_template[] = {
}
};
+static const struct aead_testvec sm4_gcm_tv_template[] = {
+ { /* From https://datatracker.ietf.org/doc/html/rfc8998#appendix-A.1 */
+ .key = "\x01\x23\x45\x67\x89\xAB\xCD\xEF"
+ "\xFE\xDC\xBA\x98\x76\x54\x32\x10",
+ .klen = 16,
+ .iv = "\x00\x00\x12\x34\x56\x78\x00\x00"
+ "\x00\x00\xAB\xCD",
+ .ptext = "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+ "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"
+ "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE"
+ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
+ .plen = 64,
+ .assoc = "\xFE\xED\xFA\xCE\xDE\xAD\xBE\xEF"
+ "\xFE\xED\xFA\xCE\xDE\xAD\xBE\xEF"
+ "\xAB\xAD\xDA\xD2",
+ .alen = 20,
+ .ctext = "\x17\xF3\x99\xF0\x8C\x67\xD5\xEE"
+ "\x19\xD0\xDC\x99\x69\xC4\xBB\x7D"
+ "\x5F\xD4\x6F\xD3\x75\x64\x89\x06"
+ "\x91\x57\xB2\x82\xBB\x20\x07\x35"
+ "\xD8\x27\x10\xCA\x5C\x22\xF0\xCC"
+ "\xFA\x7C\xBF\x93\xD4\x96\xAC\x15"
+ "\xA5\x68\x34\xCB\xCF\x98\xC3\x97"
+ "\xB4\x02\x4A\x26\x91\x23\x3B\x8D"
+ "\x83\xDE\x35\x41\xE4\xC2\xB5\x81"
+ "\x77\xE0\x65\xA9\xBF\x7B\x62\xEC",
+ .clen = 80,
+ }
+};
+
+static const struct aead_testvec sm4_ccm_tv_template[] = {
+ { /* From https://datatracker.ietf.org/doc/html/rfc8998#appendix-A.2 */
+ .key = "\x01\x23\x45\x67\x89\xAB\xCD\xEF"
+ "\xFE\xDC\xBA\x98\x76\x54\x32\x10",
+ .klen = 16,
+ .iv = "\x02\x00\x00\x12\x34\x56\x78\x00"
+ "\x00\x00\x00\xAB\xCD\x00\x00\x00",
+ .ptext = "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+ "\xBB\xBB\xBB\xBB\xBB\xBB\xBB\xBB"
+ "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE"
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ "\xEE\xEE\xEE\xEE\xEE\xEE\xEE\xEE"
+ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
+ .plen = 64,
+ .assoc = "\xFE\xED\xFA\xCE\xDE\xAD\xBE\xEF"
+ "\xFE\xED\xFA\xCE\xDE\xAD\xBE\xEF"
+ "\xAB\xAD\xDA\xD2",
+ .alen = 20,
+ .ctext = "\x48\xAF\x93\x50\x1F\xA6\x2A\xDB"
+ "\xCD\x41\x4C\xCE\x60\x34\xD8\x95"
+ "\xDD\xA1\xBF\x8F\x13\x2F\x04\x20"
+ "\x98\x66\x15\x72\xE7\x48\x30\x94"
+ "\xFD\x12\xE5\x18\xCE\x06\x2C\x98"
+ "\xAC\xEE\x28\xD9\x5D\xF4\x41\x6B"
+ "\xED\x31\xA2\xF0\x44\x76\xC1\x8B"
+ "\xB4\x0C\x84\xA7\x4B\x97\xDC\x5B"
+ "\x16\x84\x2D\x4F\xA1\x86\xF5\x6A"
+ "\xB3\x32\x56\x97\x1F\xA1\x10\xF4",
+ .clen = 80,
+ }
+};
+
+static const struct hash_testvec sm4_cbcmac_tv_template[] = {
+ {
+ .key = "\xff\xee\xdd\xcc\xbb\xaa\x99\x88"
+ "\x77\x66\x55\x44\x33\x22\x11\x00",
+ .plaintext = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .digest = "\x97\xb4\x75\x8f\x84\x92\x3d\x3f"
+ "\x86\x81\x0e\x0e\xea\x14\x6d\x73",
+ .psize = 16,
+ .ksize = 16,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xBA\x98\x76\x54\x32\x10",
+ .plaintext = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb"
+ "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xee",
+ .digest = "\xc7\xdb\x17\x71\xa1\x5c\x0d\x22"
+ "\xa3\x39\x3a\x31\x88\x91\x49\xa1",
+ .psize = 33,
+ .ksize = 16,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xBA\x98\x76\x54\x32\x10",
+ .plaintext = "\xfb\xd1\xbe\x92\x7e\x50\x3f\x16"
+ "\xf9\xdd\xbe\x91\x73\x53\x37\x1a"
+ "\xfe\xdd\xba\x97\x7e\x53\x3c\x1c"
+ "\xfe\xd7\xbf\x9c\x75\x5f\x3e\x11"
+ "\xf0\xd8\xbc\x96\x73\x5c\x34\x11"
+ "\xf5\xdb\xb1\x99\x7a\x5a\x32\x1f"
+ "\xf6\xdf\xb4\x95\x7f\x5f\x3b\x17"
+ "\xfd\xdb\xb1\x9b\x76\x5c\x37",
+ .digest = "\x9b\x07\x88\x7f\xd5\x95\x23\x12"
+ "\x64\x0a\x66\x7f\x4e\x25\xca\xd0",
+ .psize = 63,
+ .ksize = 16,
+ }
+};
+
+static const struct hash_testvec sm4_cmac128_tv_template[] = {
+ {
+ .key = "\xff\xee\xdd\xcc\xbb\xaa\x99\x88"
+ "\x77\x66\x55\x44\x33\x22\x11\x00",
+ .plaintext = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xba\x98\x76\x54\x32\x10",
+ .digest = "\x00\xd4\x63\xb4\x9a\xf3\x52\xe2"
+ "\x74\xa9\x00\x55\x13\x54\x2a\xd1",
+ .psize = 16,
+ .ksize = 16,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xBA\x98\x76\x54\x32\x10",
+ .plaintext = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb"
+ "\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xcc"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xee",
+ .digest = "\x8a\x8a\xe9\xc0\xc8\x97\x0e\x85"
+ "\x21\x57\x02\x10\x1a\xbf\x9c\xc6",
+ .psize = 33,
+ .ksize = 16,
+ }, {
+ .key = "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\xfe\xdc\xBA\x98\x76\x54\x32\x10",
+ .plaintext = "\xfb\xd1\xbe\x92\x7e\x50\x3f\x16"
+ "\xf9\xdd\xbe\x91\x73\x53\x37\x1a"
+ "\xfe\xdd\xba\x97\x7e\x53\x3c\x1c"
+ "\xfe\xd7\xbf\x9c\x75\x5f\x3e\x11"
+ "\xf0\xd8\xbc\x96\x73\x5c\x34\x11"
+ "\xf5\xdb\xb1\x99\x7a\x5a\x32\x1f"
+ "\xf6\xdf\xb4\x95\x7f\x5f\x3b\x17"
+ "\xfd\xdb\xb1\x9b\x76\x5c\x37",
+ .digest = "\x5f\x14\xc9\xa9\x20\xb2\xb4\xf0"
+ "\x76\xe0\xd8\xd6\xdc\x4f\xe1\xbc",
+ .psize = 63,
+ .ksize = 16,
+ }
+};
+
/* Cast6 test vectors from RFC 2612 */
static const struct cipher_testvec cast6_tv_template[] = {
{
@@ -21916,6 +23686,55 @@ static const struct drbg_testvec drbg_nopr_hmac_sha256_tv_template[] = {
},
};
+/* Test vector obtained during NIST ACVP testing */
+static const struct drbg_testvec drbg_nopr_hmac_sha512_tv_template[] = {
+ {
+ .entropy = (unsigned char *)
+ "\xDF\xB0\xF2\x18\xF0\x78\x07\x01\x29\xA4\x29\x26"
+ "\x2F\x8A\x34\xCB\x37\xEF\xEE\x41\xE6\x96\xF7\xFF"
+ "\x61\x47\xD3\xED\x41\x97\xEF\x64\x0C\x48\x56\x5A"
+ "\xE6\x40\x6E\x4A\x3B\x9E\x7F\xAC\x08\xEC\x25\xAE"
+ "\x0B\x51\x0E\x2C\x44\x2E\xBD\xDB\x57\xD0\x4A\x6D"
+ "\x80\x3E\x37\x0F",
+ .entropylen = 64,
+ .expected = (unsigned char *)
+ "\x48\xc6\xa8\xdb\x09\xae\xde\x5d\x8c\x77\xf3\x52"
+ "\x92\x71\xa7\xb9\x6d\x53\x6d\xa3\x73\xe3\x55\xb8"
+ "\x39\xd6\x44\x2b\xee\xcb\xe1\x32\x15\x30\xbe\x4e"
+ "\x9b\x1e\x06\xd1\x6b\xbf\xd5\x3e\xea\x7c\xf5\xaa"
+ "\x4b\x05\xb5\xd3\xa7\xb2\xc4\xfe\xe7\x1b\xda\x11"
+ "\x43\x98\x03\x70\x90\xbf\x6e\x43\x9b\xe4\x14\xef"
+ "\x71\xa3\x2a\xef\x9f\x0d\xb9\xe3\x52\xf2\x89\xc9"
+ "\x66\x9a\x60\x60\x99\x60\x62\x4c\xd6\x45\x52\x54"
+ "\xe6\x32\xb2\x1b\xd4\x48\xb5\xa6\xf9\xba\xd3\xff"
+ "\x29\xc5\x21\xe0\x91\x31\xe0\x38\x8c\x93\x0f\x3c"
+ "\x30\x7b\x53\xa3\xc0\x7f\x2d\xc1\x39\xec\x69\x0e"
+ "\xf2\x4a\x3c\x65\xcc\xed\x07\x2a\xf2\x33\x83\xdb"
+ "\x10\x74\x96\x40\xa7\xc5\x1b\xde\x81\xca\x0b\x8f"
+ "\x1e\x0a\x1a\x7a\xbf\x3c\x4a\xb8\x8c\xaf\x7b\x80"
+ "\xb7\xdc\x5d\x0f\xef\x1b\x97\x6e\x3d\x17\x23\x5a"
+ "\x31\xb9\x19\xcf\x5a\xc5\x00\x2a\xb6\xf3\x99\x34"
+ "\x65\xee\xe9\x1c\x55\xa0\x3b\x07\x60\xc9\xc4\xe4"
+ "\xf7\x57\x5c\x34\x9f\xc6\x31\x30\x3f\x23\xb2\x89"
+ "\xc0\xe7\x50\xf3\xde\x59\xd1\x0e\xb3\x0f\x78\xcc"
+ "\x7e\x54\x5e\x61\xf6\x86\x3d\xb3\x11\x94\x36\x3e"
+ "\x61\x5c\x48\x99\xf6\x7b\x02\x9a\xdc\x6a\x28\xe6"
+ "\xd1\xa7\xd1\xa3",
+ .expectedlen = 256,
+ .addtla = (unsigned char *)
+ "\x6B\x0F\x4A\x48\x0B\x12\x85\xE4\x72\x23\x7F\x7F"
+ "\x94\x7C\x24\x69\x14\x9F\xDC\x72\xA6\x33\xAD\x3C"
+ "\x8C\x72\xC1\x88\x49\x59\x82\xC5",
+ .addtlb = (unsigned char *)
+ "\xC4\xAF\x36\x3D\xB8\x5D\x9D\xFA\x92\xF5\xC3\x3C"
+ "\x2D\x1E\x22\x2A\xBD\x8B\x05\x6F\xA3\xFC\xBF\x16"
+ "\xED\xAA\x75\x8D\x73\x9A\xF6\xEC",
+ .addtllen = 32,
+ .pers = NULL,
+ .perslen = 0,
+ }
+};
+
static const struct drbg_testvec drbg_nopr_ctr_aes192_tv_template[] = {
{
.entropy = (unsigned char *)
@@ -24741,1166 +26560,2864 @@ static const struct cipher_testvec seed_tv_template[] = {
}
};
-static const struct cipher_testvec salsa20_stream_tv_template[] = {
- /*
- * Testvectors from verified.test-vectors submitted to ECRYPT.
- * They are truncated to size 39, 64, 111, 129 to test a variety
- * of input length.
- */
- { /* Set 3, vector 0 */
- .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
- "\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F",
+/*
+ * ARIA test vectors
+ */
+static const struct cipher_testvec aria_tv_template[] = {
+ {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ .klen = 16,
+ .ptext = "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .ctext = "\xd7\x18\xfb\xd6\xab\x64\x4c\x73"
+ "\x9d\xa9\x5f\x3b\xe6\x45\x17\x78",
+ .len = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17",
+ .klen = 24,
+ .ptext = "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .ctext = "\x26\x44\x9c\x18\x05\xdb\xe7\xaa"
+ "\x25\xa4\x68\xce\x26\x3a\x9e\x79",
+ .len = 16,
+ }, {
+ .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ .klen = 32,
+ .ptext = "\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ .ctext = "\xf9\x2b\xd7\xc7\x9f\xb7\x2e\x2f"
+ "\x2b\x8f\x80\xc1\x97\x2d\x24\xfc",
+ .len = 16,
+ }
+};
+
+static const struct cipher_testvec aria_cbc_tv_template[] = {
+ {
+ .key = "\x7c\x95\x0d\x07\xe6\x14\x98\x92"
+ "\x07\xac\x22\x41\x4d\x23\x27\x37",
.klen = 16,
- .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00",
- .ctext = "\x2D\xD5\xC3\xF7\xBA\x2B\x20\xF7"
- "\x68\x02\x41\x0C\x68\x86\x88\x89"
- "\x5A\xD8\xC1\xBD\x4E\xA6\xC9\xB1"
- "\x40\xFB\x9B\x90\xE2\x10\x49\xBF"
- "\x58\x3F\x52\x79\x70\xEB\xC1",
- .len = 39,
- }, { /* Set 5, vector 0 */
- .key = "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .iv = "\x9d\xd5\x62\xce\x3d\x07\xd9\x89"
+ "\xf2\x78\x19\x4b\x65\x39\xc3\xc6",
+ .ptext = "\xcb\xbf\x47\x35\xc5\x37\xf0\x4e"
+ "\x85\x19\x21\x72\x33\x00\xde\x28",
+ .ctext = "\xf4\x80\x89\x89\x4a\x37\xda\x98"
+ "\x80\x52\x74\x75\xd9\xef\x58\xff",
+ .len = 16,
+ }, {
+ .key = "\x8f\xb9\x8d\xc9\xd7\x99\xfe\x7d"
+ "\xeb\x14\xaa\x65\xaf\x8c\x38\x1a",
.klen = 16,
- .iv = "\x80\x00\x00\x00\x00\x00\x00\x00",
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00",
- .ctext = "\xB6\x6C\x1E\x44\x46\xDD\x95\x57"
- "\xE5\x78\xE2\x23\xB0\xB7\x68\x01"
- "\x7B\x23\xB2\x67\xBB\x02\x34\xAE"
- "\x46\x26\xBF\x44\x3F\x21\x97\x76"
- "\x43\x6F\xB1\x9F\xD0\xE8\x86\x6F"
- "\xCD\x0D\xE9\xA9\x53\x8F\x4A\x09"
- "\xCA\x9A\xC0\x73\x2E\x30\xBC\xF9"
- "\x8E\x4F\x13\xE4\xB9\xE2\x01\xD9",
+ .iv = "\xb1\x67\x46\x57\x0c\x64\x65\xf2"
+ "\x8c\x2f\x65\x11\x12\x33\xd4\x9a",
+ .ptext = "\x3a\xaf\xc1\xeb\x3c\x0c\xc5\xcc"
+ "\x10\x6e\x45\xa1\xd6\x89\xf1\xe5"
+ "\x74\xb6\x90\xd3\x81\x45\x00\x66"
+ "\x62\x15\x78\x84\xb2\x63\x11\x76",
+ .ctext = "\x3d\x7d\x3a\xeb\x23\x85\x3e\x72"
+ "\x12\x45\xbb\x5b\x42\x99\xec\xa0"
+ "\xa2\xbe\x75\xd6\xb1\xd8\xea\x6f"
+ "\x97\xfe\xfd\xcc\xfc\x08\x38\x00",
+ .len = 32,
+ }, {
+ .key = "\xe8\xe0\x85\x9c\x33\x06\x36\x5f"
+ "\xa9\xab\x72\x66\xa1\xd7\xf5\x0d",
+ .klen = 16,
+ .iv = "\x5d\xd3\xaf\x13\xed\x82\xc8\x92"
+ "\x4f\xf4\xe2\x35\xdb\x39\x9e\xa5",
+ .ptext = "\xdf\x73\x61\x44\x86\x2f\x58\x1e"
+ "\xfe\xf6\xb9\x1d\xd9\x1e\x4c\x7c"
+ "\xb4\xe6\x2b\x7d\x17\xc3\xc6\x5f"
+ "\x9d\xf4\x29\x8a\x55\x5c\x82\x0e"
+ "\x67\x91\xdd\x4b\xfb\x31\x33\xf1"
+ "\x56\x75\xa3\x2c\x46\x08\xff\x18",
+ .ctext = "\x85\x07\x8c\x88\x70\x7b\x39\xb8"
+ "\xfd\x1d\xa1\xd0\x89\x5f\x3f\x85"
+ "\x18\x5a\xde\x64\xbd\x54\xd5\x67"
+ "\xd1\x27\x4c\x98\x82\x76\xea\x22"
+ "\x52\x98\x79\xb4\x1d\xe8\x16\xd0"
+ "\xc6\xea\xf7\xbb\x38\x89\xf2\x5d",
+ .len = 48,
+ }, {
+ .key = "\xc1\x19\x8a\x7b\xc9\xaf\x00\xb3"
+ "\x92\x3c\xd7\xed\xe7\x76\xc5\x98",
+ .klen = 16,
+ .iv = "\xca\x62\x82\x1a\x5b\xb1\xcf\xc1"
+ "\xfb\x50\xb7\xfc\xb0\x3b\x15\xcb",
+ .ptext = "\xcb\x92\x56\x74\xc9\xee\x80\x78"
+ "\x78\xf5\x73\xc5\x5b\x2c\x70\x2d"
+ "\x4e\x0d\xd7\x17\x6d\x5a\x35\x74"
+ "\x33\xb0\x7d\xf5\xdf\x5f\x96\x7b"
+ "\x1c\x79\x16\xd0\xe0\x29\x4e\x94"
+ "\x95\x46\x86\x7a\x77\x28\x89\xb4"
+ "\x3d\xbb\x65\xab\xfb\xd1\x6c\xf4"
+ "\x47\xbd\x7e\x7f\x9b\x1d\x8b\x12",
+ .ctext = "\x69\xd2\x56\xdf\xa8\x1a\x97\xbd"
+ "\x69\xb5\xbb\x6b\x29\x1d\x5f\x0f"
+ "\xdf\x5f\x63\xc0\x83\x0b\xd7\xb1"
+ "\x31\x2d\xbf\x73\xe1\xe5\x5d\x0e"
+ "\x0c\x8d\xc4\x8a\xa9\xbd\x5f\xc7"
+ "\xb5\x61\xa0\x2b\x90\x64\x1a\xde"
+ "\xd2\xe1\x61\xb9\xce\xf4\x0b\x1c"
+ "\x9c\x43\x69\x6d\xb2\x32\x98\x44",
+ .len = 64,
+ }, {
+ .key = "\xfa\xf7\x53\xf6\xd6\x08\x70\xf1"
+ "\x32\x58\x97\x74\x04\x12\x1b\x14",
+ .klen = 16,
+ .iv = "\xdd\x93\xb2\x3e\xcb\xc1\x7c\x27"
+ "\x7f\x9e\x41\x03\xab\x1d\xfb\x77",
+ .ptext = "\xae\x34\x94\x50\x73\x32\xf0\x75"
+ "\x96\x53\x2e\x1a\xc9\x91\x2b\x37"
+ "\x77\xbe\x48\x39\xa7\xd0\x6e\xf7"
+ "\x22\x7c\x4f\xe7\xd8\x06\xee\x92"
+ "\x80\x57\x61\x45\x7f\x50\xd5\x0a"
+ "\x0b\x5e\xd4\xd6\x90\x4e\xc3\x04"
+ "\x52\x63\xaf\x02\x55\xa6\x49\x4b"
+ "\x7a\x7e\x2e\x95\xea\x80\x6c\x4b"
+ "\xb7\x88\x42\x3d\xc1\x09\x28\x97"
+ "\xd7\xa1\x0f\x0f\x1f\xf1\xea\x63",
+ .ctext = "\x6b\x83\x00\xf1\x79\xb2\x23\xbf"
+ "\x17\x26\x8a\xef\xd3\xe1\x0e\x82"
+ "\x5b\xc7\xde\x3e\x39\x72\x2d\xb0"
+ "\xad\x25\x3b\xe6\x3b\x9f\xe9\x4b"
+ "\x6e\xe8\x77\xf5\x9d\x7d\x00\xae"
+ "\x73\x7b\x81\xff\xe3\x55\x8e\x90"
+ "\xdf\xe4\xcd\xd5\xdc\x16\x8b\x7a"
+ "\xe5\x04\x92\x18\xff\xcc\x63\x1b"
+ "\x53\xf3\x26\x44\x5c\x48\x1d\xa2"
+ "\x1f\x3f\xe0\x8b\x8f\x6f\xc2\x38",
+ .len = 80,
+ }, {
+ .key = "\xb8\xab\x6d\x03\x9d\xec\x15\x0a"
+ "\xcd\xcd\x68\x73\xa9\x35\x7e\x8a",
+ .klen = 16,
+ .iv = "\x9d\xf1\xc0\xa0\x02\x06\xf0\x03"
+ "\x43\x45\x6a\x2e\x3f\x21\xa9\x3c",
+ .ptext = "\xef\xbe\x0c\xa3\x49\x4a\xda\x1e"
+ "\x64\x90\x85\xeb\xdc\xca\x2b\x37"
+ "\x78\xb7\x62\xd7\x0a\xee\x35\x38"
+ "\x97\x72\x6a\x99\xb8\x86\x07\x77"
+ "\x40\xc3\x14\x49\x1f\x67\xa1\x6e"
+ "\x87\xf0\x0b\x64\x4d\xea\x7c\x3a"
+ "\x91\x05\xb1\x48\xa1\x6a\x00\x1d"
+ "\x1b\x4f\x99\xb9\x52\xc9\x0c\xfd"
+ "\xf3\xe2\x0b\x5f\xe9\xec\x71\xe2"
+ "\x7d\x15\x84\x46\xc2\x3b\x77\x7b"
+ "\x30\x01\x34\x5c\x8f\x22\x58\x9a"
+ "\x17\x05\x7e\xf6\xd5\x92\xc0\xb4",
+ .ctext = "\x79\x50\x9b\x34\xd7\x22\x9a\x72"
+ "\x61\xd7\xd8\xa9\xdb\xcf\x2f\xb0"
+ "\x81\x11\xe3\xed\xa0\xe4\xbd\x8d"
+ "\xe6\xf2\x52\x52\x40\xec\x9f\x3b"
+ "\xd4\x48\xc6\xdf\xfd\x36\x90\x8a"
+ "\x2f\x3b\xb0\xfb\xf4\x2b\x99\xa5"
+ "\xb2\x39\xc7\x52\x57\x2b\xbc\xd7"
+ "\x3f\x06\x10\x15\x2e\xf7\xaa\x79"
+ "\xd6\x6a\xe5\x4e\x2d\x0f\x5f\xaf"
+ "\xf9\x5a\x63\x28\x33\xf0\x85\x8a"
+ "\x06\x45\xce\x73\xaa\x96\x1d\xcc"
+ "\x6e\xb9\x25\xb8\x4c\xfe\xeb\x64",
+ .len = 96,
+ }, {
+ .key = "\x50\x45\x7b\x4c\x6d\x80\x53\x62"
+ "\x90\x26\x77\xf8\x04\x65\x26\xe3",
+ .klen = 16,
+ .iv = "\x9d\xd3\x73\x7b\x9b\xbd\x45\x97"
+ "\xd2\xbb\xa1\xb9\x08\x88\x2c\x85",
+ .ptext = "\x9f\x11\xeb\x78\x74\xcc\x4e\xd6"
+ "\x06\x4b\x6d\xe4\xdb\x11\x91\x58"
+ "\x1f\xa4\xf6\x0e\x8f\xe4\xcf\xfc"
+ "\x95\x9a\x8b\x68\xb4\x54\x57\x58"
+ "\x27\x71\xe4\x4b\xc5\x78\x6a\x26"
+ "\x28\xae\xed\x71\x0e\xe7\xbf\xc3"
+ "\xff\x9c\x46\x7b\x31\x3e\xff\xb1"
+ "\xa8\xca\xc3\x6d\xa1\x9e\x49\x16"
+ "\x31\x8b\xed\x2d\x2a\x2b\xaf\x3b"
+ "\x3e\x74\x7f\x07\x67\x8e\xb8\x0d"
+ "\x86\xe2\xea\x2c\x4a\x74\xdc\x9f"
+ "\x53\x72\xd1\x2e\x97\x0d\x0b\xa5"
+ "\x05\x87\x8e\x86\x69\x8d\x26\xfb"
+ "\x90\xc8\xab\x0e\xac\xaf\x84\x1c",
+ .ctext = "\x3c\x91\xab\x71\xe4\x77\x3e\xb0"
+ "\x7f\x20\x2e\xd0\xe1\xbe\xfd\x3c"
+ "\x06\x6c\x36\x75\x46\x27\xfd\x2d"
+ "\xba\x0f\xf0\x3c\x6d\x1e\x4b\x20"
+ "\xe9\x5e\x30\xd8\x03\xc6\xa0\x86"
+ "\xa8\xc7\xa4\x7f\x0e\x1f\x35\x55"
+ "\x24\x53\x02\xd5\x77\x30\x73\xdc"
+ "\xa5\xaf\x19\x92\x5b\x36\x86\x0e"
+ "\xcf\xf2\x5c\x00\xde\x92\xbf\x89"
+ "\x76\x46\xd5\x26\xb1\x8d\xa4\xef"
+ "\x61\x7e\x78\xb4\x68\xf5\x5b\x1d"
+ "\x39\x65\x32\x3a\xad\xff\x8b\x37"
+ "\x60\xc2\x8a\xaf\x48\x96\x8b\x9f"
+ "\x12\x6c\x70\x77\x95\xf3\x58\xb0",
+ .len = 112,
+ }, {
+ .key = "\xf9\x9f\x6a\x87\xa1\x2d\x6e\xac"
+ "\xde\xbb\x3e\x15\x5e\x49\xa4\xef",
+ .klen = 16,
+ .iv = "\xeb\x8e\x4f\xbe\x4b\x47\xd6\x4f"
+ "\x65\xd0\xfa\xee\xa6\xf1\x2c\xda",
+ .ptext = "\xa3\xfa\x4f\xf6\x00\x12\xbe\xc1"
+ "\x90\xcc\x91\x88\xbd\xfb\x1c\xdb"
+ "\x2b\xc8\xb9\x3d\x98\x01\xc8\x1f"
+ "\x07\xb4\xf3\x10\x1d\xfd\xb7\x2e"
+ "\xcb\x1c\x1f\xe0\x2d\xca\xd3\xc7"
+ "\xb2\xce\x52\xf1\x7e\xcb\x7c\x50"
+ "\x0c\x5c\x53\x6b\x18\x62\x02\x54"
+ "\xbc\x9d\x1f\xda\xd9\x7a\x2d\xff"
+ "\xb8\x2c\x65\xad\xf1\xfe\xb6\xa4"
+ "\x8c\xe8\x0a\xb7\x67\x60\xcb\x38"
+ "\xd7\x72\xa5\xb1\x92\x13\x8e\xd4"
+ "\xcd\xb3\x04\xb5\xa1\x11\x96\x37"
+ "\xb3\x53\xa6\xc4\x14\x56\x6d\x42"
+ "\x66\x43\x40\x42\x41\x63\x11\x7a"
+ "\xd5\x34\x38\x75\xd0\xbc\x74\x89"
+ "\x82\x1d\x2c\x0a\x3e\x6a\xfb\xbd",
+ .ctext = "\x09\x58\xf3\x22\xe5\x10\xf6\x3d"
+ "\xba\xb1\xfa\x5a\x16\xfe\xc5\x32"
+ "\x3d\x34\x59\x2e\x81\xde\x99\x2f"
+ "\xeb\x6a\x97\x86\x1f\x47\x8d\xe6"
+ "\x87\x79\x0e\xfe\xa4\xca\x09\xdc"
+ "\x24\x9b\xbb\xb1\x90\x33\xce\xd7"
+ "\x62\xfd\xfd\xa3\x65\x50\x07\x7c"
+ "\x4c\xa2\x10\xc7\x32\x0a\x0d\x5e"
+ "\x22\x29\x40\x71\xe5\xcc\x3a\x5b"
+ "\x5b\x53\x51\xa5\x5b\xc1\x76\x05"
+ "\x84\x6e\xe3\x58\x2b\xf2\x28\x76"
+ "\x5c\x66\x90\xfe\x63\x30\x1c\x45"
+ "\x26\x34\x80\xfe\x76\x87\x5b\xb1"
+ "\x63\x10\x09\xf6\x9d\x35\xcb\xee"
+ "\x3c\x60\x9d\x77\x5b\x36\x70\x09"
+ "\x4b\x63\x63\x90\x97\x3a\x6c\x8a",
+ .len = 128,
+ }, {
+ .key = "\x04\xb9\x6c\x8f\x5e\x79\x02\x87"
+ "\x88\x06\x7c\xfa\xd3\x7b\x56\xfe",
+ .klen = 16,
+ .iv = "\x4b\xc8\x93\x20\x98\x04\xba\x5a"
+ "\x22\x04\x1f\x3f\x79\x2c\x63\x79",
+ .ptext = "\xf3\x85\x3e\x75\x97\x10\x7c\x5d"
+ "\x39\x5a\x46\x47\xe7\x51\xa3\xac"
+ "\x84\x56\x3f\x1b\xb3\x93\x6a\x2e"
+ "\xf7\x8f\x63\xbe\x18\xff\xd7\x53"
+ "\xc8\xe0\xa5\xde\x86\xc2\xe4\xab"
+ "\xc3\x67\x27\x91\x43\x8c\xff\x6c"
+ "\xc7\x07\xc2\xcd\xe9\x12\x8b\xef"
+ "\x47\xe7\x82\xed\xe3\x8d\x5e\x33"
+ "\xca\xf1\x28\x32\xf4\x38\x41\x59"
+ "\x6c\x54\xa6\x40\xb0\xd5\x73\x26"
+ "\x5b\x02\xa6\x9d\x01\x29\x26\x84"
+ "\x5b\x33\x04\x36\xa4\x7b\x00\x01"
+ "\x42\xe1\x4f\xda\xa9\x1a\x9b\x4e"
+ "\x7d\x4a\x4c\xbc\xf6\xd4\x06\xc2"
+ "\x89\x70\x72\xf5\xc5\x7f\x42\xd5"
+ "\x7b\x9c\x6f\x00\x21\x74\xc5\xa5"
+ "\x78\xd7\xa2\x3c\x6d\x0f\xfb\x74"
+ "\x3d\x70\x9f\x6d\xdd\x30\xc0\x28",
+ .ctext = "\xc0\x49\x98\xb9\xf6\x58\xeb\x56"
+ "\x36\x76\x7a\x40\x7c\x27\x80\x62"
+ "\xe3\xcb\x9c\x87\x2c\x03\xc2\x0c"
+ "\x82\x00\x50\xd2\xe4\x61\x4d\x54"
+ "\x88\x10\x6f\x0a\xb4\x25\x57\xba"
+ "\xf0\x07\xe3\x55\x06\xb3\x72\xe9"
+ "\x2f\x9f\x1e\x50\xa8\x15\x69\x71"
+ "\xe3\xe5\x50\x32\xe5\xe0\x47\x0f"
+ "\x3a\xaa\x7d\xc0\x09\x0e\xdb\x1a"
+ "\xae\xb6\xa5\x87\x63\xd6\xbe\x8b"
+ "\xb2\x3d\x10\x1e\xb3\x68\xcf\x8a"
+ "\xe5\xa8\x89\xa9\xfe\x79\x13\x77"
+ "\xc4\x3f\x6f\x9f\xdd\x76\x5b\xf2"
+ "\x05\x67\x8a\x58\xb4\x31\xac\x64"
+ "\x6f\xc4\xc1\x6b\x08\x79\x3f\xe5"
+ "\x1c\x9a\x66\x3f\x7d\x1f\x18\xb1"
+ "\x07\xa5\x7b\x4f\x2c\x43\x33\x84"
+ "\xab\x1b\xc0\x7d\x49\x2f\x27\x9b",
+ .len = 144,
+ }, {
+ .key = "\x99\x79\xaf\x3c\xfb\xbd\xe7\xca"
+ "\xee\x4a\x4d\xb2\x23\x1e\xb6\x07",
+ .klen = 16,
+ .iv = "\xb4\xfc\xaa\xc1\x08\xbf\x68\xb2"
+ "\xf6\xef\x29\xbc\x2d\x92\xa9\x40",
+ .ptext = "\xd3\x44\xe4\xd9\x6c\x8a\x1d\x4b"
+ "\xfe\x64\x25\xb6\x72\x21\xda\x10"
+ "\x3e\x77\xee\xd1\x41\xd3\xea\xf0"
+ "\xee\xee\x72\x0f\xad\xa1\xca\xf3"
+ "\x7e\xfa\x99\x36\xe0\x8f\xed\x40"
+ "\xf1\x12\x80\x73\xd6\x26\x3a\xa6"
+ "\x5d\x71\xf6\xd5\xe1\xf3\x89\x16"
+ "\x6f\x96\x00\xcf\x26\x06\x2a\x27"
+ "\xe4\xc2\x57\xba\x1f\x74\x5e\x91"
+ "\x10\x7e\xe5\x51\x17\xd5\xdc\xb2"
+ "\x5b\x12\x4b\x33\xb1\xc6\x4e\x0d"
+ "\xbf\x0e\x5d\x65\x61\x68\xd1\xc5"
+ "\x4b\xc5\xa4\xcd\xf0\xe0\x79\x26"
+ "\xa3\xcd\xdc\xb8\xfc\xd5\xca\x1d"
+ "\x7e\x81\x74\x55\x76\xf5\x40\xbb"
+ "\x26\x7f\x11\x37\x23\x70\xc8\xb6"
+ "\xfc\x2b\x0b\xd7\x1c\x7b\x45\xe7"
+ "\xf2\x2a\xed\x10\x4f\xcf\x0c\xcd"
+ "\x0f\xe7\xf9\xa1\xfb\x27\x67\x09"
+ "\xee\x11\xa2\xaf\x37\xc6\x16\xe0",
+ .ctext = "\x60\xce\x9a\xdb\xb2\xe8\xa2\x64"
+ "\x35\x9c\x5b\x97\x21\x9b\x95\x89"
+ "\x7b\x89\x15\x01\x97\x8b\xec\x9b"
+ "\xb9\xce\x7d\xb9\x9d\xcc\xd0\xa0"
+ "\xda\x39\x5d\xfd\xb9\x51\xe7\x2f"
+ "\xe7\x9b\x73\x1b\x07\xfb\xfd\xbb"
+ "\xce\x84\x68\x76\x12\xc9\x6c\x38"
+ "\xc0\xdc\x67\x96\x5e\x63\xcf\xe5"
+ "\x57\x84\x7a\x14\x8c\xab\x38\x94"
+ "\x1c\x27\xc3\xe0\x03\x58\xfe\x98"
+ "\x97\xfc\x96\xba\x65\x87\x1e\x44"
+ "\xf8\x00\x91\x6a\x14\x05\xf3\xf9"
+ "\x8e\x3e\x7a\x3c\x41\x96\x15\x4f"
+ "\xa8\xc0\x73\x1f\x1b\xeb\xaf\xec"
+ "\xc4\x5a\x35\xed\x42\x2f\x47\xea"
+ "\xfd\x2f\x29\xf6\x0f\x58\x8b\x3d"
+ "\x15\x81\xe3\xa4\xa6\x5f\x33\x33"
+ "\xe9\x0d\x06\x4f\x7f\x89\x2c\x3d"
+ "\x18\x45\x1f\xd1\xc5\x74\xf7\x52"
+ "\x2f\x9b\x72\x3d\x1f\xad\x12\x1b",
+ .len = 160,
+ }, {
+ .key = "\x7f\x92\xd5\x06\x30\x6b\xc0\x23"
+ "\x87\xa8\x8e\x6d\xc7\xc5\xd7\xf1"
+ "\x5f\xce\x89\xb3\xd5\x7f\x7f\xf0",
+ .klen = 24,
+ .iv = "\xfd\xab\x56\xa6\x6e\xda\x7c\x57"
+ "\x36\x36\x89\x09\xcd\xa8\xd3\x91",
+ .ptext = "\x48\x3e\x3c\x11\xcf\xd0\x4f\xc0"
+ "\x51\xe3\x8c\xe9\x76\xcd\xff\x37",
+ .ctext = "\x2d\x8f\x39\x71\x0a\x2c\xc9\x93"
+ "\xb6\x1a\x5c\x53\x06\x4d\xaa\xcf",
+ .len = 16,
+ }, {
+ .key = "\xd6\x1a\x18\x2f\x68\x2f\xb6\xfe"
+ "\x3d\x2d\x85\x75\x6e\x18\x8a\x52"
+ "\x53\x39\xfc\xc1\xf5\xc0\x56\x22",
+ .klen = 24,
+ .iv = "\xc6\xae\xaa\x0d\x90\xf2\x38\x93"
+ "\xac\xd2\x3f\xc7\x74\x8d\x13\x7e",
+ .ptext = "\xfa\x3f\x70\x52\xfb\x04\x0e\xed"
+ "\x0e\x60\x75\x84\x21\xdf\x13\xa1"
+ "\x26\xf8\x8c\x26\x0a\x37\x51\x8f"
+ "\xe7\x9c\x74\x77\x7a\x3e\xbb\x5d",
+ .ctext = "\xc1\x53\x86\xf8\x60\x5d\x72\x59"
+ "\x7e\xdf\xc8\xdb\x85\xd6\x9f\x2a"
+ "\xa1\xda\xe5\x85\x78\x4f\x1b\x6f"
+ "\x58\xf3\x2b\xff\x34\xe4\x97\x4e",
+ .len = 32,
+ }, {
+ .key = "\xd7\x33\xf3\xa9\x5b\xb4\x86\xea"
+ "\xe3\x7d\x50\x62\x3b\x73\xaf\xc4"
+ "\xda\x89\xd9\x3c\xcc\xe4\x73\xb0",
+ .klen = 24,
+ .iv = "\xef\x3e\x5f\x46\x62\x88\xd5\x26"
+ "\x3b\xd3\xb5\x81\x78\x70\x1b\xd2",
+ .ptext = "\x39\x56\x34\x63\x2c\xc5\x51\x13"
+ "\x48\x29\x3a\x58\xbe\x41\xc5\x80"
+ "\x2c\x80\xa7\x3c\x14\xb4\x89\x5e"
+ "\x8e\xe5\x5f\xe2\x39\x80\xf5\x2b"
+ "\x77\xb5\xca\x90\xda\x1d\x22\x17"
+ "\xd9\xa0\x57\x80\xc8\x96\x70\x86",
+ .ctext = "\x25\x5f\x66\x15\xb5\x62\xfb\x55"
+ "\xb3\x77\xa1\x7d\x03\xba\x86\x0a"
+ "\x0d\x5b\xbb\x06\xe9\xe2\xa8\x41"
+ "\xa3\x58\xd6\x4b\xcb\x7f\xd0\x15"
+ "\x3b\x02\x74\x5d\x4c\x4c\xb0\xa5"
+ "\x06\xc9\x59\x53\x2a\x36\xeb\x59",
+ .len = 48,
+ }, {
+ .key = "\x07\x2c\xf4\x61\x79\x09\x01\x8f"
+ "\x37\x32\x98\xd4\x86\x2b\x3b\x80"
+ "\x07\x60\xba\xf0\x2e\xc3\x4a\x57",
+ .klen = 24,
+ .iv = "\xf5\xb5\xd7\xbf\xd2\x2a\x9b\x4a"
+ "\xe6\x08\xf0\xbe\x77\xd1\x62\x40",
+ .ptext = "\xa0\x82\x09\x60\x47\xbb\x16\x56"
+ "\x50\x1f\xab\x8b\x10\xfe\xf0\x5c"
+ "\x05\x32\x63\x1a\xc4\x46\x6f\x55"
+ "\x32\xde\x41\x5a\xf7\x52\xd7\xfa"
+ "\x30\x9d\x59\x8d\x64\x76\xad\x37"
+ "\xba\xbc\x46\x6a\x69\x17\x3c\xac"
+ "\x6f\xdd\xa2\x9b\x86\x32\x14\x2e"
+ "\x54\x74\x8f\x3d\xe2\xd6\x85\x44",
+ .ctext = "\x91\x02\xa9\xd3\x4b\x9a\x8f\xe6"
+ "\x9f\xe4\x51\x57\xc9\x42\xda\x68"
+ "\xca\xf6\x54\x51\x90\xec\x20\x2e"
+ "\xab\x25\x6c\xd9\x8b\x99\xa6\x1c"
+ "\x72\xc9\x01\xd6\xbc\x2b\x26\x78"
+ "\x42\x00\x84\x0a\xdd\xa8\xd9\xb5"
+ "\xc6\xc8\x30\xb6\xab\xea\x71\x84"
+ "\xb2\x57\x97\x32\xdb\x35\x23\xd8",
.len = 64,
- }, { /* Set 3, vector 27 */
- .key = "\x1B\x1C\x1D\x1E\x1F\x20\x21\x22"
- "\x23\x24\x25\x26\x27\x28\x29\x2A"
- "\x2B\x2C\x2D\x2E\x2F\x30\x31\x32"
- "\x33\x34\x35\x36\x37\x38\x39\x3A",
+ }, {
+ .key = "\x4f\x4a\x31\x64\xc6\xa5\x29\xaa"
+ "\xad\xfd\x32\x94\x1f\x56\x57\xd1"
+ "\x9d\x7e\x3d\x49\x00\x36\xb1\x5d",
+ .klen = 24,
+ .iv = "\xb2\x92\x83\x70\x1e\xa3\x97\xa6"
+ "\x65\x53\x39\xeb\x53\x8f\xb1\x38",
+ .ptext = "\x91\xac\x17\x11\x1c\x03\x69\x53"
+ "\xf5\xdf\xdb\x2c\x1b\x9a\x6e\x6b"
+ "\xb6\x02\xc4\xfa\x95\x01\x33\xa8"
+ "\xda\x7e\x18\x2c\xf4\x7e\x6e\x67"
+ "\xce\x8f\x9f\xea\x46\x66\x99\xb8"
+ "\xe1\xc7\x25\x4d\xbd\xa5\x74\xdf"
+ "\xc7\x8b\xfb\xe3\x2d\x3a\x82\xd3"
+ "\x17\x94\x77\x2f\x92\xb8\x87\xc2"
+ "\xcc\x6f\x70\x26\x87\xc7\x10\x8a"
+ "\xc8\xfd\xc2\xb3\xcf\xa0\xeb\x41",
+ .ctext = "\x28\x23\x3a\x4a\x18\xb7\xb6\x05"
+ "\xd4\x1b\x6a\x9e\xa7\xf2\x38\x01"
+ "\x78\xd3\xb0\x1b\x95\x68\x59\xf1"
+ "\xc0\xed\x30\x46\x2e\xb9\xa6\xdc"
+ "\xde\xef\xa6\x85\x19\xfc\x4d\x36"
+ "\x5d\x24\x92\x62\x75\x32\x76\x6d"
+ "\x6d\xa9\x07\xe1\x4f\x59\x84\x1a"
+ "\x68\x9a\x07\x48\xd3\x86\xf6\xf1"
+ "\x5b\xf9\x35\xec\x7c\xaf\x47\x13"
+ "\x9c\xc9\x33\x12\x10\x2f\x94\x8a",
+ .len = 80,
+ }, {
+ .key = "\x4c\xf4\xd0\x34\xd0\x95\xab\xae"
+ "\x82\x5c\xfd\xfa\x13\x86\x25\xce"
+ "\xf4\x13\x32\xcd\xc6\x6d\xf6\x50",
+ .klen = 24,
+ .iv = "\x12\x4a\x5b\x66\x3a\xd3\xfb\x1a"
+ "\xaf\x06\xea\xf4\x65\x59\xd6\xc2",
+ .ptext = "\x84\xa0\x53\x97\x61\x30\x70\x15"
+ "\xac\x45\x8e\xe8\xeb\xa1\x72\x93"
+ "\x26\x76\x98\x6f\xe4\x86\xca\xf0"
+ "\x57\x89\xf2\x2b\xd4\xcf\x2d\x95"
+ "\x86\x26\x20\x0e\x62\xfe\x8f\x1e"
+ "\x5d\xcb\x2b\x7e\xdd\xab\xac\xda"
+ "\x6e\x49\x20\xd5\xb7\x01\x83\x4e"
+ "\xac\x45\x8f\xe1\x05\x3f\xd5\xb1"
+ "\xee\xb7\x0d\x65\x00\x38\xab\x71"
+ "\x70\x6e\xb3\x97\x86\xd3\xcd\xad"
+ "\x51\x8b\x9c\xa0\x9a\x8b\x4c\xb9"
+ "\x16\x01\x6a\x1f\xdf\xf0\xf9\x9e",
+ .ctext = "\x38\x5b\x16\xef\xb8\x8c\x74\x7a"
+ "\x55\x17\x71\xa7\x7d\x34\xd7\x6a"
+ "\xc6\x31\x55\x6f\xbb\x61\xf4\x12"
+ "\x81\x8c\x91\x0d\x10\xdb\xd5\x22"
+ "\x77\x36\x32\xb6\x77\xb1\x5e\x21"
+ "\xb5\xec\xf9\x64\x04\x90\x6f\xc6"
+ "\x8a\x86\x23\xb5\xfe\xa4\xb6\x84"
+ "\x91\xa1\x60\xe3\xd7\xf3\xb9\xda"
+ "\x96\x23\x4a\xb3\xab\x75\x84\x04"
+ "\x15\x1a\xbb\xe8\x02\x1e\x80\x7c"
+ "\xc1\x93\x01\x0f\x5c\x4a\xde\x85"
+ "\xbb\x93\x05\x66\x53\x74\x40\x56",
+ .len = 96,
+ }, {
+ .key = "\x25\x1b\xc2\xa6\x21\x25\xeb\x97"
+ "\x4b\xf6\xcb\x3b\xcd\x61\xfd\x94"
+ "\x37\x03\xb3\xd9\x74\x6e\x4d\xbb",
+ .klen = 24,
+ .iv = "\xfd\x87\x2b\xec\x4c\x2c\xbf\xe2"
+ "\x94\x1a\xe6\xd9\xaf\x0e\x78\x17",
+ .ptext = "\x58\x2b\x1d\x73\x9a\x9c\x63\x18"
+ "\x88\x7a\x0e\x87\x2f\xf0\xb0\xdb"
+ "\xc9\x9d\x79\x51\x34\x39\x4f\x07"
+ "\xa2\x7c\x21\x04\x91\x3b\x79\x79"
+ "\xfe\xd5\x51\x46\xd5\xcd\x28\xc0"
+ "\xad\xb8\x55\xb2\xb2\x5a\x9a\xa2"
+ "\xe2\x0c\xfc\x55\x7d\x60\xd2\x95"
+ "\xb6\x08\x1d\x31\xaf\xf4\x17\x46"
+ "\xa4\xbb\x0f\xbd\x67\x3c\x73\x15"
+ "\x0c\x85\x2f\x62\xe5\xf4\x35\x96"
+ "\xb1\x9b\x5d\x00\x10\xe9\x70\x12"
+ "\x3a\x87\x7f\x67\xf1\x81\x7a\x05"
+ "\xb4\xa6\xfe\xdf\x36\x31\x6d\x9e"
+ "\x0e\xa9\x44\xa0\xb0\x05\xa9\x41",
+ .ctext = "\x4b\x56\xe0\xc2\x65\x2f\x7c\x6f"
+ "\xee\x22\xeb\x34\x1c\xa5\xb7\xc8"
+ "\x35\xd7\x51\xfd\x6a\xf4\xdd\xc3"
+ "\x38\xf4\xfc\x9d\x2e\xc2\x77\xb7"
+ "\x93\x8e\x8c\xb3\x44\x9b\xaf\xbb"
+ "\x99\xb9\xa8\x38\x1c\xfe\x63\xfb"
+ "\x1f\xa0\xaa\x35\x29\x7b\x87\x49"
+ "\x8e\x93\xa5\xb8\x5a\x85\x37\xa7"
+ "\x67\x69\x49\xbd\xc3\xfa\x89\x1c"
+ "\xf5\x60\x9b\xe7\x71\x96\x95\xd9"
+ "\x0b\x98\xe6\x74\x1d\xa3\xd9\x89"
+ "\x03\xe4\xf6\x66\xb3\x73\xb1\xac"
+ "\x9f\xee\x8f\xc2\x96\xcc\x97\x78"
+ "\x1b\x96\x63\x64\x00\x9c\x2d\x29",
+ .len = 112,
+ }, {
+ .key = "\x9c\x14\x44\x5a\xd5\x1c\x50\x08"
+ "\x95\xc2\xf2\xaf\x3f\x29\xc9\x3e"
+ "\x95\x5e\xc6\xb4\x2b\xf4\x3e\xe3",
+ .klen = 24,
+ .iv = "\x1b\xeb\x3d\x73\xfb\xd7\x1e\x2b"
+ "\x0c\x3d\x58\x6c\xb4\x41\x9b\xfe",
+ .ptext = "\x2f\x7e\x1c\x10\x81\x36\x2d\x79"
+ "\xaf\xab\x10\x44\x2e\xcc\x0d\x6c"
+ "\x9c\x14\xc2\xe4\xae\xb0\xbb\xda"
+ "\x6a\xe0\x42\x3d\x96\x9f\x78\x7d"
+ "\x70\x86\xa5\x92\x9f\xee\xcd\x3f"
+ "\x6a\x55\x84\x98\x28\x03\x02\xc2"
+ "\xf7\xec\x7a\xfa\xb1\xd9\xa8\xd8"
+ "\x1c\xc3\xaa\xd5\x61\x7f\x10\x0c"
+ "\xc0\xa1\x36\x3d\x81\x9a\xd2\x17"
+ "\x2e\x23\xc9\xb7\xff\xdf\x47\x6c"
+ "\x96\x3b\x0e\xbd\xec\x9a\x0e\xad"
+ "\x8c\xaf\x36\x3d\xff\x29\x8b\x33"
+ "\x87\x96\x77\x1a\x10\x81\x63\x8a"
+ "\x63\xde\x88\xa9\x9d\xa9\x01\xf2"
+ "\xdf\xc9\x25\x35\x48\x3a\x15\xdf"
+ "\x20\x6b\x91\x7c\x56\xe5\x10\x7a",
+ .ctext = "\x4d\x35\x70\xf1\x25\x02\x1d\x7f"
+ "\x9e\x0f\x5b\x4b\x65\xab\xcc\x6b"
+ "\x62\xab\x2b\xfa\xc0\x66\xee\x56"
+ "\xb4\x66\x95\x22\x84\x39\xd8\x3f"
+ "\x74\xba\x4f\x3f\xcd\xef\xcf\xf6"
+ "\x76\xeb\x9e\x8a\xec\x9c\x31\xa0"
+ "\x3e\x0c\xf9\xfa\x57\x90\xb4\x02"
+ "\xac\xc8\x28\xda\xa0\x05\xb7\x7e"
+ "\x75\x9c\x79\x36\xa9\x2f\x1a\x36"
+ "\x56\x77\xda\x74\xc7\xb3\xdf\xf3"
+ "\xb9\x83\x10\xf3\x6b\xe1\xdf\xcb"
+ "\x11\x70\xb1\xa0\x68\x48\x26\x95"
+ "\x10\x91\x94\xf3\xe9\x82\xb4\x8a"
+ "\xaa\xde\xf8\x9f\xce\x82\x47\x18"
+ "\x37\x5d\xda\x34\x74\x4d\x36\xbd"
+ "\xa5\x6c\xa4\xb3\x70\xad\x00\xbd",
+ .len = 128,
+ }, {
+ .key = "\x2d\x2e\x0f\x30\x32\xed\xa9\x1f"
+ "\x71\x4e\x68\x77\xe8\xa8\x5b\xdd"
+ "\x3c\x5e\x68\x6b\xab\x03\xe4\xf8",
+ .klen = 24,
+ .iv = "\x42\xc1\x61\x9a\x50\xfb\xc7\x6a"
+ "\x1a\x31\xa7\x87\xd0\x24\xcb\x5e",
+ .ptext = "\xc0\x3b\x12\x28\xca\x26\x7b\xb3"
+ "\x14\xc1\x7f\x66\xff\x3b\xa4\x80"
+ "\x59\x77\x4f\xa0\xd4\xb2\xd9\x8a"
+ "\xb6\x67\xe6\x28\xd3\x6f\xf2\xcf"
+ "\xb8\x6d\x2d\xc4\x2a\x69\x89\xff"
+ "\xcf\xbb\x11\x2e\x2a\x2b\x7c\xfd"
+ "\xcd\x56\x02\x95\xc9\x54\x6e\x62"
+ "\x6a\x97\x75\x1a\x21\x16\x46\xfb"
+ "\xc2\xab\x62\x54\xef\xba\xae\x46"
+ "\xd4\x14\xc6\xcc\x16\x1b\x95\xf9"
+ "\x05\x26\x23\x81\x19\x27\xad\x7b"
+ "\x9c\x8b\xfb\x65\xa4\x61\xee\x69"
+ "\x44\xbf\x59\xde\x03\x61\x11\x12"
+ "\x8d\x94\x48\x47\xa9\x52\x16\xfb"
+ "\x6b\xaf\x59\x6d\xab\x74\xbf\x5c"
+ "\xb6\x09\x21\x12\x42\x98\x13\xa1"
+ "\xa8\x6f\xb9\x6d\x4d\xa6\xdc\xea"
+ "\x61\x02\x3c\xa7\xcd\x1a\x28\x8c",
+ .ctext = "\xa1\x4a\x83\xb2\xe0\xef\x3d\x94"
+ "\xa4\x34\x66\x93\xb4\x89\x4e\x12"
+ "\xe5\x61\xc9\xea\xe0\x16\x96\x1a"
+ "\x3e\x94\x20\x81\xd4\x12\x7f\xf4"
+ "\xb8\x3f\xc9\xe2\x99\xb5\x0f\x9e"
+ "\x71\x86\x4f\x13\x78\x4e\xf1\x51"
+ "\xd4\x7d\x6e\x47\x31\x9a\xd8\xf7"
+ "\xb9\xb1\x17\xd0\xbd\xbf\x72\x86"
+ "\xb4\x58\x85\xf0\x05\x67\xc4\x00"
+ "\xca\xcb\xa7\x1a\x1d\x88\x29\xf4"
+ "\xe2\xf6\xdd\x5a\x3e\x5a\xbb\x29"
+ "\x48\x5a\x4a\x18\xcd\x5c\xf1\x09"
+ "\x5b\xbe\x1a\x43\x12\xc5\x6e\x6e"
+ "\x5e\x6d\x3b\x22\xf7\x58\xbd\xc8"
+ "\xb1\x04\xaf\x44\x9c\x2b\x98\x5a"
+ "\x14\xb7\x35\xb8\x9a\xce\x32\x28"
+ "\x1f\x8d\x08\x8a\xb9\x82\xf0\xa5"
+ "\x6a\x37\x29\xb6\x29\x3a\x53\x5e",
+ .len = 144,
+ }, {
+ .key = "\x66\xb8\x4d\x60\x67\x82\xcc\x8d"
+ "\x1e\xda\x8f\x28\xe5\x02\xdc\x2c"
+ "\x54\x84\x2a\x06\xb5\xd1\x34\x57",
+ .klen = 24,
+ .iv = "\xb8\x28\x4d\xf5\x69\xb9\xf3\x33"
+ "\x5e\x0b\xa6\x62\x35\x9b\xfb\x97",
+ .ptext = "\x3e\xc6\xec\xaf\x74\xe8\x72\x91"
+ "\xb2\xc6\x56\xb3\x23\x29\x43\xe0"
+ "\xfb\xcc\x21\x38\x64\x78\x9e\x78"
+ "\xbb\x6e\x0d\x7b\xfd\x05\x74\x01"
+ "\x7c\x94\xe0\xb0\xd7\x92\xfc\x58"
+ "\x28\xfc\xe2\x7b\x7f\xf7\x31\x0d"
+ "\x90\xb7\x60\x78\xa8\x9f\x52\xe3"
+ "\xe6\xaa\x2a\xb4\xa7\x09\x60\x53"
+ "\x42\x0e\x15\x31\xf6\x48\xa3\x0a"
+ "\x20\xf0\x79\x67\xb1\x83\x26\x66"
+ "\xe0\xb1\xb3\xbd\x1c\x76\x36\xfd"
+ "\x45\x87\xa4\x14\x1b\xef\xe7\x16"
+ "\xf7\xfa\x30\x3d\xb9\x52\x8f\x2e"
+ "\x01\x68\xc1\x7d\xa2\x15\x49\x74"
+ "\x53\x82\xc2\x10\xa8\x45\x73\x4d"
+ "\x41\xcc\x24\xa3\x42\xff\x30\xd1"
+ "\x02\x21\xdc\xd9\x08\xf7\xe7\x4c"
+ "\x33\x2d\x62\xc7\x38\xf5\xc2\xbe"
+ "\x52\xf1\x34\x78\x34\x53\x30\x5b"
+ "\x43\x43\x51\x6a\x02\x81\x64\x0c",
+ .ctext = "\xd9\xed\xc8\xc7\x66\xcd\x06\xc5"
+ "\xc1\x25\x9b\xf5\x14\x71\x1d\x69"
+ "\xc9\x7c\x04\x40\xab\xc0\x44\xf4"
+ "\xa1\xe6\x57\x8b\x35\x62\x4e\x3f"
+ "\xce\x4a\x99\xcd\x95\xc4\xd1\xf3"
+ "\xbc\x25\xa2\x18\xe6\xd1\xf7\xc0"
+ "\x13\x98\x60\x4c\x5c\xb1\x4f\x7a"
+ "\xbc\x45\x12\x52\xe8\x71\xb0\xf1"
+ "\x18\xef\x6f\x8a\x63\x35\x17\xae"
+ "\x90\x31\x41\x9d\xf4\xdc\x35\xcc"
+ "\x49\x72\x10\x11\x3b\xe3\x40\x7a"
+ "\x8e\x21\x39\xd0\x5b\x82\xb1\xe9"
+ "\x0c\x37\x5a\x7c\x11\xcb\x96\xd9"
+ "\xd4\x1c\x47\x4b\x70\xcb\xca\x08"
+ "\x5f\x71\xe9\x48\xf6\x29\xd8\xbb"
+ "\x5c\xad\x9b\x23\x9f\x62\xaf\xef"
+ "\x8e\xd8\x99\x1d\x60\xad\xc3\x6f"
+ "\xed\x06\x1a\xec\xfa\xc0\x0f\x0d"
+ "\xb7\x00\x02\x45\x7c\x94\x23\xb6"
+ "\xd7\x26\x6a\x16\x62\xc4\xd9\xee",
+ .len = 160,
+ }, {
+ .key = "\x7f\x92\xd5\x06\x30\x6b\xc0\x23"
+ "\x87\xa8\x8e\x6d\xc7\xc5\xd7\xf1"
+ "\x5f\xce\x89\xb3\xd5\x7f\x7f\xf0"
+ "\xfd\xab\x56\xa6\x6e\xda\x7c\x57",
.klen = 32,
- .iv = "\x00\x00\x00\x00\x00\x00\x00\x00",
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00",
- .ctext = "\xAE\x39\x50\x8E\xAC\x9A\xEC\xE7"
- "\xBF\x97\xBB\x20\xB9\xDE\xE4\x1F"
- "\x87\xD9\x47\xF8\x28\x91\x35\x98"
- "\xDB\x72\xCC\x23\x29\x48\x56\x5E"
- "\x83\x7E\x0B\xF3\x7D\x5D\x38\x7B"
- "\x2D\x71\x02\xB4\x3B\xB5\xD8\x23"
- "\xB0\x4A\xDF\x3C\xEC\xB6\xD9\x3B"
- "\x9B\xA7\x52\xBE\xC5\xD4\x50\x59"
- "\x15\x14\xB4\x0E\x40\xE6\x53\xD1"
- "\x83\x9C\x5B\xA0\x92\x29\x6B\x5E"
- "\x96\x5B\x1E\x2F\xD3\xAC\xC1\x92"
- "\xB1\x41\x3F\x19\x2F\xC4\x3B\xC6"
- "\x95\x46\x45\x54\xE9\x75\x03\x08"
- "\x44\xAF\xE5\x8A\x81\x12\x09",
- .len = 111,
- }, { /* Set 5, vector 27 */
- .key = "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .iv = "\x36\x36\x89\x09\xcd\xa8\xd3\x91"
+ "\x48\x3e\x3c\x11\xcf\xd0\x4f\xc0",
+ .ptext = "\x51\xe3\x8c\xe9\x76\xcd\xff\x37"
+ "\xd6\x1a\x18\x2f\x68\x2f\xb6\xfe",
+ .ctext = "\x05\x31\x46\x6d\xb8\xf4\x92\x64"
+ "\x46\xfd\x0d\x96\x60\x01\xd7\x94",
+ .len = 16,
+ }, {
+ .key = "\x3d\x2d\x85\x75\x6e\x18\x8a\x52"
+ "\x53\x39\xfc\xc1\xf5\xc0\x56\x22"
+ "\xc6\xae\xaa\x0d\x90\xf2\x38\x93"
+ "\xac\xd2\x3f\xc7\x74\x8d\x13\x7e",
.klen = 32,
- .iv = "\x00\x00\x00\x10\x00\x00\x00\x00",
- .ptext = "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00",
- .ctext = "\xD2\xDB\x1A\x5C\xF1\xC1\xAC\xDB"
- "\xE8\x1A\x7A\x43\x40\xEF\x53\x43"
- "\x5E\x7F\x4B\x1A\x50\x52\x3F\x8D"
- "\x28\x3D\xCF\x85\x1D\x69\x6E\x60"
- "\xF2\xDE\x74\x56\x18\x1B\x84\x10"
- "\xD4\x62\xBA\x60\x50\xF0\x61\xF2"
- "\x1C\x78\x7F\xC1\x24\x34\xAF\x58"
- "\xBF\x2C\x59\xCA\x90\x77\xF3\xB0"
- "\x5B\x4A\xDF\x89\xCE\x2C\x2F\xFC"
- "\x67\xF0\xE3\x45\xE8\xB3\xB3\x75"
- "\xA0\x95\x71\xA1\x29\x39\x94\xCA"
- "\x45\x2F\xBD\xCB\x10\xB6\xBE\x9F"
- "\x8E\xF9\xB2\x01\x0A\x5A\x0A\xB7"
- "\x6B\x9D\x70\x8E\x4B\xD6\x2F\xCD"
- "\x2E\x40\x48\x75\xE9\xE2\x21\x45"
- "\x0B\xC9\xB6\xB5\x66\xBC\x9A\x59"
- "\x5A",
- .len = 129,
- }, { /* large test vector generated using Crypto++ */
- .key = "\x00\x01\x02\x03\x04\x05\x06\x07"
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
- "\x10\x11\x12\x13\x14\x15\x16\x17"
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
- .klen = 32,
- .iv = "\x00\x00\x00\x00\x00\x00\x00\x00"
- "\x00\x00\x00\x00\x00\x00\x00\x00",
- .ptext =
- "\x00\x01\x02\x03\x04\x05\x06\x07"
- "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
- "\x10\x11\x12\x13\x14\x15\x16\x17"
- "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
- "\x20\x21\x22\x23\x24\x25\x26\x27"
- "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
- "\x30\x31\x32\x33\x34\x35\x36\x37"
- "\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
- "\x40\x41\x42\x43\x44\x45\x46\x47"
- "\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
- "\x50\x51\x52\x53\x54\x55\x56\x57"
- "\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
- "\x60\x61\x62\x63\x64\x65\x66\x67"
- "\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
- "\x70\x71\x72\x73\x74\x75\x76\x77"
- "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
- "\x80\x81\x82\x83\x84\x85\x86\x87"
- "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
- "\x90\x91\x92\x93\x94\x95\x96\x97"
- "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
- "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7"
- "\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
- "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7"
- "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7"
- "\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
- "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
- "\xe8\xe9\xea\xeb\xec\xed\xee\xef"
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
- "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
- "\x00\x03\x06\x09\x0c\x0f\x12\x15"
- "\x18\x1b\x1e\x21\x24\x27\x2a\x2d"
- "\x30\x33\x36\x39\x3c\x3f\x42\x45"
- "\x48\x4b\x4e\x51\x54\x57\x5a\x5d"
- "\x60\x63\x66\x69\x6c\x6f\x72\x75"
- "\x78\x7b\x7e\x81\x84\x87\x8a\x8d"
- "\x90\x93\x96\x99\x9c\x9f\xa2\xa5"
- "\xa8\xab\xae\xb1\xb4\xb7\xba\xbd"
- "\xc0\xc3\xc6\xc9\xcc\xcf\xd2\xd5"
- "\xd8\xdb\xde\xe1\xe4\xe7\xea\xed"
- "\xf0\xf3\xf6\xf9\xfc\xff\x02\x05"
- "\x08\x0b\x0e\x11\x14\x17\x1a\x1d"
- "\x20\x23\x26\x29\x2c\x2f\x32\x35"
- "\x38\x3b\x3e\x41\x44\x47\x4a\x4d"
- "\x50\x53\x56\x59\x5c\x5f\x62\x65"
- "\x68\x6b\x6e\x71\x74\x77\x7a\x7d"
- "\x80\x83\x86\x89\x8c\x8f\x92\x95"
- "\x98\x9b\x9e\xa1\xa4\xa7\xaa\xad"
- "\xb0\xb3\xb6\xb9\xbc\xbf\xc2\xc5"
- "\xc8\xcb\xce\xd1\xd4\xd7\xda\xdd"
- "\xe0\xe3\xe6\xe9\xec\xef\xf2\xf5"
- "\xf8\xfb\xfe\x01\x04\x07\x0a\x0d"
- "\x10\x13\x16\x19\x1c\x1f\x22\x25"
- "\x28\x2b\x2e\x31\x34\x37\x3a\x3d"
- "\x40\x43\x46\x49\x4c\x4f\x52\x55"
- "\x58\x5b\x5e\x61\x64\x67\x6a\x6d"
- "\x70\x73\x76\x79\x7c\x7f\x82\x85"
- "\x88\x8b\x8e\x91\x94\x97\x9a\x9d"
- "\xa0\xa3\xa6\xa9\xac\xaf\xb2\xb5"
- "\xb8\xbb\xbe\xc1\xc4\xc7\xca\xcd"
- "\xd0\xd3\xd6\xd9\xdc\xdf\xe2\xe5"
- "\xe8\xeb\xee\xf1\xf4\xf7\xfa\xfd"
- "\x00\x05\x0a\x0f\x14\x19\x1e\x23"
- "\x28\x2d\x32\x37\x3c\x41\x46\x4b"
- "\x50\x55\x5a\x5f\x64\x69\x6e\x73"
- "\x78\x7d\x82\x87\x8c\x91\x96\x9b"
- "\xa0\xa5\xaa\xaf\xb4\xb9\xbe\xc3"
- "\xc8\xcd\xd2\xd7\xdc\xe1\xe6\xeb"
- "\xf0\xf5\xfa\xff\x04\x09\x0e\x13"
- "\x18\x1d\x22\x27\x2c\x31\x36\x3b"
- "\x40\x45\x4a\x4f\x54\x59\x5e\x63"
- "\x68\x6d\x72\x77\x7c\x81\x86\x8b"
- "\x90\x95\x9a\x9f\xa4\xa9\xae\xb3"
- "\xb8\xbd\xc2\xc7\xcc\xd1\xd6\xdb"
- "\xe0\xe5\xea\xef\xf4\xf9\xfe\x03"
- "\x08\x0d\x12\x17\x1c\x21\x26\x2b"
- "\x30\x35\x3a\x3f\x44\x49\x4e\x53"
- "\x58\x5d\x62\x67\x6c\x71\x76\x7b"
- "\x80\x85\x8a\x8f\x94\x99\x9e\xa3"
- "\xa8\xad\xb2\xb7\xbc\xc1\xc6\xcb"
- "\xd0\xd5\xda\xdf\xe4\xe9\xee\xf3"
- "\xf8\xfd\x02\x07\x0c\x11\x16\x1b"
- "\x20\x25\x2a\x2f\x34\x39\x3e\x43"
- "\x48\x4d\x52\x57\x5c\x61\x66\x6b"
- "\x70\x75\x7a\x7f\x84\x89\x8e\x93"
- "\x98\x9d\xa2\xa7\xac\xb1\xb6\xbb"
- "\xc0\xc5\xca\xcf\xd4\xd9\xde\xe3"
- "\xe8\xed\xf2\xf7\xfc\x01\x06\x0b"
- "\x10\x15\x1a\x1f\x24\x29\x2e\x33"
- "\x38\x3d\x42\x47\x4c\x51\x56\x5b"
- "\x60\x65\x6a\x6f\x74\x79\x7e\x83"
- "\x88\x8d\x92\x97\x9c\xa1\xa6\xab"
- "\xb0\xb5\xba\xbf\xc4\xc9\xce\xd3"
- "\xd8\xdd\xe2\xe7\xec\xf1\xf6\xfb"
- "\x00\x07\x0e\x15\x1c\x23\x2a\x31"
- "\x38\x3f\x46\x4d\x54\x5b\x62\x69"
- "\x70\x77\x7e\x85\x8c\x93\x9a\xa1"
- "\xa8\xaf\xb6\xbd\xc4\xcb\xd2\xd9"
- "\xe0\xe7\xee\xf5\xfc\x03\x0a\x11"
- "\x18\x1f\x26\x2d\x34\x3b\x42\x49"
- "\x50\x57\x5e\x65\x6c\x73\x7a\x81"
- "\x88\x8f\x96\x9d\xa4\xab\xb2\xb9"
- "\xc0\xc7\xce\xd5\xdc\xe3\xea\xf1"
- "\xf8\xff\x06\x0d\x14\x1b\x22\x29"
- "\x30\x37\x3e\x45\x4c\x53\x5a\x61"
- "\x68\x6f\x76\x7d\x84\x8b\x92\x99"
- "\xa0\xa7\xae\xb5\xbc\xc3\xca\xd1"
- "\xd8\xdf\xe6\xed\xf4\xfb\x02\x09"
- "\x10\x17\x1e\x25\x2c\x33\x3a\x41"
- "\x48\x4f\x56\x5d\x64\x6b\x72\x79"
- "\x80\x87\x8e\x95\x9c\xa3\xaa\xb1"
- "\xb8\xbf\xc6\xcd\xd4\xdb\xe2\xe9"
- "\xf0\xf7\xfe\x05\x0c\x13\x1a\x21"
- "\x28\x2f\x36\x3d\x44\x4b\x52\x59"
- "\x60\x67\x6e\x75\x7c\x83\x8a\x91"
- "\x98\x9f\xa6\xad\xb4\xbb\xc2\xc9"
- "\xd0\xd7\xde\xe5\xec\xf3\xfa\x01"
- "\x08\x0f\x16\x1d\x24\x2b\x32\x39"
- "\x40\x47\x4e\x55\x5c\x63\x6a\x71"
- "\x78\x7f\x86\x8d\x94\x9b\xa2\xa9"
- "\xb0\xb7\xbe\xc5\xcc\xd3\xda\xe1"
- "\xe8\xef\xf6\xfd\x04\x0b\x12\x19"
- "\x20\x27\x2e\x35\x3c\x43\x4a\x51"
- "\x58\x5f\x66\x6d\x74\x7b\x82\x89"
- "\x90\x97\x9e\xa5\xac\xb3\xba\xc1"
- "\xc8\xcf\xd6\xdd\xe4\xeb\xf2\xf9"
- "\x00\x09\x12\x1b\x24\x2d\x36\x3f"
- "\x48\x51\x5a\x63\x6c\x75\x7e\x87"
- "\x90\x99\xa2\xab\xb4\xbd\xc6\xcf"
- "\xd8\xe1\xea\xf3\xfc\x05\x0e\x17"
- "\x20\x29\x32\x3b\x44\x4d\x56\x5f"
- "\x68\x71\x7a\x83\x8c\x95\x9e\xa7"
- "\xb0\xb9\xc2\xcb\xd4\xdd\xe6\xef"
- "\xf8\x01\x0a\x13\x1c\x25\x2e\x37"
- "\x40\x49\x52\x5b\x64\x6d\x76\x7f"
- "\x88\x91\x9a\xa3\xac\xb5\xbe\xc7"
- "\xd0\xd9\xe2\xeb\xf4\xfd\x06\x0f"
- "\x18\x21\x2a\x33\x3c\x45\x4e\x57"
- "\x60\x69\x72\x7b\x84\x8d\x96\x9f"
- "\xa8\xb1\xba\xc3\xcc\xd5\xde\xe7"
- "\xf0\xf9\x02\x0b\x14\x1d\x26\x2f"
- "\x38\x41\x4a\x53\x5c\x65\x6e\x77"
- "\x80\x89\x92\x9b\xa4\xad\xb6\xbf"
- "\xc8\xd1\xda\xe3\xec\xf5\xfe\x07"
- "\x10\x19\x22\x2b\x34\x3d\x46\x4f"
- "\x58\x61\x6a\x73\x7c\x85\x8e\x97"
- "\xa0\xa9\xb2\xbb\xc4\xcd\xd6\xdf"
- "\xe8\xf1\xfa\x03\x0c\x15\x1e\x27"
- "\x30\x39\x42\x4b\x54\x5d\x66\x6f"
- "\x78\x81\x8a\x93\x9c\xa5\xae\xb7"
- "\xc0\xc9\xd2\xdb\xe4\xed\xf6\xff"
- "\x08\x11\x1a\x23\x2c\x35\x3e\x47"
- "\x50\x59\x62\x6b\x74\x7d\x86\x8f"
- "\x98\xa1\xaa\xb3\xbc\xc5\xce\xd7"
- "\xe0\xe9\xf2\xfb\x04\x0d\x16\x1f"
- "\x28\x31\x3a\x43\x4c\x55\x5e\x67"
- "\x70\x79\x82\x8b\x94\x9d\xa6\xaf"
- "\xb8\xc1\xca\xd3\xdc\xe5\xee\xf7"
- "\x00\x0b\x16\x21\x2c\x37\x42\x4d"
- "\x58\x63\x6e\x79\x84\x8f\x9a\xa5"
- "\xb0\xbb\xc6\xd1\xdc\xe7\xf2\xfd"
- "\x08\x13\x1e\x29\x34\x3f\x4a\x55"
- "\x60\x6b\x76\x81\x8c\x97\xa2\xad"
- "\xb8\xc3\xce\xd9\xe4\xef\xfa\x05"
- "\x10\x1b\x26\x31\x3c\x47\x52\x5d"
- "\x68\x73\x7e\x89\x94\x9f\xaa\xb5"
- "\xc0\xcb\xd6\xe1\xec\xf7\x02\x0d"
- "\x18\x23\x2e\x39\x44\x4f\x5a\x65"
- "\x70\x7b\x86\x91\x9c\xa7\xb2\xbd"
- "\xc8\xd3\xde\xe9\xf4\xff\x0a\x15"
- "\x20\x2b\x36\x41\x4c\x57\x62\x6d"
- "\x78\x83\x8e\x99\xa4\xaf\xba\xc5"
- "\xd0\xdb\xe6\xf1\xfc\x07\x12\x1d"
- "\x28\x33\x3e\x49\x54\x5f\x6a\x75"
- "\x80\x8b\x96\xa1\xac\xb7\xc2\xcd"
- "\xd8\xe3\xee\xf9\x04\x0f\x1a\x25"
- "\x30\x3b\x46\x51\x5c\x67\x72\x7d"
- "\x88\x93\x9e\xa9\xb4\xbf\xca\xd5"
- "\xe0\xeb\xf6\x01\x0c\x17\x22\x2d"
- "\x38\x43\x4e\x59\x64\x6f\x7a\x85"
- "\x90\x9b\xa6\xb1\xbc\xc7\xd2\xdd"
- "\xe8\xf3\xfe\x09\x14\x1f\x2a\x35"
- "\x40\x4b\x56\x61\x6c\x77\x82\x8d"
- "\x98\xa3\xae\xb9\xc4\xcf\xda\xe5"
- "\xf0\xfb\x06\x11\x1c\x27\x32\x3d"
- "\x48\x53\x5e\x69\x74\x7f\x8a\x95"
- "\xa0\xab\xb6\xc1\xcc\xd7\xe2\xed"
- "\xf8\x03\x0e\x19\x24\x2f\x3a\x45"
- "\x50\x5b\x66\x71\x7c\x87\x92\x9d"
- "\xa8\xb3\xbe\xc9\xd4\xdf\xea\xf5"
- "\x00\x0d\x1a\x27\x34\x41\x4e\x5b"
- "\x68\x75\x82\x8f\x9c\xa9\xb6\xc3"
- "\xd0\xdd\xea\xf7\x04\x11\x1e\x2b"
- "\x38\x45\x52\x5f\x6c\x79\x86\x93"
- "\xa0\xad\xba\xc7\xd4\xe1\xee\xfb"
- "\x08\x15\x22\x2f\x3c\x49\x56\x63"
- "\x70\x7d\x8a\x97\xa4\xb1\xbe\xcb"
- "\xd8\xe5\xf2\xff\x0c\x19\x26\x33"
- "\x40\x4d\x5a\x67\x74\x81\x8e\x9b"
- "\xa8\xb5\xc2\xcf\xdc\xe9\xf6\x03"
- "\x10\x1d\x2a\x37\x44\x51\x5e\x6b"
- "\x78\x85\x92\x9f\xac\xb9\xc6\xd3"
- "\xe0\xed\xfa\x07\x14\x21\x2e\x3b"
- "\x48\x55\x62\x6f\x7c\x89\x96\xa3"
- "\xb0\xbd\xca\xd7\xe4\xf1\xfe\x0b"
- "\x18\x25\x32\x3f\x4c\x59\x66\x73"
- "\x80\x8d\x9a\xa7\xb4\xc1\xce\xdb"
- "\xe8\xf5\x02\x0f\x1c\x29\x36\x43"
- "\x50\x5d\x6a\x77\x84\x91\x9e\xab"
- "\xb8\xc5\xd2\xdf\xec\xf9\x06\x13"
- "\x20\x2d\x3a\x47\x54\x61\x6e\x7b"
- "\x88\x95\xa2\xaf\xbc\xc9\xd6\xe3"
- "\xf0\xfd\x0a\x17\x24\x31\x3e\x4b"
- "\x58\x65\x72\x7f\x8c\x99\xa6\xb3"
- "\xc0\xcd\xda\xe7\xf4\x01\x0e\x1b"
- "\x28\x35\x42\x4f\x5c\x69\x76\x83"
- "\x90\x9d\xaa\xb7\xc4\xd1\xde\xeb"
- "\xf8\x05\x12\x1f\x2c\x39\x46\x53"
- "\x60\x6d\x7a\x87\x94\xa1\xae\xbb"
- "\xc8\xd5\xe2\xef\xfc\x09\x16\x23"
- "\x30\x3d\x4a\x57\x64\x71\x7e\x8b"
- "\x98\xa5\xb2\xbf\xcc\xd9\xe6\xf3"
- "\x00\x0f\x1e\x2d\x3c\x4b\x5a\x69"
- "\x78\x87\x96\xa5\xb4\xc3\xd2\xe1"
- "\xf0\xff\x0e\x1d\x2c\x3b\x4a\x59"
- "\x68\x77\x86\x95\xa4\xb3\xc2\xd1"
- "\xe0\xef\xfe\x0d\x1c\x2b\x3a\x49"
- "\x58\x67\x76\x85\x94\xa3\xb2\xc1"
- "\xd0\xdf\xee\xfd\x0c\x1b\x2a\x39"
- "\x48\x57\x66\x75\x84\x93\xa2\xb1"
- "\xc0\xcf\xde\xed\xfc\x0b\x1a\x29"
- "\x38\x47\x56\x65\x74\x83\x92\xa1"
- "\xb0\xbf\xce\xdd\xec\xfb\x0a\x19"
- "\x28\x37\x46\x55\x64\x73\x82\x91"
- "\xa0\xaf\xbe\xcd\xdc\xeb\xfa\x09"
- "\x18\x27\x36\x45\x54\x63\x72\x81"
- "\x90\x9f\xae\xbd\xcc\xdb\xea\xf9"
- "\x08\x17\x26\x35\x44\x53\x62\x71"
- "\x80\x8f\x9e\xad\xbc\xcb\xda\xe9"
- "\xf8\x07\x16\x25\x34\x43\x52\x61"
- "\x70\x7f\x8e\x9d\xac\xbb\xca\xd9"
- "\xe8\xf7\x06\x15\x24\x33\x42\x51"
- "\x60\x6f\x7e\x8d\x9c\xab\xba\xc9"
- "\xd8\xe7\xf6\x05\x14\x23\x32\x41"
- "\x50\x5f\x6e\x7d\x8c\x9b\xaa\xb9"
- "\xc8\xd7\xe6\xf5\x04\x13\x22\x31"
- "\x40\x4f\x5e\x6d\x7c\x8b\x9a\xa9"
- "\xb8\xc7\xd6\xe5\xf4\x03\x12\x21"
- "\x30\x3f\x4e\x5d\x6c\x7b\x8a\x99"
- "\xa8\xb7\xc6\xd5\xe4\xf3\x02\x11"
- "\x20\x2f\x3e\x4d\x5c\x6b\x7a\x89"
- "\x98\xa7\xb6\xc5\xd4\xe3\xf2\x01"
- "\x10\x1f\x2e\x3d\x4c\x5b\x6a\x79"
- "\x88\x97\xa6\xb5\xc4\xd3\xe2\xf1"
- "\x00\x11\x22\x33\x44\x55\x66\x77"
- "\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
- "\x10\x21\x32\x43\x54\x65\x76\x87"
- "\x98\xa9\xba\xcb\xdc\xed\xfe\x0f"
- "\x20\x31\x42\x53\x64\x75\x86\x97"
- "\xa8\xb9\xca\xdb\xec\xfd\x0e\x1f"
- "\x30\x41\x52\x63\x74\x85\x96\xa7"
- "\xb8\xc9\xda\xeb\xfc\x0d\x1e\x2f"
- "\x40\x51\x62\x73\x84\x95\xa6\xb7"
- "\xc8\xd9\xea\xfb\x0c\x1d\x2e\x3f"
- "\x50\x61\x72\x83\x94\xa5\xb6\xc7"
- "\xd8\xe9\xfa\x0b\x1c\x2d\x3e\x4f"
- "\x60\x71\x82\x93\xa4\xb5\xc6\xd7"
- "\xe8\xf9\x0a\x1b\x2c\x3d\x4e\x5f"
- "\x70\x81\x92\xa3\xb4\xc5\xd6\xe7"
- "\xf8\x09\x1a\x2b\x3c\x4d\x5e\x6f"
- "\x80\x91\xa2\xb3\xc4\xd5\xe6\xf7"
- "\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f"
- "\x90\xa1\xb2\xc3\xd4\xe5\xf6\x07"
- "\x18\x29\x3a\x4b\x5c\x6d\x7e\x8f"
- "\xa0\xb1\xc2\xd3\xe4\xf5\x06\x17"
- "\x28\x39\x4a\x5b\x6c\x7d\x8e\x9f"
- "\xb0\xc1\xd2\xe3\xf4\x05\x16\x27"
- "\x38\x49\x5a\x6b\x7c\x8d\x9e\xaf"
- "\xc0\xd1\xe2\xf3\x04\x15\x26\x37"
- "\x48\x59\x6a\x7b\x8c\x9d\xae\xbf"
- "\xd0\xe1\xf2\x03\x14\x25\x36\x47"
- "\x58\x69\x7a\x8b\x9c\xad\xbe\xcf"
- "\xe0\xf1\x02\x13\x24\x35\x46\x57"
- "\x68\x79\x8a\x9b\xac\xbd\xce\xdf"
- "\xf0\x01\x12\x23\x34\x45\x56\x67"
- "\x78\x89\x9a\xab\xbc\xcd\xde\xef"
- "\x00\x13\x26\x39\x4c\x5f\x72\x85"
- "\x98\xab\xbe\xd1\xe4\xf7\x0a\x1d"
- "\x30\x43\x56\x69\x7c\x8f\xa2\xb5"
- "\xc8\xdb\xee\x01\x14\x27\x3a\x4d"
- "\x60\x73\x86\x99\xac\xbf\xd2\xe5"
- "\xf8\x0b\x1e\x31\x44\x57\x6a\x7d"
- "\x90\xa3\xb6\xc9\xdc\xef\x02\x15"
- "\x28\x3b\x4e\x61\x74\x87\x9a\xad"
- "\xc0\xd3\xe6\xf9\x0c\x1f\x32\x45"
- "\x58\x6b\x7e\x91\xa4\xb7\xca\xdd"
- "\xf0\x03\x16\x29\x3c\x4f\x62\x75"
- "\x88\x9b\xae\xc1\xd4\xe7\xfa\x0d"
- "\x20\x33\x46\x59\x6c\x7f\x92\xa5"
- "\xb8\xcb\xde\xf1\x04\x17\x2a\x3d"
- "\x50\x63\x76\x89\x9c\xaf\xc2\xd5"
- "\xe8\xfb\x0e\x21\x34\x47\x5a\x6d"
- "\x80\x93\xa6\xb9\xcc\xdf\xf2\x05"
- "\x18\x2b\x3e\x51\x64\x77\x8a\x9d"
- "\xb0\xc3\xd6\xe9\xfc\x0f\x22\x35"
- "\x48\x5b\x6e\x81\x94\xa7\xba\xcd"
- "\xe0\xf3\x06\x19\x2c\x3f\x52\x65"
- "\x78\x8b\x9e\xb1\xc4\xd7\xea\xfd"
- "\x10\x23\x36\x49\x5c\x6f\x82\x95"
- "\xa8\xbb\xce\xe1\xf4\x07\x1a\x2d"
- "\x40\x53\x66\x79\x8c\x9f\xb2\xc5"
- "\xd8\xeb\xfe\x11\x24\x37\x4a\x5d"
- "\x70\x83\x96\xa9\xbc\xcf\xe2\xf5"
- "\x08\x1b\x2e\x41\x54\x67\x7a\x8d"
- "\xa0\xb3\xc6\xd9\xec\xff\x12\x25"
- "\x38\x4b\x5e\x71\x84\x97\xaa\xbd"
- "\xd0\xe3\xf6\x09\x1c\x2f\x42\x55"
- "\x68\x7b\x8e\xa1\xb4\xc7\xda\xed"
- "\x00\x15\x2a\x3f\x54\x69\x7e\x93"
- "\xa8\xbd\xd2\xe7\xfc\x11\x26\x3b"
- "\x50\x65\x7a\x8f\xa4\xb9\xce\xe3"
- "\xf8\x0d\x22\x37\x4c\x61\x76\x8b"
- "\xa0\xb5\xca\xdf\xf4\x09\x1e\x33"
- "\x48\x5d\x72\x87\x9c\xb1\xc6\xdb"
- "\xf0\x05\x1a\x2f\x44\x59\x6e\x83"
- "\x98\xad\xc2\xd7\xec\x01\x16\x2b"
- "\x40\x55\x6a\x7f\x94\xa9\xbe\xd3"
- "\xe8\xfd\x12\x27\x3c\x51\x66\x7b"
- "\x90\xa5\xba\xcf\xe4\xf9\x0e\x23"
- "\x38\x4d\x62\x77\x8c\xa1\xb6\xcb"
- "\xe0\xf5\x0a\x1f\x34\x49\x5e\x73"
- "\x88\x9d\xb2\xc7\xdc\xf1\x06\x1b"
- "\x30\x45\x5a\x6f\x84\x99\xae\xc3"
- "\xd8\xed\x02\x17\x2c\x41\x56\x6b"
- "\x80\x95\xaa\xbf\xd4\xe9\xfe\x13"
- "\x28\x3d\x52\x67\x7c\x91\xa6\xbb"
- "\xd0\xe5\xfa\x0f\x24\x39\x4e\x63"
- "\x78\x8d\xa2\xb7\xcc\xe1\xf6\x0b"
- "\x20\x35\x4a\x5f\x74\x89\x9e\xb3"
- "\xc8\xdd\xf2\x07\x1c\x31\x46\x5b"
- "\x70\x85\x9a\xaf\xc4\xd9\xee\x03"
- "\x18\x2d\x42\x57\x6c\x81\x96\xab"
- "\xc0\xd5\xea\xff\x14\x29\x3e\x53"
- "\x68\x7d\x92\xa7\xbc\xd1\xe6\xfb"
- "\x10\x25\x3a\x4f\x64\x79\x8e\xa3"
- "\xb8\xcd\xe2\xf7\x0c\x21\x36\x4b"
- "\x60\x75\x8a\x9f\xb4\xc9\xde\xf3"
- "\x08\x1d\x32\x47\x5c\x71\x86\x9b"
- "\xb0\xc5\xda\xef\x04\x19\x2e\x43"
- "\x58\x6d\x82\x97\xac\xc1\xd6\xeb"
- "\x00\x17\x2e\x45\x5c\x73\x8a\xa1"
- "\xb8\xcf\xe6\xfd\x14\x2b\x42\x59"
- "\x70\x87\x9e\xb5\xcc\xe3\xfa\x11"
- "\x28\x3f\x56\x6d\x84\x9b\xb2\xc9"
- "\xe0\xf7\x0e\x25\x3c\x53\x6a\x81"
- "\x98\xaf\xc6\xdd\xf4\x0b\x22\x39"
- "\x50\x67\x7e\x95\xac\xc3\xda\xf1"
- "\x08\x1f\x36\x4d\x64\x7b\x92\xa9"
- "\xc0\xd7\xee\x05\x1c\x33\x4a\x61"
- "\x78\x8f\xa6\xbd\xd4\xeb\x02\x19"
- "\x30\x47\x5e\x75\x8c\xa3\xba\xd1"
- "\xe8\xff\x16\x2d\x44\x5b\x72\x89"
- "\xa0\xb7\xce\xe5\xfc\x13\x2a\x41"
- "\x58\x6f\x86\x9d\xb4\xcb\xe2\xf9"
- "\x10\x27\x3e\x55\x6c\x83\x9a\xb1"
- "\xc8\xdf\xf6\x0d\x24\x3b\x52\x69"
- "\x80\x97\xae\xc5\xdc\xf3\x0a\x21"
- "\x38\x4f\x66\x7d\x94\xab\xc2\xd9"
- "\xf0\x07\x1e\x35\x4c\x63\x7a\x91"
- "\xa8\xbf\xd6\xed\x04\x1b\x32\x49"
- "\x60\x77\x8e\xa5\xbc\xd3\xea\x01"
- "\x18\x2f\x46\x5d\x74\x8b\xa2\xb9"
- "\xd0\xe7\xfe\x15\x2c\x43\x5a\x71"
- "\x88\x9f\xb6\xcd\xe4\xfb\x12\x29"
- "\x40\x57\x6e\x85\x9c\xb3\xca\xe1"
- "\xf8\x0f\x26\x3d\x54\x6b\x82\x99"
- "\xb0\xc7\xde\xf5\x0c\x23\x3a\x51"
- "\x68\x7f\x96\xad\xc4\xdb\xf2\x09"
- "\x20\x37\x4e\x65\x7c\x93\xaa\xc1"
- "\xd8\xef\x06\x1d\x34\x4b\x62\x79"
- "\x90\xa7\xbe\xd5\xec\x03\x1a\x31"
- "\x48\x5f\x76\x8d\xa4\xbb\xd2\xe9"
- "\x00\x19\x32\x4b\x64\x7d\x96\xaf"
- "\xc8\xe1\xfa\x13\x2c\x45\x5e\x77"
- "\x90\xa9\xc2\xdb\xf4\x0d\x26\x3f"
- "\x58\x71\x8a\xa3\xbc\xd5\xee\x07"
- "\x20\x39\x52\x6b\x84\x9d\xb6\xcf"
- "\xe8\x01\x1a\x33\x4c\x65\x7e\x97"
- "\xb0\xc9\xe2\xfb\x14\x2d\x46\x5f"
- "\x78\x91\xaa\xc3\xdc\xf5\x0e\x27"
- "\x40\x59\x72\x8b\xa4\xbd\xd6\xef"
- "\x08\x21\x3a\x53\x6c\x85\x9e\xb7"
- "\xd0\xe9\x02\x1b\x34\x4d\x66\x7f"
- "\x98\xb1\xca\xe3\xfc\x15\x2e\x47"
- "\x60\x79\x92\xab\xc4\xdd\xf6\x0f"
- "\x28\x41\x5a\x73\x8c\xa5\xbe\xd7"
- "\xf0\x09\x22\x3b\x54\x6d\x86\x9f"
- "\xb8\xd1\xea\x03\x1c\x35\x4e\x67"
- "\x80\x99\xb2\xcb\xe4\xfd\x16\x2f"
- "\x48\x61\x7a\x93\xac\xc5\xde\xf7"
- "\x10\x29\x42\x5b\x74\x8d\xa6\xbf"
- "\xd8\xf1\x0a\x23\x3c\x55\x6e\x87"
- "\xa0\xb9\xd2\xeb\x04\x1d\x36\x4f"
- "\x68\x81\x9a\xb3\xcc\xe5\xfe\x17"
- "\x30\x49\x62\x7b\x94\xad\xc6\xdf"
- "\xf8\x11\x2a\x43\x5c\x75\x8e\xa7"
- "\xc0\xd9\xf2\x0b\x24\x3d\x56\x6f"
- "\x88\xa1\xba\xd3\xec\x05\x1e\x37"
- "\x50\x69\x82\x9b\xb4\xcd\xe6\xff"
- "\x18\x31\x4a\x63\x7c\x95\xae\xc7"
- "\xe0\xf9\x12\x2b\x44\x5d\x76\x8f"
- "\xa8\xc1\xda\xf3\x0c\x25\x3e\x57"
- "\x70\x89\xa2\xbb\xd4\xed\x06\x1f"
- "\x38\x51\x6a\x83\x9c\xb5\xce\xe7"
- "\x00\x1b\x36\x51\x6c\x87\xa2\xbd"
- "\xd8\xf3\x0e\x29\x44\x5f\x7a\x95"
- "\xb0\xcb\xe6\x01\x1c\x37\x52\x6d"
- "\x88\xa3\xbe\xd9\xf4\x0f\x2a\x45"
- "\x60\x7b\x96\xb1\xcc\xe7\x02\x1d"
- "\x38\x53\x6e\x89\xa4\xbf\xda\xf5"
- "\x10\x2b\x46\x61\x7c\x97\xb2\xcd"
- "\xe8\x03\x1e\x39\x54\x6f\x8a\xa5"
- "\xc0\xdb\xf6\x11\x2c\x47\x62\x7d"
- "\x98\xb3\xce\xe9\x04\x1f\x3a\x55"
- "\x70\x8b\xa6\xc1\xdc\xf7\x12\x2d"
- "\x48\x63\x7e\x99\xb4\xcf\xea\x05"
- "\x20\x3b\x56\x71\x8c\xa7\xc2\xdd"
- "\xf8\x13\x2e\x49\x64\x7f\x9a\xb5"
- "\xd0\xeb\x06\x21\x3c\x57\x72\x8d"
- "\xa8\xc3\xde\xf9\x14\x2f\x4a\x65"
- "\x80\x9b\xb6\xd1\xec\x07\x22\x3d"
- "\x58\x73\x8e\xa9\xc4\xdf\xfa\x15"
- "\x30\x4b\x66\x81\x9c\xb7\xd2\xed"
- "\x08\x23\x3e\x59\x74\x8f\xaa\xc5"
- "\xe0\xfb\x16\x31\x4c\x67\x82\x9d"
- "\xb8\xd3\xee\x09\x24\x3f\x5a\x75"
- "\x90\xab\xc6\xe1\xfc\x17\x32\x4d"
- "\x68\x83\x9e\xb9\xd4\xef\x0a\x25"
- "\x40\x5b\x76\x91\xac\xc7\xe2\xfd"
- "\x18\x33\x4e\x69\x84\x9f\xba\xd5"
- "\xf0\x0b\x26\x41\x5c\x77\x92\xad"
- "\xc8\xe3\xfe\x19\x34\x4f\x6a\x85"
- "\xa0\xbb\xd6\xf1\x0c\x27\x42\x5d"
- "\x78\x93\xae\xc9\xe4\xff\x1a\x35"
- "\x50\x6b\x86\xa1\xbc\xd7\xf2\x0d"
- "\x28\x43\x5e\x79\x94\xaf\xca\xe5"
- "\x00\x1d\x3a\x57\x74\x91\xae\xcb"
- "\xe8\x05\x22\x3f\x5c\x79\x96\xb3"
- "\xd0\xed\x0a\x27\x44\x61\x7e\x9b"
- "\xb8\xd5\xf2\x0f\x2c\x49\x66\x83"
- "\xa0\xbd\xda\xf7\x14\x31\x4e\x6b"
- "\x88\xa5\xc2\xdf\xfc\x19\x36\x53"
- "\x70\x8d\xaa\xc7\xe4\x01\x1e\x3b"
- "\x58\x75\x92\xaf\xcc\xe9\x06\x23"
- "\x40\x5d\x7a\x97\xb4\xd1\xee\x0b"
- "\x28\x45\x62\x7f\x9c\xb9\xd6\xf3"
- "\x10\x2d\x4a\x67\x84\xa1\xbe\xdb"
- "\xf8\x15\x32\x4f\x6c\x89\xa6\xc3"
- "\xe0\xfd\x1a\x37\x54\x71\x8e\xab"
- "\xc8\xe5\x02\x1f\x3c\x59\x76\x93"
- "\xb0\xcd\xea\x07\x24\x41\x5e\x7b"
- "\x98\xb5\xd2\xef\x0c\x29\x46\x63"
- "\x80\x9d\xba\xd7\xf4\x11\x2e\x4b"
- "\x68\x85\xa2\xbf\xdc\xf9\x16\x33"
- "\x50\x6d\x8a\xa7\xc4\xe1\xfe\x1b"
- "\x38\x55\x72\x8f\xac\xc9\xe6\x03"
- "\x20\x3d\x5a\x77\x94\xb1\xce\xeb"
- "\x08\x25\x42\x5f\x7c\x99\xb6\xd3"
- "\xf0\x0d\x2a\x47\x64\x81\x9e\xbb"
- "\xd8\xf5\x12\x2f\x4c\x69\x86\xa3"
- "\xc0\xdd\xfa\x17\x34\x51\x6e\x8b"
- "\xa8\xc5\xe2\xff\x1c\x39\x56\x73"
- "\x90\xad\xca\xe7\x04\x21\x3e\x5b"
- "\x78\x95\xb2\xcf\xec\x09\x26\x43"
- "\x60\x7d\x9a\xb7\xd4\xf1\x0e\x2b"
- "\x48\x65\x82\x9f\xbc\xd9\xf6\x13"
- "\x30\x4d\x6a\x87\xa4\xc1\xde\xfb"
- "\x18\x35\x52\x6f\x8c\xa9\xc6\xe3"
- "\x00\x1f\x3e\x5d\x7c\x9b\xba\xd9"
- "\xf8\x17\x36\x55\x74\x93\xb2\xd1"
- "\xf0\x0f\x2e\x4d\x6c\x8b\xaa\xc9"
- "\xe8\x07\x26\x45\x64\x83\xa2\xc1"
- "\xe0\xff\x1e\x3d\x5c\x7b\x9a\xb9"
- "\xd8\xf7\x16\x35\x54\x73\x92\xb1"
- "\xd0\xef\x0e\x2d\x4c\x6b\x8a\xa9"
- "\xc8\xe7\x06\x25\x44\x63\x82\xa1"
- "\xc0\xdf\xfe\x1d\x3c\x5b\x7a\x99"
- "\xb8\xd7\xf6\x15\x34\x53\x72\x91"
- "\xb0\xcf\xee\x0d\x2c\x4b\x6a\x89"
- "\xa8\xc7\xe6\x05\x24\x43\x62\x81"
- "\xa0\xbf\xde\xfd\x1c\x3b\x5a\x79"
- "\x98\xb7\xd6\xf5\x14\x33\x52\x71"
- "\x90\xaf\xce\xed\x0c\x2b\x4a\x69"
- "\x88\xa7\xc6\xe5\x04\x23\x42\x61"
- "\x80\x9f\xbe\xdd\xfc\x1b\x3a\x59"
- "\x78\x97\xb6\xd5\xf4\x13\x32\x51"
- "\x70\x8f\xae\xcd\xec\x0b\x2a\x49"
- "\x68\x87\xa6\xc5\xe4\x03\x22\x41"
- "\x60\x7f\x9e\xbd\xdc\xfb\x1a\x39"
- "\x58\x77\x96\xb5\xd4\xf3\x12\x31"
- "\x50\x6f\x8e\xad\xcc\xeb\x0a\x29"
- "\x48\x67\x86\xa5\xc4\xe3\x02\x21"
- "\x40\x5f\x7e\x9d\xbc\xdb\xfa\x19"
- "\x38\x57\x76\x95\xb4\xd3\xf2\x11"
- "\x30\x4f\x6e\x8d\xac\xcb\xea\x09"
- "\x28\x47\x66\x85\xa4\xc3\xe2\x01"
- "\x20\x3f\x5e\x7d\x9c\xbb\xda\xf9"
- "\x18\x37\x56\x75\x94\xb3\xd2\xf1"
- "\x10\x2f\x4e\x6d\x8c\xab\xca\xe9"
- "\x08\x27\x46\x65\x84\xa3\xc2\xe1"
- "\x00\x21\x42\x63",
- .ctext =
- "\xb5\x81\xf5\x64\x18\x73\xe3\xf0"
- "\x4c\x13\xf2\x77\x18\x60\x65\x5e"
- "\x29\x01\xce\x98\x55\x53\xf9\x0c"
- "\x2a\x08\xd5\x09\xb3\x57\x55\x56"
- "\xc5\xe9\x56\x90\xcb\x6a\xa3\xc0"
- "\xff\xc4\x79\xb4\xd2\x97\x5d\xc4"
- "\x43\xd1\xfe\x94\x7b\x88\x06\x5a"
- "\xb2\x9e\x2c\xfc\x44\x03\xb7\x90"
- "\xa0\xc1\xba\x6a\x33\xb8\xc7\xb2"
- "\x9d\xe1\x12\x4f\xc0\x64\xd4\x01"
- "\xfe\x8c\x7a\x66\xf7\xe6\x5a\x91"
- "\xbb\xde\x56\x86\xab\x65\x21\x30"
- "\x00\x84\x65\x24\xa5\x7d\x85\xb4"
- "\xe3\x17\xed\x3a\xb7\x6f\xb4\x0b"
- "\x0b\xaf\x15\xae\x5a\x8f\xf2\x0c"
- "\x2f\x27\xf4\x09\xd8\xd2\x96\xb7"
- "\x71\xf2\xc5\x99\x4d\x7e\x7f\x75"
- "\x77\x89\x30\x8b\x59\xdb\xa2\xb2"
- "\xa0\xf3\x19\x39\x2b\xc5\x7e\x3f"
- "\x4f\xd9\xd3\x56\x28\x97\x44\xdc"
- "\xc0\x8b\x77\x24\xd9\x52\xe7\xc5"
- "\xaf\xf6\x7d\x59\xb2\x44\x05\x1d"
- "\xb1\xb0\x11\xa5\x0f\xec\x33\xe1"
- "\x6d\x1b\x4e\x1f\xff\x57\x91\xb4"
- "\x5b\x9a\x96\xc5\x53\xbc\xae\x20"
- "\x3c\xbb\x14\xe2\xe8\x22\x33\xc1"
- "\x5e\x76\x9e\x46\x99\xf6\x2a\x15"
- "\xc6\x97\x02\xa0\x66\x43\xd1\xa6"
- "\x31\xa6\x9f\xfb\xf4\xd3\x69\xe5"
- "\xcd\x76\x95\xb8\x7a\x82\x7f\x21"
- "\x45\xff\x3f\xce\x55\xf6\x95\x10"
- "\x08\x77\x10\x43\xc6\xf3\x09\xe5"
- "\x68\xe7\x3c\xad\x00\x52\x45\x0d"
- "\xfe\x2d\xc6\xc2\x94\x8c\x12\x1d"
- "\xe6\x25\xae\x98\x12\x8e\x19\x9c"
- "\x81\x68\xb1\x11\xf6\x69\xda\xe3"
- "\x62\x08\x18\x7a\x25\x49\x28\xac"
- "\xba\x71\x12\x0b\xe4\xa2\xe5\xc7"
- "\x5d\x8e\xec\x49\x40\x21\xbf\x5a"
- "\x98\xf3\x02\x68\x55\x03\x7f\x8a"
- "\xe5\x94\x0c\x32\x5c\x07\x82\x63"
- "\xaf\x6f\x91\x40\x84\x8e\x52\x25"
- "\xd0\xb0\x29\x53\x05\xe2\x50\x7a"
- "\x34\xeb\xc9\x46\x20\xa8\x3d\xde"
- "\x7f\x16\x5f\x36\xc5\x2e\xdc\xd1"
- "\x15\x47\xc7\x50\x40\x6d\x91\xc5"
- "\xe7\x93\x95\x1a\xd3\x57\xbc\x52"
- "\x33\xee\x14\x19\x22\x52\x89\xa7"
- "\x4a\x25\x56\x77\x4b\xca\xcf\x0a"
- "\xe1\xf5\x35\x85\x30\x7e\x59\x4a"
- "\xbd\x14\x5b\xdf\xe3\x46\xcb\xac"
- "\x1f\x6c\x96\x0e\xf4\x81\xd1\x99"
- "\xca\x88\x63\x3d\x02\x58\x6b\xa9"
- "\xe5\x9f\xb3\x00\xb2\x54\xc6\x74"
- "\x1c\xbf\x46\xab\x97\xcc\xf8\x54"
- "\x04\x07\x08\x52\xe6\xc0\xda\x93"
- "\x74\x7d\x93\x99\x5d\x78\x68\xa6"
- "\x2e\x6b\xd3\x6a\x69\xcc\x12\x6b"
- "\xd4\xc7\xa5\xc6\xe7\xf6\x03\x04"
- "\x5d\xcd\x61\x5e\x17\x40\xdc\xd1"
- "\x5c\xf5\x08\xdf\x5c\x90\x85\xa4"
- "\xaf\xf6\x78\xbb\x0d\xf1\xf4\xa4"
- "\x54\x26\x72\x9e\x61\xfa\x86\xcf"
- "\xe8\x9e\xa1\xe0\xc7\x48\x23\xae"
- "\x5a\x90\xae\x75\x0a\x74\x18\x89"
- "\x05\xb1\x92\xb2\x7f\xd0\x1b\xa6"
- "\x62\x07\x25\x01\xc7\xc2\x4f\xf9"
- "\xe8\xfe\x63\x95\x80\x07\xb4\x26"
- "\xcc\xd1\x26\xb6\xc4\x3f\x9e\xcb"
- "\x8e\x3b\x2e\x44\x16\xd3\x10\x9a"
- "\x95\x08\xeb\xc8\xcb\xeb\xbf\x6f"
- "\x0b\xcd\x1f\xc8\xca\x86\xaa\xec"
- "\x33\xe6\x69\xf4\x45\x25\x86\x3a"
- "\x22\x94\x4f\x00\x23\x6a\x44\xc2"
- "\x49\x97\x33\xab\x36\x14\x0a\x70"
- "\x24\xc3\xbe\x04\x3b\x79\xa0\xf9"
- "\xb8\xe7\x76\x29\x22\x83\xd7\xf2"
- "\x94\xf4\x41\x49\xba\x5f\x7b\x07"
- "\xb5\xfb\xdb\x03\x1a\x9f\xb6\x4c"
- "\xc2\x2e\x37\x40\x49\xc3\x38\x16"
- "\xe2\x4f\x77\x82\xb0\x68\x4c\x71"
- "\x1d\x57\x61\x9c\xd9\x4e\x54\x99"
- "\x47\x13\x28\x73\x3c\xbb\x00\x90"
- "\xf3\x4d\xc9\x0e\xfd\xe7\xb1\x71"
- "\xd3\x15\x79\xbf\xcc\x26\x2f\xbd"
- "\xad\x6c\x50\x69\x6c\x3e\x6d\x80"
- "\x9a\xea\x78\xaf\x19\xb2\x0d\x4d"
- "\xad\x04\x07\xae\x22\x90\x4a\x93"
- "\x32\x0e\x36\x9b\x1b\x46\xba\x3b"
- "\xb4\xac\xc6\xd1\xa2\x31\x53\x3b"
- "\x2a\x3d\x45\xfe\x03\x61\x10\x85"
- "\x17\x69\xa6\x78\xcc\x6c\x87\x49"
- "\x53\xf9\x80\x10\xde\x80\xa2\x41"
- "\x6a\xc3\x32\x02\xad\x6d\x3c\x56"
- "\x00\x71\x51\x06\xa7\xbd\xfb\xef"
- "\x3c\xb5\x9f\xfc\x48\x7d\x53\x7c"
- "\x66\xb0\x49\x23\xc4\x47\x10\x0e"
- "\xe5\x6c\x74\x13\xe6\xc5\x3f\xaa"
- "\xde\xff\x07\x44\xdd\x56\x1b\xad"
- "\x09\x77\xfb\x5b\x12\xb8\x0d\x38"
- "\x17\x37\x35\x7b\x9b\xbc\xfe\xd4"
- "\x7e\x8b\xda\x7e\x5b\x04\xa7\x22"
- "\xa7\x31\xa1\x20\x86\xc7\x1b\x99"
- "\xdb\xd1\x89\xf4\x94\xa3\x53\x69"
- "\x8d\xe7\xe8\x74\x11\x8d\x74\xd6"
- "\x07\x37\x91\x9f\xfd\x67\x50\x3a"
- "\xc9\xe1\xf4\x36\xd5\xa0\x47\xd1"
- "\xf9\xe5\x39\xa3\x31\xac\x07\x36"
- "\x23\xf8\x66\x18\x14\x28\x34\x0f"
- "\xb8\xd0\xe7\x29\xb3\x04\x4b\x55"
- "\x01\x41\xb2\x75\x8d\xcb\x96\x85"
- "\x3a\xfb\xab\x2b\x9e\xfa\x58\x20"
- "\x44\x1f\xc0\x14\x22\x75\x61\xe8"
- "\xaa\x19\xcf\xf1\x82\x56\xf4\xd7"
- "\x78\x7b\x3d\x5f\xb3\x9e\x0b\x8a"
- "\x57\x50\xdb\x17\x41\x65\x4d\xa3"
- "\x02\xc9\x9c\x9c\x53\xfb\x39\x39"
- "\x9b\x1d\x72\x24\xda\xb7\x39\xbe"
- "\x13\x3b\xfa\x29\xda\x9e\x54\x64"
- "\x6e\xba\xd8\xa1\xcb\xb3\x36\xfa"
- "\xcb\x47\x85\xe9\x61\x38\xbc\xbe"
- "\xc5\x00\x38\x2a\x54\xf7\xc4\xb9"
- "\xb3\xd3\x7b\xa0\xa0\xf8\x72\x7f"
- "\x8c\x8e\x82\x0e\xc6\x1c\x75\x9d"
- "\xca\x8e\x61\x87\xde\xad\x80\xd2"
- "\xf5\xf9\x80\xef\x15\x75\xaf\xf5"
- "\x80\xfb\xff\x6d\x1e\x25\xb7\x40"
- "\x61\x6a\x39\x5a\x6a\xb5\x31\xab"
- "\x97\x8a\x19\x89\x44\x40\xc0\xa6"
- "\xb4\x4e\x30\x32\x7b\x13\xe7\x67"
- "\xa9\x8b\x57\x04\xc2\x01\xa6\xf4"
- "\x28\x99\xad\x2c\x76\xa3\x78\xc2"
- "\x4a\xe6\xca\x5c\x50\x6a\xc1\xb0"
- "\x62\x4b\x10\x8e\x7c\x17\x43\xb3"
- "\x17\x66\x1c\x3e\x8d\x69\xf0\x5a"
- "\x71\xf5\x97\xdc\xd1\x45\xdd\x28"
- "\xf3\x5d\xdf\x53\x7b\x11\xe5\xbc"
- "\x4c\xdb\x1b\x51\x6b\xe9\xfb\x3d"
- "\xc1\xc3\x2c\xb9\x71\xf5\xb6\xb2"
- "\x13\x36\x79\x80\x53\xe8\xd3\xa6"
- "\x0a\xaf\xfd\x56\x97\xf7\x40\x8e"
- "\x45\xce\xf8\xb0\x9e\x5c\x33\x82"
- "\xb0\x44\x56\xfc\x05\x09\xe9\x2a"
- "\xac\x26\x80\x14\x1d\xc8\x3a\x35"
- "\x4c\x82\x97\xfd\x76\xb7\xa9\x0a"
- "\x35\x58\x79\x8e\x0f\x66\xea\xaf"
- "\x51\x6c\x09\xa9\x6e\x9b\xcb\x9a"
- "\x31\x47\xa0\x2f\x7c\x71\xb4\x4a"
- "\x11\xaa\x8c\x66\xc5\x64\xe6\x3a"
- "\x54\xda\x24\x6a\xc4\x41\x65\x46"
- "\x82\xa0\x0a\x0f\x5f\xfb\x25\xd0"
- "\x2c\x91\xa7\xee\xc4\x81\x07\x86"
- "\x75\x5e\x33\x69\x97\xe4\x2c\xa8"
- "\x9d\x9f\x0b\x6a\xbe\xad\x98\xda"
- "\x6d\x94\x41\xda\x2c\x1e\x89\xc4"
- "\xc2\xaf\x1e\x00\x05\x0b\x83\x60"
- "\xbd\x43\xea\x15\x23\x7f\xb9\xac"
- "\xee\x4f\x2c\xaf\x2a\xf3\xdf\xd0"
- "\xf3\x19\x31\xbb\x4a\x74\x84\x17"
- "\x52\x32\x2c\x7d\x61\xe4\xcb\xeb"
- "\x80\x38\x15\x52\xcb\x6f\xea\xe5"
- "\x73\x9c\xd9\x24\x69\xc6\x95\x32"
- "\x21\xc8\x11\xe4\xdc\x36\xd7\x93"
- "\x38\x66\xfb\xb2\x7f\x3a\xb9\xaf"
- "\x31\xdd\x93\x75\x78\x8a\x2c\x94"
- "\x87\x1a\x58\xec\x9e\x7d\x4d\xba"
- "\xe1\xe5\x4d\xfc\xbc\xa4\x2a\x14"
- "\xef\xcc\xa7\xec\xab\x43\x09\x18"
- "\xd3\xab\x68\xd1\x07\x99\x44\x47"
- "\xd6\x83\x85\x3b\x30\xea\xa9\x6b"
- "\x63\xea\xc4\x07\xfb\x43\x2f\xa4"
- "\xaa\xb0\xab\x03\x89\xce\x3f\x8c"
- "\x02\x7c\x86\x54\xbc\x88\xaf\x75"
- "\xd2\xdc\x63\x17\xd3\x26\xf6\x96"
- "\xa9\x3c\xf1\x61\x8c\x11\x18\xcc"
- "\xd6\xea\x5b\xe2\xcd\xf0\xf1\xb2"
- "\xe5\x35\x90\x1f\x85\x4c\x76\x5b"
- "\x66\xce\x44\xa4\x32\x9f\xe6\x7b"
- "\x71\x6e\x9f\x58\x15\x67\x72\x87"
- "\x64\x8e\x3a\x44\x45\xd4\x76\xfa"
- "\xc2\xf6\xef\x85\x05\x18\x7a\x9b"
- "\xba\x41\x54\xac\xf0\xfc\x59\x12"
- "\x3f\xdf\xa0\xe5\x8a\x65\xfd\x3a"
- "\x62\x8d\x83\x2c\x03\xbe\x05\x76"
- "\x2e\x53\x49\x97\x94\x33\xae\x40"
- "\x81\x15\xdb\x6e\xad\xaa\xf5\x4b"
- "\xe3\x98\x70\xdf\xe0\x7c\xcd\xdb"
- "\x02\xd4\x7d\x2f\xc1\xe6\xb4\xf3"
- "\xd7\x0d\x7a\xd9\x23\x9e\x87\x2d"
- "\xce\x87\xad\xcc\x72\x05\x00\x29"
- "\xdc\x73\x7f\x64\xc1\x15\x0e\xc2"
- "\xdf\xa7\x5f\xeb\x41\xa1\xcd\xef"
- "\x5c\x50\x79\x2a\x56\x56\x71\x8c"
- "\xac\xc0\x79\x50\x69\xca\x59\x32"
- "\x65\xf2\x54\xe4\x52\x38\x76\xd1"
- "\x5e\xde\x26\x9e\xfb\x75\x2e\x11"
- "\xb5\x10\xf4\x17\x73\xf5\x89\xc7"
- "\x4f\x43\x5c\x8e\x7c\xb9\x05\x52"
- "\x24\x40\x99\xfe\x9b\x85\x0b\x6c"
- "\x22\x3e\x8b\xae\x86\xa1\xd2\x79"
- "\x05\x68\x6b\xab\xe3\x41\x49\xed"
- "\x15\xa1\x8d\x40\x2d\x61\xdf\x1a"
- "\x59\xc9\x26\x8b\xef\x30\x4c\x88"
- "\x4b\x10\xf8\x8d\xa6\x92\x9f\x4b"
- "\xf3\xc4\x53\x0b\x89\x5d\x28\x92"
- "\xcf\x78\xb2\xc0\x5d\xed\x7e\xfc"
- "\xc0\x12\x23\x5f\x5a\x78\x86\x43"
- "\x6e\x27\xf7\x5a\xa7\x6a\xed\x19"
- "\x04\xf0\xb3\x12\xd1\xbd\x0e\x89"
- "\x6e\xbc\x96\xa8\xd8\x49\x39\x9f"
- "\x7e\x67\xf0\x2e\x3e\x01\xa9\xba"
- "\xec\x8b\x62\x8e\xcb\x4a\x70\x43"
- "\xc7\xc2\xc4\xca\x82\x03\x73\xe9"
- "\x11\xdf\xcf\x54\xea\xc9\xb0\x95"
- "\x51\xc0\x13\x3d\x92\x05\xfa\xf4"
- "\xa9\x34\xc8\xce\x6c\x3d\x54\xcc"
- "\xc4\xaf\xf1\xdc\x11\x44\x26\xa2"
- "\xaf\xf1\x85\x75\x7d\x03\x61\x68"
- "\x4e\x78\xc6\x92\x7d\x86\x7d\x77"
- "\xdc\x71\x72\xdb\xc6\xae\xa1\xcb"
- "\x70\x9a\x0b\x19\xbe\x4a\x6c\x2a"
- "\xe2\xba\x6c\x64\x9a\x13\x28\xdf"
- "\x85\x75\xe6\x43\xf6\x87\x08\x68"
- "\x6e\xba\x6e\x79\x9f\x04\xbc\x23"
- "\x50\xf6\x33\x5c\x1f\x24\x25\xbe"
- "\x33\x47\x80\x45\x56\xa3\xa7\xd7"
- "\x7a\xb1\x34\x0b\x90\x3c\x9c\xad"
- "\x44\x5f\x9e\x0e\x9d\xd4\xbd\x93"
- "\x5e\xfa\x3c\xe0\xb0\xd9\xed\xf3"
- "\xd6\x2e\xff\x24\xd8\x71\x6c\xed"
- "\xaf\x55\xeb\x22\xac\x93\x68\x32"
- "\x05\x5b\x47\xdd\xc6\x4a\xcb\xc7"
- "\x10\xe1\x3c\x92\x1a\xf3\x23\x78"
- "\x2b\xa1\xd2\x80\xf4\x12\xb1\x20"
- "\x8f\xff\x26\x35\xdd\xfb\xc7\x4e"
- "\x78\xf1\x2d\x50\x12\x77\xa8\x60"
- "\x7c\x0f\xf5\x16\x2f\x63\x70\x2a"
- "\xc0\x96\x80\x4e\x0a\xb4\x93\x35"
- "\x5d\x1d\x3f\x56\xf7\x2f\xbb\x90"
- "\x11\x16\x8f\xa2\xec\x47\xbe\xac"
- "\x56\x01\x26\x56\xb1\x8c\xb2\x10"
- "\xf9\x1a\xca\xf5\xd1\xb7\x39\x20"
- "\x63\xf1\x69\x20\x4f\x13\x12\x1f"
- "\x5b\x65\xfc\x98\xf7\xc4\x7a\xbe"
- "\xf7\x26\x4d\x2b\x84\x7b\x42\xad"
- "\xd8\x7a\x0a\xb4\xd8\x74\xbf\xc1"
- "\xf0\x6e\xb4\x29\xa3\xbb\xca\x46"
- "\x67\x70\x6a\x2d\xce\x0e\xa2\x8a"
- "\xa9\x87\xbf\x05\xc4\xc1\x04\xa3"
- "\xab\xd4\x45\x43\x8c\xb6\x02\xb0"
- "\x41\xc8\xfc\x44\x3d\x59\xaa\x2e"
- "\x44\x21\x2a\x8d\x88\x9d\x57\xf4"
- "\xa0\x02\x77\xb8\xa6\xa0\xe6\x75"
- "\x5c\x82\x65\x3e\x03\x5c\x29\x8f"
- "\x38\x55\xab\x33\x26\xef\x9f\x43"
- "\x52\xfd\x68\xaf\x36\xb4\xbb\x9a"
- "\x58\x09\x09\x1b\xc3\x65\x46\x46"
- "\x1d\xa7\x94\x18\x23\x50\x2c\xca"
- "\x2c\x55\x19\x97\x01\x9d\x93\x3b"
- "\x63\x86\xf2\x03\x67\x45\xd2\x72"
- "\x28\x52\x6c\xf4\xe3\x1c\xb5\x11"
- "\x13\xf1\xeb\x21\xc7\xd9\x56\x82"
- "\x2b\x82\x39\xbd\x69\x54\xed\x62"
- "\xc3\xe2\xde\x73\xd4\x6a\x12\xae"
- "\x13\x21\x7f\x4b\x5b\xfc\xbf\xe8"
- "\x2b\xbe\x56\xba\x68\x8b\x9a\xb1"
- "\x6e\xfa\xbf\x7e\x5a\x4b\xf1\xac"
- "\x98\x65\x85\xd1\x93\x53\xd3\x7b"
- "\x09\xdd\x4b\x10\x6d\x84\xb0\x13"
- "\x65\xbd\xcf\x52\x09\xc4\x85\xe2"
- "\x84\x74\x15\x65\xb7\xf7\x51\xaf"
- "\x55\xad\xa4\xd1\x22\x54\x70\x94"
- "\xa0\x1c\x90\x41\xfd\x99\xd7\x5a"
- "\x31\xef\xaa\x25\xd0\x7f\x4f\xea"
- "\x1d\x55\x42\xe5\x49\xb0\xd0\x46"
- "\x62\x36\x43\xb2\x82\x15\x75\x50"
- "\xa4\x72\xeb\x54\x27\x1f\x8a\xe4"
- "\x7d\xe9\x66\xc5\xf1\x53\xa4\xd1"
- "\x0c\xeb\xb8\xf8\xbc\xd4\xe2\xe7"
- "\xe1\xf8\x4b\xcb\xa9\xa1\xaf\x15"
- "\x83\xcb\x72\xd0\x33\x79\x00\x2d"
- "\x9f\xd7\xf1\x2e\x1e\x10\xe4\x45"
- "\xc0\x75\x3a\x39\xea\x68\xf7\x5d"
- "\x1b\x73\x8f\xe9\x8e\x0f\x72\x47"
- "\xae\x35\x0a\x31\x7a\x14\x4d\x4a"
- "\x6f\x47\xf7\x7e\x91\x6e\x74\x8b"
- "\x26\x47\xf9\xc3\xf9\xde\x70\xf5"
- "\x61\xab\xa9\x27\x9f\x82\xe4\x9c"
- "\x89\x91\x3f\x2e\x6a\xfd\xb5\x49"
- "\xe9\xfd\x59\x14\x36\x49\x40\x6d"
- "\x32\xd8\x85\x42\xf3\xa5\xdf\x0c"
- "\xa8\x27\xd7\x54\xe2\x63\x2f\xf2"
- "\x7e\x8b\x8b\xe7\xf1\x9a\x95\x35"
- "\x43\xdc\x3a\xe4\xb6\xf4\xd0\xdf"
- "\x9c\xcb\x94\xf3\x21\xa0\x77\x50"
- "\xe2\xc6\xc4\xc6\x5f\x09\x64\x5b"
- "\x92\x90\xd8\xe1\xd1\xed\x4b\x42"
- "\xd7\x37\xaf\x65\x3d\x11\x39\xb6"
- "\x24\x8a\x60\xae\xd6\x1e\xbf\x0e"
- "\x0d\xd7\xdc\x96\x0e\x65\x75\x4e"
- "\x29\x06\x9d\xa4\x51\x3a\x10\x63"
- "\x8f\x17\x07\xd5\x8e\x3c\xf4\x28"
- "\x00\x5a\x5b\x05\x19\xd8\xc0\x6c"
- "\xe5\x15\xe4\x9c\x9d\x71\x9d\x5e"
- "\x94\x29\x1a\xa7\x80\xfa\x0e\x33"
- "\x03\xdd\xb7\x3e\x9a\xa9\x26\x18"
- "\x37\xa9\x64\x08\x4d\x94\x5a\x88"
- "\xca\x35\xce\x81\x02\xe3\x1f\x1b"
- "\x89\x1a\x77\x85\xe3\x41\x6d\x32"
- "\x42\x19\x23\x7d\xc8\x73\xee\x25"
- "\x85\x0d\xf8\x31\x25\x79\x1b\x6f"
- "\x79\x25\xd2\xd8\xd4\x23\xfd\xf7"
- "\x82\x36\x6a\x0c\x46\x22\x15\xe9"
- "\xff\x72\x41\x91\x91\x7d\x3a\xb7"
- "\xdd\x65\x99\x70\xf6\x8d\x84\xf8"
- "\x67\x15\x20\x11\xd6\xb2\x55\x7b"
- "\xdb\x87\xee\xef\x55\x89\x2a\x59"
- "\x2b\x07\x8f\x43\x8a\x59\x3c\x01"
- "\x8b\x65\x54\xa1\x66\xd5\x38\xbd"
- "\xc6\x30\xa9\xcc\x49\xb6\xa8\x1b"
- "\xb8\xc0\x0e\xe3\x45\x28\xe2\xff"
- "\x41\x9f\x7e\x7c\xd1\xae\x9e\x25"
- "\x3f\x4c\x7c\x7c\xf4\xa8\x26\x4d"
- "\x5c\xfd\x4b\x27\x18\xf9\x61\x76"
- "\x48\xba\x0c\x6b\xa9\x4d\xfc\xf5"
- "\x3b\x35\x7e\x2f\x4a\xa9\xc2\x9a"
- "\xae\xab\x86\x09\x89\xc9\xc2\x40"
- "\x39\x2c\x81\xb3\xb8\x17\x67\xc2"
- "\x0d\x32\x4a\x3a\x67\x81\xd7\x1a"
- "\x34\x52\xc5\xdb\x0a\xf5\x63\x39"
- "\xea\x1f\xe1\x7c\xa1\x9e\xc1\x35"
- "\xe3\xb1\x18\x45\x67\xf9\x22\x38"
- "\x95\xd9\x34\x34\x86\xc6\x41\x94"
- "\x15\xf9\x5b\x41\xa6\x87\x8b\xf8"
- "\xd5\xe1\x1b\xe2\x5b\xf3\x86\x10"
- "\xff\xe6\xae\x69\x76\xbc\x0d\xb4"
- "\x09\x90\x0c\xa2\x65\x0c\xad\x74"
- "\xf5\xd7\xff\xda\xc1\xce\x85\xbe"
- "\x00\xa7\xff\x4d\x2f\x65\xd3\x8c"
- "\x86\x2d\x05\xe8\xed\x3e\x6b\x8b"
- "\x0f\x3d\x83\x8c\xf1\x1d\x5b\x96"
- "\x2e\xb1\x9c\xc2\x98\xe1\x70\xb9"
- "\xba\x5c\x8a\x43\xd6\x34\xa7\x2d"
- "\xc9\x92\xae\xf2\xa5\x7b\x05\x49"
- "\xa7\x33\x34\x86\xca\xe4\x96\x23"
- "\x76\x5b\xf2\xc6\xf1\x51\x28\x42"
- "\x7b\xcc\x76\x8f\xfa\xa2\xad\x31"
- "\xd4\xd6\x7a\x6d\x25\x25\x54\xe4"
- "\x3f\x50\x59\xe1\x5c\x05\xb7\x27"
- "\x48\xbf\x07\xec\x1b\x13\xbe\x2b"
- "\xa1\x57\x2b\xd5\xab\xd7\xd0\x4c"
- "\x1e\xcb\x71\x9b\xc5\x90\x85\xd3"
- "\xde\x59\xec\x71\xeb\x89\xbb\xd0"
- "\x09\x50\xe1\x16\x3f\xfd\x1c\x34"
- "\xc3\x1c\xa1\x10\x77\x53\x98\xef"
- "\xf2\xfd\xa5\x01\x59\xc2\x9b\x26"
- "\xc7\x42\xd9\x49\xda\x58\x2b\x6e"
- "\x9f\x53\x19\x76\x7e\xd9\xc9\x0e"
- "\x68\xc8\x7f\x51\x22\x42\xef\x49"
- "\xa4\x55\xb6\x36\xac\x09\xc7\x31"
- "\x88\x15\x4b\x2e\x8f\x3a\x08\xf7"
- "\xd8\xf7\xa8\xc5\xa9\x33\xa6\x45"
- "\xe4\xc4\x94\x76\xf3\x0d\x8f\x7e"
- "\xc8\xf6\xbc\x23\x0a\xb6\x4c\xd3"
- "\x6a\xcd\x36\xc2\x90\x5c\x5c\x3c"
- "\x65\x7b\xc2\xd6\xcc\xe6\x0d\x87"
- "\x73\x2e\x71\x79\x16\x06\x63\x28"
- "\x09\x15\xd8\x89\x38\x38\x3d\xb5"
- "\x42\x1c\x08\x24\xf7\x2a\xd2\x9d"
- "\xc8\xca\xef\xf9\x27\xd8\x07\x86"
- "\xf7\x43\x0b\x55\x15\x3f\x9f\x83"
- "\xef\xdc\x49\x9d\x2a\xc1\x54\x62"
- "\xbd\x9b\x66\x55\x9f\xb7\x12\xf3"
- "\x1b\x4d\x9d\x2a\x5c\xed\x87\x75"
- "\x87\x26\xec\x61\x2c\xb4\x0f\x89"
- "\xb0\xfb\x2e\x68\x5d\x15\xc7\x8d"
- "\x2e\xc0\xd9\xec\xaf\x4f\xd2\x25"
- "\x29\xe8\xd2\x26\x2b\x67\xe9\xfc"
- "\x2b\xa8\x67\x96\x12\x1f\x5b\x96"
- "\xc6\x14\x53\xaf\x44\xea\xd6\xe2"
- "\x94\x98\xe4\x12\x93\x4c\x92\xe0"
- "\x18\xa5\x8d\x2d\xe4\x71\x3c\x47"
- "\x4c\xf7\xe6\x47\x9e\xc0\x68\xdf"
- "\xd4\xf5\x5a\x74\xb1\x2b\x29\x03"
- "\x19\x07\xaf\x90\x62\x5c\x68\x98"
- "\x48\x16\x11\x02\x9d\xee\xb4\x9b"
- "\xe5\x42\x7f\x08\xfd\x16\x32\x0b"
- "\xd0\xb3\xfa\x2b\xb7\x99\xf9\x29"
- "\xcd\x20\x45\x9f\xb3\x1a\x5d\xa2"
- "\xaf\x4d\xe0\xbd\x42\x0d\xbc\x74"
- "\x99\x9c\x8e\x53\x1a\xb4\x3e\xbd"
- "\xa2\x9a\x2d\xf7\xf8\x39\x0f\x67"
- "\x63\xfc\x6b\xc0\xaf\xb3\x4b\x4f"
- "\x55\xc4\xcf\xa7\xc8\x04\x11\x3e"
- "\x14\x32\xbb\x1b\x38\x77\xd6\x7f"
- "\x54\x4c\xdf\x75\xf3\x07\x2d\x33"
- "\x9b\xa8\x20\xe1\x7b\x12\xb5\xf3"
- "\xef\x2f\xce\x72\xe5\x24\x60\xc1"
- "\x30\xe2\xab\xa1\x8e\x11\x09\xa8"
- "\x21\x33\x44\xfe\x7f\x35\x32\x93"
- "\x39\xa7\xad\x8b\x79\x06\xb2\xcb"
- "\x4e\xa9\x5f\xc7\xba\x74\x29\xec"
- "\x93\xa0\x4e\x54\x93\xc0\xbc\x55"
- "\x64\xf0\x48\xe5\x57\x99\xee\x75"
- "\xd6\x79\x0f\x66\xb7\xc6\x57\x76"
- "\xf7\xb7\xf3\x9c\xc5\x60\xe8\x7f"
- "\x83\x76\xd6\x0e\xaa\xe6\x90\x39"
- "\x1d\xa6\x32\x6a\x34\xe3\x55\xf8"
- "\x58\xa0\x58\x7d\x33\xe0\x22\x39"
- "\x44\x64\x87\x86\x5a\x2f\xa7\x7e"
- "\x0f\x38\xea\xb0\x30\xcc\x61\xa5"
- "\x6a\x32\xae\x1e\xf7\xe9\xd0\xa9"
- "\x0c\x32\x4b\xb5\x49\x28\xab\x85"
- "\x2f\x8e\x01\x36\x38\x52\xd0\xba"
- "\xd6\x02\x78\xf8\x0e\x3e\x9c\x8b"
- "\x6b\x45\x99\x3f\x5c\xfe\x58\xf1"
- "\x5c\x94\x04\xe1\xf5\x18\x6d\x51"
- "\xb2\x5d\x18\x20\xb6\xc2\x9a\x42"
- "\x1d\xb3\xab\x3c\xb6\x3a\x13\x03"
- "\xb2\x46\x82\x4f\xfc\x64\xbc\x4f"
- "\xca\xfa\x9c\xc0\xd5\xa7\xbd\x11"
- "\xb7\xe4\x5a\xf6\x6f\x4d\x4d\x54"
- "\xea\xa4\x98\x66\xd4\x22\x3b\xd3"
- "\x8f\x34\x47\xd9\x7c\xf4\x72\x3b"
- "\x4d\x02\x77\xf6\xd6\xdd\x08\x0a"
- "\x81\xe1\x86\x89\x3e\x56\x10\x3c"
- "\xba\xd7\x81\x8c\x08\xbc\x8b\xe2"
- "\x53\xec\xa7\x89\xee\xc8\x56\xb5"
- "\x36\x2c\xb2\x03\xba\x99\xdd\x7c"
- "\x48\xa0\xb0\xbc\x91\x33\xe9\xa8"
- "\xcb\xcd\xcf\x59\x5f\x1f\x15\xe2"
- "\x56\xf5\x4e\x01\x35\x27\x45\x77"
- "\x47\xc8\xbc\xcb\x7e\x39\xc1\x97"
- "\x28\xd3\x84\xfc\x2c\x3e\xc8\xad"
- "\x9c\xf8\x8a\x61\x9c\x28\xaa\xc5"
- "\x99\x20\x43\x85\x9d\xa5\xe2\x8b"
- "\xb8\xae\xeb\xd0\x32\x0d\x52\x78"
- "\x09\x56\x3f\xc7\xd8\x7e\x26\xfc"
- "\x37\xfb\x6f\x04\xfc\xfa\x92\x10"
- "\xac\xf8\x3e\x21\xdc\x8c\x21\x16"
- "\x7d\x67\x6e\xf6\xcd\xda\xb6\x98"
- "\x23\xab\x23\x3c\xb2\x10\xa0\x53"
- "\x5a\x56\x9f\xc5\xd0\xff\xbb\xe4"
- "\x98\x3c\x69\x1e\xdb\x38\x8f\x7e"
- "\x0f\xd2\x98\x88\x81\x8b\x45\x67"
- "\xea\x33\xf1\xeb\xe9\x97\x55\x2e"
- "\xd9\xaa\xeb\x5a\xec\xda\xe1\x68"
- "\xa8\x9d\x3c\x84\x7c\x05\x3d\x62"
- "\x87\x8f\x03\x21\x28\x95\x0c\x89"
- "\x25\x22\x4a\xb0\x93\xa9\x50\xa2"
- "\x2f\x57\x6e\x18\x42\x19\x54\x0c"
- "\x55\x67\xc6\x11\x49\xf4\x5c\xd2"
- "\xe9\x3d\xdd\x8b\x48\x71\x21\x00"
- "\xc3\x9a\x6c\x85\x74\x28\x83\x4a"
- "\x1b\x31\x05\xe1\x06\x92\xe7\xda"
- "\x85\x73\x78\x45\x20\x7f\xae\x13"
- "\x7c\x33\x06\x22\xf4\x83\xf9\x35"
- "\x3f\x6c\x71\xa8\x4e\x48\xbe\x9b"
- "\xce\x8a\xba\xda\xbe\x28\x08\xf7"
- "\xe2\x14\x8c\x71\xea\x72\xf9\x33"
- "\xf2\x88\x3f\xd7\xbb\x69\x6c\x29"
- "\x19\xdc\x84\xce\x1f\x12\x4f\xc8"
- "\xaf\xa5\x04\xba\x5a\xab\xb0\xd9"
- "\x14\x1f\x6c\x68\x98\x39\x89\x7a"
- "\xd9\xd8\x2f\xdf\xa8\x47\x4a\x25"
- "\xe2\xfb\x33\xf4\x59\x78\xe1\x68"
- "\x85\xcf\xfe\x59\x20\xd4\x05\x1d"
- "\x80\x99\xae\xbc\xca\xae\x0f\x2f"
- "\x65\x43\x34\x8e\x7e\xac\xd3\x93"
- "\x2f\xac\x6d\x14\x3d\x02\x07\x70"
- "\x9d\xa4\xf3\x1b\x5c\x36\xfc\x01"
- "\x73\x34\x85\x0c\x6c\xd6\xf1\xbd"
- "\x3f\xdf\xee\xf5\xd9\xba\x56\xef"
- "\xf4\x9b\x6b\xee\x9f\x5a\x78\x6d"
- "\x32\x19\xf4\xf7\xf8\x4c\x69\x0b"
- "\x4b\xbc\xbb\xb7\xf2\x85\xaf\x70"
- "\x75\x24\x6c\x54\xa7\x0e\x4d\x1d"
- "\x01\xbf\x08\xac\xcf\x7f\x2c\xe3"
- "\x14\x89\x5e\x70\x5a\x99\x92\xcd"
- "\x01\x84\xc8\xd2\xab\xe5\x4f\x58"
- "\xe7\x0f\x2f\x0e\xff\x68\xea\xfd"
- "\x15\xb3\x17\xe6\xb0\xe7\x85\xd8"
- "\x23\x2e\x05\xc7\xc9\xc4\x46\x1f"
- "\xe1\x9e\x49\x20\x23\x24\x4d\x7e"
- "\x29\x65\xff\xf4\xb6\xfd\x1a\x85"
- "\xc4\x16\xec\xfc\xea\x7b\xd6\x2c"
- "\x43\xf8\xb7\xbf\x79\xc0\x85\xcd"
- "\xef\xe1\x98\xd3\xa5\xf7\x90\x8c"
- "\xe9\x7f\x80\x6b\xd2\xac\x4c\x30"
- "\xa7\xc6\x61\x6c\xd2\xf9\x2c\xff"
- "\x30\xbc\x22\x81\x7d\x93\x12\xe4"
- "\x0a\xcd\xaf\xdd\xe8\xab\x0a\x1e"
- "\x13\xa4\x27\xc3\x5f\xf7\x4b\xbb"
- "\x37\x09\x4b\x91\x6f\x92\x4f\xaf"
- "\x52\xee\xdf\xef\x09\x6f\xf7\x5c"
- "\x6e\x12\x17\x72\x63\x57\xc7\xba"
- "\x3b\x6b\x38\x32\x73\x1b\x9c\x80"
- "\xc1\x7a\xc6\xcf\xcd\x35\xc0\x6b"
- "\x31\x1a\x6b\xe9\xd8\x2c\x29\x3f"
- "\x96\xfb\xb6\xcd\x13\x91\x3b\xc2"
- "\xd2\xa3\x31\x8d\xa4\xcd\x57\xcd"
- "\x13\x3d\x64\xfd\x06\xce\xe6\xdc"
- "\x0c\x24\x43\x31\x40\x57\xf1\x72"
- "\x17\xe3\x3a\x63\x6d\x35\xcf\x5d"
- "\x97\x40\x59\xdd\xf7\x3c\x02\xf7"
- "\x1c\x7e\x05\xbb\xa9\x0d\x01\xb1"
- "\x8e\xc0\x30\xa9\x53\x24\xc9\x89"
- "\x84\x6d\xaa\xd0\xcd\x91\xc2\x4d"
- "\x91\xb0\x89\xe2\xbf\x83\x44\xaa"
- "\x28\x72\x23\xa0\xc2\xad\xad\x1c"
- "\xfc\x3f\x09\x7a\x0b\xdc\xc5\x1b"
- "\x87\x13\xc6\x5b\x59\x8d\xf2\xc8"
- "\xaf\xdf\x11\x95",
- .len = 4100,
- },
+ .iv = "\xfa\x3f\x70\x52\xfb\x04\x0e\xed"
+ "\x0e\x60\x75\x84\x21\xdf\x13\xa1",
+ .ptext = "\x26\xf8\x8c\x26\x0a\x37\x51\x8f"
+ "\xe7\x9c\x74\x77\x7a\x3e\xbb\x5d"
+ "\xd7\x33\xf3\xa9\x5b\xb4\x86\xea"
+ "\xe3\x7d\x50\x62\x3b\x73\xaf\xc4",
+ .ctext = "\x24\x36\xe4\x14\xb7\xe1\x56\x8a"
+ "\xf3\xc5\xaf\x0e\xa7\xeb\xbd\xcd"
+ "\x2d\xe9\xd7\x19\xae\x24\x5d\x3b"
+ "\x1d\xfb\xdc\x21\xb3\x1a\x37\x0b",
+ .len = 32,
+ }, {
+ .key = "\xda\x89\xd9\x3c\xcc\xe4\x73\xb0"
+ "\xef\x3e\x5f\x46\x62\x88\xd5\x26"
+ "\x3b\xd3\xb5\x81\x78\x70\x1b\xd2"
+ "\x39\x56\x34\x63\x2c\xc5\x51\x13",
+ .klen = 32,
+ .iv = "\x48\x29\x3a\x58\xbe\x41\xc5\x80"
+ "\x2c\x80\xa7\x3c\x14\xb4\x89\x5e",
+ .ptext = "\x8e\xe5\x5f\xe2\x39\x80\xf5\x2b"
+ "\x77\xb5\xca\x90\xda\x1d\x22\x17"
+ "\xd9\xa0\x57\x80\xc8\x96\x70\x86"
+ "\x07\x2c\xf4\x61\x79\x09\x01\x8f"
+ "\x37\x32\x98\xd4\x86\x2b\x3b\x80"
+ "\x07\x60\xba\xf0\x2e\xc3\x4a\x57",
+ .ctext = "\x2e\x73\x60\xec\xd3\x95\x78\xe8"
+ "\x0f\x98\x1a\xc2\x92\x49\x0b\x49"
+ "\x71\x42\xf4\xb0\xaa\x8b\xf8\x53"
+ "\x16\xab\x6d\x74\xc0\xda\xab\xcd"
+ "\x85\x52\x11\x20\x2c\x59\x16\x00"
+ "\x26\x47\x4a\xea\x08\x5f\x38\x68",
+ .len = 48,
+ }, {
+ .key = "\xf5\xb5\xd7\xbf\xd2\x2a\x9b\x4a"
+ "\xe6\x08\xf0\xbe\x77\xd1\x62\x40"
+ "\xa0\x82\x09\x60\x47\xbb\x16\x56"
+ "\x50\x1f\xab\x8b\x10\xfe\xf0\x5c",
+ .klen = 32,
+ .iv = "\x05\x32\x63\x1a\xc4\x46\x6f\x55"
+ "\x32\xde\x41\x5a\xf7\x52\xd7\xfa",
+ .ptext = "\x30\x9d\x59\x8d\x64\x76\xad\x37"
+ "\xba\xbc\x46\x6a\x69\x17\x3c\xac"
+ "\x6f\xdd\xa2\x9b\x86\x32\x14\x2e"
+ "\x54\x74\x8f\x3d\xe2\xd6\x85\x44"
+ "\x4f\x4a\x31\x64\xc6\xa5\x29\xaa"
+ "\xad\xfd\x32\x94\x1f\x56\x57\xd1"
+ "\x9d\x7e\x3d\x49\x00\x36\xb1\x5d"
+ "\xb2\x92\x83\x70\x1e\xa3\x97\xa6",
+ .ctext = "\xfb\xd3\xc3\x8b\xf7\x89\xcc\x31"
+ "\xb1\x7f\xc3\x91\xdc\x04\xc6\xd7"
+ "\x33\xbd\xe0\xee\x0c\xd5\x70\xed"
+ "\x1b\x1d\xad\x49\x6f\x5c\xa1\x68"
+ "\xd7\x03\xc9\x65\xa7\x90\x30\x2b"
+ "\x26\xeb\xf4\x7a\xac\xcc\x03\xe1"
+ "\x6a\xe5\xdb\x23\x10\x8a\xcd\x70"
+ "\x39\x4d\x7a\xc9\xcd\x62\xd1\x65",
+ .len = 64,
+ }, {
+ .key = "\x65\x53\x39\xeb\x53\x8f\xb1\x38"
+ "\x91\xac\x17\x11\x1c\x03\x69\x53"
+ "\xf5\xdf\xdb\x2c\x1b\x9a\x6e\x6b"
+ "\xb6\x02\xc4\xfa\x95\x01\x33\xa8",
+ .klen = 32,
+ .iv = "\xda\x7e\x18\x2c\xf4\x7e\x6e\x67"
+ "\xce\x8f\x9f\xea\x46\x66\x99\xb8",
+ .ptext = "\xe1\xc7\x25\x4d\xbd\xa5\x74\xdf"
+ "\xc7\x8b\xfb\xe3\x2d\x3a\x82\xd3"
+ "\x17\x94\x77\x2f\x92\xb8\x87\xc2"
+ "\xcc\x6f\x70\x26\x87\xc7\x10\x8a"
+ "\xc8\xfd\xc2\xb3\xcf\xa0\xeb\x41"
+ "\x4c\xf4\xd0\x34\xd0\x95\xab\xae"
+ "\x82\x5c\xfd\xfa\x13\x86\x25\xce"
+ "\xf4\x13\x32\xcd\xc6\x6d\xf6\x50"
+ "\x12\x4a\x5b\x66\x3a\xd3\xfb\x1a"
+ "\xaf\x06\xea\xf4\x65\x59\xd6\xc2",
+ .ctext = "\xa2\x51\x28\xc2\x5e\x58\x1c\xaf"
+ "\x84\x92\x1c\xe1\x92\xf0\xf9\x9e"
+ "\xf2\xb3\xc6\x2b\x34\xd2\x8d\xa0"
+ "\xb3\xd7\x87\x56\xeb\xd9\x32\x6a"
+ "\xca\x90\x28\x26\x49\x34\xca\x41"
+ "\xce\xc5\x9e\xd6\xfe\x57\x71\x3c"
+ "\x98\xaf\xdd\xfc\x7d\xdf\x26\x7e"
+ "\xb7\x9c\xd5\x15\xe5\x81\x7a\x4f"
+ "\x4f\x4f\xe5\x77\xf2\x2e\x67\x68"
+ "\x52\xc1\xac\x28\x2c\x88\xf4\x38",
+ .len = 80,
+ }, {
+ .key = "\x84\xa0\x53\x97\x61\x30\x70\x15"
+ "\xac\x45\x8e\xe8\xeb\xa1\x72\x93"
+ "\x26\x76\x98\x6f\xe4\x86\xca\xf0"
+ "\x57\x89\xf2\x2b\xd4\xcf\x2d\x95",
+ .klen = 32,
+ .iv = "\x86\x26\x20\x0e\x62\xfe\x8f\x1e"
+ "\x5d\xcb\x2b\x7e\xdd\xab\xac\xda",
+ .ptext = "\x6e\x49\x20\xd5\xb7\x01\x83\x4e"
+ "\xac\x45\x8f\xe1\x05\x3f\xd5\xb1"
+ "\xee\xb7\x0d\x65\x00\x38\xab\x71"
+ "\x70\x6e\xb3\x97\x86\xd3\xcd\xad"
+ "\x51\x8b\x9c\xa0\x9a\x8b\x4c\xb9"
+ "\x16\x01\x6a\x1f\xdf\xf0\xf9\x9e"
+ "\x25\x1b\xc2\xa6\x21\x25\xeb\x97"
+ "\x4b\xf6\xcb\x3b\xcd\x61\xfd\x94"
+ "\x37\x03\xb3\xd9\x74\x6e\x4d\xbb"
+ "\xfd\x87\x2b\xec\x4c\x2c\xbf\xe2"
+ "\x94\x1a\xe6\xd9\xaf\x0e\x78\x17"
+ "\x58\x2b\x1d\x73\x9a\x9c\x63\x18",
+ .ctext = "\xd1\xce\xbe\xe0\x4a\x6e\x6d\x7f"
+ "\x89\x19\x28\xb1\xca\xe8\xc1\x9c"
+ "\x8c\x0b\x7d\x63\xfe\xff\x3d\xf4"
+ "\x65\x9e\xd6\xe7\x2f\x5a\xc1\x31"
+ "\x1e\xe7\x59\x27\x54\x92\xcc\xaa"
+ "\x5b\x3d\xeb\xe7\x96\xc1\x49\x54"
+ "\x18\xf3\x14\xaa\x56\x03\x28\x53"
+ "\xaa\x0a\x91\xdf\x92\x96\x9b\x06"
+ "\x1a\x24\x02\x09\xe7\xa6\xdc\x75"
+ "\xeb\x00\x1d\xf5\xf2\xa7\x4a\x9d"
+ "\x75\x80\xb7\x47\x63\xfc\xad\x18"
+ "\x85\x5f\xfc\x64\x03\x72\x38\xe7",
+ .len = 96,
+ }, {
+ .key = "\x88\x7a\x0e\x87\x2f\xf0\xb0\xdb"
+ "\xc9\x9d\x79\x51\x34\x39\x4f\x07"
+ "\xa2\x7c\x21\x04\x91\x3b\x79\x79"
+ "\xfe\xd5\x51\x46\xd5\xcd\x28\xc0",
+ .klen = 32,
+ .iv = "\xad\xb8\x55\xb2\xb2\x5a\x9a\xa2"
+ "\xe2\x0c\xfc\x55\x7d\x60\xd2\x95",
+ .ptext = "\xb6\x08\x1d\x31\xaf\xf4\x17\x46"
+ "\xa4\xbb\x0f\xbd\x67\x3c\x73\x15"
+ "\x0c\x85\x2f\x62\xe5\xf4\x35\x96"
+ "\xb1\x9b\x5d\x00\x10\xe9\x70\x12"
+ "\x3a\x87\x7f\x67\xf1\x81\x7a\x05"
+ "\xb4\xa6\xfe\xdf\x36\x31\x6d\x9e"
+ "\x0e\xa9\x44\xa0\xb0\x05\xa9\x41"
+ "\x9c\x14\x44\x5a\xd5\x1c\x50\x08"
+ "\x95\xc2\xf2\xaf\x3f\x29\xc9\x3e"
+ "\x95\x5e\xc6\xb4\x2b\xf4\x3e\xe3"
+ "\x1b\xeb\x3d\x73\xfb\xd7\x1e\x2b"
+ "\x0c\x3d\x58\x6c\xb4\x41\x9b\xfe"
+ "\x2f\x7e\x1c\x10\x81\x36\x2d\x79"
+ "\xaf\xab\x10\x44\x2e\xcc\x0d\x6c",
+ .ctext = "\x0b\x07\xdc\x6a\x47\x45\xd2\xb0"
+ "\xa3\xf2\x42\x2f\xa4\x79\x6b\x4c"
+ "\x53\x9c\x8a\x2f\x48\x9c\xf2\x89"
+ "\x73\x8b\xdd\x97\xde\x41\x06\xc8"
+ "\x8a\x30\x7a\xa9\x90\x4a\x43\xd0"
+ "\xd5\xee\x16\x51\x44\xda\xe4\xb8"
+ "\xe8\x5f\x6f\xef\x84\xf3\x44\x43"
+ "\xbd\xdc\xc3\xdf\x65\x2b\xaf\xf6"
+ "\xfe\xd0\x4a\x5b\x30\x47\x8c\xaf"
+ "\x8d\xed\x2d\x91\xa1\x03\x9a\x80"
+ "\x58\xdd\xaa\x8f\x3b\x6b\x39\x10"
+ "\xe5\x92\xbc\xac\xaa\x25\xa1\x13"
+ "\x7e\xaa\x03\x83\x05\x83\x11\xfe"
+ "\x19\x5f\x04\x01\x48\x00\x3b\x58",
+ .len = 112,
+ }, {
+ .key = "\x9c\x14\xc2\xe4\xae\xb0\xbb\xda"
+ "\x6a\xe0\x42\x3d\x96\x9f\x78\x7d"
+ "\x70\x86\xa5\x92\x9f\xee\xcd\x3f"
+ "\x6a\x55\x84\x98\x28\x03\x02\xc2",
+ .klen = 32,
+ .iv = "\xf7\xec\x7a\xfa\xb1\xd9\xa8\xd8"
+ "\x1c\xc3\xaa\xd5\x61\x7f\x10\x0c",
+ .ptext = "\xc0\xa1\x36\x3d\x81\x9a\xd2\x17"
+ "\x2e\x23\xc9\xb7\xff\xdf\x47\x6c"
+ "\x96\x3b\x0e\xbd\xec\x9a\x0e\xad"
+ "\x8c\xaf\x36\x3d\xff\x29\x8b\x33"
+ "\x87\x96\x77\x1a\x10\x81\x63\x8a"
+ "\x63\xde\x88\xa9\x9d\xa9\x01\xf2"
+ "\xdf\xc9\x25\x35\x48\x3a\x15\xdf"
+ "\x20\x6b\x91\x7c\x56\xe5\x10\x7a"
+ "\x2d\x2e\x0f\x30\x32\xed\xa9\x1f"
+ "\x71\x4e\x68\x77\xe8\xa8\x5b\xdd"
+ "\x3c\x5e\x68\x6b\xab\x03\xe4\xf8"
+ "\x42\xc1\x61\x9a\x50\xfb\xc7\x6a"
+ "\x1a\x31\xa7\x87\xd0\x24\xcb\x5e"
+ "\xc0\x3b\x12\x28\xca\x26\x7b\xb3"
+ "\x14\xc1\x7f\x66\xff\x3b\xa4\x80"
+ "\x59\x77\x4f\xa0\xd4\xb2\xd9\x8a",
+ .ctext = "\xfe\xba\x8f\x68\x47\x55\xaa\x61"
+ "\x48\xdd\xf3\x7c\xc4\xdc\xa6\x93"
+ "\x4e\x72\x3f\xc7\xd0\x2b\x9b\xac"
+ "\xc1\xb5\x95\xf8\x8e\x75\x62\x0c"
+ "\x05\x6a\x90\x76\x35\xed\x73\xf2"
+ "\x0f\x44\x3d\xaf\xd4\x00\xeb\x1d"
+ "\xad\x27\xf2\x2f\x55\x65\x91\x0f"
+ "\xe4\x04\x9c\xfb\x8a\x18\x22\x8e"
+ "\x21\xbe\x93\x09\xdd\x3e\x93\x34"
+ "\x60\x82\xcd\xff\x42\x10\xed\x43"
+ "\x3a\x4b\xb8\x5c\x6c\xa8\x9e\x1c"
+ "\x95\x6a\x17\xa7\xa3\xe0\x7d\xdb"
+ "\x6e\xca\xaf\xc1\x1f\xb2\x86\x15"
+ "\xf0\xc1\x55\x72\xf2\x74\x44\xeb"
+ "\x09\x09\x83\x8b\x2c\xc9\x63\x13"
+ "\x99\xe3\xe1\x4b\x5c\xf7\xb1\x04",
+ .len = 128,
+ }, {
+ .key = "\xb6\x67\xe6\x28\xd3\x6f\xf2\xcf"
+ "\xb8\x6d\x2d\xc4\x2a\x69\x89\xff"
+ "\xcf\xbb\x11\x2e\x2a\x2b\x7c\xfd"
+ "\xcd\x56\x02\x95\xc9\x54\x6e\x62",
+ .klen = 32,
+ .iv = "\x6a\x97\x75\x1a\x21\x16\x46\xfb"
+ "\xc2\xab\x62\x54\xef\xba\xae\x46",
+ .ptext = "\xd4\x14\xc6\xcc\x16\x1b\x95\xf9"
+ "\x05\x26\x23\x81\x19\x27\xad\x7b"
+ "\x9c\x8b\xfb\x65\xa4\x61\xee\x69"
+ "\x44\xbf\x59\xde\x03\x61\x11\x12"
+ "\x8d\x94\x48\x47\xa9\x52\x16\xfb"
+ "\x6b\xaf\x59\x6d\xab\x74\xbf\x5c"
+ "\xb6\x09\x21\x12\x42\x98\x13\xa1"
+ "\xa8\x6f\xb9\x6d\x4d\xa6\xdc\xea"
+ "\x61\x02\x3c\xa7\xcd\x1a\x28\x8c"
+ "\x66\xb8\x4d\x60\x67\x82\xcc\x8d"
+ "\x1e\xda\x8f\x28\xe5\x02\xdc\x2c"
+ "\x54\x84\x2a\x06\xb5\xd1\x34\x57"
+ "\xb8\x28\x4d\xf5\x69\xb9\xf3\x33"
+ "\x5e\x0b\xa6\x62\x35\x9b\xfb\x97"
+ "\x3e\xc6\xec\xaf\x74\xe8\x72\x91"
+ "\xb2\xc6\x56\xb3\x23\x29\x43\xe0"
+ "\xfb\xcc\x21\x38\x64\x78\x9e\x78"
+ "\xbb\x6e\x0d\x7b\xfd\x05\x74\x01",
+ .ctext = "\xa5\x19\x33\xad\x2d\x1a\x7b\x34"
+ "\xb0\x21\x68\x0e\x20\x11\x7a\x37"
+ "\xef\x35\x33\x64\x31\x0a\x42\x77"
+ "\x2c\x7f\x1a\x34\xd6\x93\x2d\xe9"
+ "\x26\xb9\x15\xec\x4f\x83\xbd\x48"
+ "\x5b\xe9\x63\xea\x10\x3b\xec\xfb"
+ "\xb0\x5e\x81\x90\xf0\x07\x43\xc4"
+ "\xda\x54\x69\x98\x13\x5d\x93\x16"
+ "\xca\x06\x81\x64\x36\xbe\x36\xa2"
+ "\xd4\xd8\x48\x63\xc7\x53\x39\x93"
+ "\x6d\x6b\xd6\x49\x00\x72\x5e\x02"
+ "\xc7\x88\x61\x0f\x10\x88\xd4\x9e"
+ "\x17\x81\xa4\xdc\x43\x4e\x83\x43"
+ "\xd4\xc3\xd7\x25\x9a\xd4\x76\xde"
+ "\x88\xe3\x98\x5a\x0e\x80\x23\xfb"
+ "\x49\xb3\x83\xf6\xb9\x16\x00\x06"
+ "\xa5\x06\x24\x17\x65\xbb\x68\xa9"
+ "\x56\x6d\xeb\xcd\x3c\x14\xd2\x64",
+ .len = 144,
+ }, {
+ .key = "\x7c\x94\xe0\xb0\xd7\x92\xfc\x58"
+ "\x28\xfc\xe2\x7b\x7f\xf7\x31\x0d"
+ "\x90\xb7\x60\x78\xa8\x9f\x52\xe3"
+ "\xe6\xaa\x2a\xb4\xa7\x09\x60\x53",
+ .klen = 32,
+ .iv = "\x42\x0e\x15\x31\xf6\x48\xa3\x0a"
+ "\x20\xf0\x79\x67\xb1\x83\x26\x66",
+ .ptext = "\xe0\xb1\xb3\xbd\x1c\x76\x36\xfd"
+ "\x45\x87\xa4\x14\x1b\xef\xe7\x16"
+ "\xf7\xfa\x30\x3d\xb9\x52\x8f\x2e"
+ "\x01\x68\xc1\x7d\xa2\x15\x49\x74"
+ "\x53\x82\xc2\x10\xa8\x45\x73\x4d"
+ "\x41\xcc\x24\xa3\x42\xff\x30\xd1"
+ "\x02\x21\xdc\xd9\x08\xf7\xe7\x4c"
+ "\x33\x2d\x62\xc7\x38\xf5\xc2\xbe"
+ "\x52\xf1\x34\x78\x34\x53\x30\x5b"
+ "\x43\x43\x51\x6a\x02\x81\x64\x0c"
+ "\xcd\x4b\xbf\x0f\xcb\x81\xd4\xec"
+ "\x1e\x07\x05\x4d\x5c\x6b\xba\xcc"
+ "\x43\xc7\xb1\xfe\xa8\xe9\x96\xb0"
+ "\xb1\xb2\xd4\x70\x44\xbc\xaa\x50"
+ "\xbf\x3f\x81\xe6\xea\x36\x7d\x97"
+ "\x2a\xbd\x52\x16\xf7\xbe\x59\x27"
+ "\x8f\xcc\xe3\xa9\xec\x4f\xcd\xd3"
+ "\xf4\xe2\x54\xbe\xf1\xf9\x2b\x23"
+ "\x40\xc7\xcb\x67\x4d\x5f\x0b\xd4"
+ "\xbf\x19\xf0\x2a\xef\x37\xc6\x56",
+ .ctext = "\x0a\x69\xd8\x67\x33\x2a\x2f\xa9"
+ "\x26\x79\x65\xd6\x75\x1e\x98\xe8"
+ "\x52\x56\x32\xbf\x67\x71\xf4\x01"
+ "\xb1\x6f\xef\xf9\xc9\xad\xb3\x49"
+ "\x7a\x4f\x24\x9a\xae\x06\x62\x26"
+ "\x3e\xe4\xa7\x6f\x5a\xbf\xe9\x52"
+ "\x13\x01\x74\x8b\x6e\xb1\x65\x24"
+ "\xaa\x8d\xbb\x54\x21\x20\x60\xa4"
+ "\xb7\xa5\xf9\x4e\x7b\xf5\x0b\x70"
+ "\xd2\xb9\xdc\x9b\xdb\x2c\xb2\x43"
+ "\xf7\x71\x30\xa5\x13\x6f\x16\x75"
+ "\xd0\xdf\x72\xae\xe4\xed\xc1\xa3"
+ "\x81\xe0\xd5\xc0\x0e\x62\xe8\xe5"
+ "\x86\x2c\x37\xde\xf8\xb0\x21\xe4"
+ "\xcd\xa6\x76\x9b\xa1\x56\xd3\x67"
+ "\x70\x69\xd6\x5d\xc7\x65\x19\x59"
+ "\x43\x9c\xca\x32\xe9\xd1\x48\x92"
+ "\x71\x79\x87\x73\x24\xcb\xc0\x0f"
+ "\x23\x3b\x8f\x51\x8a\xb3\x3a\x9c"
+ "\x74\xa4\x19\xa7\xe4\x4f\x6b\x32",
+ .len = 160,
+ }
+};
+
+static const struct cipher_testvec aria_ctr_tv_template[] = {
+ {
+ .key = "\x7f\x92\xd5\x06\x30\x6b\xc0\x23"
+ "\x87\xa8\x8e\x6d\xc7\xc5\xd7\xf1",
+ .klen = 16,
+ .iv = "\x5f\xce\x89\xb3\xd5\x7f\x7f\xf0"
+ "\xfd\xab\x56\xa6\x6e\xda\x7c\x57",
+ .ptext = "\x36\x36\x89\x09\xcd\xa8\xd3\x91"
+ "\x48\x3e\x3c\x11\xcf\xd0\x4f\xc0",
+ .ctext = "\x19\x28\xb5\xf2\x1c\xbc\xf8\xaf"
+ "\xb9\xae\x1b\x23\x4f\xe1\x6e\x40",
+ .len = 16,
+ }, {
+ .key = "\x51\xe3\x8c\xe9\x76\xcd\xff\x37"
+ "\xd6\x1a\x18\x2f\x68\x2f\xb6\xfe",
+ .klen = 16,
+ .iv = "\x3d\x2d\x85\x75\x6e\x18\x8a\x52"
+ "\x53\x39\xfc\xc1\xf5\xc0\x56\x22",
+ .ptext = "\xc6\xae\xaa\x0d\x90\xf2\x38\x93"
+ "\xac\xd2\x3f\xc7\x74\x8d\x13\x7e"
+ "\xfa\x3f\x70\x52\xfb\x04\x0e\xed"
+ "\x0e\x60\x75\x84\x21\xdf\x13\xa1",
+ .ctext = "\x3f\x8c\xa9\x19\xd6\xb4\xfb\xed"
+ "\x9c\x6d\xaa\x1b\xe1\xc1\xe6\xa8"
+ "\xa9\x0a\x63\xd3\xa2\x1e\x6b\xa8"
+ "\x52\x97\x1e\x81\x34\x6f\x98\x0e",
+ .len = 32,
+ }, {
+ .key = "\x26\xf8\x8c\x26\x0a\x37\x51\x8f"
+ "\xe7\x9c\x74\x77\x7a\x3e\xbb\x5d",
+ .klen = 16,
+ .iv = "\xd7\x33\xf3\xa9\x5b\xb4\x86\xea"
+ "\xe3\x7d\x50\x62\x3b\x73\xaf\xc4",
+ .ptext = "\xda\x89\xd9\x3c\xcc\xe4\x73\xb0"
+ "\xef\x3e\x5f\x46\x62\x88\xd5\x26"
+ "\x3b\xd3\xb5\x81\x78\x70\x1b\xd2"
+ "\x39\x56\x34\x63\x2c\xc5\x51\x13"
+ "\x48\x29\x3a\x58\xbe\x41\xc5\x80"
+ "\x2c\x80\xa7\x3c\x14\xb4\x89\x5e",
+ .ctext = "\x28\xd8\xa7\xf8\x74\x98\x00\xfc"
+ "\xd6\x48\xad\xbd\xbe\x3f\x0e\x7b"
+ "\x3d\x46\xfd\xde\x3e\x4f\x12\x43"
+ "\xac\x85\xda\xff\x70\x24\x44\x9d"
+ "\x1e\xf8\x9f\x30\xba\xca\xe0\x97"
+ "\x03\x6d\xe1\x1d\xc7\x21\x79\x37",
+ .len = 48,
+ }, {
+ .key = "\x8e\xe5\x5f\xe2\x39\x80\xf5\x2b"
+ "\x77\xb5\xca\x90\xda\x1d\x22\x17",
+ .klen = 16,
+ .iv = "\xd9\xa0\x57\x80\xc8\x96\x70\x86"
+ "\x07\x2c\xf4\x61\x79\x09\x01\x8f",
+ .ptext = "\x37\x32\x98\xd4\x86\x2b\x3b\x80"
+ "\x07\x60\xba\xf0\x2e\xc3\x4a\x57"
+ "\xf5\xb5\xd7\xbf\xd2\x2a\x9b\x4a"
+ "\xe6\x08\xf0\xbe\x77\xd1\x62\x40"
+ "\xa0\x82\x09\x60\x47\xbb\x16\x56"
+ "\x50\x1f\xab\x8b\x10\xfe\xf0\x5c"
+ "\x05\x32\x63\x1a\xc4\x46\x6f\x55"
+ "\x32\xde\x41\x5a\xf7\x52\xd7\xfa",
+ .ctext = "\x29\x31\x55\xd2\xe5\x0b\x81\x39"
+ "\xf9\xbc\x63\xe2\xfa\x26\x99\xde"
+ "\xde\x18\x93\x68\x81\x7b\x0a\x4d"
+ "\xf6\x03\xe1\xee\xf9\x0e\x1f\xe8"
+ "\xa8\x80\x81\x46\xdc\x24\x43\x3f"
+ "\xff\xfe\x8c\x3e\x17\x0a\x6d\xa2"
+ "\x47\x55\x62\xa0\x03\x4e\x48\x67"
+ "\xa2\x64\xc0\x9b\x6c\xa4\xfd\x6a",
+ .len = 64,
+ }, {
+ .key = "\x30\x9d\x59\x8d\x64\x76\xad\x37"
+ "\xba\xbc\x46\x6a\x69\x17\x3c\xac",
+ .klen = 16,
+ .iv = "\x6f\xdd\xa2\x9b\x86\x32\x14\x2e"
+ "\x54\x74\x8f\x3d\xe2\xd6\x85\x44",
+ .ptext = "\x4f\x4a\x31\x64\xc6\xa5\x29\xaa"
+ "\xad\xfd\x32\x94\x1f\x56\x57\xd1"
+ "\x9d\x7e\x3d\x49\x00\x36\xb1\x5d"
+ "\xb2\x92\x83\x70\x1e\xa3\x97\xa6"
+ "\x65\x53\x39\xeb\x53\x8f\xb1\x38"
+ "\x91\xac\x17\x11\x1c\x03\x69\x53"
+ "\xf5\xdf\xdb\x2c\x1b\x9a\x6e\x6b"
+ "\xb6\x02\xc4\xfa\x95\x01\x33\xa8"
+ "\xda\x7e\x18\x2c\xf4\x7e\x6e\x67"
+ "\xce\x8f\x9f\xea\x46\x66\x99\xb8",
+ .ctext = "\x38\xbc\xf5\x9d\x0e\x26\xa6\x18"
+ "\x95\x0b\x23\x54\x09\xa1\xf9\x46"
+ "\x12\xf1\x42\x57\xa1\xaa\x52\xfa"
+ "\x8a\xbd\xf2\x03\x63\x4e\xbc\xf7"
+ "\x21\xea\xed\xca\xdd\x42\x41\x94"
+ "\xe4\x6c\x07\x06\x19\x59\x30\xff"
+ "\x8c\x9d\x51\xbf\x2c\x2e\x5b\xa5"
+ "\x7d\x11\xec\x6b\x21\x08\x12\x18"
+ "\xe4\xdf\x5a\xfd\xa6\x5f\xee\x2f"
+ "\x5c\x24\xb7\xea\xc1\xcd\x6d\x68",
+ .len = 80,
+ }, {
+ .key = "\xe1\xc7\x25\x4d\xbd\xa5\x74\xdf"
+ "\xc7\x8b\xfb\xe3\x2d\x3a\x82\xd3",
+ .klen = 16,
+ .iv = "\x17\x94\x77\x2f\x92\xb8\x87\xc2"
+ "\xcc\x6f\x70\x26\x87\xc7\x10\x8a",
+ .ptext = "\xc8\xfd\xc2\xb3\xcf\xa0\xeb\x41"
+ "\x4c\xf4\xd0\x34\xd0\x95\xab\xae"
+ "\x82\x5c\xfd\xfa\x13\x86\x25\xce"
+ "\xf4\x13\x32\xcd\xc6\x6d\xf6\x50"
+ "\x12\x4a\x5b\x66\x3a\xd3\xfb\x1a"
+ "\xaf\x06\xea\xf4\x65\x59\xd6\xc2"
+ "\x84\xa0\x53\x97\x61\x30\x70\x15"
+ "\xac\x45\x8e\xe8\xeb\xa1\x72\x93"
+ "\x26\x76\x98\x6f\xe4\x86\xca\xf0"
+ "\x57\x89\xf2\x2b\xd4\xcf\x2d\x95"
+ "\x86\x26\x20\x0e\x62\xfe\x8f\x1e"
+ "\x5d\xcb\x2b\x7e\xdd\xab\xac\xda",
+ .ctext = "\xdf\x79\x58\x30\x6f\x47\x12\x78"
+ "\x04\xb2\x0b\x1a\x62\x22\xe2\x9f"
+ "\xfe\xc2\xf5\x6d\x9e\x0e\x2e\x56"
+ "\x76\x01\x7f\x25\x8f\x6e\xc5\xf3"
+ "\x91\xff\xcd\x67\xc6\xae\x0b\x01"
+ "\x4d\x5f\x40\x25\x88\xc5\xe0\x3d"
+ "\x37\x62\x12\x58\xfe\xc5\x4a\x21"
+ "\x4a\x86\x8d\x94\xdd\xfd\xe6\xf6"
+ "\x1e\xa6\x78\x4f\x90\x66\xda\xe4"
+ "\x4e\x64\xa8\x05\xc6\xd8\x7d\xfb"
+ "\xac\xc9\x1d\x14\xb5\xb0\xfa\x9c"
+ "\xe8\x84\xef\x87\xbe\xb4\x2a\x87",
+ .len = 96,
+ }, {
+ .key = "\x6e\x49\x20\xd5\xb7\x01\x83\x4e"
+ "\xac\x45\x8f\xe1\x05\x3f\xd5\xb1",
+ .klen = 16,
+ .iv = "\xee\xb7\x0d\x65\x00\x38\xab\x71"
+ "\x70\x6e\xb3\x97\x86\xd3\xcd\xad",
+ .ptext = "\x51\x8b\x9c\xa0\x9a\x8b\x4c\xb9"
+ "\x16\x01\x6a\x1f\xdf\xf0\xf9\x9e"
+ "\x25\x1b\xc2\xa6\x21\x25\xeb\x97"
+ "\x4b\xf6\xcb\x3b\xcd\x61\xfd\x94"
+ "\x37\x03\xb3\xd9\x74\x6e\x4d\xbb"
+ "\xfd\x87\x2b\xec\x4c\x2c\xbf\xe2"
+ "\x94\x1a\xe6\xd9\xaf\x0e\x78\x17"
+ "\x58\x2b\x1d\x73\x9a\x9c\x63\x18"
+ "\x88\x7a\x0e\x87\x2f\xf0\xb0\xdb"
+ "\xc9\x9d\x79\x51\x34\x39\x4f\x07"
+ "\xa2\x7c\x21\x04\x91\x3b\x79\x79"
+ "\xfe\xd5\x51\x46\xd5\xcd\x28\xc0"
+ "\xad\xb8\x55\xb2\xb2\x5a\x9a\xa2"
+ "\xe2\x0c\xfc\x55\x7d\x60\xd2\x95",
+ .ctext = "\xe4\x25\x0d\x22\xeb\xbe\x5e\x90"
+ "\x01\xe5\xae\xc9\x94\xbd\x93\x89"
+ "\x5f\x98\xf1\x46\x6a\x50\x3b\xa2"
+ "\x79\xd9\xe4\x9c\x9a\xde\xf2\x8c"
+ "\x25\x49\x4c\xda\xb4\x2c\x76\xab"
+ "\x0a\xa8\x51\xaf\xc0\x62\x1b\xe9"
+ "\xe9\x7a\x35\x6a\x4b\x1f\x48\x00"
+ "\xeb\x24\x1d\x5e\xdd\x06\x09\x23"
+ "\x2a\xfa\x8f\x3b\x3e\x9e\x14\x6f"
+ "\x2a\x3c\xef\x6d\x73\x67\xdd\x6c"
+ "\xc8\xa5\x57\xc8\x02\xb6\x9a\xe8"
+ "\x8d\xcf\x10\xfa\x3e\x9c\x4d\xeb"
+ "\x44\xd2\x05\x31\x40\x94\x77\x87"
+ "\xf0\x83\xb5\xd2\x2a\x9c\xbc\xe4",
+ .len = 112,
+ }, {
+ .key = "\xb6\x08\x1d\x31\xaf\xf4\x17\x46"
+ "\xa4\xbb\x0f\xbd\x67\x3c\x73\x15",
+ .klen = 16,
+ .iv = "\x0c\x85\x2f\x62\xe5\xf4\x35\x96"
+ "\xb1\x9b\x5d\x00\x10\xe9\x70\x12",
+ .ptext = "\x3a\x87\x7f\x67\xf1\x81\x7a\x05"
+ "\xb4\xa6\xfe\xdf\x36\x31\x6d\x9e"
+ "\x0e\xa9\x44\xa0\xb0\x05\xa9\x41"
+ "\x9c\x14\x44\x5a\xd5\x1c\x50\x08"
+ "\x95\xc2\xf2\xaf\x3f\x29\xc9\x3e"
+ "\x95\x5e\xc6\xb4\x2b\xf4\x3e\xe3"
+ "\x1b\xeb\x3d\x73\xfb\xd7\x1e\x2b"
+ "\x0c\x3d\x58\x6c\xb4\x41\x9b\xfe"
+ "\x2f\x7e\x1c\x10\x81\x36\x2d\x79"
+ "\xaf\xab\x10\x44\x2e\xcc\x0d\x6c"
+ "\x9c\x14\xc2\xe4\xae\xb0\xbb\xda"
+ "\x6a\xe0\x42\x3d\x96\x9f\x78\x7d"
+ "\x70\x86\xa5\x92\x9f\xee\xcd\x3f"
+ "\x6a\x55\x84\x98\x28\x03\x02\xc2"
+ "\xf7\xec\x7a\xfa\xb1\xd9\xa8\xd8"
+ "\x1c\xc3\xaa\xd5\x61\x7f\x10\x0c",
+ .ctext = "\xa7\x4c\x96\x55\x7c\x07\xce\xb2"
+ "\x6f\x63\x9f\xc6\x8b\x6f\xc6\x4a"
+ "\x2c\x47\x8d\x99\xdf\x65\x75\x96"
+ "\xb7\x1d\x50\x5b\x57\x4a\x69\xcc"
+ "\xc9\x3a\x18\x8a\xd1\xab\x70\x4a"
+ "\xa3\x13\x80\xdd\x48\xc0\x6a\x7d"
+ "\x21\xa8\x22\x06\x32\x47\xc0\x16"
+ "\x1f\x9a\xc0\x21\x33\x66\xf2\xd8"
+ "\x69\x79\xae\x02\x82\x3f\xaf\xa6"
+ "\x98\xdb\xcd\x2a\xe5\x12\x39\x80"
+ "\x8a\xc1\x73\x99\xe5\xe4\x17\xe3"
+ "\x56\xc2\x43\xa6\x41\x6b\xb2\xa4"
+ "\x9f\x81\xc4\xe9\xf4\x29\x65\x50"
+ "\x69\x81\x80\x4b\x86\xab\x5e\x30"
+ "\xd0\x81\x9d\x6f\x24\x59\x42\xc7"
+ "\x6d\x5e\x41\xb8\xf5\x99\xc2\xae",
+ .len = 128,
+ }, {
+ .key = "\xc0\xa1\x36\x3d\x81\x9a\xd2\x17"
+ "\x2e\x23\xc9\xb7\xff\xdf\x47\x6c",
+ .klen = 16,
+ .iv = "\x96\x3b\x0e\xbd\xec\x9a\x0e\xad"
+ "\x8c\xaf\x36\x3d\xff\x29\x8b\x33",
+ .ptext = "\x87\x96\x77\x1a\x10\x81\x63\x8a"
+ "\x63\xde\x88\xa9\x9d\xa9\x01\xf2"
+ "\xdf\xc9\x25\x35\x48\x3a\x15\xdf"
+ "\x20\x6b\x91\x7c\x56\xe5\x10\x7a"
+ "\x2d\x2e\x0f\x30\x32\xed\xa9\x1f"
+ "\x71\x4e\x68\x77\xe8\xa8\x5b\xdd"
+ "\x3c\x5e\x68\x6b\xab\x03\xe4\xf8"
+ "\x42\xc1\x61\x9a\x50\xfb\xc7\x6a"
+ "\x1a\x31\xa7\x87\xd0\x24\xcb\x5e"
+ "\xc0\x3b\x12\x28\xca\x26\x7b\xb3"
+ "\x14\xc1\x7f\x66\xff\x3b\xa4\x80"
+ "\x59\x77\x4f\xa0\xd4\xb2\xd9\x8a"
+ "\xb6\x67\xe6\x28\xd3\x6f\xf2\xcf"
+ "\xb8\x6d\x2d\xc4\x2a\x69\x89\xff"
+ "\xcf\xbb\x11\x2e\x2a\x2b\x7c\xfd"
+ "\xcd\x56\x02\x95\xc9\x54\x6e\x62"
+ "\x6a\x97\x75\x1a\x21\x16\x46\xfb"
+ "\xc2\xab\x62\x54\xef\xba\xae\x46",
+ .ctext = "\x11\x7f\xea\x49\xaf\x24\x52\xa2"
+ "\xde\x60\x99\x58\x23\xf9\x9e\x91"
+ "\x73\xd5\x9a\xcb\xdd\x10\xcd\x68"
+ "\xb8\x9e\xef\xa4\xe9\x2d\xf0\x27"
+ "\x44\xd4\x9a\xd6\xb6\x9c\x7a\xec"
+ "\x17\x17\xea\xa7\x8e\xa8\x40\x6b"
+ "\x43\x3d\x50\x59\x0f\x74\x1b\x9e"
+ "\x03\xed\x4f\x2f\xb8\xda\xef\xc3"
+ "\x3f\x29\xb3\xf4\x5c\xcd\xce\x3c"
+ "\xba\xfb\xc6\xd1\x1d\x6f\x61\x3a"
+ "\x2b\xbd\xde\x30\xc5\x53\xe0\x6e"
+ "\xbe\xae\x2f\x81\x13\x0f\xd2\xd5"
+ "\x14\xda\xd3\x60\x9c\xf8\x00\x86"
+ "\xe9\x97\x3e\x05\xb3\x95\xb3\x21"
+ "\x1f\x3c\x56\xef\xcb\x32\x49\x5c"
+ "\x89\xf1\x34\xe4\x8d\x7f\xde\x01"
+ "\x1f\xd9\x25\x6d\x34\x1d\x6b\x71"
+ "\xc9\xa9\xd6\x14\x1a\xf1\x44\x59",
+ .len = 144,
+ }, {
+ .key = "\xd4\x14\xc6\xcc\x16\x1b\x95\xf9"
+ "\x05\x26\x23\x81\x19\x27\xad\x7b",
+ .klen = 16,
+ .iv = "\x9c\x8b\xfb\x65\xa4\x61\xee\x69"
+ "\x44\xbf\x59\xde\x03\x61\x11\x12",
+ .ptext = "\x8d\x94\x48\x47\xa9\x52\x16\xfb"
+ "\x6b\xaf\x59\x6d\xab\x74\xbf\x5c"
+ "\xb6\x09\x21\x12\x42\x98\x13\xa1"
+ "\xa8\x6f\xb9\x6d\x4d\xa6\xdc\xea"
+ "\x61\x02\x3c\xa7\xcd\x1a\x28\x8c"
+ "\x66\xb8\x4d\x60\x67\x82\xcc\x8d"
+ "\x1e\xda\x8f\x28\xe5\x02\xdc\x2c"
+ "\x54\x84\x2a\x06\xb5\xd1\x34\x57"
+ "\xb8\x28\x4d\xf5\x69\xb9\xf3\x33"
+ "\x5e\x0b\xa6\x62\x35\x9b\xfb\x97"
+ "\x3e\xc6\xec\xaf\x74\xe8\x72\x91"
+ "\xb2\xc6\x56\xb3\x23\x29\x43\xe0"
+ "\xfb\xcc\x21\x38\x64\x78\x9e\x78"
+ "\xbb\x6e\x0d\x7b\xfd\x05\x74\x01"
+ "\x7c\x94\xe0\xb0\xd7\x92\xfc\x58"
+ "\x28\xfc\xe2\x7b\x7f\xf7\x31\x0d"
+ "\x90\xb7\x60\x78\xa8\x9f\x52\xe3"
+ "\xe6\xaa\x2a\xb4\xa7\x09\x60\x53"
+ "\x42\x0e\x15\x31\xf6\x48\xa3\x0a"
+ "\x20\xf0\x79\x67\xb1\x83\x26\x66",
+ .ctext = "\x5b\xc0\xe8\x17\xa4\xf9\xea\xce"
+ "\x9e\xf9\xe0\xb1\xac\x37\xe9\x41"
+ "\x0b\x57\xc6\x55\x54\x50\xfa\xa9"
+ "\x60\xaf\x7a\x4e\x98\x56\xde\x81"
+ "\x14\xfc\xac\x21\x81\x3e\xf4\x0f"
+ "\x40\x92\x30\xa8\x16\x88\x1a\xc3"
+ "\xf1\x39\xbd\x0a\xb9\x44\xc8\x67"
+ "\x8c\xaa\x2b\x45\x8b\x5b\x7b\x24"
+ "\xd5\xd8\x9e\xd3\x59\xa5\xd7\x69"
+ "\xdf\xf4\x50\xf9\x5f\x4f\x44\x1f"
+ "\x2c\x75\x68\x6e\x3a\xa8\xae\x4b"
+ "\x84\xf0\x42\x6c\xc0\x3c\x42\xaf"
+ "\x87\x2b\x89\xe9\x51\x69\x16\x63"
+ "\xc5\x62\x13\x05\x4c\xb2\xa9\x69"
+ "\x01\x14\x73\x88\x8e\x41\x47\xb6"
+ "\x68\x74\xbc\xe9\xad\xda\x94\xa1"
+ "\x0c\x12\x8e\xd4\x38\x15\x02\x97"
+ "\x27\x72\x4d\xdf\x61\xcc\x86\x3d"
+ "\xd6\x32\x4a\xc3\xa9\x4c\x35\x4f"
+ "\x5b\x91\x7d\x5c\x79\x59\xb3\xd5",
+ .len = 160,
+ }, {
+ .key = "\x7f\x92\xd5\x06\x30\x6b\xc0\x23"
+ "\x87\xa8\x8e\x6d\xc7\xc5\xd7\xf1"
+ "\x5f\xce\x89\xb3\xd5\x7f\x7f\xf0",
+ .klen = 24,
+ .iv = "\xfd\xab\x56\xa6\x6e\xda\x7c\x57"
+ "\x36\x36\x89\x09\xcd\xa8\xd3\x91",
+ .ptext = "\x48\x3e\x3c\x11\xcf\xd0\x4f\xc0"
+ "\x51\xe3\x8c\xe9\x76\xcd\xff\x37",
+ .ctext = "\xa4\x12\x2f\xc4\xf0\x6d\xd9\x46"
+ "\xe4\xe6\xd1\x0b\x6d\x14\xf0\x8f",
+ .len = 16,
+ }, {
+ .key = "\xd6\x1a\x18\x2f\x68\x2f\xb6\xfe"
+ "\x3d\x2d\x85\x75\x6e\x18\x8a\x52"
+ "\x53\x39\xfc\xc1\xf5\xc0\x56\x22",
+ .klen = 24,
+ .iv = "\xc6\xae\xaa\x0d\x90\xf2\x38\x93"
+ "\xac\xd2\x3f\xc7\x74\x8d\x13\x7e",
+ .ptext = "\xfa\x3f\x70\x52\xfb\x04\x0e\xed"
+ "\x0e\x60\x75\x84\x21\xdf\x13\xa1"
+ "\x26\xf8\x8c\x26\x0a\x37\x51\x8f"
+ "\xe7\x9c\x74\x77\x7a\x3e\xbb\x5d",
+ .ctext = "\x80\x2b\xf0\x88\xb9\x4b\x8d\xf5"
+ "\xc3\x0e\x15\x5b\xea\x5d\x5b\xa8"
+ "\x07\x95\x78\x72\xc0\xb9\xbf\x25"
+ "\x33\x22\xd1\x05\x56\x46\x62\x25",
+ .len = 32,
+ }, {
+ .key = "\xd7\x33\xf3\xa9\x5b\xb4\x86\xea"
+ "\xe3\x7d\x50\x62\x3b\x73\xaf\xc4"
+ "\xda\x89\xd9\x3c\xcc\xe4\x73\xb0",
+ .klen = 24,
+ .iv = "\xef\x3e\x5f\x46\x62\x88\xd5\x26"
+ "\x3b\xd3\xb5\x81\x78\x70\x1b\xd2",
+ .ptext = "\x39\x56\x34\x63\x2c\xc5\x51\x13"
+ "\x48\x29\x3a\x58\xbe\x41\xc5\x80"
+ "\x2c\x80\xa7\x3c\x14\xb4\x89\x5e"
+ "\x8e\xe5\x5f\xe2\x39\x80\xf5\x2b"
+ "\x77\xb5\xca\x90\xda\x1d\x22\x17"
+ "\xd9\xa0\x57\x80\xc8\x96\x70\x86",
+ .ctext = "\x65\x01\x3c\xb0\xac\x4c\x63\xb6"
+ "\xe7\xf1\xf4\x61\x35\xf4\x36\xde"
+ "\x7f\x85\xba\x41\xa8\xb0\x27\x11"
+ "\x86\x2c\x71\x16\x05\x1d\xcf\x70"
+ "\x35\xef\x23\x17\xfc\xed\x3f\x1a"
+ "\x8e\xb3\xe5\xdb\x90\xb4\xb8\x35",
+ .len = 48,
+ }, {
+ .key = "\x07\x2c\xf4\x61\x79\x09\x01\x8f"
+ "\x37\x32\x98\xd4\x86\x2b\x3b\x80"
+ "\x07\x60\xba\xf0\x2e\xc3\x4a\x57",
+ .klen = 24,
+ .iv = "\xf5\xb5\xd7\xbf\xd2\x2a\x9b\x4a"
+ "\xe6\x08\xf0\xbe\x77\xd1\x62\x40",
+ .ptext = "\xa0\x82\x09\x60\x47\xbb\x16\x56"
+ "\x50\x1f\xab\x8b\x10\xfe\xf0\x5c"
+ "\x05\x32\x63\x1a\xc4\x46\x6f\x55"
+ "\x32\xde\x41\x5a\xf7\x52\xd7\xfa"
+ "\x30\x9d\x59\x8d\x64\x76\xad\x37"
+ "\xba\xbc\x46\x6a\x69\x17\x3c\xac"
+ "\x6f\xdd\xa2\x9b\x86\x32\x14\x2e"
+ "\x54\x74\x8f\x3d\xe2\xd6\x85\x44",
+ .ctext = "\x5a\xfb\xb1\x2c\x6e\xe5\xb8\xe0"
+ "\x80\xb6\x77\xa8\xfe\x10\x3a\x99"
+ "\x00\x8e\x30\x23\x7d\x50\x87\xda"
+ "\xc6\x46\x73\x37\x8b\xf1\xab\x26"
+ "\x2d\xa8\x0c\xa8\x9e\x77\xee\xfc"
+ "\x78\x4f\x03\x0f\xeb\xc6\x03\x34"
+ "\xb9\x9c\x4f\x59\x55\xc5\x99\x47"
+ "\xd4\x7e\xe8\x06\x43\x5f\xa1\x6b",
+ .len = 64,
+ }, {
+ .key = "\x4f\x4a\x31\x64\xc6\xa5\x29\xaa"
+ "\xad\xfd\x32\x94\x1f\x56\x57\xd1"
+ "\x9d\x7e\x3d\x49\x00\x36\xb1\x5d",
+ .klen = 24,
+ .iv = "\xb2\x92\x83\x70\x1e\xa3\x97\xa6"
+ "\x65\x53\x39\xeb\x53\x8f\xb1\x38",
+ .ptext = "\x91\xac\x17\x11\x1c\x03\x69\x53"
+ "\xf5\xdf\xdb\x2c\x1b\x9a\x6e\x6b"
+ "\xb6\x02\xc4\xfa\x95\x01\x33\xa8"
+ "\xda\x7e\x18\x2c\xf4\x7e\x6e\x67"
+ "\xce\x8f\x9f\xea\x46\x66\x99\xb8"
+ "\xe1\xc7\x25\x4d\xbd\xa5\x74\xdf"
+ "\xc7\x8b\xfb\xe3\x2d\x3a\x82\xd3"
+ "\x17\x94\x77\x2f\x92\xb8\x87\xc2"
+ "\xcc\x6f\x70\x26\x87\xc7\x10\x8a"
+ "\xc8\xfd\xc2\xb3\xcf\xa0\xeb\x41",
+ .ctext = "\xc9\x5f\xe0\x60\x61\x38\x7e\x79"
+ "\x52\x68\x64\x8f\x55\x9b\x6b\x72"
+ "\xbf\x09\xef\x2f\xb2\x92\xbb\xa3"
+ "\xe1\x6a\xeb\xe6\x4e\x7c\x5d\xe0"
+ "\x6a\x4b\xd0\x57\x3b\x28\x8a\x83"
+ "\x75\xd4\x5a\x2e\xd1\x9a\x57\xe3"
+ "\xc5\x43\x36\xde\x02\xac\x2c\x75"
+ "\xea\x33\x3a\x7e\x5d\xb8\xf6\x12"
+ "\x42\xbd\x06\x8a\x09\x6b\xd6\xb6"
+ "\x25\x59\xcd\xbd\x17\xeb\x69\xb3",
+ .len = 80,
+ }, {
+ .key = "\x4c\xf4\xd0\x34\xd0\x95\xab\xae"
+ "\x82\x5c\xfd\xfa\x13\x86\x25\xce"
+ "\xf4\x13\x32\xcd\xc6\x6d\xf6\x50",
+ .klen = 24,
+ .iv = "\x12\x4a\x5b\x66\x3a\xd3\xfb\x1a"
+ "\xaf\x06\xea\xf4\x65\x59\xd6\xc2",
+ .ptext = "\x84\xa0\x53\x97\x61\x30\x70\x15"
+ "\xac\x45\x8e\xe8\xeb\xa1\x72\x93"
+ "\x26\x76\x98\x6f\xe4\x86\xca\xf0"
+ "\x57\x89\xf2\x2b\xd4\xcf\x2d\x95"
+ "\x86\x26\x20\x0e\x62\xfe\x8f\x1e"
+ "\x5d\xcb\x2b\x7e\xdd\xab\xac\xda"
+ "\x6e\x49\x20\xd5\xb7\x01\x83\x4e"
+ "\xac\x45\x8f\xe1\x05\x3f\xd5\xb1"
+ "\xee\xb7\x0d\x65\x00\x38\xab\x71"
+ "\x70\x6e\xb3\x97\x86\xd3\xcd\xad"
+ "\x51\x8b\x9c\xa0\x9a\x8b\x4c\xb9"
+ "\x16\x01\x6a\x1f\xdf\xf0\xf9\x9e",
+ .ctext = "\x03\x2c\x39\x24\x99\xb5\xf6\x79"
+ "\x91\x89\xb7\xf8\x89\x68\x37\x9d"
+ "\xe7\x4d\x7d\x1c\x36\xae\x98\xd2"
+ "\xbf\x2a\xa4\x30\x38\x30\xe7\x5d"
+ "\xbb\x00\x09\x40\x34\xa4\xef\x82"
+ "\x23\xca\x0e\xb3\x71\x80\x29\x0a"
+ "\xa9\x0b\x26\x65\x9a\x12\xbf\x18"
+ "\xfb\xf8\xe4\xc2\x62\x57\x18\xfb"
+ "\x1e\x98\xea\x5b\xf6\xd6\x7c\x52"
+ "\x7a\xba\x0e\x6a\x54\x19\xb6\xfa"
+ "\xe5\xd7\x60\x40\xb0\x1a\xf1\x09"
+ "\x70\x96\x23\x49\x98\xfc\x79\xd2",
+ .len = 96,
+ }, {
+ .key = "\x25\x1b\xc2\xa6\x21\x25\xeb\x97"
+ "\x4b\xf6\xcb\x3b\xcd\x61\xfd\x94"
+ "\x37\x03\xb3\xd9\x74\x6e\x4d\xbb",
+ .klen = 24,
+ .iv = "\xfd\x87\x2b\xec\x4c\x2c\xbf\xe2"
+ "\x94\x1a\xe6\xd9\xaf\x0e\x78\x17",
+ .ptext = "\x58\x2b\x1d\x73\x9a\x9c\x63\x18"
+ "\x88\x7a\x0e\x87\x2f\xf0\xb0\xdb"
+ "\xc9\x9d\x79\x51\x34\x39\x4f\x07"
+ "\xa2\x7c\x21\x04\x91\x3b\x79\x79"
+ "\xfe\xd5\x51\x46\xd5\xcd\x28\xc0"
+ "\xad\xb8\x55\xb2\xb2\x5a\x9a\xa2"
+ "\xe2\x0c\xfc\x55\x7d\x60\xd2\x95"
+ "\xb6\x08\x1d\x31\xaf\xf4\x17\x46"
+ "\xa4\xbb\x0f\xbd\x67\x3c\x73\x15"
+ "\x0c\x85\x2f\x62\xe5\xf4\x35\x96"
+ "\xb1\x9b\x5d\x00\x10\xe9\x70\x12"
+ "\x3a\x87\x7f\x67\xf1\x81\x7a\x05"
+ "\xb4\xa6\xfe\xdf\x36\x31\x6d\x9e"
+ "\x0e\xa9\x44\xa0\xb0\x05\xa9\x41",
+ .ctext = "\xd4\x9a\x04\x54\x05\xd2\xe6\x3f"
+ "\xb0\xa4\x36\x5e\x1e\x9c\x35\xb0"
+ "\xa6\x62\x35\x47\xf4\x4d\x08\x9e"
+ "\x1c\x22\x91\x8e\x7f\x00\xa6\x3e"
+ "\x0a\x04\x42\x0f\xc4\xa6\x5d\xe2"
+ "\x49\x4c\x61\x12\xea\x9d\x7d\x7c"
+ "\xfa\x93\x74\x6b\x79\x8c\xdb\xc6"
+ "\x47\xf6\xea\x84\x3e\x97\x7d\x87"
+ "\x40\x38\x92\xc7\x44\xef\xdf\x63"
+ "\x29\xe4\x5b\x3a\x87\x22\xa1\x3f"
+ "\x2b\x31\xb1\xa4\x0d\xea\xf3\x0b"
+ "\xd7\x4f\xb6\x9c\xba\x40\xa3\x2f"
+ "\x21\x2b\x05\xe4\xca\xef\x87\x04"
+ "\xe6\xd0\x29\x2c\x29\x26\x57\xcd",
+ .len = 112,
+ }, {
+ .key = "\x9c\x14\x44\x5a\xd5\x1c\x50\x08"
+ "\x95\xc2\xf2\xaf\x3f\x29\xc9\x3e"
+ "\x95\x5e\xc6\xb4\x2b\xf4\x3e\xe3",
+ .klen = 24,
+ .iv = "\x1b\xeb\x3d\x73\xfb\xd7\x1e\x2b"
+ "\x0c\x3d\x58\x6c\xb4\x41\x9b\xfe",
+ .ptext = "\x2f\x7e\x1c\x10\x81\x36\x2d\x79"
+ "\xaf\xab\x10\x44\x2e\xcc\x0d\x6c"
+ "\x9c\x14\xc2\xe4\xae\xb0\xbb\xda"
+ "\x6a\xe0\x42\x3d\x96\x9f\x78\x7d"
+ "\x70\x86\xa5\x92\x9f\xee\xcd\x3f"
+ "\x6a\x55\x84\x98\x28\x03\x02\xc2"
+ "\xf7\xec\x7a\xfa\xb1\xd9\xa8\xd8"
+ "\x1c\xc3\xaa\xd5\x61\x7f\x10\x0c"
+ "\xc0\xa1\x36\x3d\x81\x9a\xd2\x17"
+ "\x2e\x23\xc9\xb7\xff\xdf\x47\x6c"
+ "\x96\x3b\x0e\xbd\xec\x9a\x0e\xad"
+ "\x8c\xaf\x36\x3d\xff\x29\x8b\x33"
+ "\x87\x96\x77\x1a\x10\x81\x63\x8a"
+ "\x63\xde\x88\xa9\x9d\xa9\x01\xf2"
+ "\xdf\xc9\x25\x35\x48\x3a\x15\xdf"
+ "\x20\x6b\x91\x7c\x56\xe5\x10\x7a",
+ .ctext = "\xbc\x57\x2a\x88\x0a\xd0\x06\x4f"
+ "\xdb\x7b\x03\x9f\x97\x1a\x20\xfe"
+ "\xdb\xdc\x8e\x7b\x68\x13\xc8\xf5"
+ "\x06\xe3\xe0\x7e\xd3\x51\x21\x86"
+ "\x4f\x32\xdb\x78\xe3\x26\xbe\x34"
+ "\x52\x4c\x4e\x6b\x85\x52\x63\x8b"
+ "\x8c\x5c\x0e\x33\xf5\xa3\x88\x2d"
+ "\x04\xdc\x01\x2d\xbe\xa1\x48\x6d"
+ "\x50\xf4\x16\xb1\xd7\x4d\x1e\x99"
+ "\xa8\x1d\x54\xcb\x13\xf9\x85\x51"
+ "\x18\x9f\xef\x45\x62\x5d\x48\xe5"
+ "\x0c\x54\xf7\x7b\x33\x18\xce\xb0"
+ "\xd5\x82\x1b\xe2\x91\xae\xdc\x09"
+ "\xe2\x97\xa8\x27\x13\x78\xc6\xb8"
+ "\x20\x06\x1a\x71\x5a\xb3\xbc\x1b"
+ "\x69\x1f\xcd\x57\x70\xa7\x1e\x35",
+ .len = 128,
+ }, {
+ .key = "\x2d\x2e\x0f\x30\x32\xed\xa9\x1f"
+ "\x71\x4e\x68\x77\xe8\xa8\x5b\xdd"
+ "\x3c\x5e\x68\x6b\xab\x03\xe4\xf8",
+ .klen = 24,
+ .iv = "\x42\xc1\x61\x9a\x50\xfb\xc7\x6a"
+ "\x1a\x31\xa7\x87\xd0\x24\xcb\x5e",
+ .ptext = "\xc0\x3b\x12\x28\xca\x26\x7b\xb3"
+ "\x14\xc1\x7f\x66\xff\x3b\xa4\x80"
+ "\x59\x77\x4f\xa0\xd4\xb2\xd9\x8a"
+ "\xb6\x67\xe6\x28\xd3\x6f\xf2\xcf"
+ "\xb8\x6d\x2d\xc4\x2a\x69\x89\xff"
+ "\xcf\xbb\x11\x2e\x2a\x2b\x7c\xfd"
+ "\xcd\x56\x02\x95\xc9\x54\x6e\x62"
+ "\x6a\x97\x75\x1a\x21\x16\x46\xfb"
+ "\xc2\xab\x62\x54\xef\xba\xae\x46"
+ "\xd4\x14\xc6\xcc\x16\x1b\x95\xf9"
+ "\x05\x26\x23\x81\x19\x27\xad\x7b"
+ "\x9c\x8b\xfb\x65\xa4\x61\xee\x69"
+ "\x44\xbf\x59\xde\x03\x61\x11\x12"
+ "\x8d\x94\x48\x47\xa9\x52\x16\xfb"
+ "\x6b\xaf\x59\x6d\xab\x74\xbf\x5c"
+ "\xb6\x09\x21\x12\x42\x98\x13\xa1"
+ "\xa8\x6f\xb9\x6d\x4d\xa6\xdc\xea"
+ "\x61\x02\x3c\xa7\xcd\x1a\x28\x8c",
+ .ctext = "\xd7\xb4\xfc\xcc\x1f\xf7\xfc\x7d"
+ "\x69\xfa\xcb\x01\x60\xf3\x5a\x14"
+ "\x88\xf7\xea\x43\xaa\x47\xf1\x8a"
+ "\x4e\xd0\x3c\x50\x58\x35\x95\x21"
+ "\x5f\xcc\x73\x0b\x97\xa0\x2c\x6b"
+ "\x70\x4d\x3d\xa8\x21\xbe\xfc\xec"
+ "\xb6\x55\xf0\x48\x2b\x11\xcc\x4b"
+ "\xda\xf7\x09\xd9\x18\x7b\x4f\x00"
+ "\x76\x40\xe0\x7d\x33\xcf\x4f\x77"
+ "\x91\x97\x63\xfa\x72\xba\x5c\x3d"
+ "\xcf\x2e\xb8\x19\x56\x4a\xa5\x02"
+ "\xc3\xb1\x80\xa8\x57\x03\x32\x57"
+ "\xa8\xe1\x65\xf7\xd3\x52\xc5\xcf"
+ "\x55\x1e\x34\xe3\x77\xab\x83\xdb"
+ "\xaf\xd3\x8a\xcc\x96\x1c\xc9\x73"
+ "\xd9\x0b\xb6\x4c\x31\xac\x2c\x82"
+ "\xb8\xb4\xc8\xe1\xa5\x71\xcc\xb3"
+ "\x7e\x85\xb8\xfa\x6b\xef\x41\x24",
+ .len = 144,
+ }, {
+ .key = "\x66\xb8\x4d\x60\x67\x82\xcc\x8d"
+ "\x1e\xda\x8f\x28\xe5\x02\xdc\x2c"
+ "\x54\x84\x2a\x06\xb5\xd1\x34\x57",
+ .klen = 24,
+ .iv = "\xb8\x28\x4d\xf5\x69\xb9\xf3\x33"
+ "\x5e\x0b\xa6\x62\x35\x9b\xfb\x97",
+ .ptext = "\x3e\xc6\xec\xaf\x74\xe8\x72\x91"
+ "\xb2\xc6\x56\xb3\x23\x29\x43\xe0"
+ "\xfb\xcc\x21\x38\x64\x78\x9e\x78"
+ "\xbb\x6e\x0d\x7b\xfd\x05\x74\x01"
+ "\x7c\x94\xe0\xb0\xd7\x92\xfc\x58"
+ "\x28\xfc\xe2\x7b\x7f\xf7\x31\x0d"
+ "\x90\xb7\x60\x78\xa8\x9f\x52\xe3"
+ "\xe6\xaa\x2a\xb4\xa7\x09\x60\x53"
+ "\x42\x0e\x15\x31\xf6\x48\xa3\x0a"
+ "\x20\xf0\x79\x67\xb1\x83\x26\x66"
+ "\xe0\xb1\xb3\xbd\x1c\x76\x36\xfd"
+ "\x45\x87\xa4\x14\x1b\xef\xe7\x16"
+ "\xf7\xfa\x30\x3d\xb9\x52\x8f\x2e"
+ "\x01\x68\xc1\x7d\xa2\x15\x49\x74"
+ "\x53\x82\xc2\x10\xa8\x45\x73\x4d"
+ "\x41\xcc\x24\xa3\x42\xff\x30\xd1"
+ "\x02\x21\xdc\xd9\x08\xf7\xe7\x4c"
+ "\x33\x2d\x62\xc7\x38\xf5\xc2\xbe"
+ "\x52\xf1\x34\x78\x34\x53\x30\x5b"
+ "\x43\x43\x51\x6a\x02\x81\x64\x0c",
+ .ctext = "\x71\xf6\x96\x02\x07\x71\x1a\x08"
+ "\x7c\xfe\x33\xc4\xc9\xbe\xe2\xed"
+ "\xf8\x46\x69\xce\x1b\xdc\xd3\x05"
+ "\x7a\xec\x26\x4d\x27\x2a\x49\x36"
+ "\x85\xe1\x5d\xd3\x91\xd7\x68\xb8"
+ "\x55\xa5\x27\x55\x2d\xc1\x78\x27"
+ "\x0c\x49\x0a\x24\x3b\x76\x3f\x5f"
+ "\x29\x1c\x37\x2f\x30\xfc\x50\xcb"
+ "\xe2\x54\x26\x7d\x97\xa7\xf3\x58"
+ "\x15\xe1\x4c\xeb\x35\xc9\xd1\x1e"
+ "\x7e\x7d\xa0\xe5\x62\xa5\x2d\xf6"
+ "\x77\xb0\xef\x13\x55\xb4\x66\x2c"
+ "\x3b\x50\x1b\x4d\xc2\x64\xce\xc6"
+ "\xfe\xf2\xad\xfe\x26\x73\x36\x66"
+ "\x0c\x2f\x10\x35\x97\x3c\x9c\x98"
+ "\xc1\x90\xa8\x82\xd7\xc6\x31\x68"
+ "\xcf\x77\xa8\x5b\xdf\xf9\x5a\x8e"
+ "\x84\xb5\x0b\x6e\x5b\xec\x36\x89"
+ "\x0b\xb1\xbf\xb9\x70\x02\x5c\x22"
+ "\xc3\xd5\xc1\xc6\xfd\x07\xdb\x70",
+ .len = 160,
+ }, {
+ .key = "\x82\x8e\x9e\x06\x7b\xc2\xe9\xb3"
+ "\x06\xa3\xfa\x99\x42\x67\x87\xac"
+ "\x21\xc7\xb0\x98\x6c\xf8\x26\x57"
+ "\x08\xdd\x92\x02\x77\x7b\x35\xe7",
+ .klen = 32,
+ .iv = "\xa1\xad\xcb\xdd\xd5\x19\xb6\xd4"
+ "\x0b\x62\x58\xb0\x6c\xa0\xc1\x58",
+ .ptext = "\x14\x0d\x8a\x09\x16\x00\x00\xf1"
+ "\xc0\x20\x86\xf9\x21\xd1\x34\xe2",
+ .ctext = "\x05\xe3\x34\xaf\x6c\x83\x14\x8b"
+ "\x9d\x1c\xd6\x87\x74\x91\xdf\x17",
+ .len = 16,
+ }, {
+ .key = "\xc9\xf3\xc4\x93\xd0\xcc\xaf\xb1"
+ "\x1a\x42\x93\x71\xd8\x4e\xd8\xaa"
+ "\x52\xad\x93\x2f\xe5\xd9\xaa\x5b"
+ "\x47\x37\x3a\xed\x13\x92\x35\x16",
+ .klen = 32,
+ .iv = "\x81\xc8\x50\xd1\x74\xc3\x1c\x73"
+ "\xbb\xab\x72\x83\x90\x5a\x15\xcb",
+ .ptext = "\x65\x11\x93\xaf\xe1\x69\x6c\xbe"
+ "\x25\x8c\x76\x87\x53\xa4\x80\xae"
+ "\x51\x94\x36\x3f\xca\xe7\x45\x41"
+ "\x76\x05\xbf\x8f\x9c\xad\xc0\xe3",
+ .ctext = "\x6b\x00\x6e\x49\x7a\x6d\xe3\x04"
+ "\x4e\xf7\x9f\x8a\x1f\x14\xbd\xb1"
+ "\x51\xbf\x13\x9f\x29\x95\x51\x16"
+ "\xd0\x23\x9a\x1a\x45\xc2\xc3\xd1",
+ .len = 32,
+ }, {
+ .key = "\xd5\x9f\x52\x34\x12\x99\x8e\x42"
+ "\xe0\x85\x04\x6f\xeb\xf1\x5d\xd0"
+ "\xc1\xbf\x3f\x84\xd9\x1e\x71\x44"
+ "\xd4\xb9\x40\x3c\x02\x2e\x21\x19",
+ .klen = 32,
+ .iv = "\x28\xc1\x97\x64\x81\x52\x57\x0e"
+ "\x02\x8c\xab\x4c\xe2\x60\x14\xa5",
+ .ptext = "\x5a\xb1\x33\x48\xaa\x51\xe9\xa4"
+ "\x5c\x2d\xbe\x33\xcc\xc4\x7f\x96"
+ "\xe8\xde\x2b\xe7\x35\x7a\x11\x4b"
+ "\x13\x08\x32\xc6\x41\xd8\xec\x54"
+ "\xa3\xd3\xda\x35\x43\x69\xf6\x88"
+ "\x97\xca\x00\x1b\x02\x59\x24\x82",
+ .ctext = "\x03\xaf\x76\xbd\x5e\x5b\xca\xc0"
+ "\xae\x44\xa2\x2f\xc2\x76\x2f\x50"
+ "\xfa\x94\x94\x5a\x48\x9d\x9c\x38"
+ "\xc9\x75\xc9\xb2\x56\x0a\x2d\x91"
+ "\xb8\xe8\x4e\xaa\xcb\x51\x9b\x6a"
+ "\x20\x9b\x2b\xc5\xb0\x18\x9d\x01",
+ .len = 48,
+ }, {
+ .key = "\x9c\x5d\xd7\x66\x36\xfa\x02\x20"
+ "\x99\x61\x62\x86\x0f\x43\x2e\x05"
+ "\x25\x8b\xfb\xf1\xae\x4c\xde\x18"
+ "\x0b\xf8\xd0\x9d\xaa\xd4\x56\x04",
+ .klen = 32,
+ .iv = "\xcd\xa8\x61\x89\x8d\xbb\x72\xb6"
+ "\x1e\xfe\x03\x34\x54\x88\x23\xe2",
+ .ptext = "\x66\x42\x60\x24\xf3\xe4\xe9\x7e"
+ "\x42\x20\xf4\x61\xce\x1c\x5e\x44"
+ "\x02\x26\x91\xf7\x41\xa4\xab\x34"
+ "\x29\x49\xdd\x78\x19\x8f\x10\x10"
+ "\xf0\x61\xcf\x77\x18\x17\x61\xdf"
+ "\xc4\xa8\x35\x0e\x75\x1b\x84\x6b"
+ "\xc3\x3f\x31\x59\x5a\x9c\xf4\xc3"
+ "\x43\xa9\xb7\xf8\x65\x40\x40\xba",
+ .ctext = "\xb6\x41\x55\x8f\xeb\x16\x1e\x4c"
+ "\x81\xa0\x85\x6c\xf0\x07\xa5\x2a"
+ "\x19\x91\xed\x3e\xd6\x30\x8c\xca"
+ "\x5d\x0f\x58\xca\xd2\x8a\xac\xa2"
+ "\x2b\x86\x4f\xb5\x85\x4d\xac\x6d"
+ "\xe5\x39\x1b\x02\x23\x89\x4e\x4f"
+ "\x02\x00\xe8\x1b\x40\x85\x21\x2b"
+ "\xc6\xb1\x98\xed\x70\xb3\xf8\xc3",
+ .len = 64,
+ }, {
+ .key = "\x4b\x4e\x11\x91\x27\xcf\x8c\x66"
+ "\x17\xfa\x5b\x4c\xa8\xb8\x0f\xa1"
+ "\x99\x5b\x07\x56\xe1\x8d\x94\x8b"
+ "\xf2\x86\x5a\x5f\x40\x83\xfa\x06",
+ .klen = 32,
+ .iv = "\xfd\x73\xee\x1c\x27\xf3\xb4\x38"
+ "\xc5\x7c\x2e\xc5\x6e\xdb\x49\x0d",
+ .ptext = "\x0a\xe2\xdd\x97\xdd\x5e\xd4\xb3"
+ "\xc1\x49\x8f\x53\xb2\x40\x85\x1c"
+ "\x90\x37\x2d\xbd\x21\x6b\x1f\x80"
+ "\x56\x98\x76\x1e\xcf\x6c\x78\xd8"
+ "\xa0\x3c\x79\xc3\x56\xf7\xfc\x64"
+ "\x35\x58\x1c\x7c\xc4\x5f\x2a\x25"
+ "\x8c\x01\x98\x1e\x1c\x1f\x15\x64"
+ "\x50\xb5\xfa\x02\xd3\x54\xe5\x29"
+ "\xe3\xd2\xa3\x83\x54\x40\x54\xc5"
+ "\xd8\x1c\xc9\x84\x7d\xc8\x31\x49",
+ .ctext = "\x53\x2a\xa8\xa0\x15\xaf\x2f\xc4"
+ "\x7d\x31\xb4\x61\x80\x5f\xd1\xb6"
+ "\x7c\xca\x86\xb9\x28\x6e\xb6\x2b"
+ "\xe3\x4b\x7e\xea\xb3\x4f\xa2\xa2"
+ "\x4e\x8f\xbe\x22\x66\xb3\x92\xbc"
+ "\x70\x91\xaf\xa6\x09\x5d\xe2\x05"
+ "\x38\x62\xd3\x6e\x07\x63\x91\xad"
+ "\x48\x5a\x42\xe7\xdc\x0d\xb1\xe3"
+ "\x92\x88\x64\xee\x93\xaa\xaf\x31"
+ "\x68\x57\x35\x8d\x54\x2c\xfa\xb1",
+ .len = 80,
+ }, {
+ .key = "\x77\x3b\xf5\xe7\x20\xf7\xe0\x0c"
+ "\x3d\x3a\x83\x17\x83\x79\xd8\x29"
+ "\x5a\x0a\x25\x7f\xe0\x21\x23\xff"
+ "\x31\xfd\x60\x10\xe6\x63\xe2\xaf",
+ .klen = 32,
+ .iv = "\xdb\x4c\x0d\xc0\x36\xdb\xc7\xa1"
+ "\xa4\x91\xd9\x05\xe6\xc4\x98\x00",
+ .ptext = "\x8d\x4d\xc6\x5e\x01\x82\xb3\x39"
+ "\xc8\x64\xa7\xcb\x05\x19\x84\x80"
+ "\x3f\x9c\xa8\x4f\x64\xb3\x11\x4b"
+ "\x0e\x21\xc4\x75\x04\x1d\x6f\xd5"
+ "\x04\x04\x4d\xc9\xc0\x4b\x4a\x9c"
+ "\x26\xb7\x68\x5a\xe4\xd0\x61\xe3"
+ "\x2c\x93\x8e\x3f\xb4\x67\x07\x31"
+ "\x02\x52\x0c\x0f\xe6\x6d\xa3\xd0"
+ "\x48\x95\x83\x67\x23\x64\x31\x50"
+ "\xd2\x5f\x69\x68\x8b\x71\xbf\x01"
+ "\x29\x99\x86\x36\x2e\xdf\xf1\x7c"
+ "\x08\x8c\x78\x7a\x93\x9a\x7d\x1b",
+ .ctext = "\x92\x90\x48\x2f\x3a\x6b\x68\x43"
+ "\x28\x9b\x7d\x1e\x46\x28\xd8\x58"
+ "\xd9\x1e\x44\xd7\x24\x91\x65\xb1"
+ "\x15\xde\xc4\x63\xf1\xb1\x34\x9e"
+ "\xae\x8c\x51\x94\xc5\x22\x65\x8d"
+ "\x3d\x85\xf5\x34\x5f\x04\x68\x95"
+ "\xf2\x66\x62\xbb\xc8\x3f\xe4\x0a"
+ "\x8a\xb2\x70\xc0\x77\xd5\x96\xef"
+ "\x9e\x39\x3a\x3e\x0d\x2b\xf9\xfe"
+ "\xa9\xbc\x00\xba\xc5\x43\xd7\x70"
+ "\x2f\xef\x1e\x1e\x93\xc2\x5d\xf1"
+ "\xb5\x50\xb8\xf5\xee\xf4\x26\x6f",
+ .len = 96,
+ }, {
+ .key = "\xe0\x6a\x30\xe1\x35\xb5\xb0\x7c"
+ "\x54\xc5\x73\x9b\x00\xe5\xe7\x02"
+ "\xbe\x16\x59\xdc\xd9\x03\x17\x53"
+ "\xa8\x37\xd1\x5f\x13\x8e\x45\xdb",
+ .klen = 32,
+ .iv = "\x54\xe9\x1c\xde\xfb\x26\x0e\x48"
+ "\x35\x50\x4d\x9b\x4d\x12\x21\x0d",
+ .ptext = "\x73\x72\xcf\xdb\xbd\xbc\xc0\xdf"
+ "\x6b\xbb\xdf\x65\x6f\x2f\x43\x3b"
+ "\x2d\x7c\x0e\x07\x7f\xa0\x95\xdd"
+ "\xfc\x67\xc1\x11\x7a\xe2\xb5\x4a"
+ "\xd1\x15\xb0\xd8\xe2\xf0\x35\x48"
+ "\xd8\x81\x6a\x35\xae\x67\xbf\x61"
+ "\xf2\x8a\xcf\x04\xc8\x09\x8b\x63"
+ "\x31\x74\x95\xa5\x8d\x3c\xea\xe2"
+ "\x5f\x67\xc4\x7e\x51\x88\xbf\xb5"
+ "\x78\xef\x3a\x76\xd8\x1d\x00\x75"
+ "\x2b\x7b\x28\x7c\xde\x4b\x39\x01"
+ "\x5d\xde\x92\xfe\x90\x07\x09\xfd"
+ "\xa5\xd1\xd3\x72\x11\x6d\xa4\x4e"
+ "\xd1\x6e\x16\xd1\xf6\x39\x4f\xa0",
+ .ctext = "\x3b\xc5\xee\xfc\x05\xaf\xa6\xb7"
+ "\xfe\x12\x24\x79\x31\xad\x32\xb5"
+ "\xfb\x71\x9b\x02\xad\xf4\x94\x20"
+ "\x25\x7b\xdb\xdf\x97\x99\xca\xea"
+ "\xc4\xed\x32\x26\x6b\xc8\xd4\x7b"
+ "\x5b\x55\xfa\xf9\x5b\xab\x88\xdb"
+ "\x48\xfe\x67\xd5\x5a\x47\x81\x4e"
+ "\x3e\x1e\x83\xca\x1d\x04\xe1\xb5"
+ "\x6c\x1b\xbd\xf2\x2d\xf1\xae\x75"
+ "\x09\x6a\xf8\xb2\xc3\x27\xee\x08"
+ "\x66\x94\x72\xc0\x2b\x12\x47\x23"
+ "\x4d\xde\xb4\xca\xf7\x66\xca\x14"
+ "\xe7\x68\x1b\xfb\x48\x70\x3e\x4c"
+ "\x43\xbb\x88\x32\x25\xff\x77\x6a",
+ .len = 112,
+ }, {
+ .key = "\x60\xb6\xde\x17\xca\x4c\xe7\xe0"
+ "\x07\x0d\x80\xc5\x8a\x2d\x5a\xc2"
+ "\x2c\xb9\xa4\x5f\x2a\x85\x2c\x3d"
+ "\x6d\x67\xc8\xee\x0f\xa2\xf4\x09",
+ .klen = 32,
+ .iv = "\x1a\xa5\xbc\x7e\x93\xf6\xdd\x28"
+ "\xb7\x69\x27\xa1\x84\x95\x25\x5a",
+ .ptext = "\x7b\x88\x00\xeb\xa5\xba\xa1\xa7"
+ "\xd4\x40\x16\x74\x2b\x42\x37\xda"
+ "\xe0\xaf\x89\x59\x41\x2f\x62\x00"
+ "\xf5\x5a\x4e\x3b\x85\x27\xb2\xed"
+ "\x1b\xa7\xaf\xbe\x89\xf3\x49\xb7"
+ "\x8c\x63\xc9\x0c\x52\x00\x5f\x38"
+ "\x3b\x3c\x0c\x4f\xdd\xe1\xbf\x90"
+ "\x4a\x48\xbf\x3a\x95\xcb\x48\xa2"
+ "\x92\x7c\x79\x81\xde\x18\x6e\x92"
+ "\x1f\x36\xa9\x5d\x8d\xc4\xb6\x4d"
+ "\xb2\xb4\x0e\x09\x6d\xf3\x3d\x01"
+ "\x3d\x9b\x40\x47\xbc\x69\x31\xa1"
+ "\x6a\x71\x26\xdc\xac\x10\x56\x63"
+ "\x15\x23\x7d\x10\xe3\x76\x82\x41"
+ "\xcd\x80\x57\x2f\xfc\x4d\x22\x7b"
+ "\x57\xbb\x9a\x0a\x03\xe9\xb3\x13",
+ .ctext = "\x37\x0d\x47\x21\xbc\x28\x0b\xf7"
+ "\x85\x5f\x60\x57\xf2\x7f\x92\x20"
+ "\x5f\xa7\xf6\xf4\xa6\xf5\xdf\x1e"
+ "\xae\x8e\xeb\x97\xfc\xce\x6a\x25"
+ "\x6d\x6a\x5b\xd1\x99\xf6\x27\x77"
+ "\x52\x0c\xf1\xd7\x94\xa0\x67\x5d"
+ "\x60\x35\xb0\x6d\x01\x45\x52\xc8"
+ "\x05\xd8\x7f\x69\xaf\x8e\x68\x05"
+ "\xa8\xa5\x24\x2f\x95\xef\xf1\xd2"
+ "\x8c\x45\x12\xc5\x7a\xcf\xbb\x99"
+ "\x25\xaa\xa3\x9b\x3f\xf1\xfc\x9d"
+ "\xfa\x2c\x26\x9b\x92\x47\x61\x6b"
+ "\x63\x1e\x41\x67\xcb\xb7\x0f\x52"
+ "\x70\xd4\x0d\x7e\xef\x34\xa2\x75"
+ "\x4f\x6a\x55\x9c\x2b\x4a\x02\xdd"
+ "\x96\x5d\xcb\xca\x45\xa1\xec\xaa",
+ .len = 128,
+ }, {
+ .key = "\x2a\xed\x7d\x76\xfc\xc5\x49\x50"
+ "\xf4\x90\x0f\xcc\x5d\xff\x0c\x3c"
+ "\x14\x06\xaf\x68\x8f\xd7\xb6\x25"
+ "\x1e\x10\x95\x2a\x71\x33\x17\x20",
+ .klen = 32,
+ .iv = "\x5b\x58\x47\xf8\xd5\x1e\x91\x81"
+ "\x46\xe7\x25\x3a\x02\x45\x9c\x65",
+ .ptext = "\x10\xaf\xde\x5c\x30\x79\x43\x28"
+ "\x1c\x03\xf8\x50\x0f\x30\xa5\xef"
+ "\x84\x19\x4c\x09\x40\x03\x75\x1f"
+ "\x92\x8f\x88\x01\xda\x31\x7a\xe4"
+ "\x48\xe3\xab\xb4\xe6\x1b\x0f\xac"
+ "\xd9\xfa\x8d\x23\xe4\xc6\xa4\xa9"
+ "\x2d\x9a\x54\x52\x44\x5c\x3c\x52"
+ "\x61\xf0\x00\xca\xed\xab\xed\xe2"
+ "\x44\x0b\xe0\x18\xba\xa5\x63\xd8"
+ "\xdc\x5e\x1a\x4c\xf8\xde\x5e\x75"
+ "\xdf\x42\x27\x7b\xe9\x11\x2f\x41"
+ "\x3a\x72\x54\x3d\x44\x9c\x3e\x87"
+ "\x8d\x8d\x43\x2f\xb2\xff\x87\xd4"
+ "\xad\x98\x68\x72\x53\x61\x19\x7c"
+ "\x20\x79\x8c\x2b\x37\x0b\x96\x15"
+ "\xa5\x7d\x4e\x01\xe6\xea\xb6\xfa"
+ "\xaa\xd3\x9d\xa2\xd9\x11\xc3\xc9"
+ "\xd4\x0e\x3f\x3e\xfe\x35\x1e\xe5",
+ .ctext = "\xb0\x2b\x75\x5f\x33\x1b\x05\x49"
+ "\x06\xf1\x43\x91\xc2\x85\xfa\xac"
+ "\x3f\x47\xf3\x89\x73\xb2\x0e\xa4"
+ "\x30\xcb\x87\x39\x53\x5d\x36\x89"
+ "\x77\xd9\x17\x01\x95\xa6\xe9\x71"
+ "\x51\x53\xd9\x4f\xa6\xc2\x79\x3d"
+ "\x2e\x50\x90\x52\x0d\x27\x1a\x46"
+ "\xf1\xe8\x6e\x7e\x7b\x32\xe5\x22"
+ "\x22\x1f\xba\x5e\xcf\x25\x6b\x26"
+ "\x76\xf0\xca\x8e\xdd\x5b\xd3\x09"
+ "\x6f\x82\x08\x56\x1f\x51\x72\x57"
+ "\xca\xd1\x60\x07\xfb\x9f\x71\x54"
+ "\x0f\xf6\x48\x71\xfa\x8f\xcb\xdd"
+ "\xce\xd3\x16\xcd\xae\x0e\x67\x5e"
+ "\xea\x8d\xa2\x4a\x4f\x11\xc8\xc8"
+ "\x2f\x04\xfe\xa8\x2a\x07\x1c\xb1"
+ "\x77\x39\xda\x8b\xd9\x5c\x94\x6c"
+ "\x4d\x4d\x13\x51\x6f\x07\x06\x5b",
+ .len = 144,
+ }, {
+ .key = "\x7b\xa7\x4d\x0a\x37\x30\xb9\xf5"
+ "\x2a\x79\xb4\xbf\xdb\x7f\x9b\x64"
+ "\x23\x43\xb5\x18\x34\xc4\x5f\xdf"
+ "\xd9\x2a\x66\x58\x00\x44\xb5\xd9",
+ .klen = 32,
+ .iv = "\x75\x34\x30\xc1\xf0\x69\xdf\x0a"
+ "\x52\xce\x4f\x1e\x2c\x41\x35\xec",
+ .ptext = "\x81\x47\x55\x3a\xcd\xfe\xa2\x3d"
+ "\x45\x53\xa7\x67\x61\x74\x25\x80"
+ "\x98\x89\xfe\xf8\x6a\x9f\x51\x7c"
+ "\xa4\xe4\xe7\xc7\xe0\x1a\xce\xbb"
+ "\x4b\x46\x43\xb0\xab\xa8\xd6\x0c"
+ "\xa0\xf0\xc8\x13\x29\xaf\xb8\x01"
+ "\x6b\x0c\x7e\x56\xae\xb8\x58\x72"
+ "\xa9\x24\x44\x61\xff\xf1\xac\xf8"
+ "\x09\xa8\x48\x21\xd6\xab\x41\x73"
+ "\x70\x6b\x92\x06\x61\xdc\xb4\x85"
+ "\x76\x26\x7a\x84\xc3\x9e\x3a\x14"
+ "\xe7\xf4\x2d\x95\x92\xad\x18\xcc"
+ "\x44\xd4\x2c\x36\x57\xed\x2b\x9b"
+ "\x3f\x2b\xcd\xe5\x11\xe3\x62\x33"
+ "\x42\x3f\xb8\x2a\xb1\x37\x3f\x8b"
+ "\xe8\xbd\x6b\x0b\x9f\x38\x5a\x5f"
+ "\x82\x34\xb7\x96\x35\x58\xde\xab"
+ "\x94\x98\x41\x5b\x3f\xac\x0a\x34"
+ "\x56\xc0\x02\xef\x81\x6d\xb1\xff"
+ "\x34\xe8\xc7\x6a\x31\x79\xba\xd8",
+ .ctext = "\x4e\x00\x7c\x52\x45\x76\xf9\x3d"
+ "\x1a\xd1\x72\xbc\xb9\x0f\xa9\xfb"
+ "\x0e\x5b\xe2\x3c\xc7\xae\x92\xf6"
+ "\xb8\x0b\x0a\x95\x40\xe9\x7f\xe0"
+ "\x54\x10\xf9\xf6\x23\x1f\x51\xc8"
+ "\x16\x8b\x2e\x79\xe1\x8c\x0b\x43"
+ "\xe5\xeb\xb5\x9d\x1e\xc3\x28\x07"
+ "\x5c\x8d\xb1\xe7\x80\xd3\xce\x62"
+ "\x8d\xf8\x31\x1f\x29\x8b\x90\xee"
+ "\xe5\xc3\xfa\x16\xc4\xf0\xc3\x99"
+ "\xe9\x5e\x19\xba\x37\xb8\xc0\x87"
+ "\xb5\xc6\xc9\x31\xcb\x6e\x30\xce"
+ "\x03\x1d\xfe\xce\x08\x32\x00\xeb"
+ "\x86\xc4\xfb\x48\x01\xda\x93\x73"
+ "\xcc\xb7\xae\x4e\x94\x20\xeb\xc7"
+ "\xe3\x33\x4c\xeb\xed\xe2\xfc\x86"
+ "\x0e\x73\x32\xf9\x1b\xf3\x25\xf3"
+ "\x74\xad\xd1\xf4\x2c\x45\xa4\xfd"
+ "\x52\x40\xa2\x4e\xa5\x62\xf6\x02"
+ "\xbb\xb0\xe3\x23\x86\x67\xb8\xf6",
+ .len = 160,
+ }
+};
+
+static const struct cipher_testvec aria_cfb_tv_template[] = {
+ {
+ .key = "\x7f\x92\xd5\x06\x30\x6b\xc0\x23"
+ "\x87\xa8\x8e\x6d\xc7\xc5\xd7\xf1",
+ .klen = 16,
+ .iv = "\x5f\xce\x89\xb3\xd5\x7f\x7f\xf0"
+ "\xfd\xab\x56\xa6\x6e\xda\x7c\x57",
+ .ptext = "\x36\x36\x89\x09\xcd\xa8\xd3\x91"
+ "\x48\x3e\x3c\x11\xcf\xd0\x4f\xc0",
+ .ctext = "\x19\x28\xb5\xf2\x1c\xbc\xf8\xaf"
+ "\xb9\xae\x1b\x23\x4f\xe1\x6e\x40",
+ }, {
+ .key = "\x51\xe3\x8c\xe9\x76\xcd\xff\x37"
+ "\xd6\x1a\x18\x2f\x68\x2f\xb6\xfe",
+ .klen = 16,
+ .iv = "\x3d\x2d\x85\x75\x6e\x18\x8a\x52"
+ "\x53\x39\xfc\xc1\xf5\xc0\x56\x22",
+ .ptext = "\xc6\xae\xaa\x0d\x90\xf2\x38\x93"
+ "\xac\xd2\x3f\xc7\x74\x8d\x13\x7e"
+ "\xfa\x3f\x70\x52\xfb\x04\x0e\xed"
+ "\x0e\x60\x75\x84\x21\xdf\x13\xa1",
+ .ctext = "\x3f\x8c\xa9\x19\xd6\xb4\xfb\xed"
+ "\x9c\x6d\xaa\x1b\xe1\xc1\xe6\xa8"
+ "\x47\x35\x7d\xa3\x96\x7d\x53\x60"
+ "\xa9\x33\x9c\x34\xae\x7d\x7c\x74",
+ .len = 32,
+ }, {
+ .key = "\x26\xf8\x8c\x26\x0a\x37\x51\x8f"
+ "\xe7\x9c\x74\x77\x7a\x3e\xbb\x5d",
+ .klen = 16,
+ .iv = "\xd7\x33\xf3\xa9\x5b\xb4\x86\xea"
+ "\xe3\x7d\x50\x62\x3b\x73\xaf\xc4",
+ .ptext = "\xda\x89\xd9\x3c\xcc\xe4\x73\xb0"
+ "\xef\x3e\x5f\x46\x62\x88\xd5\x26"
+ "\x3b\xd3\xb5\x81\x78\x70\x1b\xd2"
+ "\x39\x56\x34\x63\x2c\xc5\x51\x13"
+ "\x48\x29\x3a\x58\xbe\x41\xc5\x80"
+ "\x2c\x80\xa7\x3c\x14\xb4\x89\x5e",
+ .ctext = "\x28\xd8\xa7\xf8\x74\x98\x00\xfc"
+ "\xd6\x48\xad\xbd\xbe\x3f\x0e\x7b"
+ "\xa3\xec\x03\x6a\xfb\xc9\x01\x83"
+ "\xb3\x2f\xda\x5e\x66\xa0\xc3\xec"
+ "\xe9\xd4\x72\x2a\xa2\x90\x41\xcf"
+ "\xde\x30\x79\xc3\x82\x10\x51\xe1",
+ .len = 48,
+ }, {
+ .key = "\x8e\xe5\x5f\xe2\x39\x80\xf5\x2b"
+ "\x77\xb5\xca\x90\xda\x1d\x22\x17",
+ .klen = 16,
+ .iv = "\xd9\xa0\x57\x80\xc8\x96\x70\x86"
+ "\x07\x2c\xf4\x61\x79\x09\x01\x8f",
+ .ptext = "\x37\x32\x98\xd4\x86\x2b\x3b\x80"
+ "\x07\x60\xba\xf0\x2e\xc3\x4a\x57"
+ "\xf5\xb5\xd7\xbf\xd2\x2a\x9b\x4a"
+ "\xe6\x08\xf0\xbe\x77\xd1\x62\x40"
+ "\xa0\x82\x09\x60\x47\xbb\x16\x56"
+ "\x50\x1f\xab\x8b\x10\xfe\xf0\x5c"
+ "\x05\x32\x63\x1a\xc4\x46\x6f\x55"
+ "\x32\xde\x41\x5a\xf7\x52\xd7\xfa",
+ .ctext = "\x29\x31\x55\xd2\xe5\x0b\x81\x39"
+ "\xf9\xbc\x63\xe2\xfa\x26\x99\xde"
+ "\x5c\xd3\x0a\x56\xe5\xfc\x83\xdd"
+ "\xab\x26\x90\x7d\xa8\x0f\x01\xa6"
+ "\x0e\x01\xdc\x1f\xfa\xa7\xdd\x09"
+ "\xf9\xbf\x12\xf4\xc6\x9f\xbd\x57"
+ "\x23\x68\x54\x0f\xe0\xcf\x1c\x6d"
+ "\xe1\x5e\x0b\x4a\x1e\x71\x1d\xaa",
+ .len = 64,
+ }, {
+ .key = "\x30\x9d\x59\x8d\x64\x76\xad\x37"
+ "\xba\xbc\x46\x6a\x69\x17\x3c\xac",
+ .klen = 16,
+ .iv = "\x6f\xdd\xa2\x9b\x86\x32\x14\x2e"
+ "\x54\x74\x8f\x3d\xe2\xd6\x85\x44",
+ .ptext = "\x4f\x4a\x31\x64\xc6\xa5\x29\xaa"
+ "\xad\xfd\x32\x94\x1f\x56\x57\xd1"
+ "\x9d\x7e\x3d\x49\x00\x36\xb1\x5d"
+ "\xb2\x92\x83\x70\x1e\xa3\x97\xa6"
+ "\x65\x53\x39\xeb\x53\x8f\xb1\x38"
+ "\x91\xac\x17\x11\x1c\x03\x69\x53"
+ "\xf5\xdf\xdb\x2c\x1b\x9a\x6e\x6b"
+ "\xb6\x02\xc4\xfa\x95\x01\x33\xa8"
+ "\xda\x7e\x18\x2c\xf4\x7e\x6e\x67"
+ "\xce\x8f\x9f\xea\x46\x66\x99\xb8",
+ .ctext = "\x38\xbc\xf5\x9d\x0e\x26\xa6\x18"
+ "\x95\x0b\x23\x54\x09\xa1\xf9\x46"
+ "\x7a\x31\xa0\xd7\x4a\xec\xb3\x10"
+ "\x8a\x8e\x99\x78\x6c\x6e\x76\xf2"
+ "\x63\x8a\x3b\x90\xaa\xd5\x64\x65"
+ "\x5a\x52\xb0\x36\x4c\xce\xed\xc7"
+ "\x51\x3c\x06\xb0\xee\x54\xec\x10"
+ "\xc0\x5f\xfd\xa9\x44\x9a\x29\x32"
+ "\x19\x79\x7d\x2b\x14\x26\x96\x13"
+ "\x9d\xa5\x61\xbd\xb6\x72\x37\x26",
+ .len = 80,
+ }, {
+ .key = "\xe1\xc7\x25\x4d\xbd\xa5\x74\xdf"
+ "\xc7\x8b\xfb\xe3\x2d\x3a\x82\xd3",
+ .klen = 16,
+ .iv = "\x17\x94\x77\x2f\x92\xb8\x87\xc2"
+ "\xcc\x6f\x70\x26\x87\xc7\x10\x8a",
+ .ptext = "\xc8\xfd\xc2\xb3\xcf\xa0\xeb\x41"
+ "\x4c\xf4\xd0\x34\xd0\x95\xab\xae"
+ "\x82\x5c\xfd\xfa\x13\x86\x25\xce"
+ "\xf4\x13\x32\xcd\xc6\x6d\xf6\x50"
+ "\x12\x4a\x5b\x66\x3a\xd3\xfb\x1a"
+ "\xaf\x06\xea\xf4\x65\x59\xd6\xc2"
+ "\x84\xa0\x53\x97\x61\x30\x70\x15"
+ "\xac\x45\x8e\xe8\xeb\xa1\x72\x93"
+ "\x26\x76\x98\x6f\xe4\x86\xca\xf0"
+ "\x57\x89\xf2\x2b\xd4\xcf\x2d\x95"
+ "\x86\x26\x20\x0e\x62\xfe\x8f\x1e"
+ "\x5d\xcb\x2b\x7e\xdd\xab\xac\xda",
+ .ctext = "\xdf\x79\x58\x30\x6f\x47\x12\x78"
+ "\x04\xb2\x0b\x1a\x62\x22\xe2\x9f"
+ "\xfe\x90\x50\x41\x1b\x6a\x6a\x9c"
+ "\x4e\x77\x8f\xca\xd1\x68\x31\xcd"
+ "\x41\x82\xa5\x5b\xc0\x08\x2b\x37"
+ "\x62\xec\x95\xf1\x56\x12\x38\x66"
+ "\x84\x82\x72\xda\x00\x21\x96\x82"
+ "\x33\xd4\x99\xaa\xb9\xeb\xd5\xc3"
+ "\x2b\xa8\xf7\xdc\x13\x0e\x21\x9f"
+ "\x4b\xf9\x42\x58\xa8\x39\x10\xd5"
+ "\x86\xa5\xc6\x78\x3b\x34\x05\x03"
+ "\x54\x43\x2b\x80\xa9\x53\x4d\x0e",
+ .len = 96,
+ }, {
+ .key = "\x6e\x49\x20\xd5\xb7\x01\x83\x4e"
+ "\xac\x45\x8f\xe1\x05\x3f\xd5\xb1",
+ .klen = 16,
+ .iv = "\xee\xb7\x0d\x65\x00\x38\xab\x71"
+ "\x70\x6e\xb3\x97\x86\xd3\xcd\xad",
+ .ptext = "\x51\x8b\x9c\xa0\x9a\x8b\x4c\xb9"
+ "\x16\x01\x6a\x1f\xdf\xf0\xf9\x9e"
+ "\x25\x1b\xc2\xa6\x21\x25\xeb\x97"
+ "\x4b\xf6\xcb\x3b\xcd\x61\xfd\x94"
+ "\x37\x03\xb3\xd9\x74\x6e\x4d\xbb"
+ "\xfd\x87\x2b\xec\x4c\x2c\xbf\xe2"
+ "\x94\x1a\xe6\xd9\xaf\x0e\x78\x17"
+ "\x58\x2b\x1d\x73\x9a\x9c\x63\x18"
+ "\x88\x7a\x0e\x87\x2f\xf0\xb0\xdb"
+ "\xc9\x9d\x79\x51\x34\x39\x4f\x07"
+ "\xa2\x7c\x21\x04\x91\x3b\x79\x79"
+ "\xfe\xd5\x51\x46\xd5\xcd\x28\xc0"
+ "\xad\xb8\x55\xb2\xb2\x5a\x9a\xa2"
+ "\xe2\x0c\xfc\x55\x7d\x60\xd2\x95",
+ .ctext = "\xe4\x25\x0d\x22\xeb\xbe\x5e\x90"
+ "\x01\xe5\xae\xc9\x94\xbd\x93\x89"
+ "\x5e\x5a\x5a\x2f\xf6\xdf\xf8\x16"
+ "\xd3\xb2\xed\x29\x51\xe2\x75\xb0"
+ "\x1a\x48\xb5\xe6\xd3\x58\x40\xc7"
+ "\x6f\x6f\xcf\x57\x82\x43\x5a\x36"
+ "\xef\x27\xe1\x34\x85\x01\xec\x98"
+ "\x00\xbd\x94\x6f\x12\x39\xa8\x13"
+ "\xfe\x3c\x39\xc0\xc6\xe1\xcc\x05"
+ "\x0e\xd5\xc9\xda\xbd\xdd\xdb\xaa"
+ "\x5a\xaa\x8e\xe8\xa8\x0a\xc5\x18"
+ "\xb4\x1d\x13\x81\xc9\xc4\xaa\x61"
+ "\xa9\xbd\xaa\x03\x12\x93\xbb\xed"
+ "\x0c\x6e\xbd\x1c\x05\x16\x8a\x59",
+ .len = 112,
+ }, {
+ .key = "\xb6\x08\x1d\x31\xaf\xf4\x17\x46"
+ "\xa4\xbb\x0f\xbd\x67\x3c\x73\x15",
+ .klen = 16,
+ .iv = "\x0c\x85\x2f\x62\xe5\xf4\x35\x96"
+ "\xb1\x9b\x5d\x00\x10\xe9\x70\x12",
+ .ptext = "\x3a\x87\x7f\x67\xf1\x81\x7a\x05"
+ "\xb4\xa6\xfe\xdf\x36\x31\x6d\x9e"
+ "\x0e\xa9\x44\xa0\xb0\x05\xa9\x41"
+ "\x9c\x14\x44\x5a\xd5\x1c\x50\x08"
+ "\x95\xc2\xf2\xaf\x3f\x29\xc9\x3e"
+ "\x95\x5e\xc6\xb4\x2b\xf4\x3e\xe3"
+ "\x1b\xeb\x3d\x73\xfb\xd7\x1e\x2b"
+ "\x0c\x3d\x58\x6c\xb4\x41\x9b\xfe"
+ "\x2f\x7e\x1c\x10\x81\x36\x2d\x79"
+ "\xaf\xab\x10\x44\x2e\xcc\x0d\x6c"
+ "\x9c\x14\xc2\xe4\xae\xb0\xbb\xda"
+ "\x6a\xe0\x42\x3d\x96\x9f\x78\x7d"
+ "\x70\x86\xa5\x92\x9f\xee\xcd\x3f"
+ "\x6a\x55\x84\x98\x28\x03\x02\xc2"
+ "\xf7\xec\x7a\xfa\xb1\xd9\xa8\xd8"
+ "\x1c\xc3\xaa\xd5\x61\x7f\x10\x0c",
+ .ctext = "\xa7\x4c\x96\x55\x7c\x07\xce\xb2"
+ "\x6f\x63\x9f\xc6\x8b\x6f\xc6\x4a"
+ "\x85\xf2\x4b\xdf\x62\x0c\x6c\x8d"
+ "\x13\x5d\xd3\x40\x58\xa6\xf9\x03"
+ "\xd9\xf2\x48\x4e\x12\x64\x9a\x55"
+ "\xa2\xa3\xd0\x19\xe5\x5b\xaa\x62"
+ "\x7b\xe9\x2a\x23\xab\xb5\xa6\xcf"
+ "\x53\x59\x70\xc6\xb8\x92\x12\x3b"
+ "\x93\x68\x24\xba\x7d\xd6\xc0\x5b"
+ "\x06\x2e\x7f\x2e\x32\x5d\x42\x9c"
+ "\x13\x8e\x92\x3c\x99\x20\x32\x2b"
+ "\x4a\x41\xb2\x4a\x81\xe8\x6e\x7f"
+ "\x5b\x8e\xca\x4d\xd7\x29\x96\xde"
+ "\x30\x9c\xa6\x84\x90\xe7\xc2\xae"
+ "\xf4\x7e\x73\x32\x4c\x25\xec\xef"
+ "\x58\x69\x63\x3f\x4e\x71\x4b\x1c",
+ .len = 128,
+ }, {
+ .key = "\xc0\xa1\x36\x3d\x81\x9a\xd2\x17"
+ "\x2e\x23\xc9\xb7\xff\xdf\x47\x6c",
+ .klen = 16,
+ .iv = "\x96\x3b\x0e\xbd\xec\x9a\x0e\xad"
+ "\x8c\xaf\x36\x3d\xff\x29\x8b\x33",
+ .ptext = "\x87\x96\x77\x1a\x10\x81\x63\x8a"
+ "\x63\xde\x88\xa9\x9d\xa9\x01\xf2"
+ "\xdf\xc9\x25\x35\x48\x3a\x15\xdf"
+ "\x20\x6b\x91\x7c\x56\xe5\x10\x7a"
+ "\x2d\x2e\x0f\x30\x32\xed\xa9\x1f"
+ "\x71\x4e\x68\x77\xe8\xa8\x5b\xdd"
+ "\x3c\x5e\x68\x6b\xab\x03\xe4\xf8"
+ "\x42\xc1\x61\x9a\x50\xfb\xc7\x6a"
+ "\x1a\x31\xa7\x87\xd0\x24\xcb\x5e"
+ "\xc0\x3b\x12\x28\xca\x26\x7b\xb3"
+ "\x14\xc1\x7f\x66\xff\x3b\xa4\x80"
+ "\x59\x77\x4f\xa0\xd4\xb2\xd9\x8a"
+ "\xb6\x67\xe6\x28\xd3\x6f\xf2\xcf"
+ "\xb8\x6d\x2d\xc4\x2a\x69\x89\xff"
+ "\xcf\xbb\x11\x2e\x2a\x2b\x7c\xfd"
+ "\xcd\x56\x02\x95\xc9\x54\x6e\x62"
+ "\x6a\x97\x75\x1a\x21\x16\x46\xfb"
+ "\xc2\xab\x62\x54\xef\xba\xae\x46",
+ .ctext = "\x11\x7f\xea\x49\xaf\x24\x52\xa2"
+ "\xde\x60\x99\x58\x23\xf9\x9e\x91"
+ "\x94\x52\x31\xa3\x28\x07\x14\xad"
+ "\x00\x24\x4a\x4a\xe7\x18\xd7\x24"
+ "\xcc\x8b\x66\x53\x82\x65\x31\xa5"
+ "\x54\x76\x59\x0b\x69\x6f\x90\x2c"
+ "\x8d\xa5\x2b\x61\x05\x80\xfb\xe0"
+ "\xf9\x6e\xaf\xb9\xc4\x15\x67\xcc"
+ "\x15\xce\xa0\xc0\xf2\xae\xa6\x15"
+ "\x24\x9a\xe5\xcb\x09\x42\xcf\x41"
+ "\x95\xa4\x8d\xbf\xe8\xb8\x40\xcd"
+ "\xb0\x33\x2c\xb3\xc4\xdd\xf9\x45"
+ "\xda\xb2\xeb\xb3\xf8\xfa\x7f\xe3"
+ "\xc0\x3a\x98\xe7\x17\x4a\x0c\x60"
+ "\xb2\x22\xba\x3b\x21\x85\x27\x56"
+ "\xe0\xb2\xf7\x2a\x59\xb1\x56\x20"
+ "\x0b\xa9\x13\x73\xe0\x6f\x61\x32"
+ "\xa5\x38\x14\xb3\xe3\xaa\x70\x44",
+ .len = 144,
+ }, {
+ .key = "\xd4\x14\xc6\xcc\x16\x1b\x95\xf9"
+ "\x05\x26\x23\x81\x19\x27\xad\x7b",
+ .klen = 16,
+ .iv = "\x9c\x8b\xfb\x65\xa4\x61\xee\x69"
+ "\x44\xbf\x59\xde\x03\x61\x11\x12",
+ .ptext = "\x8d\x94\x48\x47\xa9\x52\x16\xfb"
+ "\x6b\xaf\x59\x6d\xab\x74\xbf\x5c"
+ "\xb6\x09\x21\x12\x42\x98\x13\xa1"
+ "\xa8\x6f\xb9\x6d\x4d\xa6\xdc\xea"
+ "\x61\x02\x3c\xa7\xcd\x1a\x28\x8c"
+ "\x66\xb8\x4d\x60\x67\x82\xcc\x8d"
+ "\x1e\xda\x8f\x28\xe5\x02\xdc\x2c"
+ "\x54\x84\x2a\x06\xb5\xd1\x34\x57"
+ "\xb8\x28\x4d\xf5\x69\xb9\xf3\x33"
+ "\x5e\x0b\xa6\x62\x35\x9b\xfb\x97"
+ "\x3e\xc6\xec\xaf\x74\xe8\x72\x91"
+ "\xb2\xc6\x56\xb3\x23\x29\x43\xe0"
+ "\xfb\xcc\x21\x38\x64\x78\x9e\x78"
+ "\xbb\x6e\x0d\x7b\xfd\x05\x74\x01"
+ "\x7c\x94\xe0\xb0\xd7\x92\xfc\x58"
+ "\x28\xfc\xe2\x7b\x7f\xf7\x31\x0d"
+ "\x90\xb7\x60\x78\xa8\x9f\x52\xe3"
+ "\xe6\xaa\x2a\xb4\xa7\x09\x60\x53"
+ "\x42\x0e\x15\x31\xf6\x48\xa3\x0a"
+ "\x20\xf0\x79\x67\xb1\x83\x26\x66",
+ .ctext = "\x5b\xc0\xe8\x17\xa4\xf9\xea\xce"
+ "\x9e\xf9\xe0\xb1\xac\x37\xe9\x41"
+ "\xc8\x06\xf9\x1c\x1a\xfc\xe8\x7a"
+ "\x38\xf2\x80\x66\xc2\x70\x59\x4e"
+ "\xe0\x32\x5b\x27\x39\xf5\xfb\x03"
+ "\xc8\xaf\xd6\x7e\x57\xc7\xc6\x71"
+ "\xd9\xd0\x48\x39\xb1\x0d\xa8\x1a"
+ "\x23\x8a\x3d\x05\xe2\x90\x7e\x18"
+ "\xd7\x20\x04\x3b\x82\x76\x3f\xaa"
+ "\xc2\x89\xb6\x9e\x14\x2f\x46\xcd"
+ "\x51\x9b\xa8\x7b\x62\x7b\x9c\x17"
+ "\xc4\xe1\x8b\x3f\xb5\x4d\xac\x66"
+ "\x49\xf6\xb6\x4c\x3e\x16\x46\xb0"
+ "\xca\x04\xef\x72\x5c\x03\x0a\xe5"
+ "\x2f\x4e\x36\x38\x36\x9f\xf4\xe2"
+ "\x81\x7a\x4c\xdf\x36\x27\xd5\x9d"
+ "\x03\xad\x1d\x3a\xe9\x2a\x99\xb0"
+ "\x2c\xba\x13\x75\xc8\x37\x97\x11"
+ "\xf4\x15\x0f\xb7\x75\x26\xa1\x14"
+ "\x79\xec\x1f\xab\xd2\x10\x8c\x5f",
+ .len = 160,
+ }, {
+ .key = "\x7f\x92\xd5\x06\x30\x6b\xc0\x23"
+ "\x87\xa8\x8e\x6d\xc7\xc5\xd7\xf1"
+ "\x5f\xce\x89\xb3\xd5\x7f\x7f\xf0",
+ .klen = 24,
+ .iv = "\xfd\xab\x56\xa6\x6e\xda\x7c\x57"
+ "\x36\x36\x89\x09\xcd\xa8\xd3\x91",
+ .ptext = "\x48\x3e\x3c\x11\xcf\xd0\x4f\xc0"
+ "\x51\xe3\x8c\xe9\x76\xcd\xff\x37",
+ .ctext = "\xa4\x12\x2f\xc4\xf0\x6d\xd9\x46"
+ "\xe4\xe6\xd1\x0b\x6d\x14\xf0\x8f",
+ .len = 16,
+ }, {
+ .key = "\xd6\x1a\x18\x2f\x68\x2f\xb6\xfe"
+ "\x3d\x2d\x85\x75\x6e\x18\x8a\x52"
+ "\x53\x39\xfc\xc1\xf5\xc0\x56\x22",
+ .klen = 24,
+ .iv = "\xc6\xae\xaa\x0d\x90\xf2\x38\x93"
+ "\xac\xd2\x3f\xc7\x74\x8d\x13\x7e",
+ .ptext = "\xfa\x3f\x70\x52\xfb\x04\x0e\xed"
+ "\x0e\x60\x75\x84\x21\xdf\x13\xa1"
+ "\x26\xf8\x8c\x26\x0a\x37\x51\x8f"
+ "\xe7\x9c\x74\x77\x7a\x3e\xbb\x5d",
+ .ctext = "\x80\x2b\xf0\x88\xb9\x4b\x8d\xf5"
+ "\xc3\x0e\x15\x5b\xea\x5d\x5b\xa8"
+ "\x52\xe7\x83\x3c\xa1\x51\x1c\x1f"
+ "\x38\xd9\x7c\x88\x3c\x3a\xcd\x3e",
+ .len = 32,
+ }, {
+ .key = "\xd7\x33\xf3\xa9\x5b\xb4\x86\xea"
+ "\xe3\x7d\x50\x62\x3b\x73\xaf\xc4"
+ "\xda\x89\xd9\x3c\xcc\xe4\x73\xb0",
+ .klen = 24,
+ .iv = "\xef\x3e\x5f\x46\x62\x88\xd5\x26"
+ "\x3b\xd3\xb5\x81\x78\x70\x1b\xd2",
+ .ptext = "\x39\x56\x34\x63\x2c\xc5\x51\x13"
+ "\x48\x29\x3a\x58\xbe\x41\xc5\x80"
+ "\x2c\x80\xa7\x3c\x14\xb4\x89\x5e"
+ "\x8e\xe5\x5f\xe2\x39\x80\xf5\x2b"
+ "\x77\xb5\xca\x90\xda\x1d\x22\x17"
+ "\xd9\xa0\x57\x80\xc8\x96\x70\x86",
+ .ctext = "\x65\x01\x3c\xb0\xac\x4c\x63\xb6"
+ "\xe7\xf1\xf4\x61\x35\xf4\x36\xde"
+ "\xeb\x0f\x8c\x34\xd1\x78\xb4\x00"
+ "\xb2\xc1\x7c\x28\xb2\xb7\xbb\xa3"
+ "\xc6\xb7\x27\xf7\x6d\x56\x79\xfa"
+ "\x61\x57\xba\x30\x6f\x56\xe9\x8c",
+ .len = 48,
+ }, {
+ .key = "\x07\x2c\xf4\x61\x79\x09\x01\x8f"
+ "\x37\x32\x98\xd4\x86\x2b\x3b\x80"
+ "\x07\x60\xba\xf0\x2e\xc3\x4a\x57",
+ .klen = 24,
+ .iv = "\xf5\xb5\xd7\xbf\xd2\x2a\x9b\x4a"
+ "\xe6\x08\xf0\xbe\x77\xd1\x62\x40",
+ .ptext = "\xa0\x82\x09\x60\x47\xbb\x16\x56"
+ "\x50\x1f\xab\x8b\x10\xfe\xf0\x5c"
+ "\x05\x32\x63\x1a\xc4\x46\x6f\x55"
+ "\x32\xde\x41\x5a\xf7\x52\xd7\xfa"
+ "\x30\x9d\x59\x8d\x64\x76\xad\x37"
+ "\xba\xbc\x46\x6a\x69\x17\x3c\xac"
+ "\x6f\xdd\xa2\x9b\x86\x32\x14\x2e"
+ "\x54\x74\x8f\x3d\xe2\xd6\x85\x44",
+ .ctext = "\x5a\xfb\xb1\x2c\x6e\xe5\xb8\xe0"
+ "\x80\xb6\x77\xa8\xfe\x10\x3a\x99"
+ "\xbf\xc0\x2a\xfe\x6f\x38\xf2\x1d"
+ "\x53\x6c\x05\x83\xb1\x13\x00\x87"
+ "\x92\x92\x42\x70\xcf\x9f\xf7\x8f"
+ "\x53\x55\x18\x6f\x35\x68\x35\x50"
+ "\x3a\xc8\x45\x3e\xa3\xf1\x33\x2e"
+ "\xa1\x65\x42\xe2\x6d\x31\x8c\x4b",
+ .len = 64,
+ }, {
+ .key = "\x4f\x4a\x31\x64\xc6\xa5\x29\xaa"
+ "\xad\xfd\x32\x94\x1f\x56\x57\xd1"
+ "\x9d\x7e\x3d\x49\x00\x36\xb1\x5d",
+ .klen = 24,
+ .iv = "\xb2\x92\x83\x70\x1e\xa3\x97\xa6"
+ "\x65\x53\x39\xeb\x53\x8f\xb1\x38",
+ .ptext = "\x91\xac\x17\x11\x1c\x03\x69\x53"
+ "\xf5\xdf\xdb\x2c\x1b\x9a\x6e\x6b"
+ "\xb6\x02\xc4\xfa\x95\x01\x33\xa8"
+ "\xda\x7e\x18\x2c\xf4\x7e\x6e\x67"
+ "\xce\x8f\x9f\xea\x46\x66\x99\xb8"
+ "\xe1\xc7\x25\x4d\xbd\xa5\x74\xdf"
+ "\xc7\x8b\xfb\xe3\x2d\x3a\x82\xd3"
+ "\x17\x94\x77\x2f\x92\xb8\x87\xc2"
+ "\xcc\x6f\x70\x26\x87\xc7\x10\x8a"
+ "\xc8\xfd\xc2\xb3\xcf\xa0\xeb\x41",
+ .ctext = "\xc9\x5f\xe0\x60\x61\x38\x7e\x79"
+ "\x52\x68\x64\x8f\x55\x9b\x6b\x72"
+ "\xa5\x17\x61\xb7\xce\x02\xa9\xa4"
+ "\x5c\x73\x45\x33\xd1\x07\x5e\xdc"
+ "\xe5\xbe\xa7\xde\x69\xa0\x97\x98"
+ "\x02\xef\xa4\x67\x51\x60\x69\x4f"
+ "\x03\xf5\xa8\x5f\x03\x69\xbc\xc2"
+ "\x34\x59\x7e\xd4\xd2\xb3\x32\x2f"
+ "\x0c\xb4\x37\xca\xc4\xc7\x93\xf4"
+ "\xa4\xab\x01\x3f\x91\x29\x55\x98",
+ .len = 80,
+ }, {
+ .key = "\x4c\xf4\xd0\x34\xd0\x95\xab\xae"
+ "\x82\x5c\xfd\xfa\x13\x86\x25\xce"
+ "\xf4\x13\x32\xcd\xc6\x6d\xf6\x50",
+ .klen = 24,
+ .iv = "\x12\x4a\x5b\x66\x3a\xd3\xfb\x1a"
+ "\xaf\x06\xea\xf4\x65\x59\xd6\xc2",
+ .ptext = "\x84\xa0\x53\x97\x61\x30\x70\x15"
+ "\xac\x45\x8e\xe8\xeb\xa1\x72\x93"
+ "\x26\x76\x98\x6f\xe4\x86\xca\xf0"
+ "\x57\x89\xf2\x2b\xd4\xcf\x2d\x95"
+ "\x86\x26\x20\x0e\x62\xfe\x8f\x1e"
+ "\x5d\xcb\x2b\x7e\xdd\xab\xac\xda"
+ "\x6e\x49\x20\xd5\xb7\x01\x83\x4e"
+ "\xac\x45\x8f\xe1\x05\x3f\xd5\xb1"
+ "\xee\xb7\x0d\x65\x00\x38\xab\x71"
+ "\x70\x6e\xb3\x97\x86\xd3\xcd\xad"
+ "\x51\x8b\x9c\xa0\x9a\x8b\x4c\xb9"
+ "\x16\x01\x6a\x1f\xdf\xf0\xf9\x9e",
+ .ctext = "\x03\x2c\x39\x24\x99\xb5\xf6\x79"
+ "\x91\x89\xb7\xf8\x89\x68\x37\x9d"
+ "\xa2\x80\x95\x74\x87\x64\xb9\xeb"
+ "\x85\x28\x92\x9a\x6e\xd3\x3b\x50"
+ "\x4c\x80\x5b\xe4\xf2\x7e\xda\x2a"
+ "\xd4\xf8\xcb\xe3\x6f\xdf\xae\x0e"
+ "\xc5\x6c\x0b\x49\x2e\x29\x1c\xf2"
+ "\x3f\x44\x44\x12\x67\xa6\xff\x44"
+ "\xe0\xec\xd8\xf7\x32\xde\x21\x15"
+ "\xab\x8f\x98\x4d\xed\xb0\x42\xfd"
+ "\x83\x94\xe2\xcc\x69\x6d\xe8\xdb"
+ "\x62\x93\x1f\xd0\xf4\x8c\x62\xc0",
+ .len = 96,
+ }, {
+ .key = "\x25\x1b\xc2\xa6\x21\x25\xeb\x97"
+ "\x4b\xf6\xcb\x3b\xcd\x61\xfd\x94"
+ "\x37\x03\xb3\xd9\x74\x6e\x4d\xbb",
+ .klen = 24,
+ .iv = "\xfd\x87\x2b\xec\x4c\x2c\xbf\xe2"
+ "\x94\x1a\xe6\xd9\xaf\x0e\x78\x17",
+ .ptext = "\x58\x2b\x1d\x73\x9a\x9c\x63\x18"
+ "\x88\x7a\x0e\x87\x2f\xf0\xb0\xdb"
+ "\xc9\x9d\x79\x51\x34\x39\x4f\x07"
+ "\xa2\x7c\x21\x04\x91\x3b\x79\x79"
+ "\xfe\xd5\x51\x46\xd5\xcd\x28\xc0"
+ "\xad\xb8\x55\xb2\xb2\x5a\x9a\xa2"
+ "\xe2\x0c\xfc\x55\x7d\x60\xd2\x95"
+ "\xb6\x08\x1d\x31\xaf\xf4\x17\x46"
+ "\xa4\xbb\x0f\xbd\x67\x3c\x73\x15"
+ "\x0c\x85\x2f\x62\xe5\xf4\x35\x96"
+ "\xb1\x9b\x5d\x00\x10\xe9\x70\x12"
+ "\x3a\x87\x7f\x67\xf1\x81\x7a\x05"
+ "\xb4\xa6\xfe\xdf\x36\x31\x6d\x9e"
+ "\x0e\xa9\x44\xa0\xb0\x05\xa9\x41",
+ .ctext = "\xd4\x9a\x04\x54\x05\xd2\xe6\x3f"
+ "\xb0\xa4\x36\x5e\x1e\x9c\x35\xb0"
+ "\xc0\x89\xbd\x1c\xaa\x45\xa6\xc8"
+ "\x16\x68\x4a\x06\x93\x67\x88\xd7"
+ "\x72\x6e\x48\x0a\x17\xa3\x52\x8b"
+ "\x96\x5f\x41\xf6\x17\x64\x55\x8b"
+ "\xac\xce\xf6\x8c\xce\xd2\xd4\xd4"
+ "\x8d\x92\x32\xe0\x0d\xb4\xf7\x4a"
+ "\x90\xaf\x7b\x85\x21\x46\x2e\xa6"
+ "\x9e\xac\x0d\x22\xf2\x26\xf6\xd3"
+ "\x27\xcd\x59\xa0\xe2\xbb\x22\xcd"
+ "\x35\xb6\x28\x45\x0a\x46\xb0\x3a"
+ "\xac\x3e\xd3\x5b\xc6\x54\xa2\xa3"
+ "\x6d\xbb\xb3\xcd\xc5\x64\x62\x92",
+ .len = 112,
+ }, {
+ .key = "\x9c\x14\x44\x5a\xd5\x1c\x50\x08"
+ "\x95\xc2\xf2\xaf\x3f\x29\xc9\x3e"
+ "\x95\x5e\xc6\xb4\x2b\xf4\x3e\xe3",
+ .klen = 24,
+ .iv = "\x1b\xeb\x3d\x73\xfb\xd7\x1e\x2b"
+ "\x0c\x3d\x58\x6c\xb4\x41\x9b\xfe",
+ .ptext = "\x2f\x7e\x1c\x10\x81\x36\x2d\x79"
+ "\xaf\xab\x10\x44\x2e\xcc\x0d\x6c"
+ "\x9c\x14\xc2\xe4\xae\xb0\xbb\xda"
+ "\x6a\xe0\x42\x3d\x96\x9f\x78\x7d"
+ "\x70\x86\xa5\x92\x9f\xee\xcd\x3f"
+ "\x6a\x55\x84\x98\x28\x03\x02\xc2"
+ "\xf7\xec\x7a\xfa\xb1\xd9\xa8\xd8"
+ "\x1c\xc3\xaa\xd5\x61\x7f\x10\x0c"
+ "\xc0\xa1\x36\x3d\x81\x9a\xd2\x17"
+ "\x2e\x23\xc9\xb7\xff\xdf\x47\x6c"
+ "\x96\x3b\x0e\xbd\xec\x9a\x0e\xad"
+ "\x8c\xaf\x36\x3d\xff\x29\x8b\x33"
+ "\x87\x96\x77\x1a\x10\x81\x63\x8a"
+ "\x63\xde\x88\xa9\x9d\xa9\x01\xf2"
+ "\xdf\xc9\x25\x35\x48\x3a\x15\xdf"
+ "\x20\x6b\x91\x7c\x56\xe5\x10\x7a",
+ .ctext = "\xbc\x57\x2a\x88\x0a\xd0\x06\x4f"
+ "\xdb\x7b\x03\x9f\x97\x1a\x20\xfe"
+ "\x15\x91\xb4\xed\x5d\x78\x89\x2a"
+ "\x67\x6b\x9c\x47\x36\xc2\x80\x0e"
+ "\x03\x8d\x6f\xfc\x94\xc7\xc5\xc2"
+ "\xeb\x43\x74\x5d\xfe\xc4\x5a\xa1"
+ "\x80\x51\x8a\x63\xd1\x27\x1b\x0a"
+ "\x88\x2c\xc4\x7f\x1a\xa3\x28\xe5"
+ "\xfd\xd0\x8a\xd4\x36\xa6\x19\xd5"
+ "\xff\x41\x7a\x8b\x6e\x9a\x97\x14"
+ "\x2a\xc8\xd0\xb8\xa3\x8e\x64\x32"
+ "\xb7\x2d\x76\x9b\x3b\xe2\x3f\x91"
+ "\xb4\x64\xbf\x59\x67\x14\xc3\xf5"
+ "\xa8\x92\x4b\x85\xdf\x80\xcb\xb5"
+ "\xc7\x80\xf9\x4a\xbc\xed\x67\x5a"
+ "\x0b\x58\x65\x1f\xc9\x6e\x9b\x0a",
+ .len = 128,
+ }, {
+ .key = "\x2d\x2e\x0f\x30\x32\xed\xa9\x1f"
+ "\x71\x4e\x68\x77\xe8\xa8\x5b\xdd"
+ "\x3c\x5e\x68\x6b\xab\x03\xe4\xf8",
+ .klen = 24,
+ .iv = "\x42\xc1\x61\x9a\x50\xfb\xc7\x6a"
+ "\x1a\x31\xa7\x87\xd0\x24\xcb\x5e",
+ .ptext = "\xc0\x3b\x12\x28\xca\x26\x7b\xb3"
+ "\x14\xc1\x7f\x66\xff\x3b\xa4\x80"
+ "\x59\x77\x4f\xa0\xd4\xb2\xd9\x8a"
+ "\xb6\x67\xe6\x28\xd3\x6f\xf2\xcf"
+ "\xb8\x6d\x2d\xc4\x2a\x69\x89\xff"
+ "\xcf\xbb\x11\x2e\x2a\x2b\x7c\xfd"
+ "\xcd\x56\x02\x95\xc9\x54\x6e\x62"
+ "\x6a\x97\x75\x1a\x21\x16\x46\xfb"
+ "\xc2\xab\x62\x54\xef\xba\xae\x46"
+ "\xd4\x14\xc6\xcc\x16\x1b\x95\xf9"
+ "\x05\x26\x23\x81\x19\x27\xad\x7b"
+ "\x9c\x8b\xfb\x65\xa4\x61\xee\x69"
+ "\x44\xbf\x59\xde\x03\x61\x11\x12"
+ "\x8d\x94\x48\x47\xa9\x52\x16\xfb"
+ "\x6b\xaf\x59\x6d\xab\x74\xbf\x5c"
+ "\xb6\x09\x21\x12\x42\x98\x13\xa1"
+ "\xa8\x6f\xb9\x6d\x4d\xa6\xdc\xea"
+ "\x61\x02\x3c\xa7\xcd\x1a\x28\x8c",
+ .ctext = "\xd7\xb4\xfc\xcc\x1f\xf7\xfc\x7d"
+ "\x69\xfa\xcb\x01\x60\xf3\x5a\x14"
+ "\xfe\x8c\x4e\xfa\x09\xb5\x0d\xda"
+ "\xff\xdd\xba\xdf\xa3\x6b\x3a\x87"
+ "\x21\xbb\xf8\x62\x14\x22\xdd\x9b"
+ "\x92\x23\xaa\xd7\xcc\xb2\x15\xd0"
+ "\xbd\x81\x95\x24\xc2\xc6\x53\x5b"
+ "\xf7\x3c\xa0\xf7\x36\xbc\xbf\xf3"
+ "\xfc\x1c\x6e\xe0\x71\x8d\xa1\x3d"
+ "\x8e\x1a\xc5\xba\xd5\x68\xd4\x7a"
+ "\xe0\x4f\x0a\x14\x89\x0b\xa6\x2f"
+ "\x18\xc5\x38\x76\xf1\xe7\x5c\xae"
+ "\x7a\xbb\x27\x1c\xf0\x7c\x6c\x14"
+ "\x07\xb7\x49\x6e\x29\x04\x38\x31"
+ "\x91\xe8\x1d\x0f\xfc\x3b\xb8\x20"
+ "\x58\x64\x11\xa1\xf5\xba\xa3\x62"
+ "\x92\xcf\x44\x63\x2c\xe8\x10\xb5"
+ "\xf0\x97\x86\xcb\x5f\xc1\x80\x7a",
+ .len = 144,
+ }, {
+ .key = "\x66\xb8\x4d\x60\x67\x82\xcc\x8d"
+ "\x1e\xda\x8f\x28\xe5\x02\xdc\x2c"
+ "\x54\x84\x2a\x06\xb5\xd1\x34\x57",
+ .klen = 24,
+ .iv = "\xb8\x28\x4d\xf5\x69\xb9\xf3\x33"
+ "\x5e\x0b\xa6\x62\x35\x9b\xfb\x97",
+ .ptext = "\x3e\xc6\xec\xaf\x74\xe8\x72\x91"
+ "\xb2\xc6\x56\xb3\x23\x29\x43\xe0"
+ "\xfb\xcc\x21\x38\x64\x78\x9e\x78"
+ "\xbb\x6e\x0d\x7b\xfd\x05\x74\x01"
+ "\x7c\x94\xe0\xb0\xd7\x92\xfc\x58"
+ "\x28\xfc\xe2\x7b\x7f\xf7\x31\x0d"
+ "\x90\xb7\x60\x78\xa8\x9f\x52\xe3"
+ "\xe6\xaa\x2a\xb4\xa7\x09\x60\x53"
+ "\x42\x0e\x15\x31\xf6\x48\xa3\x0a"
+ "\x20\xf0\x79\x67\xb1\x83\x26\x66"
+ "\xe0\xb1\xb3\xbd\x1c\x76\x36\xfd"
+ "\x45\x87\xa4\x14\x1b\xef\xe7\x16"
+ "\xf7\xfa\x30\x3d\xb9\x52\x8f\x2e"
+ "\x01\x68\xc1\x7d\xa2\x15\x49\x74"
+ "\x53\x82\xc2\x10\xa8\x45\x73\x4d"
+ "\x41\xcc\x24\xa3\x42\xff\x30\xd1"
+ "\x02\x21\xdc\xd9\x08\xf7\xe7\x4c"
+ "\x33\x2d\x62\xc7\x38\xf5\xc2\xbe"
+ "\x52\xf1\x34\x78\x34\x53\x30\x5b"
+ "\x43\x43\x51\x6a\x02\x81\x64\x0c",
+ .ctext = "\x71\xf6\x96\x02\x07\x71\x1a\x08"
+ "\x7c\xfe\x33\xc4\xc9\xbe\xe2\xed"
+ "\xd0\xcc\x5d\x27\x75\xb4\x5d\x8d"
+ "\x24\x03\xe4\x96\x31\x94\x0e\x38"
+ "\x14\x4f\xad\x16\x58\x0d\x73\xdc"
+ "\xbe\x5b\xcb\x38\xeb\x4d\xbc\x9a"
+ "\x44\x69\x7a\x12\x91\x14\x52\xfa"
+ "\xd2\xa2\xc5\x66\xd7\xaf\x4d\xb9"
+ "\xb1\x58\x24\x10\xde\x6a\xee\x7e"
+ "\x45\xf3\x76\xea\x47\x8a\xe6\x96"
+ "\x41\xf2\x96\x2d\x3c\xec\xcf\xc6"
+ "\x1d\xf4\x26\xc0\xea\x90\x27\x6e"
+ "\x87\xef\xb5\x39\x38\xdb\xad\xbf"
+ "\x57\x9a\x1d\xbc\x1d\xe5\x16\x91"
+ "\x41\x45\xbe\x67\x6c\x42\x0f\xad"
+ "\xcf\xfb\xcd\xf1\x4c\xd8\x73\xe7"
+ "\x24\x3b\xd7\x03\xeb\xd1\xb1\x1b"
+ "\x7d\xc9\x3d\x34\xd7\xb8\x69\x03"
+ "\x76\x95\x32\x26\xed\x88\x76\x89"
+ "\x13\xc6\xc8\xa6\x60\xf9\x73\x4d",
+ .len = 160,
+ }, {
+ .key = "\x82\x8e\x9e\x06\x7b\xc2\xe9\xb3"
+ "\x06\xa3\xfa\x99\x42\x67\x87\xac"
+ "\x21\xc7\xb0\x98\x6c\xf8\x26\x57"
+ "\x08\xdd\x92\x02\x77\x7b\x35\xe7",
+ .klen = 32,
+ .iv = "\xa1\xad\xcb\xdd\xd5\x19\xb6\xd4"
+ "\x0b\x62\x58\xb0\x6c\xa0\xc1\x58",
+ .ptext = "\x14\x0d\x8a\x09\x16\x00\x00\xf1"
+ "\xc0\x20\x86\xf9\x21\xd1\x34\xe2",
+ .ctext = "\x05\xe3\x34\xaf\x6c\x83\x14\x8b"
+ "\x9d\x1c\xd6\x87\x74\x91\xdf\x17",
+ .len = 16,
+ }, {
+ .key = "\xc9\xf3\xc4\x93\xd0\xcc\xaf\xb1"
+ "\x1a\x42\x93\x71\xd8\x4e\xd8\xaa"
+ "\x52\xad\x93\x2f\xe5\xd9\xaa\x5b"
+ "\x47\x37\x3a\xed\x13\x92\x35\x16",
+ .klen = 32,
+ .iv = "\x81\xc8\x50\xd1\x74\xc3\x1c\x73"
+ "\xbb\xab\x72\x83\x90\x5a\x15\xcb",
+ .ptext = "\x65\x11\x93\xaf\xe1\x69\x6c\xbe"
+ "\x25\x8c\x76\x87\x53\xa4\x80\xae"
+ "\x51\x94\x36\x3f\xca\xe7\x45\x41"
+ "\x76\x05\xbf\x8f\x9c\xad\xc0\xe3",
+ .ctext = "\x6B\x00\x6E\x49\x7A\x6D\xE3\x04"
+ "\x4E\xF7\x9F\x8A\x1F\x14\xBD\xB1"
+ "\xD3\x5D\xA4\x30\x26\x85\x85\xEF"
+ "\x12\xBC\xC7\xA1\x65\x82\xA7\x74",
+ .len = 32,
+ }, {
+ .key = "\xd5\x9f\x52\x34\x12\x99\x8e\x42"
+ "\xe0\x85\x04\x6f\xeb\xf1\x5d\xd0"
+ "\xc1\xbf\x3f\x84\xd9\x1e\x71\x44"
+ "\xd4\xb9\x40\x3c\x02\x2e\x21\x19",
+ .klen = 32,
+ .iv = "\x28\xc1\x97\x64\x81\x52\x57\x0e"
+ "\x02\x8c\xab\x4c\xe2\x60\x14\xa5",
+ .ptext = "\x5a\xb1\x33\x48\xaa\x51\xe9\xa4"
+ "\x5c\x2d\xbe\x33\xcc\xc4\x7f\x96"
+ "\xe8\xde\x2b\xe7\x35\x7a\x11\x4b"
+ "\x13\x08\x32\xc6\x41\xd8\xec\x54"
+ "\xa3\xd3\xda\x35\x43\x69\xf6\x88"
+ "\x97\xca\x00\x1b\x02\x59\x24\x82",
+ .ctext = "\x03\xaf\x76\xbd\x5e\x5b\xca\xc0"
+ "\xae\x44\xa2\x2f\xc2\x76\x2f\x50"
+ "\x6a\x73\x28\xf2\xba\xe8\xb2\xb8"
+ "\x43\x61\x41\x92\xff\xac\xcb\xa6"
+ "\x84\x31\xe3\x34\xd0\x37\x81\xab"
+ "\x2b\x0e\x97\x3c\x4a\x2d\xa4\x83",
+ .len = 48,
+ }, {
+ .key = "\x9c\x5d\xd7\x66\x36\xfa\x02\x20"
+ "\x99\x61\x62\x86\x0f\x43\x2e\x05"
+ "\x25\x8b\xfb\xf1\xae\x4c\xde\x18"
+ "\x0b\xf8\xd0\x9d\xaa\xd4\x56\x04",
+ .klen = 32,
+ .iv = "\xcd\xa8\x61\x89\x8d\xbb\x72\xb6"
+ "\x1e\xfe\x03\x34\x54\x88\x23\xe2",
+ .ptext = "\x66\x42\x60\x24\xf3\xe4\xe9\x7e"
+ "\x42\x20\xf4\x61\xce\x1c\x5e\x44"
+ "\x02\x26\x91\xf7\x41\xa4\xab\x34"
+ "\x29\x49\xdd\x78\x19\x8f\x10\x10"
+ "\xf0\x61\xcf\x77\x18\x17\x61\xdf"
+ "\xc4\xa8\x35\x0e\x75\x1b\x84\x6b"
+ "\xc3\x3f\x31\x59\x5a\x9c\xf4\xc3"
+ "\x43\xa9\xb7\xf8\x65\x40\x40\xba",
+ .ctext = "\xb6\x41\x55\x8f\xeb\x16\x1e\x4c"
+ "\x81\xa0\x85\x6c\xf0\x07\xa5\x2a"
+ "\x12\x0f\x1d\xb2\xaa\xba\x85\x0f"
+ "\xa6\x27\x1a\x91\xa6\xc5\x8c\x2a"
+ "\xde\x8d\x3a\xa9\x8b\xcf\x24\xf1"
+ "\x82\x51\x6b\xc8\x01\xd7\x7b\x89"
+ "\x6c\xfc\xb1\x96\x6c\xa2\xd7\x1f"
+ "\x4b\x7a\xd9\x8d\x34\xaa\xa0\x8a",
+ .len = 64,
+ }, {
+ .key = "\x4b\x4e\x11\x91\x27\xcf\x8c\x66"
+ "\x17\xfa\x5b\x4c\xa8\xb8\x0f\xa1"
+ "\x99\x5b\x07\x56\xe1\x8d\x94\x8b"
+ "\xf2\x86\x5a\x5f\x40\x83\xfa\x06",
+ .klen = 32,
+ .iv = "\xfd\x73\xee\x1c\x27\xf3\xb4\x38"
+ "\xc5\x7c\x2e\xc5\x6e\xdb\x49\x0d",
+ .ptext = "\x0a\xe2\xdd\x97\xdd\x5e\xd4\xb3"
+ "\xc1\x49\x8f\x53\xb2\x40\x85\x1c"
+ "\x90\x37\x2d\xbd\x21\x6b\x1f\x80"
+ "\x56\x98\x76\x1e\xcf\x6c\x78\xd8"
+ "\xa0\x3c\x79\xc3\x56\xf7\xfc\x64"
+ "\x35\x58\x1c\x7c\xc4\x5f\x2a\x25"
+ "\x8c\x01\x98\x1e\x1c\x1f\x15\x64"
+ "\x50\xb5\xfa\x02\xd3\x54\xe5\x29"
+ "\xe3\xd2\xa3\x83\x54\x40\x54\xc5"
+ "\xd8\x1c\xc9\x84\x7d\xc8\x31\x49",
+ .ctext = "\x53\x2a\xa8\xa0\x15\xaf\x2f\xc4"
+ "\x7d\x31\xb4\x61\x80\x5f\xd1\xb6"
+ "\xa4\x29\x40\x72\x1b\xb2\x96\xb7"
+ "\x4d\x5e\x5b\x53\x44\xa4\xf1\xe9"
+ "\xf0\x27\x2f\x26\x84\x66\x13\xa4"
+ "\xb2\x19\x55\xb1\x18\xf3\x69\xfd"
+ "\xb0\x2f\x08\x3f\xa5\x41\xe2\x34"
+ "\x5e\x63\x57\x0e\xef\x17\x78\xbc"
+ "\xc3\x65\x7c\xbe\x6b\xa3\xa3\xef"
+ "\x58\x05\x30\x5a\x08\xbd\xf7\x0e",
+ .len = 80,
+ }, {
+ .key = "\x77\x3b\xf5\xe7\x20\xf7\xe0\x0c"
+ "\x3d\x3a\x83\x17\x83\x79\xd8\x29"
+ "\x5a\x0a\x25\x7f\xe0\x21\x23\xff"
+ "\x31\xfd\x60\x10\xe6\x63\xe2\xaf",
+ .klen = 32,
+ .iv = "\xdb\x4c\x0d\xc0\x36\xdb\xc7\xa1"
+ "\xa4\x91\xd9\x05\xe6\xc4\x98\x00",
+ .ptext = "\x8d\x4d\xc6\x5e\x01\x82\xb3\x39"
+ "\xc8\x64\xa7\xcb\x05\x19\x84\x80"
+ "\x3f\x9c\xa8\x4f\x64\xb3\x11\x4b"
+ "\x0e\x21\xc4\x75\x04\x1d\x6f\xd5"
+ "\x04\x04\x4d\xc9\xc0\x4b\x4a\x9c"
+ "\x26\xb7\x68\x5a\xe4\xd0\x61\xe3"
+ "\x2c\x93\x8e\x3f\xb4\x67\x07\x31"
+ "\x02\x52\x0c\x0f\xe6\x6d\xa3\xd0"
+ "\x48\x95\x83\x67\x23\x64\x31\x50"
+ "\xd2\x5f\x69\x68\x8b\x71\xbf\x01"
+ "\x29\x99\x86\x36\x2e\xdf\xf1\x7c"
+ "\x08\x8c\x78\x7a\x93\x9a\x7d\x1b",
+ .ctext = "\x92\x90\x48\x2f\x3a\x6b\x68\x43"
+ "\x28\x9b\x7d\x1e\x46\x28\xd8\x58"
+ "\x0f\x47\x8b\xb5\x83\x35\x35\x3e"
+ "\xdf\x59\x3d\xb3\x47\xfc\xfc\x52"
+ "\x86\xeb\xb3\x58\x54\xd5\x0a\xb4"
+ "\xad\xbd\x5c\x09\xfc\x08\xc2\x01"
+ "\x5e\x9b\x30\x11\xc4\x40\x2e\x32"
+ "\x9c\xa0\xf1\xfd\xae\xd4\x75\x5e"
+ "\x52\xd9\x19\x4d\xc1\xd4\xb6\x19"
+ "\x88\xfb\x29\x17\x15\xbb\x60\xd6"
+ "\x5a\xe9\x82\x89\xaf\x30\x4e\xd4"
+ "\x47\xde\x86\x88\x95\x4c\x13\x59",
+ .len = 96,
+ }, {
+ .key = "\xe0\x6a\x30\xe1\x35\xb5\xb0\x7c"
+ "\x54\xc5\x73\x9b\x00\xe5\xe7\x02"
+ "\xbe\x16\x59\xdc\xd9\x03\x17\x53"
+ "\xa8\x37\xd1\x5f\x13\x8e\x45\xdb",
+ .klen = 32,
+ .iv = "\x54\xe9\x1c\xde\xfb\x26\x0e\x48"
+ "\x35\x50\x4d\x9b\x4d\x12\x21\x0d",
+ .ptext = "\x73\x72\xcf\xdb\xbd\xbc\xc0\xdf"
+ "\x6b\xbb\xdf\x65\x6f\x2f\x43\x3b"
+ "\x2d\x7c\x0e\x07\x7f\xa0\x95\xdd"
+ "\xfc\x67\xc1\x11\x7a\xe2\xb5\x4a"
+ "\xd1\x15\xb0\xd8\xe2\xf0\x35\x48"
+ "\xd8\x81\x6a\x35\xae\x67\xbf\x61"
+ "\xf2\x8a\xcf\x04\xc8\x09\x8b\x63"
+ "\x31\x74\x95\xa5\x8d\x3c\xea\xe2"
+ "\x5f\x67\xc4\x7e\x51\x88\xbf\xb5"
+ "\x78\xef\x3a\x76\xd8\x1d\x00\x75"
+ "\x2b\x7b\x28\x7c\xde\x4b\x39\x01"
+ "\x5d\xde\x92\xfe\x90\x07\x09\xfd"
+ "\xa5\xd1\xd3\x72\x11\x6d\xa4\x4e"
+ "\xd1\x6e\x16\xd1\xf6\x39\x4f\xa0",
+ .ctext = "\x3b\xc5\xee\xfc\x05\xaf\xa6\xb7"
+ "\xfe\x12\x24\x79\x31\xad\x32\xb5"
+ "\x64\x5a\x17\xc9\xbf\x1f\xdc\xce"
+ "\x8d\x73\x00\x71\xd9\xfb\xd2\xe6"
+ "\xc3\x54\xb4\xf3\x36\xe8\x89\x12"
+ "\x5a\x32\x0b\xa6\xec\x5f\x89\xe7"
+ "\xe8\x34\x92\xa6\xce\xde\x8f\xf9"
+ "\x4f\xda\xed\x61\x8e\xb2\x81\xbe"
+ "\xf2\x15\x85\xbe\xa1\x5f\x19\x85"
+ "\x71\x7e\xda\x46\x59\xed\x5d\xb0"
+ "\xd9\x68\x97\xe0\xcd\x1d\x1b\x65"
+ "\xf5\xc9\x44\xe2\xb4\x42\x17\x7c"
+ "\xe7\x58\xf3\x2f\xcf\xbe\x5c\x66"
+ "\xaa\xd3\x61\xa5\x9a\x79\xbb\xa0",
+ .len = 112,
+ }, {
+ .key = "\x60\xb6\xde\x17\xca\x4c\xe7\xe0"
+ "\x07\x0d\x80\xc5\x8a\x2d\x5a\xc2"
+ "\x2c\xb9\xa4\x5f\x2a\x85\x2c\x3d"
+ "\x6d\x67\xc8\xee\x0f\xa2\xf4\x09",
+ .klen = 32,
+ .iv = "\x1a\xa5\xbc\x7e\x93\xf6\xdd\x28"
+ "\xb7\x69\x27\xa1\x84\x95\x25\x5a",
+ .ptext = "\x7b\x88\x00\xeb\xa5\xba\xa1\xa7"
+ "\xd4\x40\x16\x74\x2b\x42\x37\xda"
+ "\xe0\xaf\x89\x59\x41\x2f\x62\x00"
+ "\xf5\x5a\x4e\x3b\x85\x27\xb2\xed"
+ "\x1b\xa7\xaf\xbe\x89\xf3\x49\xb7"
+ "\x8c\x63\xc9\x0c\x52\x00\x5f\x38"
+ "\x3b\x3c\x0c\x4f\xdd\xe1\xbf\x90"
+ "\x4a\x48\xbf\x3a\x95\xcb\x48\xa2"
+ "\x92\x7c\x79\x81\xde\x18\x6e\x92"
+ "\x1f\x36\xa9\x5d\x8d\xc4\xb6\x4d"
+ "\xb2\xb4\x0e\x09\x6d\xf3\x3d\x01"
+ "\x3d\x9b\x40\x47\xbc\x69\x31\xa1"
+ "\x6a\x71\x26\xdc\xac\x10\x56\x63"
+ "\x15\x23\x7d\x10\xe3\x76\x82\x41"
+ "\xcd\x80\x57\x2f\xfc\x4d\x22\x7b"
+ "\x57\xbb\x9a\x0a\x03\xe9\xb3\x13",
+ .ctext = "\x37\x0d\x47\x21\xbc\x28\x0b\xf7"
+ "\x85\x5f\x60\x57\xf2\x7f\x92\x20"
+ "\x53\x1a\xbf\xd1\x7f\x8c\x39\x29"
+ "\x0e\x18\xab\x0c\x00\x92\xd3\x68"
+ "\x60\x56\x3b\x00\xef\xf8\x02\xfa"
+ "\xcb\x92\x1a\x91\xe1\xf0\x4f\x8a"
+ "\xc6\x4f\x65\x16\x71\x8b\x5d\xd5"
+ "\x79\xa9\x6d\x68\x1b\x59\xe7\x2a"
+ "\x1c\xd0\x5d\xfb\x06\x3b\x15\x72"
+ "\xa8\xd1\x59\x9a\xb2\x6c\xf2\xd5"
+ "\x19\xef\xde\x03\x4c\x75\x65\x38"
+ "\x5b\xda\xc9\xf0\x44\x99\xb2\x6e"
+ "\x78\xfb\x85\x5a\x92\x91\x1a\x0a"
+ "\x13\x0c\x1b\x1c\xbe\xbe\x46\x6e"
+ "\x73\xff\xc2\x6e\xb9\x06\x16\x7e"
+ "\xf6\xc0\x01\x30\x34\x56\x46\x55",
+ .len = 128,
+ }, {
+ .key = "\x2a\xed\x7d\x76\xfc\xc5\x49\x50"
+ "\xf4\x90\x0f\xcc\x5d\xff\x0c\x3c"
+ "\x14\x06\xaf\x68\x8f\xd7\xb6\x25"
+ "\x1e\x10\x95\x2a\x71\x33\x17\x20",
+ .klen = 32,
+ .iv = "\x5b\x58\x47\xf8\xd5\x1e\x91\x81"
+ "\x46\xe7\x25\x3a\x02\x45\x9c\x65",
+ .ptext = "\x10\xaf\xde\x5c\x30\x79\x43\x28"
+ "\x1c\x03\xf8\x50\x0f\x30\xa5\xef"
+ "\x84\x19\x4c\x09\x40\x03\x75\x1f"
+ "\x92\x8f\x88\x01\xda\x31\x7a\xe4"
+ "\x48\xe3\xab\xb4\xe6\x1b\x0f\xac"
+ "\xd9\xfa\x8d\x23\xe4\xc6\xa4\xa9"
+ "\x2d\x9a\x54\x52\x44\x5c\x3c\x52"
+ "\x61\xf0\x00\xca\xed\xab\xed\xe2"
+ "\x44\x0b\xe0\x18\xba\xa5\x63\xd8"
+ "\xdc\x5e\x1a\x4c\xf8\xde\x5e\x75"
+ "\xdf\x42\x27\x7b\xe9\x11\x2f\x41"
+ "\x3a\x72\x54\x3d\x44\x9c\x3e\x87"
+ "\x8d\x8d\x43\x2f\xb2\xff\x87\xd4"
+ "\xad\x98\x68\x72\x53\x61\x19\x7c"
+ "\x20\x79\x8c\x2b\x37\x0b\x96\x15"
+ "\xa5\x7d\x4e\x01\xe6\xea\xb6\xfa"
+ "\xaa\xd3\x9d\xa2\xd9\x11\xc3\xc9"
+ "\xd4\x0e\x3f\x3e\xfe\x35\x1e\xe5",
+ .ctext = "\xb0\x2b\x75\x5f\x33\x1b\x05\x49"
+ "\x06\xf1\x43\x91\xc2\x85\xfa\xac"
+ "\x74\xd5\x8c\xc9\x47\x6e\x5a\xf6"
+ "\x69\x33\x4c\xcb\x2f\x36\x4b\x41"
+ "\xec\x05\x69\xab\x7f\x42\xc9\xd2"
+ "\x26\x64\x51\x9e\x3d\x65\x35\xf0"
+ "\x8d\x5e\x8a\xb1\xee\xdf\x1a\x98"
+ "\x36\xd2\x37\x49\x5b\xe2\x57\x00"
+ "\x1d\x72\x7e\xe8\x38\x11\x83\x15"
+ "\xc7\x4e\x65\xa4\x2c\x9e\x6a\x3e"
+ "\xb4\x78\x3f\xe9\x91\x5d\x06\xa9"
+ "\xf1\xfc\x6b\x08\xe5\x2b\x2a\x99"
+ "\x65\xa7\x2e\x47\xf9\xc2\xb1\x8b"
+ "\x88\x2f\xb7\x62\x84\x63\x94\x00"
+ "\x49\xa7\xd0\x2b\x54\x7a\x69\xb3"
+ "\x04\x66\xfc\x97\x40\x92\xd1\xb8"
+ "\xb4\x2a\x9e\xdb\x31\xcd\x48\x84"
+ "\x29\x3b\x02\xac\xb8\x54\x95\xb4",
+ .len = 144,
+ }, {
+ .key = "\x7b\xa7\x4d\x0a\x37\x30\xb9\xf5"
+ "\x2a\x79\xb4\xbf\xdb\x7f\x9b\x64"
+ "\x23\x43\xb5\x18\x34\xc4\x5f\xdf"
+ "\xd9\x2a\x66\x58\x00\x44\xb5\xd9",
+ .klen = 32,
+ .iv = "\x75\x34\x30\xc1\xf0\x69\xdf\x0a"
+ "\x52\xce\x4f\x1e\x2c\x41\x35\xec",
+ .ptext = "\x81\x47\x55\x3a\xcd\xfe\xa2\x3d"
+ "\x45\x53\xa7\x67\x61\x74\x25\x80"
+ "\x98\x89\xfe\xf8\x6a\x9f\x51\x7c"
+ "\xa4\xe4\xe7\xc7\xe0\x1a\xce\xbb"
+ "\x4b\x46\x43\xb0\xab\xa8\xd6\x0c"
+ "\xa0\xf0\xc8\x13\x29\xaf\xb8\x01"
+ "\x6b\x0c\x7e\x56\xae\xb8\x58\x72"
+ "\xa9\x24\x44\x61\xff\xf1\xac\xf8"
+ "\x09\xa8\x48\x21\xd6\xab\x41\x73"
+ "\x70\x6b\x92\x06\x61\xdc\xb4\x85"
+ "\x76\x26\x7a\x84\xc3\x9e\x3a\x14"
+ "\xe7\xf4\x2d\x95\x92\xad\x18\xcc"
+ "\x44\xd4\x2c\x36\x57\xed\x2b\x9b"
+ "\x3f\x2b\xcd\xe5\x11\xe3\x62\x33"
+ "\x42\x3f\xb8\x2a\xb1\x37\x3f\x8b"
+ "\xe8\xbd\x6b\x0b\x9f\x38\x5a\x5f"
+ "\x82\x34\xb7\x96\x35\x58\xde\xab"
+ "\x94\x98\x41\x5b\x3f\xac\x0a\x34"
+ "\x56\xc0\x02\xef\x81\x6d\xb1\xff"
+ "\x34\xe8\xc7\x6a\x31\x79\xba\xd8",
+ .ctext = "\x4e\x00\x7c\x52\x45\x76\xf9\x3d"
+ "\x1a\xd1\x72\xbc\xb9\x0f\xa9\xfb"
+ "\x0a\xf5\xe8\x11\x66\x8b\xad\x68"
+ "\x5a\x2e\xbf\x09\x33\x9d\xb6\x67"
+ "\xe5\xcb\x0a\xe0\xac\xed\x73\x4b"
+ "\xbb\x15\xde\xd8\xab\x33\x28\x5f"
+ "\x96\x07\x3c\x28\x79\x88\x84\xc7"
+ "\x13\xf7\x0d\xa5\x97\x3b\xd9\xb1"
+ "\xf2\x65\xb0\xac\xbb\x8a\x97\xd1"
+ "\x70\x3a\x91\x65\xc8\x39\x04\xe7"
+ "\x1a\x9c\x80\x65\x2b\x69\x4b\xdc"
+ "\xdc\xc7\xf1\x31\xda\xab\xb4\xd7"
+ "\x46\x2e\x1d\xc9\x2e\xe9\x46\xec"
+ "\xa4\xa1\x91\x6b\x4a\x09\xf9\x39"
+ "\x7b\x7d\x6d\xf5\x43\x7f\xcc\x74"
+ "\x96\xfa\x48\xd0\xe1\x74\x24\xd0"
+ "\x19\x22\x24\x84\x2b\x12\x10\x46"
+ "\x90\xbd\xa9\x93\xb7\xf7\x36\xd4"
+ "\x48\xc7\x32\x83\x8c\xa9\xcd\x5a"
+ "\x2f\x05\x33\xc1\x5b\x50\x70\xc4",
+ .len = 160,
+ }
+};
+
+static const struct aead_testvec aria_gcm_tv_template[] = {
+ {
+ .key = "\xe9\x1e\x5e\x75\xda\x65\x55\x4a"
+ "\x48\x18\x1f\x38\x46\x34\x95\x62",
+ .klen = 16,
+ .iv = "\x00\x00\x20\xe8\xf5\xeb\x00\x00"
+ "\x00\x00\x31\x5e",
+ .assoc = "\x80\x08\x31\x5e\xbf\x2e\x6f\xe0"
+ "\x20\xe8\xf5\xeb",
+ .alen = 12,
+ .ptext = "\xf5\x7a\xf5\xfd\x4a\xe1\x95\x62"
+ "\x97\x6e\xc5\x7a\x5a\x7a\xd5\x5a"
+ "\x5a\xf5\xc5\xe5\xc5\xfd\xf5\xc5"
+ "\x5a\xd5\x7a\x4a\x72\x72\xd5\x72"
+ "\x62\xe9\x72\x95\x66\xed\x66\xe9"
+ "\x7a\xc5\x4a\x4a\x5a\x7a\xd5\xe1"
+ "\x5a\xe5\xfd\xd5\xfd\x5a\xc5\xd5"
+ "\x6a\xe5\x6a\xd5\xc5\x72\xd5\x4a"
+ "\xe5\x4a\xc5\x5a\x95\x6a\xfd\x6a"
+ "\xed\x5a\x4a\xc5\x62\x95\x7a\x95"
+ "\x16\x99\x16\x91\xd5\x72\xfd\x14"
+ "\xe9\x7a\xe9\x62\xed\x7a\x9f\x4a"
+ "\x95\x5a\xf5\x72\xe1\x62\xf5\x7a"
+ "\x95\x66\x66\xe1\x7a\xe1\xf5\x4a"
+ "\x95\xf5\x66\xd5\x4a\x66\xe1\x6e"
+ "\x4a\xfd\x6a\x9f\x7a\xe1\xc5\xc5"
+ "\x5a\xe5\xd5\x6a\xfd\xe9\x16\xc5"
+ "\xe9\x4a\x6e\xc5\x66\x95\xe1\x4a"
+ "\xfd\xe1\x14\x84\x16\xe9\x4a\xd5"
+ "\x7a\xc5\x14\x6e\xd5\x9d\x1c\xc5",
+ .plen = 160,
+ .ctext = "\x4d\x8a\x9a\x06\x75\x55\x0c\x70"
+ "\x4b\x17\xd8\xc9\xdd\xc8\x1a\x5c"
+ "\xd6\xf7\xda\x34\xf2\xfe\x1b\x3d"
+ "\xb7\xcb\x3d\xfb\x96\x97\x10\x2e"
+ "\xa0\xf3\xc1\xfc\x2d\xbc\x87\x3d"
+ "\x44\xbc\xee\xae\x8e\x44\x42\x97"
+ "\x4b\xa2\x1f\xf6\x78\x9d\x32\x72"
+ "\x61\x3f\xb9\x63\x1a\x7c\xf3\xf1"
+ "\x4b\xac\xbe\xb4\x21\x63\x3a\x90"
+ "\xff\xbe\x58\xc2\xfa\x6b\xdc\xa5"
+ "\x34\xf1\x0d\x0d\xe0\x50\x2c\xe1"
+ "\xd5\x31\xb6\x33\x6e\x58\x87\x82"
+ "\x78\x53\x1e\x5c\x22\xbc\x6c\x85"
+ "\xbb\xd7\x84\xd7\x8d\x9e\x68\x0a"
+ "\xa1\x90\x31\xaa\xf8\x91\x01\xd6"
+ "\x69\xd7\xa3\x96\x5c\x1f\x7e\x16"
+ "\x22\x9d\x74\x63\xe0\x53\x5f\x4e"
+ "\x25\x3f\x5d\x18\x18\x7d\x40\xb8"
+ "\xae\x0f\x56\x4b\xd9\x70\xb5\xe7"
+ "\xe2\xad\xfb\x21\x1e\x89\xa9\x53"
+ "\x5a\xba\xce\x3f\x37\xf5\xa7\x36"
+ "\xf4\xbe\x98\x4b\xbf\xfb\xed\xc1",
+ .clen = 176,
+ }, {
+ .key = "\x0c\x5f\xfd\x37\xa1\x1e\xdc\x42"
+ "\xc3\x25\x28\x7f\xc0\x60\x4f\x2e"
+ "\x3e\x8c\xd5\x67\x1a\x00\xfe\x32"
+ "\x16\xaa\x5e\xb1\x05\x78\x3b\x54",
+ .klen = 32,
+ .iv = "\x00\x00\x20\xe8\xf5\xeb\x00\x00"
+ "\x00\x00\x31\x5e",
+ .assoc = "\x80\x08\x31\x5e\xbf\x2e\x6f\xe0"
+ "\x20\xe8\xf5\xeb",
+ .alen = 12,
+ .ptext = "\xf5\x7a\xf5\xfd\x4a\xe1\x95\x62"
+ "\x97\x6e\xc5\x7a\x5a\x7a\xd5\x5a"
+ "\x5a\xf5\xc5\xe5\xc5\xfd\xf5\xc5"
+ "\x5a\xd5\x7a\x4a\x72\x72\xd5\x72"
+ "\x62\xe9\x72\x95\x66\xed\x66\xe9"
+ "\x7a\xc5\x4a\x4a\x5a\x7a\xd5\xe1"
+ "\x5a\xe5\xfd\xd5\xfd\x5a\xc5\xd5"
+ "\x6a\xe5\x6a\xd5\xc5\x72\xd5\x4a"
+ "\xe5\x4a\xc5\x5a\x95\x6a\xfd\x6a"
+ "\xed\x5a\x4a\xc5\x62\x95\x7a\x95"
+ "\x16\x99\x16\x91\xd5\x72\xfd\x14"
+ "\xe9\x7a\xe9\x62\xed\x7a\x9f\x4a"
+ "\x95\x5a\xf5\x72\xe1\x62\xf5\x7a"
+ "\x95\x66\x66\xe1\x7a\xe1\xf5\x4a"
+ "\x95\xf5\x66\xd5\x4a\x66\xe1\x6e"
+ "\x4a\xfd\x6a\x9f\x7a\xe1\xc5\xc5"
+ "\x5a\xe5\xd5\x6a\xfd\xe9\x16\xc5"
+ "\xe9\x4a\x6e\xc5\x66\x95\xe1\x4a"
+ "\xfd\xe1\x14\x84\x16\xe9\x4a\xd5"
+ "\x7a\xc5\x14\x6e\xd5\x9d\x1c\xc5",
+ .plen = 160,
+ .ctext = "\x6f\x9e\x4b\xcb\xc8\xc8\x5f\xc0"
+ "\x12\x8f\xb1\xe4\xa0\xa2\x0c\xb9"
+ "\x93\x2f\xf7\x45\x81\xf5\x4f\xc0"
+ "\x13\xdd\x05\x4b\x19\xf9\x93\x71"
+ "\x42\x5b\x35\x2d\x97\xd3\xf3\x37"
+ "\xb9\x0b\x63\xd1\xb0\x82\xad\xee"
+ "\xea\x9d\x2d\x73\x91\x89\x7d\x59"
+ "\x1b\x98\x5e\x55\xfb\x50\xcb\x53"
+ "\x50\xcf\x7d\x38\xdc\x27\xdd\xa1"
+ "\x27\xc0\x78\xa1\x49\xc8\xeb\x98"
+ "\x08\x3d\x66\x36\x3a\x46\xe3\x72"
+ "\x6a\xf2\x17\xd3\xa0\x02\x75\xad"
+ "\x5b\xf7\x72\xc7\x61\x0e\xa4\xc2"
+ "\x30\x06\x87\x8f\x0e\xe6\x9a\x83"
+ "\x97\x70\x31\x69\xa4\x19\x30\x3f"
+ "\x40\xb7\x2e\x45\x73\x71\x4d\x19"
+ "\xe2\x69\x7d\xf6\x1e\x7c\x72\x52"
+ "\xe5\xab\xc6\xba\xde\x87\x6a\xc4"
+ "\x96\x1b\xfa\xc4\xd5\xe8\x67\xaf"
+ "\xca\x35\x1a\x48\xae\xd5\x28\x22"
+ "\xe2\x10\xd6\xce\xd2\xcf\x43\x0f"
+ "\xf8\x41\x47\x29\x15\xe7\xef\x48",
+ .clen = 176,
+ }
};
static const struct cipher_testvec chacha20_tv_template[] = {
@@ -33480,221 +36997,1540 @@ static const struct hash_testvec blake2b_512_tv_template[] = {{
0xae, 0x15, 0x81, 0x15, 0xd0, 0x88, 0xa0, 0x3c, },
}};
-static const struct hash_testvec blakes2s_128_tv_template[] = {{
- .digest = (u8[]){ 0x64, 0x55, 0x0d, 0x6f, 0xfe, 0x2c, 0x0a, 0x01,
- 0xa1, 0x4a, 0xba, 0x1e, 0xad, 0xe0, 0x20, 0x0c, },
-}, {
- .plaintext = blake2_ordered_sequence,
- .psize = 64,
- .digest = (u8[]){ 0xdc, 0x66, 0xca, 0x8f, 0x03, 0x86, 0x58, 0x01,
- 0xb0, 0xff, 0xe0, 0x6e, 0xd8, 0xa1, 0xa9, 0x0e, },
-}, {
- .ksize = 16,
- .key = blake2_ordered_sequence,
- .plaintext = blake2_ordered_sequence,
- .psize = 1,
- .digest = (u8[]){ 0x88, 0x1e, 0x42, 0xe7, 0xbb, 0x35, 0x80, 0x82,
- 0x63, 0x7c, 0x0a, 0x0f, 0xd7, 0xec, 0x6c, 0x2f, },
-}, {
- .ksize = 32,
- .key = blake2_ordered_sequence,
- .plaintext = blake2_ordered_sequence,
- .psize = 7,
- .digest = (u8[]){ 0xcf, 0x9e, 0x07, 0x2a, 0xd5, 0x22, 0xf2, 0xcd,
- 0xa2, 0xd8, 0x25, 0x21, 0x80, 0x86, 0x73, 0x1c, },
-}, {
- .ksize = 1,
- .key = "B",
- .plaintext = blake2_ordered_sequence,
- .psize = 15,
- .digest = (u8[]){ 0xf6, 0x33, 0x5a, 0x2c, 0x22, 0xa0, 0x64, 0xb2,
- 0xb6, 0x3f, 0xeb, 0xbc, 0xd1, 0xc3, 0xe5, 0xb2, },
-}, {
- .ksize = 16,
- .key = blake2_ordered_sequence,
- .plaintext = blake2_ordered_sequence,
- .psize = 247,
- .digest = (u8[]){ 0x72, 0x66, 0x49, 0x60, 0xf9, 0x4a, 0xea, 0xbe,
- 0x1f, 0xf4, 0x60, 0xce, 0xb7, 0x81, 0xcb, 0x09, },
-}, {
- .ksize = 32,
- .key = blake2_ordered_sequence,
- .plaintext = blake2_ordered_sequence,
- .psize = 256,
- .digest = (u8[]){ 0xd5, 0xa4, 0x0e, 0xc3, 0x16, 0xc7, 0x51, 0xa6,
- 0x3c, 0xd0, 0xd9, 0x11, 0x57, 0xfa, 0x1e, 0xbb, },
-}};
+/*
+ * Test vectors generated using https://github.com/google/hctr2
+ */
+static const struct cipher_testvec aes_xctr_tv_template[] = {
+ {
+ .key = "\x9c\x8d\xc4\xbd\x71\x36\xdc\x82"
+ "\x7c\xa1\xca\xa3\x23\x5a\xdb\xa4",
+ .iv = "\x8d\xe7\xa5\x6a\x95\x86\x42\xde"
+ "\xba\xea\x6e\x69\x03\x33\x86\x0f",
+ .ptext = "\xbd",
+ .ctext = "\xb9",
+ .klen = 16,
+ .len = 1,
+ },
+ {
+ .key = "\xbc\x1b\x12\x0c\x3f\x18\xcc\x1f"
+ "\x5a\x1d\xab\x81\xa8\x68\x7c\x63",
+ .iv = "\x22\xc1\xdd\x25\x0b\x18\xcb\xa5"
+ "\x4a\xda\x15\x07\x73\xd9\x88\x10",
+ .ptext = "\x24\x6e\x64\xc6\x15\x26\x9c\xda"
+ "\x2a\x4b\x57\x12\xff\x7c\xd6\xb5",
+ .ctext = "\xd6\x47\x8d\x58\x92\xb2\x84\xf9"
+ "\xb7\xee\x0d\x98\xa1\x39\x4d\x8f",
+ .klen = 16,
+ .len = 16,
+ },
+ {
+ .key = "\x44\x03\xbf\x4c\x30\xf0\xa7\xd6"
+ "\xbd\x54\xbb\x66\x8e\xa6\x0e\x8a",
+ .iv = "\xe6\xf7\x26\xdf\x8c\x3c\xaa\x88"
+ "\xce\xc1\xbd\x43\x3b\x09\x62\xad",
+ .ptext = "\x3c\xe3\x46\xb9\x8f\x9d\x3f\x8d"
+ "\xef\xf2\x53\xab\x24\xe2\x29\x08"
+ "\xf8\x7e\x1d\xa6\x6d\x86\x7d\x60"
+ "\x97\x63\x93\x29\x71\x94\xb4",
+ .ctext = "\xd4\xa3\xc6\xb8\xc1\x6f\x70\x1a"
+ "\x52\x0c\xed\x4c\xaf\x51\x56\x23"
+ "\x48\x45\x07\x10\x34\xc5\xba\x71"
+ "\xe5\xf8\x1e\xd8\xcb\xa6\xe7",
+ .klen = 16,
+ .len = 31,
+ },
+ {
+ .key = "\x5b\x17\x30\x94\x19\x31\xa1\xae"
+ "\x24\x8e\x42\x1e\x82\xe6\xec\xb8",
+ .iv = "\xd1\x2e\xb9\xb8\xf8\x49\xeb\x68"
+ "\x06\xeb\x65\x33\x34\xa2\xeb\xf0",
+ .ptext = "\x19\x75\xec\x59\x60\x1b\x7a\x3e"
+ "\x62\x46\x87\xf0\xde\xab\x81\x36"
+ "\x63\x53\x11\xa0\x1f\xce\x25\x85"
+ "\x49\x6b\x28\xfa\x1c\x92\xe5\x18"
+ "\x38\x14\x00\x79\xf2\x9e\xeb\xfc"
+ "\x36\xa7\x6b\xe1\xe5\xcf\x04\x48"
+ "\x44\x6d\xbd\x64\xb3\xcb\x78\x05"
+ "\x8d\x7f\x9a\xaf\x3c\xcf\x6c\x45"
+ "\x6c\x7c\x46\x4c\xa8\xc0\x1e\xe4"
+ "\x33\xa5\x7b\xbb\x26\xd9\xc0\x32"
+ "\x9d\x8a\xb3\xf3\x3d\x52\xe6\x48"
+ "\x4c\x9b\x4c\x6e\xa4\xa3\xad\x66"
+ "\x56\x48\xd5\x98\x3a\x93\xc4\x85"
+ "\xe9\x89\xca\xa6\xc1\xc8\xe7\xf8"
+ "\xc3\xe9\xef\xbe\x77\xe6\xd1\x3a"
+ "\xa6\x99\xc8\x2d\xdf\x40\x0f\x44",
+ .ctext = "\xc6\x1a\x01\x1a\x00\xba\x04\xff"
+ "\x10\xd1\x7e\x5d\xad\x91\xde\x8c"
+ "\x08\x55\x95\xae\xd7\x22\x77\x40"
+ "\xf0\x33\x1b\x51\xef\xfe\x3d\x67"
+ "\xdf\xc4\x9f\x39\x47\x67\x93\xab"
+ "\xaa\x37\x55\xfe\x41\xe0\xba\xcd"
+ "\x25\x02\x7c\x61\x51\xa1\xcc\x72"
+ "\x7a\x20\x26\xb9\x06\x68\xbd\x19"
+ "\xc5\x2e\x1b\x75\x4a\x40\xb2\xd2"
+ "\xc4\xee\xd8\x5b\xa4\x55\x7d\x25"
+ "\xfc\x01\x4d\x6f\x0a\xfd\x37\x5d"
+ "\x3e\x67\xc0\x35\x72\x53\x7b\xe2"
+ "\xd6\x19\x5b\x92\x6c\x3a\x8c\x2a"
+ "\xe2\xc2\xa2\x4f\x2a\xf2\xb5\x15"
+ "\x65\xc5\x8d\x97\xf9\xbf\x8c\x98"
+ "\xe4\x50\x1a\xf2\x76\x55\x07\x49",
+ .klen = 16,
+ .len = 128,
+ },
+ {
+ .key = "\x17\xa6\x01\x3d\x5d\xd6\xef\x2d"
+ "\x69\x8f\x4c\x54\x5b\xae\x43\xf0",
+ .iv = "\xa9\x1b\x47\x60\x26\x82\xf7\x1c"
+ "\x80\xf8\x88\xdd\xfb\x44\xd9\xda",
+ .ptext = "\xf7\x67\xcd\xa6\x04\x65\x53\x99"
+ "\x90\x5c\xa2\x56\x74\xd7\x9d\xf2"
+ "\x0b\x03\x7f\x4e\xa7\x84\x72\x2b"
+ "\xf0\xa5\xbf\xe6\x9a\x62\x3a\xfe"
+ "\x69\x5c\x93\x79\x23\x86\x64\x85"
+ "\xeb\x13\xb1\x5a\xd5\x48\x39\xa0"
+ "\x70\xfb\x06\x9a\xd7\x12\x5a\xb9"
+ "\xbe\xed\x2c\x81\x64\xf7\xcf\x80"
+ "\xee\xe6\x28\x32\x2d\x37\x4c\x32"
+ "\xf4\x1f\x23\x21\xe9\xc8\xc9\xbf"
+ "\x54\xbc\xcf\xb4\xc2\x65\x39\xdf"
+ "\xa5\xfb\x14\x11\xed\x62\x38\xcf"
+ "\x9b\x58\x11\xdd\xe9\xbd\x37\x57"
+ "\x75\x4c\x9e\xd5\x67\x0a\x48\xc6"
+ "\x0d\x05\x4e\xb1\x06\xd7\xec\x2e"
+ "\x9e\x59\xde\x4f\xab\x38\xbb\xe5"
+ "\x87\x04\x5a\x2c\x2a\xa2\x8f\x3c"
+ "\xe7\xe1\x46\xa9\x49\x9f\x24\xad"
+ "\x2d\xb0\x55\x40\x64\xd5\xda\x7e"
+ "\x1e\x77\xb8\x29\x72\x73\xc3\x84"
+ "\xcd\xf3\x94\x90\x58\x76\xc9\x2c"
+ "\x2a\xad\x56\xde\x33\x18\xb6\x3b"
+ "\x10\xe9\xe9\x8d\xf0\xa9\x7f\x05"
+ "\xf7\xb5\x8c\x13\x7e\x11\x3d\x1e"
+ "\x02\xbb\x5b\xea\x69\xff\x85\xcf"
+ "\x6a\x18\x97\x45\xe3\x96\xba\x4d"
+ "\x2d\x7a\x70\x78\x15\x2c\xe9\xdc"
+ "\x4e\x09\x92\x57\x04\xd8\x0b\xa6"
+ "\x20\x71\x76\x47\x76\x96\x89\xa0"
+ "\xd9\x29\xa2\x5a\x06\xdb\x56\x39"
+ "\x60\x33\x59\x04\x95\x89\xf6\x18"
+ "\x1d\x70\x75\x85\x3a\xb7\x6e",
+ .ctext = "\xe1\xe7\x3f\xd3\x6a\xb9\x2f\x64"
+ "\x37\xc5\xa4\xe9\xca\x0a\xa1\xd6"
+ "\xea\x7d\x39\xe5\xe6\xcc\x80\x54"
+ "\x74\x31\x2a\x04\x33\x79\x8c\x8e"
+ "\x4d\x47\x84\x28\x27\x9b\x3c\x58"
+ "\x54\x58\x20\x4f\x70\x01\x52\x5b"
+ "\xac\x95\x61\x49\x5f\xef\xba\xce"
+ "\xd7\x74\x56\xe7\xbb\xe0\x3c\xd0"
+ "\x7f\xa9\x23\x57\x33\x2a\xf6\xcb"
+ "\xbe\x42\x14\x95\xa8\xf9\x7a\x7e"
+ "\x12\x53\x3a\xe2\x13\xfe\x2d\x89"
+ "\xeb\xac\xd7\xa8\xa5\xf8\x27\xf3"
+ "\x74\x9a\x65\x63\xd1\x98\x3a\x7e"
+ "\x27\x7b\xc0\x20\x00\x4d\xf4\xe5"
+ "\x7b\x69\xa6\xa8\x06\x50\x85\xb6"
+ "\x7f\xac\x7f\xda\x1f\xf5\x37\x56"
+ "\x9b\x2f\xd3\x86\x6b\x70\xbd\x0e"
+ "\x55\x9a\x9d\x4b\x08\xb5\x5b\x7b"
+ "\xd4\x7c\xb4\x71\x49\x92\x4a\x1e"
+ "\xed\x6d\x11\x09\x47\x72\x32\x6a"
+ "\x97\x53\x36\xaf\xf3\x06\x06\x2c"
+ "\x69\xf1\x59\x00\x36\x95\x28\x2a"
+ "\xb6\xcd\x10\x21\x84\x73\x5c\x96"
+ "\x86\x14\x2c\x3d\x02\xdb\x53\x9a"
+ "\x61\xde\xea\x99\x84\x7a\x27\xf6"
+ "\xf7\xc8\x49\x73\x4b\xb8\xeb\xd3"
+ "\x41\x33\xdd\x09\x68\xe2\x64\xb8"
+ "\x5f\x75\x74\x97\x91\x54\xda\xc2"
+ "\x73\x2c\x1e\x5a\x84\x48\x01\x1a"
+ "\x0d\x8b\x0a\xdf\x07\x2e\xee\x77"
+ "\x1d\x17\x41\x7a\xc9\x33\x63\xfa"
+ "\x9f\xc3\x74\x57\x5f\x03\x4c",
+ .klen = 16,
+ .len = 255,
+ },
+ {
+ .key = "\xe5\xf1\x48\x2e\x88\xdb\xc7\x28"
+ "\xa2\x55\x5d\x2f\x90\x02\xdc\xd3"
+ "\xf5\xd3\x9e\x87\xd5\x58\x30\x4a",
+ .iv = "\xa6\x40\x39\xf9\x63\x6c\x2d\xd4"
+ "\x1b\x71\x05\xa4\x88\x86\x11\xd3",
+ .ptext = "\xb6\x06\xae\x15\x11\x96\xc1\x44"
+ "\x44\xc2\x98\xf9\xa8\x0a\x0b",
+ .ctext = "\x27\x3b\x68\x40\xa9\x5e\x74\x6b"
+ "\x74\x67\x18\xf9\x37\xed\xed",
+ .klen = 24,
+ .len = 15,
+ },
+ {
+ .key = "\xc8\xa0\x27\x67\x04\x3f\xed\xa5"
+ "\xb4\x0c\x51\x91\x2d\x27\x77\x33"
+ "\xa5\xfc\x2a\x9f\x78\xd8\x1c\x68",
+ .iv = "\x83\x99\x1a\xe2\x84\xca\xa9\x16"
+ "\x8d\xc4\x2d\x1b\x67\xc8\x86\x21",
+ .ptext = "\xd6\x22\x85\xb8\x5d\x7e\x26\x2e"
+ "\xbe\x04\x9d\x0c\x03\x91\x45\x4a"
+ "\x36",
+ .ctext = "\x0f\x44\xa9\x62\x72\xec\x12\x26"
+ "\x3a\xc6\x83\x26\x62\x5e\xb7\x13"
+ "\x05",
+ .klen = 24,
+ .len = 17,
+ },
+ {
+ .key = "\xc5\x87\x18\x09\x0a\x4e\x66\x3e"
+ "\x50\x90\x19\x93\xc0\x33\xcf\x80"
+ "\x3a\x36\x6b\x6c\x43\xd7\xe4\x93",
+ .iv = "\xdd\x0b\x75\x1f\xee\x2f\xb4\x52"
+ "\x10\x82\x1f\x79\x8a\xa4\x9b\x87",
+ .ptext = "\x56\xf9\x13\xce\x9f\x30\x10\x11"
+ "\x1b\x59\xfd\x39\x5a\x29\xa3\x44"
+ "\x78\x97\x8c\xf6\x99\x6d\x26\xf1"
+ "\x32\x60\x6a\xeb\x04\x47\x29\x4c"
+ "\x7e\x14\xef\x4d\x55\x29\xfe\x36"
+ "\x37\xcf\x0b\x6e\xf3\xce\x15\xd2",
+ .ctext = "\x8f\x98\xe1\x5a\x7f\xfe\xc7\x05"
+ "\x76\xb0\xd5\xde\x90\x52\x2b\xa8"
+ "\xf3\x6e\x3c\x77\xa5\x33\x63\xdd"
+ "\x6f\x62\x12\xb0\x80\x10\xc1\x28"
+ "\x58\xe5\xd6\x24\x44\x04\x55\xf3"
+ "\x6d\x94\xcb\x2c\x7e\x7a\x85\x79",
+ .klen = 24,
+ .len = 48,
+ },
+ {
+ .key = "\x84\x9b\xe8\x10\x4c\xb3\xd1\x7a"
+ "\xb3\xab\x4e\x6f\x90\x12\x07\xf8"
+ "\xef\xde\x42\x09\xbf\x34\x95\xb2",
+ .iv = "\x66\x62\xf9\x48\x9d\x17\xf7\xdf"
+ "\x06\x67\xf4\x6d\xf2\xbc\xa2\xe5",
+ .ptext = "\x2f\xd6\x16\x6b\xf9\x4b\x44\x14"
+ "\x90\x93\xe5\xfd\x05\xaa\x00\x26"
+ "\xbd\xab\x11\xb8\xf0\xcb\x11\x72"
+ "\xdd\xc5\x15\x4f\x4e\x1b\xf8\xc9"
+ "\x8f\x4a\xd5\x69\xf8\x9e\xfb\x05"
+ "\x8a\x37\x46\xfe\xfa\x58\x9b\x0e"
+ "\x72\x90\x9a\x06\xa5\x42\xf4\x7c"
+ "\x35\xd5\x64\x70\x72\x67\xfc\x8b"
+ "\xab\x5a\x2f\x64\x9b\xa1\xec\xe7"
+ "\xe6\x92\x69\xdb\x62\xa4\xe7\x44"
+ "\x88\x28\xd4\x52\x64\x19\xa9\xd7"
+ "\x0c\x00\xe6\xe7\xc1\x28\xc1\xf5"
+ "\x72\xc5\xfa\x09\x22\x2e\xf4\x82"
+ "\xa3\xdc\xc1\x68\xf9\x29\x55\x8d"
+ "\x04\x67\x13\xa6\x52\x04\x3c\x0c"
+ "\x14\xf2\x87\x23\x61\xab\x82\xcb"
+ "\x49\x5b\x6b\xd4\x4f\x0d\xd4\x95"
+ "\x82\xcd\xe3\x69\x47\x1b\x31\x73"
+ "\x73\x77\xc1\x53\x7d\x43\x5e\x4a"
+ "\x80\x3a\xca\x9c\xc7\x04\x1a\x31"
+ "\x8e\xe6\x76\x7f\xe1\xb3\xd0\x57"
+ "\xa2\xb2\xf6\x09\x51\xc9\x6d\xbc"
+ "\x79\xed\x57\x50\x36\xd2\x93\xa4"
+ "\x40\x5d\xac\x3a\x3b\xb6\x2d\x89"
+ "\x78\xa2\xbd\x23\xec\x35\x06\xf0"
+ "\xa8\xc8\xc9\xb0\xe3\x28\x2b\xba"
+ "\x70\xa0\xfe\xed\x13\xc4\xd7\x90"
+ "\xb1\x6a\xe0\xe1\x30\x71\x15\xd0"
+ "\xe2\xb3\xa6\x4e\xb0\x01\xf9\xe7"
+ "\x59\xc6\x1e\xed\x46\x2b\xe3\xa8"
+ "\x22\xeb\x7f\x1c\xd9\xcd\xe0\xa6"
+ "\x72\x42\x2c\x06\x75\xbb\xb7\x6b"
+ "\xca\x49\x5e\xa1\x47\x8d\x9e\xfe"
+ "\x60\xcc\x34\x95\x8e\xfa\x1e\x3e"
+ "\x85\x4b\x03\x54\xea\x34\x1c\x41"
+ "\x90\x45\xa6\xbe\xcf\x58\x4f\xca"
+ "\x2c\x79\xc0\x3e\x8f\xd7\x3b\xd4"
+ "\x55\x74\xa8\xe1\x57\x09\xbf\xab"
+ "\x2c\xf9\xe4\xdd\x17\x99\x57\x60"
+ "\x4b\x88\x2a\x7f\x43\x86\xb9\x9a"
+ "\x60\xbf\x4c\xcf\x9b\x41\xb8\x99"
+ "\x69\x15\x4f\x91\x4d\xeb\xdf\x6f"
+ "\xcc\x4c\xf9\x6f\xf2\x33\x23\xe7"
+ "\x02\x44\xaa\xa2\xfa\xb1\x39\xa5"
+ "\xff\x88\xf5\x37\x02\x33\x24\xfc"
+ "\x79\x11\x4c\x94\xc2\x31\x87\x9c"
+ "\x53\x19\x99\x32\xe4\xde\x18\xf4"
+ "\x8f\xe2\xe8\xa3\xfb\x0b\xaa\x7c"
+ "\xdb\x83\x0f\xf6\xc0\x8a\x9b\xcd"
+ "\x7b\x16\x05\x5b\xe4\xb4\x34\x03"
+ "\xe3\x8f\xc9\x4b\x56\x84\x2a\x4c"
+ "\x36\x72\x3c\x84\x4f\xba\xa2\x7f"
+ "\xf7\x1b\xba\x4d\x8a\xb8\x5d\x51"
+ "\x36\xfb\xef\x23\x18\x6f\x33\x2d"
+ "\xbb\x06\x24\x8e\x33\x98\x6e\xcd"
+ "\x63\x11\x18\x6b\xcc\x1b\x66\xb9"
+ "\x38\x8d\x06\x8d\x98\x1a\xef\xaa"
+ "\x35\x4a\x90\xfa\xb1\xd3\xcc\x11"
+ "\x50\x4c\x54\x18\x60\x5d\xe4\x11"
+ "\xfc\x19\xe1\x53\x20\x5c\xe7\xef"
+ "\x8a\x2b\xa8\x82\x51\x5f\x5d\x43"
+ "\x34\xe5\xcf\x7b\x1b\x6f\x81\x19"
+ "\xb7\xdf\xa8\x9e\x81\x89\x5f\x33"
+ "\x69\xaf\xde\x89\x68\x88\xf0\x71",
+ .ctext = "\xab\x15\x46\x5b\xed\x4f\xa8\xac"
+ "\xbf\x31\x30\x84\x55\xa4\xb8\x98"
+ "\x79\xba\xa0\x15\xa4\x55\x20\xec"
+ "\xf9\x94\x71\xe6\x6a\x6f\xee\x87"
+ "\x2e\x3a\xa2\x95\xae\x6e\x56\x09"
+ "\xe9\xc0\x0f\xe2\xc6\xb7\x30\xa9"
+ "\x73\x8e\x59\x7c\xfd\xe3\x71\xf7"
+ "\xae\x8b\x91\xab\x5e\x36\xe9\xa8"
+ "\xff\x17\xfa\xa2\x94\x93\x11\x42"
+ "\x67\x96\x99\xc5\xf0\xad\x2a\x57"
+ "\xf9\xa6\x70\x4a\xdf\x71\xff\xc0"
+ "\xe2\xaf\x9a\xae\x57\x58\x13\x3b"
+ "\x2d\xf1\xc7\x8f\xdb\x8a\xcc\xce"
+ "\x53\x1a\x69\x55\x39\xc8\xbe\xc3"
+ "\x2d\xb1\x03\xd9\xa3\x99\xf4\x8d"
+ "\xd9\x2d\x27\xae\xa5\xe7\x77\x7f"
+ "\xbb\x88\x84\xea\xfa\x19\x3f\x44"
+ "\x61\x21\x8a\x1f\xbe\xac\x60\xb4"
+ "\xaf\xe9\x00\xab\xef\x3c\x53\x56"
+ "\xcd\x4b\x53\xd8\x9b\xfe\x88\x23"
+ "\x5b\x85\x76\x08\xec\xd1\x6e\x4a"
+ "\x87\xa4\x7d\x29\x4e\x4f\x3f\xc9"
+ "\xa4\xab\x63\xea\xdd\xef\x9f\x79"
+ "\x38\x18\x7d\x90\x90\xf9\x12\x57"
+ "\x1d\x89\xea\xfe\xd4\x47\x45\x32"
+ "\x6a\xf6\xe7\xde\x22\x7e\xee\xc1"
+ "\xbc\x2d\xc3\xbb\xe5\xd4\x13\xac"
+ "\x63\xff\x5b\xb1\x05\x96\xd5\xf3"
+ "\x07\x9a\x62\xb6\x30\xea\x7d\x1e"
+ "\xee\x75\x0a\x1b\xcc\x6e\x4d\xa7"
+ "\xf7\x4d\x74\xd8\x60\x32\x5e\xd0"
+ "\x93\xd7\x19\x90\x4e\x26\xdb\xe4"
+ "\x5e\xd4\xa8\xb9\x76\xba\x56\x91"
+ "\xc4\x75\x04\x1e\xc2\x77\x24\x6f"
+ "\xf9\xe8\x4a\xec\x7f\x86\x95\xb3"
+ "\x5c\x2c\x97\xab\xf0\xf7\x74\x5b"
+ "\x0b\xc2\xda\x42\x40\x34\x16\xed"
+ "\x06\xc1\x25\x53\x17\x0d\x81\x4e"
+ "\xe6\xf2\x0f\x6d\x94\x3c\x90\x7a"
+ "\xae\x20\xe9\x3f\xf8\x18\x67\x6a"
+ "\x49\x1e\x41\xb6\x46\xab\xc8\xa7"
+ "\xcb\x19\x96\xf5\x99\xc0\x66\x3e"
+ "\x77\xcf\x73\x52\x83\x2a\xe2\x48"
+ "\x27\x6c\xeb\xe7\xe7\xc4\xd5\x6a"
+ "\x40\x67\xbc\xbf\x6b\x3c\xf3\xbb"
+ "\x51\x5e\x31\xac\x03\x81\xab\x61"
+ "\xfa\xa5\xa6\x7d\x8b\xc3\x8a\x75"
+ "\x28\x7a\x71\x9c\xac\x8f\x76\xfc"
+ "\xf9\x6c\x5d\x9b\xd7\xf6\x36\x2d"
+ "\x61\xd5\x61\xaa\xdd\x01\xfc\x57"
+ "\x91\x10\xcd\xcd\x6d\x27\x63\x24"
+ "\x67\x46\x7a\xbb\x61\x56\x39\xb1"
+ "\xd6\x79\xfe\x77\xca\xd6\x73\x59"
+ "\x6e\x58\x11\x90\x03\x26\x74\x2a"
+ "\xfa\x52\x12\x47\xfb\x12\xeb\x3e"
+ "\x88\xf0\x52\x6c\xc0\x54\x7a\x88"
+ "\x8c\xe5\xde\x9e\xba\xb9\xf2\xe1"
+ "\x97\x2e\x5c\xbd\xf4\x13\x7e\xf3"
+ "\xc4\xe1\x87\xa5\x35\xfa\x7c\x71"
+ "\x1a\xc9\xf4\xa8\x57\xe2\x5a\x6b"
+ "\x14\xe0\x73\xaf\x56\x6b\xa0\x00"
+ "\x9e\x5f\x64\xac\x00\xfb\xc4\x92"
+ "\xe5\xe2\x8a\xb2\x9e\x75\x49\x85"
+ "\x25\x66\xa5\x1a\xf9\x7d\x1d\x60",
+ .klen = 24,
+ .len = 512,
+ },
+ {
+ .key = "\x05\x60\x3a\x7e\x60\x90\x46\x18"
+ "\x6c\x60\xba\xeb\x12\xd7\xbe\xd1"
+ "\xd3\xf6\x10\x46\x9d\xf1\x0c\xb4"
+ "\x73\xe3\x93\x27\xa8\x2c\x13\xaa",
+ .iv = "\xf5\x96\xd1\xb6\xcb\x44\xd8\xd0"
+ "\x3e\xdb\x92\x80\x08\x94\xcd\xd3",
+ .ptext = "\x78",
+ .ctext = "\xc5",
+ .klen = 32,
+ .len = 1,
+ },
+ {
+ .key = "\x35\xca\x38\xf3\xd9\xd6\x34\xef"
+ "\xcd\xee\xa3\x26\x86\xba\xfb\x45"
+ "\x01\xfa\x52\x67\xff\xc5\x9d\xaa"
+ "\x64\x9a\x05\xbb\x85\x20\xa7\xf2",
+ .iv = "\xe3\xda\xf5\xff\x42\x59\x87\x86"
+ "\xee\x7b\xd6\xb4\x6a\x25\x44\xff",
+ .ptext = "\x44\x67\x1e\x04\x53\xd2\x4b\xd9"
+ "\x96\x33\x07\x54\xe4\x8e\x20",
+ .ctext = "\xcc\x55\x40\x79\x47\x5c\x8b\xa6"
+ "\xca\x7b\x9f\x50\xe3\x21\xea",
+ .klen = 32,
+ .len = 15,
+ },
+ {
+ .key = "\xaf\xd9\x14\x14\xd5\xdb\xc9\xce"
+ "\x76\x5c\x5a\xbf\x43\x05\x29\x24"
+ "\xc4\x13\x68\xcc\xe8\x37\xbd\xb9"
+ "\x41\x20\xf5\x53\x48\xd0\xa2\xd6",
+ .iv = "\xa7\xb4\x00\x08\x79\x10\xae\xf5"
+ "\x02\xbf\x85\xb2\x69\x4c\xc6\x04",
+ .ptext = "\xac\x6a\xa8\x0c\xb0\x84\xbf\x4c"
+ "\xae\x94\x20\x58\x7e\x00\x93\x89",
+ .ctext = "\xd5\xaa\xe2\xe9\x86\x4c\x95\x4e"
+ "\xde\xb6\x15\xcb\xdc\x1f\x13\x38",
+ .klen = 32,
+ .len = 16,
+ },
+ {
+ .key = "\xed\xe3\x8b\xe7\x1c\x17\xbf\x4a"
+ "\x02\xe2\xfc\x76\xac\xf5\x3c\x00"
+ "\x5d\xdc\xfc\x83\xeb\x45\xb4\xcb"
+ "\x59\x62\x60\xec\x69\x9c\x16\x45",
+ .iv = "\xe4\x0e\x2b\x90\xd2\xfa\x94\x2e"
+ "\x10\xe5\x64\x2b\x97\x28\x15\xc7",
+ .ptext = "\xe6\x53\xff\x60\x0e\xc4\x51\xe4"
+ "\x93\x4d\xe5\x55\xc5\xd9\xad\x48"
+ "\x52",
+ .ctext = "\xba\x25\x28\xf5\xcf\x31\x91\x80"
+ "\xda\x2b\x95\x5f\x20\xcb\xfb\x9f"
+ "\xc6",
+ .klen = 32,
+ .len = 17,
+ },
+ {
+ .key = "\x77\x5c\xc0\x73\x9a\x64\x97\x91"
+ "\x2f\xee\xe0\x20\xc2\x04\x59\x2e"
+ "\x97\xd2\xa7\x70\xb3\xb0\x21\x6b"
+ "\x8f\xbf\xb8\x51\xa8\xea\x0f\x62",
+ .iv = "\x31\x8e\x1f\xcd\xfd\x23\xeb\x7f"
+ "\x8a\x1f\x1b\x23\x53\x27\x44\xe5",
+ .ptext = "\xcd\xff\x8c\x9b\x94\x5a\x51\x3f"
+ "\x40\x93\x56\x93\x66\x39\x63\x1f"
+ "\xbf\xe6\xa4\xfa\xbe\x79\x93\x03"
+ "\xf5\x66\x74\x16\xfc\xe4\xce",
+ .ctext = "\x8b\xd3\xc3\xce\x66\xf8\x66\x4c"
+ "\xad\xd6\xf5\x0f\xd8\x99\x5a\x75"
+ "\xa1\x3c\xab\x0b\x21\x36\x57\x72"
+ "\x88\x29\xe9\xea\x4a\x8d\xe9",
+ .klen = 32,
+ .len = 31,
+ },
+ {
+ .key = "\xa1\x2f\x4d\xde\xfe\xa1\xff\xa8"
+ "\x73\xdd\xe3\xe2\x95\xfc\xea\x9c"
+ "\xd0\x80\x42\x0c\xb8\x43\x3e\x99"
+ "\x39\x38\x0a\x8c\xe8\x45\x3a\x7b",
+ .iv = "\x32\xc4\x6f\xb1\x14\x43\xd1\x87"
+ "\xe2\x6f\x5a\x58\x02\x36\x7e\x2a",
+ .ptext = "\x9e\x5c\x1e\xf1\xd6\x7d\x09\x57"
+ "\x18\x48\x55\xda\x7d\x44\xf9\x6d"
+ "\xac\xcd\x59\xbb\x10\xa2\x94\x67"
+ "\xd1\x6f\xfe\x6b\x4a\x11\xe8\x04"
+ "\x09\x26\x4f\x8d\x5d\xa1\x7b\x42"
+ "\xf9\x4b\x66\x76\x38\x12\xfe\xfe",
+ .ctext = "\x42\xbc\xa7\x64\x15\x9a\x04\x71"
+ "\x2c\x5f\x94\xba\x89\x3a\xad\xbc"
+ "\x87\xb3\xf4\x09\x4f\x57\x06\x18"
+ "\xdc\x84\x20\xf7\x64\x85\xca\x3b"
+ "\xab\xe6\x33\x56\x34\x60\x5d\x4b"
+ "\x2e\x16\x13\xd4\x77\xde\x2d\x2b",
+ .klen = 32,
+ .len = 48,
+ },
+ {
+ .key = "\xfb\xf5\xb7\x3d\xa6\x95\x42\xbf"
+ "\xd2\x94\x6c\x74\x0f\xbc\x5a\x28"
+ "\x35\x3c\x51\x58\x84\xfb\x7d\x11"
+ "\x16\x1e\x00\x97\x37\x08\xb7\x16",
+ .iv = "\x9b\x53\x57\x40\xe6\xd9\xa7\x27"
+ "\x78\xd4\x9b\xd2\x29\x1d\x24\xa9",
+ .ptext = "\x8b\x02\x60\x0a\x3e\xb7\x10\x59"
+ "\xc3\xac\xd5\x2a\x75\x81\xf2\xdb"
+ "\x55\xca\x65\x86\x44\xfb\xfe\x91"
+ "\x26\xbb\x45\xb2\x46\x22\x3e\x08"
+ "\xa2\xbf\x46\xcb\x68\x7d\x45\x7b"
+ "\xa1\x6a\x3c\x6e\x25\xeb\xed\x31"
+ "\x7a\x8b\x47\xf9\xde\xec\x3d\x87"
+ "\x09\x20\x2e\xfa\xba\x8b\x9b\xc5"
+ "\x6c\x25\x9c\x9d\x2a\xe8\xab\x90"
+ "\x3f\x86\xee\x61\x13\x21\xd4\xde"
+ "\xe1\x0c\x95\xfc\x5c\x8a\x6e\x0a"
+ "\x73\xcf\x08\x69\x44\x4e\xde\x25"
+ "\xaf\xaa\x56\x04\xc4\xb3\x60\x44"
+ "\x3b\x8b\x3d\xee\xae\x42\x4b\xd2"
+ "\x9a\x6c\xa0\x8e\x52\x06\xb2\xd1"
+ "\x5d\x38\x30\x6d\x27\x9b\x1a\xd8",
+ .ctext = "\xa3\x78\x33\x78\x95\x95\x97\x07"
+ "\x53\xa3\xa1\x5b\x18\x32\x27\xf7"
+ "\x09\x12\x53\x70\x83\xb5\x6a\x9f"
+ "\x26\x6d\x10\x0d\xe0\x1c\xe6\x2b"
+ "\x70\x00\xdc\xa1\x60\xef\x1b\xee"
+ "\xc5\xa5\x51\x17\xae\xcc\xf2\xed"
+ "\xc4\x60\x07\xdf\xd5\x7a\xe9\x90"
+ "\x3c\x9f\x96\x5d\x72\x65\x5d\xef"
+ "\xd0\x94\x32\xc4\x85\x90\x78\xa1"
+ "\x2e\x64\xf6\xee\x8e\x74\x3f\x20"
+ "\x2f\x12\x3b\x3d\xd5\x39\x8e\x5a"
+ "\xf9\x8f\xce\x94\x5d\x82\x18\x66"
+ "\x14\xaf\x4c\xfe\xe0\x91\xc3\x4a"
+ "\x85\xcf\xe7\xe8\xf7\xcb\xf0\x31"
+ "\x88\x7d\xc9\x5b\x71\x9d\x5f\xd2"
+ "\xfa\xed\xa6\x24\xda\xbb\xb1\x84",
+ .klen = 32,
+ .len = 128,
+ },
+ {
+ .key = "\x32\x37\x2b\x8f\x7b\xb1\x23\x79"
+ "\x05\x52\xde\x05\xf1\x68\x3f\x6c"
+ "\xa4\xae\xbc\x21\xc2\xc6\xf0\xbd"
+ "\x0f\x20\xb7\xa4\xc5\x05\x7b\x64",
+ .iv = "\xff\x26\x4e\x67\x48\xdd\xcf\xfe"
+ "\x42\x09\x04\x98\x5f\x1e\xfa\x80",
+ .ptext = "\x99\xdc\x3b\x19\x41\xf9\xff\x6e"
+ "\x76\xb5\x03\xfa\x61\xed\xf8\x44"
+ "\x70\xb9\xf0\x83\x80\x6e\x31\x77"
+ "\x77\xe4\xc7\xb4\x77\x02\xab\x91"
+ "\x82\xc6\xf8\x7c\x46\x61\x03\x69"
+ "\x09\xa0\xf7\x12\xb7\x81\x6c\xa9"
+ "\x10\x5c\xbb\x55\xb3\x44\xed\xb5"
+ "\xa2\x52\x48\x71\x90\x5d\xda\x40"
+ "\x0b\x7f\x4a\x11\x6d\xa7\x3d\x8e"
+ "\x1b\xcd\x9d\x4e\x75\x8b\x7d\x87"
+ "\xe5\x39\x34\x32\x1e\xe6\x8d\x51"
+ "\xd4\x1f\xe3\x1d\x50\xa0\x22\x37"
+ "\x7c\xb0\xd9\xfb\xb6\xb2\x16\xf6"
+ "\x6d\x26\xa0\x4e\x8c\x6a\xe6\xb6"
+ "\xbe\x4c\x7c\xe3\x88\x10\x18\x90"
+ "\x11\x50\x19\x90\xe7\x19\x3f\xd0"
+ "\x31\x15\x0f\x06\x96\xfe\xa7\x7b"
+ "\xc3\x32\x88\x69\xa4\x12\xe3\x64"
+ "\x02\x30\x17\x74\x6c\x88\x7c\x9b"
+ "\xd6\x6d\x75\xdf\x11\x86\x70\x79"
+ "\x48\x7d\x34\x3e\x33\x58\x07\x8b"
+ "\xd2\x50\xac\x35\x15\x45\x05\xb4"
+ "\x4d\x31\x97\x19\x87\x23\x4b\x87"
+ "\x53\xdc\xa9\x19\x78\xf1\xbf\x35"
+ "\x30\x04\x14\xd4\xcf\xb2\x8c\x87"
+ "\x7d\xdb\x69\xc9\xcd\xfe\x40\x3e"
+ "\x8d\x66\x5b\x61\xe5\xf0\x2d\x87"
+ "\x93\x3a\x0c\x2b\x04\x98\x05\xc2"
+ "\x56\x4d\xc4\x6c\xcd\x7a\x98\x7e"
+ "\xe2\x2d\x79\x07\x91\x9f\xdf\x2f"
+ "\x72\xc9\x8f\xcb\x0b\x87\x1b\xb7"
+ "\x04\x86\xcb\x47\xfa\x5d\x03",
+ .ctext = "\x0b\x00\xf7\xf2\xc8\x6a\xba\x9a"
+ "\x0a\x97\x18\x7a\x00\xa0\xdb\xf4"
+ "\x5e\x8e\x4a\xb7\xe0\x51\xf1\x75"
+ "\x17\x8b\xb4\xf1\x56\x11\x05\x9f"
+ "\x2f\x2e\xba\x67\x04\xe1\xb4\xa5"
+ "\xfc\x7c\x8c\xad\xc6\xb9\xd1\x64"
+ "\xca\xbd\x5d\xaf\xdb\x65\x48\x4f"
+ "\x1b\xb3\x94\x5c\x0b\xd0\xee\xcd"
+ "\xb5\x7f\x43\x8a\xd8\x8b\x66\xde"
+ "\xd2\x9c\x13\x65\xa4\x47\xa7\x03"
+ "\xc5\xa1\x46\x8f\x2f\x84\xbc\xef"
+ "\x48\x9d\x9d\xb5\xbd\x43\xff\xd2"
+ "\xd2\x7a\x5a\x13\xbf\xb4\xf6\x05"
+ "\x17\xcd\x01\x12\xf0\x35\x27\x96"
+ "\xf4\xc1\x65\xf7\x69\xef\x64\x1b"
+ "\x6e\x4a\xe8\x77\xce\x83\x01\xb7"
+ "\x60\xe6\x45\x2a\xcd\x41\x4a\xb5"
+ "\x8e\xcc\x45\x93\xf1\xd6\x64\x5f"
+ "\x32\x60\xe4\x29\x4a\x82\x6c\x86"
+ "\x16\xe4\xcc\xdb\x5f\xc8\x11\xa6"
+ "\xfe\x88\xd6\xc3\xe5\x5c\xbb\x67"
+ "\xec\xa5\x7b\xf5\xa8\x4f\x77\x25"
+ "\x5d\x0c\x2a\x99\xf9\xb9\xd1\xae"
+ "\x3c\x83\x2a\x93\x9b\x66\xec\x68"
+ "\x2c\x93\x02\x8a\x8a\x1e\x2f\x50"
+ "\x09\x37\x19\x5c\x2a\x3a\xc2\xcb"
+ "\xcb\x89\x82\x81\xb7\xbb\xef\x73"
+ "\x8b\xc9\xae\x42\x96\xef\x70\xc0"
+ "\x89\xc7\x3e\x6a\x26\xc3\xe4\x39"
+ "\x53\xa9\xcf\x63\x7d\x05\xf3\xff"
+ "\x52\x04\xf6\x7f\x23\x96\xe9\xf7"
+ "\xff\xd6\x50\xa3\x0e\x20\x71",
+ .klen = 32,
+ .len = 255,
+ },
+ {
+ .key = "\x39\x5f\xf4\x9c\x90\x3a\x9a\x25"
+ "\x15\x11\x79\x39\xed\x26\x5e\xf6"
+ "\xda\xcf\x33\x4f\x82\x97\xab\x10"
+ "\xc1\x55\x48\x82\x80\xa8\x02\xb2",
+ .iv = "\x82\x60\xd9\x06\xeb\x40\x99\x76"
+ "\x08\xc5\xa4\x83\x45\xb8\x38\x5a",
+ .ptext = "\xa1\xa8\xac\xac\x08\xaf\x8f\x84"
+ "\xbf\xcc\x79\x31\x5e\x61\x01\xd1"
+ "\x4d\x5f\x9b\xcd\x91\x92\x9a\xa1"
+ "\x99\x0d\x49\xb2\xd7\xfd\x25\x93"
+ "\x51\x96\xbd\x91\x8b\x08\xf1\xc6"
+ "\x0d\x17\xf6\xef\xfd\xd2\x78\x16"
+ "\xc8\x08\x27\x7b\xca\x98\xc6\x12"
+ "\x86\x11\xdb\xd5\x08\x3d\x5a\x2c"
+ "\xcf\x15\x0e\x9b\x42\x78\xeb\x1f"
+ "\x52\xbc\xd7\x5a\x8a\x33\x6c\x14"
+ "\xfc\x61\xad\x2e\x1e\x03\x66\xea"
+ "\x79\x0e\x88\x88\xde\x93\xe3\x81"
+ "\xb5\xc4\x1c\xe6\x9c\x08\x18\x8e"
+ "\xa0\x87\xda\xe6\xf8\xcb\x30\x44"
+ "\x2d\x4e\xc0\xa3\x60\xf9\x62\x7b"
+ "\x4b\xd5\x61\x6d\xe2\x67\x95\x54"
+ "\x10\xd1\xca\x22\xe8\xb6\xb1\x3a"
+ "\x2d\xd7\x35\x5b\x22\x88\x55\x67"
+ "\x3d\x83\x8f\x07\x98\xa8\xf2\xcf"
+ "\x04\xb7\x9e\x52\xca\xe0\x98\x72"
+ "\x5c\xc1\x00\xd4\x1f\x2c\x61\xf3"
+ "\xe8\x40\xaf\x4a\xee\x66\x41\xa0"
+ "\x02\x77\x29\x30\x65\x59\x4b\x20"
+ "\x7b\x0d\x80\x97\x27\x7f\xd5\x90"
+ "\xbb\x9d\x76\x90\xe5\x43\x43\x72"
+ "\xd0\xd4\x14\x75\x66\xb3\xb6\xaf"
+ "\x09\xe4\x23\xb0\x62\xad\x17\x28"
+ "\x39\x26\xab\xf5\xf7\x5c\xb6\x33"
+ "\xbd\x27\x09\x5b\x29\xe4\x40\x0b"
+ "\xc1\x26\x32\xdb\x9a\xdf\xf9\x5a"
+ "\xae\x03\x2c\xa4\x40\x84\x9a\xb7"
+ "\x4e\x47\xa8\x0f\x23\xc7\xbb\xcf"
+ "\x2b\xf2\x32\x6c\x35\x6a\x91\xba"
+ "\x0e\xea\xa2\x8b\x2f\xbd\xb5\xea"
+ "\x6e\xbc\xb5\x4b\x03\xb3\x86\xe0"
+ "\x86\xcf\xba\xcb\x38\x2c\x32\xa6"
+ "\x6d\xe5\x28\xa6\xad\xd2\x7f\x73"
+ "\x43\x14\xf8\xb1\x99\x12\x2d\x2b"
+ "\xdf\xcd\xf2\x81\x43\x94\xdf\xb1"
+ "\x17\xc9\x33\xa6\x3d\xef\x96\xb8"
+ "\xd6\x0d\x00\xec\x49\x66\x85\x5d"
+ "\x44\x62\x12\x04\x55\x5c\x48\xd3"
+ "\xbd\x73\xac\x54\x8f\xbf\x97\x8e"
+ "\x85\xfd\xc2\xa1\x25\x32\x38\x6a"
+ "\x1f\xac\x57\x3c\x4f\x56\x73\xf2"
+ "\x1d\xb6\x48\x68\xc7\x0c\xe7\x60"
+ "\xd2\x8e\x4d\xfb\xc7\x20\x7b\xb7"
+ "\x45\x28\x12\xc6\x26\xae\xea\x7c"
+ "\x5d\xe2\x46\xb5\xae\xe1\xc3\x98"
+ "\x6f\x72\xd5\xa2\xfd\xed\x40\xfd"
+ "\xf9\xdf\x61\xec\x45\x2c\x15\xe0"
+ "\x1e\xbb\xde\x71\x37\x5f\x73\xc2"
+ "\x11\xcc\x6e\x6d\xe1\xb5\x1b\xd2"
+ "\x2a\xdd\x19\x8a\xc2\xe1\xa0\xa4"
+ "\x26\xeb\xb2\x2c\x4f\x77\x52\xf1"
+ "\x42\x72\x6c\xad\xd7\x78\x5d\x72"
+ "\xc9\x16\x26\x25\x1b\x4c\xe6\x58"
+ "\x79\x57\xb5\x06\x15\x4f\xe5\xba"
+ "\xa2\x7f\x2d\x5b\x87\x8a\x44\x70"
+ "\xec\xc7\xef\x84\xae\x60\xa2\x61"
+ "\x86\xe9\x18\xcd\x28\xc4\xa4\xf5"
+ "\xbc\x84\xb8\x86\xa0\xba\xf1\xf1"
+ "\x08\x3b\x32\x75\x35\x22\x7a\x65"
+ "\xca\x48\xe8\xef\x6e\xe2\x8e\x00",
+ .ctext = "\x2f\xae\xd8\x67\xeb\x15\xde\x75"
+ "\x53\xa3\x0e\x5a\xcf\x1c\xbe\xea"
+ "\xde\xf9\xcf\xc2\x9f\xfd\x0f\x44"
+ "\xc0\xe0\x7a\x76\x1d\xcb\x4a\xf8"
+ "\x35\xd6\xe3\x95\x98\x6b\x3f\x89"
+ "\xc4\xe6\xb6\x6f\xe1\x8b\x39\x4b"
+ "\x1c\x6c\x77\xe4\xe1\x8a\xbc\x61"
+ "\x00\x6a\xb1\x37\x2f\x45\xe6\x04"
+ "\x52\x0b\xfc\x1e\x32\xc1\xd8\x9d"
+ "\xfa\xdd\x67\x5c\xe0\x75\x83\xd0"
+ "\x21\x9e\x02\xea\xc0\x7f\xc0\x29"
+ "\xb3\x6c\xa5\x97\xb3\x29\x82\x1a"
+ "\x94\xa5\xb4\xb6\x49\xe5\xa5\xad"
+ "\x95\x40\x52\x7c\x84\x88\xa4\xa8"
+ "\x26\xe4\xd9\x5d\x41\xf2\x93\x7b"
+ "\xa4\x48\x1b\x66\x91\xb9\x7c\xc2"
+ "\x99\x29\xdf\xd8\x30\xac\xd4\x47"
+ "\x42\xa0\x14\x87\x67\xb8\xfd\x0b"
+ "\x1e\xcb\x5e\x5c\x9a\xc2\x04\x8b"
+ "\x17\x29\x9d\x99\x7f\x86\x4c\xe2"
+ "\x5c\x96\xa6\x0f\xb6\x47\x33\x5c"
+ "\xe4\x50\x49\xd5\x4f\x92\x0b\x9a"
+ "\xbc\x52\x4c\x41\xf5\xc9\x3e\x76"
+ "\x55\x55\xd4\xdc\x71\x14\x23\xfc"
+ "\x5f\xd5\x08\xde\xa0\xf7\x28\xc0"
+ "\xe1\x61\xac\x64\x66\xf6\xd1\x31"
+ "\xe4\xa4\xa9\xed\xbc\xad\x4f\x3b"
+ "\x59\xb9\x48\x1b\xe7\xb1\x6f\xc6"
+ "\xba\x40\x1c\x0b\xe7\x2f\x31\x65"
+ "\x85\xf5\xe9\x14\x0a\x31\xf5\xf3"
+ "\xc0\x1c\x20\x35\x73\x38\x0f\x8e"
+ "\x39\xf0\x68\xae\x08\x9c\x87\x4b"
+ "\x42\xfc\x22\x17\xee\x96\x51\x2a"
+ "\xd8\x57\x5a\x35\xea\x72\x74\xfc"
+ "\xb3\x0e\x69\x9a\xe1\x4f\x24\x90"
+ "\xc5\x4b\xe5\xd7\xe3\x82\x2f\xc5"
+ "\x62\x46\x3e\xab\x72\x4e\xe0\xf3"
+ "\x90\x09\x4c\xb2\xe1\xe8\xa0\xf5"
+ "\x46\x40\x2b\x47\x85\x3c\x21\x90"
+ "\x3d\xad\x25\x5a\x36\xdf\xe5\xbc"
+ "\x7e\x80\x4d\x53\x77\xf1\x79\xa6"
+ "\xec\x22\x80\x88\x68\xd6\x2d\x8b"
+ "\x3e\xf7\x52\xc7\x2a\x20\x42\x5c"
+ "\xed\x99\x4f\x32\x80\x00\x7e\x73"
+ "\xd7\x6d\x7f\x7d\x42\x54\x4a\xfe"
+ "\xff\x6f\x61\xca\x2a\xbb\x4f\xeb"
+ "\x4f\xe4\x4e\xaf\x2c\x4f\x82\xcd"
+ "\xa1\xa7\x11\xb3\x34\x33\xcf\x32"
+ "\x63\x0e\x24\x3a\x35\xbe\x06\xd5"
+ "\x17\xcb\x02\x30\x33\x6e\x8c\x49"
+ "\x40\x6e\x34\x8c\x07\xd4\x3e\xe6"
+ "\xaf\x78\x6d\x8c\x10\x5f\x21\x58"
+ "\x49\x26\xc5\xaf\x0d\x7d\xd4\xaf"
+ "\xcd\x5b\xa1\xe3\xf6\x39\x1c\x9b"
+ "\x8e\x00\xa1\xa7\x9e\x17\x4a\xc0"
+ "\x54\x56\x9e\xcf\xcf\x88\x79\x8d"
+ "\x50\xf7\x56\x8e\x0a\x73\x46\x6b"
+ "\xc3\xb9\x9b\x6c\x7d\xc4\xc8\xb6"
+ "\x03\x5f\x30\x62\x7d\xe6\xdb\x15"
+ "\xe1\x39\x02\x8c\xff\xda\xc8\x43"
+ "\xf2\xa9\xbf\x00\xe7\x3a\x61\x89"
+ "\xdf\xb0\xca\x7d\x8c\x8a\x6a\x9f"
+ "\x18\x89\x3d\x39\xac\x36\x6f\x05"
+ "\x1f\xb5\xda\x00\xea\xe1\x51\x21",
+ .klen = 32,
+ .len = 512,
+ },
-static const struct hash_testvec blakes2s_160_tv_template[] = {{
- .plaintext = blake2_ordered_sequence,
- .psize = 7,
- .digest = (u8[]){ 0xb4, 0xf2, 0x03, 0x49, 0x37, 0xed, 0xb1, 0x3e,
- 0x5b, 0x2a, 0xca, 0x64, 0x82, 0x74, 0xf6, 0x62,
- 0xe3, 0xf2, 0x84, 0xff, },
-}, {
- .plaintext = blake2_ordered_sequence,
- .psize = 256,
- .digest = (u8[]){ 0xaa, 0x56, 0x9b, 0xdc, 0x98, 0x17, 0x75, 0xf2,
- 0xb3, 0x68, 0x83, 0xb7, 0x9b, 0x8d, 0x48, 0xb1,
- 0x9b, 0x2d, 0x35, 0x05, },
-}, {
- .ksize = 1,
- .key = "B",
- .digest = (u8[]){ 0x50, 0x16, 0xe7, 0x0c, 0x01, 0xd0, 0xd3, 0xc3,
- 0xf4, 0x3e, 0xb1, 0x6e, 0x97, 0xa9, 0x4e, 0xd1,
- 0x79, 0x65, 0x32, 0x93, },
-}, {
- .ksize = 32,
- .key = blake2_ordered_sequence,
- .plaintext = blake2_ordered_sequence,
- .psize = 1,
- .digest = (u8[]){ 0x1c, 0x2b, 0xcd, 0x9a, 0x68, 0xca, 0x8c, 0x71,
- 0x90, 0x29, 0x6c, 0x54, 0xfa, 0x56, 0x4a, 0xef,
- 0xa2, 0x3a, 0x56, 0x9c, },
-}, {
- .ksize = 16,
- .key = blake2_ordered_sequence,
- .plaintext = blake2_ordered_sequence,
- .psize = 15,
- .digest = (u8[]){ 0x36, 0xc3, 0x5f, 0x9a, 0xdc, 0x7e, 0xbf, 0x19,
- 0x68, 0xaa, 0xca, 0xd8, 0x81, 0xbf, 0x09, 0x34,
- 0x83, 0x39, 0x0f, 0x30, },
-}, {
- .ksize = 1,
- .key = "B",
- .plaintext = blake2_ordered_sequence,
- .psize = 64,
- .digest = (u8[]){ 0x86, 0x80, 0x78, 0xa4, 0x14, 0xec, 0x03, 0xe5,
- 0xb6, 0x9a, 0x52, 0x0e, 0x42, 0xee, 0x39, 0x9d,
- 0xac, 0xa6, 0x81, 0x63, },
-}, {
- .ksize = 32,
- .key = blake2_ordered_sequence,
- .plaintext = blake2_ordered_sequence,
- .psize = 247,
- .digest = (u8[]){ 0x2d, 0xd8, 0xd2, 0x53, 0x66, 0xfa, 0xa9, 0x01,
- 0x1c, 0x9c, 0xaf, 0xa3, 0xe2, 0x9d, 0x9b, 0x10,
- 0x0a, 0xf6, 0x73, 0xe8, },
-}};
+};
-static const struct hash_testvec blakes2s_224_tv_template[] = {{
- .plaintext = blake2_ordered_sequence,
- .psize = 1,
- .digest = (u8[]){ 0x61, 0xb9, 0x4e, 0xc9, 0x46, 0x22, 0xa3, 0x91,
- 0xd2, 0xae, 0x42, 0xe6, 0x45, 0x6c, 0x90, 0x12,
- 0xd5, 0x80, 0x07, 0x97, 0xb8, 0x86, 0x5a, 0xfc,
- 0x48, 0x21, 0x97, 0xbb, },
-}, {
- .plaintext = blake2_ordered_sequence,
- .psize = 247,
- .digest = (u8[]){ 0x9e, 0xda, 0xc7, 0x20, 0x2c, 0xd8, 0x48, 0x2e,
- 0x31, 0x94, 0xab, 0x46, 0x6d, 0x94, 0xd8, 0xb4,
- 0x69, 0xcd, 0xae, 0x19, 0x6d, 0x9e, 0x41, 0xcc,
- 0x2b, 0xa4, 0xd5, 0xf6, },
-}, {
- .ksize = 16,
- .key = blake2_ordered_sequence,
- .digest = (u8[]){ 0x32, 0xc0, 0xac, 0xf4, 0x3b, 0xd3, 0x07, 0x9f,
- 0xbe, 0xfb, 0xfa, 0x4d, 0x6b, 0x4e, 0x56, 0xb3,
- 0xaa, 0xd3, 0x27, 0xf6, 0x14, 0xbf, 0xb9, 0x32,
- 0xa7, 0x19, 0xfc, 0xb8, },
-}, {
- .ksize = 1,
- .key = "B",
- .plaintext = blake2_ordered_sequence,
- .psize = 7,
- .digest = (u8[]){ 0x73, 0xad, 0x5e, 0x6d, 0xb9, 0x02, 0x8e, 0x76,
- 0xf2, 0x66, 0x42, 0x4b, 0x4c, 0xfa, 0x1f, 0xe6,
- 0x2e, 0x56, 0x40, 0xe5, 0xa2, 0xb0, 0x3c, 0xe8,
- 0x7b, 0x45, 0xfe, 0x05, },
-}, {
- .ksize = 32,
- .key = blake2_ordered_sequence,
- .plaintext = blake2_ordered_sequence,
- .psize = 15,
- .digest = (u8[]){ 0x16, 0x60, 0xfb, 0x92, 0x54, 0xb3, 0x6e, 0x36,
- 0x81, 0xf4, 0x16, 0x41, 0xc3, 0x3d, 0xd3, 0x43,
- 0x84, 0xed, 0x10, 0x6f, 0x65, 0x80, 0x7a, 0x3e,
- 0x25, 0xab, 0xc5, 0x02, },
-}, {
- .ksize = 16,
- .key = blake2_ordered_sequence,
- .plaintext = blake2_ordered_sequence,
- .psize = 64,
- .digest = (u8[]){ 0xca, 0xaa, 0x39, 0x67, 0x9c, 0xf7, 0x6b, 0xc7,
- 0xb6, 0x82, 0xca, 0x0e, 0x65, 0x36, 0x5b, 0x7c,
- 0x24, 0x00, 0xfa, 0x5f, 0xda, 0x06, 0x91, 0x93,
- 0x6a, 0x31, 0x83, 0xb5, },
-}, {
- .ksize = 1,
- .key = "B",
- .plaintext = blake2_ordered_sequence,
- .psize = 256,
- .digest = (u8[]){ 0x90, 0x02, 0x26, 0xb5, 0x06, 0x9c, 0x36, 0x86,
- 0x94, 0x91, 0x90, 0x1e, 0x7d, 0x2a, 0x71, 0xb2,
- 0x48, 0xb5, 0xe8, 0x16, 0xfd, 0x64, 0x33, 0x45,
- 0xb3, 0xd7, 0xec, 0xcc, },
-}};
+/*
+ * Test vectors generated using https://github.com/google/hctr2
+ *
+ * To ensure compatibility with RFC 8452, some tests were sourced from
+ * https://datatracker.ietf.org/doc/html/rfc8452
+ */
+static const struct hash_testvec polyval_tv_template[] = {
+ { // From RFC 8452
+ .key = "\x31\x07\x28\xd9\x91\x1f\x1f\x38"
+ "\x37\xb2\x43\x16\xc3\xfa\xb9\xa0",
+ .plaintext = "\x65\x78\x61\x6d\x70\x6c\x65\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x48\x65\x6c\x6c\x6f\x20\x77\x6f"
+ "\x72\x6c\x64\x00\x00\x00\x00\x00"
+ "\x38\x00\x00\x00\x00\x00\x00\x00"
+ "\x58\x00\x00\x00\x00\x00\x00\x00",
+ .digest = "\xad\x7f\xcf\x0b\x51\x69\x85\x16"
+ "\x62\x67\x2f\x3c\x5f\x95\x13\x8f",
+ .psize = 48,
+ .ksize = 16,
+ },
+ { // From RFC 8452
+ .key = "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+ "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+ .plaintext = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .digest = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .psize = 16,
+ .ksize = 16,
+ },
+ { // From RFC 8452
+ .key = "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+ "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+ .plaintext = "\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x40\x00\x00\x00\x00\x00\x00\x00",
+ .digest = "\xeb\x93\xb7\x74\x09\x62\xc5\xe4"
+ "\x9d\x2a\x90\xa7\xdc\x5c\xec\x74",
+ .psize = 32,
+ .ksize = 16,
+ },
+ { // From RFC 8452
+ .key = "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+ "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+ .plaintext = "\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x02\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x03\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x80\x01\x00\x00\x00\x00\x00\x00",
+ .digest = "\x81\x38\x87\x46\xbc\x22\xd2\x6b"
+ "\x2a\xbc\x3d\xcb\x15\x75\x42\x22",
+ .psize = 64,
+ .ksize = 16,
+ },
+ { // From RFC 8452
+ .key = "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+ "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+ .plaintext = "\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x02\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x03\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x04\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x02\x00\x00\x00\x00\x00\x00",
+ .digest = "\x1e\x39\xb6\xd3\x34\x4d\x34\x8f"
+ "\x60\x44\xf8\x99\x35\xd1\xcf\x78",
+ .psize = 80,
+ .ksize = 16,
+ },
+ { // From RFC 8452
+ .key = "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+ "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+ .plaintext = "\x01\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x02\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x03\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x04\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x05\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x08\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x02\x00\x00\x00\x00\x00\x00",
+ .digest = "\xff\xcd\x05\xd5\x77\x0f\x34\xad"
+ "\x92\x67\xf0\xa5\x99\x94\xb1\x5a",
+ .psize = 96,
+ .ksize = 16,
+ },
+ { // Random ( 1)
+ .key = "\x90\xcc\xac\xee\xba\xd7\xd4\x68"
+ "\x98\xa6\x79\x70\xdf\x66\x15\x6c",
+ .plaintext = "",
+ .digest = "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ .psize = 0,
+ .ksize = 16,
+ },
+ { // Random ( 1)
+ .key = "\xc1\x45\x71\xf0\x30\x07\x94\xe7"
+ "\x3a\xdd\xe4\xc6\x19\x2d\x02\xa2",
+ .plaintext = "\xc1\x5d\x47\xc7\x4c\x7c\x5e\x07"
+ "\x85\x14\x8f\x79\xcc\x73\x83\xf7"
+ "\x35\xb8\xcb\x73\x61\xf0\x53\x31"
+ "\xbf\x84\xde\xb6\xde\xaf\xb0\xb8"
+ "\xb7\xd9\x11\x91\x89\xfd\x1e\x4c"
+ "\x84\x4a\x1f\x2a\x87\xa4\xaf\x62"
+ "\x8d\x7d\x58\xf6\x43\x35\xfc\x53"
+ "\x8f\x1a\xf6\x12\xe1\x13\x3f\x66"
+ "\x91\x4b\x13\xd6\x45\xfb\xb0\x7a"
+ "\xe0\x8b\x8e\x99\xf7\x86\x46\x37"
+ "\xd1\x22\x9e\x52\xf3\x3f\xd9\x75"
+ "\x2c\x2c\xc6\xbb\x0e\x08\x14\x29"
+ "\xe8\x50\x2f\xd8\xbe\xf4\xe9\x69"
+ "\x4a\xee\xf7\xae\x15\x65\x35\x1e",
+ .digest = "\x00\x4f\x5d\xe9\x3b\xc0\xd6\x50"
+ "\x3e\x38\x73\x86\xc6\xda\xca\x7f",
+ .psize = 112,
+ .ksize = 16,
+ },
+ { // Random ( 1)
+ .key = "\x37\xbe\x68\x16\x50\xb9\x4e\xb0"
+ "\x47\xde\xe2\xbd\xde\xe4\x48\x09",
+ .plaintext = "\x87\xfc\x68\x9f\xff\xf2\x4a\x1e"
+ "\x82\x3b\x73\x8f\xc1\xb2\x1b\x7a"
+ "\x6c\x4f\x81\xbc\x88\x9b\x6c\xa3"
+ "\x9c\xc2\xa5\xbc\x14\x70\x4c\x9b"
+ "\x0c\x9f\x59\x92\x16\x4b\x91\x3d"
+ "\x18\x55\x22\x68\x12\x8c\x63\xb2"
+ "\x51\xcb\x85\x4b\xd2\xae\x0b\x1c"
+ "\x5d\x28\x9d\x1d\xb1\xc8\xf0\x77"
+ "\xe9\xb5\x07\x4e\x06\xc8\xee\xf8"
+ "\x1b\xed\x72\x2a\x55\x7d\x16\xc9"
+ "\xf2\x54\xe7\xe9\xe0\x44\x5b\x33"
+ "\xb1\x49\xee\xff\x43\xfb\x82\xcd"
+ "\x4a\x70\x78\x81\xa4\x34\x36\xe8"
+ "\x4c\x28\x54\xa6\x6c\xc3\x6b\x78"
+ "\xe7\xc0\x5d\xc6\x5d\x81\xab\x70"
+ "\x08\x86\xa1\xfd\xf4\x77\x55\xfd"
+ "\xa3\xe9\xe2\x1b\xdf\x99\xb7\x80"
+ "\xf9\x0a\x4f\x72\x4a\xd3\xaf\xbb"
+ "\xb3\x3b\xeb\x08\x58\x0f\x79\xce"
+ "\xa5\x99\x05\x12\x34\xd4\xf4\x86"
+ "\x37\x23\x1d\xc8\x49\xc0\x92\xae"
+ "\xa6\xac\x9b\x31\x55\xed\x15\xc6"
+ "\x05\x17\x37\x8d\x90\x42\xe4\x87"
+ "\x89\x62\x88\x69\x1c\x6a\xfd\xe3"
+ "\x00\x2b\x47\x1a\x73\xc1\x51\xc2"
+ "\xc0\x62\x74\x6a\x9e\xb2\xe5\x21"
+ "\xbe\x90\xb5\xb0\x50\xca\x88\x68"
+ "\xe1\x9d\x7a\xdf\x6c\xb7\xb9\x98"
+ "\xee\x28\x62\x61\x8b\xd1\x47\xf9"
+ "\x04\x7a\x0b\x5d\xcd\x2b\x65\xf5"
+ "\x12\xa3\xfe\x1a\xaa\x2c\x78\x42"
+ "\xb8\xbe\x7d\x74\xeb\x59\xba\xba",
+ .digest = "\xae\x11\xd4\x60\x2a\x5f\x9e\x42"
+ "\x89\x04\xc2\x34\x8d\x55\x94\x0a",
+ .psize = 256,
+ .ksize = 16,
+ },
-static const struct hash_testvec blakes2s_256_tv_template[] = {{
- .plaintext = blake2_ordered_sequence,
- .psize = 15,
- .digest = (u8[]){ 0xd9, 0x7c, 0x82, 0x8d, 0x81, 0x82, 0xa7, 0x21,
- 0x80, 0xa0, 0x6a, 0x78, 0x26, 0x83, 0x30, 0x67,
- 0x3f, 0x7c, 0x4e, 0x06, 0x35, 0x94, 0x7c, 0x04,
- 0xc0, 0x23, 0x23, 0xfd, 0x45, 0xc0, 0xa5, 0x2d, },
-}, {
- .ksize = 32,
- .key = blake2_ordered_sequence,
- .digest = (u8[]){ 0x48, 0xa8, 0x99, 0x7d, 0xa4, 0x07, 0x87, 0x6b,
- 0x3d, 0x79, 0xc0, 0xd9, 0x23, 0x25, 0xad, 0x3b,
- 0x89, 0xcb, 0xb7, 0x54, 0xd8, 0x6a, 0xb7, 0x1a,
- 0xee, 0x04, 0x7a, 0xd3, 0x45, 0xfd, 0x2c, 0x49, },
-}, {
- .ksize = 1,
- .key = "B",
- .plaintext = blake2_ordered_sequence,
- .psize = 1,
- .digest = (u8[]){ 0x22, 0x27, 0xae, 0xaa, 0x6e, 0x81, 0x56, 0x03,
- 0xa7, 0xe3, 0xa1, 0x18, 0xa5, 0x9a, 0x2c, 0x18,
- 0xf4, 0x63, 0xbc, 0x16, 0x70, 0xf1, 0xe7, 0x4b,
- 0x00, 0x6d, 0x66, 0x16, 0xae, 0x9e, 0x74, 0x4e, },
-}, {
- .ksize = 16,
- .key = blake2_ordered_sequence,
- .plaintext = blake2_ordered_sequence,
- .psize = 7,
- .digest = (u8[]){ 0x58, 0x5d, 0xa8, 0x60, 0x1c, 0xa4, 0xd8, 0x03,
- 0x86, 0x86, 0x84, 0x64, 0xd7, 0xa0, 0x8e, 0x15,
- 0x2f, 0x05, 0xa2, 0x1b, 0xbc, 0xef, 0x7a, 0x34,
- 0xb3, 0xc5, 0xbc, 0x4b, 0xf0, 0x32, 0xeb, 0x12, },
-}, {
- .ksize = 32,
- .key = blake2_ordered_sequence,
- .plaintext = blake2_ordered_sequence,
- .psize = 64,
- .digest = (u8[]){ 0x89, 0x75, 0xb0, 0x57, 0x7f, 0xd3, 0x55, 0x66,
- 0xd7, 0x50, 0xb3, 0x62, 0xb0, 0x89, 0x7a, 0x26,
- 0xc3, 0x99, 0x13, 0x6d, 0xf0, 0x7b, 0xab, 0xab,
- 0xbd, 0xe6, 0x20, 0x3f, 0xf2, 0x95, 0x4e, 0xd4, },
-}, {
- .ksize = 1,
- .key = "B",
- .plaintext = blake2_ordered_sequence,
- .psize = 247,
- .digest = (u8[]){ 0x2e, 0x74, 0x1c, 0x1d, 0x03, 0xf4, 0x9d, 0x84,
- 0x6f, 0xfc, 0x86, 0x32, 0x92, 0x49, 0x7e, 0x66,
- 0xd7, 0xc3, 0x10, 0x88, 0xfe, 0x28, 0xb3, 0xe0,
- 0xbf, 0x50, 0x75, 0xad, 0x8e, 0xa4, 0xe6, 0xb2, },
-}, {
- .ksize = 16,
- .key = blake2_ordered_sequence,
- .plaintext = blake2_ordered_sequence,
- .psize = 256,
- .digest = (u8[]){ 0xb9, 0xd2, 0x81, 0x0e, 0x3a, 0xb1, 0x62, 0x9b,
- 0xad, 0x44, 0x05, 0xf4, 0x92, 0x2e, 0x99, 0xc1,
- 0x4a, 0x47, 0xbb, 0x5b, 0x6f, 0xb2, 0x96, 0xed,
- 0xd5, 0x06, 0xb5, 0x3a, 0x7c, 0x7a, 0x65, 0x1d, },
-}};
+};
+
+/*
+ * Test vectors generated using https://github.com/google/hctr2
+ */
+static const struct cipher_testvec aes_hctr2_tv_template[] = {
+ {
+ .key = "\xe1\x15\x66\x3c\x8d\xc6\x3a\xff"
+ "\xef\x41\xd7\x47\xa2\xcc\x8a\xba",
+ .iv = "\xc3\xbe\x2a\xcb\xb5\x39\x86\xf1"
+ "\x91\xad\x6c\xf4\xde\x74\x45\x63"
+ "\x5c\x7a\xd5\xcc\x8b\x76\xef\x0e"
+ "\xcf\x2c\x60\x69\x37\xfd\x07\x96",
+ .ptext = "\x65\x75\xae\xd3\xe2\xbc\x43\x5c"
+ "\xb3\x1a\xd8\x05\xc3\xd0\x56\x29",
+ .ctext = "\x11\x91\xea\x74\x58\xcc\xd5\xa2"
+ "\xd0\x55\x9e\x3d\xfe\x7f\xc8\xfe",
+ .klen = 16,
+ .len = 16,
+ },
+ {
+ .key = "\xe7\xd1\x77\x48\x76\x0b\xcd\x34"
+ "\x2a\x2d\xe7\x74\xca\x11\x9c\xae",
+ .iv = "\x71\x1c\x49\x62\xd9\x5b\x50\x5e"
+ "\x68\x87\xbc\xf6\x89\xff\xed\x30"
+ "\xe4\xe5\xbd\xb6\x10\x4f\x9f\x66"
+ "\x28\x06\x5a\xf4\x27\x35\xcd\xe5",
+ .ptext = "\x87\x03\x8f\x06\xa8\x61\x54\xda"
+ "\x01\x45\xd4\x01\xef\x4a\x22\xcf"
+ "\x78\x15\x9f\xbd\x64\xbd\x2c\xb9"
+ "\x40\x1d\x72\xae\x53\x63\xa5",
+ .ctext = "\x4e\xa1\x05\x27\xb8\x45\xe4\xa1"
+ "\xbb\x30\xb4\xa6\x12\x74\x63\xd6"
+ "\x17\xc9\xcc\x2f\x18\x64\xe0\x06"
+ "\x0a\xa0\xff\x72\x10\x7b\x22",
+ .klen = 16,
+ .len = 31,
+ },
+ {
+ .key = "\x59\x65\x3b\x1d\x43\x5e\xc0\xae"
+ "\xb8\x9d\x9b\xdd\x22\x03\xbf\xca",
+ .iv = "\xec\x95\xfa\x5a\xcf\x5e\xd2\x93"
+ "\xa3\xb5\xe5\xbe\xf3\x01\x7b\x01"
+ "\xd1\xca\x6c\x06\x82\xf0\xbd\x67"
+ "\xd9\x6c\xa4\xdc\xb4\x38\x0f\x74",
+ .ptext = "\x45\xdf\x75\x87\xbc\x72\xce\x55"
+ "\xc9\xfa\xcb\xfc\x9f\x40\x82\x2b"
+ "\xc6\x4f\x4f\x5b\x8b\x3b\x6d\x67"
+ "\xa6\x93\x62\x89\x8c\x19\xf4\xe3"
+ "\x08\x92\x9c\xc9\x47\x2c\x6e\xd0"
+ "\xa3\x02\x2b\xdb\x2c\xf2\x8d\x46"
+ "\xcd\xb0\x9d\x26\x63\x4c\x40\x6b"
+ "\x79\x43\xe5\xce\x42\xa8\xec\x3b"
+ "\x5b\xd0\xea\xa4\xe6\xdb\x66\x55"
+ "\x7a\x76\xec\xab\x7d\x2a\x2b\xbd"
+ "\xa9\xab\x22\x64\x1a\xa1\xae\x84"
+ "\x86\x79\x67\xe9\xb2\x50\xbe\x12"
+ "\x2f\xb2\x14\xf0\xdb\x71\xd8\xa7"
+ "\x41\x8a\x88\xa0\x6a\x6e\x9d\x2a"
+ "\xfa\x11\x37\x40\x32\x09\x4c\x47"
+ "\x41\x07\x31\x85\x3d\xa8\xf7\x64",
+ .ctext = "\x2d\x4b\x9f\x93\xca\x5a\x48\x26"
+ "\x01\xcc\x54\xe4\x31\x50\x12\xf0"
+ "\x49\xff\x59\x42\x68\xbd\x87\x8f"
+ "\x9e\x62\x96\xcd\xb9\x24\x57\xa4"
+ "\x0b\x7b\xf5\x2e\x0e\xa8\x65\x07"
+ "\xab\x05\xd5\xca\xe7\x9c\x6c\x34"
+ "\x5d\x42\x34\xa4\x62\xe9\x75\x48"
+ "\x3d\x9e\x8f\xfa\x42\xe9\x75\x08"
+ "\x4e\x54\x91\x2b\xbd\x11\x0f\x8e"
+ "\xf0\x82\xf5\x24\xf1\xc4\xfc\xae"
+ "\x42\x54\x7f\xce\x15\xa8\xb2\x33"
+ "\xc0\x86\xb6\x2b\xe8\x44\xce\x1f"
+ "\x68\x57\x66\x94\x6e\xad\xeb\xf3"
+ "\x30\xf8\x11\xbd\x60\x00\xc6\xd5"
+ "\x4c\x81\xf1\x20\x2b\x4a\x5b\x99"
+ "\x79\x3b\xc9\x5c\x74\x23\xe6\x5d",
+ .klen = 16,
+ .len = 128,
+ },
+ {
+ .key = "\x3e\x08\x5d\x64\x6c\x98\xec\xec"
+ "\x70\x0e\x0d\xa1\x41\x20\x99\x82",
+ .iv = "\x11\xb7\x77\x91\x0d\x99\xd9\x8d"
+ "\x35\x3a\xf7\x14\x6b\x09\x37\xe5"
+ "\xad\x51\xf6\xc3\x96\x4b\x64\x56"
+ "\xa8\xbd\x81\xcc\xbe\x94\xaf\xe4",
+ .ptext = "\xff\x8d\xb9\xc0\xe3\x69\xb3\xb2"
+ "\x8b\x11\x26\xb3\x11\xec\xfb\xb9"
+ "\x9c\xc1\x71\xd6\xe3\x26\x0e\xe0"
+ "\x68\x40\x60\xb9\x3a\x63\x56\x8a"
+ "\x9e\xc1\xf0\x10\xb1\x64\x32\x70"
+ "\xf8\xcd\xc6\xc4\x49\x4c\xe1\xce"
+ "\xf3\xe1\x03\xf8\x35\xae\xe0\x5e"
+ "\xef\x5f\xbc\x41\x75\x26\x13\xcc"
+ "\x37\x85\xdf\xc0\x5d\xa6\x47\x98"
+ "\xf1\x97\x52\x58\x04\xe6\xb5\x01"
+ "\xc0\xb8\x17\x6d\x74\xbd\x9a\xdf"
+ "\xa4\x37\x94\x86\xb0\x13\x83\x28"
+ "\xc9\xa2\x07\x3f\xb5\xb2\x72\x40"
+ "\x0e\x60\xdf\x57\x07\xb7\x2c\x66"
+ "\x10\x3f\x8d\xdd\x30\x0a\x47\xd5"
+ "\xe8\x9d\xfb\xa1\xaf\x53\xd7\x05"
+ "\xc7\xd2\xba\xe7\x2c\xa0\xbf\xb8"
+ "\xd1\x93\xe7\x41\x82\xa3\x41\x3a"
+ "\xaf\x12\xd6\xf8\x34\xda\x92\x46"
+ "\xad\xa2\x2f\xf6\x7e\x46\x96\xd8"
+ "\x03\xf3\x49\x64\xde\xd8\x06\x8b"
+ "\xa0\xbc\x63\x35\x38\xb6\x6b\xda"
+ "\x5b\x50\x3f\x13\xa5\x84\x1b\x1b"
+ "\x66\x89\x95\xb7\xc2\x16\x3c\xe9"
+ "\x24\xb0\x8c\x6f\x49\xef\xf7\x28"
+ "\x6a\x24\xfd\xbe\x25\xe2\xb4\x90"
+ "\x77\x44\x08\xb8\xda\xd2\xde\x2c"
+ "\xa0\x57\x45\x57\x29\x47\x6b\x89"
+ "\x4a\xf6\xa7\x2a\xc3\x9e\x7b\xc8"
+ "\xfd\x9f\x89\xab\xee\x6d\xa3\xb4"
+ "\x23\x90\x7a\xe9\x89\xa0\xc7\xb3"
+ "\x17\x41\x87\x91\xfc\x97\x42",
+ .ctext = "\xfc\x9b\x96\x66\xc4\x82\x2a\x4a"
+ "\xb1\x24\xba\xc7\x78\x5f\x79\xc1"
+ "\x57\x2e\x47\x29\x4d\x7b\xd2\x9a"
+ "\xbd\xc6\xc1\x26\x7b\x8e\x3f\x5d"
+ "\xd4\xb4\x9f\x6a\x02\x24\x4a\xad"
+ "\x0c\x00\x1b\xdf\x92\xc5\x8a\xe1"
+ "\x77\x79\xcc\xd5\x20\xbf\x83\xf4"
+ "\x4b\xad\x11\xbf\xdb\x47\x65\x70"
+ "\x43\xf3\x65\xdf\xb7\xdc\xb2\xb9"
+ "\xaa\x3f\xb3\xdf\x79\x69\x0d\xa0"
+ "\x86\x1c\xba\x48\x0b\x01\xc1\x88"
+ "\xdf\x03\xb1\x06\x3c\x1d\x56\xa1"
+ "\x8e\x98\xc1\xa6\x95\xa2\x5b\x72"
+ "\x76\x59\xd2\x26\x25\xcd\xef\x7c"
+ "\xc9\x60\xea\x43\xd1\x12\x8a\x8a"
+ "\x63\x12\x78\xcb\x2f\x88\x1e\x88"
+ "\x78\x59\xde\xba\x4d\x2c\x78\x61"
+ "\x75\x37\x54\xfd\x80\xc7\x5e\x98"
+ "\xcf\x14\x62\x8e\xfb\x72\xee\x4d"
+ "\x9f\xaf\x8b\x09\xe5\x21\x0a\x91"
+ "\x8f\x88\x87\xd5\xb1\x84\xab\x18"
+ "\x08\x57\xed\x72\x35\xa6\x0e\xc6"
+ "\xff\xcb\xfe\x2c\x48\x39\x14\x44"
+ "\xba\x59\x32\x3a\x2d\xc4\x5f\xcb"
+ "\xbe\x68\x8e\x7b\xee\x21\xa4\x32"
+ "\x11\xa0\x99\xfd\x90\xde\x59\x43"
+ "\xeb\xed\xd5\x87\x68\x46\xc6\xde"
+ "\x0b\x07\x17\x59\x6a\xab\xca\x15"
+ "\x65\x02\x01\xb6\x71\x8c\x3b\xaa"
+ "\x18\x3b\x30\xae\x38\x5b\x2c\x74"
+ "\xd4\xee\x4a\xfc\xf7\x1b\x09\xd4"
+ "\xda\x8b\x1d\x5d\x6f\x21\x6c",
+ .klen = 16,
+ .len = 255,
+ },
+ {
+ .key = "\x24\xf6\xe1\x62\xe5\xaf\x99\xda"
+ "\x84\xec\x41\xb0\xa3\x0b\xd5\xa8"
+ "\xa0\x3e\x7b\xa6\xdd\x6c\x8f\xa8",
+ .iv = "\x7f\x80\x24\x62\x32\xdd\xab\x66"
+ "\xf2\x87\x29\x24\xec\xd2\x4b\x9f"
+ "\x0c\x33\x52\xd9\xe0\xcc\x6e\xe4"
+ "\x90\x85\x43\x97\xc4\x62\x14\x33",
+ .ptext = "\xef\x58\xe7\x7f\xa9\xd9\xb8\xd7"
+ "\xa2\x91\x97\x07\x27\x9e\xba\xe8"
+ "\xaa",
+ .ctext = "\xd7\xc3\x81\x91\xf2\x40\x17\x73"
+ "\x3e\x3b\x1c\x2a\x8e\x11\x9c\x17"
+ "\xf1",
+ .klen = 24,
+ .len = 17,
+ },
+ {
+ .key = "\xbf\xaf\xd7\x67\x8c\x47\xcf\x21"
+ "\x8a\xa5\xdd\x32\x25\x47\xbe\x4f"
+ "\xf1\x3a\x0b\xa6\xaa\x2d\xcf\x09",
+ .iv = "\xd9\xe8\xf0\x92\x4e\xfc\x1d\xf2"
+ "\x81\x37\x7c\x8f\xf1\x59\x09\x20"
+ "\xf4\x46\x51\x86\x4f\x54\x8b\x32"
+ "\x58\xd1\x99\x8b\x8c\x03\xeb\x5d",
+ .ptext = "\xcd\x64\x90\xf9\x7c\xe5\x0e\x5a"
+ "\x75\xe7\x8e\x39\x86\xec\x20\x43"
+ "\x8a\x49\x09\x15\x47\xf4\x3c\x89"
+ "\x21\xeb\xcf\x4e\xcf\x91\xb5\x40"
+ "\xcd\xe5\x4d\x5c\x6f\xf2\xd2\x80"
+ "\xfa\xab\xb3\x76\x9f\x7f\x84\x0a",
+ .ctext = "\x44\x98\x64\x15\xb7\x0b\x80\xa3"
+ "\xb9\xca\x23\xff\x3b\x0b\x68\x74"
+ "\xbb\x3e\x20\x19\x9f\x28\x71\x2a"
+ "\x48\x3c\x7c\xe2\xef\xb5\x10\xac"
+ "\x82\x9f\xcd\x08\x8f\x6b\x16\x6f"
+ "\xc3\xbb\x07\xfb\x3c\xb0\x1b\x27",
+ .klen = 24,
+ .len = 48,
+ },
+ {
+ .key = "\xb8\x35\xa2\x5f\x86\xbb\x82\x99"
+ "\x27\xeb\x01\x3f\x92\xaf\x80\x24"
+ "\x4c\x66\xa2\x89\xff\x2e\xa2\x25",
+ .iv = "\x0a\x1d\x96\xd3\xe0\xe8\x0c\x9b"
+ "\x9d\x6f\x21\x97\xc2\x17\xdb\x39"
+ "\x3f\xd8\x64\x48\x80\x04\xee\x43"
+ "\x02\xce\x88\xe2\x81\x81\x5f\x81",
+ .ptext = "\xb8\xf9\x16\x8b\x25\x68\xd0\x9c"
+ "\xd2\x28\xac\xa8\x79\xc2\x30\xc1"
+ "\x31\xde\x1c\x37\x1b\xa2\xb5\xe6"
+ "\xf0\xd0\xf8\x9c\x7f\xc6\x46\x07"
+ "\x5c\xc3\x06\xe4\xf0\x02\xec\xf8"
+ "\x59\x7c\xc2\x5d\xf8\x0c\x21\xae"
+ "\x9e\x82\xb1\x1a\x5f\x78\x44\x15"
+ "\x00\xa7\x2e\x52\xc5\x98\x98\x35"
+ "\x03\xae\xd0\x8e\x07\x57\xe2\x5a"
+ "\x17\xbf\x52\x40\x54\x5b\x74\xe5"
+ "\x2d\x35\xaf\x9e\x37\xf7\x7e\x4a"
+ "\x8c\x9e\xa1\xdc\x40\xb4\x5b\x36"
+ "\xdc\x3a\x68\xe6\xb7\x35\x0b\x8a"
+ "\x90\xec\x74\x8f\x09\x9a\x7f\x02"
+ "\x4d\x03\x46\x35\x62\xb1\xbd\x08"
+ "\x3f\x54\x2a\x10\x0b\xdc\x69\xaf"
+ "\x25\x3a\x0c\x5f\xe0\x51\xe7\x11"
+ "\xb7\x00\xab\xbb\x9a\xb0\xdc\x4d"
+ "\xc3\x7d\x1a\x6e\xd1\x09\x52\xbd"
+ "\x6b\x43\x55\x22\x3a\x78\x14\x7d"
+ "\x79\xfd\x8d\xfc\x9b\x1d\x0f\xa2"
+ "\xc7\xb9\xf8\x87\xd5\x96\x50\x61"
+ "\xa7\x5e\x1e\x57\x97\xe0\xad\x2f"
+ "\x93\xe6\xe8\x83\xec\x85\x26\x5e"
+ "\xd9\x2a\x15\xe0\xe9\x09\x25\xa1"
+ "\x77\x2b\x88\xdc\xa4\xa5\x48\xb6"
+ "\xf7\xcc\xa6\xa9\xba\xf3\x42\x5c"
+ "\x70\x9d\xe9\x29\xc1\xf1\x33\xdd"
+ "\x56\x48\x17\x86\x14\x51\x5c\x10"
+ "\xab\xfd\xd3\x26\x8c\x21\xf5\x93"
+ "\x1b\xeb\x47\x97\x73\xbb\x88\x10"
+ "\xf3\xfe\xf5\xde\xf3\x2e\x05\x46"
+ "\x1c\x0d\xa3\x10\x48\x9c\x71\x16"
+ "\x78\x33\x4d\x0a\x74\x3b\xe9\x34"
+ "\x0b\xa7\x0e\x9e\x61\xe9\xe9\xfd"
+ "\x85\xa0\xcb\x19\xfd\x7c\x33\xe3"
+ "\x0e\xce\xc2\x6f\x9d\xa4\x2d\x77"
+ "\xfd\xad\xee\x5e\x08\x3e\xd7\xf5"
+ "\xfb\xc3\xd7\x93\x96\x08\x96\xca"
+ "\x58\x81\x16\x9b\x98\x0a\xe2\xef"
+ "\x7f\xda\x40\xe4\x1f\x46\x9e\x67"
+ "\x2b\x84\xcb\x42\xc4\xd6\x6a\xcf"
+ "\x2d\xb2\x33\xc0\x56\xb3\x35\x6f"
+ "\x29\x36\x8f\x6a\x5b\xec\xd5\x4f"
+ "\xa0\x70\xff\xb6\x5b\xde\x6a\x93"
+ "\x20\x3c\xe2\x76\x7a\xef\x3c\x79"
+ "\x31\x65\xce\x3a\x0e\xd0\xbe\xa8"
+ "\x21\x95\xc7\x2b\x62\x8e\x67\xdd"
+ "\x20\x79\xe4\xe5\x01\x15\xc0\xec"
+ "\x0f\xd9\x23\xc8\xca\xdf\xd4\x7d"
+ "\x1d\xf8\x64\x4f\x56\xb1\x83\xa7"
+ "\x43\xbe\xfc\xcf\xc2\x8c\x33\xda"
+ "\x36\xd0\x52\xef\x9e\x9e\x88\xf4"
+ "\xa8\x21\x0f\xaa\xee\x8d\xa0\x24"
+ "\x4d\xcb\xb1\x72\x07\xf0\xc2\x06"
+ "\x60\x65\x85\x84\x2c\x60\xcf\x61"
+ "\xe7\x56\x43\x5b\x2b\x50\x74\xfa"
+ "\xdb\x4e\xea\x88\xd4\xb3\x83\x8f"
+ "\x6f\x97\x4b\x57\x7a\x64\x64\xae"
+ "\x0a\x37\x66\xc5\x03\xad\xb5\xf9"
+ "\x08\xb0\x3a\x74\xde\x97\x51\xff"
+ "\x48\x4f\x5c\xa4\xf8\x7a\xb4\x05"
+ "\x27\x70\x52\x86\x1b\x78\xfc\x18"
+ "\x06\x27\xa9\x62\xf7\xda\xd2\x8e",
+ .ctext = "\x3b\xe1\xdb\xb3\xc5\x9a\xde\x69"
+ "\x58\x05\xcc\xeb\x02\x51\x78\x4a"
+ "\xac\x28\xe9\xed\xd1\xc9\x15\x7d"
+ "\x33\x7d\xc1\x47\x12\x41\x11\xf8"
+ "\x4a\x2c\xb7\xa3\x41\xbe\x59\xf7"
+ "\x22\xdb\x2c\xda\x9c\x00\x61\x9b"
+ "\x73\xb3\x0b\x84\x2b\xc1\xf3\x80"
+ "\x84\xeb\x19\x60\x80\x09\xe1\xcd"
+ "\x16\x3a\x20\x23\xc4\x82\x4f\xba"
+ "\x3b\x8e\x55\xd7\xa9\x0b\x75\xd0"
+ "\xda\xce\xd2\xee\x7e\x4b\x7f\x65"
+ "\x4d\x28\xc5\xd3\x15\x2c\x40\x96"
+ "\x52\xd4\x18\x61\x2b\xe7\x83\xec"
+ "\x89\x62\x9c\x4c\x50\xe6\xe2\xbb"
+ "\x25\xa1\x0f\xa7\xb0\xb4\xb2\xde"
+ "\x54\x20\xae\xa3\x56\xa5\x26\x4c"
+ "\xd5\xcc\xe5\xcb\x28\x44\xb1\xef"
+ "\x67\x2e\x93\x6d\x00\x88\x83\x9a"
+ "\xf2\x1c\x48\x38\xec\x1a\x24\x90"
+ "\x73\x0a\xdb\xe8\xce\x95\x7a\x2c"
+ "\x8c\xe9\xb7\x07\x1d\xb3\xa3\x20"
+ "\xbe\xad\x61\x84\xac\xde\x76\xb5"
+ "\xa6\x28\x29\x47\x63\xc4\xfc\x13"
+ "\x3f\x71\xfb\x58\x37\x34\x82\xed"
+ "\x9e\x05\x19\x1f\xc1\x67\xc1\xab"
+ "\xf5\xfd\x7c\xea\xfa\xa4\xf8\x0a"
+ "\xac\x4c\x92\xdf\x65\x73\xd7\xdb"
+ "\xed\x2c\xe0\x84\x5f\x57\x8c\x76"
+ "\x3e\x05\xc0\xc3\x68\x96\x95\x0b"
+ "\x88\x97\xfe\x2e\x99\xd5\xc2\xb9"
+ "\x53\x9f\xf3\x32\x10\x1f\x1f\x5d"
+ "\xdf\x21\x95\x70\x91\xe8\xa1\x3e"
+ "\x19\x3e\xb6\x0b\xa8\xdb\xf8\xd4"
+ "\x54\x27\xb8\xab\x5d\x78\x0c\xe6"
+ "\xb7\x08\xee\xa4\xb6\x6b\xeb\x5a"
+ "\x89\x69\x2b\xbd\xd4\x21\x5b\xbf"
+ "\x79\xbb\x0f\xff\xdb\x23\x9a\xeb"
+ "\x8d\xf2\xc4\x39\xb4\x90\x77\x6f"
+ "\x68\xe2\xb8\xf3\xf1\x65\x4f\xd5"
+ "\x24\x80\x06\xaf\x7c\x8d\x15\x0c"
+ "\xfd\x56\xe5\xe3\x01\xa5\xf7\x1c"
+ "\x31\xd6\xa2\x01\x1e\x59\xf9\xa9"
+ "\x42\xd5\xc2\x34\xda\x25\xde\xc6"
+ "\x5d\x38\xef\xd1\x4c\xc1\xd9\x1b"
+ "\x98\xfd\xcd\x57\x6f\xfd\x46\x91"
+ "\x90\x3d\x52\x2b\x2c\x7d\xcf\x71"
+ "\xcf\xd1\x77\x23\x71\x36\xb1\xce"
+ "\xc7\x5d\xf0\x5b\x44\x3d\x43\x71"
+ "\xac\xb8\xa0\x6a\xea\x89\x5c\xff"
+ "\x81\x73\xd4\x83\xd1\xc9\xe9\xe2"
+ "\xa8\xa6\x0f\x36\xe6\xaa\x57\xd4"
+ "\x27\xd2\xc9\xda\x94\x02\x1f\xfb"
+ "\xe1\xa1\x07\xbe\xe1\x1b\x15\x94"
+ "\x1e\xac\x2f\x57\xbb\x41\x22\xaf"
+ "\x60\x5e\xcc\x66\xcb\x16\x62\xab"
+ "\xb8\x7c\x99\xf4\x84\x93\x0c\xc2"
+ "\xa2\x49\xe4\xfd\x17\x55\xe1\xa6"
+ "\x8d\x5b\xc6\x1b\xc8\xac\xec\x11"
+ "\x33\xcf\xb0\xe8\xc7\x28\x4f\xb2"
+ "\x5c\xa6\xe2\x71\xab\x80\x0a\xa7"
+ "\x5c\x59\x50\x9f\x7a\x32\xb7\xe5"
+ "\x24\x9a\x8e\x25\x21\x2e\xb7\x18"
+ "\xd0\xf2\xe7\x27\x6f\xda\xc1\x00"
+ "\xd9\xa6\x03\x59\xac\x4b\xcb\xba",
+ .klen = 24,
+ .len = 512,
+ },
+ {
+ .key = "\x9e\xeb\xb2\x49\x3c\x1c\xf5\xf4"
+ "\x6a\x99\xc2\xc4\xdf\xb1\xf4\xdd"
+ "\x75\x20\x57\xea\x2c\x4f\xcd\xb2"
+ "\xa5\x3d\x7b\x49\x1e\xab\xfd\x0f",
+ .iv = "\xdf\x63\xd4\xab\xd2\x49\xf3\xd8"
+ "\x33\x81\x37\x60\x7d\xfa\x73\x08"
+ "\xd8\x49\x6d\x80\xe8\x2f\x62\x54"
+ "\xeb\x0e\xa9\x39\x5b\x45\x7f\x8a",
+ .ptext = "\x67\xc9\xf2\x30\x84\x41\x8e\x43"
+ "\xfb\xf3\xb3\x3e\x79\x36\x7f\xe8",
+ .ctext = "\x27\x38\x78\x47\x16\xd9\x71\x35"
+ "\x2e\x7e\xdd\x7e\x43\x3c\xb8\x40",
+ .klen = 32,
+ .len = 16,
+ },
+ {
+ .key = "\x93\xfa\x7e\xe2\x0e\x67\xc4\x39"
+ "\xe7\xca\x47\x95\x68\x9d\x5e\x5a"
+ "\x7c\x26\x19\xab\xc6\xca\x6a\x4c"
+ "\x45\xa6\x96\x42\xae\x6c\xff\xe7",
+ .iv = "\xea\x82\x47\x95\x3b\x22\xa1\x3a"
+ "\x6a\xca\x24\x4c\x50\x7e\x23\xcd"
+ "\x0e\x50\xe5\x41\xb6\x65\x29\xd8"
+ "\x30\x23\x00\xd2\x54\xa7\xd6\x56",
+ .ptext = "\xdb\x1f\x1f\xec\xad\x83\x6e\x5d"
+ "\x19\xa5\xf6\x3b\xb4\x93\x5a\x57"
+ "\x6f",
+ .ctext = "\xf1\x46\x6e\x9d\xb3\x01\xf0\x6b"
+ "\xc2\xac\x57\x88\x48\x6d\x40\x72"
+ "\x68",
+ .klen = 32,
+ .len = 17,
+ },
+ {
+ .key = "\x36\x2b\x57\x97\xf8\x5d\xcd\x99"
+ "\x5f\x1a\x5a\x44\x1d\x92\x0f\x27"
+ "\xcc\x16\xd7\x2b\x85\x63\x99\xd3"
+ "\xba\x96\xa1\xdb\xd2\x60\x68\xda",
+ .iv = "\xef\x58\x69\xb1\x2c\x5e\x9a\x47"
+ "\x24\xc1\xb1\x69\xe1\x12\x93\x8f"
+ "\x43\x3d\x6d\x00\xdb\x5e\xd8\xd9"
+ "\x12\x9a\xfe\xd9\xff\x2d\xaa\xc4",
+ .ptext = "\x5e\xa8\x68\x19\x85\x98\x12\x23"
+ "\x26\x0a\xcc\xdb\x0a\x04\xb9\xdf"
+ "\x4d\xb3\x48\x7b\xb0\xe3\xc8\x19"
+ "\x43\x5a\x46\x06\x94\x2d\xf2",
+ .ctext = "\xdb\xfd\xc8\x03\xd0\xec\xc1\xfe"
+ "\xbd\x64\x37\xb8\x82\x43\x62\x4e"
+ "\x7e\x54\xa3\xe2\x24\xa7\x27\xe8"
+ "\xa4\xd5\xb3\x6c\xb2\x26\xb4",
+ .klen = 32,
+ .len = 31,
+ },
+ {
+ .key = "\x03\x65\x03\x6e\x4d\xe6\xe8\x4e"
+ "\x8b\xbe\x22\x19\x48\x31\xee\xd9"
+ "\xa0\x91\x21\xbe\x62\x89\xde\x78"
+ "\xd9\xb0\x36\xa3\x3c\xce\x43\xd5",
+ .iv = "\xa9\xc3\x4b\xe7\x0f\xfc\x6d\xbf"
+ "\x56\x27\x21\x1c\xfc\xd6\x04\x10"
+ "\x5f\x43\xe2\x30\x35\x29\x6c\x10"
+ "\x90\xf1\xbf\x61\xed\x0f\x8a\x91",
+ .ptext = "\x07\xaa\x02\x26\xb4\x98\x11\x5e"
+ "\x33\x41\x21\x51\x51\x63\x2c\x72"
+ "\x00\xab\x32\xa7\x1c\xc8\x3c\x9c"
+ "\x25\x0e\x8b\x9a\xdf\x85\xed\x2d"
+ "\xf4\xf2\xbc\x55\xca\x92\x6d\x22"
+ "\xfd\x22\x3b\x42\x4c\x0b\x74\xec",
+ .ctext = "\x7b\xb1\x43\x6d\xd8\x72\x6c\xf6"
+ "\x67\x6a\x00\xc4\xf1\xf0\xf5\xa4"
+ "\xfc\x60\x91\xab\x46\x0b\x15\xfc"
+ "\xd7\xc1\x28\x15\xa1\xfc\xf7\x68"
+ "\x8e\xcc\x27\x62\x00\x64\x56\x72"
+ "\xa6\x17\xd7\x3f\x67\x80\x10\x58",
+ .klen = 32,
+ .len = 48,
+ },
+ {
+ .key = "\xa5\x28\x24\x34\x1a\x3c\xd8\xf7"
+ "\x05\x91\x8f\xee\x85\x1f\x35\x7f"
+ "\x80\x3d\xfc\x9b\x94\xf6\xfc\x9e"
+ "\x19\x09\x00\xa9\x04\x31\x4f\x11",
+ .iv = "\xa1\xba\x49\x95\xff\x34\x6d\xb8"
+ "\xcd\x87\x5d\x5e\xfd\xea\x85\xdb"
+ "\x8a\x7b\x5e\xb2\x5d\x57\xdd\x62"
+ "\xac\xa9\x8c\x41\x42\x94\x75\xb7",
+ .ptext = "\x69\xb4\xe8\x8c\x37\xe8\x67\x82"
+ "\xf1\xec\x5d\x04\xe5\x14\x91\x13"
+ "\xdf\xf2\x87\x1b\x69\x81\x1d\x71"
+ "\x70\x9e\x9c\x3b\xde\x49\x70\x11"
+ "\xa0\xa3\xdb\x0d\x54\x4f\x66\x69"
+ "\xd7\xdb\x80\xa7\x70\x92\x68\xce"
+ "\x81\x04\x2c\xc6\xab\xae\xe5\x60"
+ "\x15\xe9\x6f\xef\xaa\x8f\xa7\xa7"
+ "\x63\x8f\xf2\xf0\x77\xf1\xa8\xea"
+ "\xe1\xb7\x1f\x9e\xab\x9e\x4b\x3f"
+ "\x07\x87\x5b\x6f\xcd\xa8\xaf\xb9"
+ "\xfa\x70\x0b\x52\xb8\xa8\xa7\x9e"
+ "\x07\x5f\xa6\x0e\xb3\x9b\x79\x13"
+ "\x79\xc3\x3e\x8d\x1c\x2c\x68\xc8"
+ "\x51\x1d\x3c\x7b\x7d\x79\x77\x2a"
+ "\x56\x65\xc5\x54\x23\x28\xb0\x03",
+ .ctext = "\xeb\xf9\x98\x86\x3c\x40\x9f\x16"
+ "\x84\x01\xf9\x06\x0f\xeb\x3c\xa9"
+ "\x4c\xa4\x8e\x5d\xc3\x8d\xe5\xd3"
+ "\xae\xa6\xe6\xcc\xd6\x2d\x37\x4f"
+ "\x99\xc8\xa3\x21\x46\xb8\x69\xf2"
+ "\xe3\x14\x89\xd7\xb9\xf5\x9e\x4e"
+ "\x07\x93\x6f\x78\x8e\x6b\xea\x8f"
+ "\xfb\x43\xb8\x3e\x9b\x4c\x1d\x7e"
+ "\x20\x9a\xc5\x87\xee\xaf\xf6\xf9"
+ "\x46\xc5\x18\x8a\xe8\x69\xe7\x96"
+ "\x52\x55\x5f\x00\x1e\x1a\xdc\xcc"
+ "\x13\xa5\xee\xff\x4b\x27\xca\xdc"
+ "\x10\xa6\x48\x76\x98\x43\x94\xa3"
+ "\xc7\xe2\xc9\x65\x9b\x08\x14\x26"
+ "\x1d\x68\xfb\x15\x0a\x33\x49\x84"
+ "\x84\x33\x5a\x1b\x24\x46\x31\x92",
+ .klen = 32,
+ .len = 128,
+ },
+ {
+ .key = "\x36\x45\x11\xa2\x98\x5f\x96\x7c"
+ "\xc6\xb4\x94\x31\x0a\x67\x09\x32"
+ "\x6c\x6f\x6f\x00\xf0\x17\xcb\xac"
+ "\xa5\xa9\x47\x9e\x2e\x85\x2f\xfa",
+ .iv = "\x28\x88\xaa\x9b\x59\x3b\x1e\x97"
+ "\x82\xe5\x5c\x9e\x6d\x14\x11\x19"
+ "\x6e\x38\x8f\xd5\x40\x2b\xca\xf9"
+ "\x7b\x4c\xe4\xa3\xd0\xd2\x8a\x13",
+ .ptext = "\x95\xd2\xf7\x71\x1b\xca\xa5\x86"
+ "\xd9\x48\x01\x93\x2f\x79\x55\x29"
+ "\x71\x13\x15\x0e\xe6\x12\xbc\x4d"
+ "\x8a\x31\xe3\x40\x2a\xc6\x5e\x0d"
+ "\x68\xbb\x4a\x62\x8d\xc7\x45\x77"
+ "\xd2\xb8\xc7\x1d\xf1\xd2\x5d\x97"
+ "\xcf\xac\x52\xe5\x32\x77\xb6\xda"
+ "\x30\x85\xcf\x2b\x98\xe9\xaa\x34"
+ "\x62\xb5\x23\x9e\xb7\xa6\xd4\xe0"
+ "\xb4\x58\x18\x8c\x4d\xde\x4d\x01"
+ "\x83\x89\x24\xca\xfb\x11\xd4\x82"
+ "\x30\x7a\x81\x35\xa0\xb4\xd4\xb6"
+ "\x84\xea\x47\x91\x8c\x19\x86\x25"
+ "\xa6\x06\x8d\x78\xe6\xed\x87\xeb"
+ "\xda\xea\x73\x7c\xbf\x66\xb8\x72"
+ "\xe3\x0a\xb8\x0c\xcb\x1a\x73\xf1"
+ "\xa7\xca\x0a\xde\x57\x2b\xbd\x2b"
+ "\xeb\x8b\x24\x38\x22\xd3\x0e\x1f"
+ "\x17\xa0\x84\x98\x31\x77\xfd\x34"
+ "\x6a\x4e\x3d\x84\x4c\x0e\xfb\xed"
+ "\xc8\x2a\x51\xfa\xd8\x73\x21\x8a"
+ "\xdb\xb5\xfe\x1f\xee\xc4\xe8\x65"
+ "\x54\x84\xdd\x96\x6d\xfd\xd3\x31"
+ "\x77\x36\x52\x6b\x80\x4f\x9e\xb4"
+ "\xa2\x55\xbf\x66\x41\x49\x4e\x87"
+ "\xa7\x0c\xca\xe7\xa5\xc5\xf6\x6f"
+ "\x27\x56\xe2\x48\x22\xdd\x5f\x59"
+ "\x3c\xf1\x9f\x83\xe5\x2d\xfb\x71"
+ "\xad\xd1\xae\x1b\x20\x5c\x47\xb7"
+ "\x3b\xd3\x14\xce\x81\x42\xb1\x0a"
+ "\xf0\x49\xfa\xc2\xe7\x86\xbf\xcd"
+ "\xb0\x95\x9f\x8f\x79\x41\x54",
+ .ctext = "\xf6\x57\x51\xc4\x25\x61\x2d\xfa"
+ "\xd6\xd9\x3f\x9a\x81\x51\xdd\x8e"
+ "\x3d\xe7\xaa\x2d\xb1\xda\xc8\xa6"
+ "\x9d\xaa\x3c\xab\x62\xf2\x80\xc3"
+ "\x2c\xe7\x58\x72\x1d\x44\xc5\x28"
+ "\x7f\xb4\xf9\xbc\x9c\xb2\xab\x8e"
+ "\xfa\xd1\x4d\x72\xd9\x79\xf5\xa0"
+ "\x24\x3e\x90\x25\x31\x14\x38\x45"
+ "\x59\xc8\xf6\xe2\xc6\xf6\xc1\xa7"
+ "\xb2\xf8\xa7\xa9\x2b\x6f\x12\x3a"
+ "\xb0\x81\xa4\x08\x57\x59\xb1\x56"
+ "\x4c\x8f\x18\x55\x33\x5f\xd6\x6a"
+ "\xc6\xa0\x4b\xd6\x6b\x64\x3e\x9e"
+ "\xfd\x66\x16\xe2\xdb\xeb\x5f\xb3"
+ "\x50\x50\x3e\xde\x8d\x72\x76\x01"
+ "\xbe\xcc\xc9\x52\x09\x2d\x8d\xe7"
+ "\xd6\xc3\x66\xdb\x36\x08\xd1\x77"
+ "\xc8\x73\x46\x26\x24\x29\xbf\x68"
+ "\x2d\x2a\x99\x43\x56\x55\xe4\x93"
+ "\xaf\xae\x4d\xe7\x55\x4a\xc0\x45"
+ "\x26\xeb\x3b\x12\x90\x7c\xdc\xd1"
+ "\xd5\x6f\x0a\xd0\xa9\xd7\x4b\x89"
+ "\x0b\x07\xd8\x86\xad\xa1\xc4\x69"
+ "\x1f\x5e\x8b\xc4\x9e\x91\x41\x25"
+ "\x56\x98\x69\x78\x3a\x9e\xae\x91"
+ "\xd8\xd9\xfa\xfb\xff\x81\x25\x09"
+ "\xfc\xed\x2d\x87\xbc\x04\x62\x97"
+ "\x35\xe1\x26\xc2\x46\x1c\xcf\xd7"
+ "\x14\xed\x02\x09\xa5\xb2\xb6\xaa"
+ "\x27\x4e\x61\xb3\x71\x6b\x47\x16"
+ "\xb7\xe8\xd4\xaf\x52\xeb\x6a\x6b"
+ "\xdb\x4c\x65\x21\x9e\x1c\x36",
+ .klen = 32,
+ .len = 255,
+ },
+ {
+ .key = "\xd3\x81\x72\x18\x23\xff\x6f\x4a"
+ "\x25\x74\x29\x0d\x51\x8a\x0e\x13"
+ "\xc1\x53\x5d\x30\x8d\xee\x75\x0d"
+ "\x14\xd6\x69\xc9\x15\xa9\x0c\x60",
+ .iv = "\x65\x9b\xd4\xa8\x7d\x29\x1d\xf4"
+ "\xc4\xd6\x9b\x6a\x28\xab\x64\xe2"
+ "\x62\x81\x97\xc5\x81\xaa\xf9\x44"
+ "\xc1\x72\x59\x82\xaf\x16\xc8\x2c",
+ .ptext = "\xc7\x6b\x52\x6a\x10\xf0\xcc\x09"
+ "\xc1\x12\x1d\x6d\x21\xa6\x78\xf5"
+ "\x05\xa3\x69\x60\x91\x36\x98\x57"
+ "\xba\x0c\x14\xcc\xf3\x2d\x73\x03"
+ "\xc6\xb2\x5f\xc8\x16\x27\x37\x5d"
+ "\xd0\x0b\x87\xb2\x50\x94\x7b\x58"
+ "\x04\xf4\xe0\x7f\x6e\x57\x8e\xc9"
+ "\x41\x84\xc1\xb1\x7e\x4b\x91\x12"
+ "\x3a\x8b\x5d\x50\x82\x7b\xcb\xd9"
+ "\x9a\xd9\x4e\x18\x06\x23\x9e\xd4"
+ "\xa5\x20\x98\xef\xb5\xda\xe5\xc0"
+ "\x8a\x6a\x83\x77\x15\x84\x1e\xae"
+ "\x78\x94\x9d\xdf\xb7\xd1\xea\x67"
+ "\xaa\xb0\x14\x15\xfa\x67\x21\x84"
+ "\xd3\x41\x2a\xce\xba\x4b\x4a\xe8"
+ "\x95\x62\xa9\x55\xf0\x80\xad\xbd"
+ "\xab\xaf\xdd\x4f\xa5\x7c\x13\x36"
+ "\xed\x5e\x4f\x72\xad\x4b\xf1\xd0"
+ "\x88\x4e\xec\x2c\x88\x10\x5e\xea"
+ "\x12\xc0\x16\x01\x29\xa3\xa0\x55"
+ "\xaa\x68\xf3\xe9\x9d\x3b\x0d\x3b"
+ "\x6d\xec\xf8\xa0\x2d\xf0\x90\x8d"
+ "\x1c\xe2\x88\xd4\x24\x71\xf9\xb3"
+ "\xc1\x9f\xc5\xd6\x76\x70\xc5\x2e"
+ "\x9c\xac\xdb\x90\xbd\x83\x72\xba"
+ "\x6e\xb5\xa5\x53\x83\xa9\xa5\xbf"
+ "\x7d\x06\x0e\x3c\x2a\xd2\x04\xb5"
+ "\x1e\x19\x38\x09\x16\xd2\x82\x1f"
+ "\x75\x18\x56\xb8\x96\x0b\xa6\xf9"
+ "\xcf\x62\xd9\x32\x5d\xa9\xd7\x1d"
+ "\xec\xe4\xdf\x1b\xbe\xf1\x36\xee"
+ "\xe3\x7b\xb5\x2f\xee\xf8\x53\x3d"
+ "\x6a\xb7\x70\xa9\xfc\x9c\x57\x25"
+ "\xf2\x89\x10\xd3\xb8\xa8\x8c\x30"
+ "\xae\x23\x4f\x0e\x13\x66\x4f\xe1"
+ "\xb6\xc0\xe4\xf8\xef\x93\xbd\x6e"
+ "\x15\x85\x6b\xe3\x60\x81\x1d\x68"
+ "\xd7\x31\x87\x89\x09\xab\xd5\x96"
+ "\x1d\xf3\x6d\x67\x80\xca\x07\x31"
+ "\x5d\xa7\xe4\xfb\x3e\xf2\x9b\x33"
+ "\x52\x18\xc8\x30\xfe\x2d\xca\x1e"
+ "\x79\x92\x7a\x60\x5c\xb6\x58\x87"
+ "\xa4\x36\xa2\x67\x92\x8b\xa4\xb7"
+ "\xf1\x86\xdf\xdc\xc0\x7e\x8f\x63"
+ "\xd2\xa2\xdc\x78\xeb\x4f\xd8\x96"
+ "\x47\xca\xb8\x91\xf9\xf7\x94\x21"
+ "\x5f\x9a\x9f\x5b\xb8\x40\x41\x4b"
+ "\x66\x69\x6a\x72\xd0\xcb\x70\xb7"
+ "\x93\xb5\x37\x96\x05\x37\x4f\xe5"
+ "\x8c\xa7\x5a\x4e\x8b\xb7\x84\xea"
+ "\xc7\xfc\x19\x6e\x1f\x5a\xa1\xac"
+ "\x18\x7d\x52\x3b\xb3\x34\x62\x99"
+ "\xe4\x9e\x31\x04\x3f\xc0\x8d\x84"
+ "\x17\x7c\x25\x48\x52\x67\x11\x27"
+ "\x67\xbb\x5a\x85\xca\x56\xb2\x5c"
+ "\xe6\xec\xd5\x96\x3d\x15\xfc\xfb"
+ "\x22\x25\xf4\x13\xe5\x93\x4b\x9a"
+ "\x77\xf1\x52\x18\xfa\x16\x5e\x49"
+ "\x03\x45\xa8\x08\xfa\xb3\x41\x92"
+ "\x79\x50\x33\xca\xd0\xd7\x42\x55"
+ "\xc3\x9a\x0c\x4e\xd9\xa4\x3c\x86"
+ "\x80\x9f\x53\xd1\xa4\x2e\xd1\xbc"
+ "\xf1\x54\x6e\x93\xa4\x65\x99\x8e"
+ "\xdf\x29\xc0\x64\x63\x07\xbb\xea",
+ .ctext = "\x9f\x72\x87\xc7\x17\xfb\x20\x15"
+ "\x65\xb3\x55\xa8\x1c\x8e\x52\x32"
+ "\xb1\x82\x8d\xbf\xb5\x9f\x10\x0a"
+ "\xe8\x0c\x70\x62\xef\x89\xb6\x1f"
+ "\x73\xcc\xe4\xcc\x7a\x3a\x75\x4a"
+ "\x26\xe7\xf5\xd7\x7b\x17\x39\x2d"
+ "\xd2\x27\x6e\xf9\x2f\x9e\xe2\xf6"
+ "\xfa\x16\xc2\xf2\x49\x26\xa7\x5b"
+ "\xe7\xca\x25\x0e\x45\xa0\x34\xc2"
+ "\x9a\x37\x79\x7e\x7c\x58\x18\x94"
+ "\x10\xa8\x7c\x48\xa9\xd7\x63\x89"
+ "\x9e\x61\x4d\x26\x34\xd9\xf0\xb1"
+ "\x2d\x17\x2c\x6f\x7c\x35\x0e\xbe"
+ "\x77\x71\x7c\x17\x5b\xab\x70\xdb"
+ "\x2f\x54\x0f\xa9\xc8\xf4\xf5\xab"
+ "\x52\x04\x3a\xb8\x03\xa7\xfd\x57"
+ "\x45\x5e\xbc\x77\xe1\xee\x79\x8c"
+ "\x58\x7b\x1f\xf7\x75\xde\x68\x17"
+ "\x98\x85\x8a\x18\x5c\xd2\x39\x78"
+ "\x7a\x6f\x26\x6e\xe1\x13\x91\xdd"
+ "\xdf\x0e\x6e\x67\xcc\x51\x53\xd8"
+ "\x17\x5e\xce\xa7\xe4\xaf\xfa\xf3"
+ "\x4f\x9f\x01\x9b\x04\xe7\xfc\xf9"
+ "\x6a\xdc\x1d\x0c\x9a\xaa\x3a\x7a"
+ "\x73\x03\xdf\xbf\x3b\x82\xbe\xb0"
+ "\xb4\xa4\xcf\x07\xd7\xde\x71\x25"
+ "\xc5\x10\xee\x0a\x15\x96\x8b\x4f"
+ "\xfe\xb8\x28\xbd\x4a\xcd\xeb\x9f"
+ "\x5d\x00\xc1\xee\xe8\x16\x44\xec"
+ "\xe9\x7b\xd6\x85\x17\x29\xcf\x58"
+ "\x20\xab\xf7\xce\x6b\xe7\x71\x7d"
+ "\x4f\xa8\xb0\xe9\x7d\x70\xd6\x0b"
+ "\x2e\x20\xb1\x1a\x63\x37\xaa\x2c"
+ "\x94\xee\xd5\xf6\x58\x2a\xf4\x7a"
+ "\x4c\xba\xf5\xe9\x3c\x6f\x95\x13"
+ "\x5f\x96\x81\x5b\xb5\x62\xf2\xd7"
+ "\x8d\xbe\xa1\x31\x51\xe6\xfe\xc9"
+ "\x07\x7d\x0f\x00\x3a\x66\x8c\x4b"
+ "\x94\xaa\xe5\x56\xde\xcd\x74\xa7"
+ "\x48\x67\x6f\xed\xc9\x6a\xef\xaf"
+ "\x9a\xb7\xae\x60\xfa\xc0\x37\x39"
+ "\xa5\x25\xe5\x22\xea\x82\x55\x68"
+ "\x3e\x30\xc3\x5a\xb6\x29\x73\x7a"
+ "\xb6\xfb\x34\xee\x51\x7c\x54\xe5"
+ "\x01\x4d\x72\x25\x32\x4a\xa3\x68"
+ "\x80\x9a\x89\xc5\x11\x66\x4c\x8c"
+ "\x44\x50\xbe\xd7\xa0\xee\xa6\xbb"
+ "\x92\x0c\xe6\xd7\x83\x51\xb1\x69"
+ "\x63\x40\xf3\xf4\x92\x84\xc4\x38"
+ "\x29\xfb\xb4\x84\xa0\x19\x75\x16"
+ "\x60\xbf\x0a\x9c\x89\xee\xad\xb4"
+ "\x43\xf9\x71\x39\x45\x7c\x24\x83"
+ "\x30\xbb\xee\x28\xb0\x86\x7b\xec"
+ "\x93\xc1\xbf\xb9\x97\x1b\x96\xef"
+ "\xee\x58\x35\x61\x12\x19\xda\x25"
+ "\x77\xe5\x80\x1a\x31\x27\x9b\xe4"
+ "\xda\x8b\x7e\x51\x4d\xcb\x01\x19"
+ "\x4f\xdc\x92\x1a\x17\xd5\x6b\xf4"
+ "\x50\xe3\x06\xe4\x76\x9f\x65\x00"
+ "\xbd\x7a\xe2\x64\x26\xf2\xe4\x7e"
+ "\x40\xf2\x80\xab\x62\xd5\xef\x23"
+ "\x8b\xfb\x6f\x24\x6e\x9b\x66\x0e"
+ "\xf4\x1c\x24\x1e\x1d\x26\x95\x09"
+ "\x94\x3c\xb2\xb6\x02\xa7\xd9\x9a",
+ .klen = 32,
+ .len = 512,
+ },
+
+};
#endif /* _CRYPTO_TESTMGR_H */
diff --git a/crypto/tgr192.c b/crypto/tgr192.c
deleted file mode 100644
index aa29c529b44e..000000000000
--- a/crypto/tgr192.c
+++ /dev/null
@@ -1,682 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Cryptographic API.
- *
- * Tiger hashing Algorithm
- *
- * Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * The Tiger algorithm was developed by Ross Anderson and Eli Biham.
- * It was optimized for 64-bit processors while still delievering
- * decent performance on 32 and 16-bit processors.
- *
- * This version is derived from the GnuPG implementation and the
- * Tiger-Perl interface written by Rafael Sevilla
- *
- * Adapted for Linux Kernel Crypto by Aaron Grothe
- * ajgrothe@yahoo.com, February 22, 2005
- */
-#include <crypto/internal/hash.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/types.h>
-#include <asm/byteorder.h>
-#include <asm/unaligned.h>
-
-#define TGR192_DIGEST_SIZE 24
-#define TGR160_DIGEST_SIZE 20
-#define TGR128_DIGEST_SIZE 16
-
-#define TGR192_BLOCK_SIZE 64
-
-struct tgr192_ctx {
- u64 a, b, c;
- u8 hash[64];
- int count;
- u32 nblocks;
-};
-
-static const u64 sbox1[256] = {
- 0x02aab17cf7e90c5eULL, 0xac424b03e243a8ecULL, 0x72cd5be30dd5fcd3ULL,
- 0x6d019b93f6f97f3aULL, 0xcd9978ffd21f9193ULL, 0x7573a1c9708029e2ULL,
- 0xb164326b922a83c3ULL, 0x46883eee04915870ULL, 0xeaace3057103ece6ULL,
- 0xc54169b808a3535cULL, 0x4ce754918ddec47cULL, 0x0aa2f4dfdc0df40cULL,
- 0x10b76f18a74dbefaULL, 0xc6ccb6235ad1ab6aULL, 0x13726121572fe2ffULL,
- 0x1a488c6f199d921eULL, 0x4bc9f9f4da0007caULL, 0x26f5e6f6e85241c7ULL,
- 0x859079dbea5947b6ULL, 0x4f1885c5c99e8c92ULL, 0xd78e761ea96f864bULL,
- 0x8e36428c52b5c17dULL, 0x69cf6827373063c1ULL, 0xb607c93d9bb4c56eULL,
- 0x7d820e760e76b5eaULL, 0x645c9cc6f07fdc42ULL, 0xbf38a078243342e0ULL,
- 0x5f6b343c9d2e7d04ULL, 0xf2c28aeb600b0ec6ULL, 0x6c0ed85f7254bcacULL,
- 0x71592281a4db4fe5ULL, 0x1967fa69ce0fed9fULL, 0xfd5293f8b96545dbULL,
- 0xc879e9d7f2a7600bULL, 0x860248920193194eULL, 0xa4f9533b2d9cc0b3ULL,
- 0x9053836c15957613ULL, 0xdb6dcf8afc357bf1ULL, 0x18beea7a7a370f57ULL,
- 0x037117ca50b99066ULL, 0x6ab30a9774424a35ULL, 0xf4e92f02e325249bULL,
- 0x7739db07061ccae1ULL, 0xd8f3b49ceca42a05ULL, 0xbd56be3f51382f73ULL,
- 0x45faed5843b0bb28ULL, 0x1c813d5c11bf1f83ULL, 0x8af0e4b6d75fa169ULL,
- 0x33ee18a487ad9999ULL, 0x3c26e8eab1c94410ULL, 0xb510102bc0a822f9ULL,
- 0x141eef310ce6123bULL, 0xfc65b90059ddb154ULL, 0xe0158640c5e0e607ULL,
- 0x884e079826c3a3cfULL, 0x930d0d9523c535fdULL, 0x35638d754e9a2b00ULL,
- 0x4085fccf40469dd5ULL, 0xc4b17ad28be23a4cULL, 0xcab2f0fc6a3e6a2eULL,
- 0x2860971a6b943fcdULL, 0x3dde6ee212e30446ULL, 0x6222f32ae01765aeULL,
- 0x5d550bb5478308feULL, 0xa9efa98da0eda22aULL, 0xc351a71686c40da7ULL,
- 0x1105586d9c867c84ULL, 0xdcffee85fda22853ULL, 0xccfbd0262c5eef76ULL,
- 0xbaf294cb8990d201ULL, 0xe69464f52afad975ULL, 0x94b013afdf133e14ULL,
- 0x06a7d1a32823c958ULL, 0x6f95fe5130f61119ULL, 0xd92ab34e462c06c0ULL,
- 0xed7bde33887c71d2ULL, 0x79746d6e6518393eULL, 0x5ba419385d713329ULL,
- 0x7c1ba6b948a97564ULL, 0x31987c197bfdac67ULL, 0xde6c23c44b053d02ULL,
- 0x581c49fed002d64dULL, 0xdd474d6338261571ULL, 0xaa4546c3e473d062ULL,
- 0x928fce349455f860ULL, 0x48161bbacaab94d9ULL, 0x63912430770e6f68ULL,
- 0x6ec8a5e602c6641cULL, 0x87282515337ddd2bULL, 0x2cda6b42034b701bULL,
- 0xb03d37c181cb096dULL, 0xe108438266c71c6fULL, 0x2b3180c7eb51b255ULL,
- 0xdf92b82f96c08bbcULL, 0x5c68c8c0a632f3baULL, 0x5504cc861c3d0556ULL,
- 0xabbfa4e55fb26b8fULL, 0x41848b0ab3baceb4ULL, 0xb334a273aa445d32ULL,
- 0xbca696f0a85ad881ULL, 0x24f6ec65b528d56cULL, 0x0ce1512e90f4524aULL,
- 0x4e9dd79d5506d35aULL, 0x258905fac6ce9779ULL, 0x2019295b3e109b33ULL,
- 0xf8a9478b73a054ccULL, 0x2924f2f934417eb0ULL, 0x3993357d536d1bc4ULL,
- 0x38a81ac21db6ff8bULL, 0x47c4fbf17d6016bfULL, 0x1e0faadd7667e3f5ULL,
- 0x7abcff62938beb96ULL, 0xa78dad948fc179c9ULL, 0x8f1f98b72911e50dULL,
- 0x61e48eae27121a91ULL, 0x4d62f7ad31859808ULL, 0xeceba345ef5ceaebULL,
- 0xf5ceb25ebc9684ceULL, 0xf633e20cb7f76221ULL, 0xa32cdf06ab8293e4ULL,
- 0x985a202ca5ee2ca4ULL, 0xcf0b8447cc8a8fb1ULL, 0x9f765244979859a3ULL,
- 0xa8d516b1a1240017ULL, 0x0bd7ba3ebb5dc726ULL, 0xe54bca55b86adb39ULL,
- 0x1d7a3afd6c478063ULL, 0x519ec608e7669eddULL, 0x0e5715a2d149aa23ULL,
- 0x177d4571848ff194ULL, 0xeeb55f3241014c22ULL, 0x0f5e5ca13a6e2ec2ULL,
- 0x8029927b75f5c361ULL, 0xad139fabc3d6e436ULL, 0x0d5df1a94ccf402fULL,
- 0x3e8bd948bea5dfc8ULL, 0xa5a0d357bd3ff77eULL, 0xa2d12e251f74f645ULL,
- 0x66fd9e525e81a082ULL, 0x2e0c90ce7f687a49ULL, 0xc2e8bcbeba973bc5ULL,
- 0x000001bce509745fULL, 0x423777bbe6dab3d6ULL, 0xd1661c7eaef06eb5ULL,
- 0xa1781f354daacfd8ULL, 0x2d11284a2b16affcULL, 0xf1fc4f67fa891d1fULL,
- 0x73ecc25dcb920adaULL, 0xae610c22c2a12651ULL, 0x96e0a810d356b78aULL,
- 0x5a9a381f2fe7870fULL, 0xd5ad62ede94e5530ULL, 0xd225e5e8368d1427ULL,
- 0x65977b70c7af4631ULL, 0x99f889b2de39d74fULL, 0x233f30bf54e1d143ULL,
- 0x9a9675d3d9a63c97ULL, 0x5470554ff334f9a8ULL, 0x166acb744a4f5688ULL,
- 0x70c74caab2e4aeadULL, 0xf0d091646f294d12ULL, 0x57b82a89684031d1ULL,
- 0xefd95a5a61be0b6bULL, 0x2fbd12e969f2f29aULL, 0x9bd37013feff9fe8ULL,
- 0x3f9b0404d6085a06ULL, 0x4940c1f3166cfe15ULL, 0x09542c4dcdf3defbULL,
- 0xb4c5218385cd5ce3ULL, 0xc935b7dc4462a641ULL, 0x3417f8a68ed3b63fULL,
- 0xb80959295b215b40ULL, 0xf99cdaef3b8c8572ULL, 0x018c0614f8fcb95dULL,
- 0x1b14accd1a3acdf3ULL, 0x84d471f200bb732dULL, 0xc1a3110e95e8da16ULL,
- 0x430a7220bf1a82b8ULL, 0xb77e090d39df210eULL, 0x5ef4bd9f3cd05e9dULL,
- 0x9d4ff6da7e57a444ULL, 0xda1d60e183d4a5f8ULL, 0xb287c38417998e47ULL,
- 0xfe3edc121bb31886ULL, 0xc7fe3ccc980ccbefULL, 0xe46fb590189bfd03ULL,
- 0x3732fd469a4c57dcULL, 0x7ef700a07cf1ad65ULL, 0x59c64468a31d8859ULL,
- 0x762fb0b4d45b61f6ULL, 0x155baed099047718ULL, 0x68755e4c3d50baa6ULL,
- 0xe9214e7f22d8b4dfULL, 0x2addbf532eac95f4ULL, 0x32ae3909b4bd0109ULL,
- 0x834df537b08e3450ULL, 0xfa209da84220728dULL, 0x9e691d9b9efe23f7ULL,
- 0x0446d288c4ae8d7fULL, 0x7b4cc524e169785bULL, 0x21d87f0135ca1385ULL,
- 0xcebb400f137b8aa5ULL, 0x272e2b66580796beULL, 0x3612264125c2b0deULL,
- 0x057702bdad1efbb2ULL, 0xd4babb8eacf84be9ULL, 0x91583139641bc67bULL,
- 0x8bdc2de08036e024ULL, 0x603c8156f49f68edULL, 0xf7d236f7dbef5111ULL,
- 0x9727c4598ad21e80ULL, 0xa08a0896670a5fd7ULL, 0xcb4a8f4309eba9cbULL,
- 0x81af564b0f7036a1ULL, 0xc0b99aa778199abdULL, 0x959f1ec83fc8e952ULL,
- 0x8c505077794a81b9ULL, 0x3acaaf8f056338f0ULL, 0x07b43f50627a6778ULL,
- 0x4a44ab49f5eccc77ULL, 0x3bc3d6e4b679ee98ULL, 0x9cc0d4d1cf14108cULL,
- 0x4406c00b206bc8a0ULL, 0x82a18854c8d72d89ULL, 0x67e366b35c3c432cULL,
- 0xb923dd61102b37f2ULL, 0x56ab2779d884271dULL, 0xbe83e1b0ff1525afULL,
- 0xfb7c65d4217e49a9ULL, 0x6bdbe0e76d48e7d4ULL, 0x08df828745d9179eULL,
- 0x22ea6a9add53bd34ULL, 0xe36e141c5622200aULL, 0x7f805d1b8cb750eeULL,
- 0xafe5c7a59f58e837ULL, 0xe27f996a4fb1c23cULL, 0xd3867dfb0775f0d0ULL,
- 0xd0e673de6e88891aULL, 0x123aeb9eafb86c25ULL, 0x30f1d5d5c145b895ULL,
- 0xbb434a2dee7269e7ULL, 0x78cb67ecf931fa38ULL, 0xf33b0372323bbf9cULL,
- 0x52d66336fb279c74ULL, 0x505f33ac0afb4eaaULL, 0xe8a5cd99a2cce187ULL,
- 0x534974801e2d30bbULL, 0x8d2d5711d5876d90ULL, 0x1f1a412891bc038eULL,
- 0xd6e2e71d82e56648ULL, 0x74036c3a497732b7ULL, 0x89b67ed96361f5abULL,
- 0xffed95d8f1ea02a2ULL, 0xe72b3bd61464d43dULL, 0xa6300f170bdc4820ULL,
- 0xebc18760ed78a77aULL
-};
-
-static const u64 sbox2[256] = {
- 0xe6a6be5a05a12138ULL, 0xb5a122a5b4f87c98ULL, 0x563c6089140b6990ULL,
- 0x4c46cb2e391f5dd5ULL, 0xd932addbc9b79434ULL, 0x08ea70e42015aff5ULL,
- 0xd765a6673e478cf1ULL, 0xc4fb757eab278d99ULL, 0xdf11c6862d6e0692ULL,
- 0xddeb84f10d7f3b16ULL, 0x6f2ef604a665ea04ULL, 0x4a8e0f0ff0e0dfb3ULL,
- 0xa5edeef83dbcba51ULL, 0xfc4f0a2a0ea4371eULL, 0xe83e1da85cb38429ULL,
- 0xdc8ff882ba1b1ce2ULL, 0xcd45505e8353e80dULL, 0x18d19a00d4db0717ULL,
- 0x34a0cfeda5f38101ULL, 0x0be77e518887caf2ULL, 0x1e341438b3c45136ULL,
- 0xe05797f49089ccf9ULL, 0xffd23f9df2591d14ULL, 0x543dda228595c5cdULL,
- 0x661f81fd99052a33ULL, 0x8736e641db0f7b76ULL, 0x15227725418e5307ULL,
- 0xe25f7f46162eb2faULL, 0x48a8b2126c13d9feULL, 0xafdc541792e76eeaULL,
- 0x03d912bfc6d1898fULL, 0x31b1aafa1b83f51bULL, 0xf1ac2796e42ab7d9ULL,
- 0x40a3a7d7fcd2ebacULL, 0x1056136d0afbbcc5ULL, 0x7889e1dd9a6d0c85ULL,
- 0xd33525782a7974aaULL, 0xa7e25d09078ac09bULL, 0xbd4138b3eac6edd0ULL,
- 0x920abfbe71eb9e70ULL, 0xa2a5d0f54fc2625cULL, 0xc054e36b0b1290a3ULL,
- 0xf6dd59ff62fe932bULL, 0x3537354511a8ac7dULL, 0xca845e9172fadcd4ULL,
- 0x84f82b60329d20dcULL, 0x79c62ce1cd672f18ULL, 0x8b09a2add124642cULL,
- 0xd0c1e96a19d9e726ULL, 0x5a786a9b4ba9500cULL, 0x0e020336634c43f3ULL,
- 0xc17b474aeb66d822ULL, 0x6a731ae3ec9baac2ULL, 0x8226667ae0840258ULL,
- 0x67d4567691caeca5ULL, 0x1d94155c4875adb5ULL, 0x6d00fd985b813fdfULL,
- 0x51286efcb774cd06ULL, 0x5e8834471fa744afULL, 0xf72ca0aee761ae2eULL,
- 0xbe40e4cdaee8e09aULL, 0xe9970bbb5118f665ULL, 0x726e4beb33df1964ULL,
- 0x703b000729199762ULL, 0x4631d816f5ef30a7ULL, 0xb880b5b51504a6beULL,
- 0x641793c37ed84b6cULL, 0x7b21ed77f6e97d96ULL, 0x776306312ef96b73ULL,
- 0xae528948e86ff3f4ULL, 0x53dbd7f286a3f8f8ULL, 0x16cadce74cfc1063ULL,
- 0x005c19bdfa52c6ddULL, 0x68868f5d64d46ad3ULL, 0x3a9d512ccf1e186aULL,
- 0x367e62c2385660aeULL, 0xe359e7ea77dcb1d7ULL, 0x526c0773749abe6eULL,
- 0x735ae5f9d09f734bULL, 0x493fc7cc8a558ba8ULL, 0xb0b9c1533041ab45ULL,
- 0x321958ba470a59bdULL, 0x852db00b5f46c393ULL, 0x91209b2bd336b0e5ULL,
- 0x6e604f7d659ef19fULL, 0xb99a8ae2782ccb24ULL, 0xccf52ab6c814c4c7ULL,
- 0x4727d9afbe11727bULL, 0x7e950d0c0121b34dULL, 0x756f435670ad471fULL,
- 0xf5add442615a6849ULL, 0x4e87e09980b9957aULL, 0x2acfa1df50aee355ULL,
- 0xd898263afd2fd556ULL, 0xc8f4924dd80c8fd6ULL, 0xcf99ca3d754a173aULL,
- 0xfe477bacaf91bf3cULL, 0xed5371f6d690c12dULL, 0x831a5c285e687094ULL,
- 0xc5d3c90a3708a0a4ULL, 0x0f7f903717d06580ULL, 0x19f9bb13b8fdf27fULL,
- 0xb1bd6f1b4d502843ULL, 0x1c761ba38fff4012ULL, 0x0d1530c4e2e21f3bULL,
- 0x8943ce69a7372c8aULL, 0xe5184e11feb5ce66ULL, 0x618bdb80bd736621ULL,
- 0x7d29bad68b574d0bULL, 0x81bb613e25e6fe5bULL, 0x071c9c10bc07913fULL,
- 0xc7beeb7909ac2d97ULL, 0xc3e58d353bc5d757ULL, 0xeb017892f38f61e8ULL,
- 0xd4effb9c9b1cc21aULL, 0x99727d26f494f7abULL, 0xa3e063a2956b3e03ULL,
- 0x9d4a8b9a4aa09c30ULL, 0x3f6ab7d500090fb4ULL, 0x9cc0f2a057268ac0ULL,
- 0x3dee9d2dedbf42d1ULL, 0x330f49c87960a972ULL, 0xc6b2720287421b41ULL,
- 0x0ac59ec07c00369cULL, 0xef4eac49cb353425ULL, 0xf450244eef0129d8ULL,
- 0x8acc46e5caf4deb6ULL, 0x2ffeab63989263f7ULL, 0x8f7cb9fe5d7a4578ULL,
- 0x5bd8f7644e634635ULL, 0x427a7315bf2dc900ULL, 0x17d0c4aa2125261cULL,
- 0x3992486c93518e50ULL, 0xb4cbfee0a2d7d4c3ULL, 0x7c75d6202c5ddd8dULL,
- 0xdbc295d8e35b6c61ULL, 0x60b369d302032b19ULL, 0xce42685fdce44132ULL,
- 0x06f3ddb9ddf65610ULL, 0x8ea4d21db5e148f0ULL, 0x20b0fce62fcd496fULL,
- 0x2c1b912358b0ee31ULL, 0xb28317b818f5a308ULL, 0xa89c1e189ca6d2cfULL,
- 0x0c6b18576aaadbc8ULL, 0xb65deaa91299fae3ULL, 0xfb2b794b7f1027e7ULL,
- 0x04e4317f443b5bebULL, 0x4b852d325939d0a6ULL, 0xd5ae6beefb207ffcULL,
- 0x309682b281c7d374ULL, 0xbae309a194c3b475ULL, 0x8cc3f97b13b49f05ULL,
- 0x98a9422ff8293967ULL, 0x244b16b01076ff7cULL, 0xf8bf571c663d67eeULL,
- 0x1f0d6758eee30da1ULL, 0xc9b611d97adeb9b7ULL, 0xb7afd5887b6c57a2ULL,
- 0x6290ae846b984fe1ULL, 0x94df4cdeacc1a5fdULL, 0x058a5bd1c5483affULL,
- 0x63166cc142ba3c37ULL, 0x8db8526eb2f76f40ULL, 0xe10880036f0d6d4eULL,
- 0x9e0523c9971d311dULL, 0x45ec2824cc7cd691ULL, 0x575b8359e62382c9ULL,
- 0xfa9e400dc4889995ULL, 0xd1823ecb45721568ULL, 0xdafd983b8206082fULL,
- 0xaa7d29082386a8cbULL, 0x269fcd4403b87588ULL, 0x1b91f5f728bdd1e0ULL,
- 0xe4669f39040201f6ULL, 0x7a1d7c218cf04adeULL, 0x65623c29d79ce5ceULL,
- 0x2368449096c00bb1ULL, 0xab9bf1879da503baULL, 0xbc23ecb1a458058eULL,
- 0x9a58df01bb401eccULL, 0xa070e868a85f143dULL, 0x4ff188307df2239eULL,
- 0x14d565b41a641183ULL, 0xee13337452701602ULL, 0x950e3dcf3f285e09ULL,
- 0x59930254b9c80953ULL, 0x3bf299408930da6dULL, 0xa955943f53691387ULL,
- 0xa15edecaa9cb8784ULL, 0x29142127352be9a0ULL, 0x76f0371fff4e7afbULL,
- 0x0239f450274f2228ULL, 0xbb073af01d5e868bULL, 0xbfc80571c10e96c1ULL,
- 0xd267088568222e23ULL, 0x9671a3d48e80b5b0ULL, 0x55b5d38ae193bb81ULL,
- 0x693ae2d0a18b04b8ULL, 0x5c48b4ecadd5335fULL, 0xfd743b194916a1caULL,
- 0x2577018134be98c4ULL, 0xe77987e83c54a4adULL, 0x28e11014da33e1b9ULL,
- 0x270cc59e226aa213ULL, 0x71495f756d1a5f60ULL, 0x9be853fb60afef77ULL,
- 0xadc786a7f7443dbfULL, 0x0904456173b29a82ULL, 0x58bc7a66c232bd5eULL,
- 0xf306558c673ac8b2ULL, 0x41f639c6b6c9772aULL, 0x216defe99fda35daULL,
- 0x11640cc71c7be615ULL, 0x93c43694565c5527ULL, 0xea038e6246777839ULL,
- 0xf9abf3ce5a3e2469ULL, 0x741e768d0fd312d2ULL, 0x0144b883ced652c6ULL,
- 0xc20b5a5ba33f8552ULL, 0x1ae69633c3435a9dULL, 0x97a28ca4088cfdecULL,
- 0x8824a43c1e96f420ULL, 0x37612fa66eeea746ULL, 0x6b4cb165f9cf0e5aULL,
- 0x43aa1c06a0abfb4aULL, 0x7f4dc26ff162796bULL, 0x6cbacc8e54ed9b0fULL,
- 0xa6b7ffefd2bb253eULL, 0x2e25bc95b0a29d4fULL, 0x86d6a58bdef1388cULL,
- 0xded74ac576b6f054ULL, 0x8030bdbc2b45805dULL, 0x3c81af70e94d9289ULL,
- 0x3eff6dda9e3100dbULL, 0xb38dc39fdfcc8847ULL, 0x123885528d17b87eULL,
- 0xf2da0ed240b1b642ULL, 0x44cefadcd54bf9a9ULL, 0x1312200e433c7ee6ULL,
- 0x9ffcc84f3a78c748ULL, 0xf0cd1f72248576bbULL, 0xec6974053638cfe4ULL,
- 0x2ba7b67c0cec4e4cULL, 0xac2f4df3e5ce32edULL, 0xcb33d14326ea4c11ULL,
- 0xa4e9044cc77e58bcULL, 0x5f513293d934fcefULL, 0x5dc9645506e55444ULL,
- 0x50de418f317de40aULL, 0x388cb31a69dde259ULL, 0x2db4a83455820a86ULL,
- 0x9010a91e84711ae9ULL, 0x4df7f0b7b1498371ULL, 0xd62a2eabc0977179ULL,
- 0x22fac097aa8d5c0eULL
-};
-
-static const u64 sbox3[256] = {
- 0xf49fcc2ff1daf39bULL, 0x487fd5c66ff29281ULL, 0xe8a30667fcdca83fULL,
- 0x2c9b4be3d2fcce63ULL, 0xda3ff74b93fbbbc2ULL, 0x2fa165d2fe70ba66ULL,
- 0xa103e279970e93d4ULL, 0xbecdec77b0e45e71ULL, 0xcfb41e723985e497ULL,
- 0xb70aaa025ef75017ULL, 0xd42309f03840b8e0ULL, 0x8efc1ad035898579ULL,
- 0x96c6920be2b2abc5ULL, 0x66af4163375a9172ULL, 0x2174abdcca7127fbULL,
- 0xb33ccea64a72ff41ULL, 0xf04a4933083066a5ULL, 0x8d970acdd7289af5ULL,
- 0x8f96e8e031c8c25eULL, 0xf3fec02276875d47ULL, 0xec7bf310056190ddULL,
- 0xf5adb0aebb0f1491ULL, 0x9b50f8850fd58892ULL, 0x4975488358b74de8ULL,
- 0xa3354ff691531c61ULL, 0x0702bbe481d2c6eeULL, 0x89fb24057deded98ULL,
- 0xac3075138596e902ULL, 0x1d2d3580172772edULL, 0xeb738fc28e6bc30dULL,
- 0x5854ef8f63044326ULL, 0x9e5c52325add3bbeULL, 0x90aa53cf325c4623ULL,
- 0xc1d24d51349dd067ULL, 0x2051cfeea69ea624ULL, 0x13220f0a862e7e4fULL,
- 0xce39399404e04864ULL, 0xd9c42ca47086fcb7ULL, 0x685ad2238a03e7ccULL,
- 0x066484b2ab2ff1dbULL, 0xfe9d5d70efbf79ecULL, 0x5b13b9dd9c481854ULL,
- 0x15f0d475ed1509adULL, 0x0bebcd060ec79851ULL, 0xd58c6791183ab7f8ULL,
- 0xd1187c5052f3eee4ULL, 0xc95d1192e54e82ffULL, 0x86eea14cb9ac6ca2ULL,
- 0x3485beb153677d5dULL, 0xdd191d781f8c492aULL, 0xf60866baa784ebf9ULL,
- 0x518f643ba2d08c74ULL, 0x8852e956e1087c22ULL, 0xa768cb8dc410ae8dULL,
- 0x38047726bfec8e1aULL, 0xa67738b4cd3b45aaULL, 0xad16691cec0dde19ULL,
- 0xc6d4319380462e07ULL, 0xc5a5876d0ba61938ULL, 0x16b9fa1fa58fd840ULL,
- 0x188ab1173ca74f18ULL, 0xabda2f98c99c021fULL, 0x3e0580ab134ae816ULL,
- 0x5f3b05b773645abbULL, 0x2501a2be5575f2f6ULL, 0x1b2f74004e7e8ba9ULL,
- 0x1cd7580371e8d953ULL, 0x7f6ed89562764e30ULL, 0xb15926ff596f003dULL,
- 0x9f65293da8c5d6b9ULL, 0x6ecef04dd690f84cULL, 0x4782275fff33af88ULL,
- 0xe41433083f820801ULL, 0xfd0dfe409a1af9b5ULL, 0x4325a3342cdb396bULL,
- 0x8ae77e62b301b252ULL, 0xc36f9e9f6655615aULL, 0x85455a2d92d32c09ULL,
- 0xf2c7dea949477485ULL, 0x63cfb4c133a39ebaULL, 0x83b040cc6ebc5462ULL,
- 0x3b9454c8fdb326b0ULL, 0x56f56a9e87ffd78cULL, 0x2dc2940d99f42bc6ULL,
- 0x98f7df096b096e2dULL, 0x19a6e01e3ad852bfULL, 0x42a99ccbdbd4b40bULL,
- 0xa59998af45e9c559ULL, 0x366295e807d93186ULL, 0x6b48181bfaa1f773ULL,
- 0x1fec57e2157a0a1dULL, 0x4667446af6201ad5ULL, 0xe615ebcacfb0f075ULL,
- 0xb8f31f4f68290778ULL, 0x22713ed6ce22d11eULL, 0x3057c1a72ec3c93bULL,
- 0xcb46acc37c3f1f2fULL, 0xdbb893fd02aaf50eULL, 0x331fd92e600b9fcfULL,
- 0xa498f96148ea3ad6ULL, 0xa8d8426e8b6a83eaULL, 0xa089b274b7735cdcULL,
- 0x87f6b3731e524a11ULL, 0x118808e5cbc96749ULL, 0x9906e4c7b19bd394ULL,
- 0xafed7f7e9b24a20cULL, 0x6509eadeeb3644a7ULL, 0x6c1ef1d3e8ef0edeULL,
- 0xb9c97d43e9798fb4ULL, 0xa2f2d784740c28a3ULL, 0x7b8496476197566fULL,
- 0x7a5be3e6b65f069dULL, 0xf96330ed78be6f10ULL, 0xeee60de77a076a15ULL,
- 0x2b4bee4aa08b9bd0ULL, 0x6a56a63ec7b8894eULL, 0x02121359ba34fef4ULL,
- 0x4cbf99f8283703fcULL, 0x398071350caf30c8ULL, 0xd0a77a89f017687aULL,
- 0xf1c1a9eb9e423569ULL, 0x8c7976282dee8199ULL, 0x5d1737a5dd1f7abdULL,
- 0x4f53433c09a9fa80ULL, 0xfa8b0c53df7ca1d9ULL, 0x3fd9dcbc886ccb77ULL,
- 0xc040917ca91b4720ULL, 0x7dd00142f9d1dcdfULL, 0x8476fc1d4f387b58ULL,
- 0x23f8e7c5f3316503ULL, 0x032a2244e7e37339ULL, 0x5c87a5d750f5a74bULL,
- 0x082b4cc43698992eULL, 0xdf917becb858f63cULL, 0x3270b8fc5bf86ddaULL,
- 0x10ae72bb29b5dd76ULL, 0x576ac94e7700362bULL, 0x1ad112dac61efb8fULL,
- 0x691bc30ec5faa427ULL, 0xff246311cc327143ULL, 0x3142368e30e53206ULL,
- 0x71380e31e02ca396ULL, 0x958d5c960aad76f1ULL, 0xf8d6f430c16da536ULL,
- 0xc8ffd13f1be7e1d2ULL, 0x7578ae66004ddbe1ULL, 0x05833f01067be646ULL,
- 0xbb34b5ad3bfe586dULL, 0x095f34c9a12b97f0ULL, 0x247ab64525d60ca8ULL,
- 0xdcdbc6f3017477d1ULL, 0x4a2e14d4decad24dULL, 0xbdb5e6d9be0a1eebULL,
- 0x2a7e70f7794301abULL, 0xdef42d8a270540fdULL, 0x01078ec0a34c22c1ULL,
- 0xe5de511af4c16387ULL, 0x7ebb3a52bd9a330aULL, 0x77697857aa7d6435ULL,
- 0x004e831603ae4c32ULL, 0xe7a21020ad78e312ULL, 0x9d41a70c6ab420f2ULL,
- 0x28e06c18ea1141e6ULL, 0xd2b28cbd984f6b28ULL, 0x26b75f6c446e9d83ULL,
- 0xba47568c4d418d7fULL, 0xd80badbfe6183d8eULL, 0x0e206d7f5f166044ULL,
- 0xe258a43911cbca3eULL, 0x723a1746b21dc0bcULL, 0xc7caa854f5d7cdd3ULL,
- 0x7cac32883d261d9cULL, 0x7690c26423ba942cULL, 0x17e55524478042b8ULL,
- 0xe0be477656a2389fULL, 0x4d289b5e67ab2da0ULL, 0x44862b9c8fbbfd31ULL,
- 0xb47cc8049d141365ULL, 0x822c1b362b91c793ULL, 0x4eb14655fb13dfd8ULL,
- 0x1ecbba0714e2a97bULL, 0x6143459d5cde5f14ULL, 0x53a8fbf1d5f0ac89ULL,
- 0x97ea04d81c5e5b00ULL, 0x622181a8d4fdb3f3ULL, 0xe9bcd341572a1208ULL,
- 0x1411258643cce58aULL, 0x9144c5fea4c6e0a4ULL, 0x0d33d06565cf620fULL,
- 0x54a48d489f219ca1ULL, 0xc43e5eac6d63c821ULL, 0xa9728b3a72770dafULL,
- 0xd7934e7b20df87efULL, 0xe35503b61a3e86e5ULL, 0xcae321fbc819d504ULL,
- 0x129a50b3ac60bfa6ULL, 0xcd5e68ea7e9fb6c3ULL, 0xb01c90199483b1c7ULL,
- 0x3de93cd5c295376cULL, 0xaed52edf2ab9ad13ULL, 0x2e60f512c0a07884ULL,
- 0xbc3d86a3e36210c9ULL, 0x35269d9b163951ceULL, 0x0c7d6e2ad0cdb5faULL,
- 0x59e86297d87f5733ULL, 0x298ef221898db0e7ULL, 0x55000029d1a5aa7eULL,
- 0x8bc08ae1b5061b45ULL, 0xc2c31c2b6c92703aULL, 0x94cc596baf25ef42ULL,
- 0x0a1d73db22540456ULL, 0x04b6a0f9d9c4179aULL, 0xeffdafa2ae3d3c60ULL,
- 0xf7c8075bb49496c4ULL, 0x9cc5c7141d1cd4e3ULL, 0x78bd1638218e5534ULL,
- 0xb2f11568f850246aULL, 0xedfabcfa9502bc29ULL, 0x796ce5f2da23051bULL,
- 0xaae128b0dc93537cULL, 0x3a493da0ee4b29aeULL, 0xb5df6b2c416895d7ULL,
- 0xfcabbd25122d7f37ULL, 0x70810b58105dc4b1ULL, 0xe10fdd37f7882a90ULL,
- 0x524dcab5518a3f5cULL, 0x3c9e85878451255bULL, 0x4029828119bd34e2ULL,
- 0x74a05b6f5d3ceccbULL, 0xb610021542e13ecaULL, 0x0ff979d12f59e2acULL,
- 0x6037da27e4f9cc50ULL, 0x5e92975a0df1847dULL, 0xd66de190d3e623feULL,
- 0x5032d6b87b568048ULL, 0x9a36b7ce8235216eULL, 0x80272a7a24f64b4aULL,
- 0x93efed8b8c6916f7ULL, 0x37ddbff44cce1555ULL, 0x4b95db5d4b99bd25ULL,
- 0x92d3fda169812fc0ULL, 0xfb1a4a9a90660bb6ULL, 0x730c196946a4b9b2ULL,
- 0x81e289aa7f49da68ULL, 0x64669a0f83b1a05fULL, 0x27b3ff7d9644f48bULL,
- 0xcc6b615c8db675b3ULL, 0x674f20b9bcebbe95ULL, 0x6f31238275655982ULL,
- 0x5ae488713e45cf05ULL, 0xbf619f9954c21157ULL, 0xeabac46040a8eae9ULL,
- 0x454c6fe9f2c0c1cdULL, 0x419cf6496412691cULL, 0xd3dc3bef265b0f70ULL,
- 0x6d0e60f5c3578a9eULL
-};
-
-static const u64 sbox4[256] = {
- 0x5b0e608526323c55ULL, 0x1a46c1a9fa1b59f5ULL, 0xa9e245a17c4c8ffaULL,
- 0x65ca5159db2955d7ULL, 0x05db0a76ce35afc2ULL, 0x81eac77ea9113d45ULL,
- 0x528ef88ab6ac0a0dULL, 0xa09ea253597be3ffULL, 0x430ddfb3ac48cd56ULL,
- 0xc4b3a67af45ce46fULL, 0x4ececfd8fbe2d05eULL, 0x3ef56f10b39935f0ULL,
- 0x0b22d6829cd619c6ULL, 0x17fd460a74df2069ULL, 0x6cf8cc8e8510ed40ULL,
- 0xd6c824bf3a6ecaa7ULL, 0x61243d581a817049ULL, 0x048bacb6bbc163a2ULL,
- 0xd9a38ac27d44cc32ULL, 0x7fddff5baaf410abULL, 0xad6d495aa804824bULL,
- 0xe1a6a74f2d8c9f94ULL, 0xd4f7851235dee8e3ULL, 0xfd4b7f886540d893ULL,
- 0x247c20042aa4bfdaULL, 0x096ea1c517d1327cULL, 0xd56966b4361a6685ULL,
- 0x277da5c31221057dULL, 0x94d59893a43acff7ULL, 0x64f0c51ccdc02281ULL,
- 0x3d33bcc4ff6189dbULL, 0xe005cb184ce66af1ULL, 0xff5ccd1d1db99beaULL,
- 0xb0b854a7fe42980fULL, 0x7bd46a6a718d4b9fULL, 0xd10fa8cc22a5fd8cULL,
- 0xd31484952be4bd31ULL, 0xc7fa975fcb243847ULL, 0x4886ed1e5846c407ULL,
- 0x28cddb791eb70b04ULL, 0xc2b00be2f573417fULL, 0x5c9590452180f877ULL,
- 0x7a6bddfff370eb00ULL, 0xce509e38d6d9d6a4ULL, 0xebeb0f00647fa702ULL,
- 0x1dcc06cf76606f06ULL, 0xe4d9f28ba286ff0aULL, 0xd85a305dc918c262ULL,
- 0x475b1d8732225f54ULL, 0x2d4fb51668ccb5feULL, 0xa679b9d9d72bba20ULL,
- 0x53841c0d912d43a5ULL, 0x3b7eaa48bf12a4e8ULL, 0x781e0e47f22f1ddfULL,
- 0xeff20ce60ab50973ULL, 0x20d261d19dffb742ULL, 0x16a12b03062a2e39ULL,
- 0x1960eb2239650495ULL, 0x251c16fed50eb8b8ULL, 0x9ac0c330f826016eULL,
- 0xed152665953e7671ULL, 0x02d63194a6369570ULL, 0x5074f08394b1c987ULL,
- 0x70ba598c90b25ce1ULL, 0x794a15810b9742f6ULL, 0x0d5925e9fcaf8c6cULL,
- 0x3067716cd868744eULL, 0x910ab077e8d7731bULL, 0x6a61bbdb5ac42f61ULL,
- 0x93513efbf0851567ULL, 0xf494724b9e83e9d5ULL, 0xe887e1985c09648dULL,
- 0x34b1d3c675370cfdULL, 0xdc35e433bc0d255dULL, 0xd0aab84234131be0ULL,
- 0x08042a50b48b7eafULL, 0x9997c4ee44a3ab35ULL, 0x829a7b49201799d0ULL,
- 0x263b8307b7c54441ULL, 0x752f95f4fd6a6ca6ULL, 0x927217402c08c6e5ULL,
- 0x2a8ab754a795d9eeULL, 0xa442f7552f72943dULL, 0x2c31334e19781208ULL,
- 0x4fa98d7ceaee6291ULL, 0x55c3862f665db309ULL, 0xbd0610175d53b1f3ULL,
- 0x46fe6cb840413f27ULL, 0x3fe03792df0cfa59ULL, 0xcfe700372eb85e8fULL,
- 0xa7be29e7adbce118ULL, 0xe544ee5cde8431ddULL, 0x8a781b1b41f1873eULL,
- 0xa5c94c78a0d2f0e7ULL, 0x39412e2877b60728ULL, 0xa1265ef3afc9a62cULL,
- 0xbcc2770c6a2506c5ULL, 0x3ab66dd5dce1ce12ULL, 0xe65499d04a675b37ULL,
- 0x7d8f523481bfd216ULL, 0x0f6f64fcec15f389ULL, 0x74efbe618b5b13c8ULL,
- 0xacdc82b714273e1dULL, 0xdd40bfe003199d17ULL, 0x37e99257e7e061f8ULL,
- 0xfa52626904775aaaULL, 0x8bbbf63a463d56f9ULL, 0xf0013f1543a26e64ULL,
- 0xa8307e9f879ec898ULL, 0xcc4c27a4150177ccULL, 0x1b432f2cca1d3348ULL,
- 0xde1d1f8f9f6fa013ULL, 0x606602a047a7ddd6ULL, 0xd237ab64cc1cb2c7ULL,
- 0x9b938e7225fcd1d3ULL, 0xec4e03708e0ff476ULL, 0xfeb2fbda3d03c12dULL,
- 0xae0bced2ee43889aULL, 0x22cb8923ebfb4f43ULL, 0x69360d013cf7396dULL,
- 0x855e3602d2d4e022ULL, 0x073805bad01f784cULL, 0x33e17a133852f546ULL,
- 0xdf4874058ac7b638ULL, 0xba92b29c678aa14aULL, 0x0ce89fc76cfaadcdULL,
- 0x5f9d4e0908339e34ULL, 0xf1afe9291f5923b9ULL, 0x6e3480f60f4a265fULL,
- 0xeebf3a2ab29b841cULL, 0xe21938a88f91b4adULL, 0x57dfeff845c6d3c3ULL,
- 0x2f006b0bf62caaf2ULL, 0x62f479ef6f75ee78ULL, 0x11a55ad41c8916a9ULL,
- 0xf229d29084fed453ULL, 0x42f1c27b16b000e6ULL, 0x2b1f76749823c074ULL,
- 0x4b76eca3c2745360ULL, 0x8c98f463b91691bdULL, 0x14bcc93cf1ade66aULL,
- 0x8885213e6d458397ULL, 0x8e177df0274d4711ULL, 0xb49b73b5503f2951ULL,
- 0x10168168c3f96b6bULL, 0x0e3d963b63cab0aeULL, 0x8dfc4b5655a1db14ULL,
- 0xf789f1356e14de5cULL, 0x683e68af4e51dac1ULL, 0xc9a84f9d8d4b0fd9ULL,
- 0x3691e03f52a0f9d1ULL, 0x5ed86e46e1878e80ULL, 0x3c711a0e99d07150ULL,
- 0x5a0865b20c4e9310ULL, 0x56fbfc1fe4f0682eULL, 0xea8d5de3105edf9bULL,
- 0x71abfdb12379187aULL, 0x2eb99de1bee77b9cULL, 0x21ecc0ea33cf4523ULL,
- 0x59a4d7521805c7a1ULL, 0x3896f5eb56ae7c72ULL, 0xaa638f3db18f75dcULL,
- 0x9f39358dabe9808eULL, 0xb7defa91c00b72acULL, 0x6b5541fd62492d92ULL,
- 0x6dc6dee8f92e4d5bULL, 0x353f57abc4beea7eULL, 0x735769d6da5690ceULL,
- 0x0a234aa642391484ULL, 0xf6f9508028f80d9dULL, 0xb8e319a27ab3f215ULL,
- 0x31ad9c1151341a4dULL, 0x773c22a57bef5805ULL, 0x45c7561a07968633ULL,
- 0xf913da9e249dbe36ULL, 0xda652d9b78a64c68ULL, 0x4c27a97f3bc334efULL,
- 0x76621220e66b17f4ULL, 0x967743899acd7d0bULL, 0xf3ee5bcae0ed6782ULL,
- 0x409f753600c879fcULL, 0x06d09a39b5926db6ULL, 0x6f83aeb0317ac588ULL,
- 0x01e6ca4a86381f21ULL, 0x66ff3462d19f3025ULL, 0x72207c24ddfd3bfbULL,
- 0x4af6b6d3e2ece2ebULL, 0x9c994dbec7ea08deULL, 0x49ace597b09a8bc4ULL,
- 0xb38c4766cf0797baULL, 0x131b9373c57c2a75ULL, 0xb1822cce61931e58ULL,
- 0x9d7555b909ba1c0cULL, 0x127fafdd937d11d2ULL, 0x29da3badc66d92e4ULL,
- 0xa2c1d57154c2ecbcULL, 0x58c5134d82f6fe24ULL, 0x1c3ae3515b62274fULL,
- 0xe907c82e01cb8126ULL, 0xf8ed091913e37fcbULL, 0x3249d8f9c80046c9ULL,
- 0x80cf9bede388fb63ULL, 0x1881539a116cf19eULL, 0x5103f3f76bd52457ULL,
- 0x15b7e6f5ae47f7a8ULL, 0xdbd7c6ded47e9ccfULL, 0x44e55c410228bb1aULL,
- 0xb647d4255edb4e99ULL, 0x5d11882bb8aafc30ULL, 0xf5098bbb29d3212aULL,
- 0x8fb5ea14e90296b3ULL, 0x677b942157dd025aULL, 0xfb58e7c0a390acb5ULL,
- 0x89d3674c83bd4a01ULL, 0x9e2da4df4bf3b93bULL, 0xfcc41e328cab4829ULL,
- 0x03f38c96ba582c52ULL, 0xcad1bdbd7fd85db2ULL, 0xbbb442c16082ae83ULL,
- 0xb95fe86ba5da9ab0ULL, 0xb22e04673771a93fULL, 0x845358c9493152d8ULL,
- 0xbe2a488697b4541eULL, 0x95a2dc2dd38e6966ULL, 0xc02c11ac923c852bULL,
- 0x2388b1990df2a87bULL, 0x7c8008fa1b4f37beULL, 0x1f70d0c84d54e503ULL,
- 0x5490adec7ece57d4ULL, 0x002b3c27d9063a3aULL, 0x7eaea3848030a2bfULL,
- 0xc602326ded2003c0ULL, 0x83a7287d69a94086ULL, 0xc57a5fcb30f57a8aULL,
- 0xb56844e479ebe779ULL, 0xa373b40f05dcbce9ULL, 0xd71a786e88570ee2ULL,
- 0x879cbacdbde8f6a0ULL, 0x976ad1bcc164a32fULL, 0xab21e25e9666d78bULL,
- 0x901063aae5e5c33cULL, 0x9818b34448698d90ULL, 0xe36487ae3e1e8abbULL,
- 0xafbdf931893bdcb4ULL, 0x6345a0dc5fbbd519ULL, 0x8628fe269b9465caULL,
- 0x1e5d01603f9c51ecULL, 0x4de44006a15049b7ULL, 0xbf6c70e5f776cbb1ULL,
- 0x411218f2ef552bedULL, 0xcb0c0708705a36a3ULL, 0xe74d14754f986044ULL,
- 0xcd56d9430ea8280eULL, 0xc12591d7535f5065ULL, 0xc83223f1720aef96ULL,
- 0xc3a0396f7363a51fULL
-};
-
-
-static void tgr192_round(u64 * ra, u64 * rb, u64 * rc, u64 x, int mul)
-{
- u64 a = *ra;
- u64 b = *rb;
- u64 c = *rc;
-
- c ^= x;
- a -= sbox1[c & 0xff] ^ sbox2[(c >> 16) & 0xff]
- ^ sbox3[(c >> 32) & 0xff] ^ sbox4[(c >> 48) & 0xff];
- b += sbox4[(c >> 8) & 0xff] ^ sbox3[(c >> 24) & 0xff]
- ^ sbox2[(c >> 40) & 0xff] ^ sbox1[(c >> 56) & 0xff];
- b *= mul;
-
- *ra = a;
- *rb = b;
- *rc = c;
-}
-
-
-static void tgr192_pass(u64 * ra, u64 * rb, u64 * rc, u64 * x, int mul)
-{
- u64 a = *ra;
- u64 b = *rb;
- u64 c = *rc;
-
- tgr192_round(&a, &b, &c, x[0], mul);
- tgr192_round(&b, &c, &a, x[1], mul);
- tgr192_round(&c, &a, &b, x[2], mul);
- tgr192_round(&a, &b, &c, x[3], mul);
- tgr192_round(&b, &c, &a, x[4], mul);
- tgr192_round(&c, &a, &b, x[5], mul);
- tgr192_round(&a, &b, &c, x[6], mul);
- tgr192_round(&b, &c, &a, x[7], mul);
-
- *ra = a;
- *rb = b;
- *rc = c;
-}
-
-
-static void tgr192_key_schedule(u64 * x)
-{
- x[0] -= x[7] ^ 0xa5a5a5a5a5a5a5a5ULL;
- x[1] ^= x[0];
- x[2] += x[1];
- x[3] -= x[2] ^ ((~x[1]) << 19);
- x[4] ^= x[3];
- x[5] += x[4];
- x[6] -= x[5] ^ ((~x[4]) >> 23);
- x[7] ^= x[6];
- x[0] += x[7];
- x[1] -= x[0] ^ ((~x[7]) << 19);
- x[2] ^= x[1];
- x[3] += x[2];
- x[4] -= x[3] ^ ((~x[2]) >> 23);
- x[5] ^= x[4];
- x[6] += x[5];
- x[7] -= x[6] ^ 0x0123456789abcdefULL;
-}
-
-
-/****************
- * Transform the message DATA which consists of 512 bytes (8 words)
- */
-
-static void tgr192_transform(struct tgr192_ctx *tctx, const u8 * data)
-{
- u64 a, b, c, aa, bb, cc;
- u64 x[8];
- int i;
-
- for (i = 0; i < 8; i++)
- x[i] = get_unaligned_le64(data + i * sizeof(__le64));
-
- /* save */
- a = aa = tctx->a;
- b = bb = tctx->b;
- c = cc = tctx->c;
-
- tgr192_pass(&a, &b, &c, x, 5);
- tgr192_key_schedule(x);
- tgr192_pass(&c, &a, &b, x, 7);
- tgr192_key_schedule(x);
- tgr192_pass(&b, &c, &a, x, 9);
-
-
- /* feedforward */
- a ^= aa;
- b -= bb;
- c += cc;
- /* store */
- tctx->a = a;
- tctx->b = b;
- tctx->c = c;
-}
-
-static int tgr192_init(struct shash_desc *desc)
-{
- struct tgr192_ctx *tctx = shash_desc_ctx(desc);
-
- tctx->a = 0x0123456789abcdefULL;
- tctx->b = 0xfedcba9876543210ULL;
- tctx->c = 0xf096a5b4c3b2e187ULL;
- tctx->nblocks = 0;
- tctx->count = 0;
-
- return 0;
-}
-
-
-/* Update the message digest with the contents
- * of INBUF with length INLEN. */
-static int tgr192_update(struct shash_desc *desc, const u8 *inbuf,
- unsigned int len)
-{
- struct tgr192_ctx *tctx = shash_desc_ctx(desc);
-
- if (tctx->count == 64) { /* flush the buffer */
- tgr192_transform(tctx, tctx->hash);
- tctx->count = 0;
- tctx->nblocks++;
- }
- if (!inbuf) {
- return 0;
- }
- if (tctx->count) {
- for (; len && tctx->count < 64; len--) {
- tctx->hash[tctx->count++] = *inbuf++;
- }
- tgr192_update(desc, NULL, 0);
- if (!len) {
- return 0;
- }
-
- }
-
- while (len >= 64) {
- tgr192_transform(tctx, inbuf);
- tctx->count = 0;
- tctx->nblocks++;
- len -= 64;
- inbuf += 64;
- }
- for (; len && tctx->count < 64; len--) {
- tctx->hash[tctx->count++] = *inbuf++;
- }
-
- return 0;
-}
-
-
-
-/* The routine terminates the computation */
-static int tgr192_final(struct shash_desc *desc, u8 * out)
-{
- struct tgr192_ctx *tctx = shash_desc_ctx(desc);
- __be64 *dst = (__be64 *)out;
- __be64 *be64p;
- __le32 *le32p;
- u32 t, msb, lsb;
-
- tgr192_update(desc, NULL, 0); /* flush */
-
- msb = 0;
- t = tctx->nblocks;
- if ((lsb = t << 6) < t) { /* multiply by 64 to make a byte count */
- msb++;
- }
- msb += t >> 26;
- t = lsb;
- if ((lsb = t + tctx->count) < t) { /* add the count */
- msb++;
- }
- t = lsb;
- if ((lsb = t << 3) < t) { /* multiply by 8 to make a bit count */
- msb++;
- }
- msb += t >> 29;
-
- if (tctx->count < 56) { /* enough room */
- tctx->hash[tctx->count++] = 0x01; /* pad */
- while (tctx->count < 56) {
- tctx->hash[tctx->count++] = 0; /* pad */
- }
- } else { /* need one extra block */
- tctx->hash[tctx->count++] = 0x01; /* pad character */
- while (tctx->count < 64) {
- tctx->hash[tctx->count++] = 0;
- }
- tgr192_update(desc, NULL, 0); /* flush */
- memset(tctx->hash, 0, 56); /* fill next block with zeroes */
- }
- /* append the 64 bit count */
- le32p = (__le32 *)&tctx->hash[56];
- le32p[0] = cpu_to_le32(lsb);
- le32p[1] = cpu_to_le32(msb);
-
- tgr192_transform(tctx, tctx->hash);
-
- be64p = (__be64 *)tctx->hash;
- dst[0] = be64p[0] = cpu_to_be64(tctx->a);
- dst[1] = be64p[1] = cpu_to_be64(tctx->b);
- dst[2] = be64p[2] = cpu_to_be64(tctx->c);
-
- return 0;
-}
-
-static int tgr160_final(struct shash_desc *desc, u8 * out)
-{
- u8 D[64];
-
- tgr192_final(desc, D);
- memcpy(out, D, TGR160_DIGEST_SIZE);
- memzero_explicit(D, TGR192_DIGEST_SIZE);
-
- return 0;
-}
-
-static int tgr128_final(struct shash_desc *desc, u8 * out)
-{
- u8 D[64];
-
- tgr192_final(desc, D);
- memcpy(out, D, TGR128_DIGEST_SIZE);
- memzero_explicit(D, TGR192_DIGEST_SIZE);
-
- return 0;
-}
-
-static struct shash_alg tgr_algs[3] = { {
- .digestsize = TGR192_DIGEST_SIZE,
- .init = tgr192_init,
- .update = tgr192_update,
- .final = tgr192_final,
- .descsize = sizeof(struct tgr192_ctx),
- .base = {
- .cra_name = "tgr192",
- .cra_driver_name = "tgr192-generic",
- .cra_blocksize = TGR192_BLOCK_SIZE,
- .cra_module = THIS_MODULE,
- }
-}, {
- .digestsize = TGR160_DIGEST_SIZE,
- .init = tgr192_init,
- .update = tgr192_update,
- .final = tgr160_final,
- .descsize = sizeof(struct tgr192_ctx),
- .base = {
- .cra_name = "tgr160",
- .cra_driver_name = "tgr160-generic",
- .cra_blocksize = TGR192_BLOCK_SIZE,
- .cra_module = THIS_MODULE,
- }
-}, {
- .digestsize = TGR128_DIGEST_SIZE,
- .init = tgr192_init,
- .update = tgr192_update,
- .final = tgr128_final,
- .descsize = sizeof(struct tgr192_ctx),
- .base = {
- .cra_name = "tgr128",
- .cra_driver_name = "tgr128-generic",
- .cra_blocksize = TGR192_BLOCK_SIZE,
- .cra_module = THIS_MODULE,
- }
-} };
-
-static int __init tgr192_mod_init(void)
-{
- return crypto_register_shashes(tgr_algs, ARRAY_SIZE(tgr_algs));
-}
-
-static void __exit tgr192_mod_fini(void)
-{
- crypto_unregister_shashes(tgr_algs, ARRAY_SIZE(tgr_algs));
-}
-
-MODULE_ALIAS_CRYPTO("tgr192");
-MODULE_ALIAS_CRYPTO("tgr160");
-MODULE_ALIAS_CRYPTO("tgr128");
-
-subsys_initcall(tgr192_mod_init);
-module_exit(tgr192_mod_fini);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Tiger Message Digest Algorithm");
diff --git a/crypto/twofish_common.c b/crypto/twofish_common.c
index d23fa531b91f..f921f30334f4 100644
--- a/crypto/twofish_common.c
+++ b/crypto/twofish_common.c
@@ -298,7 +298,7 @@ static const u32 mds[4][256] = {
* multiplication is inefficient without hardware support. To multiply
* faster, I make use of the fact x is a generator for the nonzero elements,
* so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
- * some n in 0..254. Note that that caret is exponentiation in GF(2^8),
+ * some n in 0..254. Note that caret is exponentiation in GF(2^8),
* *not* polynomial notation. So if I want to compute pq where p and q are
* in GF(2^8), I can just say:
* 1. if p=0 or q=0 then pq=0
diff --git a/crypto/twofish_generic.c b/crypto/twofish_generic.c
index 4f7c033224f9..86b2f067a416 100644
--- a/crypto/twofish_generic.c
+++ b/crypto/twofish_generic.c
@@ -24,7 +24,7 @@
* Third Edition.
*/
-#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <crypto/twofish.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -83,11 +83,11 @@
* whitening subkey number m. */
#define INPACK(n, x, m) \
- x = le32_to_cpu(src[n]) ^ ctx->w[m]
+ x = get_unaligned_le32(in + (n) * 4) ^ ctx->w[m]
#define OUTUNPACK(n, x, m) \
x ^= ctx->w[m]; \
- dst[n] = cpu_to_le32(x)
+ put_unaligned_le32(x, out + (n) * 4)
@@ -95,8 +95,6 @@
static void twofish_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
struct twofish_ctx *ctx = crypto_tfm_ctx(tfm);
- const __le32 *src = (const __le32 *)in;
- __le32 *dst = (__le32 *)out;
/* The four 32-bit chunks of the text. */
u32 a, b, c, d;
@@ -132,8 +130,6 @@ static void twofish_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
static void twofish_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
{
struct twofish_ctx *ctx = crypto_tfm_ctx(tfm);
- const __le32 *src = (const __le32 *)in;
- __le32 *dst = (__le32 *)out;
/* The four 32-bit chunks of the text. */
u32 a, b, c, d;
@@ -172,7 +168,6 @@ static struct crypto_alg alg = {
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = TF_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct twofish_ctx),
- .cra_alignmask = 3,
.cra_module = THIS_MODULE,
.cra_u = { .cipher = {
.cia_min_keysize = TF_MIN_KEY_SIZE,
diff --git a/crypto/vmac.c b/crypto/vmac.c
index 2d906830df96..4633b2dda1e0 100644
--- a/crypto/vmac.c
+++ b/crypto/vmac.c
@@ -36,6 +36,7 @@
#include <linux/scatterlist.h>
#include <asm/byteorder.h>
#include <crypto/scatterwalk.h>
+#include <crypto/internal/cipher.h>
#include <crypto/internal/hash.h>
/*
@@ -620,9 +621,10 @@ static int vmac_create(struct crypto_template *tmpl, struct rtattr **tb)
struct shash_instance *inst;
struct crypto_cipher_spawn *spawn;
struct crypto_alg *alg;
+ u32 mask;
int err;
- err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask);
if (err)
return err;
@@ -632,7 +634,7 @@ static int vmac_create(struct crypto_template *tmpl, struct rtattr **tb)
spawn = shash_instance_ctx(inst);
err = crypto_grab_cipher(spawn, shash_crypto_instance(inst),
- crypto_attr_alg_name(tb[1]), 0, 0);
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
goto err_free_inst;
alg = crypto_spawn_cipher_alg(spawn);
@@ -692,3 +694,4 @@ module_exit(vmac_module_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("VMAC hash algorithm");
MODULE_ALIAS_CRYPTO("vmac64");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/wp512.c b/crypto/wp512.c
index feadc13ccae0..5e820afa3c78 100644
--- a/crypto/wp512.c
+++ b/crypto/wp512.c
@@ -775,7 +775,7 @@ static const u64 rc[WHIRLPOOL_ROUNDS] = {
0xca2dbf07ad5a8333ULL,
};
-/**
+/*
* The core Whirlpool transform.
*/
@@ -1066,33 +1066,31 @@ static int wp512_final(struct shash_desc *desc, u8 *out)
{
struct wp512_ctx *wctx = shash_desc_ctx(desc);
int i;
- u8 *buffer = wctx->buffer;
- u8 *bitLength = wctx->bitLength;
- int bufferBits = wctx->bufferBits;
- int bufferPos = wctx->bufferPos;
+ u8 *buffer = wctx->buffer;
+ u8 *bitLength = wctx->bitLength;
+ int bufferBits = wctx->bufferBits;
+ int bufferPos = wctx->bufferPos;
__be64 *digest = (__be64 *)out;
- buffer[bufferPos] |= 0x80U >> (bufferBits & 7);
- bufferPos++;
- if (bufferPos > WP512_BLOCK_SIZE - WP512_LENGTHBYTES) {
- if (bufferPos < WP512_BLOCK_SIZE) {
- memset(&buffer[bufferPos], 0, WP512_BLOCK_SIZE - bufferPos);
- }
- wp512_process_buffer(wctx);
- bufferPos = 0;
- }
- if (bufferPos < WP512_BLOCK_SIZE - WP512_LENGTHBYTES) {
- memset(&buffer[bufferPos], 0,
+ buffer[bufferPos] |= 0x80U >> (bufferBits & 7);
+ bufferPos++;
+ if (bufferPos > WP512_BLOCK_SIZE - WP512_LENGTHBYTES) {
+ if (bufferPos < WP512_BLOCK_SIZE)
+ memset(&buffer[bufferPos], 0, WP512_BLOCK_SIZE - bufferPos);
+ wp512_process_buffer(wctx);
+ bufferPos = 0;
+ }
+ if (bufferPos < WP512_BLOCK_SIZE - WP512_LENGTHBYTES)
+ memset(&buffer[bufferPos], 0,
(WP512_BLOCK_SIZE - WP512_LENGTHBYTES) - bufferPos);
- }
- bufferPos = WP512_BLOCK_SIZE - WP512_LENGTHBYTES;
- memcpy(&buffer[WP512_BLOCK_SIZE - WP512_LENGTHBYTES],
+ bufferPos = WP512_BLOCK_SIZE - WP512_LENGTHBYTES;
+ memcpy(&buffer[WP512_BLOCK_SIZE - WP512_LENGTHBYTES],
bitLength, WP512_LENGTHBYTES);
- wp512_process_buffer(wctx);
+ wp512_process_buffer(wctx);
for (i = 0; i < WP512_DIGEST_SIZE/8; i++)
digest[i] = cpu_to_be64(wctx->hash[i]);
- wctx->bufferBits = bufferBits;
- wctx->bufferPos = bufferPos;
+ wctx->bufferBits = bufferBits;
+ wctx->bufferPos = bufferPos;
return 0;
}
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 598ec88abf0f..6074c5c1da49 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -6,6 +6,7 @@
* Kazunori Miyazawa <miyazawa@linux-ipv6.org>
*/
+#include <crypto/internal/cipher.h>
#include <crypto/internal/hash.h>
#include <linux/err.h>
#include <linux/kernel.h>
@@ -191,9 +192,10 @@ static int xcbc_create(struct crypto_template *tmpl, struct rtattr **tb)
struct crypto_cipher_spawn *spawn;
struct crypto_alg *alg;
unsigned long alignmask;
+ u32 mask;
int err;
- err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH);
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH, &mask);
if (err)
return err;
@@ -203,7 +205,7 @@ static int xcbc_create(struct crypto_template *tmpl, struct rtattr **tb)
spawn = shash_instance_ctx(inst);
err = crypto_grab_cipher(spawn, shash_crypto_instance(inst),
- crypto_attr_alg_name(tb[1]), 0, 0);
+ crypto_attr_alg_name(tb[1]), 0, mask);
if (err)
goto err_free_inst;
alg = crypto_spawn_cipher_alg(spawn);
@@ -271,3 +273,4 @@ module_exit(crypto_xcbc_module_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("XCBC keyed hash algorithm");
MODULE_ALIAS_CRYPTO("xcbc");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/xctr.c b/crypto/xctr.c
new file mode 100644
index 000000000000..5c00147e8ec4
--- /dev/null
+++ b/crypto/xctr.c
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * XCTR: XOR Counter mode - Adapted from ctr.c
+ *
+ * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
+ * Copyright 2021 Google LLC
+ */
+
+/*
+ * XCTR mode is a blockcipher mode of operation used to implement HCTR2. XCTR is
+ * closely related to the CTR mode of operation; the main difference is that CTR
+ * generates the keystream using E(CTR + IV) whereas XCTR generates the
+ * keystream using E(CTR ^ IV). This allows implementations to avoid dealing
+ * with multi-limb integers (as is required in CTR mode). XCTR is also specified
+ * using little-endian arithmetic which makes it slightly faster on LE machines.
+ *
+ * See the HCTR2 paper for more details:
+ * Length-preserving encryption with HCTR2
+ * (https://eprint.iacr.org/2021/1441.pdf)
+ */
+
+#include <crypto/algapi.h>
+#include <crypto/internal/cipher.h>
+#include <crypto/internal/skcipher.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+/* For now this implementation is limited to 16-byte blocks for simplicity */
+#define XCTR_BLOCKSIZE 16
+
+static void crypto_xctr_crypt_final(struct skcipher_walk *walk,
+ struct crypto_cipher *tfm, u32 byte_ctr)
+{
+ u8 keystream[XCTR_BLOCKSIZE];
+ const u8 *src = walk->src.virt.addr;
+ u8 *dst = walk->dst.virt.addr;
+ unsigned int nbytes = walk->nbytes;
+ __le32 ctr32 = cpu_to_le32(byte_ctr / XCTR_BLOCKSIZE + 1);
+
+ crypto_xor(walk->iv, (u8 *)&ctr32, sizeof(ctr32));
+ crypto_cipher_encrypt_one(tfm, keystream, walk->iv);
+ crypto_xor_cpy(dst, keystream, src, nbytes);
+ crypto_xor(walk->iv, (u8 *)&ctr32, sizeof(ctr32));
+}
+
+static int crypto_xctr_crypt_segment(struct skcipher_walk *walk,
+ struct crypto_cipher *tfm, u32 byte_ctr)
+{
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
+ crypto_cipher_alg(tfm)->cia_encrypt;
+ const u8 *src = walk->src.virt.addr;
+ u8 *dst = walk->dst.virt.addr;
+ unsigned int nbytes = walk->nbytes;
+ __le32 ctr32 = cpu_to_le32(byte_ctr / XCTR_BLOCKSIZE + 1);
+
+ do {
+ crypto_xor(walk->iv, (u8 *)&ctr32, sizeof(ctr32));
+ fn(crypto_cipher_tfm(tfm), dst, walk->iv);
+ crypto_xor(dst, src, XCTR_BLOCKSIZE);
+ crypto_xor(walk->iv, (u8 *)&ctr32, sizeof(ctr32));
+
+ le32_add_cpu(&ctr32, 1);
+
+ src += XCTR_BLOCKSIZE;
+ dst += XCTR_BLOCKSIZE;
+ } while ((nbytes -= XCTR_BLOCKSIZE) >= XCTR_BLOCKSIZE);
+
+ return nbytes;
+}
+
+static int crypto_xctr_crypt_inplace(struct skcipher_walk *walk,
+ struct crypto_cipher *tfm, u32 byte_ctr)
+{
+ void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
+ crypto_cipher_alg(tfm)->cia_encrypt;
+ unsigned long alignmask = crypto_cipher_alignmask(tfm);
+ unsigned int nbytes = walk->nbytes;
+ u8 *data = walk->src.virt.addr;
+ u8 tmp[XCTR_BLOCKSIZE + MAX_CIPHER_ALIGNMASK];
+ u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1);
+ __le32 ctr32 = cpu_to_le32(byte_ctr / XCTR_BLOCKSIZE + 1);
+
+ do {
+ crypto_xor(walk->iv, (u8 *)&ctr32, sizeof(ctr32));
+ fn(crypto_cipher_tfm(tfm), keystream, walk->iv);
+ crypto_xor(data, keystream, XCTR_BLOCKSIZE);
+ crypto_xor(walk->iv, (u8 *)&ctr32, sizeof(ctr32));
+
+ le32_add_cpu(&ctr32, 1);
+
+ data += XCTR_BLOCKSIZE;
+ } while ((nbytes -= XCTR_BLOCKSIZE) >= XCTR_BLOCKSIZE);
+
+ return nbytes;
+}
+
+static int crypto_xctr_crypt(struct skcipher_request *req)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+ struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);
+ struct skcipher_walk walk;
+ unsigned int nbytes;
+ int err;
+ u32 byte_ctr = 0;
+
+ err = skcipher_walk_virt(&walk, req, false);
+
+ while (walk.nbytes >= XCTR_BLOCKSIZE) {
+ if (walk.src.virt.addr == walk.dst.virt.addr)
+ nbytes = crypto_xctr_crypt_inplace(&walk, cipher,
+ byte_ctr);
+ else
+ nbytes = crypto_xctr_crypt_segment(&walk, cipher,
+ byte_ctr);
+
+ byte_ctr += walk.nbytes - nbytes;
+ err = skcipher_walk_done(&walk, nbytes);
+ }
+
+ if (walk.nbytes) {
+ crypto_xctr_crypt_final(&walk, cipher, byte_ctr);
+ err = skcipher_walk_done(&walk, 0);
+ }
+
+ return err;
+}
+
+static int crypto_xctr_create(struct crypto_template *tmpl, struct rtattr **tb)
+{
+ struct skcipher_instance *inst;
+ struct crypto_alg *alg;
+ int err;
+
+ inst = skcipher_alloc_instance_simple(tmpl, tb);
+ if (IS_ERR(inst))
+ return PTR_ERR(inst);
+
+ alg = skcipher_ialg_simple(inst);
+
+ /* Block size must be 16 bytes. */
+ err = -EINVAL;
+ if (alg->cra_blocksize != XCTR_BLOCKSIZE)
+ goto out_free_inst;
+
+ /* XCTR mode is a stream cipher. */
+ inst->alg.base.cra_blocksize = 1;
+
+ /*
+ * To simplify the implementation, configure the skcipher walk to only
+ * give a partial block at the very end, never earlier.
+ */
+ inst->alg.chunksize = alg->cra_blocksize;
+
+ inst->alg.encrypt = crypto_xctr_crypt;
+ inst->alg.decrypt = crypto_xctr_crypt;
+
+ err = skcipher_register_instance(tmpl, inst);
+ if (err) {
+out_free_inst:
+ inst->free(inst);
+ }
+
+ return err;
+}
+
+static struct crypto_template crypto_xctr_tmpl = {
+ .name = "xctr",
+ .create = crypto_xctr_create,
+ .module = THIS_MODULE,
+};
+
+static int __init crypto_xctr_module_init(void)
+{
+ return crypto_register_template(&crypto_xctr_tmpl);
+}
+
+static void __exit crypto_xctr_module_exit(void)
+{
+ crypto_unregister_template(&crypto_xctr_tmpl);
+}
+
+subsys_initcall(crypto_xctr_module_init);
+module_exit(crypto_xctr_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("XCTR block cipher mode of operation");
+MODULE_ALIAS_CRYPTO("xctr");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/xor.c b/crypto/xor.c
index ea7349e6ed23..8e72e5d5db0d 100644
--- a/crypto/xor.c
+++ b/crypto/xor.c
@@ -54,49 +54,65 @@ EXPORT_SYMBOL(xor_blocks);
/* Set of all registered templates. */
static struct xor_block_template *__initdata template_list;
-#define BENCH_SIZE (PAGE_SIZE)
+#ifndef MODULE
+static void __init do_xor_register(struct xor_block_template *tmpl)
+{
+ tmpl->next = template_list;
+ template_list = tmpl;
+}
+
+static int __init register_xor_blocks(void)
+{
+ active_template = XOR_SELECT_TEMPLATE(NULL);
+
+ if (!active_template) {
+#define xor_speed do_xor_register
+ // register all the templates and pick the first as the default
+ XOR_TRY_TEMPLATES;
+#undef xor_speed
+ active_template = template_list;
+ }
+ return 0;
+}
+#endif
+
+#define BENCH_SIZE 4096
+#define REPS 800U
static void __init
do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2)
{
int speed;
- unsigned long now, j;
- int i, count, max;
+ int i, j;
+ ktime_t min, start, diff;
tmpl->next = template_list;
template_list = tmpl;
preempt_disable();
- /*
- * Count the number of XORs done during a whole jiffy, and use
- * this to calculate the speed of checksumming. We use a 2-page
- * allocation to have guaranteed color L1-cache layout.
- */
- max = 0;
- for (i = 0; i < 5; i++) {
- j = jiffies;
- count = 0;
- while ((now = jiffies) == j)
- cpu_relax();
- while (time_before(jiffies, now + 1)) {
- mb(); /* prevent loop optimzation */
+ min = (ktime_t)S64_MAX;
+ for (i = 0; i < 3; i++) {
+ start = ktime_get();
+ for (j = 0; j < REPS; j++) {
+ mb(); /* prevent loop optimization */
tmpl->do_2(BENCH_SIZE, b1, b2);
mb();
- count++;
- mb();
}
- if (count > max)
- max = count;
+ diff = ktime_sub(ktime_get(), start);
+ if (diff < min)
+ min = diff;
}
preempt_enable();
- speed = max * (HZ * BENCH_SIZE / 1024);
+ // bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s]
+ if (!min)
+ min = 1;
+ speed = (1000 * REPS * BENCH_SIZE) / (unsigned int)ktime_to_ns(min);
tmpl->speed = speed;
- printk(KERN_INFO " %-10s: %5d.%03d MB/sec\n", tmpl->name,
- speed / 1000, speed % 1000);
+ pr_info(" %-16s: %5d MB/sec\n", tmpl->name, speed);
}
static int __init
@@ -129,14 +145,15 @@ calibrate_xor_blocks(void)
#define xor_speed(templ) do_xor_speed((templ), b1, b2)
printk(KERN_INFO "xor: measuring software checksum speed\n");
+ template_list = NULL;
XOR_TRY_TEMPLATES;
fastest = template_list;
for (f = fastest; f; f = f->next)
if (f->speed > fastest->speed)
fastest = f;
- printk(KERN_INFO "xor: using function: %s (%d.%03d MB/sec)\n",
- fastest->name, fastest->speed / 1000, fastest->speed % 1000);
+ pr_info("xor: using function: %s (%d MB/sec)\n",
+ fastest->name, fastest->speed);
#undef xor_speed
@@ -150,6 +167,10 @@ static __exit void xor_exit(void) { }
MODULE_LICENSE("GPL");
+#ifndef MODULE
/* when built-in xor.o must initialize before drivers/md/md.o */
-core_initcall(calibrate_xor_blocks);
+core_initcall(register_xor_blocks);
+#endif
+
+module_init(calibrate_xor_blocks);
module_exit(xor_exit);
diff --git a/crypto/xts.c b/crypto/xts.c
index 29efa15f1495..63c85b9e64e0 100644
--- a/crypto/xts.c
+++ b/crypto/xts.c
@@ -7,6 +7,7 @@
* Based on ecb.c
* Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
*/
+#include <crypto/internal/cipher.h>
#include <crypto/internal/skcipher.h>
#include <crypto/scatterwalk.h>
#include <linux/err.h>
@@ -20,7 +21,7 @@
#include <crypto/b128ops.h>
#include <crypto/gf128mul.h>
-struct priv {
+struct xts_tfm_ctx {
struct crypto_skcipher *child;
struct crypto_cipher *tweak;
};
@@ -30,17 +31,17 @@ struct xts_instance_ctx {
char name[CRYPTO_MAX_ALG_NAME];
};
-struct rctx {
+struct xts_request_ctx {
le128 t;
struct scatterlist *tail;
struct scatterlist sg[2];
struct skcipher_request subreq;
};
-static int setkey(struct crypto_skcipher *parent, const u8 *key,
- unsigned int keylen)
+static int xts_setkey(struct crypto_skcipher *parent, const u8 *key,
+ unsigned int keylen)
{
- struct priv *ctx = crypto_skcipher_ctx(parent);
+ struct xts_tfm_ctx *ctx = crypto_skcipher_ctx(parent);
struct crypto_skcipher *child;
struct crypto_cipher *tweak;
int err;
@@ -78,9 +79,10 @@ static int setkey(struct crypto_skcipher *parent, const u8 *key,
* mutliple calls to the 'ecb(..)' instance, which usually would be slower than
* just doing the gf128mul_x_ble() calls again.
*/
-static int xor_tweak(struct skcipher_request *req, bool second_pass, bool enc)
+static int xts_xor_tweak(struct skcipher_request *req, bool second_pass,
+ bool enc)
{
- struct rctx *rctx = skcipher_request_ctx(req);
+ struct xts_request_ctx *rctx = skcipher_request_ctx(req);
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
const bool cts = (req->cryptlen % XTS_BLOCK_SIZE);
const int bs = XTS_BLOCK_SIZE;
@@ -128,23 +130,23 @@ static int xor_tweak(struct skcipher_request *req, bool second_pass, bool enc)
return err;
}
-static int xor_tweak_pre(struct skcipher_request *req, bool enc)
+static int xts_xor_tweak_pre(struct skcipher_request *req, bool enc)
{
- return xor_tweak(req, false, enc);
+ return xts_xor_tweak(req, false, enc);
}
-static int xor_tweak_post(struct skcipher_request *req, bool enc)
+static int xts_xor_tweak_post(struct skcipher_request *req, bool enc)
{
- return xor_tweak(req, true, enc);
+ return xts_xor_tweak(req, true, enc);
}
-static void cts_done(struct crypto_async_request *areq, int err)
+static void xts_cts_done(struct crypto_async_request *areq, int err)
{
struct skcipher_request *req = areq->data;
le128 b;
if (!err) {
- struct rctx *rctx = skcipher_request_ctx(req);
+ struct xts_request_ctx *rctx = skcipher_request_ctx(req);
scatterwalk_map_and_copy(&b, rctx->tail, 0, XTS_BLOCK_SIZE, 0);
le128_xor(&b, &rctx->t, &b);
@@ -154,12 +156,13 @@ static void cts_done(struct crypto_async_request *areq, int err)
skcipher_request_complete(req, err);
}
-static int cts_final(struct skcipher_request *req,
- int (*crypt)(struct skcipher_request *req))
+static int xts_cts_final(struct skcipher_request *req,
+ int (*crypt)(struct skcipher_request *req))
{
- struct priv *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
+ const struct xts_tfm_ctx *ctx =
+ crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
int offset = req->cryptlen & ~(XTS_BLOCK_SIZE - 1);
- struct rctx *rctx = skcipher_request_ctx(req);
+ struct xts_request_ctx *rctx = skcipher_request_ctx(req);
struct skcipher_request *subreq = &rctx->subreq;
int tail = req->cryptlen % XTS_BLOCK_SIZE;
le128 b[2];
@@ -169,7 +172,7 @@ static int cts_final(struct skcipher_request *req,
offset - XTS_BLOCK_SIZE);
scatterwalk_map_and_copy(b, rctx->tail, 0, XTS_BLOCK_SIZE, 0);
- memcpy(b + 1, b, tail);
+ b[1] = b[0];
scatterwalk_map_and_copy(b, req->src, offset, tail, 0);
le128_xor(b, &rctx->t, b);
@@ -177,7 +180,8 @@ static int cts_final(struct skcipher_request *req,
scatterwalk_map_and_copy(b, rctx->tail, 0, XTS_BLOCK_SIZE + tail, 1);
skcipher_request_set_tfm(subreq, ctx->child);
- skcipher_request_set_callback(subreq, req->base.flags, cts_done, req);
+ skcipher_request_set_callback(subreq, req->base.flags, xts_cts_done,
+ req);
skcipher_request_set_crypt(subreq, rctx->tail, rctx->tail,
XTS_BLOCK_SIZE, NULL);
@@ -192,18 +196,18 @@ static int cts_final(struct skcipher_request *req,
return 0;
}
-static void encrypt_done(struct crypto_async_request *areq, int err)
+static void xts_encrypt_done(struct crypto_async_request *areq, int err)
{
struct skcipher_request *req = areq->data;
if (!err) {
- struct rctx *rctx = skcipher_request_ctx(req);
+ struct xts_request_ctx *rctx = skcipher_request_ctx(req);
rctx->subreq.base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
- err = xor_tweak_post(req, true);
+ err = xts_xor_tweak_post(req, true);
if (!err && unlikely(req->cryptlen % XTS_BLOCK_SIZE)) {
- err = cts_final(req, crypto_skcipher_encrypt);
+ err = xts_cts_final(req, crypto_skcipher_encrypt);
if (err == -EINPROGRESS)
return;
}
@@ -212,18 +216,18 @@ static void encrypt_done(struct crypto_async_request *areq, int err)
skcipher_request_complete(req, err);
}
-static void decrypt_done(struct crypto_async_request *areq, int err)
+static void xts_decrypt_done(struct crypto_async_request *areq, int err)
{
struct skcipher_request *req = areq->data;
if (!err) {
- struct rctx *rctx = skcipher_request_ctx(req);
+ struct xts_request_ctx *rctx = skcipher_request_ctx(req);
rctx->subreq.base.flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
- err = xor_tweak_post(req, false);
+ err = xts_xor_tweak_post(req, false);
if (!err && unlikely(req->cryptlen % XTS_BLOCK_SIZE)) {
- err = cts_final(req, crypto_skcipher_decrypt);
+ err = xts_cts_final(req, crypto_skcipher_decrypt);
if (err == -EINPROGRESS)
return;
}
@@ -232,10 +236,12 @@ static void decrypt_done(struct crypto_async_request *areq, int err)
skcipher_request_complete(req, err);
}
-static int init_crypt(struct skcipher_request *req, crypto_completion_t compl)
+static int xts_init_crypt(struct skcipher_request *req,
+ crypto_completion_t compl)
{
- struct priv *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
- struct rctx *rctx = skcipher_request_ctx(req);
+ const struct xts_tfm_ctx *ctx =
+ crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
+ struct xts_request_ctx *rctx = skcipher_request_ctx(req);
struct skcipher_request *subreq = &rctx->subreq;
if (req->cryptlen < XTS_BLOCK_SIZE)
@@ -252,45 +258,45 @@ static int init_crypt(struct skcipher_request *req, crypto_completion_t compl)
return 0;
}
-static int encrypt(struct skcipher_request *req)
+static int xts_encrypt(struct skcipher_request *req)
{
- struct rctx *rctx = skcipher_request_ctx(req);
+ struct xts_request_ctx *rctx = skcipher_request_ctx(req);
struct skcipher_request *subreq = &rctx->subreq;
int err;
- err = init_crypt(req, encrypt_done) ?:
- xor_tweak_pre(req, true) ?:
+ err = xts_init_crypt(req, xts_encrypt_done) ?:
+ xts_xor_tweak_pre(req, true) ?:
crypto_skcipher_encrypt(subreq) ?:
- xor_tweak_post(req, true);
+ xts_xor_tweak_post(req, true);
if (err || likely((req->cryptlen % XTS_BLOCK_SIZE) == 0))
return err;
- return cts_final(req, crypto_skcipher_encrypt);
+ return xts_cts_final(req, crypto_skcipher_encrypt);
}
-static int decrypt(struct skcipher_request *req)
+static int xts_decrypt(struct skcipher_request *req)
{
- struct rctx *rctx = skcipher_request_ctx(req);
+ struct xts_request_ctx *rctx = skcipher_request_ctx(req);
struct skcipher_request *subreq = &rctx->subreq;
int err;
- err = init_crypt(req, decrypt_done) ?:
- xor_tweak_pre(req, false) ?:
+ err = xts_init_crypt(req, xts_decrypt_done) ?:
+ xts_xor_tweak_pre(req, false) ?:
crypto_skcipher_decrypt(subreq) ?:
- xor_tweak_post(req, false);
+ xts_xor_tweak_post(req, false);
if (err || likely((req->cryptlen % XTS_BLOCK_SIZE) == 0))
return err;
- return cts_final(req, crypto_skcipher_decrypt);
+ return xts_cts_final(req, crypto_skcipher_decrypt);
}
-static int init_tfm(struct crypto_skcipher *tfm)
+static int xts_init_tfm(struct crypto_skcipher *tfm)
{
struct skcipher_instance *inst = skcipher_alg_instance(tfm);
struct xts_instance_ctx *ictx = skcipher_instance_ctx(inst);
- struct priv *ctx = crypto_skcipher_ctx(tfm);
+ struct xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
struct crypto_skcipher *child;
struct crypto_cipher *tweak;
@@ -309,41 +315,39 @@ static int init_tfm(struct crypto_skcipher *tfm)
ctx->tweak = tweak;
crypto_skcipher_set_reqsize(tfm, crypto_skcipher_reqsize(child) +
- sizeof(struct rctx));
+ sizeof(struct xts_request_ctx));
return 0;
}
-static void exit_tfm(struct crypto_skcipher *tfm)
+static void xts_exit_tfm(struct crypto_skcipher *tfm)
{
- struct priv *ctx = crypto_skcipher_ctx(tfm);
+ struct xts_tfm_ctx *ctx = crypto_skcipher_ctx(tfm);
crypto_free_skcipher(ctx->child);
crypto_free_cipher(ctx->tweak);
}
-static void free(struct skcipher_instance *inst)
+static void xts_free_instance(struct skcipher_instance *inst)
{
- crypto_drop_skcipher(skcipher_instance_ctx(inst));
+ struct xts_instance_ctx *ictx = skcipher_instance_ctx(inst);
+
+ crypto_drop_skcipher(&ictx->spawn);
kfree(inst);
}
-static int create(struct crypto_template *tmpl, struct rtattr **tb)
+static int xts_create(struct crypto_template *tmpl, struct rtattr **tb)
{
struct skcipher_instance *inst;
- struct crypto_attr_type *algt;
struct xts_instance_ctx *ctx;
struct skcipher_alg *alg;
const char *cipher_name;
u32 mask;
int err;
- algt = crypto_get_attr_type(tb);
- if (IS_ERR(algt))
- return PTR_ERR(algt);
-
- if ((algt->type ^ CRYPTO_ALG_TYPE_SKCIPHER) & algt->mask)
- return -EINVAL;
+ err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
+ if (err)
+ return err;
cipher_name = crypto_attr_alg_name(tb[1]);
if (IS_ERR(cipher_name))
@@ -355,10 +359,6 @@ static int create(struct crypto_template *tmpl, struct rtattr **tb)
ctx = skcipher_instance_ctx(inst);
- mask = crypto_requires_off(algt->type, algt->mask,
- CRYPTO_ALG_NEED_FALLBACK |
- CRYPTO_ALG_ASYNC);
-
err = crypto_grab_skcipher(&ctx->spawn, skcipher_crypto_instance(inst),
cipher_name, 0, mask);
if (err == -ENOENT) {
@@ -379,15 +379,15 @@ static int create(struct crypto_template *tmpl, struct rtattr **tb)
err = -EINVAL;
if (alg->base.cra_blocksize != XTS_BLOCK_SIZE)
- goto err_drop_spawn;
+ goto err_free_inst;
if (crypto_skcipher_alg_ivsize(alg))
- goto err_drop_spawn;
+ goto err_free_inst;
err = crypto_inst_setname(skcipher_crypto_instance(inst), "xts",
&alg->base);
if (err)
- goto err_drop_spawn;
+ goto err_free_inst;
err = -EINVAL;
cipher_name = alg->base.cra_name;
@@ -400,22 +400,21 @@ static int create(struct crypto_template *tmpl, struct rtattr **tb)
len = strlcpy(ctx->name, cipher_name + 4, sizeof(ctx->name));
if (len < 2 || len >= sizeof(ctx->name))
- goto err_drop_spawn;
+ goto err_free_inst;
if (ctx->name[len - 1] != ')')
- goto err_drop_spawn;
+ goto err_free_inst;
ctx->name[len - 1] = 0;
if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
"xts(%s)", ctx->name) >= CRYPTO_MAX_ALG_NAME) {
err = -ENAMETOOLONG;
- goto err_drop_spawn;
+ goto err_free_inst;
}
} else
- goto err_drop_spawn;
+ goto err_free_inst;
- 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 = XTS_BLOCK_SIZE;
inst->alg.base.cra_alignmask = alg->base.cra_alignmask |
@@ -425,50 +424,46 @@ static int create(struct crypto_template *tmpl, struct rtattr **tb)
inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(alg) * 2;
inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(alg) * 2;
- inst->alg.base.cra_ctxsize = sizeof(struct priv);
+ inst->alg.base.cra_ctxsize = sizeof(struct xts_tfm_ctx);
- inst->alg.init = init_tfm;
- inst->alg.exit = exit_tfm;
+ inst->alg.init = xts_init_tfm;
+ inst->alg.exit = xts_exit_tfm;
- inst->alg.setkey = setkey;
- inst->alg.encrypt = encrypt;
- inst->alg.decrypt = decrypt;
+ inst->alg.setkey = xts_setkey;
+ inst->alg.encrypt = xts_encrypt;
+ inst->alg.decrypt = xts_decrypt;
- inst->free = free;
+ inst->free = xts_free_instance;
err = skcipher_register_instance(tmpl, inst);
- if (err)
- goto err_drop_spawn;
-
-out:
- return err;
-
-err_drop_spawn:
- crypto_drop_skcipher(&ctx->spawn);
+ if (err) {
err_free_inst:
- kfree(inst);
- goto out;
+ xts_free_instance(inst);
+ }
+ return err;
}
-static struct crypto_template crypto_tmpl = {
+static struct crypto_template xts_tmpl = {
.name = "xts",
- .create = create,
+ .create = xts_create,
.module = THIS_MODULE,
};
-static int __init crypto_module_init(void)
+static int __init xts_module_init(void)
{
- return crypto_register_template(&crypto_tmpl);
+ return crypto_register_template(&xts_tmpl);
}
-static void __exit crypto_module_exit(void)
+static void __exit xts_module_exit(void)
{
- crypto_unregister_template(&crypto_tmpl);
+ crypto_unregister_template(&xts_tmpl);
}
-subsys_initcall(crypto_module_init);
-module_exit(crypto_module_exit);
+subsys_initcall(xts_module_init);
+module_exit(xts_module_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("XTS block cipher mode");
MODULE_ALIAS_CRYPTO("xts");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
+MODULE_SOFTDEP("pre: ecb");
diff --git a/crypto/zstd.c b/crypto/zstd.c
index 5a3ff258d8f7..154a969c83a8 100644
--- a/crypto/zstd.c
+++ b/crypto/zstd.c
@@ -18,22 +18,22 @@
#define ZSTD_DEF_LEVEL 3
struct zstd_ctx {
- ZSTD_CCtx *cctx;
- ZSTD_DCtx *dctx;
+ zstd_cctx *cctx;
+ zstd_dctx *dctx;
void *cwksp;
void *dwksp;
};
-static ZSTD_parameters zstd_params(void)
+static zstd_parameters zstd_params(void)
{
- return ZSTD_getParams(ZSTD_DEF_LEVEL, 0, 0);
+ return zstd_get_params(ZSTD_DEF_LEVEL, 0);
}
static int zstd_comp_init(struct zstd_ctx *ctx)
{
int ret = 0;
- const ZSTD_parameters params = zstd_params();
- const size_t wksp_size = ZSTD_CCtxWorkspaceBound(params.cParams);
+ const zstd_parameters params = zstd_params();
+ const size_t wksp_size = zstd_cctx_workspace_bound(&params.cParams);
ctx->cwksp = vzalloc(wksp_size);
if (!ctx->cwksp) {
@@ -41,7 +41,7 @@ static int zstd_comp_init(struct zstd_ctx *ctx)
goto out;
}
- ctx->cctx = ZSTD_initCCtx(ctx->cwksp, wksp_size);
+ ctx->cctx = zstd_init_cctx(ctx->cwksp, wksp_size);
if (!ctx->cctx) {
ret = -EINVAL;
goto out_free;
@@ -56,7 +56,7 @@ out_free:
static int zstd_decomp_init(struct zstd_ctx *ctx)
{
int ret = 0;
- const size_t wksp_size = ZSTD_DCtxWorkspaceBound();
+ const size_t wksp_size = zstd_dctx_workspace_bound();
ctx->dwksp = vzalloc(wksp_size);
if (!ctx->dwksp) {
@@ -64,7 +64,7 @@ static int zstd_decomp_init(struct zstd_ctx *ctx)
goto out;
}
- ctx->dctx = ZSTD_initDCtx(ctx->dwksp, wksp_size);
+ ctx->dctx = zstd_init_dctx(ctx->dwksp, wksp_size);
if (!ctx->dctx) {
ret = -EINVAL;
goto out_free;
@@ -137,7 +137,7 @@ static void __zstd_exit(void *ctx)
static void zstd_free_ctx(struct crypto_scomp *tfm, void *ctx)
{
__zstd_exit(ctx);
- kzfree(ctx);
+ kfree_sensitive(ctx);
}
static void zstd_exit(struct crypto_tfm *tfm)
@@ -152,10 +152,10 @@ static int __zstd_compress(const u8 *src, unsigned int slen,
{
size_t out_len;
struct zstd_ctx *zctx = ctx;
- const ZSTD_parameters params = zstd_params();
+ const zstd_parameters params = zstd_params();
- out_len = ZSTD_compressCCtx(zctx->cctx, dst, *dlen, src, slen, params);
- if (ZSTD_isError(out_len))
+ out_len = zstd_compress_cctx(zctx->cctx, dst, *dlen, src, slen, &params);
+ if (zstd_is_error(out_len))
return -EINVAL;
*dlen = out_len;
return 0;
@@ -182,8 +182,8 @@ static int __zstd_decompress(const u8 *src, unsigned int slen,
size_t out_len;
struct zstd_ctx *zctx = ctx;
- out_len = ZSTD_decompressDCtx(zctx->dctx, dst, *dlen, src, slen);
- if (ZSTD_isError(out_len))
+ out_len = zstd_decompress_dctx(zctx->dctx, dst, *dlen, src, slen);
+ if (zstd_is_error(out_len))
return -EINVAL;
*dlen = out_len;
return 0;
diff --git a/crypto/ecc.h b/include/crypto/internal/ecc.h
index ab0eb70b9c09..4f6c1a68882f 100644
--- a/crypto/ecc.h
+++ b/include/crypto/internal/ecc.h
@@ -26,49 +26,35 @@
#ifndef _CRYPTO_ECC_H
#define _CRYPTO_ECC_H
+#include <crypto/ecc_curve.h>
+#include <asm/unaligned.h>
+
/* One digit is u64 qword. */
#define ECC_CURVE_NIST_P192_DIGITS 3
#define ECC_CURVE_NIST_P256_DIGITS 4
-#define ECC_MAX_DIGITS (512 / 64)
+#define ECC_CURVE_NIST_P384_DIGITS 6
+#define ECC_MAX_DIGITS (512 / 64) /* due to ecrdsa */
#define ECC_DIGITS_TO_BYTES_SHIFT 3
-/**
- * struct ecc_point - elliptic curve point in affine coordinates
- *
- * @x: X coordinate in vli form.
- * @y: Y coordinate in vli form.
- * @ndigits: Length of vlis in u64 qwords.
- */
-struct ecc_point {
- u64 *x;
- u64 *y;
- u8 ndigits;
-};
+#define ECC_MAX_BYTES (ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT)
#define ECC_POINT_INIT(x, y, ndigits) (struct ecc_point) { x, y, ndigits }
/**
- * struct ecc_curve - definition of elliptic curve
- *
- * @name: Short name of the curve.
- * @g: Generator point of the curve.
- * @p: Prime number, if Barrett's reduction is used for this curve
- * pre-calculated value 'mu' is appended to the @p after ndigits.
- * Use of Barrett's reduction is heuristically determined in
- * vli_mmod_fast().
- * @n: Order of the curve group.
- * @a: Curve parameter a.
- * @b: Curve parameter b.
+ * ecc_swap_digits() - Copy ndigits from big endian array to native array
+ * @in: Input array
+ * @out: Output array
+ * @ndigits: Number of digits to copy
*/
-struct ecc_curve {
- char *name;
- struct ecc_point g;
- u64 *p;
- u64 *n;
- u64 *a;
- u64 *b;
-};
+static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigits)
+{
+ const __be64 *src = (__force __be64 *)in;
+ int i;
+
+ for (i = 0; i < ndigits; i++)
+ out[i] = get_unaligned_be64(&src[ndigits - 1 - i]);
+}
/**
* ecc_is_key_valid() - Validate a given ECDH private key
@@ -148,6 +134,20 @@ int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve,
struct ecc_point *pk);
/**
+ * ecc_is_pubkey_valid_full() - Full public key validation
+ *
+ * @curve: elliptic curve domain parameters
+ * @pk: public key as a point
+ *
+ * Valdiate public key according to SP800-56A section 5.6.2.3.3 ECC Full
+ * Public-Key Validation Routine.
+ *
+ * Return: 0 if validation is successful, -EINVAL if validation is failed.
+ */
+int ecc_is_pubkey_valid_full(const struct ecc_curve *curve,
+ struct ecc_point *pk);
+
+/**
* vli_is_zero() - Determine is vli is zero
*
* @vli: vli to check.
@@ -226,6 +226,41 @@ void vli_mod_mult_slow(u64 *result, const u64 *left, const u64 *right,
const u64 *mod, unsigned int ndigits);
/**
+ * vli_num_bits() - Counts the number of bits required for vli.
+ *
+ * @vli: vli to check.
+ * @ndigits: Length of the @vli
+ *
+ * Return: The number of bits required to represent @vli.
+ */
+unsigned int vli_num_bits(const u64 *vli, unsigned int ndigits);
+
+/**
+ * ecc_aloc_point() - Allocate ECC point.
+ *
+ * @ndigits: Length of vlis in u64 qwords.
+ *
+ * Return: Pointer to the allocated point or NULL if allocation failed.
+ */
+struct ecc_point *ecc_alloc_point(unsigned int ndigits);
+
+/**
+ * ecc_free_point() - Free ECC point.
+ *
+ * @p: The point to free.
+ */
+void ecc_free_point(struct ecc_point *p);
+
+/**
+ * ecc_point_is_zero() - Check if point is zero.
+ *
+ * @p: Point to check for zero.
+ *
+ * Return: true if point is the point at infinity, false otherwise.
+ */
+bool ecc_point_is_zero(const struct ecc_point *point);
+
+/**
* ecc_point_mult_shamir() - Add two points multiplied by scalars
*
* @result: resulting point
@@ -242,4 +277,5 @@ void ecc_point_mult_shamir(const struct ecc_point *result,
const u64 *x, const struct ecc_point *p,
const u64 *y, const struct ecc_point *q,
const struct ecc_curve *curve);
+
#endif
diff --git a/crypto/memneq.c b/lib/crypto/memneq.c
index afed1bd16aee..243d8677cc51 100644
--- a/crypto/memneq.c
+++ b/lib/crypto/memneq.c
@@ -59,9 +59,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <asm/unaligned.h>
#include <crypto/algapi.h>
-
-#ifndef __HAVE_ARCH_CRYPTO_MEMNEQ
+#include <linux/module.h>
/* Generic path for arbitrary size */
static inline unsigned long
@@ -71,7 +71,8 @@ __crypto_memneq_generic(const void *a, const void *b, size_t size)
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
while (size >= sizeof(unsigned long)) {
- neq |= *(unsigned long *)a ^ *(unsigned long *)b;
+ neq |= get_unaligned((unsigned long *)a) ^
+ get_unaligned((unsigned long *)b);
OPTIMIZER_HIDE_VAR(neq);
a += sizeof(unsigned long);
b += sizeof(unsigned long);
@@ -95,18 +96,24 @@ static inline unsigned long __crypto_memneq_16(const void *a, const void *b)
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
if (sizeof(unsigned long) == 8) {
- neq |= *(unsigned long *)(a) ^ *(unsigned long *)(b);
+ neq |= get_unaligned((unsigned long *)a) ^
+ get_unaligned((unsigned long *)b);
OPTIMIZER_HIDE_VAR(neq);
- neq |= *(unsigned long *)(a+8) ^ *(unsigned long *)(b+8);
+ neq |= get_unaligned((unsigned long *)(a + 8)) ^
+ get_unaligned((unsigned long *)(b + 8));
OPTIMIZER_HIDE_VAR(neq);
} else if (sizeof(unsigned int) == 4) {
- neq |= *(unsigned int *)(a) ^ *(unsigned int *)(b);
+ neq |= get_unaligned((unsigned int *)a) ^
+ get_unaligned((unsigned int *)b);
OPTIMIZER_HIDE_VAR(neq);
- neq |= *(unsigned int *)(a+4) ^ *(unsigned int *)(b+4);
+ neq |= get_unaligned((unsigned int *)(a + 4)) ^
+ get_unaligned((unsigned int *)(b + 4));
OPTIMIZER_HIDE_VAR(neq);
- neq |= *(unsigned int *)(a+8) ^ *(unsigned int *)(b+8);
+ neq |= get_unaligned((unsigned int *)(a + 8)) ^
+ get_unaligned((unsigned int *)(b + 8));
OPTIMIZER_HIDE_VAR(neq);
- neq |= *(unsigned int *)(a+12) ^ *(unsigned int *)(b+12);
+ neq |= get_unaligned((unsigned int *)(a + 12)) ^
+ get_unaligned((unsigned int *)(b + 12));
OPTIMIZER_HIDE_VAR(neq);
} else
#endif /* CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS */
@@ -164,5 +171,3 @@ noinline unsigned long __crypto_memneq(const void *a, const void *b,
}
}
EXPORT_SYMBOL(__crypto_memneq);
-
-#endif /* __HAVE_ARCH_CRYPTO_MEMNEQ */