Compare commits

...

296 Commits

Author SHA1 Message Date
Jeffrey Walton 0c82df181c Update documentation 2019-08-31 07:46:19 -04:00
Jeffrey Walton 033f204a86 Fix .Net 2002 compile
This testing occurs on Windows XP. We are still rockin it
2019-08-27 14:44:27 -04:00
Jeffrey Walton b067d16e88 Update documentation 2019-08-27 10:28:13 -04:00
Jeffrey Walton 29453dcf08
Update comments 2019-08-27 07:52:33 -04:00
Jeffrey Walton 56165883fc
Update comments 2019-08-27 07:08:07 -04:00
Jeffrey Walton 54c8819c70
Fix ElGamal compile on Linux 2019-08-27 06:44:02 -04:00
Jeffrey Walton fcbfd68dfb
Add specialized Validate() to ElGamal
This was added for compatibility with BouncyCastle and other libraries. ElGamals paper and the HAC says to select x over the interval [1,p-1]. Crypto++ selects x over [1,q-1] as with other GFP schemes. Crypto++ fails to validate some of the keys of other libraries.
DL_PublicKey_GFP_OldFormat used to perform a reduction on x, but I think it treated a symptom and not the underlying cause. The underlying cause was, Crypto++ wass too strict in validating the parameter.
Note that wikipedia says to select the privaye key x over [1,q-1]. We are unable to find a reference for the practice, though it is OK.
2019-08-27 06:38:25 -04:00
Jeffrey Walton 90b0699edd
Add private key test data for ElGamal 2019-08-27 06:10:38 -04:00
Jeffrey Walton e06e3bd7a9
Fix ECP::Double and brainpoolP256r1 (GH #878) 2019-08-26 18:33:26 -04:00
Jeffrey Walton 66a6994e99
Add asserts to pubkey.h 2019-08-26 14:44:52 -04:00
Jeffrey Walton 8fa8ec9913
Update documentation 2019-08-25 12:20:21 -04:00
Jeffrey Walton db6d6b38b8
Update documentation 2019-08-25 12:00:28 -04:00
Jeffrey Walton 72f2b72920
Add test data from bug report (GH #876) 2019-08-24 18:00:03 -04:00
Jeffrey Walton f78c3c00d2
Regenerate ElGamal test data 2019-08-24 17:49:41 -04:00
Jeffrey Walton ff941db163
Update documentation 2019-08-24 16:59:39 -04:00
Jeffrey Walton a2c06c35b8
Use ASN1::elGamal() in ElGamal keys (GH #876) 2019-08-24 16:17:03 -04:00
Jeffrey Walton a7e83e6bf4
Update asserts in gfpcrypt.cpp 2019-08-24 15:48:14 -04:00
Jeffrey Walton 3d96234038
Fix typedef for MSVC (GH #876) 2019-08-24 06:44:14 -04:00
Jeffrey Walton 29e3818fd2
Add typedef for ElGamal::PrivateKey and ElGamal::PublicKey (GH #876) 2019-08-24 04:44:22 -04:00
Jeffrey Walton b80693d532
Add OID for ElGamal encryption (GH #876) 2019-08-24 03:18:29 -04:00
Jeffrey Walton 8130bd7a24
Update comments 2019-08-19 08:30:11 -04:00
Jeffrey Walton b9ff95f35a
Add define for CRYPTOPP_BOOL_ARM64 2019-08-18 04:27:25 -04:00
Jeffrey Walton 6545754337
Check size_t to DWORD and ULONG conversions
DWORD and ULONG are 32-bit. The conversion from size_t could fail, and the RNG would return a truncated result. I think it is low risk, but the test for the conversion test is cheap.
2019-08-17 21:19:04 -04:00
Jeffrey Walton d49c1a1605
Update documentation 2019-08-17 14:49:03 -04:00
Jeffrey Walton e22700f741
Fix use of MaxDerivedKeyLength (GH #874) 2019-08-16 07:12:14 -04:00
Jeffrey Walton c0a5a06a82
Fix use of MaxDerivedKeyLength (GH #874)
Also fix memcpy with NULL buffer
2019-08-16 06:45:30 -04:00
Jeffrey Walton 2ba9d3d00f
Restore former Test_RandomNumberGenerator behavior
There's no need to special case for HURD. No one uses it
2019-08-12 14:55:05 -04:00
Jeffrey Walton 7606c35fda
Update comments 2019-08-12 06:32:21 -04:00
Jeffrey Walton ea08de08d6
Add missing pumpAll to Test_RandomNumberGenerator 2019-08-12 06:27:10 -04:00
Jeffrey Walton 197f5fb1df
Add ASSERT to check m_fd for values <0
We are seeing RNG falures on HURD, but we are not throwing when constructing BlockingRng or NonblockingRng. This is despite the fact that /dev/urandom is missing during testing. NonblockingRng should always thwo when /dev/urandom is missing.
2019-08-12 05:40:22 -04:00
Jeffrey Walton 6028587b9f
Tighten Test_RandomNumberGenerator test
Debian HURD was slipping between the cracks. HURD appeared to be a minor failure because entropy on the heap improved the test result. After we zero'd the block, it was a catastrophic failure.
2019-08-12 05:34:11 -04:00
Jeffrey Walton 34e49627b7 Use C++ dynamic initialization if available 2019-08-12 00:11:41 -04:00
Jeffrey Walton 2d6895acb4 Update documentation 2019-08-11 22:37:15 -04:00
Jeffrey Walton 247418eec0 Use Bash arithmetic operators 2019-08-11 14:54:14 -04:00
Jeffrey Walton 11c5d14f85
Whitespace check-in 2019-08-10 03:24:52 -04:00
Jeffrey Walton 04b2a20c5d
Restore ECP ABI (GH #869)
Placing AdditionFunction as an inner class of ECP broke the ABI. We need to maintain the ABI so distros can patch Crypto++ 8.2.
2019-08-09 17:34:14 -04:00
Jeffrey Walton 7ac5791199
Fix cryptest.sh when swap is 0
If there is enough RAM then we don't need a swap file. I've got a Core i7-8800 with 64 GB or RAM that does not need a swap file.
2019-08-09 17:18:58 -04:00
Jeffrey Walton 242df465e8
Update comments 2019-08-07 23:30:48 -04:00
Jeffrey Walton c4700ae0b9
Avoid bitwise operation on boolean values 2019-08-07 23:27:33 -04:00
Jeffrey Walton 348e8e3b30
Clear unreachable code warnings under VC++ 2019-08-07 22:54:32 -04:00
Jeffrey Walton 1a5155fd96
Split public key benchmarks into integers and elliptic curves 2019-08-07 04:20:37 -04:00
Jeffrey Walton f3dd3d2559
Avoid temporary ECP::Point in ECP Addition and Double
This regains a lot of performance lost to the const-timeness (GH #869)
2019-08-07 02:43:13 -04:00
Jeffrey Walton b5fe6ab383
Clear parenthesis warning with GCC 2019-08-07 01:57:59 -04:00
Jeffrey Walton 7dc3b73e92
Add rdseed.asm to FileList.txt 2019-08-06 23:25:01 -04:00
Jeffrey Walton 7bba334641
Whitespace check-in 2019-08-06 21:42:43 -04:00
Jeffrey Walton b1c691b53a
Fix RDSEED hang on x86 (GH #872) (#873)
Calls to `MASM_RDSEED_GenerateBlock` would hang for an unknown reasons on Windows 10 and VS2017/VS2019 toolchains. Similar calls to `MASM_RDRAND_GenerateBlock` worked as expected. They were effectively the same code. The only differences were the function names and the opcodes (they were literally copy/paste).

Splitting `rdrand.asm` (with both `RDRAND` and `RDSEED`) into `rdrand.asm` (with `RDRAND`) and `rdseed.asm` (with `RDSEED`) resolved the issue. We don't know why.
2019-08-06 21:01:22 -04:00
Jeffrey Walton e5ab7919f9
Remove unneeded T in ECP Add()
Switch to 'R' variable in AdditionFunction to avoid shadow warnings
2019-08-06 03:28:53 -04:00
Jeffrey Walton 0ded32192e
Avoid branches in Montgomery Add() (GH #869) 2019-08-06 03:14:03 -04:00
Jeffrey Walton 5ae70e22b9
Avoid branches in Montgomery Double() (GH #869) 2019-08-06 01:23:37 -04:00
Jeffrey Walton df18c5b745 Add Debug and Release linker flags 2019-08-06 00:20:59 -04:00
Jeffrey Walton 41864fd49e Use local labels for RDRAND and RDSEED code (GH #872)
This did not fix the issue, but it is something on the TODO list.
2019-08-06 00:18:56 -04:00
Jeffrey Walton a01711e347 Fix CopyToRoot target with spaces in path 2019-08-05 13:27:54 -04:00
Jeffrey Walton c9ef9420e7
Fix ECP leakage in Add() and Double() (GH #869, PR #871)
This check-in provides the fix for leaks in ECP's Add() and Double(). The fixes were taken from Joost Renes, Craig Costello, and Lejla Batina's [Complete addition formulas for prime order elliptic curves](https://eprint.iacr.org/2015/1060.pdf).

The Pull Request includes two additional changes that were related to testing the primary fix. First, an `AuthenticatedKeyAgreementWithRolesValidate` interface was added. It allows us to test key agreement when roles are involved. Roles are "client", "server", "initiator", "recipient", etc.

Second, `SetGlobalSeed` was added to `test.cpp` to help with reproducible results. We had code in two different places that set the seed value for the random number generator. But it was sloppy and doing a poor job since results could not be reproduced under some circumstances.
2019-08-05 03:51:58 -04:00
Jeffrey Walton b3eb4c6a69
Fix AuthenticatedKeyAgreementWithRolesValidate messages 2019-08-03 23:59:25 -04:00
Jeffrey Walton 5aac8506bd
Use recipient rather than responder in authenticated key agreement
The recipient may not respond (though they do in the case of these key agreement schemes)
2019-08-03 23:52:50 -04:00
Jeffrey Walton 0b42a18cde
Update documentation 2019-08-03 23:25:15 -04:00
Jeffrey Walton 4e6dd922f7
Update documentation 2019-08-03 22:33:46 -04:00
Jeffrey Walton c3e0d123b2
Update documentation 2019-08-03 22:08:07 -04:00
Jeffrey Walton 37c0fb7ba8
Update documentation 2019-08-03 22:05:01 -04:00
Jeffrey Walton 057c2b434b
Update documentation 2019-08-03 21:58:26 -04:00
Jeffrey Walton 47a58050c6
Update documentation 2019-08-03 19:22:17 -04:00
Jeffrey Walton 2e6ccd7fb1
Fix authenticated key agreement domain parameter consistency test 2019-08-03 17:01:02 -04:00
Jeffrey Walton 7eeb954b23
Add AuthenticatedKeyAgreementValidateWithRoles free standing test function 2019-08-03 16:32:36 -04:00
Jeffrey Walton 3c5cb828b1
Spelling 2019-08-03 15:38:39 -04:00
Jeffrey Walton 84c4ae429f
Fix const-ness in HMQV and FHMQV 2019-08-03 03:24:26 -04:00
Jeffrey Walton 176cab0dc5
Update comments
Reference the bug report in DL_SignerBase::SignAndRestart for future readers
2019-07-29 10:36:29 -04:00
Ján Jančár f68f00f560 Fix ECDSA scalar multiplication leakage of bit-length. (GH #870)
This fixes the timing leakage of bit-length of nonces in ECDSA by essentially
fixing the bit-length, by using a nonce equivalent modulo the subgroup order.
2019-07-29 10:12:14 -04:00
Jeffrey Walton 739e5799e3 Whitespace check-in 2019-07-27 15:56:15 -04:00
Jeffrey Walton e4c402ace9
Clear truncation warning in rng.cpp (PR #867) 2019-07-25 04:52:24 -04:00
Andrew Marshall 12382a14be Use fixed size temporary in LC_RNG for consistency across platforms (#867) 2019-07-23 12:39:51 -04:00
Jeffrey Walton 614795f3e1
Add -DNDEBUG for openSUSE standrad build test 2019-07-22 16:10:43 -04:00
Jeffrey Walton 6eab4b7c32
Add openSUSE standard build test (GH #865) 2019-07-22 15:37:25 -04:00
Jeffrey Walton 9d2cab7548
Add CRYPTOPP_CXX14 define 2019-07-22 01:08:12 -04:00
Jeffrey Walton a7f2796dda
Update comments 2019-07-21 22:21:10 -04:00
Jeffrey Walton 7b7827e9cb
Clear Clang warning on SSE2 load 2019-07-21 22:20:55 -04:00
Jeffrey Walton 46e58df837
Add LINK_LIBRARY_PATH (GH #866) 2019-07-21 15:57:26 -04:00
Jeffrey Walton 3747e3d944
Don't use BASH_SOURCE in cryptest.sh 2019-07-21 03:19:14 -04:00
Jeffrey Walton ed7f4a0493
Use LINK_LIBRARY in cryptest-symbols.sh script (GH #866) 2019-07-21 03:16:01 -04:00
Jeffrey Walton dfaf2fc453
Remove references to GNUmakefile.shared (GH# 866) 2019-07-21 03:06:44 -04:00
Jeffrey Walton ef6e57990e
Use LINK_LIBRARY in cryptest.sh script (GH #866) 2019-07-21 03:02:43 -04:00
Jeffrey Walton 52ad132134
Add link-library variable to Makefiles (GH #866)
This should help distros and Crypto++ test scripts
2019-07-21 02:24:06 -04:00
Jeffrey Walton 5957b19fb8
Fix AVX2 feature test under Clang 3.3
Clang 3.3 appears to support some of AVX2, but it is missing _mm256_broadcastsi128_si256.
2019-07-21 00:27:23 -04:00
Jeffrey Walton 22a55bbbc5
Use wildcard for FORTIFY_SOURCE filter on TCXXFLAGS (GH #865) 2019-07-19 11:26:20 -04:00
Jeffrey Walton 417fbd719a
Fix missing if statement
Copy/paste error from the regular GNUmakefile
2019-07-19 00:16:23 -04:00
Jeffrey Walton 058a59814f
Fix TCXXFLAGS using openSUSE standard flags (GH #865) 2019-07-19 00:14:25 -04:00
Jeffrey Walton 07c208dbc6
Filter out static_assert from Posix assert test 2019-07-14 22:43:31 -04:00
Jeffrey Walton 769643bbe1
Fix macro paste in CRYPTOPP_ASSERT_JOIN 2019-07-14 19:09:05 -04:00
Jeffrey Walton 388a2e6ded
Fix macro paste in CRYPTOPP_ASSERT_JOIN 2019-07-14 19:04:52 -04:00
Jeffrey Walton f5881d121a
CRYPTOPP_CXX11_STATIC_ASSERT -> CRYPTOPP_CXX14_STATIC_ASSERT
WHoops, this is a C++14 feature
2019-07-14 19:02:58 -04:00
Jeffrey Walton 002e794ae2
Use C++ static_assert from N3928 when available 2019-07-14 18:28:51 -04:00
Jeffrey Walton 5de1089c8c
Update documentation 2019-07-14 12:50:50 -04:00
Jeffrey Walton e8b07b162f
Avoid preprocessor error in SIZE_MAX (GH #864) 2019-07-14 00:52:30 -04:00
Jeffrey Walton 6ae9c055cc
Move CRYPTOPP_CXX11 down in list of defines 2019-07-11 12:12:19 -04:00
Jeffrey Walton f0d7917719
Move CRYPTOPP_NO_CXX11 and CRYPTOPP_NO_CXX17 to config_cxx.h
It looks like these two were overlooked during refactoring
2019-07-11 12:10:19 -04:00
Jeffrey Walton 8260dd1e81
Increase m_buf size (GH #862) 2019-07-10 15:54:48 -04:00
Jeffrey Walton 6d69043403
Add BufferedTransformation GetWord64 and PutWord64 (GH #862) 2019-07-10 10:04:58 -04:00
Jeffrey Walton a76c6a203f
Update documentation 2019-07-10 08:10:44 -04:00
Jeffrey Walton 60e7bf3081
Update documentation 2019-07-08 18:46:27 -04:00
Jeffrey Walton 195cd6e7c8
Update documentation 2019-07-06 16:06:27 -04:00
Jeffrey Walton 2ffa70fbc6
Clear asserts under DEBUG builds 2019-07-06 15:57:08 -04:00
Jeffrey Walton fd7115fc8b
Remove duplicate CRYPTOPP_GCC_VERSION test 2019-07-06 08:06:00 -04:00
Jeffrey Walton b76a010dda
Cleanup PowerPC defines 2019-07-06 07:35:36 -04:00
Jeffrey Walton f0a2967191
Fix missing binary operator 2019-07-06 07:07:16 -04:00
Jeffrey Walton 37de652635
Use C++ feature test macros when available
There are not too many of them. __cpp_threadsafe_static_init may be useful for less frequently used compilers and platforms.
2019-07-06 07:03:26 -04:00
Jeffrey Walton 76fa704cbe
Avoid potential uninitialized read in AutoSeededX917RNG
This is a minor fix to AutoSeededX917RNG::Reseed. Valgrind produces a finding if user input is too small or seed size is too large. The constraints make it a little tricky to use correctly. HKDF will always produce the correct amount of material with provable security, and avoid the Valgrind finding.
2019-07-06 02:58:43 -04:00
Jeffrey Walton 6c995e215a Fold CRYPTOPP_VALGRIND into CRYPTOPP_COVERAGE 2019-07-05 19:10:01 -04:00
Jeffrey Walton d4b3e1535a
Limit GCC workaround to 5.3 on PowerPC
GCC fixed the issue at GCC 5.3. Also see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31690
2019-07-05 18:08:05 -04:00
Jeffrey Walton 9c28cf2227
Whitespace check-in
Cleanup after the VMAC fixes
2019-07-05 17:26:50 -04:00
Jeffrey Walton ad99fc5b05
Clear Asan finding in VMAC under 32-bit inline ASM (GH #860)
Second try. The first try cleared the Asan finding but broke at -O3. Eventually we will skin this cat.
2019-07-05 16:33:01 -04:00
Jeffrey Walton 7fd751ed36
Revert Asan finding in VMAC change (GH #860)
cryptest.sh showed it broke at -O3
2019-07-05 11:58:35 -04:00
Jeffrey Walton f7986129df
Clear Asan finding in VMAC under 32-bit inline ASM (GH #860)
This one has been nagging us for a while. Tested OK under i686 and x86_64.
2019-07-05 03:38:03 -04:00
Jeffrey Walton 6bead34bd9
Update headers for 'make dep' 2019-07-05 02:42:27 -04:00
Jeffrey Walton ae04195d1f
Use xattr in cryptest-autotools.sh 2019-07-04 16:06:51 -04:00
Jeffrey Walton 6afa6fc213
Fix cryptest-autotools.sh on OS X
Needed to remove quarantine bit
2019-07-04 15:36:17 -04:00
Jeffrey Walton 6eeebaf26b
Update documentation 2019-07-04 13:57:33 -04:00
Jeffrey Walton 2baa37efac
Clear unused parameter warnings for GCC with -Wextra (GH #856) 2019-07-03 15:17:53 -04:00
Jeffrey Walton cd0d145635 Add legacy ECIES EC2N cryptosystem and kat (GH #856) 2019-07-03 03:06:58 -04:00
Jeffrey Walton ce6d3c1306 Add legacy ECIES ECP cryptosystem and kat (GH #856) 2019-07-03 01:41:23 -04:00
Mouse 5d0ceb3b04
Revert #857 for now
Travis CI fails "deep tests" of DLIES with #857 applied. Let's revert it for now and get back to
```c++
    cipherKey = key + MAC::DEDAULT_KEYLENGTH;
```
and see if it improves the situation.
2019-07-02 23:24:45 -04:00
Jeffrey Walton eeb7dadc76
Fix missing _mm_roti_epi32 and _mm_roti_epi64 under GCC (GH #859) 2019-07-02 19:10:11 -04:00
Jeffrey Walton fbbf0a08e8
Add missing XOP header for blake2b_simd.cpp (GH #859)
The Gentoo folks caught a bug at https://bugs.gentoo.org/689162. The 689162 bug uses -march=bdver1 -msse4.1 on a AMD Bulldozer machine.

Investigating the issue we are missing the XOP header blake2b_simd.cpp. However, adding the XOP header is not enough for this particular config. Four source files fail to compile with the expected headers. We are waiting on the GCC folks to get back to us with a fix.
2019-07-02 16:55:00 -04:00
Alon Bar-Lev 2eb400c52f config: guard CRYPTOPP_SSE2_INTRIN_AVAILABLE with CRYPTOPP_DISABLE_SSE2 (#858)
Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
2019-07-02 16:45:03 -04:00
Mouse c80a7ad028
Merge pull request #857 from rectalogic/nullhash
Use MAC::DIGESTSIZE in ECIES SymmetricEncrypt/SymmetricDecrypt
2019-07-02 11:06:29 -04:00
Mouse 97f5174226
Complete change from DEFAULT_KEYLENGTH to DIGESTSIZE in DLAES
Change from `MAC::DEFAULT_KEYLENGTH` to `MAC::DIGESTSIZE` in `DL_EncryptionAlgorithm_Xor` was only partially done. This was discovered when null hash was used. This, along with the proposed fix, was discovered by Andrew Wason (thanks!).
2019-07-02 11:02:07 -04:00
Andrew Wason 9c307ff4ba Use MAC::DIGESTSIZE in ECIES SymmetricEncrypt/SymmetricDecrypt
Fixes #856
2019-07-02 10:47:46 -04:00
Jeffrey Walton 445ec61125
Remove copy ctor from DERGeneralEncoder and BERGeneralDecoder
GCC was giving too many warnings at -Wextra. We also could not comply with Rule of 3 because it resulted in compile failures in C++98 and C++03
2019-07-01 13:29:46 -04:00
Jeffrey Walton c3d4e79a09
Use CRYPTOPP_CXX11_DELETED_FUNCTIONS in NotCopyable 2019-07-01 13:27:51 -04:00
Jeffrey Walton 36e8dfeca8
Add define for C++11 deleted functions 2019-07-01 08:17:22 -04:00
Jeffrey Walton 18d5e5528f Fix divide by 0 finding (GH #855)
I'm not sure which tool is producing this finding. I am pretty sure it is a false positive, but clear it for the sake of dark and silent cockpits
2019-06-28 14:22:03 -04:00
Jeffrey Walton 26a59cd94b
Update README 2019-06-15 06:42:34 -04:00
Jeffrey Walton 840bc65740
Update README 2019-06-15 06:20:49 -04:00
Mouse 03619c0800
Merge pull request #853 from DimaStebaev/pull-request
Compilation warning fix.
2019-06-12 07:37:52 -04:00
Dmytro Stebaiev d24c991913
Pull changes from master branch 2019-06-10 11:25:46 +03:00
Jeffrey Walton 0ea4354157
Update comments 2019-06-09 12:52:10 -04:00
Jeffrey Walton 570a8e1b36
Whitespace check-in 2019-06-09 12:12:46 -04:00
Jeffrey Walton 955ac6fe24
Rework SSE2 and AVX2 loads and stores 2019-06-09 04:29:40 -04:00
Jeffrey Walton 8c78985de2
Add ModularArithmetic::operator= 2019-06-09 02:56:30 -04:00
Jeffrey Walton c1f4d17e10
Cleanup BERGeneralDecoder constructors
For real this time...
2019-06-09 02:03:06 -04:00
Jeffrey Walton 55fe6a2191
Cleanup BERGeneralDecoder constructors 2019-06-09 02:00:53 -04:00
Jeffrey Walton 8fab1c3677
Revert changes for lgtm findings
This broke SunCC to the point of no repair. SunCC is using AVX2 instructions for C++ and SSE2. Man this compiler sucks...
2019-06-09 01:49:44 -04:00
Jeffrey Walton 3ce1823fd1
Fix SunCC compile
Sun's compiler is mostly braindead.
2019-06-09 00:00:22 -04:00
Jeffrey Walton 6a11f00768
Clear lgtm findings 2019-06-08 12:59:14 -04:00
Jeffrey Walton 43b01973b1
Clear lgtm findings
We did some refactoring and added sse_simd.h. Over time more SSE functions will likely move into sse_simd.h
2019-06-08 11:00:11 -04:00
Jeffrey Walton afffba7b7b
Add -mtune=native option to makefile
Added for Solaris 11 .3 on SPARC64
2019-06-07 13:02:25 -04:00
Dmytro Stebaiev fa9187ac77
Fix compilation warning 2019-06-07 18:17:15 +03:00
Jeffrey Walton ed4996f652
Cleanup governor.sh script 2019-06-05 23:21:00 -04:00
Jeffrey Walton 29a30b74b0
Update head comments 2019-06-05 23:09:58 -04:00
Jeffrey Walton 17fa3031b3
Clear lgtm finding in ECP class 2019-06-05 10:52:45 -04:00
Jeffrey Walton d8122cec16
Avoid ARM rev on Aarch64
This broke Aarch64
2019-06-04 21:17:13 -04:00
Jeffrey Walton 6c009ddf43
Remove dummy operator= in ModularArithmetic 2019-06-04 19:05:33 -04:00
Jeffrey Walton 994c98b6c0
Fix GCC compile on AIX
In file included from test.cpp:31:0:
validate.h:213:93: error: operator '||' has no right operand
 #elif (_POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE || _POSIX_SOURCE)
2019-06-04 09:45:33 -04:00
Jeffrey Walton 3afb1f1099
Fix GCC compile on AIX
In file included from test.cpp:31:0:
validate.h:213:93: error: operator '||' has no right operand
 #elif (_POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE || _POSIX_SOURCE)
2019-06-04 09:37:28 -04:00
Jeffrey Walton 198b081df5
Add assert to RemainingLength member function 2019-06-04 09:29:01 -04:00
Jeffrey Walton 238578a808
Clear lgtm findings
The lgtm service asks for scoped calls to IsolatedInitialize. The code is a tad bit more readable, so we will clear the findings.
2019-06-04 05:31:46 -04:00
Jeffrey Walton 462bcc859d
Update Poly1305 nonce length check 2019-06-04 04:39:19 -04:00
Jeffrey Walton a644008679
Cleanup ASN.1 encoders and decoders (GH #851) 2019-06-04 02:49:16 -04:00
Jeffrey Walton ab538471b1
Update documentation 2019-06-04 02:46:43 -04:00
Jeffrey Walton f330c0eca8
Clear warning on missing assignment operator 2019-06-03 23:17:15 -04:00
Jeffrey Walton c76711237a
Call base class IsolatedInitialize 2019-06-03 06:45:58 -04:00
Jeffrey Walton 3faf716d73
Call base class IsolatedInitialize 2019-06-03 06:44:58 -04:00
Jeffrey Walton 0a20141f36
Clear warning for assignment operator in HuffmanNode 2019-06-03 06:32:24 -04:00
Jeffrey Walton 54d48ac1f4
Add header guard for serpentp.h 2019-06-03 06:17:58 -04:00
Jeffrey Walton 342cdb9589
Clear lgtm warning on unsafe functions 2019-06-03 05:41:58 -04:00
Jeffrey Walton 959494871f
Guard use of volatile cast in TEA and XTEA 2019-06-02 05:29:08 -04:00
Jeffrey Walton 9538f2d715
Fix compile on iOS 2019-06-01 08:05:39 -04:00
Jeffrey Walton f00b0427aa
Exit setenv script if not sourced 2019-06-01 07:43:32 -04:00
Jeffrey Walton 1a0d7c516d
Disable BMI2 code paths in Integer class (GH #850) 2019-06-01 00:14:19 -04:00
Jeffrey Walton 8e27c6b3fa
Fix OS X compile with Clang later than 6.0
It looks like Apple Clang 6.0 does not provide _blsr_u32 and friends. Later versions of Clang defines _blsr_u32 and it causes a stream of warnings.
2019-05-31 23:33:17 -04:00
Jeffrey Walton 392ec3465e
Fix OS X compile with Clang 6.0 2019-05-31 23:03:24 -04:00
Jeffrey Walton 4952fa489d
Use BMI2 when available for MultiplyWordsLoHi, MulAcc and friends
Using BMI2 saves about 0.03 ms on a Core i5 6400 @ 2.7 GHz. It is small but measurable. It also gives GCC more freedom in selecting memory or register operands
2019-05-31 09:42:39 -04:00
Jeffrey Walton fb0bef1eb6
Use BMI2 when available for MultiplyWordsLoHi, MulAcc and friends
Using BMI2 saves about 0.03 ms on a Core i5 6400 @ 2.7 GHz. It is small but measurable. It also gives GCC more freedom in selecting memory or register operands
2019-05-31 05:37:35 -04:00
Jeffrey Walton aed6e935d6
Update documentation 2019-05-30 23:22:47 -04:00
Jeffrey Walton 1f2be58434
Update Doxygen comments 2019-05-30 22:30:22 -04:00
Jeffrey Walton 0dd07252d2
Update comments 2019-05-28 20:19:34 -04:00
Jeffrey Walton e40de18538
Update comments 2019-05-28 20:18:58 -04:00
Jeffrey Walton b61da7acfe
Update cryptest-autotools script 2019-05-28 06:36:01 -04:00
Jeffrey Walton a2e7c26f6c
Add 16-bit rev16 and rbit 2019-05-28 02:50:58 -04:00
Jeffrey Walton 623059f28c
Use ARM rev and rbit when appropriate
We tried to add a ByteReverse(word64) and BitReverse(word64) overloads but GCC was producing bad code for it.
2019-05-27 14:27:12 -04:00
Jeffrey Walton 81da61fe7b
Breakout sha_block_data_order and sha_block_data_order_neon (GH #847) 2019-05-26 22:10:26 -04:00
Jeffrey Walton d4b533a60f
Add Thumb and Arm versions of CPU_ProbeARMv7() 2019-05-26 17:06:55 -04:00
Jeffrey Walton 7cd8d0278a
Remove VFP_ABI_PUSH and VFP_ABI_POP macros 2019-05-26 02:14:03 -04:00
Jeffrey Walton 9a3c1e351d
Clear Valgrind finding in IncrementCounterByOne
The single buffer IncrementCounterByOne generated a Valgrind finding on ARM. This commit uses the same pattern for both overloads in case Valgrind wants to fire on the two-buffer version.
2019-05-25 19:49:49 -04:00
Jeffrey Walton ca11105a40
Clear sign comparison warning under GCC 2019-05-25 17:00:32 -04:00
Jeffrey Walton f90c162b68
Fix IncrementCounterByOne
This was introduced earlier in the day when clearing a Valgrind finding. It tested good with the self tests. However, we double process byte[0] if there's a carry.
2019-05-25 07:02:32 -04:00
Jeffrey Walton fc10a7f1ea
Fix SHA512 on ARM benchmarks
This was a mistake when porting from Cryptogams to Crypto++. The macros VFP_ABI_PUSH and VFP_ABI_POP needed to be defined because they save and restore SIMD register state. They were originally missing during the port. The benchmarks would hang because the doubles we used for benchmarking were blown away in sha512_block_data_order_neon.
2019-05-25 06:23:19 -04:00
Jeffrey Walton 92df2a685f
Clear Valgrind warnings on ARM
I don't believe these should have been findings. They were clear on x86, Aarch64 and PowerPC.
2019-05-25 03:41:05 -04:00
Jeffrey Walton 1400757fea
Update comments 2019-05-25 00:43:27 -04:00
Jeffrey Walton ea96b9d375
Use CRYPTOGAMS_armcap_P for ARM (GH #846)
Andy advised against removing the global caps variable. This commit reintroduces CRYPTOGAMS_armcap_P. However, due to the shared object symbol loading problem, we needed to use CRYPTOGAMS_armcap_P as a global, and not CRYPTOGAMS_armcap as a local. Using CRYPTOGAMS_armcap_P directly caused the symbol to be marked as R_ARM_ABS32 which avoids the problem with R_ARM_REL32.
2019-05-24 16:33:47 -04:00
Jeffrey Walton 1650cac3f3
Update comments 2019-05-23 19:35:05 -04:00
Jeffrey Walton 2a09376211
Remove const_cast from CryptogamsArmCaps() 2019-05-23 03:17:17 -04:00
Jeffrey Walton c5bb85754f
Add RDRAND and RDSEED test programs
These are for Autotools on Solaris.
2019-05-22 21:25:31 -04:00
Jeffrey Walton fed4a55f39
Update cryptest-autotools script 2019-05-22 21:03:19 -04:00
Jeffrey Walton 57b85fafce
Update Cryptogams SHA headers (GH #846) 2019-05-22 19:11:16 -04:00
Jeffrey Walton 7eaa5837e0
Fix "unexpected reloc type 0x03" for ARM shared object (GH #846) 2019-05-22 19:00:08 -04:00
Jeffrey Walton ce5d5d5c0f
Use CRYPTOGAMS_armcap_loc for word label 2019-05-22 06:37:16 -04:00
Jeffrey Walton 0a4b370d3f
Use CRYPTOGAMS_armcaps
It looks like CRYPTOGAMS_armcap was used in some places, and it broke Autotools
2019-05-22 05:46:06 -04:00
Jeffrey Walton 13e3a19e94
Remove __KERNEL__ guard
Andy's code is used in the Linux kernel. The define is not needed here.
2019-05-22 05:12:16 -04:00
Jeffrey Walton 073c246595
Rename CRYPTOGAMS_armcap_P to CRYPTOGAMS_armcap 2019-05-22 05:01:27 -04:00
Jeffrey Walton 50dd3ad354
Spelling 2019-05-22 03:04:38 -04:00
Jeffrey Walton 7287a79669
Use config_ver.h in change-version script 2019-05-22 02:56:37 -04:00
Jeffrey Walton 1abab8050e
Clear documentation warnings 2019-05-22 02:53:26 -04:00
Jeffrey Walton 879b8c6fe9
Remove unused CLANG_INTEGRATED_ASSEMBLER from Makefile
This is an artifact that should have been removed at CRYPTOPP_DISABLE_MIXED_ASM.
2019-05-21 20:05:44 -04:00
Jeffrey Walton f396ade93a
Rename XGETBV to XGETBV64 2019-05-21 19:44:48 -04:00
Jeffrey Walton 6f3be56c9d
Update comments 2019-05-21 19:40:11 -04:00
Jeffrey Walton 02cdbf61d3
Rename ExtendedControlRegister to XGETBV 2019-05-21 19:31:13 -04:00
Jeffrey Walton cf85d768b4
Fix armv8l-unknown-linux-gnueabihf yet again 2019-05-21 18:48:13 -04:00
Jeffrey Walton 5e15b46234
Fix Aarch64 compile in CPU_ProbeARMv7
Previous to the Cryptogams cut-in we could be sloppy and return anything for ARMv8. Now e have real code backing ARMv7 we need to return an accurate value.
2019-05-21 08:13:52 -04:00
Jeffrey Walton 268ea61f1c
Cutover to CRYPTOPP_LLVM_CLANG_VERSION (GH #845)
We were using CRYPTOPP_CLANG_VERSION in some places.
2019-05-21 07:54:47 -04:00
Jeffrey Walton 2d4a932c33
Remove -tvos_simulator_version_min from AppleTVSimulator
It did not clear the problem.
2019-05-21 07:08:41 -04:00
Jeffrey Walton 5b1cae0c63
Fix compile using MSVC 2013 ARM 2019-05-21 06:54:33 -04:00
Jeffrey Walton 751515901b
Limit Cryptogams AES and SHA to Linux distros
The Apple assembler cannot translate the source files for iOS.
2019-05-21 05:59:58 -04:00
Jeffrey Walton ddb9249444
Fix source warning 2019-05-21 05:44:21 -04:00
Jeffrey Walton 1973674732
Add sanity check to setenv-*.sh scripts
Prompt user to source the script when required. Whitespace check-in
2019-05-21 05:37:40 -04:00
Jeffrey Walton 3e897eb0f6
Use CRYPTOPP_ARM_NEON_AVAILABLE in neon_simd.cpp 2019-05-21 05:11:24 -04:00
Jeffrey Walton 02baab2307
Enable Cryptogams AES on ARM using Clang
It looks like AES needed -mthumb for Clang. SHA must not use -mthumb under Clang due to a crash.
2019-05-21 04:23:40 -04:00
Jeffrey Walton 6acbbf1849
Fix crash in GCM mode on ARM with -mthumb 2019-05-21 04:03:22 -04:00
Jeffrey Walton 08235400b0
Add CRYPTOPP_CLANG_VERSION for ARM asm defines
We should be using both CRYPTOPP_APPLE_CLANG_VERSION and CRYPTOPP_LLVM_CLANG_VERSION. We'll loop back to it when we have some time.
2019-05-21 03:02:35 -04:00
Jeffrey Walton 5fb03078eb
Use void return value for Cryptogams SHA functions 2019-05-21 02:38:30 -04:00
Jeffrey Walton e8603143dc
Whitespace check-in
We also simplified the CPU_ProbeNEON logic a bit to a vmov.u32 and vshl.u32.
2019-05-21 02:21:15 -04:00
Jeffrey Walton 40251d9b7f
Guard CPU_ProbeARMv7 with CRYPTOPP_BOOL_ARM32 (GH #844)
We make these queries available on all platforms so folks don't need to guard code.
2019-05-20 23:33:06 -04:00
Jeffrey Walton c456d6aa69
Guard CPU_ProbeARMv7 with CRYPTOPP_BOOL_ARM32 (GH #844)
We make these queries available on all platforms so folks don't need to guard code.
2019-05-20 23:30:12 -04:00
Jeffrey Walton cc011d2e44
Remove Aarch32 and Aarch64 from CPU_QueryARMv7
I believe some of the code may be generated differently. When testing CPU_ProbeARMv7 I had trouble compiling it on ARMv8.
2019-05-20 23:09:57 -04:00
Jeffrey Walton a9be7ced86
Fix CPU_QueryARMv7 for Clang (GH #844)
This fixes the query under Clang. This appears to be a trickier problem because there is no explicit define for HWCAP_ARMv7. We rely on HWCAP_NEON as a proxy, or fallback to a CPU_ProbeARMv7.
2019-05-20 23:02:36 -04:00
Jeffrey Walton a164c1f41d
Fix CPU_ProbeARMv7 for Clang (GH #844)
This fixes the probe undr Clang. However, we need to fix the CPU_QueryARMv7
2019-05-20 21:41:57 -04:00
Jeffrey Walton c0cff24953
Update comments 2019-05-20 17:11:59 -04:00
Jeffrey Walton b1b6ea5b78
Fold declarations for CRYPTOGAMS_armcaps
Also declare storage for CRYPTOGAMS_armcaps. This moves the symbol from BSS to initialized data. The Cryptogams module declares the symbol as common, so they are weak and use our declaration.
2019-05-20 17:03:57 -04:00
Jeffrey Walton 5c7c092336
Cleanup Cryptogams defines 2019-05-20 16:39:26 -04:00
Jeffrey Walton 00155d42cc
Enable Cryptogams SHA asm for Clang
AES is still disabled
2019-05-20 15:29:30 -04:00
Jeffrey Walton 9590481c7f
Update cryptest-autotools.sh 2019-05-20 03:48:02 -04:00
Jeffrey Walton 122529ed4a
Add test for automake in cryptest-autotools.sh 2019-05-19 21:46:36 -04:00
Jeffrey Walton e0b60439bf
Fix Scrypt crash when blockSize is 0 (GH #842)
This may change in the future. I prefer to recover, and use default block size when block size is 0. But this stops the immediate problem of a crash.
2019-05-19 21:24:32 -04:00
Jeffrey Walton 2c0455edf8
Add additional asserts in Scrypt::ValidateParameters (GH #842)
We still need to figure out what to do, but we can start warning users immediately.
2019-05-19 18:52:37 -04:00
Jeffrey Walton e3788aacc5
Display C++ for SHA512_AlgorithmProvider on ARM 2019-05-19 18:17:46 -04:00
Jeffrey Walton 6528561cb3
Update comments 2019-05-19 18:10:09 -04:00
Jeffrey Walton e19a6152b5
Return CRYPTOGAMS_armcaps in CryptogamsArmCaps 2019-05-19 16:51:40 -04:00
Jeffrey Walton 62d53e6c44
Disable Cryptogams ASM on static Transform function
This needs mmore testing.
2019-05-19 16:46:01 -04:00
Jeffrey Walton d38e5a954d
Add ARM SHA512 asm implementation from Cryptogams (GH #841, PR #843)
Cryptogams is Andy Polyakov's project used to create high speed crypto algorithms and share them with other developers. Cryptogams  has a dual license. First is the OpenSSL license because Andy contributes to OpenSSL. Second is a BSD license for those who want a more permissive license.

Andy's implementation runs about 45% faster than C/C++ code. Testing on a 1.8 GHz Cortex-A17 shows Cryptograms at 45 cpb, and C++ at 79 cpb.

The integration instructions are documented at [Cryptogams SHA](https://wiki.openssl.org/index.php/Cryptogams_SHA) on the OpenSSL wiki.
2019-05-19 16:29:45 -04:00
Jeffrey Walton 4c9ca6b723
Add ARM SHA256 asm implementation from Cryptogams (GH #840, PR #840)
Cryptogams is Andy Polyakov's project used to create high speed crypto algorithms and share them with other developers. Cryptogams  has a dual license. First is the OpenSSL license because Andy contributes to OpenSSL. Second is a BSD license for those who want a more permissive license.

Andy's implementation runs about 45% faster than C/C++ code. Testing on a 1 GHz Cortex-A7 shows Cryptograms at 17 cpb, and C++ at 30 cpb.

The integration instructions are documented at [Cryptogams SHA](https://wiki.openssl.org/index.php/Cryptogams_SHA) on the OpenSSL wiki.
2019-05-19 06:59:12 -04:00
Jeffrey Walton 8c99b1cd75
Add call to automake in cryptest-automake.sh 2019-05-19 02:26:44 -04:00
Jeffrey Walton ffb11da13b
Add call to automake in cryptest-automake.sh 2019-05-19 02:19:47 -04:00
Jeffrey Walton 1a63112faf
Add ARM SHA1 asm implementation from Cryptogams (GH #837, PR #838)
Add ARM SHA1 asm implementation from Cryptogams.

Cryptogams is Andy Polyakov's project used to create high speed crypto algorithms and share them with other developers. Cryptogams  has a dual license. First is the OpenSSL license because Andy contributes to OpenSSL. Second is a BSD license for those who want a more permissive license.

Andy's implementation runs about 30% faster than C/C++ code. Testing on a 1 GHz Cortex-A7 shows Cryptograms at 16 cpb, and C++ at 23 cpb.

The integration instructions are documented at [Cryptogams SHA](https://wiki.openssl.org/index.php/Cryptogams_SHA) on the OpenSSL wiki.
2019-05-18 23:07:17 -04:00
Jeffrey Walton 4a21619bff
Regenerate Cryptogams AES assembly file
> It does not look like much has changed in the last year.
2019-05-18 06:49:51 -04:00
Jeffrey Walton 6cc9c81fa5
Use test_arm_sha1.cxx for feature tests 2019-05-17 23:45:23 -04:00
Jeffrey Walton 83ee4e1fc0
Use test_arm_sha1.cxx for feature tests 2019-05-17 23:42:15 -04:00
Jeffrey Walton f027361369
Split test_arm_sha.cxx into SHA1 and SHA256 tests 2019-05-17 22:19:26 -04:00
Jeffrey Walton c51f0ecbfd
Make config.h more Autoconf friendly (GH #835, PR #836) 2019-05-17 15:18:17 -04:00
Jeffrey Walton b25b6f0892
Cleanup SIMON64 and SPECK64 flags in Makefile (GH #834) 2019-05-16 18:57:57 -04:00
Jeffrey Walton edc0952b25
Whitespace check-in 2019-05-16 02:47:44 -04:00
Jeffrey Walton ef3968f551
Guard x86 cache line size 2019-05-08 21:20:49 -04:00
Jeffrey Walton 72a71eb230
Use fallback in detecting ARM and PowerPC cache line size 2019-05-08 19:54:05 -04:00
Jeffrey Walton c91813c0b4
Use fallback in detecting VIA cach line size 2019-05-08 19:46:23 -04:00
Jeffrey Walton 40e5891635
Use CPU_QuerySHA256 for ARM 2019-05-08 19:31:31 -04:00
Jeffrey Walton 73bf2f29c0
Add "AMDisbetter!" cpuid detection 2019-05-08 18:51:12 -04:00
Jeffrey Walton 986fded372
Spelling 2019-05-08 18:33:55 -04:00
Jeffrey Walton d9aed27ad3
Add code for VIA L1 data cache line size 2019-05-08 18:29:33 -04:00
Jeffrey Walton 30fc56d58c
Clear alignment warnings on ARM 32-bit platforms 2019-05-01 12:54:25 -04:00
Jeffrey Walton 337d1c88c8
Use armv7l for machine of Clang triplet armv8l-unknown-linux-gnueabihf (GH #831)
Autotools uses armv7l. We should be safe using the same machine.
2019-05-01 11:00:34 -04:00
Jeffrey Walton a5fe6fa6da
Remove unneeded perm check in cryptest-autotools.sh 2019-05-01 10:45:11 -04:00
Jeffrey Walton 4acdcc46d0
Try workaround Clang triplet on ARMv7l (GH #831) 2019-05-01 01:48:00 -04:00
Jeffrey Walton 7ef3dacdc2
Remove C++11 constexpr code for CRYPTOPP_ALIGN_DATA (PR #830)
I don't have faith in it even though it has tested good so far.
2019-04-30 23:00:56 -04:00
Jeffrey Walton ff544c386c
Use dynamic_cast in ed25519 (GH #829) 2019-04-30 20:29:21 -04:00
Jeffrey Walton a379c5644a
Clear alignment warnings on ARM 32-bit platforms (#828) 2019-04-30 17:53:58 -04:00
Jeffrey Walton b9fe3a3415
Clear alignment warnings on ARM 32-bit platforms 2019-04-29 22:40:07 -04:00
Jeffrey Walton 6c60e2cd1d
Add conservative governor setting
This governor setting is showing up on dev-board 4.19 kernels
2019-04-29 18:21:50 -04:00
Jeffrey Walton a11ac1e879
Use ConstBytePtr in TestDataNameValuePairs (GH #827) 2019-04-29 00:13:32 -04:00
Jeffrey Walton 38a4bb55cf
Post-release version increment 2019-04-29 00:12:18 -04:00
Jeffrey Walton 9dcc26c582
Prepare for Crypto++ 8.2 release
Make ConstBytePtr return non-NULL pointer
2019-04-28 19:37:23 -04:00
Jeffrey Walton ec1aa8874c
Prepare for Crypto++ 8.2 release
Fix SHAKE-128 and SHAKE-256 tests
2019-04-28 19:09:45 -04:00
Jeffrey Walton 7ba4657375
Prepare for Crypto++ 8.2 release
Fix VS2010 compile on WIndows Vista; Add BytePtr inline function
2019-04-28 18:10:03 -04:00
Jeffrey Walton c9703ab5ea
Prepare for Crypto++ 8.2 release
Fix VS2010 compile on WIndows Vista
2019-04-28 17:27:09 -04:00
Jeffrey Walton a04014aa48
Prepare for Crypto++ 8.2 release
Fix Fedora 7 compile
2019-04-28 15:21:26 -04:00
Jeffrey Walton e705fa7fad
Prepare for Crypto++ 8.2 release 2019-04-28 12:47:07 -04:00
Jeffrey Walton 4e0c3ed837
Prepare for Crypto++ 8.2 release 2019-04-28 11:48:32 -04:00
Jeffrey Walton 9e22df09a1
Prepare for Crypto++ 8.2 release 2019-04-28 11:48:04 -04:00
Jeffrey Walton 68b4fc0d8b
Prepare for Crypto++ 8.2 release 2019-04-28 11:30:32 -04:00
Jeffrey Walton c9dc95a45c
Clear GCC multiline comment warning 2019-04-27 23:30:33 -04:00
Jeffrey Walton fd2fd0c199
Remove unneeded permutes
Loading byte arrays does not suffer the endian swaps.
2019-04-27 23:09:30 -04:00
Jeffrey Walton 90f52dd9ae
Regenerate cryptest.nmake list 2019-04-27 21:37:23 -04:00
Jeffrey Walton b16d37e347
Clear C4296 under MSVC++ (GH #821) 2019-04-27 21:21:56 -04:00
Jeffrey Walton 255a6f2aa0
Clear UBsan warning -Wstringop-overflow 2019-04-27 21:08:02 -04:00
Jeffrey Walton 39418a8512
Use PowerPC unaligned loads and stores with Power8 (GH #825, PR #826)
Use PowerPC unaligned loads and stores with Power8. Formerly we were using Power7 as the floor because the IBM POWER Architecture manuals said unaligned loads and stores were available. However, some compilers generate bad code for unaligned loads and stores using `-march=power7`, so bump to a known good.
2019-04-27 20:35:01 -04:00
Jeffrey Walton d451751eb2
Update SKIPJACK documentation (GH #824) 2019-04-27 14:40:53 -04:00
Jeffrey Walton cdaac6b844
Add SKIPJACK/CBC test vectors (GH #824)
Generated using Botan 1.11.17, https://github.com/noloader/cryptopp-test/tree/master/SKIPJACK
2019-04-27 14:21:48 -04:00
Jeffrey Walton d1b1554188
Add SKIPJACK test vectors from SP800-17, Table 6, pp. 140-42 (GH #824) 2019-04-27 13:24:54 -04:00
Jeffrey Walton e8107e9cb8
Update documentation
The library uses both PKCS #5 and PKCS #7 padding
2019-04-04 07:20:33 -04:00
Jeffrey Walton 9f8017a276
Fix missing GF2NT_233_Multiply_Reduce_CLMUL in the cursed DLL (GH #783)
This should have been checked-in during GH #783 and PR #784. I think there was one mailing list message about missing symbols GF2NT_233_Multiply_Reduce_CLMUL and GF2NT_233_Square_Reduce_CLMUL. I missed it when attempting to reproduce the issue. I can duplicate it now using VS2013. I think the addition of CRYPTOPP_DLL caused the issue to surface.
2019-03-21 08:13:14 -04:00
Jeffrey Walton fc3b16e3a3
Fix SHAKE compile error with old GCC (GH #818) 2019-03-18 08:06:48 -04:00
Jeffrey Walton 0d17eea82c
Add x25519 default constructor 2019-03-04 19:43:33 -05:00
Jeffrey Walton 08b9e21e5a
Use TCXXFLAGS for feature tests in GNUmakefile-cross
This mirrors PR #815, where we used CXXFLAGS instead of TCXXFLAGS for feature tests
2019-02-28 06:42:16 -05:00
Nicolas Chauvet (kwizart) 7c7a12c584 Use TCXXFLAGS instead of CXXFLAGS (#815)
As done with others tests. This will avoid a miss-detection of aarch64 features
when using flags such as _FORTIFY_SOURCE that needs to be filtered for testing

This fixes https://github.com/weidai11/cryptopp/issues/812

V2: Fix all cases

Signed-off-by: Nicolas Chauvet <kwizart@gmail.com>
2019-02-28 06:37:18 -05:00
Jeffrey Walton 84ab1f3c66
Remove early NEON qualification tests from Makefile (GH #812, GH #813)
The makefile tries to pre-qualify NEON (for lack of a better term), and sets IS_NEON accordingly. If IS_NEON=1, then we go on to perform test compiles to see if -mfloat-abi=X -mfpu=neon (and friends) actually work. Effectively we are performing a test to see if we should perform another test.

The IS_NEON flag predates our compile time feature tests. It was kind of helpful when we were trying to sort out if a platform and compiler options supported NEON without a compile test. That was an absolute mess and we quickly learned we needed a real compile time feature test (which we now have).

Additionally, Debian and Fedora ARMEL builds are failing because we are misdetecting NEON availability. It looks like we fail to set IS_NEON properly, so we never get into the code paths that set either (1) -mfloat-abi=X -mfpu=neon or (2) -DCRYPTOPP_DISABLE_NEON or -DCRYPTOPP_DISABLE_ASM. Later, the makefile builds a *_simd.cpp and the result is an error that NEON needs to be activated (or disabled).

This commit removes IS_NEON so we immediately move to compile time feature tests.
2019-02-27 19:35:04 -05:00
Jeffrey Walton 8624a91988
Spelling 2019-02-24 17:00:20 -05:00
Jeffrey Walton 3183970300
Add missing BLAKE2 constructors
BLAKE2b and BLAKE2s are both missing a constructor that takes only the digest size. Also see https://groups.google.com/d/msg/cryptopp-users/QCFGYw8q3Yo/vpBCqz-vBgAJ
2019-02-24 15:45:00 -05:00
Jeffrey Walton 758939ab2e
Fix missing BlockSize() in BLAKE2 classes (GH #811) 2019-02-23 14:13:31 -05:00
Jeffrey Walton 6138b8a127
Post-release version increment
Also see https://www.cryptopp.com/wiki/Release_Process#Increment_version_numbers
2019-02-23 14:03:49 -05:00
Jeffrey Walton 20e9e0cb10
Prepare for Crypto++ 8.1 release
This should have been checked in with 1c34979592. Too late now, but fix it anyway.
2019-02-23 13:57:40 -05:00
177 changed files with 15792 additions and 5692 deletions

View File

@ -41,7 +41,7 @@ PROJECT_NAME = Crypto++
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 8.1
PROJECT_NUMBER = 8.3
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View File

@ -66,6 +66,16 @@ channels.h
cmac.cpp
cmac.h
config.h
config_align.h
config_asm.h
config_cpu.h
config_cxx.h
config_dll.h
config_int.h
config_misc.h
config_ns.h
config_os.h
config_ver.h
cpu.cpp
cpu.h
crc.cpp
@ -269,6 +279,7 @@ rdrand.s
rdrand.asm
rdrand.cpp
rdrand.h
rdseed.asm
rdtables.cpp
regtest1.cpp
regtest2.cpp
@ -304,6 +315,12 @@ serpentp.h
sha.cpp
sha_simd.cpp
sha.h
sha1_armv4.h
sha1_armv4.S
sha256_armv4.h
sha256_armv4.S
sha512_armv4.h
sha512_armv4.S
sha3.cpp
sha3.h
shacal2.cpp
@ -421,6 +438,8 @@ TestData/dlie2048.dat
TestData/dsa1024.dat
TestData/dsa1024b.dat
TestData/dsa512.dat
TestData/ecies_p160.dat
TestData/ecies_t163.dat
TestData/ed25519.dat
TestData/ed25519_ver.dat
TestData/ed25519v0.dat
@ -542,6 +561,7 @@ TestVectors/shacal2.txt
TestVectors/simeck.txt
TestVectors/simon.txt
TestVectors/siphash.txt
TestVectors/skipjack.txt
TestVectors/sm3.txt
TestVectors/sm4.txt
TestVectors/sosemanuk.txt
@ -561,9 +581,10 @@ TestPrograms/test_arm_asimd.cxx
TestPrograms/test_arm_crc.cxx
TestPrograms/test_arm_neon.cxx
TestPrograms/test_arm_pmull.cxx
TestPrograms/test_arm_sha.cxx
TestPrograms/test_arm_sha3.cxx
TestPrograms/test_arm_sha1.cxx
TestPrograms/test_arm_sha256.cxx
TestPrograms/test_arm_sha512.cxx
TestPrograms/test_arm_sha3.cxx
TestPrograms/test_arm_sm3.cxx
TestPrograms/test_arm_sm4.cxx
TestPrograms/test_cxx.cxx
@ -583,6 +604,8 @@ TestPrograms/test_x86_avx2.cxx
TestPrograms/test_x86_avx512.cxx
TestPrograms/test_x86_clmul.cxx
TestPrograms/test_x86_cpuid.cxx
TestPrograms/test_x86_rdrand.cxx
TestPrograms/test_x86_rdseed.cxx
TestPrograms/test_x86_sha.cxx
TestPrograms/test_x86_sse2.cxx
TestPrograms/test_x86_sse3.cxx

View File

@ -10,12 +10,16 @@ SHELL = /bin/sh
# If needed
TMPDIR ?= /tmp
# Used for ARMv7 and NEON.
FP_ABI ?= hard
# Used for feature tests
TOUT ?= a.out
TOUT := $(strip $(TOUT))
# Allow override for the cryptest.exe recipe. Change to
# ./libcryptopp.so or ./libcryptopp.dylib to suit your
# taste. https://github.com/weidai11/cryptopp/issues/866
LINK_LIBRARY ?= libcryptopp.a
LINK_LIBRARY_PATH ?= ./
# Command and arguments
AR ?= ar
ARFLAGS ?= -cr # ar needs the dash on OpenBSD
@ -25,6 +29,7 @@ CP ?= cp
MV ?= mv
RM ?= rm -f
GREP ?= grep
SED ?= sed
CHMOD ?= chmod
MKDIR ?= mkdir -p
@ -35,11 +40,17 @@ LDCONF ?= /sbin/ldconfig -n
ifneq ($(wildcard /usr/xpg4/bin/grep),)
GREP := /usr/xpg4/bin/grep
endif
ifneq ($(wildcard /usr/xpg4/bin/sed),)
SED := /usr/xpg4/bin/sed
endif
# Attempt to determine target machine, fallback to "this" machine.
# The target machine is the one the package runs on. Most people
# call this the "target", but not Autotools.
HOSTX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null | cut -f 1 -d '-')
# Yet another Clang hack. I think the LLVM devs are making the shit up
# as they go. Also see https://github.com/weidai11/cryptopp/issues/831.
MACHINEX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null)
ifeq ($(MACHINEX),armv8l-unknown-linux-gnueabihf)
MACHINEX := armv7l-unknown-linux-gnueabihf
endif
HOSTX := $(shell echo $(MACHINEX) | cut -f 1 -d '-')
ifeq ($(HOSTX),)
HOSTX := $(shell uname -m 2>/dev/null)
endif
@ -53,8 +64,6 @@ IS_SPARC64 := $(shell echo "$(HOSTX)" | $(GREP) -i -c -E 'sun|sparc64')
IS_ARM32 := $(shell echo "$(HOSTX)" | $(GREP) -i -c -E 'arm|armhf|arm7l|eabihf')
IS_ARMV8 := $(shell echo "$(HOSTX)" | $(GREP) -i -c -E 'aarch32|aarch64|arm64|armv8')
IS_NEON := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null | $(GREP) -i -c -E 'armv7|armhf|arm7l|eabihf|armv8|aarch32|aarch64')
# Attempt to determine platform
SYSTEMX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null)
ifeq ($(SYSTEMX),)
@ -116,9 +125,10 @@ else ifeq ($(findstring distclean,$(MAKECMDGOALS)),trim)
DETECT_FEATURES := 0
endif
# Strip out -Wall, -Wextra and friends for feature testing
# Strip out -Wall, -Wextra and friends for feature testing. FORTIFY_SOURCE is removed
# because it requires -O1 or higher, but we use -O0 to tame the optimizer.
ifeq ($(DETECT_FEATURES),1)
TCXXFLAGS := $(filter-out -Wall -Wextra -Werror% -Wunused -Wconversion -Wp%, $(CXXFLAGS))
TCXXFLAGS := $(filter-out -D_FORTIFY_SOURCE=% -Wall -Wextra -Werror% -Wunused -Wconversion -Wp%, $(CXXFLAGS))
ifneq ($(strip $(TCXXFLAGS)),)
$(info Using testing flags: $(TCXXFLAGS))
endif
@ -161,6 +171,11 @@ else
ZOPT = -O0
endif
# Fix CXX on Cygwin 1.1.4
ifeq ($(CXX),gcc)
CXX := g++
endif
# On ARM we may compile aes_armv4.S though the CC compiler
ifeq ($(GCC_COMPILER),1)
CC=gcc
@ -187,19 +202,11 @@ ifeq ($(INCLUDEDIR),)
INCLUDEDIR := $(PREFIX)/include
endif
# Fix CXX on Cygwin 1.1.4
ifeq ($(CXX),gcc)
CXX := g++
endif
# We honor ARFLAGS, but the "v" option used by default causes a noisy make
ifeq ($(ARFLAGS),rv)
ARFLAGS = r
endif
# Clang integrated assembler will be used with -Wa,-q
CLANG_INTEGRATED_ASSEMBLER ?= 0
# Original MinGW targets Win2k by default, but lacks proper Win2k support
# if target Windows version is not specified, use Windows XP instead
ifeq ($(IS_MINGW),1)
@ -273,9 +280,7 @@ ifeq ($(DETECT_FEATURES),1)
KECCAK_FLAG = $(SSSE3_FLAG)
LEA_FLAG = $(SSSE3_FLAG)
SIMECK_FLAG = $(SSSE3_FLAG)
SIMON64_FLAG = $(SSSE3_FLAG)
SIMON128_FLAG = $(SSSE3_FLAG)
SPECK64_FLAG = $(SSSE3_FLAG)
SPECK128_FLAG = $(SSSE3_FLAG)
SUN_LDFLAGS += $(SSSE3_FLAG)
else
@ -439,37 +444,37 @@ endif
##### ARM A-32, Aach64 and NEON #####
###########################################################
ifneq ($(IS_ARM32)$(IS_ARMV8)$(IS_NEON),000)
ifneq ($(IS_ARM32)$(IS_ARMV8),00)
ifeq ($(DETECT_FEATURES),1)
ifeq ($(IS_ARM32)$(IS_NEON),11)
ifneq ($(IS_ARM32),0)
TPROG = TestPrograms/test_arm_neon.cxx
TOPT = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
TOPT = -march=armv7-a -mfpu=neon
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
NEON_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
ARIA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
AES_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
CRC_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
GCM_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
BLAKE2B_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
BLAKE2S_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
CHACHA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
CHAM_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
LEA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SHA_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SIMECK_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SIMON64_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SIMON128_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SPECK64_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SPECK128_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
SM4_FLAG = -march=armv7-a -mfloat-abi=$(FP_ABI) -mfpu=neon
NEON_FLAG = -march=armv7-a -mfpu=neon
ARIA_FLAG = -march=armv7-a -mfpu=neon
AES_FLAG = -march=armv7-a -mfpu=neon
CRC_FLAG = -march=armv7-a -mfpu=neon
GCM_FLAG = -march=armv7-a -mfpu=neon
BLAKE2B_FLAG = -march=armv7-a -mfpu=neon
BLAKE2S_FLAG = -march=armv7-a -mfpu=neon
CHACHA_FLAG = -march=armv7-a -mfpu=neon
CHAM_FLAG = -march=armv7-a -mfpu=neon
LEA_FLAG = -march=armv7-a -mfpu=neon
SHA_FLAG = -march=armv7-a -mfpu=neon
SIMECK_FLAG = -march=armv7-a -mfpu=neon
SIMON64_FLAG = -march=armv7-a -mfpu=neon
SIMON128_FLAG = -march=armv7-a -mfpu=neon
SPECK64_FLAG = -march=armv7-a -mfpu=neon
SPECK128_FLAG = -march=armv7-a -mfpu=neon
SM4_FLAG = -march=armv7-a -mfpu=neon
else
CXXFLAGS += -DCRYPTOPP_DISABLE_ASM
endif
# IS_NEON
# IS_ARM32
endif
ifeq ($(IS_ARMV8),1)
@ -485,7 +490,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_asimd.cxx
TOPT = -march=armv8-a
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
ASIMD_FLAG = -march=armv8-a
ARIA_FLAG = -march=armv8-a
@ -508,7 +513,7 @@ ifeq ($(IS_ARMV8),1)
ifneq ($(ASIMD_FLAG),)
TPROG = TestPrograms/test_arm_crc.cxx
TOPT = -march=armv8-a+crc
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
CRC_FLAG = -march=armv8-a+crc
else
@ -517,7 +522,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_aes.cxx
TOPT = -march=armv8-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
AES_FLAG = -march=armv8-a+crypto
else
@ -526,7 +531,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_pmull.cxx
TOPT = -march=armv8-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
GCM_FLAG = -march=armv8-a+crypto
GF2N_FLAG = -march=armv8-a+crypto
@ -534,9 +539,9 @@ ifeq ($(IS_ARMV8),1)
CXXFLAGS += -DCRYPTOPP_ARM_PMULL_AVAILABLE=0
endif
TPROG = TestPrograms/test_arm_sha.cxx
TPROG = TestPrograms/test_arm_sha1.cxx
TOPT = -march=armv8-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
SHA_FLAG = -march=armv8-a+crypto
else
@ -545,7 +550,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_sm3.cxx
TOPT = -march=armv8.4-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
SM3_FLAG = -march=armv8.4-a+crypto
SM4_FLAG = -march=armv8.4-a+crypto
@ -553,7 +558,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_sha3.cxx
TOPT = -march=armv8.4-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
SHA3_FLAG = -march=armv8.4-a+crypto
endif
@ -567,7 +572,7 @@ endif
# DETECT_FEATURES
endif
# IS_ARM32, IS_ARMV8, IS_NEON
# IS_ARM32, IS_ARMV8
endif
###########################################################
@ -622,13 +627,21 @@ ifeq ($(DETECT_FEATURES),1)
TOPT = $(POWER8_FLAG)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
AES_FLAG = $(POWER8_FLAG)
ARIA_FLAG = $(POWER8_FLAG)
BLAKE2B_FLAG = $(POWER8_FLAG)
BLAKE2S_FLAG = $(POWER8_FLAG)
CHACHA_FLAG = $(POWER8_FLAG)
CHAM_FLAG = $(POWER8_FLAG)
CRC_FLAG = $(POWER8_FLAG)
GCM_FLAG = $(POWER8_FLAG)
GF2N_FLAG = $(POWER8_FLAG)
AES_FLAG = $(POWER8_FLAG)
LEA_FLAG = $(POWER8_FLAG)
SHA_FLAG = $(POWER8_FLAG)
SHACAL2_FLAG = $(POWER8_FLAG)
SIMECK_FLAG = $(POWER8_FLAG)
SIMON64_FLAG = $(POWER8_FLAG)
SPECK64_FLAG = $(POWER8_FLAG)
SIMON128_FLAG = $(POWER8_FLAG)
SPECK128_FLAG = $(POWER8_FLAG)
else
@ -641,16 +654,7 @@ ifeq ($(DETECT_FEATURES),1)
TPROG = TestPrograms/test_ppc_power7.cxx
TOPT = $(POWER7_FLAG)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
ARIA_FLAG = $(POWER7_FLAG)
BLAKE2S_FLAG = $(POWER7_FLAG)
CHACHA_FLAG = $(POWER7_FLAG)
CHAM_FLAG = $(POWER7_FLAG)
LEA_FLAG = $(POWER7_FLAG)
SIMECK_FLAG = $(POWER7_FLAG)
SIMON64_FLAG = $(POWER7_FLAG)
SPECK64_FLAG = $(POWER7_FLAG)
else
ifneq ($(strip $(HAVE_OPT)),0)
POWER7_FLAG =
endif
@ -693,18 +697,12 @@ ifeq ($(DETECT_FEATURES),1)
#####################################################################
# Fixups for algorithms that can drop to a lower ISA, if needed
# Drop to Power7 if Power8 is not available.
# Drop to Power4 if Power8 not available
ifeq ($(POWER8_FLAG),)
ifneq ($(POWER7_FLAG),)
GCM_FLAG = $(POWER7_FLAG)
endif
endif
# Drop to Power4 if Power7 not available
ifeq ($(POWER7_FLAG),)
ifneq ($(ALTIVEC_FLAG),)
BLAKE2S_FLAG = $(ALTIVEC_FLAG)
CHACHA_FLAG = $(ALTIVEC_FLAG)
GCM_FLAG = $(ALTIVEC_FLAG)
SIMON64_FLAG = $(ALTIVEC_FLAG)
SPECK64_FLAG = $(ALTIVEC_FLAG)
endif
@ -869,6 +867,15 @@ ifeq ($(findstring native,$(MAKECMDGOALS)),native)
NATIVE_OPT = -march=native
endif # NATIVE_OPT
# And tune
ifeq ($(NATIVE_OPT),)
TOPT = -mtune=native
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
NATIVE_OPT = -mtune=native
endif # NATIVE_OPT
endif
# Try SunCC next
ifeq ($(NATIVE_OPT),)
TOPT = -native
@ -956,9 +963,9 @@ ifneq ($(filter valgrind,$(MAKECMDGOALS)),)
CXXFLAGS := $(CXXFLAGS:-g%=-g3)
CXXFLAGS := $(CXXFLAGS:-O%=-O1)
CXXFLAGS := $(CXXFLAGS:-xO%=-xO1)
ifeq ($(findstring -DCRYPTOPP_VALGRIND,$(CXXFLAGS)),)
CXXFLAGS += -DCRYPTOPP_VALGRIND
endif # -DCRYPTOPP_VALGRIND
ifeq ($(findstring -DCRYPTOPP_COVERAGE,$(CXXFLAGS)),)
CXXFLAGS += -DCRYPTOPP_COVERAGE
endif # -DCRYPTOPP_COVERAGE
endif # Valgrind
# Debug testing on GNU systems. Triggered by -DDEBUG.
@ -1004,7 +1011,7 @@ ifeq ($(findstring lean,$(MAKECMDGOALS)),lean)
endif # Dead code stripping
# For Shared Objects, Diff, Dist/Zip rules
LIB_VER := $(shell $(GREP) "define CRYPTOPP_VERSION" config.h | cut -d" " -f 3)
LIB_VER := $(shell $(GREP) "define CRYPTOPP_VERSION" config_ver.h | cut -d" " -f 3)
LIB_MAJOR := $(shell echo $(LIB_VER) | cut -c 1)
LIB_MINOR := $(shell echo $(LIB_VER) | cut -c 2)
LIB_PATCH := $(shell echo $(LIB_VER) | cut -c 3)
@ -1061,12 +1068,18 @@ ifneq ($(IS_MINGW),0)
INCL += resource.h
endif
# Cryptogams AES for ARMv4 and above. We couple to ARMv7.
# Avoid iOS. It cannot consume the assembly.
ifeq ($(IS_ARM32),1)
CRYPTOGAMS_AES_FLAG = -march=armv7-a
CRYPTOGAMS_AES_FLAG += -Wa,--noexecstack
SRCS += aes_armv4.S
# Cryptogams source files. We couple to ARMv7.
# Limit to Linux. The source files target the GNU assembler.
# Also see https://www.cryptopp.com/wiki/Cryptogams.
ifeq ($(IS_ARM32)$(IS_LINUX),11)
ifeq ($(CLANG_COMPILER),1)
CRYPTOGAMS_ARMV7_FLAG = -march=armv7-a -Wa,--noexecstack
CRYPTOGAMS_ARMV7_THUMB_FLAG = -march=armv7-a -mthumb -Wa,--noexecstack
else
CRYPTOGAMS_ARMV7_FLAG = -march=armv7-a -Wa,--noexecstack
CRYPTOGAMS_ARMV7_THUMB_FLAG = -march=armv7-a -Wa,--noexecstack
endif
SRCS += aes_armv4.S sha1_armv4.S sha256_armv4.S sha512_armv4.S
endif
# List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems.
@ -1281,10 +1294,14 @@ remove uninstall:
-$(RM) -r $(DESTDIR)$(INCLUDEDIR)/cryptopp
-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.a
-$(RM) $(DESTDIR)$(BINDIR)/cryptest.exe
@-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.dylib
ifneq ($(wildcard $(DESTDIR)$(LIBDIR)/libcryptopp.dylib),)
-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.dylib
endif
ifneq ($(wildcard $(DESTDIR)$(LIBDIR)/libcryptopp.so),)
-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so
endif
@-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so$(SOLIB_VERSION_SUFFIX)
@-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so$(SOLIB_COMPAT_SUFFIX)
@-$(RM) $(DESTDIR)$(LIBDIR)/libcryptopp.so
@-$(RM) $(DESTDIR)$(LIBDIR)/pkgconfig/libcryptopp.pc
@-$(RM) -r $(DESTDIR)$(DATADIR)/cryptopp
@ -1313,8 +1330,8 @@ endif
libcryptopp.dylib: $(LIBOBJS)
$(CXX) -dynamiclib -o $@ $(strip $(CXXFLAGS)) -install_name "$@" -current_version "$(LIB_MAJOR).$(LIB_MINOR).$(LIB_PATCH)" -compatibility_version "$(LIB_MAJOR).$(LIB_MINOR)" -headerpad_max_install_names $(LDFLAGS) $(LIBOBJS)
cryptest.exe:libcryptopp.a $(TESTOBJS)
$(CXX) -o $@ $(strip $(CXXFLAGS)) $(TESTOBJS) ./libcryptopp.a $(LDFLAGS) $(LDLIBS)
cryptest.exe: $(LINK_LIBRARY) $(TESTOBJS)
$(CXX) -o $@ $(strip $(CXXFLAGS)) $(TESTOBJS) $(LINK_LIBRARY_PATH)$(LINK_LIBRARY) $(LDFLAGS) $(LDLIBS)
# Makes it faster to test changes
nolib: $(OBJS)
@ -1349,7 +1366,7 @@ libcryptopp.pc:
@echo '' >> libcryptopp.pc
@echo 'Name: Crypto++' >> libcryptopp.pc
@echo 'Description: Crypto++ cryptographic library' >> libcryptopp.pc
@echo 'Version: 8.1' >> libcryptopp.pc
@echo 'Version: 8.3' >> libcryptopp.pc
@echo 'URL: https://cryptopp.com/' >> libcryptopp.pc
@echo '' >> libcryptopp.pc
@echo 'Cflags: -I$${includedir}' >> libcryptopp.pc
@ -1366,14 +1383,14 @@ endif
.PHONY: trim
trim:
ifneq ($(IS_DARWIN),0)
sed -i '' -e's/[[:space:]]*$$//' *.supp *.txt *.sh .*.yml *.h *.cpp *.asm *.s *.S
sed -i '' -e's/[[:space:]]*$$//' *.sln *.vcxproj *.filters GNUmakefile GNUmakefile-cross
sed -i '' -e's/[[:space:]]*$$//' TestData/*.dat TestVectors/*.txt TestPrograms/*.cxx TestScripts/*.*
$(SED) -i '' -e's/[[:space:]]*$$//' *.supp *.txt *.sh .*.yml *.h *.cpp *.asm *.s *.S
$(SED) -i '' -e's/[[:space:]]*$$//' *.sln *.vcxproj *.filters GNUmakefile GNUmakefile-cross
$(SED) -i '' -e's/[[:space:]]*$$//' TestData/*.dat TestVectors/*.txt TestPrograms/*.cxx TestScripts/*.*
make convert
else
sed -i -e's/[[:space:]]*$$//' *.supp *.txt *.sh .*.yml *.h *.cpp *.asm *.s *.S
sed -i -e's/[[:space:]]*$$//' *.sln *.vcxproj *.filters GNUmakefile GNUmakefile-cross
sed -i -e's/[[:space:]]*$$//' TestData/*.dat TestVectors/*.txt TestPrograms/*.cxx TestScripts/*.*
$(SED) -i -e's/[[:space:]]*$$//' *.supp *.txt *.sh .*.yml *.h *.cpp *.asm *.s *.S
$(SED) -i -e's/[[:space:]]*$$//' *.sln *.vcxproj *.filters GNUmakefile GNUmakefile-cross
$(SED) -i -e's/[[:space:]]*$$//' TestData/*.dat TestVectors/*.txt TestPrograms/*.cxx TestScripts/*.*
make convert
endif
@ -1428,9 +1445,9 @@ ifeq ($(wildcard GNUmakefile.deps),GNUmakefile.deps)
-include GNUmakefile.deps
endif # Dependencies
# Cryptogams ARM asm implementation.
# Cryptogams ARM asm implementation. AES needs -mthumb for Clang
aes_armv4.o : aes_armv4.S
$(CC) $(strip $(CXXFLAGS) $(CRYPTOGAMS_AES_FLAG) -mfloat-abi=$(FP_ABI) -c) $<
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_THUMB_FLAG) -c) $<
# SSSE3 or NEON available
aria_simd.o : aria_simd.cpp
@ -1512,6 +1529,18 @@ rijndael_simd.o : rijndael_simd.cpp
sha_simd.o : sha_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SHA_FLAG) -c) $<
# Cryptogams SHA1 asm implementation.
sha1_armv4.o : sha1_armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_FLAG) -c) $<
# Cryptogams SHA256 asm implementation.
sha256_armv4.o : sha256_armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_FLAG) -c) $<
# Cryptogams SHA512 asm implementation.
sha512_armv4.o : sha512_armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_FLAG) -c) $<
sha3_simd.o : sha3_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SHA3_FLAG) -c) $<

View File

@ -11,6 +11,12 @@ FP_ABI ?= hard
TOUT ?= a.out
TOUT := $(strip $(TOUT))
# Allow override for the cryptest.exe recipe. Change to
# ./libcryptopp.so or ./libcryptopp.dylib to suit your
# taste. https://github.com/weidai11/cryptopp/issues/866
LINK_LIBRARY ?= ./libcryptopp.a
LINK_LIBRARY_PATH ?= ./
# Default CXXFLAGS if none were provided
CXXFLAGS ?= -DNDEBUG -g2 -O3 -fPIC -pipe
@ -21,7 +27,8 @@ CP ?= cp
MV ?= mv
CHMOD ?= chmod
MKDIR ?= mkdir -p
EGREP ?= egrep
GREP ?= grep
SED ?= sed
LN ?= ln -sf
LDCONF ?= /sbin/ldconfig -n
@ -31,6 +38,19 @@ IS_ANDROID ?= 0
IS_ARM_EMBEDDED ?= 0
IS_NEON ?= 0
# Yet another Clang hack. I think the LLVM devs are making the shit up
# as they go. Also see https://github.com/weidai11/cryptopp/issues/831.
MACHINEX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null)
ifeq ($(MACHINEX),armv8l-unknown-linux-gnueabihf)
MACHINEX := armv7l-unknown-linux-gnueabihf
endif
HOSTX := $(shell echo $(MACHINEX) | cut -f 1 -d '-')
ifeq ($(HOSTX),)
HOSTX := $(shell uname -m 2>/dev/null)
endif
IS_LINUX := $(shell echo $(MACHINEX) | $(GREP) -i -c "Linux")
# Can be used by Android and Embeeded cross-compiles. Disable by default because
# Android and embedded users typically don't run this configuration.
HAS_SOLIB_VERSION ?= 0
@ -136,8 +156,8 @@ endif
# Wait until CXXFLAGS have been set by setenv scripts.
GCC_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(EGREP) -v -E 'llvm|clang' | $(EGREP) -i -c -E '(gcc|g\+\+)')
CLANG_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(EGREP) -i -c -E 'llvm|clang')
GCC_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(GREP) -v -E 'llvm|clang' | $(GREP) -i -c -E '(gcc|g\+\+)')
CLANG_COMPILER := $(shell $(CXX) --version 2>/dev/null | $(GREP) -i -c -E 'llvm|clang')
HOSTX := $(shell $(CXX) $(CXXFLAGS) -dumpmachine 2>/dev/null | cut -f 1 -d '-')
ifeq ($(HOSTX),)
@ -149,15 +169,15 @@ endif
# -arch arm64 yields x86_64 instead of aarch64 or arm64.
ifeq ($(CLANG_COMPILER),1)
IS_X86 := $(shell echo $(CXXFLAGS) | $(EGREP) -v 64 | $(EGREP) -i -c -E 'i.86')
IS_X64 := $(shell echo $(CXXFLAGS) | $(EGREP) -i -c -E 'x86_64|amd64')
IS_ARM32 := $(shell echo $(CXXFLAGS) | $(EGREP) -v 64 | $(EGREP) -i -c -E 'arm|armhf|arm7l|eabihf')
IS_ARMV8 := $(shell echo $(CXXFLAGS) | $(EGREP) -i -c -E 'aarch32|aarch64|arm64|armv8')
IS_X86 := $(shell echo $(CXXFLAGS) | $(GREP) -v 64 | $(GREP) -i -c -E 'i.86')
IS_X64 := $(shell echo $(CXXFLAGS) | $(GREP) -i -c -E 'x86_64|amd64')
IS_ARM32 := $(shell echo $(CXXFLAGS) | $(GREP) -v 64 | $(GREP) -i -c -E 'arm|armhf|arm7l|eabihf')
IS_ARMV8 := $(shell echo $(CXXFLAGS) | $(GREP) -i -c -E 'aarch32|aarch64|arm64|armv8')
else
IS_X86 := $(shell echo $(HOSTX) | $(EGREP) -v 64 | $(EGREP) -i -c -E 'i.86')
IS_X64 := $(shell echo $(HOSTX) | $(EGREP) -i -c -E 'x86_64|amd64')
IS_ARM32 := $(shell echo $(HOSTX) | $(EGREP) -v 64 | $(EGREP) -i -c -E 'arm|armhf|arm7l|eabihf')
IS_ARMV8 := $(shell echo $(HOSTX) | $(EGREP) -i -c -E 'aarch32|aarch64|arm64|armv8')
IS_X86 := $(shell echo $(HOSTX) | $(GREP) -v 64 | $(GREP) -i -c -E 'i.86')
IS_X64 := $(shell echo $(HOSTX) | $(GREP) -i -c -E 'x86_64|amd64')
IS_ARM32 := $(shell echo $(HOSTX) | $(GREP) -v 64 | $(GREP) -i -c -E 'arm|armhf|arm7l|eabihf')
IS_ARMV8 := $(shell echo $(HOSTX) | $(GREP) -i -c -E 'aarch32|aarch64|arm64|armv8')
endif
$(info Here's what we found... IS_X86: $(IS_X86), IS_X64: $(IS_X64), IS_ARM32: $(IS_ARM32), IS_ARMV8: $(IS_ARMV8))
@ -178,9 +198,10 @@ else ifeq ($(findstring distclean,$(MAKECMDGOALS)),trim)
DETECT_FEATURES := 0
endif
# Strip out -Wall, -Wextra and friends for feature testing
# Strip out -Wall, -Wextra and friends for feature testing. FORTIFY_SOURCE is removed
# because it requires -O1 or higher, but we use -O0 to tame the optimizer.
ifeq ($(DETECT_FEATURES),1)
TCXXFLAGS := $(filter-out -Wall -Wextra -Werror% -Wunused -Wconversion -Wp%, $(CXXFLAGS))
TCXXFLAGS := $(filter-out -D_FORTIFY_SOURCE=% -Wall -Wextra -Werror% -Wunused -Wconversion -Wp%, $(CXXFLAGS))
ifneq ($(strip $(TCXXFLAGS)),)
$(info Using testing flags: $(TCXXFLAGS))
endif
@ -227,9 +248,7 @@ ifeq ($(DETECT_FEATURES),1)
CHAM_FLAG = $(SSSE3_FLAG)
LEA_FLAG = $(SSSE3_FLAG)
SIMECK_FLAG = $(SSSE3_FLAG)
SIMON64_FLAG = $(SSSE3_FLAG)
SIMON128_FLAG = $(SSSE3_FLAG)
SPECK64_FLAG = $(SSSE3_FLAG)
SPECK128_FLAG = $(SSSE3_FLAG)
else
SSSE3_FLAG =
@ -384,10 +403,10 @@ ifeq ($(IS_ARM32),1)
SM4_FLAG = $(NEON_FLAG)
else
NEON_FLAG =
CXXFLAGS += -DCRYPTOPP_DISABLE_NEON
CXXFLAGS += -DCRYPTOPP_DISABLE_ASM
endif
# IS_NEON
# IS_ARM32
endif
ifeq ($(IS_ARMV8),1)
@ -417,7 +436,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_asimd.cxx
TOPT = $(ASIMD_FLAG)
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
ARIA_FLAG = $(ASIMD_FLAG)
BLAKE2B_FLAG = $(ASIMD_FLAG)
@ -439,7 +458,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_crc.cxx
TOPT = $(CRC_FLAG)
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifneq ($(strip $(HAVE_OPT)),0)
CRC_FLAG =
CXXFLAGS += -DCRYPTOPP_ARM_CRC32_AVAILABLE=0
@ -447,7 +466,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_aes.cxx
TOPT = $(AES_FLAG)
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifneq ($(strip $(HAVE_OPT)),0)
AES_FLAG =
CXXFLAGS += -DCRYPTOPP_ARM_AES_AVAILABLE=0
@ -455,15 +474,15 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_pmull.cxx
TOPT = $(PMULL_FLAG)
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifneq ($(strip $(HAVE_OPT)),0)
PMULL_FLAG =
CXXFLAGS += -DCRYPTOPP_ARM_PMULL_AVAILABLE=0
endif
TPROG = TestPrograms/test_arm_sha.cxx
TPROG = TestPrograms/test_arm_sha1.cxx
TOPT = $(SHA_FLAG)
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifneq ($(strip $(HAVE_OPT)),0)
SHA_FLAG =
CXXFLAGS += -DCRYPTOPP_ARM_SHA_AVAILABLE=0
@ -471,7 +490,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_sm3.cxx
TOPT = -march=armv8.4-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
SM3_FLAG = -march=armv8.4-a+crypto
SM4_FLAG = -march=armv8.4-a+crypto
@ -479,7 +498,7 @@ ifeq ($(IS_ARMV8),1)
TPROG = TestPrograms/test_arm_sha3.cxx
TOPT = -march=armv8.4-a+crypto
HAVE_OPT = $(shell $(CXX) $(CXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
HAVE_OPT = $(shell $(CXX) $(TCXXFLAGS) $(ACLE_FLAG) $(ZOPT) $(TOPT) $(TPROG) -o $(TOUT) 2>&1 | tr ' ' '\n' | wc -l)
ifeq ($(strip $(HAVE_OPT)),0)
SHA3_FLAG = -march=armv8.4-a+crypto
SHA512_FLAG = -march=armv8.4-a+crypto
@ -531,7 +550,7 @@ endif # Asan
# LD gold linker testing. Triggered by 'LD=ld.gold'.
ifeq ($(findstring ld.gold,$(LD)),ld.gold)
ifeq ($(findstring -fuse-ld=gold,$(CXXFLAGS)),)
ELF_FORMAT := $(shell file `which ld.gold` 2>&1 | cut -d":" -f 2 | $(EGREP) -i -c "elf")
ELF_FORMAT := $(shell file `which ld.gold` 2>&1 | cut -d":" -f 2 | $(GREP) -i -c "elf")
ifneq ($(ELF_FORMAT),0)
LDFLAGS += -fuse-ld=gold
endif # ELF/ELF64
@ -544,15 +563,15 @@ ifneq ($(filter valgrind,$(MAKECMDGOALS)),)
CXXFLAGS := $(CXXFLAGS:-g%=-g3)
CXXFLAGS := $(CXXFLAGS:-O%=-O1)
CXXFLAGS := $(CXXFLAGS:-xO%=-xO1)
ifeq ($(findstring -DCRYPTOPP_VALGRIND,$(CXXFLAGS)),)
CXXFLAGS += -DCRYPTOPP_VALGRIND
endif # -DCRYPTOPP_VALGRIND
ifeq ($(findstring -DCRYPTOPP_COVERAGE,$(CXXFLAGS)),)
CXXFLAGS += -DCRYPTOPP_COVERAGE
endif # -DCRYPTOPP_COVERAGE
endif # Valgrind
# Debug testing on GNU systems. Triggered by -DDEBUG.
# Newlib test due to http://sourceware.org/bugzilla/show_bug.cgi?id=20268
ifneq ($(filter -DDEBUG -DDEBUG=1,$(CXXFLAGS)),)
USING_GLIBCXX := $(shell $(CXX) $(CXXFLAGS) -E pch.cpp 2>&1 | $(EGREP) -i -c "__GLIBCXX__")
USING_GLIBCXX := $(shell $(CXX) $(CXXFLAGS) -E pch.cpp 2>&1 | $(GREP) -i -c "__GLIBCXX__")
ifneq ($(USING_GLIBCXX),0)
ifeq ($(HAS_NEWLIB),0)
ifeq ($(findstring -D_GLIBCXX_DEBUG,$(CXXFLAGS)),)
@ -590,14 +609,18 @@ SRCS := cryptlib.cpp cpu.cpp integer.cpp $(filter-out cryptlib.cpp cpu.cpp integ
# For Makefile.am; resource.h is Windows
INCL := $(filter-out resource.h,$(sort $(wildcard *.h)))
# Cryptogams AES for ARMv4 and above. We couple to ARMv7.
# Avoid iOS. It cannot consume the assembly.
ifeq ($(IS_ARM32),1)
ifneq ($(IS_IOS),1)
CRYPTOGAMS_AES_FLAG = -march=armv7-a
CRYPTOGAMS_AES_FLAG += -Wa,--noexecstack
SRCS += aes_armv4.S
# Cryptogams source files. We couple to ARMv7.
# Limit to Linux. The source files target the GNU assembler.
# Also see https://www.cryptopp.com/wiki/Cryptogams.
ifeq ($(IS_ARM32)$(IS_LINUX),11)
ifeq ($(CLANG_COMPILER),1)
CRYPTOGAMS_ARMV7_FLAG = -march=armv7-a -Wa,--noexecstack
CRYPTOGAMS_ARMV7_THUMB_FLAG = -march=armv7-a -mthumb -Wa,--noexecstack
else
CRYPTOGAMS_ARMV7_FLAG = -march=armv7-a -Wa,--noexecstack
CRYPTOGAMS_ARMV7_THUMB_FLAG = -march=armv7-a -Wa,--noexecstack
endif
SRCS += aes_armv4.S sha1_armv4.S sha256_armv4.S sha512_armv4.S
endif
# List cryptlib.cpp first, then cpu.cpp, then integer.cpp to tame C++ static initialization problems.
@ -613,7 +636,7 @@ TESTOBJS := $(TESTSRCS:.cpp=.o)
LIBOBJS := $(filter-out $(TESTOBJS),$(OBJS))
# For Shared Objects, Diff, Dist/Zip rules
LIB_VER := $(shell $(EGREP) "define CRYPTOPP_VERSION" config.h | cut -d" " -f 3)
LIB_VER := $(shell $(GREP) "define CRYPTOPP_VERSION" config_ver.h | cut -d" " -f 3)
LIB_MAJOR := $(shell echo $(LIB_VER) | cut -c 1)
LIB_MINOR := $(shell echo $(LIB_VER) | cut -c 2)
LIB_PATCH := $(shell echo $(LIB_VER) | cut -c 3)
@ -770,8 +793,8 @@ endif
libcryptopp.dylib: $(LIBOBJS) $(AOSP_CPU_OBJ)
$(CXX) -dynamiclib -o $@ $(strip $(CXXFLAGS)) -install_name "$@" -current_version "$(LIB_MAJOR).$(LIB_MINOR).$(LIB_PATCH)" -compatibility_version "$(LIB_MAJOR).$(LIB_MINOR)" -headerpad_max_install_names $(LDFLAGS) $(LIBOBJS) $(AOSP_CPU_OBJ)
cryptest.exe: libcryptopp.a $(TESTOBJS)
$(CXX) -o $@ $(strip $(CXXFLAGS)) $(TESTOBJS) ./libcryptopp.a $(LDFLAGS) $(LDLIBS)
cryptest.exe: $(LINK_LIBRARY) $(TESTOBJS)
$(CXX) -o $@ $(strip $(CXXFLAGS)) $(TESTOBJS) $(LINK_LIBRARY_PATH)$(LINK_LIBRARY) $(LDFLAGS) $(LDLIBS)
# Used to generate list of source files for Autotools, CMakeList and Android.mk
.PHONY: sources
@ -800,9 +823,9 @@ ifeq ($(wildcard GNUmakefile.deps),GNUmakefile.deps)
-include GNUmakefile.deps
endif # Dependencies
# Cryptogams ARM asm implementation.
# Cryptogams ARM asm implementation. AES needs -mthumb for Clang
aes_armv4.o : aes_armv4.S
$(CXX) $(strip $(CXXFLAGS) -fpermissive $(CRYPTOGAMS_AES_FLAG) -c) $<
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_THUMB_FLAG) -c) $<
cpu-features.o: cpu-features.h cpu-features.c
$(CXX) $(strip $(CXXFLAGS) -fpermissive -c) cpu-features.c
@ -867,6 +890,18 @@ rijndael_simd.o : rijndael_simd.cpp
sha_simd.o : sha_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SHA_FLAG) -c) $<
# Cryptogams SHA1 asm implementation.
sha1_armv4.o : sha1_armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_FLAG) -c) $<
# Cryptogams SHA256 asm implementation.
sha256_armv4.o : sha256_armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_FLAG) -c) $<
# Cryptogams SHA512 asm implementation.
sha512_armv4.o : sha512_armv4.S
$(CXX) $(strip $(CXXFLAGS) $(CRYPTOGAMS_ARMV7_FLAG) -c) $<
# SSE4.2/SHA-NI or ARMv8a available
shacal2_simd.o : shacal2_simd.cpp
$(CXX) $(strip $(CXXFLAGS) $(SHA_FLAG) -c) $<

View File

@ -455,10 +455,10 @@ last several releases.
8.1.0 - February 22, 2019
- minor release, no recompile of programs required
- expanded community input and support
56 unique contributors as of this release
* 56 unique contributors as of this release
- fix OS X PowerPC builds with Clang
- add Microsoft ARM64 support
- fix iPhone Simulator build due to missign symbols
- fix iPhone Simulator build due to missing symbols
- add CRYPTOPP_BUGGY_SIMD_LOAD_AND_STORE
- add carryless multiplies for NIST b233 and k233 curves
- fix OpenMP build due to use of OpenMP 4 with down-level compilers
@ -467,3 +467,16 @@ last several releases.
- add SHAKE-128 and SHAKE-256
- fix AVX2 build due to _mm256_broadcastsi128_si256
- add IETF ChaCha, XChaCha, ChaChaPoly1305 and XChaChaPoly1305
8.2.0 - April 28, 2019
- minor release, no recompile of programs required
- expanded community input and support
* 56 unique contributors as of this release
- use PowerPC unaligned loads and stores with Power8
- add SKIPJACK test vectors
- fix SHAKE-128 and SHAKE-256 compile
- removed IS_NEON from Makefile
- fix Aarch64 build on Fedora 29
- fix missing GF2NT_233_Multiply_Reduce_CLMUL in FIPS DLL
- add missing BLAKE2 constructors
- fix missing BlockSize() in BLAKE2 classes

View File

@ -29,8 +29,9 @@ Daniel J. Bernstein, Jack Lloyd - chacha.cpp, chacha_simd.cpp, chacha_avx.cpp
Andrew Moon - ed25519, x25519, donna_32.cpp, donna_64.cpp, donna_sse.cpp
The Crypto++ Library uses portions of Andy Polyakov's CRYPTOGAMS for Poly1305
scalar multiplication and aes_armv4.S. CRYPTOGAMS is dual licensed with a
permissive BSD-style license. The CRYPTOGAMS license is reproduced below.
scalar multiplication, aes_armv4.S, sha1_armv4.S and sha256_armv4.S. CRYPTOGAMS
is dual licensed with a permissive BSD-style license. The CRYPTOGAMS license is
reproduced below.
The Crypto++ Library uses portions of Jack Lloyd's Botan for ChaCha SSE2 and
AVX. Botan placed the code in public domain for Crypto++ to use.

View File

@ -1,5 +1,5 @@
Crypto++: free C++ Class Library of Cryptographic Schemes
Version 8.0 - DEC/28/2018
Version 8.3 - TBD
Crypto++ Library is a free C++ class library of cryptographic schemes.
Currently the library contains the following algorithms:
@ -205,23 +205,29 @@ library in your programs to help avoid unwanted redirections.
*** Side Channel Attacks ***
Crypto++ attempts to resist side channel attacks using various remediations. We
believe the library is mostly hardened but the remdiations may be incomplete. The
first line of defense uses hardware instructions when possible for block ciphers,
hashes and other primitives. Hardware acceleration remediates many timing attacks.
The library also uses cache-aware algoirthms and access patterns to minimize leakage.
Crypto++ attempts to resist side channel attacks using various remediations.
The remdiations are applied as a best effort but are probably incomplete. They
are incomplete due to cpu speculation bugs like Spectre, Meltdown, Foreshadow.
The attacks target both cpu caches and internal buffers. Intel generally refers
to internal buffer attacks as "Microarchitectural Data Sampling" (MDS).
Some of the public key algorithms have branches and some of the branches depend on
data that can be private or secret. The branching occurs in some field operations
like exponentiation over integers and elliptic curves. The branching has been
minimized but not completely eliminated.
The library uses hardware instructions when possible for block ciphers, hashes
and other operations. The hardware acceleration remediates some timing
attacks. The library also uses cache-aware algoirthms and access patterns
to minimize leakage cache evictions.
Crypto++ does not enagage Specter remediations at this time. The GCC options for
Specter are -mfunction-return=thunk and -mindirect-branch=thunk, and the library
uses them during testing. If you want the Specter workarounds then add the GCC
options to your CXXFLAGS when building the library.
Some of the public key algorithms have branches and some of the branches depend
on data that can be private or secret. The branching occurs in some field
operations like exponentiation over integers and elliptic curves. The branching
has been minimized but not completely eliminated.
If you suspect or find an information leak then please report it.
Crypto++ does not enagage Specter remediations at this time. The GCC options
for Specter are -mfunction-return=thunk and -mindirect-branch=thunk, and the
library uses them during testing. If you want the Specter workarounds then add
the GCC options to your CXXFLAGS when building the library.
To help resist attacks you should disable hyperthreading on cpus. If you
suspect or find an information leak then please report it.
*** Documentation and Support ***
@ -290,8 +296,36 @@ documentation is one of the highest returns on investment.
The items in this section comprise the most recent history. Please see History.txt
for the record back to Crypto++ 1.0.
8.0.0 - December 28, 2018
8.2.0 - April 28, 2019
- minor release, no recompile of programs required
- expanded community input and support
* 56 unique contributors as of this release
- use PowerPC unaligned loads and stores with Power8
- add SKIPJACK test vectors
- fix SHAKE-128 and SHAKE-256 compile
- removed IS_NEON from Makefile
- fix Aarch64 build on Fedora 29
- fix missing GF2NT_233_Multiply_Reduce_CLMUL in FIPS DLL
- add missing BLAKE2 constructors
- fix missing BlockSize() in BLAKE2 classes
8.1.0 - February 22, 2019
- minor release, no recompile of programs required
- expanded community input and support
* 56 unique contributors as of this release
- fix OS X PowerPC builds with Clang
- add Microsoft ARM64 support
- fix iPhone Simulator build due to missing symbols
- add CRYPTOPP_BUGGY_SIMD_LOAD_AND_STORE
- add carryless multiplies for NIST b233 and k233 curves
- fix OpenMP build due to use of OpenMP 4 with down-level compilers
- add SignStream and VerifyStream for ed25519 and large files
- fix missing AlgorithmProvider in PanamaHash
- add SHAKE-128 and SHAKE-256
- fix AVX2 build due to _mm256_broadcastsi128_si256
- add IETF ChaCha, XChaCha, ChaChaPoly1305 and XChaChaPoly1305
8.0.0 - December 28, 2018
- major release, recompile of programs required
- expanded community input and support
* 54 unique contributors as of this release

1
TestData/ecies_p160.dat Normal file
View File

@ -0,0 +1 @@
3081C80201003081A406072A8648CE3D0201308198020101302006072A8648CE3D0101021500FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF302C0414FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC04141C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA450429044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB3202150100000000000000000001F4C8F927AED3CA752257020101041C301A02010104150023A68821ABB99DBB8429ED2320D61A8EA4C6D81B

1
TestData/ecies_t163.dat Normal file
View File

@ -0,0 +1 @@
3081D10201003081AD06072A8648CE3D02013081A1020101302506072A8648CE3D0102301A020200A306092A8648CE3D010203033009020103020106020107302E041507B6882CAAEFA84F9554FF8428BD88E246D2782AE204150713612DCDDCB40AAB946BDA29CA91F73AF958AFD9042B040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883021503FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B020102041C301A02010104150003693AB4D83EE8B544548BE7647AEA0EA64E8211

View File

@ -1 +1 @@
308201A40201003082011706072A8648CE3804013082010A028181008B333697371663F8869E3EC80A414E46BBAFE41F6D40E754A01ADA60FE7D12ACD16DE311C4115293114F6B92A54195909276380F04BCD4ED5CD993ED7F516DF7A752B928E5035E0D3A1A979A1CDE8387734338793C02001D59B662D4FC8F2BF0EABB1F553F9F46F57E74BCABCBA4E458812DB601FCD04609D435317181236B9702818045999B4B9B8B31FC434F1F640520A7235DD7F20FB6A073AA500D6D307F3E895668B6F188E208A94988A7B5C952A0CAC8493B1C07825E6A76AE6CC9F6BFA8B6FBD3A95C947281AF069D0D4BCD0E6F41C3B9A19C3C9E01000EACDB316A7E4795F8755D8FAA9FCFA37ABF3A5E55E5D2722C4096DB00FE682304EA1A98B8C091B5CB02010204818302818045999B4B9B8B31FC434F1F640520A7235DD7F20FB6A073AA500D6D307F3E895668B6F188E208A94988A7B5C952A0CAC8493B1C07825E6A76AE6CC9F6BFA8B6FBD3A95C947281AF069D0D4BCD0E6F41C3B9A19C3C9E01000EACDB316A7E4795F8755D8FAA9FCFA37ABF3A5E2958F40032EF29CB145C7481380458812D62F09287
308201360201003082011606062B0E070201013082010A02818100D18892CC35AD9E532C53810019E525CDE08882E6344D6787C366B171D68948F53D74F7923B148E0A0B4C9B956D695384DE24AC3034000B3C4AD4C8226470BBD88B5B053BCCB01E608B1352D6ED16324745253BDB204308E065368CB9D75ACDB290E671BD4CA1608500BFACD758E6E9EFAC8CCBAD83BE7E397A62E4F55634FC3B02818068C449661AD6CF299629C0800CF292E6F04441731A26B3C3E1B358B8EB44A47A9EBA7BC91D8A470505A64DCAB6B4A9C26F1256181A00059E256A641132385DEC45AD829DE6580F304589A96B768B1923A2929DED90218470329B465CEBAD66D9487338DEA650B042805FD66BAC7374F7D64665D6C1DF3F1CBD31727AAB1A7E1D0201030417021504ED7AED68B1A5EFDE11262210D9F1121D4A119CE8

View File

@ -0,0 +1,18 @@
#include <arm_neon.h>
#include <stdint.h>
// test_acle.h determines if this is available. Then,
// -DCRYPTOPP_ARM_ACLE_AVAILABLE=0 is added to CXXFLAGS
// if the ACLE header is not available.
#if (CRYPTOPP_ARM_ACLE_AVAILABLE)
# include <arm_acle.h>
#endif
int main(int argc, char* argv[])
{
uint32x4_t y = {0};
y=vsha1cq_u32(y,0,y);
y=vsha1mq_u32(y,1,y);
y=vsha1pq_u32(y,2,y);
return 0;
}

View File

@ -11,9 +11,6 @@
int main(int argc, char* argv[])
{
uint32x4_t y = {0};
y=vsha1cq_u32(y,0,y);
y=vsha1mq_u32(y,1,y);
y=vsha1pq_u32(y,2,y);
y=vsha256hq_u32(y, y, y);
y=vsha256h2q_u32(y, y, y);
y=vsha256su1q_u32(y, y, y);

View File

@ -1,7 +1,9 @@
#include <immintrin.h>
int main(int argc, char* argv[])
{
__m256i x = _mm256_setzero_si256();
x=_mm256_add_epi64 (x,x);
// _mm256_broadcastsi128_si256 due to Clang
__m128i x = _mm_setzero_si128 ();
__m256i y = _mm256_broadcastsi128_si256 (x);
y = _mm256_add_epi64 (y,y);
return 0;
}

View File

@ -0,0 +1,7 @@
#include <immintrin.h>
int main(int argc, char* argv[])
{
unsigned int x=0;
(void)_rdrand32_step (&x);
return x == 0 ? 0 : 0;
}

View File

@ -0,0 +1,7 @@
#include <immintrin.h>
int main(int argc, char* argv[])
{
unsigned int x=0;
(void)_rdseed32_step (&x);
return x == 0 ? 0 : 0;
}

View File

@ -4,11 +4,14 @@
# building the docs. Before running the script, copy it to the root
# directory. After running this script, you can 'make docs'
sed 's|Library 8.1 API|Library 8.0 API|g' cryptlib.h > cryptlib.h.new
sed 's|Library 8.3 API|Library 8.2 API|g' cryptlib.h > cryptlib.h.new
mv cryptlib.h.new cryptlib.h
sed 's|= 8.1|= 8.0|g' Doxyfile > Doxyfile.new
sed 's|= 8.3|= 8.2|g' Doxyfile > Doxyfile.new
mv Doxyfile.new Doxyfile
sed 's|CRYPTOPP_VERSION 810|CRYPTOPP_VERSION 800|g' config.h > config.h.new
mv config.h.new config.h
sed 's|CRYPTOPP_MINOR 3|CRYPTOPP_MINOR 2|g' config_ver.h > config_ver.h.new
mv config_ver.h.new config_ver.h
sed 's|CRYPTOPP_VERSION 830|CRYPTOPP_VERSION 820|g' config_ver.h > config_ver.h.new
mv config_ver.h.new config_ver.h

View File

@ -6,17 +6,13 @@ function cleanup {
}
trap cleanup EXIT
#############################################################################
GREP=grep
SED=sed
AWK=awk
MAKE=make
# Fixup ancient Bash
# https://unix.stackexchange.com/q/468579/56041
if [[ -z "$BASH_SOURCE" ]]; then
BASH_SOURCE="$0"
fi
# Fixup, Solaris and friends
if [[ (-d /usr/xpg4/bin) ]]; then
SED=/usr/xpg4/bin/sed
@ -34,7 +30,6 @@ if [[ "$IS_DARWIN" -ne 0 ]]; then
export LC_ALL=C
fi
# Fixup for Solaris and BSDs
# Fixup for Solaris and BSDs
if [[ ! -z $(command -v gmake) ]]; then
MAKE=gmake
@ -53,24 +48,30 @@ elif [[ ! -z $(command -v glibtool) ]]; then
LIBTOOLIZE=$(command -v glibtool)
fi
# Fecth the three required files
if ! wget --no-check-certificate 'https://raw.githubusercontent.com/noloader/cryptopp-autotools/master/Makefile.am' -O Makefile.am; then
echo "Makefile.am download failed"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
#############################################################################
if ! wget --no-check-certificate 'https://raw.githubusercontent.com/noloader/cryptopp-autotools/master/configure.ac' -O configure.ac; then
echo "Downloading configure.ac"
if ! wget -O configure.ac -q --no-check-certificate 'https://raw.githubusercontent.com/noloader/cryptopp-autotools/master/configure.ac'; then
echo "configure.ac download failed"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
if ! wget --no-check-certificate 'https://raw.githubusercontent.com/noloader/cryptopp-autotools/master/libcryptopp.pc.in' -O libcryptopp.pc.in; then
echo "Downloading Makefile.am"
if ! wget -O Makefile.am -q --no-check-certificate 'https://raw.githubusercontent.com/noloader/cryptopp-autotools/master/Makefile.am'; then
echo "Makefile.am download failed"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
echo "Downloading libcryptopp.pc.in"
if ! wget -O libcryptopp.pc.in -q --no-check-certificate 'https://raw.githubusercontent.com/noloader/cryptopp-autotools/master/libcryptopp.pc.in'; then
echo "libcryptopp.pc.in download failed"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
mkdir -p m4/
#############################################################################
if [[ -z $(command -v autoupdate) ]]; then
echo "Cannot find autoupdate. Things may fail."
fi
@ -79,56 +80,71 @@ if [[ -z "$LIBTOOLIZE" ]]; then
echo "Cannot find libtoolize. Things may fail."
fi
if [[ -z $(command -v automake) ]]; then
echo "Cannot find automake. Things may fail."
fi
if [[ -z $(command -v autoreconf) ]]; then
echo "Cannot find autoreconf. Things may fail."
fi
echo "Running autoupdate"
if ! autoupdate 2>/dev/null; then
if ! autoupdate &>/dev/null; then
echo "autoupdate failed."
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
echo "Running libtoolize"
if ! "$LIBTOOLIZE" 2>/dev/null; then
echo "libtoolize failed."
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
if ! "$LIBTOOLIZE" --force --install &>/dev/null; then
echo "libtoolize failed... skipping."
# [[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
# Run autoreconf twice on failure. Also see
# https://github.com/tracebox/tracebox/issues/57
echo "Running autoreconf"
if ! autoreconf 2>/dev/null; then
if ! autoreconf --force --install &>/dev/null; then
echo "autoreconf failed, running again."
if ! autoreconf -fi; then
if ! autoreconf --force --install; then
echo "autoreconf failed, again."
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
fi
# Sparc need +w
if [[ -e config.sub ]]; then
chmod +w config.sub
fi
if [[ -e config.guess ]]; then
chmod +w config.guess
fi
#############################################################################
# Update config.sub config.guess. GNU recommends using the latest for all projects.
echo "Updating config.sub"
wget --no-check-certificate 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub' -O config.sub
wget -O config.sub.new -q --no-check-certificate 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub'
if [[ -e config.sub ]]; then
# Solaris removes +w, can't overwrite
chmod +w config.sub
mv config.sub.new config.sub
chmod +x config.sub
if [[ "$IS_DARWIN" -ne 0 ]] && [[ -n $(command -v xattr) ]]; then
echo "Removing config.sub quarantine"
xattr -d "com.apple.quarantine" config.sub &>/dev/null
fi
echo "Updating config.guess"
wget --no-check-certificate 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess' -O config.guess
wget -O config.guess.new -q --no-check-certificate 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess'
if [[ -e config.guess ]]; then
# Solaris removes +w, can't overwrite
chmod +w config.guess
mv config.guess.new config.guess
chmod +x config.guess
if [[ "$IS_DARWIN" -ne 0 ]] && [[ -n $(command -v xattr) ]]; then
echo "Removing config.guess quarantine"
xattr -d "com.apple.quarantine" config.guess &>/dev/null
fi
#############################################################################
echo "Running configure"
echo ""
if ! ./configure; then
echo "configure failed."
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
@ -136,6 +152,8 @@ fi
"$MAKE" clean 2>/dev/null
#############################################################################
if ! "$MAKE" -j2 -f Makefile; then
echo "make failed."
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1

View File

@ -18,7 +18,7 @@ fi
PWD_DIR=$(pwd)
function cleanup {
rm -f adhoc.cpp *.a *.o *.so *.dylib GNUmakefile-symbols
rm -f adhoc.cpp *.a *.o *.so *.dylib
cd "$PWD_DIR"
}
trap cleanup EXIT
@ -26,7 +26,7 @@ trap cleanup EXIT
############################################
# Tags to test
OLD_VERSION_TAG=CRYPTOPP_8_0_0
OLD_VERSION_TAG=CRYPTOPP_8_2_0
NEW_VERSION_TAG=master
############################################
@ -40,7 +40,7 @@ if [[ ! (-z "$DIRTY") ]]; then
read -p "Type 'Y' to proceed or 'N' to exit. Proceed? " -n 1 -r
echo # (optional) move to a new line
if [[ !($REPLY =~ ^[Yy]$) ]]; then
[[ "$0" = "$BASH_SOURCE" ]] && exit 0 || return 0
exit 0
fi
else
echo
@ -222,29 +222,13 @@ fi
"$MAKE" distclean &>/dev/null
rm -f GNUmakefile-symbols
git checkout master -f &>/dev/null
cp GNUmakefile GNUmakefile-symbols
git checkout "$OLD_VERSION_TAG" -f &>/dev/null
if [[ "$?" -ne "0" ]]; then
echo "Failed to checkout $OLD_VERSION_TAG"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1
fi
echo
echo "****************************************************************"
echo "Patching makefile for dynamic linking by cryptest.exe"
echo "****************************************************************"
if [[ "$IS_DARWIN" -ne "0" ]]; then
"$SED" "$SED_OPTS" -e 's|libcryptopp.a $(TESTOBJS)|libcryptopp.dylib $(TESTOBJS)|g' GNUmakefile-symbols
"$SED" "$SED_OPTS" -e 's|$(TESTOBJS) ./libcryptopp.a |$(TESTOBJS) ./libcryptopp.dylib |g' GNUmakefile-symbols
else
"$SED" "$SED_OPTS" -e 's|libcryptopp.a $(TESTOBJS)|libcryptopp.so $(TESTOBJS)|g' GNUmakefile-symbols
"$SED" "$SED_OPTS" -e 's|$(TESTOBJS) ./libcryptopp.a |$(TESTOBJS) ./libcryptopp.so |g' GNUmakefile-symbols
exit 1
fi
echo
@ -253,17 +237,17 @@ echo "Building dynamic library for $OLD_VERSION_TAG"
echo "****************************************************************"
echo
"$MAKE" "${MAKEARGS[@]}" -f GNUmakefile-symbols dynamic
if [[ "$IS_DARWIN" -ne "0" ]]; then
LIBNAME=libcryptopp.dylib
LINK_LIBRARY=libcryptopp.dylib
else
LIBNAME=libcryptopp.so
LINK_LIBRARY=libcryptopp.so
fi
if [[ ! -f "$LIBNAME" ]]; then
LINK_LIBRARY="$LINK_LIBRARY" "$MAKE" "${MAKEARGS[@]}" -f GNUmakefile dynamic
if [[ ! -f "$LINK_LIBRARY" ]]; then
echo "Failed to make $OLD_VERSION_TAG library"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1
exit 1
fi
echo
@ -272,11 +256,11 @@ echo "Building cryptest.exe for $OLD_VERSION_TAG"
echo "****************************************************************"
echo
"$MAKE" "${MAKEARGS[@]}" -f GNUmakefile-symbols cryptest.exe
"$MAKE" "${MAKEARGS[@]}" -f GNUmakefile cryptest.exe
if [[ ! -f "cryptest.exe" ]]; then
echo "Failed to make cryptest.exe"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1
exit 1
fi
echo
@ -304,7 +288,7 @@ git checkout "$NEW_VERSION_TAG" -f &>/dev/null
if [[ "$?" -ne "0" ]]; then
echo "Failed to checkout $OLD_VERSION_TAG"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1
exit 1
fi
echo
@ -313,11 +297,11 @@ echo "Building dynamic library for $NEW_VERSION_TAG"
echo "****************************************************************"
echo
"$MAKE" "${MAKEARGS[@]}" -f GNUmakefile-symbols dynamic
LINK_LIBRARY="$LINK_LIBRARY" "$MAKE" "${MAKEARGS[@]}" -f GNUmakefile dynamic
if [[ ! -f "$LIBNAME" ]]; then
if [[ ! -f "$LINK_LIBRARY" ]]; then
echo "Failed to make $NEW_VERSION_TAG library"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1
exit 1
fi
echo
@ -338,7 +322,7 @@ git checkout master -f &>/dev/null
if [[ "$?" -ne "0" ]]; then
echo "Failed to checkout Master"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1
exit 1
fi
[[ "$0" = "$BASH_SOURCE" ]] && exit 0 || return 0
exit 0

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,25 @@
#!/usr/bin/env bash
# This scripts queries and modifies CPU scaling frequencies to produce more
# accurate benchmark results. To move from a low energy state C-state to a
# higher one, run 'governor.sh performance'. To move back to a low power state
# run 'governor.sh powersave' or reboot. The script is based on code by
# Andy Polyakov, http://www.openssl.org/~appro/cryptogams/.
# accurate benchmark results. To move from a low energy state to a higher
# one, run 'governor.sh performance'. To move back to a low power state
# run 'governor.sh powersave' or 'governor.sh ondemand' or reboot. The script
# based on code by Andy Polyakov, http://www.openssl.org/~appro/cryptogams/.
# Fixup ancient Bash
# https://unix.stackexchange.com/q/468579/56041
if [[ -z "$BASH_SOURCE" ]]; then
if [[ -z "${BASH_SOURCE[0]}" ]]; then
BASH_SOURCE="$0"
fi
if [[ "$EUID" -ne 0 ]]; then
echo "This script must be run as root"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
if [ "x$1" = "x" ]; then
echo "usage: $0 on[demand]|pe[rformance]|po[wersave]|us[erspace]?"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
# "on demand" may result in a "invalid write argument" or similar
@ -27,40 +27,41 @@ case $1 in
on*|de*) governor="ondemand";;
po*|pw*) governor="powersave";;
pe*) governor="performance";;
co*) governor="conservative";;
us*) governor="userspace";;
\?) ;;
*) echo "$1: unrecognized governor";;
esac
if [ -z "$governor" ]; then
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
cpus=$(ls /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor 2>/dev/null)
if [ -z "$cpus" ]; then
echo "Failed to read CPU system device tree"
[[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
echo "Current CPU governor scaling settings:"
count=0
for cpu in $cpus; do
echo " CPU $count:" $(cat "$cpu")
echo " CPU $count: $(cat "$cpu")"
((count++))
done
if [ "x$governor" != "x" ]; then
for cpu in $cpus; do
echo $governor > $cpu
echo "$governor" > "$cpu"
done
fi
echo "New CPU governor scaling settings:"
count=0
for cpu in $cpus; do
echo " CPU $count:" $(cat "$cpu")
echo " CPU $count: $(cat "$cpu")"
((count++))
done
[[ "$0" = "$BASH_SOURCE" ]] && exit 0 || return 0
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 0 || return 0

View File

@ -18,6 +18,12 @@
# set -eu
# Sanity check
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
echo "Please source this setenv script"
exit 0
fi
unset IS_CROSS_COMPILE
unset IS_IOS
@ -39,7 +45,7 @@ unset CPP CC CXX LD AS AR RANLIB STRIP
# Similar to a "make clean"
if [ x"${1-}" = "xunset" ]; then
echo "Unsetting script variables. PATH may remain tainted"
[ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0
fi
# Set AOSP_TOOLCHAIN_SUFFIX to your preference of tools and STL library.
@ -71,7 +77,7 @@ if [ -z "${AOSP_API-}" ]; then
else
echo "WARNING: Using AOSP_API has been deprecated. Please use AOSP_API_VERSION instead."
echo "If you set for example AOSP_API=android-23 then now instead set AOSP_API_VERSION=23"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
#####################################################################
@ -98,7 +104,7 @@ fi
# Error checking
if [ ! -d "$ANDROID_NDK_ROOT/toolchains" ]; then
echo "ERROR: ANDROID_NDK_ROOT is not a valid path. Please set it."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
#####################################################################
@ -127,7 +133,7 @@ case "$THE_ARCH" in
;;
hard|armv7a-hard|armeabi-v7a-hard)
echo hard, armv7a-hard and armeabi-v7a-hard are not supported, as android uses softfloats
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
#TOOLCHAIN_ARCH="arm-linux-androideabi"
#TOOLCHAIN_NAME="arm-linux-androideabi"
#AOSP_ABI="armeabi-v7a"
@ -178,7 +184,7 @@ case "$THE_ARCH" in
;;
*)
echo "ERROR: Unknown architecture $1"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
;;
esac
@ -218,48 +224,48 @@ done
# Error checking
if [ -z "$AOSP_TOOLCHAIN_PATH" ] || [ ! -d "$AOSP_TOOLCHAIN_PATH" ]; then
echo "ERROR: AOSP_TOOLCHAIN_PATH is not valid. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CPP" ]; then
echo "ERROR: Failed to find Android cpp. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CC" ]; then
echo "ERROR: Failed to find Android gcc. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CXX" ]; then
echo "ERROR: Failed to find Android g++. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$RANLIB" ]; then
echo "ERROR: Failed to find Android ranlib. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AR" ]; then
echo "ERROR: Failed to find Android ar. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AS" ]; then
echo "ERROR: Failed to find Android as. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$LD" ]; then
echo "ERROR: Failed to find Android ld. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Only modify/export PATH if AOSP_TOOLCHAIN_PATH good
@ -278,10 +284,10 @@ fi
# Error checking
if [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API" ]; then
echo "ERROR: AOSP_API is not valid. Does the NDK support the API? Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
elif [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API/$AOSP_ARCH" ]; then
echo "ERROR: AOSP_ARCH is not valid. Does the NDK support the architecture? Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Android SYSROOT. It will be used on the command line with --sysroot
@ -328,7 +334,7 @@ case "$THE_STL" in
echo WARNING: llvm is still in experimental state and migth not work as expected
if [ ! -d "$LLVM_INCLUDE_DIR" ]; then
echo "ERROR: Unable to locate include LLVM directory at $LLVM_INCLUDE_DIR -- has it moved since NDK r16beta1?"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
AOSP_STL_INC="$LLVM_INCLUDE_DIR"
AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_static.a"
@ -337,26 +343,26 @@ case "$THE_STL" in
echo WARNING: llvm is still in experimental state and migth not work as expected
if [ ! -d "$LLVM_INCLUDE_DIR" ]; then
echo "ERROR: Unable to locate LLVM include directory at $LLVM_INCLUDE_DIR -- has it moved since NDK r16beta1?"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
AOSP_STL_INC="$LLVM_INCLUDE_DIR"
AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_shared.so"
;;
*)
echo "ERROR: Unknown STL library $2"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
esac
# Error checking
if [ ! -d "$AOSP_STL_INC" ] || [ ! -e "$AOSP_STL_INC/memory" ]; then
echo "ERROR: AOSP_STL_INC is not valid. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_STL_LIB" ]; then
echo "ERROR: AOSP_STL_LIB is not valid. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
export AOSP_STL_INC
@ -372,13 +378,13 @@ fi
if [[ ! -e "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.h" ]]; then
echo "ERROR: Unable to locate cpu-features.h"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
cp "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.h" .
if [[ ! -e "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.c" ]]; then
echo "ERROR: Unable to locate cpu-features.c"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
cp "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.c" .
@ -446,4 +452,4 @@ echo "shared object using 'HAS_SOLIB_VERSION=1 make -f GNUmakefile-cross'"
echo "*******************************************************************************"
echo
[ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0

View File

@ -20,6 +20,12 @@
# set -eu
# Sanity check
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
echo "Please source this setenv script"
exit 0
fi
unset IS_CROSS_COMPILE
unset IS_IOS
@ -39,7 +45,7 @@ unset CPP CC CXX LD AS AR RANLIB STRIP
# Similar to a "make clean"
if [ x"${1-}" = "xunset" ]; then
echo "Unsetting script variables. PATH may remain tainted"
[ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0
fi
# Set AOSP_TOOLCHAIN_SUFFIX to your preference of tools and STL library.
@ -90,7 +96,7 @@ fi
# Error checking
if [ ! -d "$ANDROID_NDK_ROOT/toolchains" ]; then
echo "ERROR: ANDROID_NDK_ROOT is not a valid path. Please set it."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
#####################################################################
@ -168,7 +174,7 @@ case "$THE_ARCH" in
;;
*)
echo "ERROR: Unknown architecture $1"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
;;
esac
@ -204,48 +210,48 @@ done
# Error checking
if [ -z "$AOSP_TOOLCHAIN_PATH" ] || [ ! -d "$AOSP_TOOLCHAIN_PATH" ]; then
echo "ERROR: AOSP_TOOLCHAIN_PATH is not valid. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CPP" ]; then
echo "ERROR: Failed to find Android cpp. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CC" ]; then
echo "ERROR: Failed to find Android gcc. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$CXX" ]; then
echo "ERROR: Failed to find Android g++. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$RANLIB" ]; then
echo "ERROR: Failed to find Android ranlib. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AR" ]; then
echo "ERROR: Failed to find Android ar. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$AS" ]; then
echo "ERROR: Failed to find Android as. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_TOOLCHAIN_PATH/$LD" ]; then
echo "ERROR: Failed to find Android ld. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Only modify/export PATH if AOSP_TOOLCHAIN_PATH good
@ -264,10 +270,10 @@ fi
# Error checking
if [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API" ]; then
echo "ERROR: AOSP_API is not valid. Does the NDK support the API? Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
elif [ ! -d "$ANDROID_NDK_ROOT/platforms/$AOSP_API/$AOSP_ARCH" ]; then
echo "ERROR: AOSP_ARCH is not valid. Does the NDK support the architecture? Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Android SYSROOT. It will be used on the command line with --sysroot
@ -312,7 +318,7 @@ case "$THE_STL" in
llvm-static)
if [ ! -d "$LLVM_INCLUDE_DIR" ]; then
echo "ERROR: Unable to locate include LLVM directory at $LLVM_INCLUDE_DIR -- has it moved since NDK r16beta1?"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
AOSP_STL_INC="$LLVM_INCLUDE_DIR"
AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_static.a"
@ -320,26 +326,26 @@ case "$THE_STL" in
llvm|llvm-shared)
if [ ! -d "$LLVM_INCLUDE_DIR" ]; then
echo "ERROR: Unable to locate LLVM include directory at $LLVM_INCLUDE_DIR -- has it moved since NDK r16beta1?"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
AOSP_STL_INC="$LLVM_INCLUDE_DIR"
AOSP_STL_LIB="$ANDROID_NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$AOSP_ABI/libc++_shared.so"
;;
*)
echo "ERROR: Unknown STL library $2"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
esac
# Error checking
if [ ! -d "$AOSP_STL_INC" ] || [ ! -e "$AOSP_STL_INC/memory" ]; then
echo "ERROR: AOSP_STL_INC is not valid. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$AOSP_STL_LIB" ]; then
echo "ERROR: AOSP_STL_LIB is not valid. Please edit this script."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
export AOSP_STL_INC
@ -355,13 +361,13 @@ fi
if [[ ! -e "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.h" ]]; then
echo "ERROR: Unable to locate cpu-features.h"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
cp "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.h" .
if [[ ! -e "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.c" ]]; then
echo "ERROR: Unable to locate cpu-features.c"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
cp "$ANDROID_NDK_ROOT/sources/android/cpufeatures/cpu-features.c" .
@ -427,4 +433,4 @@ echo "shared object using 'HAS_SOLIB_VERSION=1 make -f GNUmakefile-cross'"
echo "*******************************************************************************"
echo
[ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0

View File

@ -15,6 +15,12 @@
# set -eu
# Sanity check
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
echo "Please source this setenv script"
exit 0
fi
# Unset old options
unset IS_CROSS_COMPILE
@ -29,7 +35,7 @@ fi
if [ ! -d "$ARM_EMBEDDED_TOOLCHAIN" ]; then
echo "ARM_EMBEDDED_TOOLCHAIN is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Fedora
@ -50,37 +56,37 @@ export RANLIB="$ARM_EMBEDDED_TOOLCHAIN/$TOOL_PREFIX-ranlib"
# Test a few of the tools
if [ ! -e "$CPP" ]; then
echo "ERROR: CPP is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
if [ ! -e "$CC" ]; then
echo "ERROR: CC is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
if [ ! -e "$CXX" ]; then
echo "ERROR: CXX is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
if [ ! -e "$AR" ]; then
echo "ERROR: AR is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
if [ ! -e "$AS" ]; then
echo "ERROR: AS is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
if [ ! -e "$RANLIB" ]; then
echo "ERROR: RANLIB is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
if [ ! -e "$LD" ]; then
echo "ERROR: LD is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# The Crypto++ Makefile uses these to disable host settings like
@ -94,7 +100,7 @@ fi
if [ ! -d "$ARM_EMBEDDED_SYSROOT" ]; then
echo "ERROR: ARM_EMBEDDED_SYSROOT is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Fix C++ header paths for Ubuntu
@ -104,12 +110,12 @@ ARM_EMBEDDED_CXX_HEADERS="$ARM_EMBEDDED_SYSROOT/include/c++/$ARM_EMBEDDED_TOOLCH
if [ ! -d "$ARM_EMBEDDED_CXX_HEADERS" ]; then
echo "ERROR: ARM_EMBEDDED_CXX_HEADERS is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
if [ ! -d "$ARM_EMBEDDED_CXX_HEADERS/arm-linux-gnueabi" ]; then
echo "ERROR: ARM_EMBEDDED_CXX_HEADERS is not valid"
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Finally, the flags...
@ -142,4 +148,4 @@ echo "shared object using 'HAS_SOLIB_VERSION=1 make -f GNUmakefile-cross'"
echo "*******************************************************************************"
echo
[ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0

View File

@ -13,6 +13,12 @@
# set -eu
# Sanity check
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
echo "Please source this setenv script"
exit 0
fi
#########################################
##### Clear old options #####
#########################################
@ -149,7 +155,7 @@ fi
if [ ! -d "$XCODE_DEVELOPER" ]; then
echo "ERROR: unable to find XCODE_DEVELOPER directory."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Default toolchain location
@ -157,7 +163,7 @@ XCODE_TOOLCHAIN="$XCODE_DEVELOPER/usr/bin"
if [ ! -d "$XCODE_TOOLCHAIN" ]; then
echo "ERROR: unable to find XCODE_TOOLCHAIN directory."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# XCODE_DEVELOPER_TOP is the top of the development tools tree
@ -165,7 +171,7 @@ XCODE_DEVELOPER_TOP="$XCODE_DEVELOPER/Platforms/$APPLE_SDK.platform/Developer"
if [ ! -d "$XCODE_DEVELOPER_TOP" ]; then
echo "ERROR: unable to find XCODE_DEVELOPER_TOP directory."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# IOS_TOOLCHAIN is the location of the actual compiler tools.
@ -177,7 +183,7 @@ fi
if [ -z "$IOS_TOOLCHAIN" ] || [ ! -d "$IOS_TOOLCHAIN" ]; then
echo "ERROR: unable to find Xcode cross-compiler tools."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
#
@ -196,7 +202,7 @@ done
# Error checking
if [ -z "$XCODE_SDK" ]; then
echo "ERROR: unable to find a SDK."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# https://github.com/weidai11/cryptopp/issues/635
@ -237,7 +243,7 @@ fi
# https://stackoverflow.com/q/24841283/608639
# -tvos_simulator_version_min does not work though it is in LLVM sources.
if [ "$APPLE_SDK" == "AppleTVSimulator" ]; then
IOS_FLAGS="$IOS_FLAGS -tvos_simulator_version_min -DCRYPTOPP_DISABLE_ASM"
IOS_FLAGS="$IOS_FLAGS -DCRYPTOPP_DISABLE_ASM"
fi
# Simulator uses i386 or x86_64, Device uses ARMv5, ARMv6, ARMv7, ARMv7s or ARMv8
@ -285,7 +291,7 @@ if [ ! -z "$IOS_TOOLCHAIN" ] && [ ! -z "$XCODE_TOOLCHAIN" ]; then
fi
else
echo "ERROR: unable to set new PATH."
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
########################################
@ -307,7 +313,7 @@ do
done
if [ "$FOUND_ALL" -eq "0" ]; then
[ "$0" = "$BASH_SOURCE" ] && exit 1 || return 1
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Exports added for Autotools. GNUmakefile-cross does not use them.
@ -329,4 +335,4 @@ echo "shared object using 'HAS_SOLIB_VERSION=1 make -f GNUmakefile-cross'"
echo "*******************************************************************************"
echo
[ "$0" = "$BASH_SOURCE" ] && exit 0 || return 0
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0

View File

@ -49,6 +49,7 @@ Test: TestVectors/sha.txt
Test: TestVectors/simeck.txt
Test: TestVectors/simon.txt
Test: TestVectors/siphash.txt
Test: TestVectors/skipjack.txt
Test: TestVectors/sm3.txt
Test: TestVectors/sm4.txt
Test: TestVectors/sosemanuk.txt

1046
TestVectors/skipjack.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -355,9 +355,7 @@ inline size_t AdvancedProcessBlocks128_6x1_NEON(F1 func1, F6 func6,
CRYPTOPP_ASSERT(length >= 16);
const unsigned int w_one[] = {0, 0<<24, 0, 1<<24};
const unsigned int w_two[] = {0, 2<<24, 0, 2<<24};
const uint32x4_t s_one = vld1q_u32(w_one);
const uint32x4_t s_two = vld1q_u32(w_two);
const size_t blockSize = 16;
// const size_t neonBlockSize = 16;
@ -511,9 +509,7 @@ inline size_t AdvancedProcessBlocks128_4x1_NEON(F1 func1, F4 func4,
CRYPTOPP_ASSERT(length >= 16);
const unsigned int w_one[] = {0, 0<<24, 0, 1<<24};
const unsigned int w_two[] = {0, 2<<24, 0, 2<<24};
const uint32x4_t s_one = vld1q_u32(w_one);
const uint32x4_t s_two = vld1q_u32(w_two);
const size_t blockSize = 16;
// const size_t neonBlockSize = 16;
@ -647,9 +643,7 @@ inline size_t AdvancedProcessBlocks128_6x2_NEON(F2 func2, F6 func6,
CRYPTOPP_ASSERT(length >= 16);
const unsigned int w_one[] = {0, 0<<24, 0, 1<<24};
const unsigned int w_two[] = {0, 2<<24, 0, 2<<24};
const uint32x4_t s_one = vld1q_u32(w_one);
const uint32x4_t s_two = vld1q_u32(w_two);
const size_t blockSize = 16;
// const size_t neonBlockSize = 16;

View File

@ -7,31 +7,6 @@
@ details see http://www.openssl.org/~appro/cryptogams/.
@ ====================================================================
@ AES for ARMv4
@ January 2007.
@
@ Code uses single 1K S-box and is >2 times faster than code generated
@ by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which
@ allows to merge logical or arithmetic operation with shift or rotate
@ in one instruction and emit combined result every cycle. The module
@ is endian-neutral. The performance is ~42 cycles/byte for 128-bit
@ key [on single-issue Xscale PXA250 core].
@ May 2007.
@
@ AES_set_[en|de]crypt_key is added.
@ July 2010.
@
@ Rescheduling for dual-issue pipeline resulted in 12% improvement on
@ Cortex A8 core and ~25 cycles per byte processed with 128-bit key.
@ February 2011.
@
@ Profiler-assisted and platform-specific optimization resulted in 16%
@ improvement on Cortex A8 core and ~21.5 cycles per byte.
@ JW, JUL 2018: Begin defines from taken from arm_arch.h
@ The defines were included through the header.
@ -92,7 +67,6 @@
@ JW, JUL 2018: End defines from taken from arm_arch.h
@ Back to original Cryptogams code
.text
#if defined(__thumb2__) && !defined(__APPLE__)
.syntax unified
.thumb
@ -101,6 +75,8 @@
#undef __thumb2__
#endif
.text
.type AES_Te,%object
.align 5
AES_Te:
@ -1237,6 +1213,3 @@ _armv4_AES_decrypt:
sub r10,r10,#1024
ldr pc,[sp],#4 @ pop and return
.size _armv4_AES_decrypt,.-_armv4_AES_decrypt
.byte 65,69,83,32,102,111,114,32,65,82,77,118,52,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align 2
.align 2

View File

@ -320,10 +320,12 @@ public:
if (m_throwIfNotUsed && !m_used)
throw ParameterNotUsed(m_name);
}
#if !defined(CRYPTOPP_CXX17_EXCEPTIONS) && !defined(CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE)
#if !defined(CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE)
# if !defined(CRYPTOPP_CXX17_EXCEPTIONS)
catch(const Exception&)
{
}
# endif
#endif
}

View File

@ -24,7 +24,7 @@
# include <arm_acle.h>
#endif
// Clang __m128i casts, http://bugs.llvm.org/show_bug.cgi?id=20670
// Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670
#define M128_CAST(x) ((__m128i *)(void *)(x))
#define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x))

19
asn.cpp
View File

@ -394,14 +394,20 @@ void EncodedObjectFilter::Put(const byte *inString, size_t length)
}
}
BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue)
: m_inQueue(inQueue), m_length(0), m_finished(false)
{
Init(DefaultTag);
}
BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag)
: m_inQueue(inQueue), m_finished(false)
: m_inQueue(inQueue), m_length(0), m_finished(false)
{
Init(asnTag);
}
BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag)
: m_inQueue(inQueue), m_finished(false)
: m_inQueue(inQueue), m_length(0), m_finished(false)
{
Init(asnTag);
}
@ -501,13 +507,18 @@ lword BERGeneralDecoder::ReduceLength(lword delta)
return delta;
}
DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue)
: m_outQueue(outQueue), m_asnTag(DefaultTag), m_finished(false)
{
}
DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag)
: ByteQueue(), m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
: m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
{
}
DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag)
: ByteQueue(), m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
: m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
{
}

210
asn.h
View File

@ -258,21 +258,99 @@ private:
class CRYPTOPP_DLL BERGeneralDecoder : public Store
{
public:
/// \brief Default ASN.1 tag
enum {DefaultTag = SEQUENCE | CONSTRUCTED};
virtual ~BERGeneralDecoder();
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \details BERGeneralDecoder uses DefaultTag
explicit BERGeneralDecoder(BufferedTransformation &inQueue);
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \param asnTag ASN.1 tag
explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag);
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \param asnTag ASN.1 tag
explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag);
bool IsDefiniteLength() const {return m_definiteLength;}
lword RemainingLength() const {CRYPTOPP_ASSERT(m_definiteLength); return m_length;}
/// \brief Determine length encoding
/// \returns true if the ASN.1 object is definite length encoded, false otherwise
bool IsDefiniteLength() const {
return m_definiteLength;
}
/// \brief Determine remaining length
/// \returns number of octets that remain to be consumed
/// \details RemainingLength() is only valid if IsDefiniteLength()
/// returns true.
lword RemainingLength() const {
CRYPTOPP_ASSERT(m_definiteLength);
return IsDefiniteLength() ? m_length : 0;
}
/// \brief Determine end of stream
/// \returns true if all octets have been consumed, false otherwise
bool EndReached() const;
/// \brief Determine next octet
/// \returns next octet in the stream
/// \details PeekByte does not consume the octet.
/// \throws BERDecodeError if there are no octets remaining
byte PeekByte() const;
/// \brief Determine next octet
/// \details CheckByte reads the next byte in the stream and verifies
/// the octet matches b.
/// \throws BERDecodeError if the next octet is not b
void CheckByte(byte b);
/// \brief Transfer bytes to another BufferedTransformation
/// \param target the destination BufferedTransformation
/// \param transferBytes the number of bytes to transfer
/// \param channel the channel on which the transfer should occur
/// \param blocking specifies whether the object should block when
/// processing input
/// \return the number of bytes that remain in the transfer block
/// (i.e., bytes not transferred)
/// \details TransferTo2() removes bytes and moves
/// them to the destination. Transfer begins at the index position
/// in the current stream, and not from an absolute position in the
/// stream.
/// \details transferBytes is an \a IN and \a OUT parameter. When
/// the call is made, transferBytes is the requested size of the
/// transfer. When the call returns, transferBytes is the number
/// of bytes that were transferred.
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true);
/// \brief Copy bytes to another BufferedTransformation
/// \param target the destination BufferedTransformation
/// \param begin the 0-based index of the first byte to copy in
/// the stream
/// \param end the 0-based index of the last byte to copy in
/// the stream
/// \param channel the channel on which the transfer should occur
/// \param blocking specifies whether the object should block when
/// processing input
/// \return the number of bytes that remain in the copy block
/// (i.e., bytes not copied)
/// \details CopyRangeTo2 copies bytes to the
/// destination. The bytes are not removed from this object. Copying
/// begins at the index position in the current stream, and not from
/// an absolute position in the stream.
/// \details begin is an \a IN and \a OUT parameter. When the call is
/// made, begin is the starting position of the copy. When the call
/// returns, begin is the position of the first byte that was \a not
/// copied (which may be different than end). begin can be used for
/// subsequent calls to CopyRangeTo2().
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const;
// call this to denote end of sequence
/// \brief Signals the end of messages to the object
/// \details Call this to denote end of sequence
void MessageEnd();
protected:
@ -291,12 +369,28 @@ private:
class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue
{
public:
/// \brief Default ASN.1 tag
enum {DefaultTag = SEQUENCE | CONSTRUCTED};
virtual ~DERGeneralEncoder();
explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \details DERGeneralEncoder uses DefaultTag
explicit DERGeneralEncoder(BufferedTransformation &outQueue);
// call this to denote end of sequence
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \param asnTag ASN.1 tag
explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag);
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \param asnTag ASN.1 tag
explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag);
/// \brief Signals the end of messages to the object
/// \details Call this to denote end of sequence
void MessageEnd();
private:
@ -309,9 +403,31 @@ private:
class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder
{
public:
explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
/// \brief Default ASN.1 tag
enum {DefaultTag = SEQUENCE | CONSTRUCTED};
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \details BERSequenceDecoder uses DefaultTag
explicit BERSequenceDecoder(BufferedTransformation &inQueue)
: BERGeneralDecoder(inQueue, DefaultTag) {}
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \param asnTag ASN.1 tag
explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag)
: BERGeneralDecoder(inQueue, asnTag) {}
explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \details BERSequenceDecoder uses DefaultTag
explicit BERSequenceDecoder(BERSequenceDecoder &inQueue)
: BERGeneralDecoder(inQueue, DefaultTag) {}
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \param asnTag ASN.1 tag
explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag)
: BERGeneralDecoder(inQueue, asnTag) {}
};
@ -319,9 +435,31 @@ public:
class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder
{
public:
explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
/// \brief Default ASN.1 tag
enum {DefaultTag = SEQUENCE | CONSTRUCTED};
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \details DERSequenceEncoder uses DefaultTag
explicit DERSequenceEncoder(BufferedTransformation &outQueue)
: DERGeneralEncoder(outQueue, DefaultTag) {}
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \param asnTag ASN.1 tag
explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag)
: DERGeneralEncoder(outQueue, asnTag) {}
explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED)
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \details DERSequenceEncoder uses DefaultTag
explicit DERSequenceEncoder(DERSequenceEncoder &outQueue)
: DERGeneralEncoder(outQueue, DefaultTag) {}
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \param asnTag ASN.1 tag
explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag)
: DERGeneralEncoder(outQueue, asnTag) {}
};
@ -329,9 +467,31 @@ public:
class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder
{
public:
explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag = SET | CONSTRUCTED)
/// \brief Default ASN.1 tag
enum {DefaultTag = SET | CONSTRUCTED};
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \details BERSetDecoder uses DefaultTag
explicit BERSetDecoder(BufferedTransformation &inQueue)
: BERGeneralDecoder(inQueue, DefaultTag) {}
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \param asnTag ASN.1 tag
explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag)
: BERGeneralDecoder(inQueue, asnTag) {}
explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag = SET | CONSTRUCTED)
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \details BERSetDecoder uses DefaultTag
explicit BERSetDecoder(BERSetDecoder &inQueue)
: BERGeneralDecoder(inQueue, DefaultTag) {}
/// \brief Construct an ASN.1 decoder
/// \param inQueue input byte queue
/// \param asnTag ASN.1 tag
explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag)
: BERGeneralDecoder(inQueue, asnTag) {}
};
@ -339,9 +499,31 @@ public:
class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder
{
public:
explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag = SET | CONSTRUCTED)
/// \brief Default ASN.1 tag
enum {DefaultTag = SET | CONSTRUCTED};
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \details DERSetEncoder uses DefaultTag
explicit DERSetEncoder(BufferedTransformation &outQueue)
: DERGeneralEncoder(outQueue, DefaultTag) {}
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \param asnTag ASN.1 tag
explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag)
: DERGeneralEncoder(outQueue, asnTag) {}
explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag = SET | CONSTRUCTED)
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \details DERSetEncoder uses DefaultTag
explicit DERSetEncoder(DERSetEncoder &outQueue)
: DERGeneralEncoder(outQueue, DefaultTag) {}
/// \brief Construct an ASN.1 encoder
/// \param outQueue output byte queue
/// \param asnTag ASN.1 tag
explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag)
: DERGeneralEncoder(outQueue, asnTag) {}
};

View File

@ -36,7 +36,9 @@ public:
, m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
{
Detach(attachment);
IsolatedInitialize(MakeParameters(Name::EncodingLookupArray(), alphabet)
BaseN_Encoder::IsolatedInitialize(
MakeParameters
(Name::EncodingLookupArray(), alphabet)
(Name::Log2Base(), log2base)
(Name::Pad(), padding != -1)
(Name::PaddingByte(), byte(padding)));
@ -78,7 +80,10 @@ public:
, m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
{
Detach(attachment);
IsolatedInitialize(MakeParameters(Name::DecodingLookupArray(), lookup)(Name::Log2Base(), log2base));
BaseN_Decoder::IsolatedInitialize(
MakeParameters
(Name::DecodingLookupArray(), lookup)
(Name::Log2Base(), log2base));
}
void IsolatedInitialize(const NameValuePairs &parameters);
@ -121,7 +126,9 @@ public:
: m_groupSize(0), m_counter(0)
{
Detach(attachment);
IsolatedInitialize(MakeParameters(Name::GroupSize(), groupSize)
Grouper::IsolatedInitialize(
MakeParameters
(Name::GroupSize(), groupSize)
(Name::Separator(), ConstByteArrayParameter(separator))
(Name::Terminator(), ConstByteArrayParameter(terminator)));
}

48
bench.h
View File

@ -16,14 +16,48 @@ NAMESPACE_BEGIN(Test)
// More granular control over benchmarks
enum TestClass {
UnkeyedRNG=(1<<0),UnkeyedHash=(1<<1),UnkeyedOther=(1<<2),
SharedKeyMAC=(1<<3),SharedKeyStream=(1<<4),SharedKeyBlock=(1<<5),SharedKeyOther=(1<<6),
PublicKeyAgreement=(1<<7),PublicKeyEncryption=(1<<8),PublicKeySignature=(1<<9),PublicKeyOther=(1<<10),
/// \brief Random number generators
UnkeyedRNG=(1<<0),
/// \brief Message digests
UnkeyedHash=(1<<1),
/// \brief Other unkeyed algorithms
UnkeyedOther=(1<<2),
/// \brief Message authentication codes
SharedKeyMAC=(1<<3),
/// \brief Stream ciphers
SharedKeyStream=(1<<4),
/// \brief Block ciphers ciphers
SharedKeyBlock=(1<<5),
/// \brief Other shared key algorithms
SharedKeyOther=(1<<6),
/// \brief Key agreement algorithms over integers
PublicKeyAgreement=(1<<7),
/// \brief Encryption algorithms over integers
PublicKeyEncryption=(1<<8),
/// \brief Signature algorithms over integers
PublicKeySignature=(1<<9),
/// \brief Other public key algorithms over integers
PublicKeyOther=(1<<10),
/// \brief Key agreement algorithms over EC
PublicKeyAgreementEC=(1<<11),
/// \brief Encryption algorithms over EC
PublicKeyEncryptionEC=(1<<12),
/// \brief Signature algorithms over EC
PublicKeySignatureEC=(1<<13),
/// \brief Other public key algorithms over EC
PublicKeyOtherEC=(1<<14),
Unkeyed=UnkeyedRNG|UnkeyedHash|UnkeyedOther,
SharedKey=SharedKeyMAC|SharedKeyStream|SharedKeyBlock|SharedKeyOther,
PublicKey=PublicKeyAgreement|PublicKeyEncryption|PublicKeySignature|PublicKeyOther,
All=Unkeyed|SharedKey|PublicKey,
TestFirst=(0), TestLast=(1<<11)
PublicKeyEC=PublicKeyAgreementEC|PublicKeyEncryptionEC|PublicKeySignatureEC|PublicKeyOtherEC,
All=Unkeyed|SharedKey|PublicKey|PublicKeyEC,
TestFirst=(0), TestLast=(1<<15)
};
extern const double CLOCK_TICKS_PER_SECOND;
@ -45,8 +79,10 @@ void Benchmark(Test::TestClass suites, double t, double hertz);
void Benchmark1(double t, double hertz);
// Shared key systems
void Benchmark2(double t, double hertz);
// Public key systems
// Public key systems over integers
void Benchmark3(double t, double hertz);
// Public key systems over elliptic curves
void Benchmark4(double t, double hertz);
// These are defined in bench1.cpp
extern void OutputResultKeying(double iterations, double timeTaken);

View File

@ -351,6 +351,8 @@ void BenchmarkWithCommand(int argc, const char* const argv[])
if (command == "b") // All benchmarks
Benchmark(Test::All, runningTime, cpuFreq);
else if (command == "b4") // Public key algorithms over EC
Test::Benchmark(Test::PublicKeyEC, runningTime, cpuFreq);
else if (command == "b3") // Public key algorithms
Test::Benchmark(Test::PublicKey, runningTime, cpuFreq);
else if (command == "b2") // Shared key algorithms
@ -392,6 +394,13 @@ void Benchmark(Test::TestClass suites, double t, double hertz)
Benchmark3(t, hertz);
}
// Public key algorithms over EC
if (suites & Test::PublicKeyEC)
{
std::cout << "\n<BR>";
Benchmark4(t, hertz);
}
g_testEnd = ::time(NULLPTR);
std::ostringstream oss;

View File

@ -12,6 +12,12 @@
#include "smartptr.h"
#include "stdcpp.h"
#include "vmac.h"
#include "hmac.h"
#include "ttmac.h"
#include "cmac.h"
#include "dmac.h"
#if CRYPTOPP_MSC_VERSION
# pragma warning(disable: 4355)
#endif

View File

@ -365,21 +365,29 @@ void Benchmark3(double t, double hertz)
BenchMarkKeyAgreement<LUC_DH>("TestData/lucd1024.dat", "LUCDIF 1024", t);
BenchMarkKeyAgreement<MQV>("TestData/mqv1024.dat", "MQV 1024", t);
BenchMarkKeyAgreement<MQV>("TestData/mqv2048.dat", "MQV 2048", t);
#if 0
BenchMarkKeyAgreement<ECHMQV160>("TestData/hmqv160.dat", "HMQV P-160", t);
BenchMarkKeyAgreement<ECHMQV256>("TestData/hmqv256.dat", "HMQV P-256", t);
BenchMarkKeyAgreement<ECHMQV384>("TestData/hmqv384.dat", "HMQV P-384", t);
BenchMarkKeyAgreement<ECHMQV512>("TestData/hmqv512.dat", "HMQV P-512", t);
BenchMarkKeyAgreement<ECFHMQV160>("TestData/fhmqv160.dat", "FHMQV P-160", t);
BenchMarkKeyAgreement<ECFHMQV256>("TestData/fhmqv256.dat", "FHMQV P-256", t);
BenchMarkKeyAgreement<ECFHMQV384>("TestData/fhmqv384.dat", "FHMQV P-384", t);
BenchMarkKeyAgreement<ECFHMQV512>("TestData/fhmqv512.dat", "FHMQV P-512", t);
#endif
}
std::cout << "\n<TBODY style=\"background: yellow;\">";
std::cout << "\n</TABLE>" << std::endl;
}
void Benchmark4(double t, double hertz)
{
g_allocatedTime = t;
g_hertz = hertz;
const char *mco;
if (g_hertz > 1.0f)
mco = "<TH>Megacycles/Operation";
else
mco = "";
std::cout << "\n<TABLE>";
std::cout << "\n<COLGROUP><COL style=\"text-align: left;\"><COL style=";
std::cout << "\"text-align: right;\"><COL style=\"text-align: right;\">";
std::cout << "\n<THEAD style=\"background: #F0F0F0\">";
std::cout << "\n<TR><TH>Operation<TH>Milliseconds/Operation" << mco;
std::cout << "\n<TBODY style=\"background: white;\">";
{
ed25519::Signer sign(Test::GlobalRNG());
ed25519::Verifier verify(sign);
@ -391,7 +399,27 @@ void Benchmark3(double t, double hertz)
BenchMarkAgreement("x25519", agree, t);
}
std::cout << "\n<TBODY style=\"background: white;\">";
#if 0
std::cout << "\n<TBODY style=\"background: yellow;\">";
{
BenchMarkKeyAgreement<ECMQV160>("TestData/mqv160.dat", "MQV P-160", t);
BenchMarkKeyAgreement<ECMQV256>("TestData/mqv256.dat", "MQV P-256", t);
BenchMarkKeyAgreement<ECMQV384>("TestData/mqv384.dat", "MQV P-384", t);
BenchMarkKeyAgreement<ECMQV512>("TestData/mqv512.dat", "MQV P-521", t);
BenchMarkKeyAgreement<ECHMQV160>("TestData/hmqv160.dat", "HMQV P-160", t);
BenchMarkKeyAgreement<ECHMQV256>("TestData/hmqv256.dat", "HMQV P-256", t);
BenchMarkKeyAgreement<ECHMQV384>("TestData/hmqv384.dat", "HMQV P-384", t);
BenchMarkKeyAgreement<ECHMQV512>("TestData/hmqv512.dat", "HMQV P-521", t);
BenchMarkKeyAgreement<ECFHMQV160>("TestData/fhmqv160.dat", "FHMQV P-160", t);
BenchMarkKeyAgreement<ECFHMQV256>("TestData/fhmqv256.dat", "FHMQV P-256", t);
BenchMarkKeyAgreement<ECFHMQV384>("TestData/fhmqv384.dat", "FHMQV P-384", t);
BenchMarkKeyAgreement<ECFHMQV512>("TestData/fhmqv512.dat", "FHMQV P-521", t);
}
#endif
std::cout << "\n<TBODY style=\"background: yellow;\">";
{
ECIES<ECP>::Decryptor cpriv(Test::GlobalRNG(), ASN1::secp256k1());
ECIES<ECP>::Encryptor cpub(cpriv);
@ -418,7 +446,7 @@ void Benchmark3(double t, double hertz)
BenchMarkAgreement("ECMQVC over GF(p) 256", ecmqvc, t);
}
std::cout << "\n<TBODY style=\"background: yellow;\">";
std::cout << "\n<TBODY style=\"background: white;\">";
{
ECIES<EC2N>::Decryptor cpriv(Test::GlobalRNG(), ASN1::sect233r1());
ECIES<EC2N>::Encryptor cpub(cpriv);

View File

@ -38,24 +38,34 @@
// https://github.com/weidai11/cryptopp/issues/743
#if defined(__xlC__) && (__xlC__ < 0x0d01)
# define CRYPTOPP_DISABLE_ALTIVEC 1
# define CRYPTOPP_POWER7_ALTIVEC 1
# undef CRYPTOPP_POWER7_AVAILABLE
# undef CRYPTOPP_POWER8_AVAILABLE
# undef CRYPTOPP_ALTIVEC_AVAILABLE
#endif
// Can't use GetAlignmentOf<word64>() because of C++11 and constexpr
// Can use 'const unsigned int' because of MSVC 2013
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
# define ALIGN_SPEC32 16
# define ALIGN_SPEC64 16
#else
# define ALIGN_SPEC32 4
# define ALIGN_SPEC64 8
#endif
NAMESPACE_BEGIN(CryptoPP)
// Export the tables to the SIMD files
extern const word32 BLAKE2S_IV[8];
extern const word64 BLAKE2B_IV[8];
CRYPTOPP_ALIGN_DATA(16)
CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32)
const word32 BLAKE2S_IV[8] = {
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
};
CRYPTOPP_ALIGN_DATA(16)
CRYPTOPP_ALIGN_DATA(ALIGN_SPEC64)
const word64 BLAKE2B_IV[8] = {
W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
@ -72,7 +82,7 @@ using CryptoPP::word32;
using CryptoPP::word64;
using CryptoPP::rotrConstant;
CRYPTOPP_ALIGN_DATA(16)
CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32)
const byte BLAKE2S_SIGMA[10][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 },
@ -86,7 +96,7 @@ const byte BLAKE2S_SIGMA[10][16] = {
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
};
CRYPTOPP_ALIGN_DATA(16)
CRYPTOPP_ALIGN_DATA(ALIGN_SPEC32)
const byte 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 },
@ -171,8 +181,8 @@ extern void BLAKE2_Compress32_NEON(const byte* input, BLAKE2s_State& state);
extern void BLAKE2_Compress64_NEON(const byte* input, BLAKE2b_State& state);
#endif
#if CRYPTOPP_POWER7_AVAILABLE
extern void BLAKE2_Compress32_POWER7(const byte* input, BLAKE2s_State& state);
#if CRYPTOPP_POWER8_AVAILABLE
extern void BLAKE2_Compress32_POWER8(const byte* input, BLAKE2s_State& state);
#elif CRYPTOPP_ALTIVEC_AVAILABLE
extern void BLAKE2_Compress32_ALTIVEC(const byte* input, BLAKE2s_State& state);
#endif
@ -233,8 +243,8 @@ unsigned int BLAKE2s::OptimalDataAlignment() const
return 4;
else
#endif
#if (CRYPTOPP_POWER7_AVAILABLE)
if (HasPower7())
#if (CRYPTOPP_POWER8_AVAILABLE)
if (HasPower8())
return 16;
else
#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
@ -257,9 +267,9 @@ std::string BLAKE2s::AlgorithmProvider() const
return "NEON";
else
#endif
#if (CRYPTOPP_POWER7_AVAILABLE)
if (HasPower7())
return "Power7";
#if (CRYPTOPP_POWER8_AVAILABLE)
if (HasPower8())
return "Power8";
else
#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
if (HasAltivec())
@ -343,6 +353,26 @@ BLAKE2b::BLAKE2b(bool treeMode, unsigned int digestSize)
(Name::TreeMode(), treeMode));
}
BLAKE2s::BLAKE2s(unsigned int digestSize)
: m_digestSize(digestSize), m_keyLength(0), m_treeMode(false)
{
CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE);
UncheckedSetKey(NULLPTR, 0, MakeParameters
(Name::DigestSize(), (int)digestSize)
(Name::TreeMode(), false));
}
BLAKE2b::BLAKE2b(unsigned int digestSize)
: m_digestSize(digestSize), m_keyLength(0), m_treeMode(false)
{
CRYPTOPP_ASSERT(digestSize <= DIGESTSIZE);
UncheckedSetKey(NULLPTR, 0, MakeParameters
(Name::DigestSize(), (int)digestSize)
(Name::TreeMode(), false));
}
BLAKE2s::BLAKE2s(const byte *key, size_t keyLength, const byte* salt, size_t saltLength,
const byte* personalization, size_t personalizationLength, bool treeMode, unsigned int digestSize)
: m_digestSize(digestSize), m_keyLength(static_cast<unsigned int>(keyLength)), m_treeMode(treeMode)
@ -670,10 +700,10 @@ void BLAKE2s::Compress(const byte *input)
return BLAKE2_Compress32_NEON(input, m_state);
}
#endif
#if CRYPTOPP_POWER7_AVAILABLE
if(HasPower7())
#if CRYPTOPP_POWER8_AVAILABLE
if(HasPower8())
{
return BLAKE2_Compress32_POWER7(input, m_state);
return BLAKE2_Compress32_POWER8(input, m_state);
}
#elif CRYPTOPP_ALTIVEC_AVAILABLE
if(HasAltivec())

View File

@ -256,17 +256,25 @@ public:
/// \brief Construct a BLAKE2s hash
/// \param digestSize the digest size, in bytes
/// \param treeMode flag indicating tree mode
/// \since Crypto++ 5.6.4
BLAKE2s(bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
/// \brief Construct a BLAKE2s hash
/// \param digestSize the digest size, in bytes
/// \details treeMode flag is set to false
/// \since Crypto++ 8.2
BLAKE2s(unsigned int digestSize);
/// \brief Construct a BLAKE2s hash
/// \param key a byte array used to key the cipher
/// \param keyLength the size of the byte array
/// \param salt a byte array used as salt
/// \param saltLength the size of the byte array
/// \param personalization a byte array used as prsonalization string
/// \param personalization a byte array used as personalization string
/// \param personalizationLength the size of the byte array
/// \param treeMode flag indicating tree mode
/// \param digestSize the digest size, in bytes
/// \since Crypto++ 5.6.4
BLAKE2s(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0,
const byte* personalization = NULLPTR, size_t personalizationLength = 0,
bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
@ -278,6 +286,7 @@ public:
/// Message Authentication Code (MAC)</A>. For example, "BLAKE2b-512" and "BLAKE2s-256".
std::string AlgorithmName() const {return std::string(BLAKE2s_Info::StaticAlgorithmName()) + "-" + IntToString(DigestSize()*8);}
unsigned int BlockSize() const {return BLOCKSIZE;}
unsigned int DigestSize() const {return m_digestSize;}
unsigned int OptimalDataAlignment() const;
@ -354,17 +363,25 @@ public:
/// \brief Construct a BLAKE2b hash
/// \param digestSize the digest size, in bytes
/// \param treeMode flag indicating tree mode
/// \since Crypto++ 5.6.4
BLAKE2b(bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
/// \brief Construct a BLAKE2s hash
/// \param digestSize the digest size, in bytes
/// \details treeMode flag is set to false
/// \since Crypto++ 8.2
BLAKE2b(unsigned int digestSize);
/// \brief Construct a BLAKE2b hash
/// \param key a byte array used to key the cipher
/// \param keyLength the size of the byte array
/// \param salt a byte array used as salt
/// \param saltLength the size of the byte array
/// \param personalization a byte array used as prsonalization string
/// \param personalization a byte array used as personalization string
/// \param personalizationLength the size of the byte array
/// \param treeMode flag indicating tree mode
/// \param digestSize the digest size, in bytes
/// \since Crypto++ 5.6.4
BLAKE2b(const byte *key, size_t keyLength, const byte* salt = NULLPTR, size_t saltLength = 0,
const byte* personalization = NULLPTR, size_t personalizationLength = 0,
bool treeMode=false, unsigned int digestSize = DIGESTSIZE);
@ -376,6 +393,7 @@ public:
/// Message Authentication Code (MAC)</A>. For example, "BLAKE2b-512" and "BLAKE2s-256".
std::string AlgorithmName() const {return std::string(BLAKE2b_Info::StaticAlgorithmName()) + "-" + IntToString(DigestSize()*8);}
unsigned int BlockSize() const {return BLOCKSIZE;}
unsigned int DigestSize() const {return m_digestSize;}
unsigned int OptimalDataAlignment() const;

View File

@ -28,10 +28,17 @@
// https://github.com/weidai11/cryptopp/issues/743
#if defined(__xlC__) && (__xlC__ < 0x0d01)
# define CRYPTOPP_DISABLE_ALTIVEC 1
# undef CRYPTOPP_POWER7_AVAILABLE
# undef CRYPTOPP_POWER8_AVAILABLE
# undef CRYPTOPP_ALTIVEC_AVAILABLE
#endif
#if defined(__XOP__)
# include <ammintrin.h>
# if defined(__GNUC__)
# include <x86intrin.h>
# endif
#endif
#if (CRYPTOPP_SSE41_AVAILABLE)
# include <emmintrin.h>
# include <tmmintrin.h>

View File

@ -8,9 +8,9 @@
// appropriate instructions sets in some build configurations.
// The BLAKE2b and BLAKE2s numbers are consistent with the BLAKE2 team's
// numbers. However, we have an Altivec/POWER7 implementation of BLAKE2s,
// numbers. However, we have an Altivec/POWER8 implementation of BLAKE2s,
// and a POWER8 implementation of BLAKE2b (BLAKE2 is missing them). The
// Altivec/POWER7 code is about 2x faster than C++ when using GCC 5.0 or
// Altivec/POWER8 code is about 2x faster than C++ when using GCC 5.0 or
// above. The POWER8 code is about 2.5x faster than C++ when using GCC 5.0
// or above. If you use GCC 4.0 (PowerMac) or GCC 4.8 (GCC Compile Farm)
// then the PowerPC code will be slower than C++. Be sure to use GCC 5.0
@ -38,11 +38,17 @@
// https://github.com/weidai11/cryptopp/issues/743
#if defined(__xlC__) && (__xlC__ < 0x0d01)
# define CRYPTOPP_DISABLE_ALTIVEC 1
# define CRYPTOPP_POWER7_ALTIVEC 1
# undef CRYPTOPP_POWER7_AVAILABLE
# undef CRYPTOPP_POWER8_AVAILABLE
# undef CRYPTOPP_ALTIVEC_AVAILABLE
#endif
#if defined(__XOP__)
# include <ammintrin.h>
# if defined(__GNUC__)
# include <x86intrin.h>
# endif
#endif
#if (CRYPTOPP_SSE41_AVAILABLE)
# include <emmintrin.h>
# include <tmmintrin.h>
@ -692,7 +698,7 @@ void BLAKE2_Compress32_NEON(const byte* input, BLAKE2s_State& state)
}
#endif // CRYPTOPP_ARM_NEON_AVAILABLE
#if (CRYPTOPP_POWER7_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE)
#if (CRYPTOPP_POWER8_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE)
inline uint32x4_p VecLoad32(const void* p)
{
@ -838,7 +844,7 @@ inline uint32x4_p VectorSet32(const uint32x4_p a, const uint32x4_p b,
const uint32x4_p t0 = VectorSet32<W,X>(a, b);
const uint32x4_p t1 = VectorSet32<Y,Z>(c, d);
// Power7 follows SSE2's implementation, and this is _mm_set_epi32.
// PowerPC follows SSE2's implementation, and this is _mm_set_epi32.
const uint8x16_p mask = {20,21,22,23, 16,17,18,19, 4,5,6,7, 0,1,2,3};
return VecPermute(t0, t1, mask);
}
@ -863,10 +869,10 @@ uint32x4_p VectorSet32<3,1,3,1>(const uint32x4_p a, const uint32x4_p b,
return VecPermute(a, c, mask);
}
// BLAKE2_Compress32_CORE will use either POWER7 or ALTIVEC,
// BLAKE2_Compress32_CORE will use either POWER8 or ALTIVEC,
// depending on the flags used to compile this source file. The
// abstractions are handled in VecLoad, VecStore and friends. In
// the future we may to provide both POWER7 or ALTIVEC at the same
// the future we may provide both POWER8 or ALTIVEC at the same
// time to better support distros.
void BLAKE2_Compress32_CORE(const byte* input, BLAKE2s_State& state)
{
@ -1015,11 +1021,11 @@ void BLAKE2_Compress32_CORE(const byte* input, BLAKE2s_State& state)
VecStore32LE(state.h()+0, VecXor(ff0, VecXor(row1, row3)));
VecStore32LE(state.h()+4, VecXor(ff1, VecXor(row2, row4)));
}
#endif // CRYPTOPP_POWER7_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE
#endif // CRYPTOPP_POWER8_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE
#if (CRYPTOPP_POWER7_AVAILABLE)
#if (CRYPTOPP_POWER8_AVAILABLE)
void BLAKE2_Compress32_POWER7(const byte* input, BLAKE2s_State& state)
void BLAKE2_Compress32_POWER8(const byte* input, BLAKE2s_State& state)
{
BLAKE2_Compress32_CORE(input, state);
}

View File

@ -28,8 +28,8 @@ extern void ChaCha_OperateKeystream_AVX2(const word32 *state, const byte* input,
extern void ChaCha_OperateKeystream_SSE2(const word32 *state, const byte* input, byte *output, unsigned int rounds);
#endif
#if (CRYPTOPP_POWER7_AVAILABLE)
extern void ChaCha_OperateKeystream_POWER7(const word32 *state, const byte* input, byte *output, unsigned int rounds);
#if (CRYPTOPP_POWER8_AVAILABLE)
extern void ChaCha_OperateKeystream_POWER8(const word32 *state, const byte* input, byte *output, unsigned int rounds);
#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
extern void ChaCha_OperateKeystream_ALTIVEC(const word32 *state, const byte* input, byte *output, unsigned int rounds);
#endif
@ -153,13 +153,13 @@ void ChaCha_OperateKeystream(KeystreamOperation operation,
}
#endif
#if (CRYPTOPP_POWER7_AVAILABLE)
if (HasPower7())
#if (CRYPTOPP_POWER8_AVAILABLE)
if (HasPower8())
{
while (iterationCount >= 4 && MultiBlockSafe(state[12], 4))
{
const bool xorInput = (operation & INPUT_NULL) != INPUT_NULL;
ChaCha_OperateKeystream_POWER7(state, xorInput ? input : NULLPTR, output, rounds);
ChaCha_OperateKeystream_POWER8(state, xorInput ? input : NULLPTR, output, rounds);
// MultiBlockSafe avoids overflow on the counter words
state[12] += 4;
@ -267,9 +267,9 @@ std::string ChaCha_AlgorithmProvider()
return "NEON";
else
#endif
#if (CRYPTOPP_POWER7_AVAILABLE)
if (HasPower7())
return "Power7";
#if (CRYPTOPP_POWER8_AVAILABLE)
if (HasPower8())
return "Power8";
else
#elif (CRYPTOPP_ALTIVEC_AVAILABLE)
if (HasAltivec())

View File

@ -91,14 +91,14 @@ NAMESPACE_BEGIN(CryptoPP)
void ChaCha_OperateKeystream_AVX2(const word32 *state, const byte* input, byte *output, unsigned int rounds)
{
MAYBE_CONST __m128i* state_mm = (MAYBE_CONST __m128i*)(state);
MAYBE_CONST __m256i* input_mm = (MAYBE_CONST __m256i*)(input);
__m256i* output_mm = reinterpret_cast<__m256i*>(output);
const __m256i state0 = _mm256_broadcastsi128_si256(_mm_loadu_si128(state_mm + 0));
const __m256i state1 = _mm256_broadcastsi128_si256(_mm_loadu_si128(state_mm + 1));
const __m256i state2 = _mm256_broadcastsi128_si256(_mm_loadu_si128(state_mm + 2));
const __m256i state3 = _mm256_broadcastsi128_si256(_mm_loadu_si128(state_mm + 3));
const __m256i state0 = _mm256_broadcastsi128_si256(
_mm_loadu_si128(reinterpret_cast<const __m128i*>(state+0*4)));
const __m256i state1 = _mm256_broadcastsi128_si256(
_mm_loadu_si128(reinterpret_cast<const __m128i*>(state+1*4)));
const __m256i state2 = _mm256_broadcastsi128_si256(
_mm_loadu_si128(reinterpret_cast<const __m128i*>(state+2*4)));
const __m256i state3 = _mm256_broadcastsi128_si256(
_mm_loadu_si128(reinterpret_cast<const __m128i*>(state+3*4)));
const __m256i CTR0 = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, 4);
const __m256i CTR1 = _mm256_set_epi32(0, 0, 0, 1, 0, 0, 0, 5);
@ -304,80 +304,112 @@ void ChaCha_OperateKeystream_AVX2(const word32 *state, const byte* input, byte *
X3_3 = _mm256_add_epi32(X3_3, state3);
X3_3 = _mm256_add_epi64(X3_3, CTR3);
if (input_mm)
if (input)
{
_mm256_storeu_si256(output_mm + 0, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 0),
_mm256_permute2x128_si256(X0_0, X0_1, 1 + (3 << 4))));
_mm256_storeu_si256(output_mm + 1, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 1),
_mm256_permute2x128_si256(X0_2, X0_3, 1 + (3 << 4))));
_mm256_storeu_si256(output_mm + 2, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 2),
_mm256_permute2x128_si256(X1_0, X1_1, 1 + (3 << 4))));
_mm256_storeu_si256(output_mm + 3, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 3),
_mm256_permute2x128_si256(X1_2, X1_3, 1 + (3 << 4))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+0*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X0_0, X0_1, 1 + (3 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+0*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+1*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X0_2, X0_3, 1 + (3 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+1*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+2*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X1_0, X1_1, 1 + (3 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+2*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+3*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X1_2, X1_3, 1 + (3 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+3*32))));
}
else
{
_mm256_storeu_si256(output_mm + 0, _mm256_permute2x128_si256(X0_0, X0_1, 1 + (3 << 4)));
_mm256_storeu_si256(output_mm + 1, _mm256_permute2x128_si256(X0_2, X0_3, 1 + (3 << 4)));
_mm256_storeu_si256(output_mm + 2, _mm256_permute2x128_si256(X1_0, X1_1, 1 + (3 << 4)));
_mm256_storeu_si256(output_mm + 3, _mm256_permute2x128_si256(X1_2, X1_3, 1 + (3 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+0*32),
_mm256_permute2x128_si256(X0_0, X0_1, 1 + (3 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+1*32),
_mm256_permute2x128_si256(X0_2, X0_3, 1 + (3 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+2*32),
_mm256_permute2x128_si256(X1_0, X1_1, 1 + (3 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+3*32),
_mm256_permute2x128_si256(X1_2, X1_3, 1 + (3 << 4)));
}
if (input_mm)
if (input)
{
_mm256_storeu_si256(output_mm + 4, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 4),
_mm256_permute2x128_si256(X2_0, X2_1, 1 + (3 << 4))));
_mm256_storeu_si256(output_mm + 5, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 5),
_mm256_permute2x128_si256(X2_2, X2_3, 1 + (3 << 4))));
_mm256_storeu_si256(output_mm + 6, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 6),
_mm256_permute2x128_si256(X3_0, X3_1, 1 + (3 << 4))));
_mm256_storeu_si256(output_mm + 7, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 7),
_mm256_permute2x128_si256(X3_2, X3_3, 1 + (3 << 4))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+4*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X2_0, X2_1, 1 + (3 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+4*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+5*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X2_2, X2_3, 1 + (3 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+5*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+6*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X3_0, X3_1, 1 + (3 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+6*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+7*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X3_2, X3_3, 1 + (3 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+7*32))));
}
else
{
_mm256_storeu_si256(output_mm + 4, _mm256_permute2x128_si256(X2_0, X2_1, 1 + (3 << 4)));
_mm256_storeu_si256(output_mm + 5, _mm256_permute2x128_si256(X2_2, X2_3, 1 + (3 << 4)));
_mm256_storeu_si256(output_mm + 6, _mm256_permute2x128_si256(X3_0, X3_1, 1 + (3 << 4)));
_mm256_storeu_si256(output_mm + 7, _mm256_permute2x128_si256(X3_2, X3_3, 1 + (3 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+4*32),
_mm256_permute2x128_si256(X2_0, X2_1, 1 + (3 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+5*32),
_mm256_permute2x128_si256(X2_2, X2_3, 1 + (3 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+6*32),
_mm256_permute2x128_si256(X3_0, X3_1, 1 + (3 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+7*32),
_mm256_permute2x128_si256(X3_2, X3_3, 1 + (3 << 4)));
}
if (input_mm)
if (input)
{
_mm256_storeu_si256(output_mm + 8, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 8),
_mm256_permute2x128_si256(X0_0, X0_1, 0 + (2 << 4))));
_mm256_storeu_si256(output_mm + 9, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 9),
_mm256_permute2x128_si256(X0_2, X0_3, 0 + (2 << 4))));
_mm256_storeu_si256(output_mm + 10, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 10),
_mm256_permute2x128_si256(X1_0, X1_1, 0 + (2 << 4))));
_mm256_storeu_si256(output_mm + 11, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 11),
_mm256_permute2x128_si256(X1_2, X1_3, 0 + (2 << 4))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+ 8*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X0_0, X0_1, 0 + (2 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+8*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+ 9*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X0_2, X0_3, 0 + (2 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+9*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+10*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X1_0, X1_1, 0 + (2 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+10*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+11*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X1_2, X1_3, 0 + (2 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+11*32))));
}
else
{
_mm256_storeu_si256(output_mm + 8, _mm256_permute2x128_si256(X0_0, X0_1, 0 + (2 << 4)));
_mm256_storeu_si256(output_mm + 9, _mm256_permute2x128_si256(X0_2, X0_3, 0 + (2 << 4)));
_mm256_storeu_si256(output_mm + 10, _mm256_permute2x128_si256(X1_0, X1_1, 0 + (2 << 4)));
_mm256_storeu_si256(output_mm + 11, _mm256_permute2x128_si256(X1_2, X1_3, 0 + (2 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+ 8*32),
_mm256_permute2x128_si256(X0_0, X0_1, 0 + (2 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+ 9*32),
_mm256_permute2x128_si256(X0_2, X0_3, 0 + (2 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+10*32),
_mm256_permute2x128_si256(X1_0, X1_1, 0 + (2 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+11*32),
_mm256_permute2x128_si256(X1_2, X1_3, 0 + (2 << 4)));
}
if (input_mm)
if (input)
{
_mm256_storeu_si256(output_mm + 12, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 12),
_mm256_permute2x128_si256(X2_0, X2_1, 0 + (2 << 4))));
_mm256_storeu_si256(output_mm + 13, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 13),
_mm256_permute2x128_si256(X2_2, X2_3, 0 + (2 << 4))));
_mm256_storeu_si256(output_mm + 14, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 14),
_mm256_permute2x128_si256(X3_0, X3_1, 0 + (2 << 4))));
_mm256_storeu_si256(output_mm + 15, _mm256_xor_si256(_mm256_loadu_si256(input_mm + 15),
_mm256_permute2x128_si256(X3_2, X3_3, 0 + (2 << 4))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+12*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X2_0, X2_1, 0 + (2 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+12*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+13*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X2_2, X2_3, 0 + (2 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+13*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+14*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X3_0, X3_1, 0 + (2 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+14*32))));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+15*32),
_mm256_xor_si256(_mm256_permute2x128_si256(X3_2, X3_3, 0 + (2 << 4)),
_mm256_loadu_si256(reinterpret_cast<const __m256i*>(input+15*32))));
}
else
{
_mm256_storeu_si256(output_mm + 12, _mm256_permute2x128_si256(X2_0, X2_1, 0 + (2 << 4)));
_mm256_storeu_si256(output_mm + 13, _mm256_permute2x128_si256(X2_2, X2_3, 0 + (2 << 4)));
_mm256_storeu_si256(output_mm + 14, _mm256_permute2x128_si256(X3_0, X3_1, 0 + (2 << 4)));
_mm256_storeu_si256(output_mm + 15, _mm256_permute2x128_si256(X3_2, X3_3, 0 + (2 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+12*32),
_mm256_permute2x128_si256(X2_0, X2_1, 0 + (2 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+13*32),
_mm256_permute2x128_si256(X2_2, X2_3, 0 + (2 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+14*32),
_mm256_permute2x128_si256(X3_0, X3_1, 0 + (2 << 4)));
_mm256_storeu_si256(reinterpret_cast<__m256i*>(output+15*32),
_mm256_permute2x128_si256(X3_2, X3_3, 0 + (2 << 4)));
}
// https://software.intel.com/en-us/articles/avoiding-avx-sse-transition-penalties

View File

@ -46,6 +46,9 @@
#if defined(__XOP__)
# include <ammintrin.h>
# if defined(__GNUC__)
# include <x86intrin.h>
# endif
#endif
// C1189: error: This header is specific to ARM targets
@ -209,7 +212,7 @@ inline __m128i RotateLeft<16>(const __m128i val)
#if (CRYPTOPP_ALTIVEC_AVAILABLE)
// ChaCha_OperateKeystream_POWER7 is optimized for POWER7. However, Altivec
// ChaCha_OperateKeystream_POWER8 is optimized for POWER7. However, Altivec
// is supported by using vec_ld and vec_st, and using a composite VecAdd
// that supports 64-bit element adds. vec_ld and vec_st add significant
// overhead when memory is not aligned. Despite the drawbacks Altivec
@ -565,14 +568,10 @@ void ChaCha_OperateKeystream_NEON(const word32 *state, const byte* input, byte *
void ChaCha_OperateKeystream_SSE2(const word32 *state, const byte* input, byte *output, unsigned int rounds)
{
const __m128i* state_mm = reinterpret_cast<const __m128i*>(state);
const __m128i* input_mm = reinterpret_cast<const __m128i*>(input);
__m128i* output_mm = reinterpret_cast<__m128i*>(output);
const __m128i state0 = _mm_load_si128(state_mm + 0);
const __m128i state1 = _mm_load_si128(state_mm + 1);
const __m128i state2 = _mm_load_si128(state_mm + 2);
const __m128i state3 = _mm_load_si128(state_mm + 3);
const __m128i state0 = _mm_load_si128(reinterpret_cast<const __m128i*>(state+0*4));
const __m128i state1 = _mm_load_si128(reinterpret_cast<const __m128i*>(state+1*4));
const __m128i state2 = _mm_load_si128(reinterpret_cast<const __m128i*>(state+2*4));
const __m128i state3 = _mm_load_si128(reinterpret_cast<const __m128i*>(state+3*4));
__m128i r0_0 = state0;
__m128i r0_1 = state1;
@ -772,62 +771,62 @@ void ChaCha_OperateKeystream_SSE2(const word32 *state, const byte* input, byte *
r3_3 = _mm_add_epi32(r3_3, state3);
r3_3 = _mm_add_epi64(r3_3, _mm_set_epi32(0, 0, 0, 3));
if (input_mm)
if (input)
{
r0_0 = _mm_xor_si128(_mm_loadu_si128(input_mm + 0), r0_0);
r0_1 = _mm_xor_si128(_mm_loadu_si128(input_mm + 1), r0_1);
r0_2 = _mm_xor_si128(_mm_loadu_si128(input_mm + 2), r0_2);
r0_3 = _mm_xor_si128(_mm_loadu_si128(input_mm + 3), r0_3);
r0_0 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+0*16)), r0_0);
r0_1 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+1*16)), r0_1);
r0_2 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+2*16)), r0_2);
r0_3 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+3*16)), r0_3);
}
_mm_storeu_si128(output_mm + 0, r0_0);
_mm_storeu_si128(output_mm + 1, r0_1);
_mm_storeu_si128(output_mm + 2, r0_2);
_mm_storeu_si128(output_mm + 3, r0_3);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+0*16), r0_0);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+1*16), r0_1);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+2*16), r0_2);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+3*16), r0_3);
if (input_mm)
if (input)
{
r1_0 = _mm_xor_si128(_mm_loadu_si128(input_mm + 4), r1_0);
r1_1 = _mm_xor_si128(_mm_loadu_si128(input_mm + 5), r1_1);
r1_2 = _mm_xor_si128(_mm_loadu_si128(input_mm + 6), r1_2);
r1_3 = _mm_xor_si128(_mm_loadu_si128(input_mm + 7), r1_3);
r1_0 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+4*16)), r1_0);
r1_1 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+5*16)), r1_1);
r1_2 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+6*16)), r1_2);
r1_3 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+7*16)), r1_3);
}
_mm_storeu_si128(output_mm + 4, r1_0);
_mm_storeu_si128(output_mm + 5, r1_1);
_mm_storeu_si128(output_mm + 6, r1_2);
_mm_storeu_si128(output_mm + 7, r1_3);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+4*16), r1_0);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+5*16), r1_1);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+6*16), r1_2);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+7*16), r1_3);
if (input_mm)
if (input)
{
r2_0 = _mm_xor_si128(_mm_loadu_si128(input_mm + 8), r2_0);
r2_1 = _mm_xor_si128(_mm_loadu_si128(input_mm + 9), r2_1);
r2_2 = _mm_xor_si128(_mm_loadu_si128(input_mm + 10), r2_2);
r2_3 = _mm_xor_si128(_mm_loadu_si128(input_mm + 11), r2_3);
r2_0 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+ 8*16)), r2_0);
r2_1 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+ 9*16)), r2_1);
r2_2 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+10*16)), r2_2);
r2_3 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+11*16)), r2_3);
}
_mm_storeu_si128(output_mm + 8, r2_0);
_mm_storeu_si128(output_mm + 9, r2_1);
_mm_storeu_si128(output_mm + 10, r2_2);
_mm_storeu_si128(output_mm + 11, r2_3);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+ 8*16), r2_0);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+ 9*16), r2_1);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+10*16), r2_2);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+11*16), r2_3);
if (input_mm)
if (input)
{
r3_0 = _mm_xor_si128(_mm_loadu_si128(input_mm + 12), r3_0);
r3_1 = _mm_xor_si128(_mm_loadu_si128(input_mm + 13), r3_1);
r3_2 = _mm_xor_si128(_mm_loadu_si128(input_mm + 14), r3_2);
r3_3 = _mm_xor_si128(_mm_loadu_si128(input_mm + 15), r3_3);
r3_0 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+12*16)), r3_0);
r3_1 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+13*16)), r3_1);
r3_2 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+14*16)), r3_2);
r3_3 = _mm_xor_si128(_mm_loadu_si128(reinterpret_cast<const __m128i*>(input+15*16)), r3_3);
}
_mm_storeu_si128(output_mm + 12, r3_0);
_mm_storeu_si128(output_mm + 13, r3_1);
_mm_storeu_si128(output_mm + 14, r3_2);
_mm_storeu_si128(output_mm + 15, r3_3);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+12*16), r3_0);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+13*16), r3_1);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+14*16), r3_2);
_mm_storeu_si128(reinterpret_cast<__m128i*>(output+15*16), r3_3);
}
#endif // CRYPTOPP_SSE2_INTRIN_AVAILABLE
#if (CRYPTOPP_POWER7_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE)
#if (CRYPTOPP_POWER8_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE)
// ChaCha_OperateKeystream_CORE will use either POWER7 or ALTIVEC,
// depending on the flags used to compile this source file. The
@ -1096,11 +1095,11 @@ inline void ChaCha_OperateKeystream_CORE(const word32 *state, const byte* input,
VecStore32LE(output + 15*16, r3_3);
}
#endif // CRYPTOPP_POWER7_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE
#endif // CRYPTOPP_POWER8_AVAILABLE || CRYPTOPP_ALTIVEC_AVAILABLE
#if (CRYPTOPP_POWER7_AVAILABLE)
#if (CRYPTOPP_POWER8_AVAILABLE)
void ChaCha_OperateKeystream_POWER7(const word32 *state, const byte* input, byte *output, unsigned int rounds)
void ChaCha_OperateKeystream_POWER8(const word32 *state, const byte* input, byte *output, unsigned int rounds)
{
ChaCha_OperateKeystream_CORE(state, input, output, rounds);
}

View File

@ -24,6 +24,9 @@
#if defined(__XOP__)
# include <ammintrin.h>
# if defined(__GNUC__)
# include <x86intrin.h>
# endif
#endif
#if defined(__AVX512F__)
@ -31,6 +34,10 @@
# include <immintrin.h>
#endif
// Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670
#define DOUBLE_CAST(x) ((double*)(void*)(x))
#define CONST_DOUBLE_CAST(x) ((const double*)(const void*)(x))
// Squash MS LNK4221 and libtool warnings
extern const char CHAM_SIMD_FNAME[] = __FILE__;
@ -355,7 +362,7 @@ inline void CHAM64_Enc_Block(__m128i &block0,
for (int i=0; i<static_cast<int>(rounds); i+=4)
{
__m128i k, kr, t1, t2, t3, t4;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i+0) & MASK])));
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+0) & MASK])));
// Shuffle out key
kr = _mm_shuffle_epi8(k, _mm_set_epi8(1,0,1,0, 1,0,1,0, 1,0,1,0, 1,0,1,0));
@ -428,7 +435,7 @@ inline void CHAM64_Dec_Block(__m128i &block0,
for (int i = static_cast<int>(rounds)-1; i >= 0; i-=4)
{
__m128i k, kr, t1, t2, t3, t4;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i-3) & MASK])));
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-3) & MASK])));
// Shuffle out key
kr = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,7,6, 7,6,7,6, 7,6,7,6, 7,6,7,6));
@ -505,7 +512,7 @@ inline void CHAM64_Enc_2_Blocks(__m128i &block0,
for (int i=0; i<static_cast<int>(rounds); i+=4)
{
__m128i k, kr, t1, t2, t3, t4;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[i & MASK])));
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+0) & MASK])));
// Shuffle out key
kr = _mm_shuffle_epi8(k, _mm_set_epi8(1,0,1,0, 1,0,1,0, 1,0,1,0, 1,0,1,0));
@ -579,7 +586,7 @@ inline void CHAM64_Dec_2_Blocks(__m128i &block0,
for (int i = static_cast<int>(rounds)-1; i >= 0; i-=4)
{
__m128i k, kr, t1, t2, t3, t4;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i-3) & MASK])));
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-3) & MASK])));
// Shuffle out key
kr = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,7,6, 7,6,7,6, 7,6,7,6, 7,6,7,6));
@ -814,7 +821,7 @@ inline void CHAM128_Enc_Block(__m128i &block0,
for (int i=0; i<static_cast<int>(rounds); i+=4)
{
__m128i k, k1, k2, t1, t2;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i+0) & MASK])));
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+0) & MASK])));
// Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0));
@ -831,8 +838,7 @@ inline void CHAM128_Enc_Block(__m128i &block0,
b = RotateLeft32<1>(_mm_add_epi32(t1, t2));
counter = _mm_add_epi32(counter, increment);
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i+2) & MASK])));
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+2) & MASK])));
// Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0));
@ -874,7 +880,7 @@ inline void CHAM128_Dec_Block(__m128i &block0,
for (int i = static_cast<int>(rounds)-1; i >= 0; i-=4)
{
__m128i k, k1, k2, t1, t2;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i-1) & MASK])));
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-1) & MASK])));
// Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4));
@ -893,7 +899,7 @@ inline void CHAM128_Dec_Block(__m128i &block0,
c = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter);
counter = _mm_sub_epi32(counter, decrement);
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i-3) & MASK])));
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-3) & MASK])));
// Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4));
@ -937,7 +943,7 @@ inline void CHAM128_Enc_4_Blocks(__m128i &block0, __m128i &block1,
for (int i=0; i<static_cast<int>(rounds); i+=4)
{
__m128i k, k1, k2, t1, t2;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i+0) & MASK])));
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+0) & MASK])));
// Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0));
@ -954,7 +960,7 @@ inline void CHAM128_Enc_4_Blocks(__m128i &block0, __m128i &block1,
b = RotateLeft32<1>(_mm_add_epi32(t1, t2));
counter = _mm_add_epi32(counter, increment);
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i+2) & MASK])));
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i+2) & MASK])));
// Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(3,2,1,0, 3,2,1,0, 3,2,1,0, 3,2,1,0));
@ -999,7 +1005,7 @@ inline void CHAM128_Dec_4_Blocks(__m128i &block0, __m128i &block1,
for (int i = static_cast<int>(rounds)-1; i >= 0; i-=4)
{
__m128i k, k1, k2, t1, t2;
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i-1) & MASK])));
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-1) & MASK])));
// Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4));
@ -1018,7 +1024,7 @@ inline void CHAM128_Dec_4_Blocks(__m128i &block0, __m128i &block1,
c = _mm_xor_si128(_mm_sub_epi32(t1, t2), counter);
counter = _mm_sub_epi32(counter, decrement);
k = _mm_castpd_si128(_mm_load_sd((const double*)(&subkeys[(i-3) & MASK])));
k = _mm_castpd_si128(_mm_load_sd(CONST_DOUBLE_CAST(&subkeys[(i-3) & MASK])));
// Shuffle out two subkeys
k1 = _mm_shuffle_epi8(k, _mm_set_epi8(7,6,5,4, 7,6,5,4, 7,6,5,4, 7,6,5,4));

1278
config.h

File diff suppressed because it is too large Load Diff

61
config_align.h Normal file
View File

@ -0,0 +1,61 @@
// config_align.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_align.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_ALIGN_H
#define CRYPTOPP_CONFIG_ALIGN_H
#include "config_cpu.h"
#include "config_cxx.h"
#include "config_ver.h"
// Nearly all Intel's and AMD's have SSE. Enable it independent of SSE ASM and intrinscs
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) && !defined(CRYPTOPP_DISABLE_ASM)
#define CRYPTOPP_BOOL_ALIGN16 1
#else
#define CRYPTOPP_BOOL_ALIGN16 0
#endif
// How to allocate 16-byte aligned memory (for SSE2)
// posix_memalign see https://forum.kde.org/viewtopic.php?p=66274
#if defined(_MSC_VER)
#define CRYPTOPP_MM_MALLOC_AVAILABLE
#elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__)
#define CRYPTOPP_MEMALIGN_AVAILABLE
#elif defined(__APPLE__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
#define CRYPTOPP_MALLOC_ALIGNMENT_IS_16
#elif (defined(_GNU_SOURCE) || ((_XOPEN_SOURCE + 0) >= 600)) && (_POSIX_ADVISORY_INFO > 0)
#define CRYPTOPP_POSIX_MEMALIGN_AVAILABLE
#else
#define CRYPTOPP_NO_ALIGNED_ALLOC
#endif
// Sun Studio Express 3 (December 2006) provides GCC-style attributes.
// IBM XL C/C++ alignment modifier per Optimization Guide, pp. 19-20.
// __IBM_ATTRIBUTES per XLC 12.1 AIX Compiler Manual, p. 473.
// CRYPTOPP_ALIGN_DATA may not be reliable on AIX.
#ifndef CRYPTOPP_ALIGN_DATA
#if defined(CRYPTOPP_CXX11_ALIGNAS)
#define CRYPTOPP_ALIGN_DATA(x) alignas(x)
#elif defined(_MSC_VER)
#define CRYPTOPP_ALIGN_DATA(x) __declspec(align(x))
#elif defined(__GNUC__) || defined(__clang__) || (__SUNPRO_CC >= 0x5100)
#define CRYPTOPP_ALIGN_DATA(x) __attribute__((aligned(x)))
#elif defined(__xlc__) || defined(__xlC__)
#define CRYPTOPP_ALIGN_DATA(x) __attribute__((aligned(x)))
#else
#define CRYPTOPP_ALIGN_DATA(x)
#endif
#endif
#endif // CRYPTOPP_CONFIG_ALIGN_H

418
config_asm.h Normal file
View File

@ -0,0 +1,418 @@
// config_asm.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_asm.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_ASM_H
#define CRYPTOPP_CONFIG_ASM_H
#include "config_os.h"
#include "config_cpu.h"
#include "config_ver.h"
// Define this to disable ASM, intrinsics and built-ins. The library will be
// compiled using C++ only. The library code will not include SSE2 (and
// above), NEON, Aarch32, Aarch64, or Altivec (and above). Note the compiler
// may use higher ISAs depending on compiler options, but the library will not
// explictly use the ISAs. When disabling ASM, it is best to do it from
// config.h to ensure the library and all programs share the setting.
// #define CRYPTOPP_DISABLE_ASM 1
// https://github.com/weidai11/cryptopp/issues/719
#if defined(__native_client__) && !defined(CRYPTOPP_DISABLE_ASM)
# define CRYPTOPP_DISABLE_ASM 1
#endif
// Some Clang and SunCC cannot handle mixed asm with positional arguments,
// where the body is Intel style with no prefix and the templates are
// AT&T style. Define this if the Makefile misdetects the configuration.
// Also see https://bugs.llvm.org/show_bug.cgi?id=39895 .
// #define CRYPTOPP_DISABLE_MIXED_ASM 1
// CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS is no longer honored. It
// was removed at https://github.com/weidai11/cryptopp/issues/682
// #define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS 1
// It is OK to remove the hard stop below, but you are on your own.
// After building the library be sure to run self tests described
// https://www.cryptopp.com/wiki/Release_Process#Self_Tests
// Some relevant bug reports can be found at:
// * Clang: http://github.com/weidai11/cryptopp/issues/147
// * Native Client: https://github.com/weidai11/cryptopp/issues/719
#if (defined(_MSC_VER) && defined(__clang__))
# error: "Unsupported configuration"
#endif
// You may need to force include a C++ header on Android when using STLPort to ensure
// _STLPORT_VERSION is defined: CXXFLAGS="-DNDEBUG -g2 -O2 -std=c++11 -include iosfwd"
// TODO: Figure out C++17 and lack of std::uncaught_exception
#if (defined(_MSC_VER) && _MSC_VER <= 1300) || defined(__MWERKS__) || (defined(_STLPORT_VERSION) && ((_STLPORT_VERSION < 0x450) || defined(_STLP_NO_UNCAUGHT_EXCEPT_SUPPORT)))
#define CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION
#endif
// ***************** IA32 CPU features ********************
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
// Apple Clang prior to 5.0 cannot handle SSE2
#if !defined(CRYPTOPP_DISABLE_ASM) && defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION < 50000)
# define CRYPTOPP_DISABLE_ASM 1
#endif
// Sun Studio 12.1 provides GCC inline assembly
// http://blogs.oracle.com/x86be/entry/gcc_style_asm_inlining_support
#if !defined(CRYPTOPP_DISABLE_ASM) && defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5100)
# define CRYPTOPP_DISABLE_ASM 1
#endif
#if !defined(CRYPTOPP_DISABLE_ASM) && ((defined(_MSC_VER) && defined(_M_IX86)) || (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))))
// C++Builder 2010 does not allow "call label" where label is defined within inline assembly
#define CRYPTOPP_X86_ASM_AVAILABLE 1
#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(_MSC_VER) || CRYPTOPP_GCC_VERSION >= 30300 || defined(__SSE2__))
#define CRYPTOPP_SSE2_ASM_AVAILABLE 1
#endif
#if !defined(CRYPTOPP_DISABLE_SSSE3) && (_MSC_VER >= 1500 || CRYPTOPP_GCC_VERSION >= 40300 || defined(__SSSE3__))
#define CRYPTOPP_SSSE3_ASM_AVAILABLE 1
#endif
#endif
#if !defined(CRYPTOPP_DISABLE_ASM) && defined(_MSC_VER) && defined(_M_X64)
#define CRYPTOPP_X64_MASM_AVAILABLE 1
#endif
#if !defined(CRYPTOPP_DISABLE_ASM) && defined(__GNUC__) && defined(__x86_64__)
#define CRYPTOPP_X64_ASM_AVAILABLE 1
#endif
// 32-bit SunCC does not enable SSE2 by default.
#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_SSE2) && (defined(_MSC_VER) || CRYPTOPP_GCC_VERSION >= 30300 || defined(__SSE2__) || (__SUNPRO_CC >= 0x5100))
#define CRYPTOPP_SSE2_INTRIN_AVAILABLE 1
#endif
#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_SSSE3)
# if defined(__SSSE3__) || (_MSC_VER >= 1500) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1000) || (__SUNPRO_CC >= 0x5110) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 20300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000)
#define CRYPTOPP_SSSE3_AVAILABLE 1
# endif
#endif
// Intrinsics availible in GCC 4.3 (http://gcc.gnu.org/gcc-4.3/changes.html) and
// MSVC 2008 (http://msdn.microsoft.com/en-us/library/bb892950%28v=vs.90%29.aspx)
// SunCC could generate SSE4 at 12.1, but the intrinsics are missing until 12.4.
#if !defined(CRYPTOPP_DISABLE_SSE4) && defined(CRYPTOPP_SSSE3_AVAILABLE) && \
(defined(__SSE4_1__) || (CRYPTOPP_MSC_VERSION >= 1500) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1000) || (__SUNPRO_CC >= 0x5110) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 20300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000))
#define CRYPTOPP_SSE41_AVAILABLE 1
#endif
#if !defined(CRYPTOPP_DISABLE_SSE4) && defined(CRYPTOPP_SSSE3_AVAILABLE) && \
(defined(__SSE4_2__) || (CRYPTOPP_MSC_VERSION >= 1500) || (__SUNPRO_CC >= 0x5110) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1000) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 20300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000))
#define CRYPTOPP_SSE42_AVAILABLE 1
#endif
// Couple to CRYPTOPP_DISABLE_AESNI, but use CRYPTOPP_CLMUL_AVAILABLE so we can selectively
// disable for misbehaving platofrms and compilers, like Solaris or some Clang.
#if defined(CRYPTOPP_DISABLE_AESNI)
#define CRYPTOPP_DISABLE_CLMUL 1
#endif
// Requires Sun Studio 12.3 (SunCC 0x5120) in theory.
#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_CLMUL) && defined(CRYPTOPP_SSE42_AVAILABLE) && \
(defined(__PCLMUL__) || (_MSC_FULL_VER >= 150030729) || (__SUNPRO_CC >= 0x5120) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1110) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30200) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300))
#define CRYPTOPP_CLMUL_AVAILABLE 1
#endif
// Requires Sun Studio 12.3 (SunCC 0x5120)
#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_AESNI) && defined(CRYPTOPP_SSE42_AVAILABLE) && \
(defined(__AES__) || (_MSC_FULL_VER >= 150030729) || (__SUNPRO_CC >= 0x5120) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__INTEL_COMPILER >= 1110) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30200) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300))
#define CRYPTOPP_AESNI_AVAILABLE 1
#endif
// Requires Binutils 2.24
#if !defined(CRYPTOPP_DISABLE_AVX) && defined(CRYPTOPP_SSE42_AVAILABLE) && \
(defined(__AVX2__) || (CRYPTOPP_MSC_VERSION >= 1800) || (__SUNPRO_CC >= 0x5130) || \
(CRYPTOPP_GCC_VERSION >= 40700) || (__INTEL_COMPILER >= 1400) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30100) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40600))
#define CRYPTOPP_AVX_AVAILABLE 1
#endif
// Requires Binutils 2.24
#if !defined(CRYPTOPP_DISABLE_AVX2) && defined(CRYPTOPP_AVX_AVAILABLE) && \
(defined(__AVX2__) || (CRYPTOPP_MSC_VERSION >= 1800) || (__SUNPRO_CC >= 0x5130) || \
(CRYPTOPP_GCC_VERSION >= 40900) || (__INTEL_COMPILER >= 1400) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30100) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40600))
#define CRYPTOPP_AVX2_AVAILABLE 1
#endif
// Guessing at SHA for SunCC. Its not in Sun Studio 12.6. Also see
// http://stackoverflow.com/questions/45872180/which-xarch-for-sha-extensions-on-solaris
#if !defined(CRYPTOPP_DISABLE_ASM) && !defined(CRYPTOPP_DISABLE_SHANI) && defined(CRYPTOPP_SSE42_AVAILABLE) && \
(defined(__SHA__) || (CRYPTOPP_MSC_VERSION >= 1900) || (__SUNPRO_CC >= 0x5160) || \
(CRYPTOPP_GCC_VERSION >= 40900) || (__INTEL_COMPILER >= 1300) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30400) || (CRYPTOPP_APPLE_CLANG_VERSION >= 50100))
#define CRYPTOPP_SHANI_AVAILABLE 1
#endif
// Fixup Android and SSE, Crypto. It may be enabled based on compiler version.
#if (defined(__ANDROID__) || defined(ANDROID))
# if (CRYPTOPP_BOOL_X86)
# undef CRYPTOPP_SSE41_AVAILABLE
# undef CRYPTOPP_SSE42_AVAILABLE
# undef CRYPTOPP_CLMUL_AVAILABLE
# undef CRYPTOPP_AESNI_AVAILABLE
# undef CRYPTOPP_SHANI_AVAILABLE
# endif
# if (CRYPTOPP_BOOL_X64)
# undef CRYPTOPP_CLMUL_AVAILABLE
# undef CRYPTOPP_AESNI_AVAILABLE
# undef CRYPTOPP_SHANI_AVAILABLE
# endif
#endif
// Fixup for SunCC 12.1-12.4. Bad code generation in AES_Encrypt and friends.
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5130)
# undef CRYPTOPP_AESNI_AVAILABLE
#endif
// Fixup for SunCC 12.1-12.6. Compiler crash on GCM_Reduce_CLMUL and friends.
// http://github.com/weidai11/cryptopp/issues/226
#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x5150)
# undef CRYPTOPP_CLMUL_AVAILABLE
#endif
#endif // X86, X32, X64
// ***************** ARM CPU features ********************
#if (CRYPTOPP_BOOL_ARM32 || CRYPTOPP_BOOL_ARMV8)
// We don't have an ARM big endian test rig. Disable
// ARM-BE ASM and instrinsics until we can test it.
#if (CRYPTOPP_BIG_ENDIAN)
# define CRYPTOPP_DISABLE_ASM 1
#endif
// Requires ACLE 1.0. -mfpu=neon or above must be present
// Requires GCC 4.3, Clang 2.8 or Visual Studio 2012
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_NEON_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__arm__) || defined(__ARM_NEON) || defined(__ARM_FEATURE_NEON) || defined(_M_ARM)
# if (CRYPTOPP_GCC_VERSION >= 40300) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20800) || \
(CRYPTOPP_MSC_VERSION >= 1700)
# define CRYPTOPP_ARM_NEON_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and ASIMD. -march=armv8-a or above must be present
// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_ASIMD_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_NEON) || defined(__ARM_FEATURE_NEON) || defined(__ARM_FEATURE_ASIMD) || \
(CRYPTOPP_GCC_VERSION >= 40800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || \
(CRYPTOPP_MSC_VERSION >= 1916)
# define CRYPTOPP_ARM_NEON_AVAILABLE 1
# define CRYPTOPP_ARM_ASIMD_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and ASIMD. -march=armv8-a+crc or above must be present
// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_CRC32_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_FEATURE_CRC32) || (CRYPTOPP_GCC_VERSION >= 40800) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_MSC_VERSION >= 1916)
# define CRYPTOPP_ARM_CRC32_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and ASIMD. -march=armv8-a+crypto or above must be present
// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_PMULL_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_FEATURE_CRYPTO) || (CRYPTOPP_GCC_VERSION >= 40800) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_MSC_VERSION >= 1916)
# define CRYPTOPP_ARM_PMULL_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and AES. -march=armv8-a+crypto or above must be present
// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_AES_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_FEATURE_CRYPTO) || (CRYPTOPP_GCC_VERSION >= 40800) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_MSC_VERSION >= 1916)
# define CRYPTOPP_ARM_AES_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and SHA-1, SHA-256. -march=armv8-a+crypto or above must be present
// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_SHA_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_FEATURE_CRYPTO) || (CRYPTOPP_GCC_VERSION >= 40800) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_MSC_VERSION >= 1916)
# define CRYPTOPP_ARM_SHA1_AVAILABLE 1
# define CRYPTOPP_ARM_SHA2_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and SHA-512, SHA-3. -march=armv8.4-a+crypto or above must be present
// Requires GCC 8.0, Clang ??? or Visual Studio 20??
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_SHA3_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_FEATURE_SHA3) || (CRYPTOPP_GCC_VERSION >= 80000)
# define CRYPTOPP_ARM_SHA512_AVAILABLE 1
# define CRYPTOPP_ARM_SHA3_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// ARMv8 and SM3, SM4. -march=armv8.4-a+crypto or above must be present
// Requires GCC 8.0, Clang ??? or Visual Studio 20??
// Do not use APPLE_CLANG_VERSION; use __ARM_FEATURE_XXX instead.
#if !defined(CRYPTOPP_ARM_SM3_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
# if defined(__ARM_FEATURE_SM3) || (CRYPTOPP_GCC_VERSION >= 80000)
# define CRYPTOPP_ARM_SM3_AVAILABLE 1
# define CRYPTOPP_ARM_SM4_AVAILABLE 1
# endif // Compilers
# endif // Platforms
#endif
// Limit the <arm_acle.h> include.
#if !defined(CRYPTOPP_ARM_ACLE_AVAILABLE)
# if defined(__aarch32__) || defined(__aarch64__) || (__ARM_ARCH >= 8) || defined(__ARM_ACLE)
# if !defined(__ANDROID__) && !defined(ANDROID) && !defined(__APPLE__)
# define CRYPTOPP_ARM_ACLE_AVAILABLE 1
# endif
# endif
#endif
// Fixup Apple Clang and PMULL. Apple defines __ARM_FEATURE_CRYPTO for Xcode 6
// but does not provide PMULL. TODO: determine when PMULL is available.
#if defined(CRYPTOPP_APPLE_CLANG_VERSION) && (CRYPTOPP_APPLE_CLANG_VERSION < 70000)
# undef CRYPTOPP_ARM_PMULL_AVAILABLE
#endif
// Fixup Android and CRC32. It may be enabled based on compiler version.
#if (defined(__ANDROID__) || defined(ANDROID)) && !defined(__ARM_FEATURE_CRC32)
# undef CRYPTOPP_ARM_CRC32_AVAILABLE
#endif
// Fixup Android and Crypto. It may be enabled based on compiler version.
#if (defined(__ANDROID__) || defined(ANDROID)) && !defined(__ARM_FEATURE_CRYPTO)
# undef CRYPTOPP_ARM_PMULL_AVAILABLE
# undef CRYPTOPP_ARM_AES_AVAILABLE
# undef CRYPTOPP_ARM_SHA1_AVAILABLE
# undef CRYPTOPP_ARM_SHA2_AVAILABLE
#endif
// Cryptogams offers an ARM asm implementations for AES and SHA. Crypto++ does
// not provide an asm implementation. The Cryptogams AES implementation is
// about 50% faster than C/C++, and SHA implementation is about 30% faster
// than C/C++. Define this to use the Cryptogams AES and SHA implementations
// on GNU Linux systems. When defined, Crypto++ will use aes_armv4.S,
// sha1_armv4.S and sha256_armv4.S. https://www.cryptopp.com/wiki/Cryptogams.
#if !defined(CRYPTOPP_DISABLE_ASM) && defined(__arm__) && defined(__linux__)
# if defined(__GNUC__) || defined(__clang__)
# define CRYPTOGAMS_ARM_AES 1
# define CRYPTOGAMS_ARM_SHA1 1
# define CRYPTOGAMS_ARM_SHA256 1
# define CRYPTOGAMS_ARM_SHA512 1
# endif
#endif
#endif // ARM32, ARM64
// ***************** AltiVec and Power8 ********************
#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
#if defined(CRYPTOPP_DISABLE_ALTIVEC) || defined(CRYPTOPP_DISABLE_ASM)
# undef CRYPTOPP_DISABLE_ALTIVEC
# undef CRYPTOPP_DISABLE_POWER7
# undef CRYPTOPP_DISABLE_POWER8
# undef CRYPTOPP_DISABLE_POWER9
# define CRYPTOPP_DISABLE_ALTIVEC 1
# define CRYPTOPP_DISABLE_POWER7 1
# define CRYPTOPP_DISABLE_POWER8 1
# define CRYPTOPP_DISABLE_POWER9 1
#endif
// An old Apple G5 with GCC 4.01 has AltiVec, but its only Power4 or so.
#if !defined(CRYPTOPP_ALTIVEC_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ALTIVEC)
# if defined(_ARCH_PWR4) || defined(__ALTIVEC__) || \
(CRYPTOPP_XLC_VERSION >= 100000) || (CRYPTOPP_GCC_VERSION >= 40001) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 20900)
# define CRYPTOPP_ALTIVEC_AVAILABLE 1
# endif
#endif
// We need Power7 for unaligned loads and stores
#if !defined(CRYPTOPP_POWER7_AVAILABLE) && !defined(CRYPTOPP_DISABLE_POWER7) && defined(CRYPTOPP_ALTIVEC_AVAILABLE)
# if defined(_ARCH_PWR7) || (CRYPTOPP_XLC_VERSION >= 100000) || \
(CRYPTOPP_GCC_VERSION >= 40100) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30100)
# define CRYPTOPP_POWER7_AVAILABLE 1
# endif
#endif
// We need Power8 for in-core crypto and 64-bit vector types
#if !defined(CRYPTOPP_POWER8_AVAILABLE) && !defined(CRYPTOPP_DISABLE_POWER8) && defined(CRYPTOPP_POWER7_AVAILABLE)
# if defined(_ARCH_PWR8) || (CRYPTOPP_XLC_VERSION >= 130000) || \
(CRYPTOPP_GCC_VERSION >= 40800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 70000)
# define CRYPTOPP_POWER8_AVAILABLE 1
# endif
#endif
// Power9 for random numbers
#if !defined(CRYPTOPP_POWER9_AVAILABLE) && !defined(CRYPTOPP_DISABLE_POWER9) && defined(CRYPTOPP_POWER8_AVAILABLE)
# if defined(_ARCH_PWR9) || (CRYPTOPP_XLC_VERSION >= 130200) || \
(CRYPTOPP_GCC_VERSION >= 70000) || (CRYPTOPP_LLVM_CLANG_VERSION >= 80000)
# define CRYPTOPP_POWER9_AVAILABLE 1
# endif
#endif
#if !defined(CRYPTOPP_POWER8_AES_AVAILABLE) && !defined(CRYPTOPP_DISABLE_POWER8_AES) && defined(CRYPTOPP_POWER8_AVAILABLE)
# if defined(__CRYPTO__) || defined(_ARCH_PWR8) || (CRYPTOPP_XLC_VERSION >= 130000) || \
(CRYPTOPP_GCC_VERSION >= 40800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 70000)
//# define CRYPTOPP_POWER8_CRC_AVAILABLE 1
# define CRYPTOPP_POWER8_AES_AVAILABLE 1
# define CRYPTOPP_POWER8_VMULL_AVAILABLE 1
# define CRYPTOPP_POWER8_SHA_AVAILABLE 1
# endif
#endif
#endif // PPC32, PPC64
#endif // CRYPTOPP_CONFIG_ASM_H

103
config_cpu.h Normal file
View File

@ -0,0 +1,103 @@
// config_cpu.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_cpu.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// <A HREF="https://sourceforge.net/p/predef/wiki/Architectures/">Sourceforge
/// Pre-defined Compiler Macros</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_CPU_H
#define CRYPTOPP_CONFIG_CPU_H
#include "config_ver.h"
#if (defined(__ILP32__) || defined(_ILP32)) && defined(__x86_64__)
#define CRYPTOPP_BOOL_X32 1
#elif (defined(_M_X64) || defined(__x86_64__))
#define CRYPTOPP_BOOL_X64 1
#elif (defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(_X86_) || defined(__I86__) || defined(__INTEL__))
#define CRYPTOPP_BOOL_X86 1
#endif
// Microsoft added ARM64 define December 2017.
#if defined(__arm64__) || defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64)
#define CRYPTOPP_BOOL_ARMV8 1
#endif
#if defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
#define CRYPTOPP_BOOL_ARM64 1
#elif defined(__arm__) || defined(_M_ARM)
#define CRYPTOPP_BOOL_ARM32 1
#endif
// And PowerPC.
#if defined(__ppc64__) || defined(__powerpc64__) || defined(__PPC64__) || defined(_ARCH_PPC64)
#define CRYPTOPP_BOOL_PPC64 1
#elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) || defined(_ARCH_PPC)
#define CRYPTOPP_BOOL_PPC32 1
#endif
// And MIPS. TODO: finish these defines
#if defined(__mips64__)
#define CRYPTOPP_BOOL_MIPS64 1
#elif defined(__mips__)
#define CRYPTOPP_BOOL_MIPS32 1
#endif
// And SPARC.
#if defined(__sparc64__) || defined(__sparc64) || defined(__sparcv9) || defined(__sparc_v9__)
#define CRYPTOPP_BOOL_SPARC64 1
#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) || defined(__sparc_v8__)
#define CRYPTOPP_BOOL_SPARC32 1
#endif
// This should be a lower bound on the L1 cache line size.
// It's used for defense against timing attacks.
#ifndef CRYPTOPP_L1_CACHE_LINE_SIZE
#if defined(CRYPTOPP_BOOL_X32) || defined(CRYPTOPP_BOOL_X64) || defined(CRYPTOPP_BOOL_ARMV8) || \
defined(CRYPTOPP_BOOL_PPC64) || defined(CRYPTOPP_BOOL_MIPS64) || defined(CRYPTOPP_BOOL_SPARC64)
#define CRYPTOPP_L1_CACHE_LINE_SIZE 64
#else
// L1 cache line size is 32 on Pentium III and earlier
#define CRYPTOPP_L1_CACHE_LINE_SIZE 32
#endif
#endif
// The section attribute attempts to initialize CPU flags to avoid Valgrind findings above -O1
#if ((defined(__MACH__) && defined(__APPLE__)) && ((CRYPTOPP_LLVM_CLANG_VERSION >= 30600) || (CRYPTOPP_APPLE_CLANG_VERSION >= 70100) || (CRYPTOPP_GCC_VERSION >= 40300)))
#define CRYPTOPP_SECTION_INIT __attribute__((section ("__DATA,__data")))
#elif (defined(__ELF__) && (CRYPTOPP_GCC_VERSION >= 40300))
#define CRYPTOPP_SECTION_INIT __attribute__((section ("nocommon")))
#elif defined(__ELF__) && (defined(__xlC__) || defined(__ibmxl__))
#define CRYPTOPP_SECTION_INIT __attribute__((section ("nocommon")))
#else
#define CRYPTOPP_SECTION_INIT
#endif
// How to disable CPU feature probing. We determine machine
// capabilities by performing an os/platform *query* first,
// like getauxv(). If the *query* fails, we move onto a
// cpu *probe*. The cpu *probe* tries to exeute an instruction
// and then catches a SIGILL on Linux or the exception
// EXCEPTION_ILLEGAL_INSTRUCTION on Windows. Some OSes
// fail to hangle a SIGILL gracefully, like Apple OSes. Apple
// machines corrupt memory and variables around the probe.
#if defined(__APPLE__)
#define CRYPTOPP_NO_CPU_FEATURE_PROBES 1
#endif
// Flavor of inline assembly language
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY 1
#else
#define CRYPTOPP_GNU_STYLE_INLINE_ASSEMBLY 1
#endif
#endif

233
config_cxx.h Normal file
View File

@ -0,0 +1,233 @@
// config_cxx.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_cxx.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
// Visual Studio began at VS2010, http://msdn.microsoft.com/en-us/library/hh567368%28v=vs.110%29.aspx
// and https://docs.microsoft.com/en-us/cpp/visual-cpp-language-conformance
// Intel, http://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler
// GCC, http://gcc.gnu.org/projects/cxx0x.html
// Clang, http://clang.llvm.org/cxx_status.html
#ifndef CRYPTOPP_CONFIG_CXX_H
#define CRYPTOPP_CONFIG_CXX_H
#include "config_os.h"
#include "config_cpu.h"
#include "config_ver.h"
// Ancient Crypto++ define, dating back to C++98 and C++03.
#ifndef CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION
# define CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE 1
#endif
// Compatibility with non-clang compilers.
#ifndef __has_feature
# define __has_feature(x) 0
#endif
// Define CRYPTOPP_NO_CXX11 to avoid C++11 related features shown at the
// end of this file. Some compilers and standard C++ headers advertise C++11
// but they are really just C++03 with some additional C++11 headers and
// non-conforming classes. You might also consider `-std=c++03` or
// `-std=gnu++03`, but they are required options when building the library
// and all programs. CRYPTOPP_NO_CXX11 is probably easier to manage but it may
// cause -Wterminate warnings under GCC. MSVC++ has a similar warning.
// Also see https://github.com/weidai11/cryptopp/issues/529
// #define CRYPTOPP_NO_CXX11 1
// Define CRYPTOPP_NO_CXX17 to avoid C++17 related features shown at the end of
// this file. At the moment it should only affect std::uncaught_exceptions.
// #define CRYPTOPP_NO_CXX17 1
// C++11 macro version, https://stackoverflow.com/q/7223991/608639
#if !defined(CRYPTOPP_NO_CXX11)
# if ((_MSC_VER >= 1600) || (__cplusplus >= 201103L)) && !defined(_STLPORT_VERSION)
# define CRYPTOPP_CXX11 1
# endif
#endif
// Hack ahead. Apple's standard library does not have C++'s unique_ptr in C++11.
// We can't test for unique_ptr directly because some of the non-Apple Clangs
// on OS X fail the same way. However, modern standard libraries have
// <forward_list>, so we test for it instead. Thanks to Jonathan Wakely for
// devising the clever test for modern/ancient versions. TODO: test under
// Xcode 3, where g++ is really g++.
#if defined(__APPLE__) && defined(__clang__)
# if !(defined(__has_include) && __has_include(<forward_list>))
# undef CRYPTOPP_CXX11
# endif
#endif
// C++14 macro version, https://stackoverflow.com/q/26089319/608639
#if defined(CRYPTOPP_CXX11) && !defined(CRYPTOPP_NO_CXX14)
# if ((_MSC_VER >= 1900) || (__cplusplus >= 201402L)) && !defined(_STLPORT_VERSION)
# define CRYPTOPP_CXX14 1
# endif
#endif
// C++17 macro version, https://stackoverflow.com/q/38456127/608639
#if defined(CRYPTOPP_CXX14) && !defined(CRYPTOPP_NO_CXX17)
# if ((_MSC_VER >= 1900) || (__cplusplus >= 201703L)) && !defined(_STLPORT_VERSION)
# define CRYPTOPP_CXX17 1
# endif
#endif
// ***************** C++11 and above ********************
#if defined(CRYPTOPP_CXX11)
// atomics: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.1/3.2; Intel 13.0; SunCC 5.14.
#if (CRYPTOPP_MSC_VERSION >= 1700) || __has_feature(cxx_atomic) || \
(__INTEL_COMPILER >= 1300) || (CRYPTOPP_GCC_VERSION >= 40400) || (__SUNPRO_CC >= 0x5140)
# define CRYPTOPP_CXX11_ATOMICS 1
#endif // atomics
// synchronization: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.3; Xcode 5.0; Intel 12.0; SunCC 5.13.
// TODO: verify Clang and Intel versions; find __has_feature(x) extension for Clang
#if (CRYPTOPP_MSC_VERSION >= 1700) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || \
(CRYPTOPP_APPLE_CLANG_VERSION >= 50000) || (__INTEL_COMPILER >= 1200) || \
(CRYPTOPP_GCC_VERSION >= 40400) || (__SUNPRO_CC >= 0x5130)
// Hack ahead. New GCC compilers like GCC 6 on AIX 7.0 or earlier as well as original MinGW
// don't have the synchronization gear. However, Wakely's test used for Apple does not work
// on the GCC/AIX combination. Another twist is we need other stuff from C++11,
// like no-except destructors. Dumping preprocessors shows the following may
// apply: http://stackoverflow.com/q/14191566/608639.
# include <cstddef>
# if !defined(__GLIBCXX__) || defined(_GLIBCXX_HAS_GTHREADS)
# define CRYPTOPP_CXX11_SYNCHRONIZATION 1
# endif
#endif // synchronization
// Dynamic Initialization and Destruction with Concurrency ("Magic Statics")
// MS at VS2015 with Vista (19.00); GCC at 4.3; LLVM Clang at 2.9; Apple Clang at 4.0; Intel 11.1; SunCC 5.13.
// Microsoft's implementation only works for Vista and above, so its further
// limited. http://connect.microsoft.com/VisualStudio/feedback/details/1789709
#if (__cpp_threadsafe_static_init >= 200806) || \
(CRYPTOPP_MSC_VERSION >= 1900) && ((WINVER >= 0x0600) || (_WIN32_WINNT >= 0x0600)) || \
(CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40000) || \
(__INTEL_COMPILER >= 1110) || (CRYPTOPP_GCC_VERSION >= 40300) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_DYNAMIC_INIT 1
#endif // Dynamic Initialization compilers
// deleted functions: MS at VS2013 (18.00); GCC at 4.3; Clang at 2.9; Intel 12.1; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1800) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || \
(CRYPTOPP_APPLE_CLANG_VERSION >= 40000) || (__INTEL_COMPILER >= 1210) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_DELETED_FUNCTIONS 1
#endif // deleted functions
// alignof/alignas: MS at VS2015 (19.00); GCC at 4.8; Clang at 3.0; Intel 15.0; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1900) || __has_feature(cxx_alignas) || \
(__INTEL_COMPILER >= 1500) || (CRYPTOPP_GCC_VERSION >= 40800) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_ALIGNAS 1
#endif // alignas
// alignof: MS at VS2015 (19.00); GCC at 4.5; Clang at 2.9; Intel 15.0; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1900) || __has_feature(cxx_alignof) || \
(__INTEL_COMPILER >= 1500) || (CRYPTOPP_GCC_VERSION >= 40500) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_ALIGNOF 1
#endif // alignof
// lambdas: MS at VS2012 (17.00); GCC at 4.9; Clang at 3.3; Intel 12.0; SunCC 5.14.
#if (CRYPTOPP_MSC_VERSION >= 1700) || __has_feature(cxx_lambdas) || \
(__INTEL_COMPILER >= 1200) || (CRYPTOPP_GCC_VERSION >= 40900) || (__SUNPRO_CC >= 0x5140)
# define CRYPTOPP_CXX11_LAMBDA 1
#endif // lambdas
// noexcept: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.0; Intel 14.0; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1900) || __has_feature(cxx_noexcept) || \
(__INTEL_COMPILER >= 1400) || (CRYPTOPP_GCC_VERSION >= 40600) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_NOEXCEPT 1
#endif // noexcept compilers
// variadic templates: MS at VS2013 (18.00); GCC at 4.3; Clang at 2.9; Intel 12.1; SunCC 5.13.
#if (__cpp_variadic_templates >= 200704) || __has_feature(cxx_variadic_templates) || \
(CRYPTOPP_MSC_VERSION >= 1800) || (__INTEL_COMPILER >= 1210) || \
(CRYPTOPP_GCC_VERSION >= 40300) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_VARIADIC_TEMPLATES 1
#endif // variadic templates
// constexpr: MS at VS2015 (19.00); GCC at 4.6; Clang at 3.1; Intel 16.0; SunCC 5.13.
// Intel has mis-supported the feature since at least ICPC 13.00
#if (__cpp_constexpr >= 200704) || __has_feature(cxx_constexpr) || \
(CRYPTOPP_MSC_VERSION >= 1900) || (__INTEL_COMPILER >= 1600) || \
(CRYPTOPP_GCC_VERSION >= 40600) || (__SUNPRO_CC >= 0x5130)
# define CRYPTOPP_CXX11_CONSTEXPR 1
#endif // constexpr compilers
// strong typed enums: MS at VS2012 (17.00); GCC at 4.4; Clang at 3.3; Intel 14.0; SunCC 5.12.
// Mircorosft and Intel had partial support earlier, but we require full support.
#if (CRYPTOPP_MSC_VERSION >= 1700) || __has_feature(cxx_strong_enums) || \
(__INTEL_COMPILER >= 1400) || (CRYPTOPP_GCC_VERSION >= 40400) || (__SUNPRO_CC >= 0x5120)
# define CRYPTOPP_CXX11_ENUM 1
#endif // constexpr compilers
// nullptr_t: MS at VS2010 (16.00); GCC at 4.6; Clang at 3.3; Intel 10.0; SunCC 5.13.
#if (CRYPTOPP_MSC_VERSION >= 1600) || __has_feature(cxx_nullptr) || \
(__INTEL_COMPILER >= 1000) || (CRYPTOPP_GCC_VERSION >= 40600) || \
(__SUNPRO_CC >= 0x5130) || defined(__IBMCPP_NULLPTR)
# define CRYPTOPP_CXX11_NULLPTR 1
#endif // nullptr_t compilers
#endif // CRYPTOPP_CXX11
// ***************** C++14 and above ********************
#if defined(CRYPTOPP_CXX14)
// Extended static_assert with one argument
// Microsoft cannot handle the single argument static_assert as of VS2019 (cl.exe 19.00)
#if (__cpp_static_assert >= 201411)
# define CRYPTOPP_CXX14_STATIC_ASSERT 1
#endif // static_assert
#endif
// ***************** C++17 and above ********************
// C++17 is available
#if defined(CRYPTOPP_CXX17)
// C++17 uncaught_exceptions: MS at VS2015 (19.00); GCC at 6.0; Clang at 3.5; Intel 18.0.
// Clang and __EXCEPTIONS see http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html
#if defined(__clang__)
# if __EXCEPTIONS && __has_feature(cxx_exceptions)
# if __cpp_lib_uncaught_exceptions
# define CRYPTOPP_CXX17_EXCEPTIONS 1
# endif
# endif
#elif (CRYPTOPP_MSC_VERSION >= 1900) || (__INTEL_COMPILER >= 1800) || \
(CRYPTOPP_GCC_VERSION >= 60000) || (__cpp_lib_uncaught_exceptions)
# define CRYPTOPP_CXX17_EXCEPTIONS 1
#endif // uncaught_exceptions compilers
#endif // CRYPTOPP_CXX17
// ***************** C++ fixups ********************
#if defined(CRYPTOPP_CXX11_NOEXCEPT)
# define CRYPTOPP_THROW noexcept(false)
# define CRYPTOPP_NO_THROW noexcept(true)
#else
# define CRYPTOPP_THROW
# define CRYPTOPP_NO_THROW
#endif // CRYPTOPP_CXX11_NOEXCEPT
// Hack... C++11 nullptr_t type safety and analysis
#if defined(CRYPTOPP_CXX11_NULLPTR) && !defined(NULLPTR)
# define NULLPTR nullptr
#elif !defined(NULLPTR)
# define NULLPTR NULL
#endif // CRYPTOPP_CXX11_NULLPTR
#endif // CRYPTOPP_CONFIG_CXX_H

77
config_dll.h Normal file
View File

@ -0,0 +1,77 @@
// config_dll.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_dll.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_DLL_H
#define CRYPTOPP_CONFIG_DLL_H
#include "config_os.h"
#if !defined(CRYPTOPP_DOXYGEN_PROCESSING)
#if defined(CRYPTOPP_WIN32_AVAILABLE)
#ifdef CRYPTOPP_EXPORTS
# define CRYPTOPP_IS_DLL
# define CRYPTOPP_DLL __declspec(dllexport)
#elif defined(CRYPTOPP_IMPORTS)
# define CRYPTOPP_IS_DLL
# define CRYPTOPP_DLL __declspec(dllimport)
#else
# define CRYPTOPP_DLL
#endif
// C++ makes const internal linkage
#define CRYPTOPP_TABLE extern
#define CRYPTOPP_API __cdecl
#else // not CRYPTOPP_WIN32_AVAILABLE
// C++ makes const internal linkage
#define CRYPTOPP_TABLE extern
#define CRYPTOPP_DLL
#define CRYPTOPP_API
#endif // CRYPTOPP_WIN32_AVAILABLE
#if defined(__MWERKS__)
# define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern class CRYPTOPP_DLL
#elif defined(__BORLANDC__) || defined(__SUNPRO_CC)
# define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL
#else
# define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern template class CRYPTOPP_DLL
#endif
#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_IMPORTS)
# define CRYPTOPP_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL
#else
# define CRYPTOPP_DLL_TEMPLATE_CLASS CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS
#endif
#if defined(__MWERKS__)
# define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern class
#elif defined(__BORLANDC__) || defined(__SUNPRO_CC)
# define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS template class
#else
# define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern template class
#endif
#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_EXPORTS)
# define CRYPTOPP_STATIC_TEMPLATE_CLASS template class
#else
# define CRYPTOPP_STATIC_TEMPLATE_CLASS CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS
#endif
#endif // CRYPTOPP_DOXYGEN_PROCESSING
#endif // CRYPTOPP_CONFIG_DLL_H

103
config_int.h Normal file
View File

@ -0,0 +1,103 @@
// config_int.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_int.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_INT_H
#define CRYPTOPP_CONFIG_INT_H
#include "config_ns.h"
#include "config_ver.h"
// Originally in global namespace to avoid ambiguity with other byte typedefs.
// Moved to Crypto++ namespace due to C++17, std::byte and potential compile
// problems. Also see http://www.cryptopp.com/wiki/std::byte and
// http://github.com/weidai11/cryptopp/issues/442.
// typedef unsigned char byte;
#define CRYPTOPP_NO_GLOBAL_BYTE 1
NAMESPACE_BEGIN(CryptoPP)
// Signed words added at Issue 609 for early versions of and Visual Studio and
// the NaCl gear. Also see https://github.com/weidai11/cryptopp/issues/609.
typedef unsigned char byte;
typedef unsigned short word16;
typedef unsigned int word32;
typedef signed char sbyte;
typedef signed short sword16;
typedef signed int sword32;
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef signed __int64 sword64;
typedef unsigned __int64 word64;
#define SW64LIT(x) x##i64
#define W64LIT(x) x##ui64
#elif (_LP64 || __LP64__)
typedef signed long sword64;
typedef unsigned long word64;
#define SW64LIT(x) x##L
#define W64LIT(x) x##UL
#else
typedef signed long long sword64;
typedef unsigned long long word64;
#define SW64LIT(x) x##LL
#define W64LIT(x) x##ULL
#endif
// define large word type, used for file offsets and such
typedef word64 lword;
const lword LWORD_MAX = W64LIT(0xffffffffffffffff);
// define hword, word, and dword. these are used for multiprecision integer arithmetic
// Intel compiler won't have _umul128 until version 10.0. See http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30231625.aspx
#if (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && defined(__x86_64__)) || (defined(__SUNPRO_CC) && defined(__x86_64__))
typedef word32 hword;
typedef word64 word;
#else
#define CRYPTOPP_NATIVE_DWORD_AVAILABLE 1
#if defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || defined(__x86_64__) || defined(__mips64) || defined(__sparc64__)
#if ((CRYPTOPP_GCC_VERSION >= 30400) || (CRYPTOPP_LLVM_CLANG_VERSION >= 30000) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300)) && (__SIZEOF_INT128__ >= 16)
// GCC 4.0.1 on MacOS X is missing __umodti3 and __udivti3
// GCC 4.8.3 and bad uint128_t ops on PPC64/POWER7 (Issue 421)
// mode(TI) division broken on amd64 with GCC earlier than GCC 3.4
typedef word32 hword;
typedef word64 word;
typedef __uint128_t dword;
typedef __uint128_t word128;
#define CRYPTOPP_WORD128_AVAILABLE 1
#else
// if we're here, it means we're on a 64-bit CPU but we don't have a way to obtain 128-bit multiplication results
typedef word16 hword;
typedef word32 word;
typedef word64 dword;
#endif
#else
// being here means the native register size is probably 32 bits or less
#define CRYPTOPP_BOOL_SLOW_WORD64 1
typedef word16 hword;
typedef word32 word;
typedef word64 dword;
#endif
#endif
#ifndef CRYPTOPP_BOOL_SLOW_WORD64
# define CRYPTOPP_BOOL_SLOW_WORD64 0
#endif
const unsigned int WORD_SIZE = sizeof(word);
const unsigned int WORD_BITS = WORD_SIZE * 8;
NAMESPACE_END
#endif // CRYPTOPP_CONFIG_INT_H

180
config_misc.h Normal file
View File

@ -0,0 +1,180 @@
// config_misc.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_misc.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_MISC_H
#define CRYPTOPP_CONFIG_MISC_H
#include "config_asm.h"
#include "config_cxx.h"
#include "config_os.h"
#include "config_ver.h"
// Define this if running on a big-endian CPU
// big endian will be assumed if CRYPTOPP_LITTLE_ENDIAN is not non-0
#if !defined(CRYPTOPP_LITTLE_ENDIAN) && !defined(CRYPTOPP_BIG_ENDIAN) && (defined(__BIG_ENDIAN__) || (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) || (defined(__m68k__) || defined(__MC68K__)) || defined(__sparc) || defined(__sparc__) || defined(__hppa__) || defined(__MIPSEB__) || defined(__ARMEB__) || (defined(__MWERKS__) && !defined(__INTEL__)))
# define CRYPTOPP_BIG_ENDIAN 1
#endif
// Define this if running on a little-endian CPU
// big endian will be assumed if CRYPTOPP_LITTLE_ENDIAN is not non-0
#if !defined(CRYPTOPP_BIG_ENDIAN) && !defined(CRYPTOPP_LITTLE_ENDIAN)
# define CRYPTOPP_LITTLE_ENDIAN 1
#endif
// Define this if you want to set a prefix for TestData/ and TestVectors/
// Be sure to add the trailing slash since its simple concatenation.
// After https://github.com/weidai11/cryptopp/issues/760 the library
// should find the test vectors and data without much effort. It
// will search in "./" and "$ORIGIN/../share/cryptopp" automatically.
#ifndef CRYPTOPP_DATA_DIR
# define CRYPTOPP_DATA_DIR ""
#endif
// Define this to disable the test suite from searching for test
// vectors and data in "./" and "$ORIGIN/../share/cryptopp". The
// library will still search in CRYPTOPP_DATA_DIR, regardless.
// Some distros may want to disable this feature. Also see
// https://github.com/weidai11/cryptopp/issues/760
// #ifndef CRYPTOPP_DISABLE_DATA_DIR_SEARCH
// # define CRYPTOPP_DISABLE_DATA_DIR_SEARCH
// #endif
// Define this if you want or need the library's memcpy_s and memmove_s.
// See http://github.com/weidai11/cryptopp/issues/28.
// #if !defined(CRYPTOPP_WANT_SECURE_LIB)
// # define CRYPTOPP_WANT_SECURE_LIB
// #endif
// Define this if ARMv8 shifts are slow. ARM Cortex-A53 and Cortex-A57 shift
// operation perform poorly, so NEON and ASIMD code that relies on shifts
// or rotates often performs worse than C/C++ code. Also see
// http://github.com/weidai11/cryptopp/issues/367.
#define CRYPTOPP_SLOW_ARMV8_SHIFT 1
// CRYPTOPP_DEBUG enables the library's CRYPTOPP_ASSERT. CRYPTOPP_ASSERT
// raises a SIGTRAP (Unix) or calls DebugBreak() (Windows). CRYPTOPP_ASSERT
// is only in effect when CRYPTOPP_DEBUG, DEBUG or _DEBUG is defined. Unlike
// Posix assert, CRYPTOPP_ASSERT is not affected by NDEBUG (or failure to
// define it).
// Also see http://github.com/weidai11/cryptopp/issues/277, CVE-2016-7420
#if (defined(DEBUG) || defined(_DEBUG)) && !defined(CRYPTOPP_DEBUG)
# define CRYPTOPP_DEBUG 1
#endif
// File system code to use when creating GZIP archive.
// http://www.gzip.org/format.txt
#if !defined(GZIP_OS_CODE)
# if defined(__macintosh__)
# define GZIP_OS_CODE 7
# elif defined(__unix__) || defined(__linux__)
# define GZIP_OS_CODE 3
# else
# define GZIP_OS_CODE 0
# endif
#endif
// Try this if your CPU has 256K internal cache or a slow multiply instruction
// and you want a (possibly) faster IDEA implementation using log tables
// #define IDEA_LARGECACHE
// Define this if, for the linear congruential RNG, you want to use
// the original constants as specified in S.K. Park and K.W. Miller's
// CACM paper.
// #define LCRNG_ORIGINAL_NUMBERS
// Define this if you want Integer's operator<< to honor std::showbase (and
// std::noshowbase). If defined, Integer will use a suffix of 'b', 'o', 'h'
// or '.' (the last for decimal) when std::showbase is in effect. If
// std::noshowbase is set, then the suffix is not added to the Integer. If
// not defined, existing behavior is preserved and Integer will use a suffix
// of 'b', 'o', 'h' or '.' (the last for decimal).
// #define CRYPTOPP_USE_STD_SHOWBASE
// Define this if you want to decouple AlgorithmParameters and Integer
// The decoupling should make it easier for the linker to remove Integer
// related code for those who do not need Integer, and avoid a potential
// race during AssignIntToInteger pointer initialization. Also
// see http://github.com/weidai11/cryptopp/issues/389.
// #define CRYPTOPP_NO_ASSIGN_TO_INTEGER
// Need GCC 4.6/Clang 1.7/Apple Clang 2.0 or above due to "GCC diagnostic {push|pop}"
#if (CRYPTOPP_GCC_VERSION >= 40600) || (CRYPTOPP_LLVM_CLANG_VERSION >= 10700) || \
(CRYPTOPP_APPLE_CLANG_VERSION >= 20000)
#define CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE 1
#endif
// Portable way to suppress warnings.
// Moved from misc.h due to circular depenedencies.
#ifndef CRYPTOPP_UNUSED
#define CRYPTOPP_UNUSED(x) ((void)(x))
#endif
// how to disable inlining
#if defined(_MSC_VER)
# define CRYPTOPP_NOINLINE_DOTDOTDOT
# define CRYPTOPP_NOINLINE __declspec(noinline)
#elif defined(__xlc__) || defined(__xlC__) || defined(__ibmxl__)
# define CRYPTOPP_NOINLINE_DOTDOTDOT ...
# define CRYPTOPP_NOINLINE __attribute__((noinline))
#elif defined(__GNUC__)
# define CRYPTOPP_NOINLINE_DOTDOTDOT
# define CRYPTOPP_NOINLINE __attribute__((noinline))
#else
# define CRYPTOPP_NOINLINE_DOTDOTDOT ...
# define CRYPTOPP_NOINLINE
#endif
// http://stackoverflow.com/a/13867690/608639
#if defined(CRYPTOPP_CXX11_CONSTEXPR)
# define CRYPTOPP_STATIC_CONSTEXPR static constexpr
# define CRYPTOPP_CONSTEXPR constexpr
#else
# define CRYPTOPP_STATIC_CONSTEXPR static
# define CRYPTOPP_CONSTEXPR
#endif // CRYPTOPP_CXX11_CONSTEXPR
#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
# define CRYPTOPP_CONSTANT(x) static const int x;
#elif defined(CRYPTOPP_CXX11_ENUM)
# define CRYPTOPP_CONSTANT(x) enum : int { x };
#elif defined(CRYPTOPP_CXX11_CONSTEXPR)
# define CRYPTOPP_CONSTANT(x) constexpr static int x;
#else
# define CRYPTOPP_CONSTANT(x) static const int x;
#endif
// Warnings
#ifdef _MSC_VER
// 4127: conditional expression is constant
// 4512: assignment operator not generated
// 4661: no suitable definition provided for explicit template instantiation request
// 4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation
# pragma warning(disable: 4127 4512 4661 4910)
// Security related, possible defects
// http://blogs.msdn.com/b/vcblog/archive/2010/12/14/off-by-default-compiler-warnings-in-visual-c.aspx
# pragma warning(once: 4191 4242 4263 4264 4266 4302 4826 4905 4906 4928)
#endif
#ifdef __BORLANDC__
// 8037: non-const function called for const object. needed to work around BCB2006 bug
# pragma warn -8037
#endif
// [GCC Bug 53431] "C++ preprocessor ignores #pragma GCC diagnostic". Clang honors it.
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
# pragma GCC diagnostic ignored "-Wunknown-pragmas"
# pragma GCC diagnostic ignored "-Wunused-function"
#endif
#endif // CRYPTOPP_CONFIG_MISC_H

68
config_ns.h Normal file
View File

@ -0,0 +1,68 @@
// config_ns.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_ns.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_NAMESPACE_H
#define CRYPTOPP_CONFIG_NAMESPACE_H
// namespace support is now required
#ifdef NO_NAMESPACE
# error namespace support is now required
#endif
#ifdef CRYPTOPP_DOXYGEN_PROCESSING
/// \namespace CryptoPP
/// \brief Crypto++ library namespace
/// \details Nearly all classes are located in the CryptoPP namespace. Within
/// the namespace, there are two additional namespaces.
/// <ul>
/// <li>Name - namespace for names used with NameValuePairs and documented
/// in argnames.h
/// <li>NaCl - namespace for NaCl test functions like crypto_box,
/// crypto_box_open, crypto_sign, and crypto_sign_open
/// <li>Donna - namespace for curve25519 library operations. The name was
/// selected due to use of Langley and Moon's curve25519-donna.
/// <li>Test - namespace for testing and benchmarks classes
/// <li>Weak - namespace for weak and wounded algorithms, like ARC4, MD5
/// and Pananma
/// </ul>
namespace CryptoPP { }
// Bring in the symbols found in the weak namespace; and fold Weak1 into Weak
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
#define Weak1 Weak
// Avoid putting "CryptoPP::" in front of everything in Doxygen output
#define CryptoPP
#define NAMESPACE_BEGIN(x)
#define NAMESPACE_END
// Get Doxygen to generate better documentation for these typedefs
#define DOCUMENTED_TYPEDEF(x, y) class y : public x {};
// Make "protected" "private" so the functions and members are not documented
#define protected private
#else
// Not Doxygen
#define NAMESPACE_BEGIN(x) namespace x {
#define NAMESPACE_END }
#define DOCUMENTED_TYPEDEF(x, y) typedef x y;
#endif // CRYPTOPP_DOXYGEN_PROCESSING
#define ANONYMOUS_NAMESPACE_BEGIN namespace {
#define ANONYMOUS_NAMESPACE_END }
#define USING_NAMESPACE(x) using namespace x;
#define DOCUMENTED_NAMESPACE_BEGIN(x) namespace x {
#define DOCUMENTED_NAMESPACE_END }
#endif // CRYPTOPP_CONFIG_NAMESPACE_H

152
config_os.h Normal file
View File

@ -0,0 +1,152 @@
// config_os.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_os.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_OS_H
#define CRYPTOPP_CONFIG_OS_H
#include "config_ver.h"
// Windows platform
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
#define CRYPTOPP_WIN32_AVAILABLE
#endif
// Unix and Linux platforms
#if defined(__unix__) || defined(__MACH__) || defined(__NetBSD__) || defined(__sun)
#define CRYPTOPP_UNIX_AVAILABLE
#endif
// BSD platforms
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
#define CRYPTOPP_BSD_AVAILABLE
#endif
// Microsoft compilers
#if defined(_MSC_VER) || defined(__fastcall)
#define CRYPTOPP_FASTCALL __fastcall
#else
#define CRYPTOPP_FASTCALL
#endif
// Microsoft compilers
#if defined(_MSC_VER)
#define CRYPTOPP_NO_VTABLE __declspec(novtable)
#else
#define CRYPTOPP_NO_VTABLE
#endif
// Define this if you want to disable all OS-dependent features,
// such as sockets and OS-provided random number generators
// #define NO_OS_DEPENDENCE
// Define this to use features provided by Microsoft's CryptoAPI.
// Currently the only feature used is Windows random number generation.
// This macro will be ignored if NO_OS_DEPENDENCE is defined.
// #define USE_MS_CRYPTOAPI
// Define this to use features provided by Microsoft's CryptoNG API.
// CryptoNG API is available in Vista and above and its cross platform,
// including desktop apps and store apps. Currently the only feature
// used is Windows random number generation.
// This macro will be ignored if NO_OS_DEPENDENCE is defined.
// #define USE_MS_CNGAPI
// If the user did not make a choice, then select CryptoNG if
// targeting Windows 8 or above.
#if !defined(USE_MS_CRYPTOAPI) && !defined(USE_MS_CNGAPI)
# if !defined(_USING_V110_SDK71_) && ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || \
(_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/))
# define USE_MS_CNGAPI
# else
# define USE_MS_CRYPTOAPI
# endif
#endif
// Begin OS features, like init priorities and random numbers
#ifndef NO_OS_DEPENDENCE
// CRYPTOPP_INIT_PRIORITY attempts to manage initialization of C++ static objects.
// Under GCC, the library uses init_priority attribute in the range
// [CRYPTOPP_INIT_PRIORITY, CRYPTOPP_INIT_PRIORITY+100]. Under Windows,
// CRYPTOPP_INIT_PRIORITY enlists "#pragma init_seg(lib)". The platforms
// with gaps are Apple and Sun because they require linker scripts. Apple and
// Sun will use the library's Singletons to initialize and acquire resources.
// Also see http://cryptopp.com/wiki/Static_Initialization_Order_Fiasco
#ifndef CRYPTOPP_INIT_PRIORITY
# define CRYPTOPP_INIT_PRIORITY 250
#endif
// CRYPTOPP_USER_PRIORITY is for other libraries and user code that is using Crypto++
// and managing C++ static object creation. It is guaranteed not to conflict with
// values used by (or would be used by) the Crypto++ library.
#ifndef CRYPTOPP_USER_PRIORITY
# define CRYPTOPP_USER_PRIORITY (CRYPTOPP_INIT_PRIORITY+101)
#endif
// Most platforms allow us to specify when to create C++ objects. Apple and Sun do not.
#if (CRYPTOPP_INIT_PRIORITY > 0) && !(defined(NO_OS_DEPENDENCE) || defined(__APPLE__) || defined(__sun__))
# if (CRYPTOPP_GCC_VERSION >= 30000) || (CRYPTOPP_LLVM_CLANG_VERSION >= 20900) || (_INTEL_COMPILER >= 800)
# define HAVE_GCC_INIT_PRIORITY 1
# elif (CRYPTOPP_MSC_VERSION >= 1310)
# define HAVE_MSC_INIT_PRIORITY 1
# elif defined(__xlc__) || defined(__xlC__) || defined(__ibmxl__)
# define HAVE_XLC_INIT_PRIORITY 1
# endif
#endif // CRYPTOPP_INIT_PRIORITY, NO_OS_DEPENDENCE, Apple, Sun
#if defined(CRYPTOPP_WIN32_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE)
# define HIGHRES_TIMER_AVAILABLE
#endif
#ifdef CRYPTOPP_WIN32_AVAILABLE
# if !defined(WINAPI_FAMILY)
# define THREAD_TIMER_AVAILABLE
# elif defined(WINAPI_FAMILY)
# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
# define THREAD_TIMER_AVAILABLE
# endif
# endif
#endif
#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
# define NONBLOCKING_RNG_AVAILABLE
# define BLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
#endif
// Cygwin/Newlib requires _XOPEN_SOURCE=600
#if defined(CRYPTOPP_UNIX_AVAILABLE)
# define UNIX_SIGNALS_AVAILABLE 1
#endif
#ifdef CRYPTOPP_WIN32_AVAILABLE
# if !defined(WINAPI_FAMILY)
# define NONBLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
# elif defined(WINAPI_FAMILY)
# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
# define NONBLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
# elif !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
# if ((WINVER >= 0x0A00 /*_WIN32_WINNT_WIN10*/) || (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/))
# define NONBLOCKING_RNG_AVAILABLE
# define OS_RNG_AVAILABLE
# endif
# endif
# endif
#endif
#endif // NO_OS_DEPENDENCE
#endif // CRYPTOPP_CONFIG_OS_H

46
config_ver.h Normal file
View File

@ -0,0 +1,46 @@
// config_ver.h - written and placed in public domain by Jeffrey Walton
// the bits that make up this source file are from the
// library's monolithic config.h.
/// \file config_ver.h
/// \brief Library configuration file
/// \details <tt>config.h</tt> was split into components in May 2019 to better
/// integrate with Autoconf and its feature tests. The splitting occured so
/// users could continue to include <tt>config.h</tt> while allowing Autoconf
/// to write new <tt>config_asm.h</tt> and new <tt>config_cxx.h</tt> using
/// its feature tests.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/835">Issue 835</A>
/// \since Crypto++ 8.3
#ifndef CRYPTOPP_CONFIG_VERSION_H
#define CRYPTOPP_CONFIG_VERSION_H
// Library version macro. Since this macro is in a header, it reflects
// the version of the library the headers came from. It is not
// necessarily the version of the library built as a shared object if
// versions are inadvertently mixed and matched.
#define CRYPTOPP_MAJOR 8
#define CRYPTOPP_MINOR 3
#define CRYPTOPP_REVISION 0
#define CRYPTOPP_VERSION 830
#ifdef __GNUC__
# define CRYPTOPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
#if defined(__xlc__) || defined(__xlC__)
# define CRYPTOPP_XLC_VERSION ((__xlC__ / 256) * 10000 + (__xlC__ % 256) * 100)
#endif
// Apple and LLVM's Clang. Apple Clang version 7.0 roughly equals LLVM Clang version 3.7
#if defined(__clang__) && defined(__apple_build_version__)
# define CRYPTOPP_APPLE_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#elif defined(__clang__)
# define CRYPTOPP_LLVM_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#endif
#ifdef _MSC_VER
# define CRYPTOPP_MSC_VERSION (_MSC_VER)
#endif
#endif // CRYPTOPP_CONFIG_VERSION_H

119
cpu.cpp
View File

@ -58,7 +58,7 @@ unsigned long int getauxval(unsigned long int) { return 0; }
// Visual Studio 2008 and below is missing _xgetbv. See x64dll.asm for the body.
#if defined(_MSC_VER) && _MSC_VER <= 1500 && defined(_M_X64)
extern "C" unsigned long long __fastcall ExtendedControlRegister(unsigned int);
extern "C" unsigned long long __fastcall XGETBV64(unsigned int);
#endif
ANONYMOUS_NAMESPACE_BEGIN
@ -109,6 +109,8 @@ bool IsAppleMachineARMv8(unsigned int device, unsigned int version)
bool IsAppleMachineARMv84(unsigned int device, unsigned int version)
{
CRYPTOPP_UNUSED(device);
CRYPTOPP_UNUSED(version);
return false;
}
#endif // __APPLE__
@ -274,10 +276,14 @@ static inline bool IsIntel(const word32 output[4])
static inline bool IsAMD(const word32 output[4])
{
// This is the "AuthenticAMD" string. Some early K5's can return "AMDisbetter!"
return (output[1] /*EBX*/ == 0x68747541) &&
// This is the "AuthenticAMD" string.
return ((output[1] /*EBX*/ == 0x68747541) &&
(output[2] /*ECX*/ == 0x444D4163) &&
(output[3] /*EDX*/ == 0x69746E65);
(output[3] /*EDX*/ == 0x69746E65)) ||
// Some early K5's can return "AMDisbetter!"
((output[1] /*EBX*/ == 0x69444d41) &&
(output[2] /*ECX*/ == 0x74656273) &&
(output[3] /*EDX*/ == 0x21726574));
}
static inline bool IsHygon(const word32 output[4])
@ -290,10 +296,14 @@ static inline bool IsHygon(const word32 output[4])
static inline bool IsVIA(const word32 output[4])
{
// This is the "CentaurHauls" string. Some non-PadLock's can return "VIA VIA VIA "
return (output[1] /*EBX*/ == 0x746e6543) &&
// This is the "CentaurHauls" string.
return ((output[1] /*EBX*/ == 0x746e6543) &&
(output[2] /*ECX*/ == 0x736c7561) &&
(output[3] /*EDX*/ == 0x48727561);
(output[3] /*EDX*/ == 0x48727561)) ||
// Some non-PadLock's return "VIA VIA VIA "
((output[1] /*EBX*/ == 0x32414956) &&
(output[2] /*ECX*/ == 0x32414956) &&
(output[3] /*EDX*/ == 0x32414956));
}
void DetectX86Features()
@ -341,8 +351,8 @@ void DetectX86Features()
word64 xcr0 = a | static_cast<word64>(d) << 32;
g_hasAVX = (xcr0 & YMM_FLAG) == YMM_FLAG;
// Visual Studio 2008 and below lack xgetbv
#elif defined(_MSC_VER) && _MSC_VER <= 1500 && defined(_M_IX86)
// Visual Studio 2010 and below lack xgetbv
#elif defined(_MSC_VER) && _MSC_VER <= 1600 && defined(_M_IX86)
word32 a=0, d=0;
__asm {
push eax
@ -363,7 +373,7 @@ void DetectX86Features()
// Visual Studio 2008 and below lack xgetbv
#elif defined(_MSC_VER) && _MSC_VER <= 1500 && defined(_M_X64)
word64 xcr0 = ExtendedControlRegister(0);
word64 xcr0 = XGETBV64(0);
g_hasAVX = (xcr0 & YMM_FLAG) == YMM_FLAG;
// Downlevel SunCC
@ -425,6 +435,7 @@ void DetectX86Features()
}
else if (IsVIA(cpuid0))
{
// Two bits: available and enabled
CRYPTOPP_CONSTANT( RNG_FLAGS = (0x3 << 2))
CRYPTOPP_CONSTANT( ACE_FLAGS = (0x3 << 6))
CRYPTOPP_CONSTANT(ACE2_FLAGS = (0x3 << 8))
@ -432,9 +443,10 @@ void DetectX86Features()
CRYPTOPP_CONSTANT( PMM_FLAGS = (0x3 << 12))
CpuId(0xC0000000, 0, cpuid2);
if (cpuid2[0] >= 0xC0000001)
word32 extendedFeatures = cpuid2[0];
if (extendedFeatures >= 0xC0000001)
{
// Extended features available
CpuId(0xC0000001, 0, cpuid2);
g_hasPadlockRNG = (cpuid2[3] /*EDX*/ & RNG_FLAGS) == RNG_FLAGS;
g_hasPadlockACE = (cpuid2[3] /*EDX*/ & ACE_FLAGS) == ACE_FLAGS;
@ -442,7 +454,21 @@ void DetectX86Features()
g_hasPadlockPHE = (cpuid2[3] /*EDX*/ & PHE_FLAGS) == PHE_FLAGS;
g_hasPadlockPMM = (cpuid2[3] /*EDX*/ & PMM_FLAGS) == PMM_FLAGS;
}
if (extendedFeatures >= 0xC0000005)
{
CpuId(0xC0000005, 0, cpuid2);
g_cacheLineSize = GETBYTE(cpuid2[2] /*ECX*/, 0);
}
}
#if defined(_SC_LEVEL1_DCACHE_LINESIZE)
// Glibc does not implement on some platforms. The runtime returns 0 instead of error.
// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c
int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
if (g_cacheLineSize == 0 && cacheLineSize > 0)
g_cacheLineSize = cacheLineSize;
#endif
if (g_cacheLineSize == 0)
g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
@ -474,7 +500,7 @@ word32 CRYPTOPP_SECTION_INIT g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
// then *Probe* the cpu executing an instruction and an observe a SIGILL if unsupported.
// The probes are in source files where compilation options like -march=armv8-a+crc make
// intrinsics available. They are expensive when compared to a standard OS feature query.
// Always perform the feature quesry first. For Linux see
// Always perform the feature query first. For Linux see
// http://sourceware.org/ml/libc-help/2017-08/msg00012.html
// Avoid probes on Apple platforms because Apple's signal handling for SIGILLs appears broken.
// We are trying to figure out a way to feature test without probes. Also see
@ -486,13 +512,14 @@ extern bool CPU_ProbeNEON();
extern bool CPU_ProbeCRC32();
extern bool CPU_ProbeAES();
extern bool CPU_ProbeSHA1();
extern bool CPU_ProbeSHA2();
extern bool CPU_ProbeSHA256();
extern bool CPU_ProbeSHA512();
extern bool CPU_ProbeSHA3();
extern bool CPU_ProbeSM3();
extern bool CPU_ProbeSM4();
extern bool CPU_ProbePMULL();
// https://github.com/torvalds/linux/blob/master/arch/arm/include/uapi/asm/hwcap.h
// https://github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/hwcap.h
#ifndef HWCAP_ARMv7
# define HWCAP_ARMv7 (1 << 29)
@ -500,8 +527,8 @@ extern bool CPU_ProbePMULL();
#ifndef HWCAP_ASIMD
# define HWCAP_ASIMD (1 << 1)
#endif
#ifndef HWCAP_ARM_NEON
# define HWCAP_ARM_NEON 4096
#ifndef HWCAP_NEON
# define HWCAP_NEON (1 << 12)
#endif
#ifndef HWCAP_CRC32
# define HWCAP_CRC32 (1 << 7)
@ -548,15 +575,13 @@ extern bool CPU_ProbePMULL();
inline bool CPU_QueryARMv7()
{
#if defined(__aarch32__) || defined(__aarch64__)
// ARMv7 or above
return true;
#elif defined(__ANDROID__) && defined(__arm__)
#if defined(__ANDROID__) && defined(__arm__)
if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM) != 0) &&
((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_ARMv7) != 0))
return true;
#elif defined(__linux__) && defined(__arm__)
if ((getauxval(AT_HWCAP) & HWCAP_ARMv7) != 0)
if ((getauxval(AT_HWCAP) & HWCAP_ARMv7) != 0 ||
(getauxval(AT_HWCAP) & HWCAP_NEON) != 0)
return true;
#elif defined(__APPLE__) && defined(__arm__)
// Apple hardware is ARMv7 or above.
@ -582,7 +607,7 @@ inline bool CPU_QueryNEON()
if ((getauxval(AT_HWCAP2) & HWCAP2_ASIMD) != 0)
return true;
#elif defined(__linux__) && defined(__arm__)
if ((getauxval(AT_HWCAP) & HWCAP_ARM_NEON) != 0)
if ((getauxval(AT_HWCAP) & HWCAP_NEON) != 0)
return true;
#elif defined(__APPLE__) && defined(__aarch64__)
// Core feature set for Aarch32 and Aarch64.
@ -685,7 +710,7 @@ inline bool CPU_QuerySHA1()
return false;
}
inline bool CPU_QuerySHA2()
inline bool CPU_QuerySHA256()
{
#if defined(__ANDROID__) && defined(__aarch64__)
if (((android_getCpuFamily() & ANDROID_CPU_FAMILY_ARM64) != 0) &&
@ -819,13 +844,13 @@ void DetectArmFeatures()
g_hasPMULL = CPU_QueryPMULL() || CPU_ProbePMULL();
g_hasAES = CPU_QueryAES() || CPU_ProbeAES();
g_hasSHA1 = CPU_QuerySHA1() || CPU_ProbeSHA1();
g_hasSHA2 = CPU_QuerySHA2() || CPU_ProbeSHA2();
g_hasSHA2 = CPU_QuerySHA256() || CPU_ProbeSHA256();
g_hasSHA512 = CPU_QuerySHA512(); // || CPU_ProbeSHA512();
g_hasSHA3 = CPU_QuerySHA3(); // || CPU_ProbeSHA3();
g_hasSM3 = CPU_QuerySM3(); // || CPU_ProbeSM3();
g_hasSM4 = CPU_QuerySM4(); // || CPU_ProbeSM4();
#if defined(__linux__) && defined(_SC_LEVEL1_DCACHE_LINESIZE)
#if defined(_SC_LEVEL1_DCACHE_LINESIZE)
// Glibc does not implement on some platforms. The runtime returns 0 instead of error.
// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c
int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
@ -833,6 +858,9 @@ void DetectArmFeatures()
g_cacheLineSize = cacheLineSize;
#endif
if (g_cacheLineSize == 0)
g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
*const_cast<volatile bool*>(&g_ArmDetectionDone) = true;
}
@ -862,24 +890,6 @@ extern bool CPU_ProbeSHA256();
extern bool CPU_ProbeSHA512();
extern bool CPU_ProbeDARN();
// Linux define values from 64-Bit ELF V2 ABI Specification.
// http://openpowerfoundation.org/wp-content/uploads/resources/leabi/content/ch_preface.html
#ifndef PPC_FEATURE_HAS_ALTIVEC
# define PPC_FEATURE_HAS_ALTIVEC 0x10000000
#endif
#ifndef PPC_FEATURE_ARCH_2_06
# define PPC_FEATURE_ARCH_2_06 0x00000100
#endif
#ifndef PPC_FEATURE2_ARCH_2_07
# define PPC_FEATURE2_ARCH_2_07 0x80000000
#endif
#ifndef PPC_FEATURE2_ARCH_3_00
# define PPC_FEATURE2_ARCH_3_00 0x00800000
#endif
#ifndef PPC_FEATURE2_VEC_CRYPTO
# define PPC_FEATURE2_VEC_CRYPTO 0x02000000
#endif
// AIX defines. We used to just call __power_7_andup()
// and friends but at Power9, too many compilers were
// missing __power_9_andup(). Instead we switched to
@ -901,7 +911,7 @@ extern bool CPU_ProbeDARN();
// was available much earlier for other vendors.
inline bool CPU_QueryAltivec()
{
#if defined(__linux__)
#if defined(__linux__) && defined(PPC_FEATURE_HAS_ALTIVEC)
if ((getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC) != 0)
return true;
#elif defined(_AIX)
@ -918,7 +928,7 @@ inline bool CPU_QueryAltivec()
inline bool CPU_QueryPower7()
{
// Power7 and ISA 2.06
#if defined(__linux__)
#if defined(__linux__) && defined(PPC_FEATURE_ARCH_2_06)
if ((getauxval(AT_HWCAP) & PPC_FEATURE_ARCH_2_06) != 0)
return true;
#elif defined(_AIX)
@ -931,7 +941,7 @@ inline bool CPU_QueryPower7()
inline bool CPU_QueryPower8()
{
// Power8 and ISA 2.07 provide in-core crypto.
#if defined(__linux__)
#if defined(__linux__) && defined(PPC_FEATURE2_ARCH_2_07)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) != 0)
return true;
#elif defined(_AIX)
@ -944,7 +954,7 @@ inline bool CPU_QueryPower8()
inline bool CPU_QueryPower9()
{
// Power9 and ISA 3.0.
#if defined(__linux__)
#if defined(__linux__) && defined(PPC_FEATURE2_ARCH_3_00)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) != 0)
return true;
#elif defined(_AIX)
@ -958,7 +968,7 @@ inline bool CPU_QueryAES()
{
// Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
#if defined(__linux__)
#if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
return true;
#elif defined(_AIX)
@ -972,7 +982,7 @@ inline bool CPU_QueryPMULL()
{
// Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
#if defined(__linux__)
#if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
return true;
#elif defined(_AIX)
@ -986,7 +996,7 @@ inline bool CPU_QuerySHA256()
{
// Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
#if defined(__linux__)
#if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
return true;
#elif defined(_AIX)
@ -999,7 +1009,7 @@ inline bool CPU_QuerySHA512()
{
// Power8 and ISA 2.07 provide in-core crypto. Glibc
// 2.24 or higher is required for PPC_FEATURE2_VEC_CRYPTO.
#if defined(__linux__)
#if defined(__linux__) && defined(PPC_FEATURE2_VEC_CRYPTO)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) != 0)
return true;
#elif defined(_AIX)
@ -1013,7 +1023,7 @@ inline bool CPU_QuerySHA512()
inline bool CPU_QueryDARN()
{
// Power9 and ISA 3.0 provide DARN.
#if defined(__linux__)
#if defined(__linux__) && defined(PPC_FEATURE2_ARCH_3_00)
if ((getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_3_00) != 0)
return true;
#elif defined(_AIX)
@ -1042,7 +1052,7 @@ void DetectPowerpcFeatures()
int cacheLineSize = getsystemcfg(SC_L1C_DLS);
if (cacheLineSize > 0)
g_cacheLineSize = cacheLineSize;
#elif defined(__linux__) && defined(_SC_LEVEL1_DCACHE_LINESIZE)
#elif defined(_SC_LEVEL1_DCACHE_LINESIZE)
// Glibc does not implement on some platforms. The runtime returns 0 instead of error.
// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/posix/sysconf.c
int cacheLineSize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
@ -1050,6 +1060,9 @@ void DetectPowerpcFeatures()
g_cacheLineSize = cacheLineSize;
#endif
if (g_cacheLineSize == 0)
g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE;
*const_cast<volatile bool*>(&g_PowerpcDetectionDone) = true;
}

View File

@ -212,6 +212,7 @@
<ClCompile Include="gcm.cpp" />
<ClCompile Include="gcm_simd.cpp" />
<ClCompile Include="gf2n.cpp" />
<ClCompile Include="gf2n_simd.cpp" />
<ClCompile Include="gfpcrypt.cpp" />
<ClCompile Include="hex.cpp" />
<ClCompile Include="hmac.cpp" />
@ -255,6 +256,16 @@
<ClInclude Include="channels.h" />
<ClInclude Include="cmac.h" />
<ClInclude Include="config.h" />
<ClInclude Include="config_align.h" />
<ClInclude Include="config_asm.h" />
<ClInclude Include="config_cpu.h" />
<ClInclude Include="config_cxx.h" />
<ClInclude Include="config_dll.h" />
<ClInclude Include="config_int.h" />
<ClInclude Include="config_misc.h" />
<ClInclude Include="config_ns.h" />
<ClInclude Include="config_os.h" />
<ClInclude Include="config_ver.h" />
<ClInclude Include="cpu.h" />
<ClInclude Include="cryptlib.h" />
<ClInclude Include="des.h" />

View File

@ -98,6 +98,9 @@
<ClCompile Include="gf2n.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gf2n_simd.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gfpcrypt.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -229,6 +232,36 @@
<ClInclude Include="config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_align.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_asm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_cpu.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_cxx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_dll.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_int.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_misc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_ns.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_os.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_ver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cpu.h">
<Filter>Header Files</Filter>
</ClInclude>

View File

@ -69,21 +69,22 @@ LIB_SRCS = \
gcm_simd.cpp gf256.cpp gf2_32.cpp gf2n.cpp gf2n_simd.cpp gfpcrypt.cpp \
gost.cpp gzip.cpp hc128.cpp hc256.cpp hex.cpp hight.cpp hmac.cpp \
hrtimer.cpp ida.cpp idea.cpp iterhash.cpp kalyna.cpp kalynatab.cpp \
keccak.cpp keccakc.cpp lea.cpp lea_simd.cpp luc.cpp mars.cpp marss.cpp \
md2.cpp md4.cpp md5.cpp misc.cpp modes.cpp mqueue.cpp mqv.cpp \
nbtheory.cpp neon_simd.cpp oaep.cpp osrng.cpp padlkrng.cpp panama.cpp \
pkcspad.cpp poly1305.cpp polynomi.cpp ppc_power7.cpp ppc_power8.cpp \
ppc_power9.cpp ppc_simd.cpp pssr.cpp pubkey.cpp queue.cpp rabbit.cpp \
rabin.cpp randpool.cpp rc2.cpp rc5.cpp rc6.cpp rdrand.cpp rdtables.cpp \
rijndael.cpp rijndael_simd.cpp ripemd.cpp rng.cpp rsa.cpp rw.cpp \
safer.cpp salsa.cpp scrypt.cpp seal.cpp seed.cpp serpent.cpp sha.cpp \
sha3.cpp sha_simd.cpp shacal2.cpp shacal2_simd.cpp shark.cpp sharkbox.cpp \
simeck.cpp simeck_simd.cpp simon.cpp simon128_simd.cpp simon64_simd.cpp \
skipjack.cpp sm3.cpp sm4.cpp sm4_simd.cpp sosemanuk.cpp speck.cpp \
speck128_simd.cpp speck64_simd.cpp square.cpp squaretb.cpp sse_simd.cpp \
strciphr.cpp tea.cpp tftables.cpp threefish.cpp tiger.cpp tigertab.cpp \
ttmac.cpp tweetnacl.cpp twofish.cpp vmac.cpp wake.cpp whrlpool.cpp \
xed25519.cpp xtr.cpp xtrcrypt.cpp zdeflate.cpp zinflate.cpp zlib.cpp
keccak.cpp keccak_core.cpp keccak_simd.cpp lea.cpp lea_simd.cpp luc.cpp \
mars.cpp marss.cpp md2.cpp md4.cpp md5.cpp misc.cpp modes.cpp mqueue.cpp \
mqv.cpp nbtheory.cpp neon_simd.cpp oaep.cpp osrng.cpp padlkrng.cpp \
panama.cpp pkcspad.cpp poly1305.cpp polynomi.cpp ppc_power7.cpp \
ppc_power8.cpp ppc_power9.cpp ppc_simd.cpp pssr.cpp pubkey.cpp queue.cpp \
rabbit.cpp rabin.cpp randpool.cpp rc2.cpp rc5.cpp rc6.cpp rdrand.cpp \
rdtables.cpp rijndael.cpp rijndael_simd.cpp ripemd.cpp rng.cpp rsa.cpp \
rw.cpp safer.cpp salsa.cpp scrypt.cpp seal.cpp seed.cpp serpent.cpp \
sha.cpp sha3.cpp sha_simd.cpp shacal2.cpp shacal2_simd.cpp shake.cpp \
shark.cpp sharkbox.cpp simeck.cpp simeck_simd.cpp simon.cpp \
simon128_simd.cpp simon64_simd.cpp skipjack.cpp sm3.cpp sm4.cpp \
sm4_simd.cpp sosemanuk.cpp speck.cpp speck128_simd.cpp speck64_simd.cpp \
square.cpp squaretb.cpp sse_simd.cpp strciphr.cpp tea.cpp tftables.cpp \
threefish.cpp tiger.cpp tigertab.cpp ttmac.cpp tweetnacl.cpp twofish.cpp \
vmac.cpp wake.cpp whrlpool.cpp xed25519.cpp xtr.cpp xtrcrypt.cpp \
zdeflate.cpp zinflate.cpp zlib.cpp
LIB_OBJS = \
cryptlib.obj cpu.obj integer.obj 3way.obj adler32.obj algebra.obj \
@ -99,24 +100,25 @@ LIB_OBJS = \
gcm_simd.obj gf256.obj gf2_32.obj gf2n.obj gf2n_simd.obj gfpcrypt.obj \
gost.obj gzip.obj hc128.obj hc256.obj hex.obj hight.obj hmac.obj \
hrtimer.obj ida.obj idea.obj iterhash.obj kalyna.obj kalynatab.obj \
keccak.obj keccakc.obj lea.obj lea_simd.obj luc.obj mars.obj marss.obj \
md2.obj md4.obj md5.obj misc.obj modes.obj mqueue.obj mqv.obj \
nbtheory.obj neon_simd.obj oaep.obj osrng.obj padlkrng.obj panama.obj \
pkcspad.obj poly1305.obj polynomi.obj ppc_power7.obj ppc_power8.obj \
ppc_power9.obj ppc_simd.obj pssr.obj pubkey.obj queue.obj rabbit.obj \
rabin.obj randpool.obj rc2.obj rc5.obj rc6.obj rdrand.obj rdtables.obj \
rijndael.obj rijndael_simd.obj ripemd.obj rng.obj rsa.obj rw.obj \
safer.obj salsa.obj scrypt.obj seal.obj seed.obj serpent.obj sha.obj \
sha3.obj sha_simd.obj shacal2.obj shacal2_simd.obj shark.obj sharkbox.obj \
simeck.obj simeck_simd.obj simon.obj simon128_simd.obj simon64_simd.obj \
skipjack.obj sm3.obj sm4.obj sm4_simd.obj sosemanuk.obj speck.obj \
speck128_simd.obj speck64_simd.obj square.obj squaretb.obj sse_simd.obj \
strciphr.obj tea.obj tftables.obj threefish.obj tiger.obj tigertab.obj \
ttmac.obj tweetnacl.obj twofish.obj vmac.obj wake.obj whrlpool.obj \
xed25519.obj xtr.obj xtrcrypt.obj zdeflate.obj zinflate.obj zlib.obj
keccak.obj keccak_core.obj keccak_simd.obj lea.obj lea_simd.obj luc.obj \
mars.obj marss.obj md2.obj md4.obj md5.obj misc.obj modes.obj mqueue.obj \
mqv.obj nbtheory.obj neon_simd.obj oaep.obj osrng.obj padlkrng.obj \
panama.obj pkcspad.obj poly1305.obj polynomi.obj ppc_power7.obj \
ppc_power8.obj ppc_power9.obj ppc_simd.obj pssr.obj pubkey.obj queue.obj \
rabbit.obj rabin.obj randpool.obj rc2.obj rc5.obj rc6.obj rdrand.obj \
rdtables.obj rijndael.obj rijndael_simd.obj ripemd.obj rng.obj rsa.obj \
rw.obj safer.obj salsa.obj scrypt.obj seal.obj seed.obj serpent.obj \
sha.obj sha3.obj sha_simd.obj shacal2.obj shacal2_simd.obj shake.obj \
shark.obj sharkbox.obj simeck.obj simeck_simd.obj simon.obj \
simon128_simd.obj simon64_simd.obj skipjack.obj sm3.obj sm4.obj \
sm4_simd.obj sosemanuk.obj speck.obj speck128_simd.obj speck64_simd.obj \
square.obj squaretb.obj sse_simd.obj strciphr.obj tea.obj tftables.obj \
threefish.obj tiger.obj tigertab.obj ttmac.obj tweetnacl.obj twofish.obj \
vmac.obj wake.obj whrlpool.obj xed25519.obj xtr.obj xtrcrypt.obj \
zdeflate.obj zinflate.obj zlib.obj
ASM_OBJS = \
rdrand-x86.obj rdrand-x64.obj x64masm.obj x64dll.obj
rdrand-x86.obj rdrand-x64.obj rdseed-x86.obj rdseed-x64.obj x64masm.obj x64dll.obj
TEST_SRCS = \
test.cpp bench1.cpp bench2.cpp bench3.cpp datatest.cpp \
@ -151,12 +153,14 @@ LDFLAGS = /nologo /SUBSYSTEM:CONSOLE /DEBUG
ARFLAGS = /nologo
LDLIBS =
# Debug build.
# Compiler debug build.
# CXXFLAGS = $(CXXFLAGS) /DDEBUG /D_DEBUG /Oi /Oy- /Od /MTd
# Release build. Add /OPT:REF to linker
# Compiler release build.
CXXFLAGS = $(CXXFLAGS) /DNDEBUG /D_NDEBUG /Oi /Oy /O2 /MT
# Linker flags.
LDFLAGS = $(LDFLAGS) /OPT:REF
# Linker debug build.
# LDFLAGS = $(LDFLAGS) /DEBUG
# Linker release build.
LDFLAGS = $(LDFLAGS) /DEBUG /OPT:REF
# Attempt to detect when <sdkddkver.h> and <winapifamily.h> are available
# http://stackoverflow.com/q/40577415 ?
@ -192,10 +196,12 @@ PLATFORM = x64
# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP
AS = ml.exe
ASFLAGS = /nologo /D_M_X86 /W3 /Cx /Zi /safeseh
LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm
LIB_OBJS = $(LIB_OBJS) rdrand-x86.obj
LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm rdseed.asm
LIB_OBJS = $(LIB_OBJS) rdrand-x86.obj rdseed-x86.obj
LDFLAGS = $(LDFLAGS) /MACHINE:X86
LDLIBS = $(LDLIBS) kernel32.lib
RDRAND_OBJ = rdrand-x86.obj
RDSEED_OBJ = rdseed-x86.obj
!ENDIF
# May need $(VCINSTALLDIR)\bin\amd64\ml64.exe
@ -205,10 +211,12 @@ LDLIBS = $(LDLIBS) kernel32.lib
# CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP
AS = ml64.exe
ASFLAGS = /nologo /D_M_X64 /W3 /Cx /Zi
LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm
LIB_OBJS = $(LIB_OBJS) rdrand-x64.obj x64masm.obj x64dll.obj
LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm rdseed.asm
LIB_OBJS = $(LIB_OBJS) rdrand-x64.obj rdseed-x64.obj x64masm.obj x64dll.obj
LDFLAGS = $(LDFLAGS) /MACHINE:X64
LDLIBS = $(LDLIBS) kernel32.lib
RDRAND_OBJ = rdrand-x64.obj
RDSEED_OBJ = rdseed-x64.obj
!ENDIF
!IF "$(PLATFORM)" == "ARM" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "ARM64" || "$(PLATFORM)" == "arm64"
@ -256,13 +264,13 @@ clean ::
$(RM) /F /Q pch.obj $(LIB_OBJS) $(ASM_OBJS) $(TEST_OBJS) *.pdb 2>nul
distclean :: clean
!IF EXIST ($(USERNAME).sdf)
attrib -r -a -s -h $(USERNAME).sdf 2>nul
$(RM) /F /Q $(USERNAME).sdf 2>nul
!IF EXIST ("$(USERNAME).sdf")
attrib -r -a -s -h "$(USERNAME).sdf" 2>nul
$(RM) /F /Q "$(USERNAME).sdf" 2>nul
!ENDIF
!IF EXIST ($(USERNAME).suo)
attrib -r -a -s -h $(USERNAME).suo 2>nul
$(RM) /F /Q $(USERNAME).suo 2>nul
!IF EXIST ("$(USERNAME).suo")
attrib -r -a -s -h $(USERNAME).suo" 2>nul
$(RM) /F /Q $(USERNAME).suo" 2>nul
!ENDIF
!IF EXIST (Win32\)
$(RMDIR) Win32\ /q /s 2>nul
@ -279,21 +287,25 @@ pch.pch: pch.h pch.cpp
$(CXX) $(CXXFLAGS) /Yc"pch.h" /Fp"pch.pch" /c pch.cpp
# No precompiled headers
iterhash.obj:
iterhash.obj: iterhash.h iterhash.cpp
$(CXX) $(CXXFLAGS) /Y- /c iterhash.cpp
dll.obj:
dll.obj: dll.h dll.cpp
$(CXX) $(CXXFLAGS) /Y- /c dll.cpp
rdrand.obj:
rdrand.obj: rdrand.h rdrand.cpp
$(CXX) $(CXXFLAGS) /c rdrand.cpp
# Built for x86/x64
rdrand-x86.obj:
rdrand-x86.obj: rdrand.asm
$(AS) $(ASFLAGS) /Fo rdrand-x86.obj /c rdrand.asm
rdrand-x64.obj:
rdrand-x64.obj: rdrand.asm
$(AS) $(ASFLAGS) /Fo rdrand-x64.obj /c rdrand.asm
x64masm.obj:
rdseed-x86.obj: rdseed.asm
$(AS) $(ASFLAGS) /Fo rdseed-x86.obj /c rdseed.asm
rdseed-x64.obj: rdseed.asm
$(AS) $(ASFLAGS) /Fo rdseed-x64.obj /c rdseed.asm
x64masm.obj: x64masm.asm
$(AS) $(ASFLAGS) /Fo x64masm.obj /c x64masm.asm
x64dll.obj:
x64dll.obj: x64dll.asm
$(AS) $(ASFLAGS) /Fo x64dll.obj /c x64dll.asm
# You may need to delete this on early versions of Visual Studio.

File diff suppressed because it is too large Load Diff

View File

@ -195,7 +195,10 @@
<!-- The rule copies cryptest.exe to the project -->
<!-- root directory so it can be executed in place -->
<Target Name="CopyCryptestToRoot">
<Exec Command="copy $(Platform)\Output\$(Configuration)\cryptest.exe $(SolutionDir)" />
<Exec Command="copy &quot;$(Platform)\Output\$(Configuration)\cryptest.exe&quot; &quot;$(SolutionDir)&quot;" />
</Target>
<Target Name="CopyToRoot">
<Exec Command="copy &quot;$(Platform)\Output\$(Configuration)\cryptest.exe&quot; &quot;$(SolutionDir)&quot;" />
</Target>
<!-- Source Files -->
<ItemGroup>

View File

@ -16,7 +16,6 @@
#ifndef CRYPTOPP_IMPORTS
#include "cryptlib.h"
#include "misc.h"
#include "filters.h"
#include "algparam.h"
#include "fips140.h"
@ -26,6 +25,7 @@
#include "secblock.h"
#include "smartptr.h"
#include "stdcpp.h"
#include "misc.h"
NAMESPACE_BEGIN(CryptoPP)
@ -333,20 +333,20 @@ void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransform
}
}
size_t KeyDerivationFunction::MinDerivedLength() const
size_t KeyDerivationFunction::MinDerivedKeyLength() const
{
return 0;
}
size_t KeyDerivationFunction::MaxDerivedLength() const
size_t KeyDerivationFunction::MaxDerivedKeyLength() const
{
return static_cast<size_t>(-1);
}
void KeyDerivationFunction::ThrowIfInvalidDerivedLength(size_t length) const
void KeyDerivationFunction::ThrowIfInvalidDerivedKeyLength(size_t length) const
{
if (!IsValidDerivedLength(length))
throw InvalidDerivedLength(GetAlgorithm().AlgorithmName(), length);
throw InvalidDerivedKeyLength(GetAlgorithm().AlgorithmName(), length);
}
void KeyDerivationFunction::SetParameters(const NameValuePairs& params) {
@ -405,8 +405,9 @@ RandomNumberGenerator & NullRNG()
bool HashTransformation::TruncatedVerify(const byte *digest, size_t digestLength)
{
// Allocate at least 1 for calculated to avoid triggering diagnostics
ThrowIfInvalidTruncatedSize(digestLength);
SecByteBlock calculated(digestLength);
SecByteBlock calculated(digestLength ? digestLength : 1);
TruncatedFinal(calculated, digestLength);
return VerifyBufsEqual(calculated, digest, digestLength);
}
@ -742,6 +743,12 @@ size_t BufferedTransformation::ChannelPutWord32(const std::string &channel, word
return ChannelPut(channel, m_buf, 4, blocking);
}
size_t BufferedTransformation::ChannelPutWord64(const std::string &channel, word64 value, ByteOrder order, bool blocking)
{
PutWord(false, order, m_buf, value);
return ChannelPut(channel, m_buf, 8, blocking);
}
size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking)
{
return ChannelPutWord16(DEFAULT_CHANNEL, value, order, blocking);
@ -752,22 +759,20 @@ size_t BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blo
return ChannelPutWord32(DEFAULT_CHANNEL, value, order, blocking);
}
// Issue 340
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wconversion"
# pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
size_t BufferedTransformation::PutWord64(word64 value, ByteOrder order, bool blocking)
{
return ChannelPutWord64(DEFAULT_CHANNEL, value, order, blocking);
}
size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const
{
byte buf[2] = {0, 0};
size_t len = Peek(buf, 2);
if (order)
value = (buf[0] << 8) | buf[1];
if (order == BIG_ENDIAN_ORDER)
value = ((word16)buf[0] << 8) | (word16)buf[1];
else
value = (buf[1] << 8) | buf[0];
value = ((word16)buf[1] << 8) | (word16)buf[0];
return len;
}
@ -777,18 +782,32 @@ size_t BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const
byte buf[4] = {0, 0, 0, 0};
size_t len = Peek(buf, 4);
if (order)
value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3];
if (order == BIG_ENDIAN_ORDER)
value = ((word32)buf[0] << 24) | ((word32)buf[1] << 16) |
((word32)buf[2] << 8) | (word32)buf[3];
else
value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0];
value = ((word32)buf[3] << 24) | ((word32)buf[2] << 16) |
((word32)buf[1] << 8) | (word32)buf[0];
return len;
}
// Issue 340
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
# pragma GCC diagnostic pop
#endif
size_t BufferedTransformation::PeekWord64(word64 &value, ByteOrder order) const
{
byte buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
size_t len = Peek(buf, 8);
if (order == BIG_ENDIAN_ORDER)
value = ((word64)buf[0] << 56) | ((word64)buf[1] << 48) | ((word64)buf[2] << 40) |
((word64)buf[3] << 32) | ((word64)buf[4] << 24) | ((word64)buf[5] << 16) |
((word64)buf[6] << 8) | (word64)buf[7];
else
value = ((word64)buf[7] << 56) | ((word64)buf[6] << 48) | ((word64)buf[5] << 40) |
((word64)buf[4] << 32) | ((word64)buf[3] << 24) | ((word64)buf[2] << 16) |
((word64)buf[1] << 8) | (word64)buf[0];
return len;
}
size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order)
{
@ -800,6 +819,11 @@ size_t BufferedTransformation::GetWord32(word32 &value, ByteOrder order)
return (size_t)Skip(PeekWord32(value, order));
}
size_t BufferedTransformation::GetWord64(word64 &value, ByteOrder order)
{
return (size_t)Skip(PeekWord64(value, order));
}
void BufferedTransformation::Attach(BufferedTransformation *newAttachment)
{
if (AttachedTransformation() && AttachedTransformation()->Attachable())

View File

@ -3,7 +3,7 @@
/// \file cryptlib.h
/// \brief Abstract base classes that provide a uniform interface to this library.
/*! \mainpage Crypto++ Library 8.1 API Reference
/*! \mainpage Crypto++ Library 8.3 API Reference
<dl>
<dt>Abstract Base Classes<dd>
cryptlib.h
@ -202,6 +202,9 @@ private:
class CRYPTOPP_DLL InvalidArgument : public Exception
{
public:
/// \brief Construct an InvalidArgument
/// \param s the message for the exception
/// \details The member function <tt>what()</tt> returns <tt>s</tt>.
explicit InvalidArgument(const std::string &s) : Exception(INVALID_ARGUMENT, s) {}
};
@ -209,6 +212,9 @@ public:
class CRYPTOPP_DLL InvalidDataFormat : public Exception
{
public:
/// \brief Construct an InvalidDataFormat
/// \param s the message for the exception
/// \details The member function <tt>what()</tt> returns <tt>s</tt>.
explicit InvalidDataFormat(const std::string &s) : Exception(INVALID_DATA_FORMAT, s) {}
};
@ -216,6 +222,9 @@ public:
class CRYPTOPP_DLL InvalidCiphertext : public InvalidDataFormat
{
public:
/// \brief Construct an InvalidCiphertext
/// \param s the message for the exception
/// \details The member function <tt>what()</tt> returns <tt>s</tt>.
explicit InvalidCiphertext(const std::string &s) : InvalidDataFormat(s) {}
};
@ -223,6 +232,9 @@ public:
class CRYPTOPP_DLL NotImplemented : public Exception
{
public:
/// \brief Construct an NotImplemented
/// \param s the message for the exception
/// \details The member function <tt>what()</tt> returns <tt>s</tt>.
explicit NotImplemented(const std::string &s) : Exception(NOT_IMPLEMENTED, s) {}
};
@ -230,6 +242,9 @@ public:
class CRYPTOPP_DLL CannotFlush : public Exception
{
public:
/// \brief Construct an CannotFlush
/// \param s the message for the exception
/// \details The member function <tt>what()</tt> returns <tt>s</tt>.
explicit CannotFlush(const std::string &s) : Exception(CANNOT_FLUSH, s) {}
};
@ -238,6 +253,13 @@ class CRYPTOPP_DLL OS_Error : public Exception
{
public:
virtual ~OS_Error() throw() {}
/// \brief Construct an OS_Error
/// \param errorType the error type
/// \param s the message for the exception
/// \param operation the operation for the exception
/// \param errorCode the error code
/// \details The member function <tt>what()</tt> returns <tt>s</tt>.
OS_Error(ErrorType errorType, const std::string &s, const std::string& operation, int errorCode)
: Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {}
@ -255,7 +277,8 @@ protected:
struct CRYPTOPP_DLL DecodingResult
{
/// \brief Constructs a DecodingResult
/// \details isValidCoding is initialized to false and messageLength is initialized to 0.
/// \details isValidCoding is initialized to false and messageLength is
/// initialized to 0.
explicit DecodingResult() : isValidCoding(false), messageLength(0) {}
/// \brief Constructs a DecodingResult
/// \param len the message length
@ -264,11 +287,13 @@ struct CRYPTOPP_DLL DecodingResult
/// \brief Compare two DecodingResult
/// \param rhs the other DecodingResult
/// \return true if both isValidCoding and messageLength are equal, false otherwise
/// \return true if either isValidCoding or messageLength is \a not equal,
/// false otherwise
bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;}
/// \brief Compare two DecodingResult
/// \param rhs the other DecodingResult
/// \return true if either isValidCoding or messageLength is \a not equal, false otherwise
/// \return true if either isValidCoding or messageLength is \a not equal,
/// false otherwise
/// \details Returns <tt>!operator==(rhs)</tt>.
bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);}
@ -279,24 +304,28 @@ struct CRYPTOPP_DLL DecodingResult
};
/// \brief Interface for retrieving values given their names
/// \details This class is used to safely pass a variable number of arbitrarily typed arguments to functions
/// and to read values from keys and crypto parameters.
/// \details To obtain an object that implements NameValuePairs for the purpose of parameter
/// passing, use the MakeParameters() function.
/// \details To get a value from NameValuePairs, you need to know the name and the type of the value.
/// Call GetValueNames() on a NameValuePairs object to obtain a list of value names that it supports.
/// then look at the Name namespace documentation to see what the type of each value is, or
/// alternatively, call GetIntValue() with the value name, and if the type is not int, a
/// ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object.
/// \details This class is used to safely pass a variable number of arbitrarily
/// typed arguments to functions and to read values from keys and crypto parameters.
/// \details To obtain an object that implements NameValuePairs for the purpose of
/// parameter passing, use the MakeParameters() function.
/// \details To get a value from NameValuePairs, you need to know the name and the
/// type of the value. Call GetValueNames() on a NameValuePairs object to obtain a
/// list of value names that it supports. then look at the Name namespace
/// documentation to see what the type of each value is, or alternatively, call
/// GetIntValue() with the value name, and if the type is not int, a
/// ValueTypeMismatch exception will be thrown and you can get the actual type from
/// the exception object.
/// \sa NullNameValuePairs, g_nullNameValuePairs,
/// <A HREF="http://www.cryptopp.com/wiki/NameValuePairs">NameValuePairs</A> on the Crypto++ wiki
/// <A HREF="http://www.cryptopp.com/wiki/NameValuePairs">NameValuePairs</A> on the
/// Crypto++ wiki
class NameValuePairs
{
public:
virtual ~NameValuePairs() {}
/// \brief Thrown when an unexpected type is encountered
/// \details Exception thrown when trying to retrieve a value using a different type than expected
/// \details Exception thrown when trying to retrieve a value using a different
/// type than expected
class CRYPTOPP_DLL ValueTypeMismatch : public InvalidArgument
{
public:
@ -1477,11 +1506,11 @@ public:
/// \brief Determine minimum number of bytes
/// \returns Minimum number of bytes which can be derived
virtual size_t MinDerivedLength() const;
virtual size_t MinDerivedKeyLength() const;
/// \brief Determine maximum number of bytes
/// \returns Maximum number of bytes which can be derived
virtual size_t MaxDerivedLength() const;
virtual size_t MaxDerivedKeyLength() const;
/// \brief Returns a valid key length for the derivation function
/// \param keylength the size of the derived key, in bytes
@ -1503,7 +1532,7 @@ public:
/// \param secretLen the size of the secret buffer, in bytes
/// \param params additional initialization parameters to configure this object
/// \returns the number of iterations performed
/// \throws InvalidDerivedLength if <tt>derivedLen</tt> is invalid for the scheme
/// \throws InvalidDerivedKeyLength if <tt>derivedLen</tt> is invalid for the scheme
/// \details DeriveKey() provides a standard interface to derive a key from
/// a secret seed and other parameters. Each class that derives from KeyDerivationFunction
/// provides an overload that accepts most parameters used by the derivation function.
@ -1525,7 +1554,7 @@ protected:
/// \brief Validates the derived key length
/// \param length the size of the derived key material, in bytes
/// \throws InvalidKeyLength if the key length is invalid
void ThrowIfInvalidDerivedLength(size_t length) const;
void ThrowIfInvalidDerivedKeyLength(size_t length) const;
};
/// \brief Interface for password based key derivation functions
@ -1614,8 +1643,8 @@ public:
/// \brief Input a byte for processing
/// \param inByte the 8-bit byte (octet) to be processed.
/// \param blocking specifies whether the object should block when processing input.
/// \return the number of bytes that remain in the block (i.e., bytes not processed). 0 indicates all
/// bytes were processed.
/// \return the number of bytes that remain in the block (i.e., bytes not processed).
/// 0 indicates all bytes were processed.
/// \details <tt>Put(byte)</tt> calls <tt>Put(byte*, size_t)</tt>.
size_t Put(byte inByte, bool blocking=true)
{return Put(&inByte, 1, blocking);}
@ -1624,8 +1653,8 @@ public:
/// \param inString the byte buffer to process
/// \param length the size of the string, in bytes
/// \param blocking specifies whether the object should block when processing input
/// \return the number of bytes that remain in the block (i.e., bytes not processed). 0 indicates all
/// bytes were processed.
/// \return the number of bytes that remain in the block (i.e., bytes not processed).
/// 0 indicates all bytes were processed.
/// \details Internally, Put() calls Put2().
size_t Put(const byte *inString, size_t length, bool blocking=true)
{return Put2(inString, length, 0, blocking);}
@ -1634,18 +1663,26 @@ public:
/// \param value the 16-bit value to be processed
/// \param order the ByteOrder of the value to be processed.
/// \param blocking specifies whether the object should block when processing input
/// \return the number of bytes that remain in the block (i.e., bytes not processed). 0 indicates all
/// bytes were processed.
/// \return the number of bytes that remain in the block (i.e., bytes not processed).
/// 0 indicates all bytes were processed.
size_t PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
/// Input a 32-bit word for processing.
/// \param value the 32-bit value to be processed.
/// \param order the ByteOrder of the value to be processed.
/// \param blocking specifies whether the object should block when processing input.
/// \return the number of bytes that remain in the block (i.e., bytes not processed). 0 indicates all
/// bytes were processed.
/// \return the number of bytes that remain in the block (i.e., bytes not processed).
/// 0 indicates all bytes were processed.
size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
/// Input a 64-bit word for processing.
/// \param value the 64-bit value to be processed.
/// \param order the ByteOrder of the value to be processed.
/// \param blocking specifies whether the object should block when processing input.
/// \return the number of bytes that remain in the block (i.e., bytes not processed).
/// 0 indicates all bytes were processed.
size_t PutWord64(word64 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
/// \brief Request space which can be written into by the caller
/// \param size the requested size of the buffer
/// \return byte pointer to the space to input data
@ -1781,18 +1818,23 @@ public:
/// \brief Flush buffered input and/or output, with signal propagation
/// \param hardFlush is used to indicate whether all data should be flushed
/// \param propagation the number of attached transformations the Flush() signal should be passed
/// \param blocking specifies whether the object should block when processing input
/// \details propagation count includes this object. Setting propagation to <tt>1</tt> means this
/// object only. Setting propagation to <tt>-1</tt> means unlimited propagation.
/// \note Hard flushes must be used with care. It means try to process and output everything, even if
/// there may not be enough data to complete the action. For example, hard flushing a HexDecoder
/// would cause an error if you do it after inputing an odd number of hex encoded characters.
/// \note For some types of filters, like ZlibDecompressor, hard flushes can only
/// be done at "synchronization points". These synchronization points are positions in the data
/// stream that are created by hard flushes on the corresponding reverse filters, in this
/// example ZlibCompressor. This is useful when zlib compressed data is moved across a
/// network in packets and compression state is preserved across packets, as in the SSH2 protocol.
/// \param propagation the number of attached transformations the Flush()
/// signal should be passed
/// \param blocking specifies whether the object should block when processing
/// input
/// \details propagation count includes this object. Setting propagation to
/// <tt>1</tt> means this object only. Setting propagation to <tt>-1</tt>
/// means unlimited propagation.
/// \note Hard flushes must be used with care. It means try to process and
/// output everything, even if there may not be enough data to complete the
/// action. For example, hard flushing a HexDecoder would cause an error if
/// you do it after inputing an odd number of hex encoded characters.
/// \note For some types of filters, like ZlibDecompressor, hard flushes can
/// only be done at "synchronization points". These synchronization points
/// are positions in the data stream that are created by hard flushes on the
/// corresponding reverse filters, in this example ZlibCompressor. This is
/// useful when zlib compressed data is moved across a network in packets
/// and compression state is preserved across packets, as in the SSH2 protocol.
virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true);
/// \brief Marks the end of a series of messages, with signal propagation
@ -1856,7 +1898,7 @@ public:
/// \param peekMax the number of bytes to Peek
/// \return the number of bytes read during the call.
/// \details Peek does not remove bytes from the object. Use the return value of
/// Get() to detect short reads.
/// Peek() to detect short reads.
virtual size_t Peek(byte *outString, size_t peekMax) const;
/// \brief Retrieve a 16-bit word
@ -1870,15 +1912,23 @@ public:
/// \param value the 32-bit value to be retrieved
/// \param order the ByteOrder of the value to be processed.
/// \return the number of bytes consumed during the call.
/// \details Use the return value of GetWord16() to detect short reads.
/// \details Use the return value of GetWord32() to detect short reads.
size_t GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER);
/// \brief Retrieve a 64-bit word
/// \param value the 64-bit value to be retrieved
/// \param order the ByteOrder of the value to be processed.
/// \return the number of bytes consumed during the call.
/// \details Use the return value of GetWord64() to detect short reads.
/// \since Crypto++ 8.3
size_t GetWord64(word64 &value, ByteOrder order=BIG_ENDIAN_ORDER);
/// \brief Peek a 16-bit word
/// \param value the 16-bit value to be retrieved
/// \param order the ByteOrder of the value to be processed.
/// \return the number of bytes consumed during the call.
/// \details Peek does not consume bytes in the stream. Use the return value
/// of GetWord16() to detect short reads.
/// of PeekWord16() to detect short reads.
size_t PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
/// \brief Peek a 32-bit word
@ -1886,9 +1936,18 @@ public:
/// \param order the ByteOrder of the value to be processed.
/// \return the number of bytes consumed during the call.
/// \details Peek does not consume bytes in the stream. Use the return value
/// of GetWord16() to detect short reads.
/// of PeekWord32() to detect short reads.
size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
/// \brief Peek a 64-bit word
/// \param value the 64-bit value to be retrieved
/// \param order the ByteOrder of the value to be processed.
/// \return the number of bytes consumed during the call.
/// \details Peek does not consume bytes in the stream. Use the return value
/// of PeekWord64() to detect short reads.
/// \since Crypto++ 8.3
size_t PeekWord64(word64 &value, ByteOrder order=BIG_ENDIAN_ORDER) const;
/// move transferMax bytes of the buffered output to target as input
/// \brief Transfer bytes from this object to another BufferedTransformation
@ -2035,7 +2094,7 @@ public:
/// \param channel the channel on which the transfer should occur
/// \param blocking specifies whether the object should block when processing input
/// \return the number of bytes that remain in the transfer block (i.e., bytes not transferred)
/// \details TransferTo() removes bytes from this object and moves them to the destination.
/// \details TransferTo2() removes bytes from this object and moves them to the destination.
/// Transfer begins at the index position in the current stream, and not from an absolute
/// position in the stream.
/// \details byteCount is an \a IN and \a OUT parameter. When the call is made,
@ -2144,6 +2203,15 @@ public:
/// number of bytes that were not processed.
size_t ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
/// \brief Input a 64-bit word for processing on a channel.
/// \param channel the channel to process the data.
/// \param value the 64-bit value to be processed.
/// \param order the ByteOrder of the value to be processed.
/// \param blocking specifies whether the object should block when processing input.
/// \return 0 indicates all bytes were processed during the call. Non-0 indicates the
/// number of bytes that were not processed.
size_t ChannelPutWord64(const std::string &channel, word64 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true);
/// \brief Signal the end of a message
/// \param channel the channel to process the data.
/// \param propagation the number of attached transformations the ChannelMessageEnd() signal should be passed
@ -2272,7 +2340,10 @@ protected:
{return propagation != 0 ? propagation - 1 : 0;}
private:
byte m_buf[4]; // for ChannelPutWord16 and ChannelPutWord32, to ensure buffer isn't deallocated before non-blocking operation completes
// for ChannelPutWord16, ChannelPutWord32 and ChannelPutWord64,
// to ensure the buffer isn't deallocated before non-blocking
// operation completes
byte m_buf[8];
};
/// \brief An input discarding BufferedTransformation

View File

@ -373,6 +373,16 @@
<Command>ml64.exe /c /nologo /D_M_X64 /W3 /Cx /Zi /Fo"$(IntDir)rdrand-x64.obj" "%(FullPath)"</Command>
<Outputs>$(IntDir)\rdrand-x64.obj;%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Condition="'$(Platform)'=='Win32'" Include="rdseed.asm">
<Message>Building and assembling rdseed.asm</Message>
<Command>ml.exe /c /nologo /D_M_X86 /W3 /Cx /Zi /safeseh /Fo"$(IntDir)rdseed-x86.obj" "%(FullPath)"</Command>
<Outputs>$(IntDir)\rdseed-x86.obj;%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Condition="'$(Platform)'=='x64'" Include="rdseed.asm">
<Message>Building and assembling rdseed.asm</Message>
<Command>ml64.exe /c /nologo /D_M_X64 /W3 /Cx /Zi /Fo"$(IntDir)rdseed-x64.obj" "%(FullPath)"</Command>
<Outputs>$(IntDir)\rdseed-x64.obj;%(Outputs)</Outputs>
</CustomBuild>
<CustomBuild Condition="'$(Platform)'=='x64' AND ('$(Configuration)'=='Debug' Or '$(Configuration)'=='Release')" Include="x64dll.asm">
<Message>Building and assembling x64dll.asm</Message>
<Command>ml64.exe /c /nologo /D_M_X64 /W3 /Zi /Fo"$(IntDir)x64dll.obj" "%(FullPath)"</Command>
@ -412,6 +422,16 @@
<ClInclude Include="channels.h" />
<ClInclude Include="cmac.h" />
<ClInclude Include="config.h" />
<ClInclude Include="config_align.h" />
<ClInclude Include="config_asm.h" />
<ClInclude Include="config_cpu.h" />
<ClInclude Include="config_cxx.h" />
<ClInclude Include="config_dll.h" />
<ClInclude Include="config_int.h" />
<ClInclude Include="config_misc.h" />
<ClInclude Include="config_ns.h" />
<ClInclude Include="config_os.h" />
<ClInclude Include="config_ver.h" />
<ClInclude Include="cpu.h" />
<ClInclude Include="crc.h" />
<ClInclude Include="cryptlib.h" />

View File

@ -615,6 +615,36 @@
<ClInclude Include="config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_align.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_asm.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_cpu.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_cxx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_dll.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_int.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_misc.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_ns.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_os.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="config_ver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cpu.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -1034,6 +1064,9 @@
<CustomBuild Include="rdrand.asm">
<Filter>Source Files</Filter>
</CustomBuild>
<CustomBuild Include="rdseed.asm">
<Filter>Source Files</Filter>
</CustomBuild>
<CustomBuild Include="x64dll.asm">
<Filter>Source Files</Filter>
</CustomBuild>

View File

@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 8,1,0,0
PRODUCTVERSION 8,1,0,0
FILEVERSION 8,3,0,0
PRODUCTVERSION 8,3,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -46,13 +46,13 @@ BEGIN
VALUE "Comments", "Free crypto library, more information available at www.cryptopp.com"
VALUE "CompanyName", "Wei Dai"
VALUE "FileDescription", "Crypto++® Library DLL"
VALUE "FileVersion", "8, 1, 0, 0"
VALUE "FileVersion", "8, 3, 0, 0"
VALUE "InternalName", "cryptopp"
VALUE "LegalCopyright", "Copyright© 1995-2018 by Wei Dai"
VALUE "LegalCopyright", "Copyright© 1995-2019 by Wei Dai"
VALUE "LegalTrademarks", "Crypto++®"
VALUE "OriginalFilename", "cryptopp.dll"
VALUE "ProductName", "Crypto++® Library"
VALUE "ProductVersion", "8, 1, 0, 0"
VALUE "ProductVersion", "8, 3, 0, 0"
END
END
BLOCK "VarFileInfo"

11
darn.h
View File

@ -2,11 +2,12 @@
// DARN requires POWER9/ISA 3.0.
// At the moment only GCC 7.0 (and above) seems to support __builtin_darn()
// and __builtin_darn_32(). Clang 7.0 does not provide them, but it does
// support assembly instructions. XLC is unknown, but there are no hits when
// searching IBM's site. To cover more platforms we provide GCC inline
// assembly like we do with RDRAND and RDSEED. Platforms that don't support
// GCC inline assembly or the builtin will fail the compile. Also see
// and __builtin_darn_32(). However, GCC generates incorrect code. Clang 7.0
// does not provide them, but it does support assembly instructions. XLC is
// unknown, but there are no hits when searching IBM's site. To cover more
// platforms we provide GCC inline assembly like we do with RDRAND and RDSEED.
// Platforms that don't support GCC inline assembly or the builtin will fail
// to compile. Also see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91481 and
// https://gcc.gnu.org/onlinedocs/gcc/Basic-PowerPC-Built-in-Functions-Available-on-ISA-3_002e0.html
/// \file darn.h

View File

@ -8,7 +8,6 @@
#include "factory.h"
#include "integer.h"
#include "filters.h"
#include "hex.h"
#include "randpool.h"
#include "files.h"
#include "trunhash.h"
@ -16,6 +15,8 @@
#include "smartptr.h"
#include "validate.h"
#include "stdcpp.h"
#include "misc.h"
#include "hex.h"
#include "trap.h"
#include <iostream>
@ -208,7 +209,7 @@ void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransfo
while (repeat--)
{
q.Put(reinterpret_cast<const byte*>(&s2[0]), s2.size());
q.Put(ConstBytePtr(s2), BytePtrSize(s2));
RandomizedTransfer(q, target, false);
}
}
@ -265,10 +266,11 @@ public:
*reinterpret_cast<int *>(pValue) = atoi(value.c_str());
else if (valueType == typeid(word64))
{
std::string x(value); errno = 0;
std::string x(value.empty() ? "0" : value);
const char* beg = &x[0];
char* end = &x[0] + value.size();
errno = 0;
*reinterpret_cast<word64*>(pValue) = STRTOUL64(beg, &end, 0);
if (errno != 0)
return false;
@ -279,7 +281,7 @@ public:
{
m_temp.clear();
PutDecodedDatumInto(m_data, name, StringSink(m_temp).Ref());
reinterpret_cast<ConstByteArrayParameter *>(pValue)->Assign(reinterpret_cast<const byte *>(&m_temp[0]), m_temp.size(), false);
reinterpret_cast<ConstByteArrayParameter *>(pValue)->Assign(ConstBytePtr(m_temp), BytePtrSize(m_temp), false);
}
else
throw ValueTypeMismatch(name, typeid(std::string), valueType);
@ -496,8 +498,8 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
}
else
{
encryptor->SetKey(reinterpret_cast<const byte*>(&key[0]), key.size(), pairs);
decryptor->SetKey(reinterpret_cast<const byte*>(&key[0]), key.size(), pairs);
encryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs);
decryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs);
}
word64 seek64 = pairs.GetWord64ValueWithDefault("Seek64", 0);
@ -547,13 +549,13 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
encrypted.reserve(10000 * plaintext.size());
for (int j=0; j<10000; j++)
{
cipher->ProcessString(reinterpret_cast<byte*>(&buf[0]), buf.size());
cipher->ProcessString(BytePtr(buf), BytePtrSize(buf));
encrypted.append(buf.begin(), buf.end());
}
encrypted.erase(0, encrypted.size() - keybuf.size());
xorbuf(reinterpret_cast<byte*>(&keybuf[0]), reinterpret_cast<const byte*>(&encrypted[0]), keybuf.size());
cipher->SetKey(reinterpret_cast<const byte*>(&keybuf[0]), keybuf.size());
xorbuf(BytePtr(keybuf), BytePtr(encrypted), BytePtrSize(keybuf));
cipher->SetKey(BytePtr(keybuf), BytePtrSize(keybuf));
}
encrypted.assign(buf.begin(), buf.end());
@ -641,8 +643,8 @@ void TestAuthenticatedSymmetricCipher(TestData &v, const NameValuePairs &overrid
member_ptr<AuthenticatedSymmetricCipher> encryptor, decryptor;
encryptor.reset(ObjectFactoryRegistry<AuthenticatedSymmetricCipher, ENCRYPTION>::Registry().CreateObject(name.c_str()));
decryptor.reset(ObjectFactoryRegistry<AuthenticatedSymmetricCipher, DECRYPTION>::Registry().CreateObject(name.c_str()));
encryptor->SetKey(reinterpret_cast<const byte*>(&key[0]), key.size(), pairs);
decryptor->SetKey(reinterpret_cast<const byte*>(&key[0]), key.size(), pairs);
encryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs);
decryptor->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs);
// Code coverage
(void)encryptor->AlgorithmName();
@ -736,7 +738,7 @@ void TestDigestOrMAC(TestData &v, bool testDigest)
mac.reset(ObjectFactoryRegistry<MessageAuthenticationCode>::Registry().CreateObject(name.c_str()));
pHash = mac.get();
std::string key = GetDecodedDatum(v, "Key");
mac->SetKey(reinterpret_cast<const byte *>(&key[0]), key.size(), pairs);
mac->SetKey(ConstBytePtr(key), BytePtrSize(key), pairs);
// Code coverage
(void)mac->AlgorithmName();
@ -779,8 +781,7 @@ void TestKeyDerivationFunction(TestData &v)
kdf.reset(ObjectFactoryRegistry<KeyDerivationFunction>::Registry().CreateObject(name.c_str()));
std::string calculated; calculated.resize(expected.size());
kdf->DeriveKey(reinterpret_cast<byte*>(&calculated[0]), calculated.size(),
reinterpret_cast<const byte*>(&secret[0]), secret.size(), pairs);
kdf->DeriveKey(BytePtr(calculated), BytePtrSize(calculated), BytePtr(secret), BytePtrSize(secret), pairs);
if(calculated != expected)
{

View File

@ -37,6 +37,18 @@
// Squash MS LNK4221 and libtool warnings
extern const char DONNA32_FNAME[] = __FILE__;
ANONYMOUS_NAMESPACE_BEGIN
// Can't use GetAlignmentOf<word32>() because of C++11 and constexpr
// Can use 'const unsigned int' because of MSVC 2013
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
# define ALIGN_SPEC 16
#else
# define ALIGN_SPEC 4
#endif
ANONYMOUS_NAMESPACE_END
#if defined(CRYPTOPP_CURVE25519_32BIT)
#include "donna_32.h"
@ -431,7 +443,7 @@ curve25519_swap_conditional(bignum25519 x, bignum25519 qpx, word32 iswap) {
*/
void
curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
ALIGN(16) bignum25519 t0,c;
ALIGN(ALIGN_SPEC) bignum25519 t0,c;
/* 2^5 - 2^0 */ /* b */
/* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5);
@ -455,7 +467,7 @@ curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
*/
void
curve25519_recip(bignum25519 out, const bignum25519 z) {
ALIGN(16) bignum25519 a, t0, b;
ALIGN(ALIGN_SPEC) bignum25519 a, t0, b;
/* 2 */ curve25519_square(a, z); /* a = 2 */
/* 8 */ curve25519_square_times(t0, a, 2);
@ -913,7 +925,33 @@ curve25519_contract(byte out[32], const bignum25519 in) {
/* out = (flag) ? in : out */
inline void
curve25519_move_conditional_bytes(byte out[96], const byte in[96], word32 flag) {
curve25519_move_conditional_bytes(byte out[96], const byte in[96], word32 flag)
{
// TODO: enable this code path once we can test and benchmark it.
// It is about 48 insns shorter, it avoids punning which may be UB,
// and it is guaranteed constant time.
#if defined(__GNUC__) && defined(__i686__) && 0
const word32 iter = 96/sizeof(word32);
word32* outl = reinterpret_cast<word32*>(out);
const word32* inl = reinterpret_cast<const word32*>(in);
word32 idx=0, val;
__asm__ __volatile__ (
".att_syntax ;\n"
"cmpl $0, %[flag] ;\n" // compare, set ZERO flag
"movl %[iter], %%ecx ;\n" // load iteration count
"1: ;\n"
" movl (%[idx],%[out]), %[val] ;\n" // val = out[idx]
" cmovnzl (%[idx],%[in]), %[val] ;\n" // copy in[idx] to val if NZ
" movl %[val], (%[idx],%[out]) ;\n" // out[idx] = val
" leal 4(%[idx]), %[idx] ;\n" // increment index
" loopnz 1b ;\n" // does not affect flags
: [out] "+S" (outl), [in] "+D" (inl),
[idx] "+b" (idx), [val] "=r" (val)
: [flag] "g" (flag), [iter] "I" (iter)
: "ecx", "memory", "cc"
);
#else
const word32 nb = flag - 1, b = ~nb;
const word32 *inl = (const word32 *)in;
word32 *outl = (word32 *)out;
@ -941,6 +979,7 @@ curve25519_move_conditional_bytes(byte out[96], const byte in[96], word32 flag)
outl[21] = (outl[21] & nb) | (inl[21] & b);
outl[22] = (outl[22] & nb) | (inl[22] & b);
outl[23] = (outl[23] & nb) | (inl[23] & b);
#endif
}
/* if (iswap) swap(a, b) */
@ -967,7 +1006,7 @@ curve25519_swap_conditional(bignum25519 a, bignum25519 b, word32 iswap) {
*/
void
curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
ALIGN(16) bignum25519 t0,c;
ALIGN(ALIGN_SPEC) bignum25519 t0,c;
/* 2^5 - 2^0 */ /* b */
/* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5);
@ -991,7 +1030,7 @@ curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
*/
void
curve25519_recip(bignum25519 out, const bignum25519 z) {
ALIGN(16) bignum25519 a,t0,b;
ALIGN(ALIGN_SPEC) bignum25519 a,t0,b;
/* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */
/* 8 */ curve25519_square_times(t0, a, 2);
@ -1009,7 +1048,7 @@ curve25519_recip(bignum25519 out, const bignum25519 z) {
*/
void
curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) {
ALIGN(16) bignum25519 b,c,t0;
ALIGN(ALIGN_SPEC) bignum25519 b,c,t0;
/* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */
/* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */
@ -1865,7 +1904,7 @@ ed25519_publickey_CXX(byte publicKey[32], const byte secretKey[32])
using namespace CryptoPP::Donna::Ed25519;
bignum256modm a;
ALIGN(16) ge25519 A;
ALIGN(ALIGN_SPEC) ge25519 A;
hash_512bits extsk;
/* A = aB */
@ -1889,7 +1928,7 @@ ed25519_sign_CXX(std::istream& stream, const byte sk[32], const byte pk[32], byt
using namespace CryptoPP::Donna::Ed25519;
bignum256modm r, S, a;
ALIGN(16) ge25519 R;
ALIGN(ALIGN_SPEC) ge25519 R;
hash_512bits extsk, hashr, hram;
// Unfortunately we need to read the stream twice. The fisrt time calculates
@ -1938,7 +1977,7 @@ ed25519_sign_CXX(const byte *m, size_t mlen, const byte sk[32], const byte pk[32
using namespace CryptoPP::Donna::Ed25519;
bignum256modm r, S, a;
ALIGN(16) ge25519 R;
ALIGN(ALIGN_SPEC) ge25519 R;
hash_512bits extsk, hashr, hram;
ed25519_extsk(extsk, sk);
@ -1990,7 +2029,7 @@ ed25519_sign_open_CXX(std::istream& stream, const byte pk[32], const byte RS[64]
using namespace CryptoPP::Donna::Ed25519;
ALIGN(16) ge25519 R, A;
ALIGN(ALIGN_SPEC) ge25519 R, A;
hash_512bits hash;
bignum256modm hram, S;
byte checkR[32];
@ -2018,7 +2057,7 @@ ed25519_sign_open_CXX(const byte *m, size_t mlen, const byte pk[32], const byte
using namespace CryptoPP::Donna::Ed25519;
ALIGN(16) ge25519 R, A;
ALIGN(ALIGN_SPEC) ge25519 R, A;
hash_512bits hash;
bignum256modm hram, S;
byte checkR[32];

View File

@ -37,6 +37,18 @@
// Squash MS LNK4221 and libtool warnings
extern const char DONNA64_FNAME[] = __FILE__;
ANONYMOUS_NAMESPACE_BEGIN
// Can't use GetAlignmentOf<word64>() because of C++11 and constexpr
// Can use 'const unsigned int' because of MSVC 2013
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64)
# define ALIGN_SPEC 16
#else
# define ALIGN_SPEC 8
#endif
ANONYMOUS_NAMESPACE_END
#if defined(CRYPTOPP_CURVE25519_64BIT)
#include "donna_64.h"
@ -359,7 +371,7 @@ curve25519_swap_conditional(bignum25519 x, bignum25519 qpx, word64 iswap) {
*/
void
curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
ALIGN(16) bignum25519 t0,c;
ALIGN(ALIGN_SPEC) bignum25519 t0,c;
/* 2^5 - 2^0 */ /* b */
/* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5);
@ -383,7 +395,7 @@ curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
*/
void
curve25519_recip(bignum25519 out, const bignum25519 z) {
ALIGN(16) bignum25519 a, t0, b;
ALIGN(ALIGN_SPEC) bignum25519 a, t0, b;
/* 2 */ curve25519_square(a, z); /* a = 2 */
/* 8 */ curve25519_square_times(t0, a, 2);
@ -735,10 +747,36 @@ curve25519_contract(byte *out, const bignum25519 input) {
/* out = (flag) ? in : out */
inline void
curve25519_move_conditional_bytes(byte out[96], const byte in[96], word64 flag) {
curve25519_move_conditional_bytes(byte out[96], const byte in[96], word64 flag)
{
// TODO: enable this code path once we can test and benchmark it.
// It is about 24 insns shorter, it avoids punning which may be UB,
// and it is guaranteed constant time.
#if defined(__GNUC__) && defined(__x86_64__) && 0
const word32 iter = 96/sizeof(word64);
word64* outq = reinterpret_cast<word64*>(out);
const word64* inq = reinterpret_cast<const word64*>(in);
word64 idx=0, val;
__asm__ __volatile__ (
".att_syntax ;\n"
"cmpq $0, %[flag] ;\n" // compare, set ZERO flag
"movq %[iter], %%rcx ;\n" // load iteration count
"1: ;\n"
" movq (%[idx],%[out]), %[val] ;\n" // val = out[idx]
" cmovnzq (%[idx],%[in]), %[val] ;\n" // copy in[idx] to val if NZ
" movq %[val], (%[idx],%[out]) ;\n" // out[idx] = val
" leaq 8(%[idx]), %[idx] ;\n" // increment index
" loopnz 1b ;\n" // does not affect flags
: [out] "+S" (outq), [in] "+D" (inq),
[idx] "+b" (idx), [val] "=r" (val)
: [flag] "g" (flag), [iter] "I" (iter)
: "rcx", "memory", "cc"
);
#else
const word64 nb = flag - 1, b = ~nb;
const word64 *inq = (const word64 *)in;
word64 *outq = (word64 *)out;
const word64 *inq = (const word64 *)(const void*)in;
word64 *outq = (word64 *)(void *)out;
outq[0] = (outq[0] & nb) | (inq[0] & b);
outq[1] = (outq[1] & nb) | (inq[1] & b);
outq[2] = (outq[2] & nb) | (inq[2] & b);
@ -751,6 +789,7 @@ curve25519_move_conditional_bytes(byte out[96], const byte in[96], word64 flag)
outq[9] = (outq[9] & nb) | (inq[9] & b);
outq[10] = (outq[10] & nb) | (inq[10] & b);
outq[11] = (outq[11] & nb) | (inq[11] & b);
#endif
}
/* if (iswap) swap(a, b) */
@ -1065,7 +1104,7 @@ contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int wi
*/
void
curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
ALIGN(16) bignum25519 t0,c;
ALIGN(ALIGN_SPEC) bignum25519 t0,c;
/* 2^5 - 2^0 */ /* b */
/* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5);
@ -1089,7 +1128,7 @@ curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) {
*/
void
curve25519_recip(bignum25519 out, const bignum25519 z) {
ALIGN(16) bignum25519 a,t0,b;
ALIGN(ALIGN_SPEC) bignum25519 a,t0,b;
/* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */
/* 8 */ curve25519_square_times(t0, a, 2);
@ -1107,7 +1146,7 @@ curve25519_recip(bignum25519 out, const bignum25519 z) {
*/
void
curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) {
ALIGN(16) bignum25519 b,c,t0;
ALIGN(ALIGN_SPEC) bignum25519 b,c,t0;
/* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */
/* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */
@ -1580,7 +1619,7 @@ ed25519_publickey_CXX(byte publicKey[32], const byte secretKey[32])
using namespace CryptoPP::Donna::Ed25519;
bignum256modm a;
ALIGN(16) ge25519 A;
ALIGN(ALIGN_SPEC) ge25519 A;
hash_512bits extsk;
/* A = aB */
@ -1604,7 +1643,7 @@ ed25519_sign_CXX(std::istream& stream, const byte sk[32], const byte pk[32], byt
using namespace CryptoPP::Donna::Ed25519;
bignum256modm r, S, a;
ALIGN(16) ge25519 R;
ALIGN(ALIGN_SPEC) ge25519 R;
hash_512bits extsk, hashr, hram;
// Unfortunately we need to read the stream twice. The fisrt time calculates
@ -1652,7 +1691,7 @@ ed25519_sign_CXX(const byte *m, size_t mlen, const byte sk[32], const byte pk[32
using namespace CryptoPP::Donna::Ed25519;
bignum256modm r, S, a;
ALIGN(16) ge25519 R;
ALIGN(ALIGN_SPEC) ge25519 R;
hash_512bits extsk, hashr, hram;
ed25519_extsk(extsk, sk);
@ -1703,7 +1742,7 @@ ed25519_sign_open_CXX(const byte *m, size_t mlen, const byte pk[32], const byte
using namespace CryptoPP::Donna::Ed25519;
ALIGN(16) ge25519 R, A;
ALIGN(ALIGN_SPEC) ge25519 R, A;
hash_512bits hash;
bignum256modm hram, S;
byte checkR[32];
@ -1731,7 +1770,7 @@ ed25519_sign_open_CXX(std::istream& stream, const byte pk[32], const byte RS[64]
using namespace CryptoPP::Donna::Ed25519;
ALIGN(16) ge25519 R, A;
ALIGN(ALIGN_SPEC) ge25519 R, A;
hash_512bits hash;
bignum256modm hram, S;
byte checkR[32];

View File

@ -1059,13 +1059,13 @@ int curve25519_mult_SSE2(byte sharedKey[32], const byte secretKey[32], const byt
packed32bignum25519 qx, qz, pqz, pqx;
packed64bignum25519 nq, sq, sqscalar, prime, primex, primez, nqpq;
bignum25519mulprecomp preq;
size_t i=0, bit=0, lastbit=0;
size_t bit=0, lastbit=0;
curve25519_expand(nqpqx, othersKey);
curve25519_mul_precompute(&preq, nqpqx);
/* do bits 254..3 */
for (i = 254, lastbit=0; i >= 3; i--) {
for (size_t i = 254, lastbit=0; i >= 3; i--) {
bit = (e[i/8] >> (i & 7)) & 1;
curve25519_swap_conditional(nqx, nqpqx, (word32)(bit ^ lastbit));
curve25519_swap_conditional(nqz, nqpqz, (word32)(bit ^ lastbit));
@ -1098,7 +1098,7 @@ int curve25519_mult_SSE2(byte sharedKey[32], const byte secretKey[32], const byt
curve25519_swap_conditional(nqz, nqpqz, (word32)bit);
/* do bits 2..0 */
for (i = 0; i < 3; i++) {
for (size_t i = 0; i < 3; i++) {
curve25519_compute_nq(nq, nqx, nqz);
curve25519_square_packed64(sq, nq); /* sq = nq^2 */
curve25519_121665_packed64(sqscalar, sq); /* sqscalar = sq * [121666,121665] */

6
drbg.h
View File

@ -207,6 +207,9 @@ public:
size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0)
: NIST_DRBG(), m_c(SEEDLENGTH), m_v(SEEDLENGTH), m_reseed(0)
{
std::memset(m_c, 0x00, m_c.size());
std::memset(m_v, 0x00, m_v.size());
if (entropy != NULLPTR && entropyLength != 0)
DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
}
@ -324,6 +327,9 @@ public:
size_t nonceLength=0, const byte* personalization=NULLPTR, size_t personalizationLength=0)
: NIST_DRBG(), m_k(HASH::DIGESTSIZE), m_v(HASH::DIGESTSIZE), m_reseed(0)
{
std::memset(m_k, 0x00, m_k.size());
std::memset(m_v, 0x00, m_v.size());
if (entropy != NULLPTR && entropyLength != 0)
DRBG_Instantiate(entropy, entropyLength, nonce, nonceLength, personalization, personalizationLength);
}

View File

@ -16,7 +16,8 @@ ANONYMOUS_NAMESPACE_BEGIN
using CryptoPP::EC2N;
#if defined(HAVE_GCC_INIT_PRIORITY)
const EC2N::Point g_identity __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 50))) = EC2N::Point();
#define INIT_ATTRIBUTE __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 51)))
const EC2N::Point g_identity INIT_ATTRIBUTE = EC2N::Point();
#elif defined(HAVE_MSC_INIT_PRIORITY)
#pragma warning(disable: 4075)
#pragma init_seg(".CRT$XCU")
@ -260,7 +261,7 @@ const EC2N::Point& EC2N::Double(const Point &P) const
// ********************************************************
/*
#if 0
EcPrecomputation<EC2N>& EcPrecomputation<EC2N>::operator=(const EcPrecomputation<EC2N> &rhs)
{
m_ec = rhs.m_ec;
@ -312,7 +313,7 @@ EC2N::Point EcPrecomputation<EC2N>::CascadeExponentiate(const Integer &exponent,
{
return m_ep.CascadeExponentiate(exponent, static_cast<const EcPrecomputation<EC2N> &>(pc2).m_ep, exponent2);
}
*/
#endif
NAMESPACE_END

1
ec2n.h
View File

@ -3,7 +3,6 @@
/// \file ec2n.h
/// \brief Classes for Elliptic Curves over binary fields
#ifndef CRYPTOPP_EC2N_H
#define CRYPTOPP_EC2N_H

View File

@ -28,6 +28,9 @@
#include "ec2n.h"
#include "misc.h"
#include <iostream>
#include <sstream>
// Squash MS LNK4221 and libtool warnings
#ifndef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES
extern const char ECCRYPTO_FNAME[] = __FILE__;
@ -683,6 +686,13 @@ OID DL_GroupParameters_EC<EC>::GetAlgorithmID() const
return ASN1::id_ecPublicKey();
}
std::ostream& operator<<(std::ostream& os, const DL_GroupParameters_EC<ECP>::Element& obj)
{
std::ostringstream oss;
oss << "(" << std::hex << obj.x << ", " << std::hex << obj.y << ")";
return os << oss.str();
}
// ******************************************************************
template <class EC>

View File

@ -22,6 +22,8 @@
#include "ecp.h"
#include "ec2n.h"
#include <iosfwd>
#if CRYPTOPP_MSC_VERSION
# pragma warning(push)
# pragma warning(disable: 4231 4275)
@ -168,6 +170,8 @@ protected:
mutable bool m_compress, m_encodeAsOID; // presentation details
};
inline std::ostream& operator<<(std::ostream& os, const DL_GroupParameters_EC<ECP>::Element& obj);
/// \brief Elliptic Curve Discrete Log (DL) public key
/// \tparam EC elliptic curve field
template <class EC>

541
ecp.cpp
View File

@ -15,10 +15,12 @@
ANONYMOUS_NAMESPACE_BEGIN
using CryptoPP::ECP;
using CryptoPP::Integer;
using CryptoPP::ModularArithmetic;
#if defined(HAVE_GCC_INIT_PRIORITY)
const ECP::Point g_identity __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 51))) = ECP::Point();
#define INIT_ATTRIBUTE __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 50)))
const ECP::Point g_identity INIT_ATTRIBUTE = ECP::Point();
#elif defined(HAVE_MSC_INIT_PRIORITY)
#pragma warning(disable: 4075)
#pragma init_seg(".CRT$XCU")
@ -39,6 +41,503 @@ inline ECP::Point FromMontgomery(const ModularArithmetic &mr, const ECP::Point &
return P.identity ? P : ECP::Point(mr.ConvertOut(P.x), mr.ConvertOut(P.y));
}
inline Integer IdentityToInteger(bool val)
{
return val ? Integer::One() : Integer::Zero();
}
struct ProjectivePoint
{
ProjectivePoint() {}
ProjectivePoint(const Integer &x, const Integer &y, const Integer &z)
: x(x), y(y), z(z) {}
Integer x, y, z;
};
/// \brief Addition and Double functions
/// \sa <A HREF="https://eprint.iacr.org/2015/1060.pdf">Complete
/// addition formulas for prime order elliptic curves</A>
struct AdditionFunction
{
explicit AdditionFunction(const ECP::Field& field,
const ECP::FieldElement &a, const ECP::FieldElement &b, ECP::Point &r);
// Double(P)
ECP::Point operator()(const ECP::Point& P) const;
// Add(P, Q)
ECP::Point operator()(const ECP::Point& P, const ECP::Point& Q) const;
protected:
/// \brief Parameters and representation for Addition
/// \details Addition and Doubling will use different algorithms,
/// depending on the <tt>A</tt> coefficient and the representation
/// (Affine or Montgomery with precomputation).
enum Alpha {
/// \brief Coefficient A is 0
A_0 = 1,
/// \brief Coefficient A is -3
A_3 = 2,
/// \brief Coefficient A is arbitrary
A_Star = 4,
/// \brief Representation is Montgomery
A_Montgomery = 8
};
const ECP::Field& field;
const ECP::FieldElement &a, &b;
ECP::Point &R;
Alpha m_alpha;
};
#define X p.x
#define Y p.y
#define Z p.z
#define X1 p.x
#define Y1 p.y
#define Z1 p.z
#define X2 q.x
#define Y2 q.y
#define Z2 q.z
#define X3 r.x
#define Y3 r.y
#define Z3 r.z
AdditionFunction::AdditionFunction(const ECP::Field& field,
const ECP::FieldElement &a, const ECP::FieldElement &b, ECP::Point &r)
: field(field), a(a), b(b), R(r), m_alpha(static_cast<Alpha>(0))
{
if (field.IsMontgomeryRepresentation())
{
m_alpha = A_Montgomery;
}
else
{
if (a == 0)
{
m_alpha = A_0;
}
else if (a == -3 || (a - field.GetModulus()) == -3)
{
m_alpha = A_3;
}
else
{
m_alpha = A_Star;
}
}
}
ECP::Point AdditionFunction::operator()(const ECP::Point& P) const
{
if (m_alpha == A_3)
{
// Gyrations attempt to maintain constant-timeness
// We need either (P.x, P.y, 1) or (0, 1, 0).
const Integer x = P.x * IdentityToInteger(!P.identity);
const Integer y = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
const Integer z = 1 * IdentityToInteger(!P.identity);
ProjectivePoint p(x, y, z), r;
ECP::FieldElement t0 = field.Square(X);
ECP::FieldElement t1 = field.Square(Y);
ECP::FieldElement t2 = field.Square(Z);
ECP::FieldElement t3 = field.Multiply(X, Y);
t3 = field.Add(t3, t3);
Z3 = field.Multiply(X, Z);
Z3 = field.Add(Z3, Z3);
Y3 = field.Multiply(b, t2);
Y3 = field.Subtract(Y3, Z3);
X3 = field.Add(Y3, Y3);
Y3 = field.Add(X3, Y3);
X3 = field.Subtract(t1, Y3);
Y3 = field.Add(t1, Y3);
Y3 = field.Multiply(X3, Y3);
X3 = field.Multiply(X3, t3);
t3 = field.Add(t2, t2);
t2 = field.Add(t2, t3);
Z3 = field.Multiply(b, Z3);
Z3 = field.Subtract(Z3, t2);
Z3 = field.Subtract(Z3, t0);
t3 = field.Add(Z3, Z3);
Z3 = field.Add(Z3, t3);
t3 = field.Add(t0, t0);
t0 = field.Add(t3, t0);
t0 = field.Subtract(t0, t2);
t0 = field.Multiply(t0, Z3);
Y3 = field.Add(Y3, t0);
t0 = field.Multiply(Y, Z);
t0 = field.Add(t0, t0);
Z3 = field.Multiply(t0, Z3);
X3 = field.Subtract(X3, Z3);
Z3 = field.Multiply(t0, t1);
Z3 = field.Add(Z3, Z3);
Z3 = field.Add(Z3, Z3);
const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3);
X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv);
// More gyrations
R.x = X3*Z3.NotZero();
R.y = Y3*Z3.NotZero();
R.identity = Z3.IsZero();
return R;
}
else if (m_alpha == A_0)
{
// Gyrations attempt to maintain constant-timeness
// We need either (P.x, P.y, 1) or (0, 1, 0).
const Integer x = P.x * IdentityToInteger(!P.identity);
const Integer y = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
const Integer z = 1 * IdentityToInteger(!P.identity);
ProjectivePoint p(x, y, z), r;
const ECP::FieldElement b3 = field.Multiply(b, 3);
ECP::FieldElement t0 = field.Square(Y);
Z3 = field.Add(t0, t0);
Z3 = field.Add(Z3, Z3);
Z3 = field.Add(Z3, Z3);
ECP::FieldElement t1 = field.Add(Y, Z);
ECP::FieldElement t2 = field.Square(Z);
t2 = field.Multiply(b3, t2);
X3 = field.Multiply(t2, Z3);
Y3 = field.Add(t0, t2);
Z3 = field.Multiply(t1, Z3);
t1 = field.Add(t2, t2);
t2 = field.Add(t1, t2);
t0 = field.Subtract(t0, t2);
Y3 = field.Multiply(t0, Y3);
Y3 = field.Add(X3, Y3);
t1 = field.Multiply(X, Y);
X3 = field.Multiply(t0, t1);
X3 = field.Add(X3, X3);
const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3);
X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv);
// More gyrations
R.x = X3*Z3.NotZero();
R.y = Y3*Z3.NotZero();
R.identity = Z3.IsZero();
return R;
}
#if 0
// Code path disabled at the moment due to https://github.com/weidai11/cryptopp/issues/878
else if (m_alpha == A_Star)
{
// Gyrations attempt to maintain constant-timeness
// We need either (P.x, P.y, 1) or (0, 1, 0).
const Integer x = P.x * IdentityToInteger(!P.identity);
const Integer y = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
const Integer z = 1 * IdentityToInteger(!P.identity);
ProjectivePoint p(x, y, z), r;
const ECP::FieldElement b3 = field.Multiply(b, 3);
ECP::FieldElement t0 = field.Square(Y);
Z3 = field.Add(t0, t0);
Z3 = field.Add(Z3, Z3);
Z3 = field.Add(Z3, Z3);
ECP::FieldElement t1 = field.Add(Y, Z);
ECP::FieldElement t2 = field.Square(Z);
t2 = field.Multiply(b3, t2);
X3 = field.Multiply(t2, Z3);
Y3 = field.Add(t0, t2);
Z3 = field.Multiply(t1, Z3);
t1 = field.Add(t2, t2);
t2 = field.Add(t1, t2);
t0 = field.Subtract(t0, t2);
Y3 = field.Multiply(t0, Y3);
Y3 = field.Add(X3, Y3);
t1 = field.Multiply(X, Y);
X3 = field.Multiply(t0, t1);
X3 = field.Add(X3, X3);
const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3);
X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv);
// More gyrations
R.x = X3*Z3.NotZero();
R.y = Y3*Z3.NotZero();
R.identity = Z3.IsZero();
return R;
}
#endif
else // A_Montgomery
{
// More gyrations
bool identity = !!(P.identity + (P.y == field.Identity()));
ECP::FieldElement t = field.Square(P.x);
t = field.Add(field.Add(field.Double(t), t), a);
t = field.Divide(t, field.Double(P.y));
ECP::FieldElement x = field.Subtract(field.Subtract(field.Square(t), P.x), P.x);
R.y = field.Subtract(field.Multiply(t, field.Subtract(P.x, x)), P.y);
R.x.swap(x);
// More gyrations
R.x *= IdentityToInteger(!identity);
R.y *= IdentityToInteger(!identity);
R.identity = identity;
return R;
}
}
ECP::Point AdditionFunction::operator()(const ECP::Point& P, const ECP::Point& Q) const
{
if (m_alpha == A_3)
{
// Gyrations attempt to maintain constant-timeness
// We need either (P.x, P.y, 1) or (0, 1, 0).
const Integer x1 = P.x * IdentityToInteger(!P.identity);
const Integer y1 = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
const Integer z1 = 1 * IdentityToInteger(!P.identity);
const Integer x2 = Q.x * IdentityToInteger(!Q.identity);
const Integer y2 = Q.y * IdentityToInteger(!Q.identity) + 1 * IdentityToInteger(Q.identity);
const Integer z2 = 1 * IdentityToInteger(!Q.identity);
ProjectivePoint p(x1, y1, z1), q(x2, y2, z2), r;
ECP::FieldElement t0 = field.Multiply(X1, X2);
ECP::FieldElement t1 = field.Multiply(Y1, Y2);
ECP::FieldElement t2 = field.Multiply(Z1, Z2);
ECP::FieldElement t3 = field.Add(X1, Y1);
ECP::FieldElement t4 = field.Add(X2, Y2);
t3 = field.Multiply(t3, t4);
t4 = field.Add(t0, t1);
t3 = field.Subtract(t3, t4);
t4 = field.Add(Y1, Z1);
X3 = field.Add(Y2, Z2);
t4 = field.Multiply(t4, X3);
X3 = field.Add(t1, t2);
t4 = field.Subtract(t4, X3);
X3 = field.Add(X1, Z1);
Y3 = field.Add(X2, Z2);
X3 = field.Multiply(X3, Y3);
Y3 = field.Add(t0, t2);
Y3 = field.Subtract(X3, Y3);
Z3 = field.Multiply(b, t2);
X3 = field.Subtract(Y3, Z3);
Z3 = field.Add(X3, X3);
X3 = field.Add(X3, Z3);
Z3 = field.Subtract(t1, X3);
X3 = field.Add(t1, X3);
Y3 = field.Multiply(b, Y3);
t1 = field.Add(t2, t2);
t2 = field.Add(t1, t2);
Y3 = field.Subtract(Y3, t2);
Y3 = field.Subtract(Y3, t0);
t1 = field.Add(Y3, Y3);
Y3 = field.Add(t1, Y3);
t1 = field.Add(t0, t0);
t0 = field.Add(t1, t0);
t0 = field.Subtract(t0, t2);
t1 = field.Multiply(t4, Y3);
t2 = field.Multiply(t0, Y3);
Y3 = field.Multiply(X3, Z3);
Y3 = field.Add(Y3, t2);
X3 = field.Multiply(t3, X3);
X3 = field.Subtract(X3, t1);
Z3 = field.Multiply(t4, Z3);
t1 = field.Multiply(t3, t0);
Z3 = field.Add(Z3, t1);
const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3);
X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv);
// More gyrations
R.x = X3*Z3.NotZero();
R.y = Y3*Z3.NotZero();
R.identity = Z3.IsZero();
return R;
}
else if (m_alpha == A_0)
{
// Gyrations attempt to maintain constant-timeness
// We need either (P.x, P.y, 1) or (0, 1, 0).
const Integer x1 = P.x * IdentityToInteger(!P.identity);
const Integer y1 = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
const Integer z1 = 1 * IdentityToInteger(!P.identity);
const Integer x2 = Q.x * IdentityToInteger(!Q.identity);
const Integer y2 = Q.y * IdentityToInteger(!Q.identity) + 1 * IdentityToInteger(Q.identity);
const Integer z2 = 1 * IdentityToInteger(!Q.identity);
ProjectivePoint p(x1, y1, z1), q(x2, y2, z2), r;
const ECP::FieldElement b3 = field.Multiply(b, 3);
ECP::FieldElement t0 = field.Square(Y);
Z3 = field.Add(t0, t0);
Z3 = field.Add(Z3, Z3);
Z3 = field.Add(Z3, Z3);
ECP::FieldElement t1 = field.Add(Y, Z);
ECP::FieldElement t2 = field.Square(Z);
t2 = field.Multiply(b3, t2);
X3 = field.Multiply(t2, Z3);
Y3 = field.Add(t0, t2);
Z3 = field.Multiply(t1, Z3);
t1 = field.Add(t2, t2);
t2 = field.Add(t1, t2);
t0 = field.Subtract(t0, t2);
Y3 = field.Multiply(t0, Y3);
Y3 = field.Add(X3, Y3);
t1 = field.Multiply(X, Y);
X3 = field.Multiply(t0, t1);
X3 = field.Add(X3, X3);
const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3);
X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv);
// More gyrations
R.x = X3*Z3.NotZero();
R.y = Y3*Z3.NotZero();
R.identity = Z3.IsZero();
return R;
}
#if 0
// Code path disabled at the moment due to https://github.com/weidai11/cryptopp/issues/878
else if (m_alpha == A_Star)
{
// Gyrations attempt to maintain constant-timeness
// We need either (P.x, P.y, 1) or (0, 1, 0).
const Integer x1 = P.x * IdentityToInteger(!P.identity);
const Integer y1 = P.y * IdentityToInteger(!P.identity) + 1 * IdentityToInteger(P.identity);
const Integer z1 = 1 * IdentityToInteger(!P.identity);
const Integer x2 = Q.x * IdentityToInteger(!Q.identity);
const Integer y2 = Q.y * IdentityToInteger(!Q.identity) + 1 * IdentityToInteger(Q.identity);
const Integer z2 = 1 * IdentityToInteger(!Q.identity);
ProjectivePoint p(x1, y1, z1), q(x2, y2, z2), r;
const ECP::FieldElement b3 = field.Multiply(b, 3);
ECP::FieldElement t0 = field.Multiply(X1, X2);
ECP::FieldElement t1 = field.Multiply(Y1, Y2);
ECP::FieldElement t2 = field.Multiply(Z1, Z2);
ECP::FieldElement t3 = field.Add(X1, Y1);
ECP::FieldElement t4 = field.Add(X2, Y2);
t3 = field.Multiply(t3, t4);
t4 = field.Add(t0, t1);
t3 = field.Subtract(t3, t4);
t4 = field.Add(X1, Z1);
ECP::FieldElement t5 = field.Add(X2, Z2);
t4 = field.Multiply(t4, t5);
t5 = field.Add(t0, t2);
t4 = field.Subtract(t4, t5);
t5 = field.Add(Y1, Z1);
X3 = field.Add(Y2, Z2);
t5 = field.Multiply(t5, X3);
X3 = field.Add(t1, t2);
t5 = field.Subtract(t5, X3);
Z3 = field.Multiply(a, t4);
X3 = field.Multiply(b3, t2);
Z3 = field.Add(X3, Z3);
X3 = field.Subtract(t1, Z3);
Z3 = field.Add(t1, Z3);
Y3 = field.Multiply(X3, Z3);
t1 = field.Add(t0, t0);
t1 = field.Add(t1, t0);
t2 = field.Multiply(a, t2);
t4 = field.Multiply(b3, t4);
t1 = field.Add(t1, t2);
t2 = field.Subtract(t0, t2);
t2 = field.Multiply(a, t2);
t4 = field.Add(t4, t2);
t0 = field.Multiply(t1, t4);
Y3 = field.Add(Y3, t0);
t0 = field.Multiply(t5, t4);
X3 = field.Multiply(t3, X3);
X3 = field.Subtract(X3, t0);
t0 = field.Multiply(t3, t1);
Z3 = field.Multiply(t5, Z3);
Z3 = field.Add(Z3, t0);
const ECP::FieldElement inv = field.MultiplicativeInverse(Z3.IsZero() ? Integer::One() : Z3);
X3 = field.Multiply(X3, inv); Y3 = field.Multiply(Y3, inv);
// More gyrations
R.x = X3*Z3.NotZero();
R.y = Y3*Z3.NotZero();
R.identity = Z3.IsZero();
return R;
}
#endif
else // A_Montgomery
{
// More gyrations
bool return_Q = P.identity;
bool return_P = Q.identity;
bool double_P = field.Equal(P.x, Q.x) && field.Equal(P.y, Q.y);
bool identity = field.Equal(P.x, Q.x) && !field.Equal(P.y, Q.y);
// This code taken from Double(P) for below
identity = !!((double_P * (P.identity + (P.y == field.Identity()))) + identity);
ECP::Point S = R;
if (double_P)
{
// This code taken from Double(P)
ECP::FieldElement t = field.Square(P.x);
t = field.Add(field.Add(field.Double(t), t), a);
t = field.Divide(t, field.Double(P.y));
ECP::FieldElement x = field.Subtract(field.Subtract(field.Square(t), P.x), P.x);
R.y = field.Subtract(field.Multiply(t, field.Subtract(P.x, x)), P.y);
R.x.swap(x);
}
else
{
// Original Add(P,Q) code
ECP::FieldElement t = field.Subtract(Q.y, P.y);
t = field.Divide(t, field.Subtract(Q.x, P.x));
ECP::FieldElement x = field.Subtract(field.Subtract(field.Square(t), P.x), Q.x);
R.y = field.Subtract(field.Multiply(t, field.Subtract(P.x, x)), P.y);
R.x.swap(x);
}
// More gyrations
R.x = R.x * IdentityToInteger(!identity);
R.y = R.y * IdentityToInteger(!identity);
R.identity = identity;
if (return_Q)
return (R = S), Q;
else if (return_P)
return (R = S), P;
else
return (S = R), R;
}
}
#undef X
#undef Y
#undef Z
#undef X1
#undef Y1
#undef Z1
#undef X2
#undef Y2
#undef Z2
#undef X3
#undef Y3
#undef Z3
ANONYMOUS_NAMESPACE_END
NAMESPACE_BEGIN(CryptoPP)
@ -243,34 +742,14 @@ const ECP::Point& ECP::Inverse(const Point &P) const
const ECP::Point& ECP::Add(const Point &P, const Point &Q) const
{
if (P.identity) return Q;
if (Q.identity) return P;
if (GetField().Equal(P.x, Q.x))
return GetField().Equal(P.y, Q.y) ? Double(P) : Identity();
FieldElement t = GetField().Subtract(Q.y, P.y);
t = GetField().Divide(t, GetField().Subtract(Q.x, P.x));
FieldElement x = GetField().Subtract(GetField().Subtract(GetField().Square(t), P.x), Q.x);
m_R.y = GetField().Subtract(GetField().Multiply(t, GetField().Subtract(P.x, x)), P.y);
m_R.x.swap(x);
m_R.identity = false;
return m_R;
AdditionFunction add(GetField(), m_a, m_b, m_R);
return (m_R = add(P, Q));
}
const ECP::Point& ECP::Double(const Point &P) const
{
if (P.identity || P.y==GetField().Identity()) return Identity();
FieldElement t = GetField().Square(P.x);
t = GetField().Add(GetField().Add(GetField().Double(t), t), m_a);
t = GetField().Divide(t, GetField().Double(P.y));
FieldElement x = GetField().Subtract(GetField().Subtract(GetField().Square(t), P.x), P.x);
m_R.y = GetField().Subtract(GetField().Multiply(t, GetField().Subtract(P.x, x)), P.y);
m_R.x.swap(x);
m_R.identity = false;
return m_R;
AdditionFunction add(GetField(), m_a, m_b, m_R);
return (m_R = add(P));
}
template <class T, class Iterator> void ParallelInvert(const AbstractRing<T> &ring, Iterator begin, Iterator end)
@ -310,20 +789,11 @@ template <class T, class Iterator> void ParallelInvert(const AbstractRing<T> &ri
}
}
struct ProjectivePoint
{
ProjectivePoint() {}
ProjectivePoint(const Integer &x, const Integer &y, const Integer &z)
: x(x), y(y), z(z) {}
Integer x,y,z;
};
class ProjectiveDoubling
{
public:
ProjectiveDoubling(const ModularArithmetic &m_mr, const Integer &m_a, const Integer &m_b, const ECPPoint &Q)
: mr(m_mr), firstDoubling(true), negated(false)
: mr(m_mr)
{
CRYPTOPP_UNUSED(m_b);
if (Q.identity)
@ -360,7 +830,6 @@ public:
const ModularArithmetic &mr;
ProjectivePoint P;
bool firstDoubling, negated;
Integer sixteenY4, aZ4, twoY, fourY2, S, M;
};

22
ecp.h
View File

@ -35,11 +35,15 @@ public:
/// \brief Construct an ECP
ECP() {}
/// \brief Copy construct an ECP
/// \brief Construct an ECP
/// \param ecp the other ECP object
/// \param convertToMontgomeryRepresentation flag indicating if the curve should be converted to a MontgomeryRepresentation
/// \param convertToMontgomeryRepresentation flag indicating if the curve
/// should be converted to a MontgomeryRepresentation.
/// \details Prior to Crypto++ 8.3 the default value for
/// convertToMontgomeryRepresentation was false. it was changed due to
/// two audit tools finding, "Signature-compatible with a copy constructor".
/// \sa ModularArithmetic, MontgomeryRepresentation
ECP(const ECP &ecp, bool convertToMontgomeryRepresentation = false);
ECP(const ECP &ecp, bool convertToMontgomeryRepresentation);
/// \brief Construct an ECP
/// \param modulus the prime modulus
@ -50,14 +54,22 @@ public:
/// \brief Construct an ECP from BER encoded parameters
/// \param bt BufferedTransformation derived object
/// \details This constructor will decode and extract the the fields fieldID and curve of the sequence ECParameters
/// \details This constructor will decode and extract the the fields
/// fieldID and curve of the sequence ECParameters
ECP(BufferedTransformation &bt);
/// \brief Encode the fields fieldID and curve of the sequence ECParameters
/// \brief DER Encode
/// \param bt BufferedTransformation derived object
/// \details DEREncode encode the fields fieldID and curve of the sequence
/// ECParameters
void DEREncode(BufferedTransformation &bt) const;
/// \brief Compare two points
/// \param P the first point
/// \param Q the second point
/// \returns true if equal, false otherwise
bool Equal(const Point &P, const Point &Q) const;
const Point& Identity() const;
const Point& Inverse(const Point &P) const;
bool InversionIsFast() const {return true;}

179
elgamal.h
View File

@ -11,14 +11,17 @@
#include "integer.h"
#include "gfpcrypt.h"
#include "pubkey.h"
#include "dsa.h"
#include "misc.h"
#include "oids.h"
#include "dsa.h"
#include "asn.h"
NAMESPACE_BEGIN(CryptoPP)
/// \brief ElGamal key agreement and encryption schemes base class
/// \since Crypto++ 1.0
class CRYPTOPP_NO_VTABLE ElGamalBase : public DL_KeyAgreementAlgorithm_DH<Integer, NoCofactorMultiplication>,
class CRYPTOPP_NO_VTABLE ElGamalBase :
public DL_KeyAgreementAlgorithm_DH<Integer, NoCofactorMultiplication>,
public DL_KeyDerivationAlgorithm<Integer>,
public DL_SymmetricEncryptionAlgorithm
{
@ -27,7 +30,8 @@ public:
void Derive(const DL_GroupParameters<Integer> &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const
{
CRYPTOPP_UNUSED(groupParams), CRYPTOPP_UNUSED(ephemeralPublicKey), CRYPTOPP_UNUSED(derivationParams);
CRYPTOPP_UNUSED(groupParams); CRYPTOPP_UNUSED(ephemeralPublicKey);
CRYPTOPP_UNUSED(derivationParams);
agreedElement.Encode(derivedKey, derivedLength);
}
@ -49,6 +53,8 @@ public:
size_t GetMaxSymmetricPlaintextLength(size_t cipherTextLength) const
{
unsigned int len = GetGroupParameters().GetModulus().ByteCount();
CRYPTOPP_ASSERT(len >= 3);
if (cipherTextLength == len)
return STDMIN(255U, len-3);
else
@ -93,9 +99,14 @@ public:
};
/// \brief ElGamal key agreement and encryption schemes default implementation
/// \tparam BASE Base class implementation
/// \tparam SCHEME_OPTIONS Scheme options
/// \tparam Key ElGamal key classes
/// \since Crypto++ 1.0
template <class BASE, class SCHEME_OPTIONS, class KEY>
class ElGamalObjectImpl : public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>, public ElGamalBase
class ElGamalObjectImpl :
public DL_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY>,
public ElGamalBase
{
public:
virtual ~ElGamalObjectImpl() {}
@ -114,30 +125,174 @@ protected:
const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {return *this;}
};
/// \brief ElGamal Public Key adapter
/// \tparam BASE PublicKey derived class
/// \details DL_PublicKey_ElGamal provides an override for GetAlgorithmID()
/// to utilize 1.3.14.7.2.1.1. Prior to DL_PublicKey_ElGamal, the ElGamal
/// keys [mistakenly] used the OID from DSA due to DL_GroupParmaters_GFP().
/// If you need to <tt>Load</tt> an ElGamal key with the wrong OID then
/// see <A HREF="https://www.cryptopp.com/wiki/ElGamal">ElGamal</A> on
/// the Crypto++ wiki.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/876">Issue 876</A>,
/// <A HREF="https://github.com/weidai11/cryptopp/issues/567">Issue 567</A>
/// \since Crypto++ 8.3
template <class BASE>
struct DL_PublicKey_ElGamal : public BASE
{
virtual ~DL_PublicKey_ElGamal() {}
/// \brief Retrieves the OID of the algorithm
/// \returns OID of the algorithm
/// \details DL_PrivateKey_ElGamal provides an override for GetAlgorithmID()
/// to utilize 1.3.14.7.2.1.1. Prior to DL_PrivateKey_ElGamal, the ElGamal
/// keys [mistakenly] used the OID from DSA due to DL_GroupParmaters_GFP().
/// If you need to <tt>Load</tt> an ElGamal key with the wrong OID then
/// see <A HREF="https://www.cryptopp.com/wiki/ElGamal">ElGamal</A> on
/// the Crypto++ wiki.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/876">Issue 876</A>,
/// <A HREF="https://github.com/weidai11/cryptopp/issues/567">Issue 567</A>
virtual OID GetAlgorithmID() const {
return ASN1::elGamal();
}
};
/// \brief ElGamal Private Key adapter
/// \tparam BASE PrivateKey derived class
/// \details DL_PrivateKey_ElGamal provides an override for GetAlgorithmID()
/// to utilize 1.3.14.7.2.1.1. Prior to DL_PrivateKey_ElGamal, the ElGamal
/// keys [mistakenly] used the OID from DSA due to DL_GroupParmaters_GFP().
/// If you need to <tt>Load</tt> an ElGamal key with the wrong OID then
/// see <A HREF="https://www.cryptopp.com/wiki/ElGamal">ElGamal</A> on
/// the Crypto++ wiki.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/876">Issue 876</A>,
/// <A HREF="https://github.com/weidai11/cryptopp/issues/567">Issue 567</A>
/// \since Crypto++ 8.3
template <class BASE>
struct DL_PrivateKey_ElGamal : public BASE
{
virtual ~DL_PrivateKey_ElGamal() {}
/// \brief Retrieves the OID of the algorithm
/// \returns OID of the algorithm
/// \details DL_PrivateKey_ElGamal provides an override for GetAlgorithmID()
/// to utilize 1.3.14.7.2.1.1. Prior to DL_PrivateKey_ElGamal, the ElGamal
/// keys [mistakenly] used the OID from DSA due to DL_GroupParmaters_GFP().
/// If you need to <tt>Load</tt> an ElGamal key with the wrong OID then
/// see <A HREF="https://www.cryptopp.com/wiki/ElGamal">ElGamal</A> on
/// the Crypto++ wiki.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/876">Issue 876</A>,
/// <A HREF="https://github.com/weidai11/cryptopp/issues/567">Issue 567</A>
virtual OID GetAlgorithmID() const {
return ASN1::elGamal();
}
/// \brief Check the key for errors
/// \param rng RandomNumberGenerator for objects which use randomized testing
/// \param level level of thoroughness
/// \return true if the tests succeed, false otherwise
/// \details There are four levels of thoroughness:
/// <ul>
/// <li>0 - using this object won't cause a crash or exception
/// <li>1 - this object will probably function, and encrypt, sign, other
/// operations correctly
/// <li>2 - ensure this object will function correctly, and perform
/// reasonable security checks
/// <li>3 - perform reasonable security checks, and do checks that may
/// take a long time
/// </ul>
/// \details Level 0 does not require a RandomNumberGenerator. A NullRNG() can
/// be used for level 0. Level 1 may not check for weak keys and such.
/// Levels 2 and 3 are recommended.
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
{
// Validate() formerly used DL_PrivateKey_GFP implementation through
// inheritance. However, it would reject keys from other libraries
// like BouncyCastle. The failure was x < q. According to ElGamal's
// paper and the HAC, the private key is selected in over [1,p-1],
// Later Tsiounis and Yung showed the lower limit as [1,q-1] in
// "On the Security of EIGamal Based Encryption". As such, Crypto++
// will generate a key in the range [1,q-1], but accept a key
// in [1,p-1]. Thanks to JPM for finding the reference. Also see
// https://github.com/weidai11/cryptopp/commit/a5a684d92986.
CRYPTOPP_ASSERT(this->GetAbstractGroupParameters().Validate(rng, level));
bool pass = this->GetAbstractGroupParameters().Validate(rng, level);
const Integer &p = this->GetGroupParameters().GetModulus();
const Integer &q = this->GetAbstractGroupParameters().GetSubgroupOrder();
const Integer &x = this->GetPrivateExponent();
// Changed to x < p-1 based on ElGamal's paper and the HAC.
CRYPTOPP_ASSERT(x.IsPositive());
CRYPTOPP_ASSERT(x < p-1);
pass = pass && x.IsPositive() && x < p-1;
if (level >= 1)
{
// Minimum security level due to Tsiounis and Yung.
CRYPTOPP_ASSERT(Integer::Gcd(x, q) == Integer::One());
pass = pass && Integer::Gcd(x, q) == Integer::One();
}
return pass;
}
};
/// \brief ElGamal key agreement and encryption schemes keys
/// \details The ElGamalKeys class used DL_PrivateKey_GFP_OldFormat and DL_PublicKey_GFP_OldFormat
/// for the PrivateKey and PublicKey typedef from about Crypto++ 1.0 through Crypto++ 5.6.5.
/// At Crypto++ 6.0 the serialization format was cutover to standard PKCS8 and X509 encodings.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/commit/a5a684d92986e8e2">Commit a5a684d92986e8e2</A>
/// \details ElGamalKeys provide the algorithm implementation ElGamal key
/// agreement and encryption schemes.
/// \details The ElGamalKeys class used <tt>DL_PrivateKey_GFP_OldFormat</tt>
/// and <tt>DL_PublicKey_GFP_OldFormat</tt> for the <tt>PrivateKey</tt> and
/// <tt>PublicKey</tt> from about Crypto++ 1.0 through Crypto++ 5.6.5. At
/// Crypto++ 6.0 the serialization format was cutover to standard PKCS8 and
/// X509 encodings.
/// \details The ElGamalKeys class [mistakenly] used the OID for DSA from
/// about Crypto++ 1.0 through Crypto++ 8.2. At Crypto++ 8.3 the OID was
/// fixed and now uses ElGamal encryption, which is 1.3.14.7.2.1.1.
/// If you need to <tt>Load</tt> an ElGamal key with the wrong OID then
/// see <A HREF="https://www.cryptopp.com/wiki/ElGamal">ElGamal</A> on
/// the Crypto++ wiki.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/876">Issue 876</A>,
/// <A HREF="https://github.com/weidai11/cryptopp/issues/567">Issue 567</A>
/// \since Crypto++ 1.0
struct ElGamalKeys
{
/// \brief Implements DL_GroupParameters interface
typedef DL_CryptoKeys_GFP::GroupParameters GroupParameters;
typedef DL_CryptoKeys_GFP::PrivateKey PrivateKey;
typedef DL_CryptoKeys_GFP::PublicKey PublicKey;
/// \brief Implements DL_PrivateKey interface
typedef DL_PrivateKey_ElGamal<DL_CryptoKeys_GFP::PrivateKey> PrivateKey;
/// \brief Implements DL_PublicKey interface
typedef DL_PublicKey_ElGamal<DL_CryptoKeys_GFP::PublicKey> PublicKey;
};
/// \brief ElGamal encryption scheme with non-standard padding
/// \details ElGamal provide the algorithm implementation ElGamal key
/// agreement and encryption schemes.
/// \details The ElGamal class [mistakenly] used the OID for DSA from about
/// Crypto++ 1.0 through Crypto++ 8.2. At Crypto++ 8.3 the OID was fixed
/// and now uses ElGamal encryption, which is 1.3.14.7.2.1.1.
/// If you need to <tt>Load</tt> an ElGamal key with the wrong OID then
/// see <A HREF="https://www.cryptopp.com/wiki/ElGamal">ElGamal</A> on
/// the Crypto++ wiki.
/// \sa <A HREF="https://github.com/weidai11/cryptopp/issues/876">Issue 876</A>,
/// <A HREF="https://github.com/weidai11/cryptopp/issues/567">Issue 567</A>
/// \since Crypto++ 1.0
struct ElGamal
{
typedef DL_CryptoSchemeOptions<ElGamal, ElGamalKeys, int, int, int> SchemeOptions;
typedef SchemeOptions::PrivateKey PrivateKey;
typedef SchemeOptions::PublicKey PublicKey;
/// \brief The algorithm name
/// \returns the algorithm name
/// \details StaticAlgorithmName returns the algorithm's name as a static
/// member function.
CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";}
/// \brief Implements DL_GroupParameters interface
typedef SchemeOptions::GroupParameters GroupParameters;
/// implements PK_Encryptor interface
/// \brief Implements PK_Encryptor interface
typedef PK_FinalTemplate<ElGamalObjectImpl<DL_EncryptorBase<Integer>, SchemeOptions, SchemeOptions::PublicKey> > Encryptor;
/// implements PK_Decryptor interface
/// \brief Implements PK_Encryptor interface
typedef PK_FinalTemplate<ElGamalObjectImpl<DL_DecryptorBase<Integer>, SchemeOptions, SchemeOptions::PrivateKey> > Decryptor;
};

215
fhmqv.h
View File

@ -30,30 +30,85 @@ public:
virtual ~FHMQV_Domain() {}
FHMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {}
/// \brief Construct a FHMQV domain
/// \param clientRole flag indicating initiator or recipient
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
FHMQV_Domain(bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) {}
/// \brief Construct a FHMQV domain
/// \param params group parameters and options
/// \param clientRole flag indicating initiator or recipient
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
FHMQV_Domain(const GroupParameters &params, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {}
/// \brief Construct a FHMQV domain
/// \param bt BufferedTransformation with group parameters and options
/// \param clientRole flag indicating initiator or recipient
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
FHMQV_Domain(BufferedTransformation &bt, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.BERDecode(bt);}
/// \brief Construct a FHMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1 is passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1>
FHMQV_Domain(T1 v1, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.Initialize(v1);}
/// \brief Construct a FHMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \tparam T2 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param v2 second parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1, class T2>
FHMQV_Domain(T1 v1, T2 v2, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.Initialize(v1, v2);}
/// \brief Construct a FHMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \tparam T2 template parameter used as a constructor parameter
/// \tparam T3 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param v2 second parameter
/// \param v3 third parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1, class T2, class T3>
FHMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.Initialize(v1, v2, v3);}
/// \brief Construct a FHMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \tparam T2 template parameter used as a constructor parameter
/// \tparam T3 template parameter used as a constructor parameter
/// \tparam T4 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param v2 second parameter
/// \param v3 third parameter
/// \param v4 third parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1, class T2, class T3, class T4>
FHMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer)
@ -61,28 +116,62 @@ public:
public:
/// \brief Retrieves the group parameters for this domain
/// \return the group parameters for this domain as a const reference
const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
/// \brief Retrieves the group parameters for this domain
/// \return the group parameters for this domain as a non-const reference
GroupParameters & AccessGroupParameters() {return m_groupParameters;}
/// \brief Retrieves the crypto parameters for this domain
/// \return the crypto parameters for this domain as a non-const reference
CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
/// return length of agreed value produced
unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
/// return length of static private keys in this domain
unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
/// return length of static public keys in this domain
unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);}
/// \brief Provides the size of the agreed value
/// \return size of agreed value produced in this domain
/// \details The length is calculated using <tt>GetEncodedElementSize(false)</tt>,
/// which means the element is encoded in a non-reversible format. A
/// non-reversible format means its a raw byte array, and it lacks presentation
/// format like an ASN.1 BIT_STRING or OCTET_STRING.
unsigned int AgreedValueLength() const
{return GetAbstractGroupParameters().GetEncodedElementSize(false);}
/// generate static private key
/*! \pre size of privateKey == PrivateStaticKeyLength() */
/// \brief Provides the size of the static private key
/// \return size of static private keys in this domain
/// \details The length is calculated using the byte count of the subgroup order.
unsigned int StaticPrivateKeyLength() const
{return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
/// \brief Provides the size of the static public key
/// \return size of static public keys in this domain
/// \details The length is calculated using <tt>GetEncodedElementSize(true)</tt>,
/// which means the element is encoded in a reversible format. A reversible
/// format means it has a presentation format, and its an ANS.1 encoded element
/// or point.
unsigned int StaticPublicKeyLength() const
{return GetAbstractGroupParameters().GetEncodedElementSize(true);}
/// \brief Generate static private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer for the generated private key in this domain
/// \details The private key is a random scalar used as an exponent in the range
/// <tt>[1,MaxExponent()]</tt>.
/// \pre <tt>COUNTOF(privateKey) == PrivateStaticKeyLength()</tt>
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
{
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
x.Encode(privateKey, StaticPrivateKeyLength());
}
/// generate static public key
/*! \pre size of publicKey == PublicStaticKeyLength() */
/// \brief Generate a static public key from a private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer with the previously generated private key
/// \param publicKey a byte buffer for the generated public key in this domain
/// \details The public key is an element or point on the curve, and its stored
/// in a revrsible format. A reversible format means it has a presentation
/// format, and its an ANS.1 encoded element or point.
/// \pre <tt>COUNTOF(publicKey) == PublicStaticKeyLength()</tt>
void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
{
CRYPTOPP_UNUSED(rng);
@ -92,10 +181,22 @@ public:
params.EncodeElement(true, y, publicKey);
}
/// \brief Provides the size of the ephemeral private key
/// \return size of ephemeral private keys in this domain
/// \details An ephemeral private key is a private key and public key.
/// The serialized size is different than a static private key.
unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
/// \brief Provides the size of the ephemeral public key
/// \return size of ephemeral public keys in this domain
/// \details An ephemeral public key is a public key.
/// The serialized size is the same as a static public key.
unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();}
/// return length of ephemeral private keys in this domain
/// \brief Generate ephemeral private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer for the generated private key in this domain
/// \pre <tt>COUNTOF(privateKey) == EphemeralPrivateKeyLength()</tt>
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
{
const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
@ -105,28 +206,46 @@ public:
params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
}
/// return length of ephemeral public keys in this domain
/// \brief Generate ephemeral public key from a private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer with the previously generated private key
/// \param publicKey a byte buffer for the generated public key in this domain
/// \pre <tt>COUNTOF(publicKey) == EphemeralPublicKeyLength()</tt>
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
{
CRYPTOPP_UNUSED(rng);
memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
}
/// derive agreed value from your private keys and couterparty's public keys, return false in case of failure
/*! \note The ephemeral public key will always be validated.
If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time.
\pre size of agreedValue == AgreedValueLength()
\pre length of staticPrivateKey == StaticPrivateKeyLength()
\pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength()
\pre length of staticOtherPublicKey == StaticPublicKeyLength()
\pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength()
*/
/// \brief Derive agreed value or shared secret
/// \param agreedValue the shared secret
/// \param staticPrivateKey your long term private key
/// \param ephemeralPrivateKey your ephemeral private key
/// \param staticOtherPublicKey couterparty's long term public key
/// \param ephemeralOtherPublicKey couterparty's ephemeral public key
/// \param validateStaticOtherPublicKey flag indicating validation
/// \return true upon success, false in case of failure
/// \details Agree() performs the authenticated key agreement. Agree()
/// derives a shared secret from your private keys and couterparty's
/// public keys. Each instance or run of the protocol should use a new
/// ephemeral key pair.
/// \details The other's ephemeral public key will always be validated at
/// Level 1 to ensure it is a point on the curve.
/// <tt>validateStaticOtherPublicKey</tt> determines how thoroughly other's
/// static public key is validated. If you have previously validated the
/// couterparty's static public key, then use
/// <tt>validateStaticOtherPublicKey=false</tt> to save time.
/// \pre <tt>COUNTOF(agreedValue) == AgreedValueLength()
/// \pre <tt>COUNTOF(staticPrivateKey) == StaticPrivateKeyLength()</tt>
/// \pre <tt>COUNTOF(ephemeralPrivateKey) == EphemeralPrivateKeyLength()</tt>
/// \pre <tt>COUNTOF(staticOtherPublicKey) == StaticPublicKeyLength()</tt>
/// \pre <tt>COUNTOF(ephemeralOtherPublicKey) == EphemeralPublicKeyLength()</tt>
bool Agree(byte *agreedValue,
const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
bool validateStaticOtherPublicKey=true) const
{
byte *XX = NULLPTR, *YY = NULLPTR, *AA = NULLPTR, *BB = NULLPTR;
const byte *XX = NULLPTR, *YY = NULLPTR, *AA = NULLPTR, *BB = NULLPTR;
size_t xxs = 0, yys = 0, aas = 0, bbs = 0;
// Depending on the role, this will hold either A's or B's static
@ -144,60 +263,43 @@ public:
Element B = params.ExponentiateBase(b);
params.EncodeElement(true, B, tt);
XX = const_cast<byte*>(ephemeralOtherPublicKey);
XX = ephemeralOtherPublicKey;
xxs = EphemeralPublicKeyLength();
YY = const_cast<byte*>(ephemeralPrivateKey) + StaticPrivateKeyLength();
YY = ephemeralPrivateKey + StaticPrivateKeyLength();
yys = EphemeralPublicKeyLength();
AA = const_cast<byte*>(staticOtherPublicKey);
AA = staticOtherPublicKey;
aas = StaticPublicKeyLength();
BB = tt.BytePtr();
bbs = tt.SizeInBytes();
}
else if(m_role == RoleClient)
else
{
Integer a(staticPrivateKey, StaticPrivateKeyLength());
Element A = params.ExponentiateBase(a);
params.EncodeElement(true, A, tt);
XX = const_cast<byte*>(ephemeralPrivateKey) + StaticPrivateKeyLength();
XX = ephemeralPrivateKey + StaticPrivateKeyLength();
xxs = EphemeralPublicKeyLength();
YY = const_cast<byte*>(ephemeralOtherPublicKey);
YY = ephemeralOtherPublicKey;
yys = EphemeralPublicKeyLength();
AA = tt.BytePtr();
aas = tt.SizeInBytes();
BB = const_cast<byte*>(staticOtherPublicKey);
BB = staticOtherPublicKey;
bbs = StaticPublicKeyLength();
}
else
{
CRYPTOPP_ASSERT(0);
return false;
}
// DecodeElement calls ValidateElement at level 1. Level 1 only calls
// VerifyPoint to ensure the element is in G*. If the other's PublicKey is
// requested to be validated, we manually call ValidateElement at level 3.
Element VV1 = params.DecodeElement(staticOtherPublicKey, false);
if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULLPTR))
return false;
// DecodeElement calls ValidateElement at level 1. Level 1 only calls
// VerifyPoint to ensure the element is in G*. Crank it up.
Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false);
if(!params.ValidateElement(3, VV2, NULLPTR))
return false;
Element VV1 = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, true);
const Integer& q = params.GetSubgroupOrder();
const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8);
Integer d, e;
SecByteBlock dd(len), ee(len);
Hash(NULLPTR, XX, xxs, YY, yys, AA, aas, BB, bbs, dd.BytePtr(), dd.SizeInBytes());
d.Decode(dd.BytePtr(), dd.SizeInBytes());
Integer d(dd.BytePtr(), dd.SizeInBytes());
Hash(NULLPTR, YY, yys, XX, xxs, AA, aas, BB, bbs, ee.BytePtr(), ee.SizeInBytes());
e.Decode(ee.BytePtr(), ee.SizeInBytes());
Integer e(ee.BytePtr(), ee.SizeInBytes());
Element sigma;
if(m_role == RoleServer)
@ -233,6 +335,7 @@ public:
}
catch (DL_BadElement &)
{
CRYPTOPP_ASSERT(0);
return false;
}
return true;
@ -251,9 +354,11 @@ protected:
if(sigma)
{
Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma);
SecByteBlock sbb(x.MinEncodedSize());
x.Encode(sbb.BytePtr(), sbb.SizeInBytes());
//Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma);
//SecByteBlock sbb(x.MinEncodedSize());
//x.Encode(sbb.BytePtr(), sbb.SizeInBytes());
SecByteBlock sbb(GetAbstractGroupParameters().GetEncodedElementSize(false));
GetAbstractGroupParameters().EncodeElement(false, *sigma, sbb);
hash.Update(sbb.BytePtr(), sbb.SizeInBytes());
}
@ -294,7 +399,7 @@ private:
/// \details This implementation follows Augustin P. Sarr and Philippe ElbazVincent, and JeanClaude Bajard's
/// <a href="http://eprint.iacr.org/2009/408">A Secure and Efficient Authenticated Diffie-Hellman Protocol</a>.
/// Note: this is FHMQV, Protocol 5, from page 11; and not FHMQV-C.
/// \sa FHMQV, MQV_Domain, HMQV_Domain, AuthenticatedKeyAgreementDomain
/// \sa FHMQV, MQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain
/// \since Crypto++ 5.6.4
typedef FHMQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> FHMQV;

View File

@ -595,7 +595,9 @@ StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c,
m_isSpecial = m_cipher.IsLastBlockSpecial() && m_mandatoryBlockSize > 1;
m_reservedBufferSize = STDMAX(2*m_mandatoryBlockSize, m_optimalBufferSize);
IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding));
FilterWithBufferedInput::IsolatedInitialize(
MakeParameters
(Name::BlockPaddingScheme(), padding));
}
StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool authenticated)
@ -616,7 +618,9 @@ StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c,
m_isSpecial = m_cipher.IsLastBlockSpecial() && m_mandatoryBlockSize > 1;
m_reservedBufferSize = STDMAX(2*m_mandatoryBlockSize, m_optimalBufferSize);
IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding));
FilterWithBufferedInput::IsolatedInitialize(
MakeParameters
(Name::BlockPaddingScheme(), padding));
}
size_t StreamTransformationFilter::LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding)
@ -889,7 +893,10 @@ HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedT
: FilterWithBufferedInput(attachment)
, m_hashModule(hm), m_flags(0), m_digestSize(0), m_verified(false)
{
IsolatedInitialize(MakeParameters(Name::HashVerificationFilterFlags(), flags)(Name::TruncatedDigestSize(), truncatedDigestSize));
FilterWithBufferedInput::IsolatedInitialize(
MakeParameters
(Name::HashVerificationFilterFlags(), flags)
(Name::TruncatedDigestSize(), truncatedDigestSize));
}
void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
@ -994,7 +1001,11 @@ AuthenticatedDecryptionFilter::AuthenticatedDecryptionFilter(AuthenticatedSymmet
, m_streamFilter(c, new OutputProxy(*this, false), padding, true)
{
CRYPTOPP_ASSERT(!c.IsForwardTransformation() || c.IsSelfInverting());
IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding)(Name::AuthenticatedDecryptionFilterFlags(), flags)(Name::TruncatedDigestSize(), truncatedDigestSize));
FilterWithBufferedInput::IsolatedInitialize(
MakeParameters
(Name::BlockPaddingScheme(), padding)
(Name::AuthenticatedDecryptionFilterFlags(), flags)
(Name::TruncatedDigestSize(), truncatedDigestSize));
}
void AuthenticatedDecryptionFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
@ -1079,7 +1090,9 @@ SignatureVerificationFilter::SignatureVerificationFilter(const PK_Verifier &veri
: FilterWithBufferedInput(attachment)
, m_verifier(verifier), m_flags(0), m_verified(0)
{
IsolatedInitialize(MakeParameters(Name::SignatureVerificationFilterFlags(), flags));
FilterWithBufferedInput::IsolatedInitialize(
MakeParameters
(Name::SignatureVerificationFilterFlags(), flags));
}
void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)

View File

@ -474,7 +474,7 @@ struct BlockPaddingSchemeDef
/// \brief 0's padding added to a block
/// \since Crypto++ 5.0
ZEROS_PADDING,
/// \brief PKCS #5 padding added to a block
/// \brief PKCS padding added to a block
/// \since Crypto++ 5.0
PKCS_PADDING,
/// \brief 1 and 0's padding added to a block
@ -1100,6 +1100,7 @@ CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::string>;
/// \brief Append input to a std::vector<byte> object
/// \details VectorSink is a typedef for StringSinkTemplate<std::vector<byte> >.
/// \since Crypto++ 8.0
DOCUMENTED_TYPEDEF(StringSinkTemplate<std::vector<byte> >, VectorSink)
CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate<std::vector<byte> >;

View File

@ -47,31 +47,35 @@ bool PowerUpSelfTestInProgressOnThisThread()
{
#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
return s_inProgress;
#endif
#else
return false;
#endif
}
void SetPowerUpSelfTestInProgressOnThisThread(bool inProgress)
{
CRYPTOPP_UNUSED(inProgress);
#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
s_inProgress = inProgress;
#else
CRYPTOPP_UNUSED(inProgress);
#endif
}
void EncryptionPairwiseConsistencyTest_FIPS_140_Only(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor)
{
CRYPTOPP_UNUSED(encryptor), CRYPTOPP_UNUSED(decryptor);
#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
EncryptionPairwiseConsistencyTest(encryptor, decryptor);
#else
CRYPTOPP_UNUSED(encryptor), CRYPTOPP_UNUSED(decryptor);
#endif
}
void SignaturePairwiseConsistencyTest_FIPS_140_Only(const PK_Signer &signer, const PK_Verifier &verifier)
{
CRYPTOPP_UNUSED(signer), CRYPTOPP_UNUSED(verifier);
#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2
SignaturePairwiseConsistencyTest(signer, verifier);
#else
CRYPTOPP_UNUSED(signer), CRYPTOPP_UNUSED(verifier);
#endif
}

24
gcm.cpp
View File

@ -44,7 +44,7 @@ NAMESPACE_BEGIN(CryptoPP)
#endif
#endif // CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64
// Clang __m128i casts, http://bugs.llvm.org/show_bug.cgi?id=20670
// Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670
#define M128_CAST(x) ((__m128i *)(void *)(x))
#define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x))
@ -75,8 +75,8 @@ extern void GCM_Xor16_SSE2(byte *a, const byte *b, const byte *c);
extern void GCM_Xor16_NEON(byte *a, const byte *b, const byte *c);
#endif
#if CRYPTOPP_POWER7_AVAILABLE
extern void GCM_Xor16_POWER7(byte *a, const byte *b, const byte *c);
#if CRYPTOPP_POWER8_AVAILABLE
extern void GCM_Xor16_POWER8(byte *a, const byte *b, const byte *c);
#endif
#if CRYPTOPP_CLMUL_AVAILABLE
@ -213,11 +213,11 @@ void GCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const
for (k=1; k<j; k++)
GCM_Xor16_NEON(mulTable+i*256*16+(j+k)*16, mulTable+i*256*16+j*16, mulTable+i*256*16+k*16);
else
#elif CRYPTOPP_POWER7_AVAILABLE
if (HasPower7())
#elif CRYPTOPP_POWER8_AVAILABLE
if (HasPower8())
for (j=2; j<=0x80; j*=2)
for (k=1; k<j; k++)
GCM_Xor16_POWER7(mulTable+i*256*16+(j+k)*16, mulTable+i*256*16+j*16, mulTable+i*256*16+k*16);
GCM_Xor16_POWER8(mulTable+i*256*16+(j+k)*16, mulTable+i*256*16+j*16, mulTable+i*256*16+k*16);
else
#endif
for (j=2; j<=0x80; j*=2)
@ -277,13 +277,13 @@ void GCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const
GCM_Xor16_NEON(mulTable+1024+i*256+(j+k)*16, mulTable+1024+i*256+j*16, mulTable+1024+i*256+k*16);
}
else
#elif CRYPTOPP_POWER7_AVAILABLE
if (HasPower7())
#elif CRYPTOPP_POWER8_AVAILABLE
if (HasPower8())
for (j=2; j<=8; j*=2)
for (k=1; k<j; k++)
{
GCM_Xor16_POWER7(mulTable+i*256+(j+k)*16, mulTable+i*256+j*16, mulTable+i*256+k*16);
GCM_Xor16_POWER7(mulTable+1024+i*256+(j+k)*16, mulTable+1024+i*256+j*16, mulTable+1024+i*256+k*16);
GCM_Xor16_POWER8(mulTable+i*256+(j+k)*16, mulTable+i*256+j*16, mulTable+i*256+k*16);
GCM_Xor16_POWER8(mulTable+1024+i*256+(j+k)*16, mulTable+1024+i*256+j*16, mulTable+1024+i*256+k*16);
}
else
#endif
@ -369,8 +369,8 @@ unsigned int GCM_Base::OptimalDataAlignment() const
HasSSE2() ? 16 :
#elif CRYPTOPP_ARM_NEON_AVAILABLE
HasNEON() ? 4 :
#elif CRYPTOPP_POWER7_AVAILABLE
HasPower7() ? 16 :
#elif CRYPTOPP_POWER8_AVAILABLE
HasPower8() ? 16 :
#endif
GetBlockCipher().OptimalDataAlignment();
}

View File

@ -56,14 +56,10 @@
# define EXCEPTION_EXECUTE_HANDLER 1
#endif
// Clang __m128i casts, http://bugs.llvm.org/show_bug.cgi?id=20670
// Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670
#define M128_CAST(x) ((__m128i *)(void *)(x))
#define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x))
// GCC cast warning
#define UINT64X2_CAST(x) ((uint64x2_t *)(void *)(x))
#define CONST_UINT64X2_CAST(x) ((const uint64x2_t *)(const void *)(x))
// Squash MS LNK4221 and libtool warnings
extern const char GCM_SIMD_FNAME[] = __FILE__;
@ -219,10 +215,7 @@ bool CPU_ProbePMULL()
#if CRYPTOPP_ARM_NEON_AVAILABLE
void GCM_Xor16_NEON(byte *a, const byte *b, const byte *c)
{
CRYPTOPP_ASSERT(IsAlignedOn(a,GetAlignmentOf<uint64x2_t>()));
CRYPTOPP_ASSERT(IsAlignedOn(b,GetAlignmentOf<uint64x2_t>()));
CRYPTOPP_ASSERT(IsAlignedOn(c,GetAlignmentOf<uint64x2_t>()));
*UINT64X2_CAST(a) = veorq_u64(*CONST_UINT64X2_CAST(b), *CONST_UINT64X2_CAST(c));
vst1q_u8(a, veorq_u8(vld1q_u8(b), vld1q_u8(c)));
}
#endif // CRYPTOPP_ARM_NEON_AVAILABLE
@ -569,12 +562,12 @@ void GCM_ReverseHashBufferIfNeeded_CLMUL(byte *hashBuffer)
// ***************************** POWER8 ***************************** //
#if CRYPTOPP_POWER7_AVAILABLE
void GCM_Xor16_POWER7(byte *a, const byte *b, const byte *c)
#if CRYPTOPP_POWER8_AVAILABLE
void GCM_Xor16_POWER8(byte *a, const byte *b, const byte *c)
{
VecStore(VecXor(VecLoad(b), VecLoad(c)), a);
}
#endif // CRYPTOPP_POWER7_AVAILABLE
#endif // CRYPTOPP_POWER8_AVAILABLE
#if CRYPTOPP_POWER8_VMULL_AVAILABLE

View File

@ -21,6 +21,8 @@
#include "pch.h"
#include "config.h"
#ifndef CRYPTOPP_IMPORTS
#include "gf2n.h"
#if (CRYPTOPP_CLMUL_AVAILABLE)
@ -463,36 +465,33 @@ NAMESPACE_BEGIN(CryptoPP)
void
GF2NT_233_Multiply_Reduce_CLMUL(const word* pA, const word* pB, word* pC)
{
const __m128i* pAA = reinterpret_cast<const __m128i*>(pA);
const __m128i* pBB = reinterpret_cast<const __m128i*>(pB);
__m128i a0 = _mm_loadu_si128(pAA+0);
__m128i a1 = _mm_loadu_si128(pAA+1);
__m128i b0 = _mm_loadu_si128(pBB+0);
__m128i b1 = _mm_loadu_si128(pBB+1);
enum {S=sizeof(__m128i)/sizeof(word)};
__m128i a0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pA+0*S));
__m128i a1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pA+1*S));
__m128i b0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pB+0*S));
__m128i b1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pB+1*S));
__m128i c0, c1, c2, c3;
F2N_Multiply_256x256_CLMUL(c3, c2, c1, c0, a1, a0, b1, b0);
GF2NT_233_Reduce_CLMUL(c3, c2, c1, c0);
__m128i* pCC = reinterpret_cast<__m128i*>(pC);
_mm_storeu_si128(pCC+0, c0);
_mm_storeu_si128(pCC+1, c1);
_mm_storeu_si128(reinterpret_cast<__m128i*>(pC+0*S), c0);
_mm_storeu_si128(reinterpret_cast<__m128i*>(pC+1*S), c1);
}
void
GF2NT_233_Square_Reduce_CLMUL(const word* pA, word* pC)
{
const __m128i* pAA = reinterpret_cast<const __m128i*>(pA);
__m128i a0 = _mm_loadu_si128(pAA+0);
__m128i a1 = _mm_loadu_si128(pAA+1);
enum {S=sizeof(__m128i)/sizeof(word)};
__m128i a0 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pA+0*S));
__m128i a1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(pA+1*S));
__m128i c0, c1, c2, c3;
F2N_Square_256_CLMUL(c3, c2, c1, c0, a1, a0);
GF2NT_233_Reduce_CLMUL(c3, c2, c1, c0);
__m128i* pCC = reinterpret_cast<__m128i*>(pC);
_mm_storeu_si128(pCC+0, c0);
_mm_storeu_si128(pCC+1, c1);
_mm_storeu_si128(reinterpret_cast<__m128i*>(pC+0*S), c0);
_mm_storeu_si128(reinterpret_cast<__m128i*>(pC+1*S), c1);
}
#elif (CRYPTOPP_ARM_PMULL_AVAILABLE)
@ -608,3 +607,5 @@ GF2NT_233_Square_Reduce_POWER8(const word* pA, word* pC)
#endif
NAMESPACE_END
#endif // CRYPTOPP_IMPORTS

View File

@ -133,22 +133,27 @@ void DL_SignatureMessageEncodingMethod_NR::ComputeMessageRepresentative(RandomNu
bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const
{
const Integer &p = GetModulus(), &q = GetSubgroupOrder();
bool pass = true;
CRYPTOPP_ASSERT(p > Integer::One() && p.IsOdd());
pass = pass && p > Integer::One() && p.IsOdd();
CRYPTOPP_ASSERT(pass);
CRYPTOPP_ASSERT(q > Integer::One() && q.IsOdd());
pass = pass && q > Integer::One() && q.IsOdd();
CRYPTOPP_ASSERT(pass);
if (level >= 1)
{
CRYPTOPP_ASSERT(GetCofactor() > Integer::One());
CRYPTOPP_ASSERT(GetGroupOrder() % q == Integer::Zero());
pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero();
CRYPTOPP_ASSERT(pass);
}
if (level >= 2)
{
CRYPTOPP_ASSERT(VerifyPrime(rng, q, level-2));
CRYPTOPP_ASSERT(VerifyPrime(rng, p, level-2));
pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2);
CRYPTOPP_ASSERT(pass);
}
return pass;
@ -157,28 +162,28 @@ bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng,
bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation<Integer> *gpc) const
{
const Integer &p = GetModulus(), &q = GetSubgroupOrder();
bool pass = true;
pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();
CRYPTOPP_ASSERT(pass);
CRYPTOPP_ASSERT(GetFieldType() == 1 ? g.IsPositive() : g.NotNegative());
pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative();
CRYPTOPP_ASSERT(g < p && !IsIdentity(g));
pass = pass && g < p && !IsIdentity(g);
CRYPTOPP_ASSERT(pass);
if (level >= 1)
{
if (gpc)
{
CRYPTOPP_ASSERT(gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g);
pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g;
CRYPTOPP_ASSERT(pass);
}
}
if (level >= 2)
{
if (GetFieldType() == 2)
{
CRYPTOPP_ASSERT(Jacobi(g*g-4, p)==-1);
pass = pass && Jacobi(g*g-4, p)==-1;
CRYPTOPP_ASSERT(pass);
}
// verifying that Lucas((p+1)/2, w, p)==2 is omitted because it's too costly
@ -188,13 +193,13 @@ bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const
if (fullValidate && pass)
{
Integer gp = gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q);
CRYPTOPP_ASSERT(IsIdentity(gp));
pass = pass && IsIdentity(gp);
CRYPTOPP_ASSERT(pass);
}
else if (GetFieldType() == 1)
{
CRYPTOPP_ASSERT(Jacobi(g, p) == 1);
pass = pass && Jacobi(g, p) == 1;
CRYPTOPP_ASSERT(pass);
}
}

View File

@ -69,8 +69,13 @@ public:
void BERDecode(BufferedTransformation &bt);
void DEREncode(BufferedTransformation &bt) const;
// GeneratibleCryptoMaterial interface
/*! parameters: (ModulusSize, SubgroupOrderSize (optional)) */
/// \brief Generate a random key
/// \param rng a RandomNumberGenerator to produce keying material
/// \param params additional initialization parameters
/// \details Recognised NameValuePairs are ModulusSize and
/// SubgroupOrderSize (optional)
/// \throws KeyingErr if a key can't be generated or algorithm parameters
/// are invalid
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg);
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const;
void AssignFrom(const NameValuePairs &source);
@ -80,26 +85,68 @@ public:
Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();}
bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const;
bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation<Integer> *precomp) const;
/// \brief Determine if subgroup membership check is fast
/// \returns true or false
bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;}
// Cygwin i386 crash at -O3; see http://github.com/weidai11/cryptopp/issues/40.
/// \brief Encodes the element
/// \param reversible flag indicating the encoding format
/// \param element reference to the element to encode
/// \param encoded destination byte array for the encoded element
/// \details EncodeElement() must be implemented in a derived class.
/// \pre <tt>COUNTOF(encoded) == GetEncodedElementSize()</tt>
/// \sa <A HREF="http://github.com/weidai11/cryptopp/issues/40">Cygwin
/// i386 crash at -O3</A>
void EncodeElement(bool reversible, const Element &element, byte *encoded) const;
/// \brief Retrieve the encoded element's size
/// \param reversible flag indicating the encoding format
/// \return encoded element's size, in bytes
/// \details The format of the encoded element varies by the underlying
/// type of the element and the reversible flag.
/// \sa GetEncodedElementSize(), EncodeElement(), DecodeElement()
unsigned int GetEncodedElementSize(bool reversible) const;
/// \brief Decodes the element
/// \param encoded byte array with the encoded element
/// \param checkForGroupMembership flag indicating if the element should be validated
/// \return Element after decoding
/// \details DecodeElement() must be implemented in a derived class.
/// \pre <tt>COUNTOF(encoded) == GetEncodedElementSize()</tt>
Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const;
/// \brief Converts an element to an Integer
/// \param element the element to convert to an Integer
/// \return Element after converting to an Integer
/// \details ConvertElementToInteger() must be implemented in a derived class.
Integer ConvertElementToInteger(const Element &element) const
{return element;}
Integer GetMaxExponent() const;
static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";}
/// \brief Retrieve the maximum exponent for the group
/// \return the maximum exponent for the group
Integer GetMaxExponent() const;
/// \brief Retrieve the OID of the algorithm
/// \returns OID of the algorithm
OID GetAlgorithmID() const;
/// \brief Retrieve the modulus for the group
/// \return the modulus for the group
virtual const Integer & GetModulus() const =0;
/// \brief Set group parameters
/// \param p the prime modulus
/// \param g the group generator
virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0;
/// \brief Set subgroup order
/// \param q the subgroup order
void SetSubgroupOrder(const Integer &q)
{m_q = q; ParametersChanged();}
static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";}
protected:
Integer ComputeGroupOrder(const Integer &modulus) const
{return modulus-(GetFieldType() == 1 ? 1 : -1);}
@ -704,7 +751,7 @@ public:
bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;}
size_t GetSymmetricKeyLength(size_t plaintextLength) const
{return plaintextLength + static_cast<size_t>(MAC::DIGESTSIZE);}
{return plaintextLength + static_cast<size_t>(MAC::DEFAULT_KEYLENGTH);}
size_t GetSymmetricCiphertextLength(size_t plaintextLength) const
{return plaintextLength + static_cast<size_t>(MAC::DIGESTSIZE);}
size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const

View File

@ -60,7 +60,7 @@ public:
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
};
/// \brief Encryption transformation
/// \brief Decryption transformation
/// \details Dec provides implementation for decryption transformation.
/// \since Crypto++ 8.0
class CRYPTOPP_NO_VTABLE Dec : public Base

14
hkdf.h
View File

@ -39,7 +39,7 @@ public:
}
// KeyDerivationFunction interface
size_t MaxDerivedLength() const {
size_t MaxDerivedKeyLength() const {
return static_cast<size_t>(T::DIGESTSIZE) * 255;
}
@ -60,7 +60,7 @@ public:
/// \param info the additional input buffer
/// \param infoLen the size of the info buffer, in bytes
/// \returns the number of iterations performed
/// \throws InvalidDerivedLength if <tt>derivedLen</tt> is invalid for the scheme
/// \throws InvalidDerivedKeyLength if <tt>derivedLen</tt> is invalid for the scheme
/// \details DeriveKey() provides a standard interface to derive a key from
/// a seed and other parameters. Each class that derives from KeyDerivationFunction
/// provides an overload that accepts most parameters used by the derivation function.
@ -92,8 +92,8 @@ protected:
template <class T>
size_t HKDF<T>::GetValidDerivedLength(size_t keylength) const
{
if (keylength > MaxDerivedLength())
return MaxDerivedLength();
if (keylength > MaxDerivedKeyLength())
return MaxDerivedKeyLength();
return keylength;
}
@ -103,7 +103,7 @@ size_t HKDF<T>::DeriveKey(byte *derived, size_t derivedLen,
{
CRYPTOPP_ASSERT(secret && secretLen);
CRYPTOPP_ASSERT(derived && derivedLen);
CRYPTOPP_ASSERT(derivedLen <= MaxDerivedLength());
CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength());
ConstByteArrayParameter p;
SecByteBlock salt, info;
@ -127,9 +127,9 @@ size_t HKDF<T>::DeriveKey(byte *derived, size_t derivedLen, const byte *secret,
{
CRYPTOPP_ASSERT(secret && secretLen);
CRYPTOPP_ASSERT(derived && derivedLen);
CRYPTOPP_ASSERT(derivedLen <= MaxDerivedLength());
CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength());
ThrowIfInvalidDerivedLength(derivedLen);
ThrowIfInvalidDerivedKeyLength(derivedLen);
// HKDF business logic. NULL is different than empty.
if (salt == NULLPTR)

230
hmqv.h
View File

@ -1,5 +1,5 @@
// hmqv.h - written and placed in the public domain by Uri Blumenthal
// Shamelessly based upon Jeffrey Walton's FHMQV and Wei Dai's MQV source files
// Shamelessly based upon Wei Dai's MQV source files
#ifndef CRYPTOPP_HMQV_H
#define CRYPTOPP_HMQV_H
@ -29,30 +29,85 @@ public:
virtual ~HMQV_Domain() {}
HMQV_Domain(bool clientRole = true): m_role(clientRole ? RoleClient : RoleServer) {}
/// \brief Construct a HMQV domain
/// \param clientRole flag indicating initiator or recipient
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
HMQV_Domain(bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer) {}
/// \brief Construct a HMQV domain
/// \param params group parameters and options
/// \param clientRole flag indicating initiator or recipient
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
HMQV_Domain(const GroupParameters &params, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer), m_groupParameters(params) {}
/// \brief Construct a HMQV domain
/// \param bt BufferedTransformation with group parameters and options
/// \param clientRole flag indicating initiator or recipient
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
HMQV_Domain(BufferedTransformation &bt, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.BERDecode(bt);}
/// \brief Construct a HMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1 is passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1>
HMQV_Domain(T1 v1, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.Initialize(v1);}
/// \brief Construct a HMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \tparam T2 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param v2 second parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1 and v2 are passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1, class T2>
HMQV_Domain(T1 v1, T2 v2, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.Initialize(v1, v2);}
/// \brief Construct a HMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \tparam T2 template parameter used as a constructor parameter
/// \tparam T3 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param v2 second parameter
/// \param v3 third parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1, v2 and v3 are passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1, class T2, class T3>
HMQV_Domain(T1 v1, T2 v2, T3 v3, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer)
{m_groupParameters.Initialize(v1, v2, v3);}
/// \brief Construct a HMQV domain
/// \tparam T1 template parameter used as a constructor parameter
/// \tparam T2 template parameter used as a constructor parameter
/// \tparam T3 template parameter used as a constructor parameter
/// \tparam T4 template parameter used as a constructor parameter
/// \param v1 first parameter
/// \param v2 second parameter
/// \param v3 third parameter
/// \param v4 third parameter
/// \param clientRole flag indicating initiator or recipient
/// \details v1, v2, v3 and v4 are passed directly to the GROUP_PARAMETERS object.
/// \details <tt>clientRole = true</tt> indicates initiator, and
/// <tt>clientRole = false</tt> indicates recipient or server.
template <class T1, class T2, class T3, class T4>
HMQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4, bool clientRole = true)
: m_role(clientRole ? RoleClient : RoleServer)
@ -60,28 +115,62 @@ public:
public:
/// \brief Retrieves the group parameters for this domain
/// \return the group parameters for this domain as a const reference
const GroupParameters & GetGroupParameters() const {return m_groupParameters;}
/// \brief Retrieves the group parameters for this domain
/// \return the group parameters for this domain as a non-const reference
GroupParameters & AccessGroupParameters() {return m_groupParameters;}
/// \brief Retrieves the crypto parameters for this domain
/// \return the crypto parameters for this domain as a non-const reference
CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();}
/// return length of agreed value produced
unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);}
/// return length of static private keys in this domain
unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
/// return length of static public keys in this domain
unsigned int StaticPublicKeyLength() const{return GetAbstractGroupParameters().GetEncodedElementSize(true);}
/// \brief Provides the size of the agreed value
/// \return size of agreed value produced in this domain
/// \details The length is calculated using <tt>GetEncodedElementSize(false)</tt>,
/// which means the element is encoded in a non-reversible format. A
/// non-reversible format means its a raw byte array, and it lacks presentation
/// format like an ASN.1 BIT_STRING or OCTET_STRING.
unsigned int AgreedValueLength() const
{return GetAbstractGroupParameters().GetEncodedElementSize(false);}
/// generate static private key
/*! \pre size of privateKey == PrivateStaticKeyLength() */
/// \brief Provides the size of the static private key
/// \return size of static private keys in this domain
/// \details The length is calculated using the byte count of the subgroup order.
unsigned int StaticPrivateKeyLength() const
{return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();}
/// \brief Provides the size of the static public key
/// \return size of static public keys in this domain
/// \details The length is calculated using <tt>GetEncodedElementSize(true)</tt>,
/// which means the element is encoded in a reversible format. A reversible
/// format means it has a presentation format, and its an ANS.1 encoded element
/// or point.
unsigned int StaticPublicKeyLength() const
{return GetAbstractGroupParameters().GetEncodedElementSize(true);}
/// \brief Generate static private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer for the generated private key in this domain
/// \details The private key is a random scalar used as an exponent in the range
/// <tt>[1,MaxExponent()]</tt>.
/// \pre <tt>COUNTOF(privateKey) == PrivateStaticKeyLength()</tt>
void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
{
Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent());
x.Encode(privateKey, StaticPrivateKeyLength());
}
/// generate static public key
/*! \pre size of publicKey == PublicStaticKeyLength() */
/// \brief Generate a static public key from a private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer with the previously generated private key
/// \param publicKey a byte buffer for the generated public key in this domain
/// \details The public key is an element or point on the curve, and its stored
/// in a revrsible format. A reversible format means it has a presentation
/// format, and its an ANS.1 encoded element or point.
/// \pre <tt>COUNTOF(publicKey) == PublicStaticKeyLength()</tt>
void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
{
CRYPTOPP_UNUSED(rng);
@ -91,10 +180,22 @@ public:
params.EncodeElement(true, y, publicKey);
}
/// \brief Provides the size of the ephemeral private key
/// \return size of ephemeral private keys in this domain
/// \details An ephemeral private key is a private key and public key.
/// The serialized size is different than a static private key.
unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();}
/// \brief Provides the size of the ephemeral public key
/// \return size of ephemeral public keys in this domain
/// \details An ephemeral public key is a public key.
/// The serialized size is the same as a static public key.
unsigned int EphemeralPublicKeyLength() const{return StaticPublicKeyLength();}
/// return length of ephemeral private keys in this domain
/// \brief Generate ephemeral private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer for the generated private key in this domain
/// \pre <tt>COUNTOF(privateKey) == EphemeralPrivateKeyLength()</tt>
void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
{
const DL_GroupParameters<Element> &params = GetAbstractGroupParameters();
@ -104,28 +205,46 @@ public:
params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength());
}
/// return length of ephemeral public keys in this domain
/// \brief Generate ephemeral public key from a private key in this domain
/// \param rng a RandomNumberGenerator derived class
/// \param privateKey a byte buffer with the previously generated private key
/// \param publicKey a byte buffer for the generated public key in this domain
/// \pre <tt>COUNTOF(publicKey) == EphemeralPublicKeyLength()</tt>
void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
{
CRYPTOPP_UNUSED(rng);
memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength());
}
/// derive agreed value from your private keys and couterparty's public keys, return false in case of failure
/*! \note The ephemeral public key will always be validated.
If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time.
\pre size of agreedValue == AgreedValueLength()
\pre length of staticPrivateKey == StaticPrivateKeyLength()
\pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength()
\pre length of staticOtherPublicKey == StaticPublicKeyLength()
\pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength()
*/
/// \brief Derive agreed value or shared secret
/// \param agreedValue the shared secret
/// \param staticPrivateKey your long term private key
/// \param ephemeralPrivateKey your ephemeral private key
/// \param staticOtherPublicKey couterparty's long term public key
/// \param ephemeralOtherPublicKey couterparty's ephemeral public key
/// \param validateStaticOtherPublicKey flag indicating validation
/// \return true upon success, false in case of failure
/// \details Agree() performs the authenticated key agreement. Agree()
/// derives a shared secret from your private keys and couterparty's
/// public keys. Each instance or run of the protocol should use a new
/// ephemeral key pair.
/// \details The other's ephemeral public key will always be validated at
/// Level 1 to ensure it is a point on the curve.
/// <tt>validateStaticOtherPublicKey</tt> determines how thoroughly other's
/// static public key is validated. If you have previously validated the
/// couterparty's static public key, then use
/// <tt>validateStaticOtherPublicKey=false</tt> to save time.
/// \pre <tt>COUNTOF(agreedValue) == AgreedValueLength()
/// \pre <tt>COUNTOF(staticPrivateKey) == StaticPrivateKeyLength()</tt>
/// \pre <tt>COUNTOF(ephemeralPrivateKey) == EphemeralPrivateKeyLength()</tt>
/// \pre <tt>COUNTOF(staticOtherPublicKey) == StaticPublicKeyLength()</tt>
/// \pre <tt>COUNTOF(ephemeralOtherPublicKey) == EphemeralPublicKeyLength()</tt>
bool Agree(byte *agreedValue,
const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
bool validateStaticOtherPublicKey=true) const
{
byte *XX = NULLPTR, *YY = NULLPTR, *AA = NULLPTR, *BB = NULLPTR;
const byte *XX = NULLPTR, *YY = NULLPTR, *AA = NULLPTR, *BB = NULLPTR;
size_t xxs = 0, yys = 0, aas = 0, bbs = 0;
// Depending on the role, this will hold either A's or B's static
@ -143,63 +262,45 @@ public:
Element B = params.ExponentiateBase(b);
params.EncodeElement(true, B, tt);
XX = const_cast<byte*>(ephemeralOtherPublicKey);
XX = ephemeralOtherPublicKey;
xxs = EphemeralPublicKeyLength();
YY = const_cast<byte*>(ephemeralPrivateKey) + StaticPrivateKeyLength();
YY = ephemeralPrivateKey + StaticPrivateKeyLength();
yys = EphemeralPublicKeyLength();
AA = const_cast<byte*>(staticOtherPublicKey);
AA = staticOtherPublicKey;
aas = StaticPublicKeyLength();
BB = tt.BytePtr();
bbs = tt.SizeInBytes();
}
else if(m_role == RoleClient)
else
{
Integer a(staticPrivateKey, StaticPrivateKeyLength());
Element A = params.ExponentiateBase(a);
params.EncodeElement(true, A, tt);
XX = const_cast<byte*>(ephemeralPrivateKey) + StaticPrivateKeyLength();
XX = ephemeralPrivateKey + StaticPrivateKeyLength();
xxs = EphemeralPublicKeyLength();
YY = const_cast<byte*>(ephemeralOtherPublicKey);
YY = ephemeralOtherPublicKey;
yys = EphemeralPublicKeyLength();
AA = tt.BytePtr();
aas = tt.SizeInBytes();
BB = const_cast<byte*>(staticOtherPublicKey);
BB = staticOtherPublicKey;
bbs = StaticPublicKeyLength();
}
else
{
CRYPTOPP_ASSERT(0);
return false;
}
// DecodeElement calls ValidateElement at level 1. Level 1 only calls
// VerifyPoint to ensure the element is in G*. If the other's PublicKey is
// requested to be validated, we manually call ValidateElement at level 3.
Element VV1 = params.DecodeElement(staticOtherPublicKey, false);
if(!params.ValidateElement(validateStaticOtherPublicKey ? 3 : 1, VV1, NULLPTR))
return false;
Element VV1 = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey);
Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, true);
// DecodeElement calls ValidateElement at level 1. Level 1 only calls
// VerifyPoint to ensure the element is in G*. Crank it up.
Element VV2 = params.DecodeElement(ephemeralOtherPublicKey, false);
if(!params.ValidateElement(3, VV2, NULLPTR))
return false;
// const Integer& p = params.GetGroupOrder(); // not used, remove later
const Integer& q = params.GetSubgroupOrder();
const unsigned int len /*bytes*/ = (((q.BitCount()+1)/2 +7)/8);
Integer d, e;
SecByteBlock dd(len), ee(len);
// Compute $d = \hat{H}(X, \hat{B})$
Hash(NULLPTR, XX, xxs, BB, bbs, dd.BytePtr(), dd.SizeInBytes());
d.Decode(dd.BytePtr(), dd.SizeInBytes());
Integer d(dd.BytePtr(), dd.SizeInBytes());
// Compute $e = \hat{H}(Y, \hat{A})$
Hash(NULLPTR, YY, yys, AA, aas, ee.BytePtr(), ee.SizeInBytes());
e.Decode(ee.BytePtr(), ee.SizeInBytes());
Integer e(ee.BytePtr(), ee.SizeInBytes());
Element sigma;
if(m_role == RoleServer)
@ -226,16 +327,17 @@ public:
Element B = params.DecodeElement(BB, false);
Element Y = params.DecodeElement(YY, false);
Element t1 = params.ExponentiateElement(B, e);
Element t2 = m_groupParameters.MultiplyElements(Y, t1);
Element t3 = params.ExponentiateElement(B, e);
Element t4 = m_groupParameters.MultiplyElements(Y, t3);
// $\sigma_A}=(Y \cdot B^{e})^{s_A}
sigma = params.ExponentiateElement(t2, s_A);
sigma = params.ExponentiateElement(t4, s_A);
}
Hash(&sigma, NULLPTR, 0, NULLPTR, 0, agreedValue, AgreedValueLength());
}
catch (DL_BadElement &)
{
CRYPTOPP_ASSERT(0);
return false;
}
return true;
@ -259,9 +361,11 @@ protected:
if (e1len != 0 || s1len != 0) {
CRYPTOPP_ASSERT(0);
}
Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma);
SecByteBlock sbb(x.MinEncodedSize());
x.Encode(sbb.BytePtr(), sbb.SizeInBytes());
//Integer x = GetAbstractGroupParameters().ConvertElementToInteger(*sigma);
//SecByteBlock sbb(x.MinEncodedSize());
//x.Encode(sbb.BytePtr(), sbb.SizeInBytes());
SecByteBlock sbb(GetAbstractGroupParameters().GetEncodedElementSize(false));
GetAbstractGroupParameters().EncodeElement(false, *sigma, sbb);
hash.Update(sbb.BytePtr(), sbb.SizeInBytes());
} else {
if (e1len == 0 || s1len == 0) {
@ -292,8 +396,10 @@ private:
// The paper uses Initiator and Recipient - make it classical.
enum KeyAgreementRole { RoleServer = 1, RoleClient };
DL_GroupParameters<Element> & AccessAbstractGroupParameters() {return m_groupParameters;}
const DL_GroupParameters<Element> & GetAbstractGroupParameters() const{return m_groupParameters;}
DL_GroupParameters<Element> & AccessAbstractGroupParameters()
{return m_groupParameters;}
const DL_GroupParameters<Element> & GetAbstractGroupParameters() const
{return m_groupParameters;}
GroupParameters m_groupParameters;
KeyAgreementRole m_role;
@ -302,7 +408,7 @@ private:
/// \brief Hashed Menezes-Qu-Vanstone in GF(p)
/// \details This implementation follows Hugo Krawczyk's <a href="http://eprint.iacr.org/2005/176">HMQV: A High-Performance
/// Secure Diffie-Hellman Protocol</a>. Note: this implements HMQV only. HMQV-C with Key Confirmation is not provided.
/// \sa HMQV, MQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain
/// \sa HMQV, HMQV_Domain, FHMQV_Domain, AuthenticatedKeyAgreementDomain
/// \since Crypto++ 5.6.4
typedef HMQV_Domain<DL_GroupParameters_GFP_DefaultSafePrime> HMQV;

View File

@ -18,13 +18,13 @@
// For Integer::Zero(), Integer::One() and Integer::Two(), we use one of three
// strategies. First, if initialization priorities are available then we use
// them. Initialization priorities are init_priority() on Linux and init_seg()
// on Windows. AIX, OS X and several other platforms lack them. Initialization
// on Windows. OS X and several other platforms lack them. Initialization
// priorities are platform specific but they are also the most trouble free
// with determisitic destruction.
// Second, if C++11 dynamic initialization is available, then we use it. After
// the std::call_once fiasco we dropped the priority dynamic initialization
// to avoid unknown troubles platforms that are tested less frequently. In
// addition Microsoft platforms mostly do not provide dynamic initialization.
// the std::call_once fiasco we moved to dynamic initialization to avoid
// unknown troubles platforms that are tested less frequently. In addition
// Microsoft platforms mostly do not provide dynamic initialization.
// The MSDN docs claim they do but they don't in practice because we need
// Visual Studio 2017 and Windows 10 or above.
// Third, we fall back to Wei's original code of a Singleton. Wei's original
@ -45,6 +45,12 @@
// thousands of times during the life of a program. Each load produces a
// memory leak and they can add up quickly. If they library is being used in
// Java or .Net then Singleton must be avoided at all costs.
//
// The code below has a path cut-in for BMI2 using mulx and adcx instructions.
// There was a modest speedup of approximately 0.03 ms in public key Integer
// operations. We had to disable BMI2 for the moment because some OS X machines
// were advertising BMI/BMI2 support but caused SIGILL's at runtime. Also see
// https://github.com/weidai11/cryptopp/issues/850.
#include "pch.h"
#include "config.h"
@ -77,7 +83,8 @@
#include <c_asm.h>
#endif
// "Error: The operand ___LKDB cannot be assigned to", http://github.com/weidai11/cryptopp/issues/188
// "Error: The operand ___LKDB cannot be assigned to",
// http://github.com/weidai11/cryptopp/issues/188
#if (__SUNPRO_CC >= 0x5130)
# define MAYBE_CONST
# define MAYBE_UNCONST_CAST(x) const_cast<word*>(x)
@ -211,6 +218,13 @@ static word AtomicInverseModPower2(word A)
#if defined(__SUNPRO_CC) && __SUNPRO_CC < 0x5100
// Sun Studio's gcc-style inline assembly is heavily bugged as of version 5.9 Patch 124864-09 2008/12/16, but this one works
#define MultiplyWordsLoHi(p0, p1, a, b) asm ("mulq %3" : "=a"(p0), "=d"(p1) : "a"(a), "r"(b) : "cc");
#elif defined(__BMI2__) && 0
#define MultiplyWordsLoHi(p0, p1, a, b) asm ("mulxq %3, %0, %1" : "=r"(p0), "=r"(p1) : "d"(a), "r"(b));
#define MulAcc(c, d, a, b) asm ("mulxq %6, %3, %4; addq %3, %0; adcxq %4, %1; adcxq %7, %2;" : "+&r"(c), "+&r"(d##0), "+&r"(d##1), "=&r"(p0), "=&r"(p1) : "d"(a), "r"(b), "r"(W64LIT(0)) : "cc");
#define Double3Words(c, d) asm ("addq %0, %0; adcxq %1, %1; adcxq %2, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1) : : "cc");
#define Acc2WordsBy1(a, b) asm ("addq %2, %0; adcxq %3, %1;" : "+&r"(a##0), "+r"(a##1) : "r"(b), "r"(W64LIT(0)) : "cc");
#define Acc2WordsBy2(a, b) asm ("addq %2, %0; adcxq %3, %1;" : "+r"(a##0), "+r"(a##1) : "r"(b##0), "r"(b##1) : "cc");
#define Acc3WordsBy2(c, d, e) asm ("addq %5, %0; adcxq %6, %1; adcxq %7, %2;" : "+r"(c), "=&r"(e##0), "=&r"(e##1) : "1"(d##0), "2"(d##1), "r"(e##0), "r"(e##1), "r"(W64LIT(0)) : "cc");
#else
#define MultiplyWordsLoHi(p0, p1, a, b) asm ("mulq %3" : "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc");
#define MulAcc(c, d, a, b) asm ("mulq %6; addq %3, %0; adcq %4, %1; adcq $0, %2;" : "+r"(c), "+r"(d##0), "+r"(d##1), "=a"(p0), "=d"(p1) : "a"(a), "g"(b) : "cc");
@ -3537,9 +3551,9 @@ class KDF2_RNG : public RandomNumberGenerator
{
public:
KDF2_RNG(const byte *seed, size_t seedSize)
: m_counter(0), m_counterAndSeed(seedSize + 4)
: m_counter(0), m_counterAndSeed(ClampSize(seedSize) + 4)
{
memcpy(m_counterAndSeed + 4, seed, seedSize);
memcpy(m_counterAndSeed + 4, seed, ClampSize(seedSize));
}
void GenerateBlock(byte *output, size_t size)
@ -3550,6 +3564,15 @@ public:
P1363_KDF2<SHA1>::DeriveKey(output, size, m_counterAndSeed, m_counterAndSeed.size(), NULLPTR, 0);
}
// UBsan finding, -Wstringop-overflow
inline size_t ClampSize(size_t req) const
{
// Clamp at 16 MB
if (req > 16U*1024*1024)
return 16U*1024*1024;
return req;
}
private:
word32 m_counter;
SecByteBlock m_counterAndSeed;

View File

@ -306,13 +306,16 @@ public:
signed long ConvertToLong() const;
/// \brief Determines the number of bits required to represent the Integer
/// \returns number of significant bits = floor(log2(abs(*this))) + 1
/// \returns number of significant bits
/// \details BitCount is calculated as <tt>floor(log2(abs(*this))) + 1</tt>.
unsigned int BitCount() const;
/// \brief Determines the number of bytes required to represent the Integer
/// \returns number of significant bytes = ceiling(BitCount()/8)
/// \returns number of significant bytes
/// \details ByteCount is calculated as <tt>ceiling(BitCount()/8)</tt>.
unsigned int ByteCount() const;
/// \brief Determines the number of words required to represent the Integer
/// \returns number of significant words = ceiling(ByteCount()/sizeof(word))
/// \returns number of significant words
/// \details WordCount is calculated as <tt>ceiling(ByteCount()/sizeof(word))</tt>.
unsigned int WordCount() const;
/// \brief Provides the i-th bit of the Integer
@ -354,29 +357,48 @@ public:
/// \name MANIPULATORS
//@{
/// \brief Assignment
/// \param t the other Integer
/// \returns the result of assignment
Integer& operator=(const Integer& t);
/// \brief Addition Assignment
/// \param t the other Integer
/// \returns the result of <tt>*this + t</tt>
Integer& operator+=(const Integer& t);
/// \brief Subtraction Assignment
/// \param t the other Integer
/// \returns the result of <tt>*this - t</tt>
Integer& operator-=(const Integer& t);
/// \brief Multiplication Assignment
/// \param t the other Integer
/// \returns the result of <tt>*this * t</tt>
/// \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator*=(const Integer& t) {return *this = Times(t);}
/// \brief Division Assignment
/// \param t the other Integer
/// \returns the result of <tt>*this / t</tt>
Integer& operator/=(const Integer& t) {return *this = DividedBy(t);}
/// \brief Remainder Assignment
/// \param t the other Integer
/// \returns the result of <tt>*this % t</tt>
/// \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator%=(const Integer& t) {return *this = Modulo(t);}
/// \brief Division Assignment
/// \param t the other word
/// \returns the result of <tt>*this / t</tt>
Integer& operator/=(word t) {return *this = DividedBy(t);}
/// \brief Remainder Assignment
/// \param t the other word
/// \returns the result of <tt>*this % t</tt>
/// \sa a_times_b_mod_c() and a_exp_b_mod_c()
Integer& operator%=(word t) {return *this = Integer(POSITIVE, 0, Modulo(t));}
/// \brief Left-shift Assignment
/// \param n number of bits to shift
/// \returns reference to this Integer
Integer& operator<<=(size_t n);
/// \brief Right-shift Assignment
/// \param n number of bits to shift
/// \returns reference to this Integer
Integer& operator>>=(size_t n);
/// \brief Bitwise AND Assignment

View File

@ -94,8 +94,6 @@ private:
#if !defined(__BORLANDC__)
// ensure there was no underflow in the math
CRYPTOPP_COMPILE_ASSERT(BLOCKSIZE < 200);
// this is a general expectation by HMAC
CRYPTOPP_COMPILE_ASSERT((int)BLOCKSIZE > (int)DIGESTSIZE);
#endif
};

View File

@ -12,8 +12,8 @@
// KeccakF1600x2_SSE is ParallelHash128. The SSE2 ParallelHash128
// implementation was extracted from XKCP using the following command.
//
// gcc -I lib/common -I lib/low/KeccakP-1600/Optimized \
// -I lib/low/KeccakP-1600-times2/SIMD128/SSE2ufull \
// gcc -I lib/common -I lib/low/KeccakP-1600/Optimized
// -I lib/low/KeccakP-1600-times2/SIMD128/SSE2ufull
// lib/low/KeccakP-1600-times2/SIMD128/KeccakP-1600-times2-SIMD128.c -E
#include "pch.h"
@ -23,7 +23,14 @@
#if (CRYPTOPP_SSSE3_AVAILABLE)
# include <emmintrin.h>
# include <immintrin.h>
# include <tmmintrin.h>
#endif
#if defined(__XOP__)
# include <ammintrin.h>
# if defined(__GNUC__)
# include <x86intrin.h>
# endif
#endif
// Squash MS LNK4221 and libtool warnings
@ -39,16 +46,17 @@ extern void KeccakF1600x2_SSE(word64 *state);
// The F1600 round constants
extern const word64 KeccakF1600Constants[24];
const word64 rho8[2] = {0x0605040302010007, 0x0E0D0C0B0A09080F};
const word64 rho56[2] = {0x0007060504030201, 0x080F0E0D0C0B0A09};
CRYPTOPP_ALIGN_DATA(16)
const word64
rho8[2] = {W64LIT(0x0605040302010007), W64LIT(0x0E0D0C0B0A09080F)};
#define V128 __m128i
#define CV128 const __m128i
CRYPTOPP_ALIGN_DATA(16)
const word64
rho56[2] = {W64LIT(0x0007060504030201), W64LIT(0x080F0E0D0C0B0A09)};
#define CONST128(a) _mm_load_si128((CV128 *)&(a))
#define XOREQ128(a, b) a = _mm_xor_si128((a), (b))
#define UNPACKL(a, b) _mm_unpacklo_epi64((a), (b))
#define UNPACKH(a, b) _mm_unpackhi_epi64((a), (b))
// Clang intrinsic casts, http://bugs.llvm.org/show_bug.cgi?id=20670
#define M128_CAST(x) ((__m128i *)(void *)(x))
#define CONST_M128_CAST(x) ((const __m128i *)(const void *)(x))
#if defined(__XOP__)
# define ROL64in128(a, o) _mm_roti_epi64((a), (o))
@ -56,8 +64,8 @@ const word64 rho56[2] = {0x0007060504030201, 0x080F0E0D0C0B0A09};
# define ROL64in128_56(a) ROL64in128((a), 56)
#else
# define ROL64in128(a, o) _mm_or_si128(_mm_slli_epi64((a), (o)), _mm_srli_epi64(a, 64-(o)))
# define ROL64in128_8(a) _mm_shuffle_epi8((a), CONST128(rho8))
# define ROL64in128_56(a) _mm_shuffle_epi8((a), CONST128(rho56))
# define ROL64in128_8(a) _mm_shuffle_epi8((a), _mm_load_si128(CONST_M128_CAST(rho8)))
# define ROL64in128_56(a) _mm_shuffle_epi8((a), _mm_load_si128(CONST_M128_CAST(rho56)))
#endif
// Damn Visual Studio is missing too many intrinsics...
@ -74,51 +82,50 @@ inline __m128i SPLAT64(const word64 a)
// The Keccak ParallelHash128 core function
void KeccakF1600x2_SSE(word64 *state)
{
V128 *statesAsLanes = (V128 *)state;
__m128i Aba, Abe, Abi, Abo, Abu;
__m128i Aga, Age, Agi, Ago, Agu;
__m128i Aka, Ake, Aki, Ako, Aku;
__m128i Ama, Ame, Ami, Amo, Amu;
__m128i Asa, Ase, Asi, Aso, Asu;
__m128i Bba, Bbe, Bbi, Bbo, Bbu;
__m128i Bga, Bge, Bgi, Bgo, Bgu;
__m128i Bka, Bke, Bki, Bko, Bku;
__m128i Bma, Bme, Bmi, Bmo, Bmu;
__m128i Bsa, Bse, Bsi, Bso, Bsu;
__m128i Ca, Ce, Ci, Co, Cu;
__m128i Da, De, Di, Do, Du;
__m128i Eba, Ebe, Ebi, Ebo, Ebu;
__m128i Ega, Ege, Egi, Ego, Egu;
__m128i Eka, Eke, Eki, Eko, Eku;
__m128i Ema, Eme, Emi, Emo, Emu;
__m128i Esa, Ese, Esi, Eso, Esu;
V128 Aba, Abe, Abi, Abo, Abu;
V128 Aga, Age, Agi, Ago, Agu;
V128 Aka, Ake, Aki, Ako, Aku;
V128 Ama, Ame, Ami, Amo, Amu;
V128 Asa, Ase, Asi, Aso, Asu;
V128 Bba, Bbe, Bbi, Bbo, Bbu;
V128 Bga, Bge, Bgi, Bgo, Bgu;
V128 Bka, Bke, Bki, Bko, Bku;
V128 Bma, Bme, Bmi, Bmo, Bmu;
V128 Bsa, Bse, Bsi, Bso, Bsu;
V128 Ca, Ce, Ci, Co, Cu;
V128 Da, De, Di, Do, Du;
V128 Eba, Ebe, Ebi, Ebo, Ebu;
V128 Ega, Ege, Egi, Ego, Egu;
V128 Eka, Eke, Eki, Eko, Eku;
V128 Ema, Eme, Emi, Emo, Emu;
V128 Esa, Ese, Esi, Eso, Esu;
Aba = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 0]));
Abe = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 1]));
Abi = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 2]));
Abo = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 3]));
Abu = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 4]));
Aga = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 5]));
Age = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 6]));
Agi = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 7]));
Ago = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 8]));
Agu = _mm_loadu_si128((CV128 *)&(statesAsLanes[ 9]));
Aka = _mm_loadu_si128((CV128 *)&(statesAsLanes[10]));
Ake = _mm_loadu_si128((CV128 *)&(statesAsLanes[11]));
Aki = _mm_loadu_si128((CV128 *)&(statesAsLanes[12]));
Ako = _mm_loadu_si128((CV128 *)&(statesAsLanes[13]));
Aku = _mm_loadu_si128((CV128 *)&(statesAsLanes[14]));
Ama = _mm_loadu_si128((CV128 *)&(statesAsLanes[15]));
Ame = _mm_loadu_si128((CV128 *)&(statesAsLanes[16]));
Ami = _mm_loadu_si128((CV128 *)&(statesAsLanes[17]));
Amo = _mm_loadu_si128((CV128 *)&(statesAsLanes[18]));
Amu = _mm_loadu_si128((CV128 *)&(statesAsLanes[19]));
Asa = _mm_loadu_si128((CV128 *)&(statesAsLanes[20]));
Ase = _mm_loadu_si128((CV128 *)&(statesAsLanes[21]));
Asi = _mm_loadu_si128((CV128 *)&(statesAsLanes[22]));
Aso = _mm_loadu_si128((CV128 *)&(statesAsLanes[23]));
Asu = _mm_loadu_si128((CV128 *)&(statesAsLanes[24]));
__m128i* lanes = reinterpret_cast<__m128i*>(state);
Aba = _mm_loadu_si128(CONST_M128_CAST(lanes+ 0));
Abe = _mm_loadu_si128(CONST_M128_CAST(lanes+ 1));
Abi = _mm_loadu_si128(CONST_M128_CAST(lanes+ 2));
Abo = _mm_loadu_si128(CONST_M128_CAST(lanes+ 3));
Abu = _mm_loadu_si128(CONST_M128_CAST(lanes+ 4));
Aga = _mm_loadu_si128(CONST_M128_CAST(lanes+ 5));
Age = _mm_loadu_si128(CONST_M128_CAST(lanes+ 6));
Agi = _mm_loadu_si128(CONST_M128_CAST(lanes+ 7));
Ago = _mm_loadu_si128(CONST_M128_CAST(lanes+ 8));
Agu = _mm_loadu_si128(CONST_M128_CAST(lanes+ 9));
Aka = _mm_loadu_si128(CONST_M128_CAST(lanes+10));
Ake = _mm_loadu_si128(CONST_M128_CAST(lanes+11));
Aki = _mm_loadu_si128(CONST_M128_CAST(lanes+12));
Ako = _mm_loadu_si128(CONST_M128_CAST(lanes+13));
Aku = _mm_loadu_si128(CONST_M128_CAST(lanes+14));
Ama = _mm_loadu_si128(CONST_M128_CAST(lanes+15));
Ame = _mm_loadu_si128(CONST_M128_CAST(lanes+16));
Ami = _mm_loadu_si128(CONST_M128_CAST(lanes+17));
Amo = _mm_loadu_si128(CONST_M128_CAST(lanes+18));
Amu = _mm_loadu_si128(CONST_M128_CAST(lanes+19));
Asa = _mm_loadu_si128(CONST_M128_CAST(lanes+20));
Ase = _mm_loadu_si128(CONST_M128_CAST(lanes+21));
Asi = _mm_loadu_si128(CONST_M128_CAST(lanes+22));
Aso = _mm_loadu_si128(CONST_M128_CAST(lanes+23));
Asu = _mm_loadu_si128(CONST_M128_CAST(lanes+24));
Ca = _mm_xor_si128(Aba, _mm_xor_si128(Aga, _mm_xor_si128(Aka, _mm_xor_si128(Ama, Asa))));
Ce = _mm_xor_si128(Abe, _mm_xor_si128(Age, _mm_xor_si128(Ake, _mm_xor_si128(Ame, Ase))));
@ -2646,31 +2653,31 @@ void KeccakF1600x2_SSE(word64 *state)
Aso = _mm_xor_si128(Bso, _mm_andnot_si128(Bsu, Bsa));
Asu = _mm_xor_si128(Bsu, _mm_andnot_si128(Bsa, Bse));
_mm_storeu_si128((V128 *)&(statesAsLanes[ 0]), Aba);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 1]), Abe);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 2]), Abi);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 3]), Abo);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 4]), Abu);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 5]), Aga);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 6]), Age);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 7]), Agi);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 8]), Ago);
_mm_storeu_si128((V128 *)&(statesAsLanes[ 9]), Agu);
_mm_storeu_si128((V128 *)&(statesAsLanes[10]), Aka);
_mm_storeu_si128((V128 *)&(statesAsLanes[11]), Ake);
_mm_storeu_si128((V128 *)&(statesAsLanes[12]), Aki);
_mm_storeu_si128((V128 *)&(statesAsLanes[13]), Ako);
_mm_storeu_si128((V128 *)&(statesAsLanes[14]), Aku);
_mm_storeu_si128((V128 *)&(statesAsLanes[15]), Ama);
_mm_storeu_si128((V128 *)&(statesAsLanes[16]), Ame);
_mm_storeu_si128((V128 *)&(statesAsLanes[17]), Ami);
_mm_storeu_si128((V128 *)&(statesAsLanes[18]), Amo);
_mm_storeu_si128((V128 *)&(statesAsLanes[19]), Amu);
_mm_storeu_si128((V128 *)&(statesAsLanes[20]), Asa);
_mm_storeu_si128((V128 *)&(statesAsLanes[21]), Ase);
_mm_storeu_si128((V128 *)&(statesAsLanes[22]), Asi);
_mm_storeu_si128((V128 *)&(statesAsLanes[23]), Aso);
_mm_storeu_si128((V128 *)&(statesAsLanes[24]), Asu);
_mm_storeu_si128(M128_CAST(lanes+ 0), Aba);
_mm_storeu_si128(M128_CAST(lanes+ 1), Abe);
_mm_storeu_si128(M128_CAST(lanes+ 2), Abi);
_mm_storeu_si128(M128_CAST(lanes+ 3), Abo);
_mm_storeu_si128(M128_CAST(lanes+ 4), Abu);
_mm_storeu_si128(M128_CAST(lanes+ 5), Aga);
_mm_storeu_si128(M128_CAST(lanes+ 6), Age);
_mm_storeu_si128(M128_CAST(lanes+ 7), Agi);
_mm_storeu_si128(M128_CAST(lanes+ 8), Ago);
_mm_storeu_si128(M128_CAST(lanes+ 9), Agu);
_mm_storeu_si128(M128_CAST(lanes+10), Aka);
_mm_storeu_si128(M128_CAST(lanes+11), Ake);
_mm_storeu_si128(M128_CAST(lanes+12), Aki);
_mm_storeu_si128(M128_CAST(lanes+13), Ako);
_mm_storeu_si128(M128_CAST(lanes+14), Aku);
_mm_storeu_si128(M128_CAST(lanes+15), Ama);
_mm_storeu_si128(M128_CAST(lanes+16), Ame);
_mm_storeu_si128(M128_CAST(lanes+17), Ami);
_mm_storeu_si128(M128_CAST(lanes+18), Amo);
_mm_storeu_si128(M128_CAST(lanes+19), Amu);
_mm_storeu_si128(M128_CAST(lanes+20), Asa);
_mm_storeu_si128(M128_CAST(lanes+21), Ase);
_mm_storeu_si128(M128_CAST(lanes+22), Asi);
_mm_storeu_si128(M128_CAST(lanes+23), Aso);
_mm_storeu_si128(M128_CAST(lanes+24), Asu);
}
#endif

2
lea.h
View File

@ -82,7 +82,7 @@ public:
#endif
};
/// \brief Encryption transformation
/// \brief Decryption transformation
/// \details Dec provides implementation for decryption transformation. All key and block
/// sizes are supported.
/// \since Crypto++ 8.0

View File

@ -24,6 +24,9 @@
#if defined(__XOP__)
# include <ammintrin.h>
# if defined(__GNUC__)
# include <x86intrin.h>
# endif
#endif
#if defined(__AVX512F__)

View File

@ -101,12 +101,12 @@ bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count)
{
CRYPTOPP_ASSERT(buf != NULLPTR);
CRYPTOPP_ASSERT(mask != NULLPTR);
CRYPTOPP_ASSERT(count > 0);
// CRYPTOPP_ASSERT(count > 0);
size_t i=0;
byte acc8 = 0;
if (IsAligned<word32>(buf) && IsAligned<word32>(mask))
if (IsAligned<word32>(buf) && IsAligned<word32>(mask) && count)
{
word32 acc32 = 0;
if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask))

210
misc.h
View File

@ -62,36 +62,66 @@
#include <stdlib.h>
#endif
#if defined(__GNUC__) && defined(__linux__)
#define CRYPTOPP_BYTESWAP_AVAILABLE
#if (defined(__GNUC__) || defined(__clang__)) && defined(__linux__)
#define CRYPTOPP_BYTESWAP_AVAILABLE 1
#include <byteswap.h>
#endif
// Limit to ARM A-32. Aarch64 is failing self tests.
#if defined(__arm__) && (defined(__GNUC__) || defined(__clang__)) && (__ARM_ARCH >= 6)
#define CRYPTOPP_ARM_BYTEREV_AVAILABLE 1
#endif
// Limit to ARM A-32. Aarch64 is failing self tests.
#if defined(__arm__) && (defined(__GNUC__) || defined(__clang__)) && (__ARM_ARCH >= 7)
#define CRYPTOPP_ARM_BITREV_AVAILABLE 1
#endif
#if defined(__BMI__)
# include <x86intrin.h>
# include <immintrin.h>
#endif // GCC and BMI
// More LLVM bullshit. Apple Clang 6.0 does not define them.
// Later version of Clang defines them and results in warnings.
#if defined(__clang__)
# ifndef _blsr_u32
# define _blsr_u32 __blsr_u32
# endif
# ifndef _blsr_u64
# define _blsr_u64 __blsr_u64
# endif
# ifndef _tzcnt_u32
# define _tzcnt_u32 __tzcnt_u32
# endif
# ifndef _tzcnt_u64
# define _tzcnt_u64 __tzcnt_u64
# endif
#endif
#endif // CRYPTOPP_DOXYGEN_PROCESSING
#if CRYPTOPP_DOXYGEN_PROCESSING
/// \brief The maximum value of a machine word
/// \details SIZE_MAX provides the maximum value of a machine word. The value is
/// 0xffffffff on 32-bit machines, and 0xffffffffffffffff on 64-bit machines.
/// Internally, SIZE_MAX is defined as __SIZE_MAX__ if __SIZE_MAX__ is defined. If not
/// defined, then SIZE_T_MAX is tried. If neither __SIZE_MAX__ nor SIZE_T_MAX is
/// is defined, the library uses std::numeric_limits<size_t>::max(). The library
/// prefers __SIZE_MAX__ because its a constexpr that is optimized well
/// by all compilers. std::numeric_limits<size_t>::max() is not a constexpr,
/// and it is not always optimized well.
/// \details <tt>SIZE_MAX</tt> provides the maximum value of a machine word. The value
/// is <tt>0xffffffff</tt> on 32-bit targets, and <tt>0xffffffffffffffff</tt> on 64-bit
/// targets.
/// \details If <tt>SIZE_MAX</tt> is not defined, then <tt>__SIZE_MAX__</tt> is used if
/// defined. If not defined, then <tt>SIZE_T_MAX</tt> is used if defined. If not defined,
/// then the library uses <tt>std::numeric_limits<size_t>::max()</tt>.
/// \details The library prefers <tt>__SIZE_MAX__</tt> or <tt>__SIZE_T_MAX__</tt> because
/// they are effectively <tt>constexpr</tt> that is optimized well by all compilers.
/// <tt>std::numeric_limits<size_t>::max()</tt> is not always a <tt>constexpr</tt>, and
/// it is not always optimized well.
# define SIZE_MAX ...
#else
// Its amazing portability problems still plague this simple concept in 2015.
// http://stackoverflow.com/questions/30472731/which-c-standard-header-defines-size-max
// Avoid NOMINMAX macro on Windows. http://support.microsoft.com/en-us/kb/143208
#ifndef SIZE_MAX
# if defined(__SIZE_MAX__) && (__SIZE_MAX__ > 0)
# if defined(__SIZE_MAX__)
# define SIZE_MAX __SIZE_MAX__
# elif defined(SIZE_T_MAX) && (SIZE_T_MAX > 0)
# elif defined(SIZE_T_MAX)
# define SIZE_MAX SIZE_T_MAX
# elif defined(__SIZE_TYPE__)
# define SIZE_MAX (~(__SIZE_TYPE__)0)
@ -112,8 +142,13 @@ class Integer;
#if CRYPTOPP_DOXYGEN_PROCESSING
/// \brief Compile time assertion
/// \param expr the expression to evaluate
/// \details Asserts the expression expr though a dummy struct.
/// \details Asserts the expression <tt>expr</tt> during compile. If C++14 and
/// N3928 are available, then C++14 <tt>static_assert</tt> is used. Otherwise,
/// a <tt>CompileAssert</tt> structure is used. When the structure is used
/// a negative-sized array triggers the assert at compile time.
# define CRYPTOPP_COMPILE_ASSERT(expr) { ... }
#elif defined(CRYPTOPP_CXX14_STATIC_ASSERT)
# define CRYPTOPP_COMPILE_ASSERT(expr) static_assert(expr)
#else // CRYPTOPP_DOXYGEN_PROCESSING
template <bool b>
struct CompileAssert
@ -122,10 +157,13 @@ struct CompileAssert
};
#define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
#if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
#else
# if defined(__GNUC__)
# if defined(__GNUC__) || defined(__clang__)
# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \
static CompileAssert<(assertion)> \
CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance) __attribute__ ((unused))
@ -133,10 +171,8 @@ struct CompileAssert
# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \
static CompileAssert<(assertion)> \
CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance)
# endif // __GNUC__
# endif // GCC or Clang
#endif
#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
#endif // CRYPTOPP_DOXYGEN_PROCESSING
@ -194,16 +230,21 @@ protected:
/// \brief Ensures an object is not copyable
/// \details NotCopyable ensures an object is not copyable by making the
/// copy constructor and assignment operator private. Deleters are not
/// used under C++11.
/// copy constructor and assignment operator private. Deleters are used
/// under C++11.
/// \sa Clonable class
class NotCopyable
{
public:
NotCopyable() {}
#if CRYPTOPP_CXX11_DELETED_FUNCTIONS
NotCopyable(const NotCopyable &) = delete;
void operator=(const NotCopyable &) = delete;
#else
private:
NotCopyable(const NotCopyable &);
void operator=(const NotCopyable &);
#endif
};
/// \brief An object factory function
@ -388,6 +429,38 @@ inline size_t PtrByteDiff(const PTR pointer1, const PTR pointer2)
return (size_t)(reinterpret_cast<uintptr_t>(pointer1) - reinterpret_cast<uintptr_t>(pointer2));
}
/// \brief Pointer to the first element of a string
/// \param str std::string
/// \details BytePtr returns NULL pointer for an empty string.
/// \return Pointer to the first element of a string
inline byte* BytePtr(std::string& str)
{
// Caller wants a writeable pointer
CRYPTOPP_ASSERT(str.empty() == false);
if (str.empty())
return NULLPTR;
return reinterpret_cast<byte*>(&str[0]);
}
/// \brief Const pointer to the first element of a string
/// \param str std::string
/// \details ConstBytePtr returns non-NULL pointer for an empty string.
/// \return Pointer to the first element of a string
inline const byte* ConstBytePtr(const std::string& str)
{
// Use c_str() so a pointer is always available
return reinterpret_cast<const byte*>(str.c_str());
}
/// \brief Size of a string
/// \param str std::string
/// \return size of a string
inline size_t BytePtrSize(const std::string& str)
{
return str.size();
}
#if (!__STDC_WANT_SECURE_LIB__ && !defined(_MEMORY_S_DEFINED)) || defined(CRYPTOPP_WANT_SECURE_LIB)
/// \brief Bounds checking replacement for memcpy()
@ -871,11 +944,12 @@ CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byt
/// \param buf1 the first buffer
/// \param buf2 the second buffer
/// \param count the size of the buffers, in bytes
/// \details The function effectively performs an XOR of the elements in two equally sized
/// buffers and retruns a result based on the XOR operation. The function is near
/// constant-time because CPU micro-code timings could affect the "constant-ness".
/// Calling code is responsible for mitigating timing attacks if the buffers are not
/// equally sized.
/// \details VerifyBufsEqual performs an XOR of the elements in two equally sized
/// buffers and retruns a result based on the XOR operation. A count of 0 returns
/// true because two empty buffers are considered equal.
/// \details The function is near constant-time because CPU micro-code timings could
/// affect the "constant-ness". Calling code is responsible for mitigating timing
/// attacks if the buffers are not equally sized.
/// \sa ModPowerOf2
CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count);
@ -1193,9 +1267,15 @@ CRYPTOPP_DLL void CRYPTOPP_API CallNewHandler();
/// \note The function is not constant time because it stops processing when the carry is 0.
inline void IncrementCounterByOne(byte *inout, unsigned int size)
{
CRYPTOPP_ASSERT(inout != NULLPTR); CRYPTOPP_ASSERT(size < INT_MAX);
for (int i=int(size-1), carry=1; i>=0 && carry; i--)
carry = !++inout[i];
CRYPTOPP_ASSERT(inout != NULLPTR);
unsigned int carry=1;
while (carry && size != 0)
{
// On carry inout[n] equals 0
carry = ! ++inout[size-1];
size--;
}
}
/// \brief Performs an addition with carry on a block of bytes
@ -1207,12 +1287,22 @@ inline void IncrementCounterByOne(byte *inout, unsigned int size)
/// \details The function is close to near-constant time because it operates on all the bytes in the blocks.
inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int size)
{
CRYPTOPP_ASSERT(output != NULLPTR); CRYPTOPP_ASSERT(input != NULLPTR); CRYPTOPP_ASSERT(size < INT_MAX);
CRYPTOPP_ASSERT(output != NULLPTR);
CRYPTOPP_ASSERT(input != NULLPTR);
int i, carry;
for (i=int(size-1), carry=1; i>=0 && carry; i--)
carry = ((output[i] = input[i]+1) == 0);
memcpy_s(output, size, input, size_t(i)+1);
unsigned int carry=1;
while (carry && size != 0)
{
// On carry output[n] equals 0
carry = ! (output[size-1] = input[size-1] + 1);
size--;
}
while (size != 0)
{
output[size-1] = input[size-1];
size--;
}
}
/// \brief Performs a branchless swap of values a and b if condition c is true
@ -1936,7 +2026,8 @@ inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
/// \brief Reverses bytes in a 8-bit value
/// \param value the 8-bit value to reverse
/// \note ByteReverse returns the value passed to it since there is nothing to reverse
/// \note ByteReverse returns the value passed to it since there is nothing to
/// reverse.
inline byte ByteReverse(byte value)
{
return value;
@ -1944,7 +2035,8 @@ inline byte ByteReverse(byte value)
/// \brief Reverses bytes in a 16-bit value
/// \param value the 16-bit value to reverse
/// \details ByteReverse calls bswap if available. Otherwise the function performs a 8-bit rotate on the word16
/// \details ByteReverse calls bswap if available. Otherwise the function
/// performs a 8-bit rotate on the word16.
inline word16 ByteReverse(word16 value)
{
#if defined(CRYPTOPP_BYTESWAP_AVAILABLE)
@ -1958,14 +2050,19 @@ inline word16 ByteReverse(word16 value)
/// \brief Reverses bytes in a 32-bit value
/// \param value the 32-bit value to reverse
/// \details ByteReverse calls bswap if available. Otherwise the function uses a combination of rotates on the word32
/// \details ByteReverse calls bswap if available. Otherwise the function uses
/// a combination of rotates on the word32.
inline word32 ByteReverse(word32 value)
{
#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)
#if defined(CRYPTOPP_BYTESWAP_AVAILABLE)
return bswap_32(value);
#elif defined(CRYPTOPP_ARM_BYTEREV_AVAILABLE)
word32 rvalue;
__asm__ ("rev %0, %1" : "=r" (rvalue) : "r" (value));
return rvalue;
#elif defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)
__asm__ ("bswap %0" : "=r" (value) : "0" (value));
return value;
#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
return bswap_32(value);
#elif defined(__MWERKS__) && TARGET_CPU_PPC
return (word32)__lwbrx(&value,0);
#elif (_MSC_VER >= 1400) || (defined(_MSC_VER) && !defined(_DLL))
@ -1982,14 +2079,15 @@ inline word32 ByteReverse(word32 value)
/// \brief Reverses bytes in a 64-bit value
/// \param value the 64-bit value to reverse
/// \details ByteReverse calls bswap if available. Otherwise the function uses a combination of rotates on the word64
/// \details ByteReverse calls bswap if available. Otherwise the function uses
/// a combination of rotates on the word64.
inline word64 ByteReverse(word64 value)
{
#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__)
#if defined(CRYPTOPP_BYTESWAP_AVAILABLE)
return bswap_64(value);
#elif defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__)
__asm__ ("bswap %0" : "=r" (value) : "0" (value));
return value;
#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
return bswap_64(value);
#elif (_MSC_VER >= 1400) || (defined(_MSC_VER) && !defined(_DLL))
return _byteswap_uint64(value);
#elif CRYPTOPP_BOOL_SLOW_WORD64
@ -2003,7 +2101,7 @@ inline word64 ByteReverse(word64 value)
/// \brief Reverses bits in a 8-bit value
/// \param value the 8-bit value to reverse
/// \details BitReverse performs a combination of shifts on the byte
/// \details BitReverse performs a combination of shifts on the byte.
inline byte BitReverse(byte value)
{
value = byte((value & 0xAA) >> 1) | byte((value & 0x55) << 1);
@ -2013,29 +2111,45 @@ inline byte BitReverse(byte value)
/// \brief Reverses bits in a 16-bit value
/// \param value the 16-bit value to reverse
/// \details BitReverse performs a combination of shifts on the word16
/// \details BitReverse performs a combination of shifts on the word16.
inline word16 BitReverse(word16 value)
{
#if defined(CRYPTOPP_ARM_BITREV_AVAILABLE)
// 4 instructions on ARM.
word32 rvalue;
__asm__ ("rbit %0, %1" : "=r" (rvalue) : "r" (value));
return word16(rvalue >> 16);
#else
// 15 instructions on ARM.
value = word16((value & 0xAAAA) >> 1) | word16((value & 0x5555) << 1);
value = word16((value & 0xCCCC) >> 2) | word16((value & 0x3333) << 2);
value = word16((value & 0xF0F0) >> 4) | word16((value & 0x0F0F) << 4);
return ByteReverse(value);
#endif
}
/// \brief Reverses bits in a 32-bit value
/// \param value the 32-bit value to reverse
/// \details BitReverse performs a combination of shifts on the word32
/// \details BitReverse performs a combination of shifts on the word32.
inline word32 BitReverse(word32 value)
{
#if defined(CRYPTOPP_ARM_BITREV_AVAILABLE)
// 2 instructions on ARM.
word32 rvalue;
__asm__ ("rbit %0, %1" : "=r" (rvalue) : "r" (value));
return rvalue;
#else
// 19 instructions on ARM.
value = word32((value & 0xAAAAAAAA) >> 1) | word32((value & 0x55555555) << 1);
value = word32((value & 0xCCCCCCCC) >> 2) | word32((value & 0x33333333) << 2);
value = word32((value & 0xF0F0F0F0) >> 4) | word32((value & 0x0F0F0F0F) << 4);
return ByteReverse(value);
#endif
}
/// \brief Reverses bits in a 64-bit value
/// \param value the 64-bit value to reverse
/// \details BitReverse performs a combination of shifts on the word64
/// \details BitReverse performs a combination of shifts on the word64.
inline word64 BitReverse(word64 value)
{
#if CRYPTOPP_BOOL_SLOW_WORD64
@ -2063,9 +2177,11 @@ inline T BitReverse(T value)
return (T)BitReverse((word16)value);
else if (sizeof(T) == 4)
return (T)BitReverse((word32)value);
else if (sizeof(T) == 8)
return (T)BitReverse((word64)value);
else
{
CRYPTOPP_ASSERT(sizeof(T) == 8);
CRYPTOPP_ASSERT(0);
return (T)BitReverse((word64)value);
}
}

Some files were not shown because too many files have changed in this diff Show More