Giter Club home page Giter Club logo

cryptopp's Introduction

Crypto++: free C++ Class Library of Cryptographic Schemes
Version 8.9 - October 1, 2023

Crypto++ Library is a free C++ class library of cryptographic schemes.
Currently the library contains the following algorithms:

                   algorithm type  name

 authenticated encryption schemes  GCM, CCM, EAX, ChaCha20Poly1305 and
                                   XChaCha20Poly1305

        high speed stream ciphers  ChaCha (8/12/20), ChaCha (IETF), Panama, Salsa20,
                                   Sosemanuk, XSalsa20, XChaCha20

           AES and AES candidates  AES (Rijndael), RC6, MARS, Twofish, Serpent,
                                   CAST-256

                                   ARIA, Blowfish, Camellia, CHAM, HIGHT, IDEA,
                                   Kalyna (128/256/512), LEA, SEED, RC5, SHACAL-2,
              other block ciphers  SIMON (64/128), Skipjack, SPECK (64/128),
                                   Simeck, SM4, Threefish (256/512/1024),
                                   Triple-DES (DES-EDE2 and DES-EDE3), TEA, XTEA

  block cipher modes of operation  ECB, CBC, CBC ciphertext stealing (CTS),
                                   CFB, OFB, counter mode (CTR), XTS

     message authentication codes  BLAKE2s, BLAKE2b, CMAC, CBC-MAC, DMAC, GMAC, HMAC,
                                   Poly1305, Poly1305 (IETF), SipHash, Two-Track-MAC,
                                   VMAC

                                   BLAKE2s, BLAKE2b, Keccack (F1600), LSH (256/512),
                   hash functions  SHA-1, SHA-2 (224/256/384/512), SHA-3 (224/256),
                                   SHA-3 (384/512), SHAKE (128/256), SipHash, SM3, Tiger,
                                   RIPEMD (128/160/256/320), WHIRLPOOL

                                   RSA, DSA, Deterministic DSA, ElGamal,
          public-key cryptography  Nyberg-Rueppel (NR), Rabin-Williams (RW), LUC,
                                   LUCELG, EC-based German Digital Signature (ECGDSA),
                                   DLIES (variants of DHAES), ESIGN

   padding schemes for public-key  PKCS#1 v2.0, OAEP, PSS, PSSR, IEEE P1363
                          systems  EMSA2 and EMSA5

                                   Diffie-Hellman (DH), Unified Diffie-Hellman (DH2),
            key agreement schemes  Menezes-Qu-Vanstone (MQV), Hashed MQV (HMQV),
                                   Fully Hashed MQV (FHMQV), LUCDIF, XTR-DH

      elliptic curve cryptography  ECDSA, Deterministic ECDSA, ed25519, ECNR, ECIES,
                                   ECDH, ECMQV, x25519

          insecure or obsolescent  MD2, MD4, MD5, Panama Hash, DES, ARC4, SEAL
algorithms retained for backwards  3.0, WAKE-OFB, DESX (DES-XEX3), RC2,
     compatibility and historical  SAFER, 3-WAY, GOST, SHARK, CAST-128, Square
                            value

Other features include:

  * pseudo random number generators (PRNG): ANSI X9.17 appendix C, RandomPool,
    DARN, VIA Padlock, RDRAND, RDSEED, NIST Hash and HMAC DRBGs
  * password based key derivation functions: PBKDF1 and PBKDF2 from PKCS #5,
    PBKDF from PKCS #12 appendix B, HKDF from RFC 5869, Scrypt from RFC 7914
  * Shamir's secret sharing scheme and Rabin's information dispersal algorithm
    (IDA)
  * fast multi-precision integer (bignum) and polynomial operations
  * finite field arithmetics, including GF(p) and GF(2^n)
  * prime number generation and verification
  * useful non-cryptographic algorithms
      + DEFLATE (RFC 1951) compression/decompression with gzip (RFC 1952) and
        zlib (RFC 1950) format support
      + Hex, base-32, base-64, URL safe base-64 encoding and decoding
      + 32-bit CRC, CRC-C and Adler32 checksum
  * class wrappers for these platform and operating system features (optional):
      + high resolution timers on Windows, Unix, and Mac OS
      + /dev/random, /dev/urandom, /dev/srandom
      + Microsoft's CryptGenRandom or BCryptGenRandom on Windows
  * A high level interface for most of the above, using a filter/pipeline
    metaphor
  * benchmarks and validation testing
  * x86, x64 (x86-64), x32 (ILP32), ARM-32, Aarch32, Aarch64 and Power8
    in-core code for the commonly used algorithms
      + run-time CPU feature detection and code selection
      + supports GCC-style and MSVC-style inline assembly, and MASM for x64
      + x86, x64 (x86-64), x32 provides MMX, SSE2, and SSE4 implementations
      + ARM-32, Aarch32 and Aarch64 provides NEON, ASIMD and ARMv8 implementations
      + Power8 provides in-core AES using NX Crypto Acceleration

The Crypto++ library was originally written by Wei Dai. The library is now
maintained by several team members and the community. You are welcome to use it
for any purpose without paying anyone, but see License.txt for the fine print.

The following compilers are supported for this release. Please visit
http://www.cryptopp.com the most up to date build instructions and porting notes.

  * Visual Studio 2003 - 2022
  * GCC 3.3 - 13.1
  * Apple Clang 4.3 - 12.0
  * LLVM Clang 2.9 - 14.0
  * C++ Builder 2015
  * Intel C++ Compiler 9 - 16.0
  * Sun Studio 12u1 - 12.7
  * IBM XL C/C++ 10.0 - 14.0

*** Important Usage Notes ***

1. If a constructor for A takes a pointer to an object B (except primitive
types such as int and char), then A owns B and will delete B at A's
destruction.  If a constructor for A takes a reference to an object B,
then the caller retains ownership of B and should not destroy it until
A no longer needs it.

2. Crypto++ is thread safe at the class level. This means you can use
Crypto++ safely in a multithreaded application, but you must provide
synchronization when multiple threads access a common Crypto++ object.

*** MSVC-Specific Information ***

To compile Crypto++ with MSVC, open "cryptest.sln" (for MSVC 2003 - 2015)
and build one or more of the following projects:

cryptest Non-DLL-Import Configuration - This builds the full static library
  along with a full test driver.
cryptest DLL-Import Configuration - This builds a static library containing
  only algorithms not in the DLL, along with a full test driver that uses
  both the DLL and the static library.
cryptdll - This builds the DLL. Please note that if you wish to use Crypto++
  as a FIPS validated module, you must use a pre-built DLL that has undergone
  the FIPS validation process instead of building your own.
dlltest - This builds a sample application that only uses the DLL.

The DLL used to provide FIPS validated cryptography. The library was moved
to the CMVP's [Historical Validation List](http://csrc.nist.gov/groups/STM/cmvp/documents/140-1/140val-historical.htm).
The library and the DLL are no longer considered
validated. You should no longer use the DLL.

To use the Crypto++ DLL in your application, #include "dll.h" before including
any other Crypto++ header files, and place the DLL in the same directory as
your .exe file. dll.h includes the line #pragma comment(lib, "cryptopp")
so you don't have to explicitly list the import library in your project
settings. To use a static library form of Crypto++, make the "cryptlib"
project a dependency of your application project, or specify it as
an additional library to link with in your project settings.
In either case you should check the compiler options to
make sure that the library and your application are using the same C++
run-time libraries and calling conventions.

*** DLL Memory Management ***

Because it's possible for the Crypto++ DLL to delete objects allocated
by the calling application, they must use the same C++ memory heap. Three
methods are provided to achieve this.
1.  The calling application can tell Crypto++ what heap to use. This method
    is required when the calling application uses a non-standard heap.
2.  Crypto++ can tell the calling application what heap to use. This method
    is required when the calling application uses a statically linked C++ Run
    Time Library. (Method 1 does not work in this case because the Crypto++ DLL
    is initialized before the calling application's heap is initialized.)
3.  Crypto++ can automatically use the heap provided by the calling application's
    dynamically linked C++ Run Time Library. The calling application must
    make sure that the dynamically linked C++ Run Time Library is initialized
    before Crypto++ is loaded. (At this time it is not clear if it is possible
    to control the order in which DLLs are initialized on Windows 9x machines,
    so it might be best to avoid using this method.)

When Crypto++ attaches to a new process, it searches all modules loaded
into the process space for exported functions "GetNewAndDeleteForCryptoPP"
and "SetNewAndDeleteFromCryptoPP". If one of these functions is found,
Crypto++ uses methods 1 or 2, respectively, by calling the function.
Otherwise, method 3 is used.

*** Linux and Unix-like Specific Information ***

A makefile is included for you to compile Crypto++ with GCC and compatibles.
Make sure you are using GNU Make and GNU ld. The make process will produce
two files, libcryptopp.a and cryptest.exe. Run "cryptest.exe v" for the
validation suite and "cryptest.exe tv all" for additional test vectors.

The makefile uses '-DNDEBUG -g2 -O2' CXXFLAGS by default. If you use an
alternate build system, like Autotools or CMake, then ensure the build system
includes '-DNDEBUG' for production or release builds. The Crypto++ library uses
asserts for debugging and diagnostics during development; it does not
rely on them to crash a program at runtime.

If an assert triggers in production software, then unprotected sensitive
information could be egressed from the program to the filesystem or the
platform's error reporting program, like Apport on Ubuntu or CrashReporter
on Apple.

The makefile orders object files to help remediate problems associated with
C++ static initialization order. The library does not use custom linker scripts.
If you use an alternate build system, like Autotools or CMake, and collect source
files into a list, then ensure these three are at the head of the list: 'cryptlib.cpp
cpu.cpp integer.cpp <other sources>'. They should be linked in the same order:
'cryptlib.o cpu.o integer.o <other objects>'.

If your linker supports initialization attributes, like init_priority, then you can
define CRYPTOPP_INIT_PRIORITY to control object initialization order. Set it to a
value like 250. User programs can use CRYPTOPP_USER_PRIORITY to avoid conflicts with
library values. Initialization attributes are more reliable than object file ordering,
but its not ubiquitously supported by linkers.

The makefile links to the static version of the Crypto++ library to avoid binary
planting and other LD_PRELOAD tricks. You should use the static version of the
library in your programs to help avoid unwanted redirections.

*** Side Channel Attacks ***

Crypto++ attempts to resist side channel attacks using various remediations.
The remediations 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).

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 algorithms and access patterns
to minimize leakage cache evictions.

Elliptic curves over binary fields are believed to leak information. The task is a
work in progress. We don't believe binary fields are used in production, so we feel it
is a low risk at the moment.

Crypto++ does not engage 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 ***

Crypto++ is documented through inline comments in header files, which are
processed through Doxygen to produce an HTML reference manual. You can find
a link to the manual from http://www.cryptopp.com. Also at that site is
the Crypto++ FAQ, which you should browse through before attempting to
use this library, because it will likely answer many of questions that
may come up. Finally, the site provides the wiki which has many topics
and code examples.

If you run into any problems, please try the Crypto++ mailing list.
The subscription information and the list archive are available on
http://www.cryptopp.com.

*** Source Code and Contributing ***

The source code and its planned changes are available at the following locations.

  * The Crypto++ GitHub repository allows you to view the latest (unreleased)
    Crypto++ source code via the Linux kernel's git beginning around June 2015.
    Its also serves as an incubator to nurture and grow the library.
  * The former Crypto++ SourceForge repository allows you to view the Crypto++
    source code via Apache's subversion until about July 2015. At that time,
    SourceForge had infrastructure problems and a cutover to GutHub was performed.
  * The Roadmap on the wiki provides the general direction the library is heading.
    It includes planned features and releases, and even some wishlist items.

Contributions of all types are welcomed. Contributions include the following.

  * Bug finding and fixes
  * Features and enhancements
  * Test scripts and test cases
  * Branch and release testing
  * Documentation and updates

If you think you have found a bug in the library, then you should discuss it on the
Users mailing list. Discussing it will help bring the issue to the attention of folks
who can help resolve the issue. If you want to contribute a bug fix to the library,
then make a Pull Request or make a Diff available somewhere. Also see Bug Reports on
the wiki.

Features and enhancements are welcomed additions to the library. This category tends
to be time consuming because algorithms and their test cases need to be reviewed and
merged. Please be mindful of the test cases, and attempt to procure them from an
independent source.

The library cherishes test scripts and test cases. They ensure the library is fit and
they help uncover issues with the library before users experience them. If you have
some time, then write some test cases, especially the ones that are intended to break
things.

Branch and release testing is your chance to ensure Master (and planned merges) meets
your expectations and perform as expected. If you have a few spare cycles, then please
test Master on your favorite platform. We need more testing on MinGW, Windows Phone,
Windows Store, Solaris 10 (and below), and modern iOS and OS X (including TV and
Watch builds).

Documentation and updates includes both the inline source code annotations using
Doxygen, and the online information provided in the wiki. The wiki is more verbose and
usually provides more contextual information than the API reference. Besides testing,
documentation is one of the highest returns on investment.

*** History ***

The items in this section comprise the most recent history. Please see History.txt
for the record back to Crypto++ 1.0.

8.9.0 - October 1, 2023
      - minor release, recompile of programs required
      - expanded community input and support
        * 88 unique contributors as of this release
      - fix SIMON128 Asan finding on POWER8
      - fix AES/CFB and AES/CTR modes self test failures when using Cryptogams AES on ARMv7
      - fix ARIA/CTR mode self test failures when inString==outString
      - fix HIGHT/CTR mode self test failures when inString==outString
      - fix Rabbit/CTR mode self test failures when inString==outString
      - fix Prime Table and dangling reference to a temporary>
      - fix Singleton::Ref when using C++11 memory fences
      - remove unneeded call to Crop() in Randomize()

8.8.0 - June 25, 2023
      - minor release, recompile of programs required
      - expanded community input and support
        * 88 unique contributors as of this release
      - fix crash in cryptest.exe when invoked with no options
      - fix crash in library due to GCC removing live code
      - fix RSA with key size 16 may provide an invalid key
      - fix failure to build on 32-bit x86
      - fix failure to build on iPhone Simulator for arm64
      - fix failure to build on Windows arm64
      - test for SSSE3 before using the ISA
      - fix include of <x86intrin.h> when using MSVC
      - improve performance of CRC32C_Update_SSE42 for x86-64
      - update documentation

8.7.0 - August 7, 2022
      - minor release, recompile of programs required
      - expanded community input and support
        * 81 unique contributors as of this release
      - fix RSA key generation for small moduli
      - fix AES-GCM with AESNI but without CLMUL
      - fix Clang warning with C++17
      - fix MinGW builds due to use of O_NOFOLLOW
      - rework CFB_CipherTemplate::ProcessData and AdditiveCipherTemplate::ProcessData
        * restored performance and avoided performance penalty of a temp buffer
      - fix undersized SecBlock buffer in Integer bit operations
      - work around several GCC 11 & 12 problems

8.6.0 - September 21, 2021
      - minor release, recompile of programs required
      - expanded community input and support
        * 74 unique contributors as of this release
      - fix ElGamal encryption
      - fix ChaCha20 AVX2 implementation
      - add octal and decimal literal prefix parsing to Integer
      - add missing overload in ed25519Signer and ed25519Verifier
      - make SHA-NI independent of AVX and AVX2
      - fix OldRandomPool GenerateWord32
      - use CPPFLAGS during feature testing
      - fix compile on CentOS 5
      - fix compile on FreeBSD
      - fix feature testing on ARM A-32 and Aarch64
      - enable inline ASM for CRC and PMULL on Apple M1
      - fix Intel oneAPI compile
      - rename test files with *.cpp extension
      - fix GCC compile error due to missing _mm256_set_m128i
      - add LSH-256 and LSH-512 hash functions
      - add ECIES_P1363 for backwards compatibility
      - fix AdditiveCipherTemplate<T> ProcessData
      - remove CRYPTOPP_NO_CXX11 define
      - add -fno-common for Darwin builds
      - update documentation

8.5.0 - March 7, 2021
      - minor release, no recompile of programs required
      - expanded community input and support
        * 70 unique contributors as of this release
      - port to Apple M1 hardware

8.4.0 - January 2, 2021
      - minor release, recompile of programs required
      - expanded community input and support
        * 67 unique contributors as of this release
      - fix SIGILL on POWER8 when compiling with GCC 10
      - fix potential out-of-bounds write in FixedSizeAllocatorWithCleanup
      - fix compile on AIX POWER7 with IBM XLC 12.01
      - fix compile on Solaris with SunCC 12.6
      - revert changes for constant-time elliptic curve algorithms
      - fix makefile clean and distclean recipes

8.3.0 - December 20, 2020
      - minor release, recompile of programs required
      - expanded community input and support
        * 66 unique contributors as of this release
      - fix use of macro CRYPTOPP_ALIGN_DATA
      - fix potential out-of-bounds read in ECDSA
      - fix std::bad_alloc when using ByteQueue in pipeline
      - fix missing CRYPTOPP_CXX17_EXCEPTIONS with Clang
      - fix potential out-of-bounds read in GCM mode
      - add configure.sh when preprocessor macros fail
      - fix potential out-of-bounds read in SipHash
      - fix compile error on POWER9 due to vec_xl_be
      - fix K233 curve on POWER8
      - add Cirrus CI testing
      - fix broken encryption for some 64-bit ciphers
      - fix Android cpu-features.c using C++ compiler
      - disable RDRAND and RDSEED for some AMD processors
      - fix BLAKE2 hash calculation using Salt and Personalization
      - refresh Android and iOS build scripts
      - add XTS mode
      - fix circular dependency between misc.h and secblock.h
      - add Certificate interface
      - fix recursion in AES::Encryption without AESNI
      - add missing OID for ElGamal encryption
      - fix missing override in KeyDerivationFunction-derived classes
      - fix RDSEED assemble under MSVC
      - fix elliptic curve timing leaks (CVE-2019-14318)
      - add link-library variable to Makefiles
      - fix SIZE_MAX definition in misc.h
      - add GetWord64 and PutWord64 to BufferedTransformation
      - use HKDF in AutoSeededX917RNG::Reseed
      - fix Asan finding in VMAC on i686 in inline asm
      - fix undeclared identifier _mm_roti_epi64 on Gentoo
      - fix ECIES and GetSymmetricKeyLength
      - fix possible divide by zero in PKCS5_PBKDF2_HMAC
      - refine ASN.1 encoders and decoders
      - disable BMI2 code paths in Integer class
      - fix use of CRYPTOPP_CLANG_VERSION
      - add NEON SHA1, SHA256 and SHA512 from Cryptogams
      - add ARM SHA1, SHA256 and SHA512 from Cryptogams
      - make config.h more autoconf friendly
      - handle Clang triplet armv8l-unknown-linux-gnueabihf
      - fix reference binding to misaligned address in xed25519
      - clear asserts in TestDataNameValuePairs

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
      - add x25519 key exchange and ed25519 signature scheme
      - add limited Asymmetric Key Package support from RFC 5958
      - add Power9 DARN random number generator support
      - add CHAM, HC-128, HC-256, Hight, LEA, Rabbit, Simeck
      - fix FixedSizeAllocatorWithCleanup may be unaligned on some platforms
      - cutover to GNU Make-based cpu feature tests
      - rename files with dashes to underscores
      - fix LegacyDecryptor and LegacyDecryptorWithMAC use wrong MAC
      - fix incorrect AES/CBC decryption on Windows
      - avoid Singleton<T> when possible, avoid std::call_once completely
      - fix SPARC alignment problems due to GetAlignmentOf<T>() on word64
      - add ARM AES asm implementation from Cryptogams
      - remove CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS support

June 2015 - Changing of the guard. Wei Dai turned the library over to the
        community. The first community release was Crypto++ 5.6.3. Wei is
        no longer involved with the daily operations of the project. Wei
        still provides guidance when we have questions.

Originally written by Wei Dai, maintained by the Crypto++ Project

cryptopp's People

Contributors

anonimal avatar blacktempel avatar c0ff avatar cawka avatar chausner avatar crayon2000 avatar deadpikle avatar denisbider avatar devjpm avatar dimastebaev avatar ffontaine avatar floriansgit avatar gamepad64 avatar iljah avatar jnavarrom avatar kvirund avatar kwizart avatar marcelraad avatar mouse07410 avatar noloader avatar pkubaj avatar rzvncj avatar tanzislam avatar tknarr avatar tniessen avatar weidai11 avatar wyattoday avatar zabulus avatar zireael-n avatar zorun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cryptopp's Issues

Building cryptest.exe fails on MinGW-w64

g++ -DNDEBUG -g2 -O3 -march=native -Wall -Wextra -Wno-type-limits -Wno-unknown-pragmas -pipe -c validat0.cpp
validat0.cpp: In function 'bool TestSettings()':
validat0.cpp:27:47: error: call of overloaded 'memcpy_s(CryptoPP::word32*, long long unsigned int, const char [5], int)' is ambiguous
  memcpy_s(&w, sizeof(w), "\x01\x02\x03\x04", 4);
                                               ^
validat0.cpp:27:47: note: candidates are:
In file included from stdcpp.h:12:0,
                 from validat0.cpp:6:
c:/MinGW-w64/mingw64/x86_64-w64-mingw32/include/string.h:42:27: note: errno_t memcpy_s(void*, size_t, const void*, size_t)
   _CRTIMP errno_t __cdecl memcpy_s (void *_dest,size_t _numberOfElements,const
void *_src,size_t _count);
                           ^
In file included from validat0.cpp:7:0:
misc.h:201:13: note: void CryptoPP::memcpy_s(void*, size_t, const void*, size_t)

 inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t co
unt)
             ^
make: *** [validat0.o] Error 1

g++ -v output:

Using built-in specs.
COLLECT_GCC=c:\MinGW-w64\mingw64\bin\g++.exe
COLLECT_LTO_WRAPPER=c:/MinGW-w64/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/4.9.2/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../../../src/gcc-4.9.2/configure --host=x86_64-w64-mingw32 --build=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysroot=/c/mingw492/x86_64-492-win32-seh-rt_v4-rev3/mingw64 --with-gxx-include-dir=/mingw64/x86_64-w64-mingw32/include/c++ --enable-shared --enable-static --disable-multilib --enable-languages=ada,c,c++,fortran,objc,obj-c++,lto --enable-libstdcxx-time=yes --enable-threads=win32 --enable-libgomp --enable-libatomic --enable-lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --enable-version-specific-runtime-libs --disable-isl-version-check --disable-cloog-version-check --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=nocona --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw492/prerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw492/prerequisites/x86_64-w64-mingw32-static --with-mpc=/c/mingw492/prerequisites/x86_64-w64-mingw32-static --with-isl=/c/mingw492/prerequisites/x86_64-w64-mingw32-static --with-cloog=/c/mingw492/prerequisites/x86_64-w64-mingw32-static --enable-cloog-backend=isl --with-pkgversion='x86_64-win32-seh-rev3, Built by MinGW-W64 project' --with-bugurl=http://sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -I/c/mingw492/x86_64-492-win32-seh-rt_v4-rev3/mingw64/opt/include -I/c/mingw492/prerequisites/x86_64-zlib-static/include -I/c/mingw492/prerequisites/x86_64-w64-mingw32-static/include' CXXFLAGS='-O2 -pipe -I/c/mingw492/x86_64-492-win32-seh-rt_v4-rev3/mingw64/opt/include -I/c/mingw492/prerequisites/x86_64-zlib-static/include -I/c/mingw492/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS= LDFLAGS='-pipe -L/c/mingw492/x86_64-492-win32-seh-rt_v4-rev3/mingw64/opt/lib -L/c/mingw492/prerequisites/x86_64-zlib-static/lib -L/c/mingw492/prerequisites/x86_64-w64-mingw32-static/lib '
Thread model: win32
gcc version 4.9.2 (x86_64-win32-seh-rev3, Built by MinGW-W64 project)

Undefined symbol `rdtable::Te` under Visual Studio, X64, Aligned Data Access

With CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS undefined (i.e., aligned data access), a Visual Studio build for X64 results in:

------ Build started: Project: cryptest, Configuration: Debug x64 ------
Linking...
cryptlib.lib(x64dll.obj) : error LNK2001: unresolved external symbol
"unsigned __int64 CryptoPP::rdtable::Te" (?Te@rdtable@CryptoPP@@3PA_KA)
x64\Output\Debug\cryptest.exe : fatal error LNK1120: 1 unresolved externals

To duplicate the issue, ensure CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS is _not_ defined. Under 5.6.3 (and above), CRYPTOPP_NO_UNALIGNED_DATA_ACCESS can be defined to facilitate it.

The fix would appear to be simple (like ensure an aligned version of rdtable::Te is available), but its not. That's because there's an implicit assumption that Rijndael/AES is using compressed tables when unaligned data access is allowed.

Clang integrated assembler and "invalid operand for instruction"

$ make GAS210_OR_LATER=1 GAS219_OR_LATER=1 GAS219_OR_LATER=1 
clang++ -DNDEBUG -g2 -O3 -Wall -fPIC -march=native -pipe -Wno-tautological-compare -c gcm.cpp
gcm.cpp:676:3: error: invalid operand for instruction
                AS2(    movd    WORD_REG(di), xmm...
                ^
./cpu.h:221:20: note: expanded from macro 'AS2'
        #define AS2(x, y) GNU_AS2(x, y)
                          ^
./cpu.h:216:27: note: expanded from macro 'GNU_AS2'
        #define GNU_AS2(x, y) "\n\t" #x ", " #y ";"
                             ^
<inline asm>:110:12: note: instantiated into assembly here
        movd rdi, xmm0;
                  ^~~~~
gcm.cpp:685:3: error: invalid operand for instruction
                AS2(    movd    WORD_REG(di), xmm...
                ^
./cpu.h:221:20: note: expanded from macro 'AS2'
        #define AS2(x, y) GNU_AS2(x, y)
                          ^
./cpu.h:216:27: note: expanded from macro 'GNU_AS2'
        #define GNU_AS2(x, y) "\n\t" #x ", " #y ";"
                                 ^
<inline asm>:117:12: note: instantiated into assembly here
        movd rdi, xmm1;
                  ^~~~~

Possibly related: Clang Inline Assembly and Compatibility.

There are many compile warnings on GCC with '-Wabi'

There are many compile warnings when enabling '-Wabi' .
It will complain about 'contains empty classes which may cause base classes to be placed at different locations in a future version of GCC'

$ g++ -DNDEBUG -g2 -O3 -Wabi -fPIC -march=native -Wall -Wextra -Wno-type-limits -Wno-unknown-pragmas -pipe -c ecp.cpp

algebra.cpp:250: warning: ‘CryptoPP::WindowSlider::m_windowModulus’ contains empty classes which may cause base classes to be placed at different locations in a future version of GCC
ecp.cpp:294: warning: ‘CryptoPP::ProjectivePoint::y’ contains empty classes which may cause base classes to be placed at different locations in a future version of GCC
ecp.cpp:338: warning: ‘CryptoPP::ProjectiveDoubling::sixteenY4’ contains empty classes which may cause base classes to be placed at different locations in a future version of GCC
ecp.cpp:338: warning: ‘CryptoPP::ProjectiveDoubling::twoY’ contains empty classes which may cause base classes to be placed at different locations in a future version of GCC
ecp.cpp:338: warning: ‘CryptoPP::ProjectiveDoubling::S’ contains empty classes which may cause base classes to be placed at different locations in a future version of GCC


$ g++ -DNDEBUG -g2 -O3 -Wabi -fPIC -march=native -Wall -Wextra -Wno-type-limits -Wno-unknown-pragmas -pipe -c filters.cpp

integer.h:378: warning: ‘CryptoPP::Integer::reg’ contains empty classes which may cause base classes to be placed at different locations in a future version of GCC
In file included from filters.h:11,
             from filters.cpp:7:
algparam.h:57: warning: ‘CryptoPP::ConstByteArrayParameter::m_block’ contains empty classes which may cause base classes to be placed at different locations in a future version of GCC

GCC version

$ g++ -v
Using built-in specs.
Target: x86_64-redhat-linux6E
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --disable-gnu-unique-object --with-as=/usr/libexec/binutils220/as --enable-languages=c,c++,fortran --disable-libgcj --with-mpfr=/builddir/build/BUILD/gcc-4.4.7-20120601/obj-x86_64-redhat-linux6E/mpfr-install/ --with-ppl=/builddir/build/BUILD/gcc-4.4.7-20120601/obj-x86_64-redhat-linux6E/ppl-install --with-cloog=/builddir/build/BUILD/gcc-4.4.7-20120601/obj-x86_64-redhat-linux6E/cloog-install --with-tune=generic --with-arch_32=i586 --build=x86_64-redhat-linux6E
Thread model: posix
gcc version 4.4.7 20120313 (Red Hat 4.4.7-1) (GCC)

CentOS release 5.11, kernel 2.6.18-398

Should FileSInk::Put2 use streamsize blocks?

FileSink::Put2 (from files.cpp) uses the following. If length > std::streamsize, then only one iteration is performed and the user must retry manually.

size_t FileSink::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
{
    if (!m_stream)
        throw Err("FileSink: output stream not opened");

    while (length > 0)
    {
        std::streamsize size;
        bool safe = SafeConvert(length, size);
        CRYPTOPP_ASSERT(safe);
        if (!safe)
            size = numeric_limits<std::streamsize>::max();
        m_stream->write((const char *)inString, size);
        inString += size;
        length -= (size_t)size;
    }
    ...
}

Valgrind: "Conditional jump or move depends on uninitialised value(s)"

Here's the full message:

==6985== Conditional jump or move depends on uninitialised value(s)
==6985==    at 0x557A328: CryptoPP::DetectX86Features() (in /usr/lib/libcryptopp.so)
==6985==    by 0x55613F0: CryptoPP::Rijndael::Base::UncheckedSetKey(unsigned char const*, unsigned int, CryptoPP::NameValuePairs const&) (in /usr/lib/libcryptopp.so)
==6985==    by 0x55191CC: CryptoPP::GCM_Base::SetKeyWithoutResync(unsigned char const*, unsigned long, CryptoPP::NameValuePairs const&) (in /usr/lib/libcryptopp.so)
==6985==    by 0x5498312: CryptoPP::AuthenticatedSymmetricCipherBase::SetKey(unsigned char const*, unsigned long, CryptoPP::NameValuePairs const&) (in /usr/lib/libcryptopp.so)
==6985==    by 0x557F7A4: CryptoPP::SimpleKeyingInterface::SetKeyWithIV(unsigned char const*, unsigned long, unsigned char const*, unsigned long) (in /usr/lib/libcryptopp.so)

Code calling Crypto++:

// These are defined before:
// std::vector<uint8_t> plaintext;
// byte key[];
// byte iv[];
#define TAG_SIZE 12

std::string ciphertext;
CryptoPP::GCM< CryptoPP::AES >::Encryption e;
e.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv));
CryptoPP::ArraySource ss(plaintext.data(), plaintext.size(), true,
    new CryptoPP::AuthenticatedEncryptionFilter(e,
        new CryptoPP::StringSink(encrypted), false, TAG_SIZE
    )
);

I believe it has something to do with cryptopp/cpu.cpp containing this:

void DetectX86Features()
{
    // ...
    word32 cpuid2[4]; // uninitialized
    CpuId(0x080000000, cpuid2);
    if (cpuid2[0] >= 0x080000001)

And this:

bool CpuId(word32 input, word32 *output)
{
#ifdef CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY
// ...
#else
    SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID);
    if (oldHandler == SIG_ERR)
        return false; // still uninitialized

    bool result = true;
    if (setjmp(s_jmpNoCPUID))
        result = false; // still uninitialized, since the else-statement
                        // contains the code that changes output[]
    else
    {
    // ...

But it's just an assumption, because I couldn't succeed to build shared libraries of Crypto++ on Linux myself, thus I can't test it.

Memory allocation not properly aligned on Windows platforms.

Assertion failed: m_allocated
cryptopp\secblock.h, line 197

The issue appears to be some problem with the alignment of the 60 byte array that is allocated.
It’s intended to be 8 byte aligned with 8 extra bytes added on to the end. The address used for
the array is the next 16 byte aligned address, which is guaranteed to end at latest at the end
of the allocated array.
However, the memory addresses I’m seeing in the debugger are not 8 byte aligned, so the
memory accessed goes past the end of the array into whatever comes next in the struct, 
which includes the m_allocated flag, which is what’s causing the assertion failure.
For whatever reason, __declspec(align(8)) isn’t working and I can’t seem to find a way around
this.  From googling, it seems like there might be an issue with the alignment of things
allocated with new / malloc.  Work around the bug by just increasing the padding on the array.

Here's the workaround.

--- cryptopp/secblock.h.orig    2013-02-20 14:30:52.000000000 -0500
+++ cryptopp/secblock.h 2015-08-12 13:46:00.088518500 -0400
@@ -227,7 +227,7 @@
    T m_array[S];
 #else
    T* GetAlignedArray() {return (CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16) ? (T*)(((byte *)m_array) + (0-(size_t)m_array)%16) : m_array;}
-   CRYPTOPP_ALIGN_DATA(8) T m_array[(CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16) ? S+8/sizeof(T) : S];
+   CRYPTOPP_ALIGN_DATA(8) T m_array[(CRYPTOPP_BOOL_ALIGN16_ENABLED && T_Align16) ? S+16/sizeof(T) : S];
 #endif
    A m_fallbackAllocator;
    bool m_allocated;

Here's the stack trace of the assertion

CryptoPP::FixedSizeAllocatorWithCleanup<unsigned int,60,CryptoPP::NullAllocator<unsigned int>,1>::deallocate(void * p, unsigned int n) Line 197      C++
CryptoPP::SecBlock<unsigned int,CryptoPP::FixedSizeAllocatorWithCleanup<unsigned int,60,CryptoPP::NullAllocator<unsigned int>,1> >::~SecBlock<unsigned int,CryptoPP::FixedSizeAllocatorWithCleanup<unsigned int,60,CryptoPP::NullAllocator<unsigned int>,1> >() Line 261     C++
CryptoPP::FixedSizeSecBlock<unsigned int,60,CryptoPP::FixedSizeAllocatorWithCleanup<unsigned int,60,CryptoPP::NullAllocator<unsigned int>,1> >::~FixedSizeSecBlock<unsigned int,60,CryptoPP::FixedSizeAllocatorWithCleanup<unsigned int,60,CryptoPP::NullAllocator<unsigned int>,1> >()                C++
CryptoPP::FixedSizeAlignedSecBlock<unsigned int,60,1>::~FixedSizeAlignedSecBlock<unsigned int,60,1>()          C++
CryptoPP::Rijndael::Base::~Base()           C++
CryptoPP::Rijndael::Enc::~Enc() C++
CryptoPP::ClonableImpl<CryptoPP::BlockCipherFinal<0,CryptoPP::Rijndael::Enc>,CryptoPP::Rijndael::Enc>::~ClonableImpl<CryptoPP::BlockCipherFinal<0,CryptoPP::Rijndael::Enc>,CryptoPP::Rijndael::Enc>()                C++
CryptoPP::BlockCipherFinal<0,CryptoPP::Rijndael::Enc>::~BlockCipherFinal<0,CryptoPP::Rijndael::Enc>()              C++
CryptoPP::GCM_Final<CryptoPP::Rijndael,0,0>::~GCM_Final<CryptoPP::Rijndael,0,0>()                C++
I set breakpoints on the `allocate’ function of secblock.h (line 181), and recorded the following allocations prior to ultimately hitting my breakpoint at the assertion at line 197:

Here are the return values of CryptoPP::FixedSizeAllocatorWithCleanup<unsigned int,60,CryptoPP::NullAllocator<unsigned int>,1>::GetAlignedArray:

Bytes                    Address
(De-/)Allocated          of Alloc  
60                       0x00ab88d0      
16                       0x0037ef48         
16                       0x0037efa0
-16                      0x0037efa0 
-16                      0x0037ef48 
16                       0x0037ef48
16                       0x0037efa0
-16                      0x0037efa0 
-16                      0x0037ef48 
-44                      0x00ab88d0 

Some points of interest:
• The pattern above is totally reproducible (with different address values).
• The size deallocated (-44) does not match the size allocated.
• Decryption happens just fine, it’s cleanup that aborts.

Assert fires when using rotate in CAST due to Undefined Behavior

> CAST-128 validation suite running...
>
> passed   0123456712345678234567893456789A   0123456789ABCDEF
> 238B4FE5847E44B2
>
> Assertion failed: (y > 0 && y < THIS_SIZE), function rotlVariable, file
> misc.h, line 713.
>
> Abort trap: 6

Assert does not fire when inline assembler is in effect because ASM is not bound to the C/C++ UB rules.

Compiler warnings on GCC and MinGW

Here are the warnings that are displayed on Linux during compilation with CRYPTOPP_NO_UNALIGNED_ACCESS defined:


g++ -DNDEBUG -g2 -O3 -fPIC -march=native -DCRYPTOPP_DISABLE_ASM -Wall -Wextra -Wno-type-limits -Wno-unknown-pragmas -pipe -c cpu.cpp
cpu.cpp: In function ‘bool CryptoPP::CpuId(CryptoPP::word32, CryptoPP::word32*)’:
cpu.cpp:83:7: warning: variable ‘result’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]
  bool result = true;
       ^
g++ -DNDEBUG -g2 -O3 -fPIC -march=native -DCRYPTOPP_DISABLE_ASM -Wall -Wextra -Wno-type-limits -Wno-unknown-pragmas -pipe -c md2.cpp
g++ -DNDEBUG -g2 -O3 -fPIC -march=native -DCRYPTOPP_DISABLE_ASM -Wall -Wextra -Wno-type-limits -Wno-unknown-pragmas -pipe -c integer.cpp
integer.cpp: In function ‘void CryptoPP::Baseline_MultiplyBottom2(CryptoPP::word*, const word*, const word*)’:
integer.cpp:1058:16: warning: variable ‘d1’ set but not used [-Wunused-but-set-variable]
  Declare2Words(d)    \
                ^
integer.cpp:111:40: note: in definition of macro ‘Declare2Words’
  #define Declare2Words(x)   word x##0, x##1;
                                        ^
integer.cpp:972:2: note: in expansion of macro ‘Mul_Begin’
  Mul_Begin(2) \
  ^
integer.cpp:1161:2: note: in expansion of macro ‘Bot_2’
  Bot_2
  ^

GCC version: 4.9.2, Ubuntu 15.04, Linux Kernel 3.19.0-25-generic.

Compile failure under Cygwin with GCC 4.8 in C++11 mode due to alloca

g++ -std=c++11 -DNDEBUG -g2 -O3  -march=native -Wall -Wextra -Wno-type-limits -Wno-unknown-pragmas -pipe -c rijndael.cpp
rijndael.cpp: In member function ‘virtual size_t CryptoPP::Rijndael::Enc::AdvancedProcessBlocks(const byte*, const byte*, byte*, size_t, CryptoPP::word32) const’:
rijndael.cpp:1214:45: error: ‘alloca’ was not declared in this scope
    space = (byte *)alloca(255+sizeof(Locals));
                                             ^
GNUmakefile:475: recipe for target 'rijndael.o' failed
make: *** [rijndael.o] Error 1

To duplicate on a Cygwin machine:

git clone...
export CXXFLAGS="-std=c++11"
make

or:

make rijndael.o

Crash in AutoSeededRandomPool under Windows XP, VS2005, Aligned Data Access

The system is Windows XP 64-bit and Visual Studio 2005. The issue is _not_ present with Windows 8 64-bit and Visual Studio 2010 and 2012.

With CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS undefined (i.e., aligned data access), a Visual Studio build for X86 using an AutoSeededRandomPool results in a crash. TestAutoSeeded is similar to TestOS_RNG:

AutoSeededRandomPool prng;
MeterFilter meter(new Redirector(TheBitBucket()));
RandomNumberSource test(prng, 100000, true, new Deflator(new Redirector(meter)));
...

The cryptest.exe!_chkstk() Line 99 is the test dword ptr [eax],eax below:

; Find next lower page and probe
cs20:
    sub     eax, _PAGESIZE_         ; decrease by PAGESIZE
    test    dword ptr [eax],eax     ; probe page.
    jmp     short cs10

The call stack looks like:

cryptest.exe!_chkstk()  Line 99 Asm
cryptest.exe!CryptoPP::Rijndael::Enc::ProcessAndXorBlock(const unsigned char * inBlock=0x0012da88, const unsigned char * xorBlock=0x00000000, unsigned char * outBlock=0x0012da88)  Line 359 + 0x18 bytes   C++
cryptest.exe!CryptoPP::BlockTransformation::ProcessBlock(unsigned char * inoutBlock=0x0012da88)  Line 455 + 0x1e bytes  C++
cryptest.exe!CryptoPP::RandomPool::GenerateIntoBufferedTransformation(CryptoPP::BufferedTransformation & target={...}, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & channel="", unsigned __int64 size=100000)  Line 54  C++
cryptest.exe!CryptoPP::RandomNumberStore::TransferTo2(CryptoPP::BufferedTransformation & target={...}, unsigned __int64 & transferBytes=100000, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & channel="", bool blocking=true)  Line 1131 C++
cryptest.exe!CryptoPP::BufferedTransformation::TransferMessagesTo2(CryptoPP::BufferedTransformation & target={...}, unsigned int & messageCount=0, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & channel="", bool blocking=true)  Line 566 + 0x1d bytes  C++
cryptest.exe!CryptoPP::BufferedTransformation::TransferAllTo2(CryptoPP::BufferedTransformation & target={...}, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & channel="", bool blocking=true)  Line 612 + 0x18 bytes  C++
cryptest.exe!CryptoPP::SourceTemplate<CryptoPP::RandomNumberStore>::PumpAll2(bool blocking=true)  Line 794 + 0x2c bytes C++
cryptest.exe!CryptoPP::Source::PumpAll()  Line 765 + 0x19 bytes C++
cryptest.exe!CryptoPP::Source::SourceInitialize(bool pumpAll=true, const CryptoPP::NameValuePairs & parameters={...})  Line 777 C++
cryptest.exe!CryptoPP::RandomNumberSource::RandomNumberSource(CryptoPP::RandomNumberGenerator & rng={...}, int length=100000, bool pumpAll=true, CryptoPP::BufferedTransformation * attachment=0x008001c8)  Line 832 + 0x96 bytes   C++
cryptest.exe!TestAutoSeeded()  Line 401 + 0xca bytes    C++
cryptest.exe!ValidateAll(bool thorough=false)  Line 58 + 0x5 bytes  C++
cryptest.exe!Validate(int alg=0, bool thorough=false, const char * seedInput=0x00000000)  Line 818 + 0x9 bytes  C++

GeneratePrimes is not a member of CryptoPP::DSA with CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY

$ make dll.o dsa.o
g++ ... -DCRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY ... -c dll.cpp
In file included from dll.h:18:0,
                 from dll.cpp:6:
dsa.h: In function ‘bool CryptoPP::GenerateDSAPrimes(const byte*, size_t, int&, CryptoPP::Integer&, unsigned int, CryptoPP::Integer&)’:
dsa.h:30:10: error: ‘GeneratePrimes’ is not a member of ‘CryptoPP::DSA {aka CryptoPP::DSA2<CryptoPP::SHA1>}’
  {return DSA::GeneratePrimes(seed, seedLength, counter, p, primeLength, q);}
          ^
GNUmakefile:424: recipe for target 'dll.o' failed

GeneratePrimes appears to be a function from an earlier version of the library. I cannot find a definition for it in Crypto++ 5.6.2.

The other issues were cleared (relatively easily). This is the one that remains.


Here's the result of the same error under the test script used for comprehensive testing:

...
Testing started: Sat Oct 31 07:00:03 UTC 2015
Testing finished: Sat Oct 31 08:38:15 UTC 2015

21 configurations tested
1 errors detected

7753:dsa.h:30:10: error: ‘GeneratePrimes’ is not a member of ‘CryptoPP::DSA {aka CryptoPP::DSA2<CryptoPP::SHA1>}’

Need a strategy for dealing with OS X ported compilers

_Background_

Crypto++ 5.6.3 and above use GCC's init_priority in an effort to tame the C++ Static Initialization Order Fiasco. Its an optional feature that is disabled by default under 5.6.3. It can be enabled with CXXFLAGS="-DCRYPTOPP_INIT_PRIORITY=250" (or similar).

OS X has about 6 projects that provide Unix and Linux tools on OS X. The projects are called "ports' and they include:

  • Fink
  • Gentoo/Alt
  • Homebrew
  • MacPorts
  • Pkgsrc
  • Rudix

Some of the ports provide GCC, but they do not enable init_priority support and subsequently fail the compile. The compiler appears to be acting as a proxy for the linker, and assume init_priority is an error because the OS X linker does not offer a pubic interface to control the order. Or maybe more correctly, Apple did not respond to a GNU/Binutils bug report on the subject. (Its not clear if the linker would actually fail a link if the metadata was present).

As far as we know, Fink will accept init_priority, and MacPorts will reject init_priority. We don't know what the other ports are doing. Additionally, other compilers are OK, like Apple's GCC and Clang.

We attempted to acquire metrics to help gauge the impact of disabling init_priority among a ports collection, but MacPorts does not test its compilers. Also see Does MacPorts provide its Test/QA results online?

_Strategies_

We don't have a strategy for dealing with GCC-compatible compilers that refuse to compile a program. The two strategies being considered are:

  1. disable init_priority for all non-Apple GCC compilers
  2. disable init_priority for port compilers that refuse to compile the program

Strategy 1 disables init_priority for all GCC compilers since Apple no longer provides GCC. For example, if we detect any port like Fink (and not just a problematic port like MacPorts), then the code disables init_priority.

Strategy 2 disables init_priority on a per-need basis. For example, if we detect a problematic port like MacPorts (and not just any port like Fink), then the code disables init_priority.

Crash in DL_GroupParameters_IntegerBased::GetEncodedElementSize for Cygwin i386 at -O3

Here are the symptoms:

$ make
g++ -DNDEBUG -g2 -O3 -march=native -DCRYPTOPP_NO_UNALIGNED_DATA_ACCESS -pipe -c cryptlib.cpp
g++ -DNDEBUG -g2 -O3 -march=native -DCRYPTOPP_NO_UNALIGNED_DATA_ACCESS -pipe -c shacal2.cpp
...

$ ./cryptest.exe v
...

MQV validation suite running...

passed    authenticated key agreement domain parameters validation
...

$ gdb ./cryptest.exe
...
Program received signal SIGSEGV, Segmentation fault.
CryptoPP::DL_GroupParameters_IntegerBased::GetEncodedElementSize (this=0x11,
    reversible=0x1) at gfpcrypt.h:65
65        {CRYPTOPP_UNUSED(reversible); return GetModulus().ByteCount();}
(gdb)

Here is the platform and compiler version:

$ g++ --version
g++ (GCC) 4.9.3
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ uname -a
CYGWIN_NT-6.1-WOW windows-7-x64 2.2.1(0.289/5/3) 2015-08-20 11:40 i686 Cygwin

The issue is present with -DCRYPTOPP_DISABLE_ASM.

Despite best efforts, its still unclear why this pointer is 0x11.

Cryptest.exe fails to build under Cygwin-i686 with sanitizer flags

When running cryptest.sh under Cygwin-i686 and the sanitizers, the cryptest.exe program fails to build:

 ...
 g++ -DDEBUG -g2 -O2 -std=c++03 -fsanitize=address -march=native -pipe -c fipsalgt.cpp
 g++ -DDEBUG -g2 -O2 -std=c++03 -fsanitize=address -march=native -pipe -c dlltest.cpp
 g++ -o cryptest.exe -DDEBUG -g2 -O2 -std=c++03 -fsanitize=address -march=native -pipe bench.o bench2.o test.o validat1.o validat2.o validat3.o adhoc.o datatest.o regtest.o fipsalgt.o dlltest.o ./libcryptopp.a
 /usr/lib/gcc/i686-pc-cygwin/4.9.3/../../../../i686-pc-cygwin/bin/ld: cannot find -lasan
 collect2: error: ld returned 1 exit status
 GNUmakefile:333: recipe for target 'cryptest.exe' failed

The host is Windows 7, x64:

$ uname -a
CYGWIN_NT-6.1-WOW windows-7-x64 2.2.1(0.289/5/3) 2015-08-20 11:40 i686 Cygwin

Naively it seems like a simple package problem. However, I can't seem to locate the package. Searching for _ubsan_ results in 0 hits. Also see What package do I need for Cygwin's UBsan? on Stack Overflow.

Feature detection issue in Debian Unstable

László Böszörményi of Debian reports the following issue when testing under Debian Unstable.

passed:  sizeof(hword) == 4, sizeof(word) == 8, sizeof(dword) == 16
FAILED:  hasMMX == 1, hasISSE == 1, hasSSE2 == 1, hasSSSE3 == 0,
hasAESNI == 0, hasCLMUL == 0, isP4 == 0, cacheLineSize == 808,
AESNI_INTRINSICS == 1
Some critical setting in config.h is in error.  Please fix it and recompile.

 Process terminating with default action of signal 6 (SIGABRT)
    at 0x5FA1107: raise (raise.c:56)
    by 0x5FA24E7: abort (abort.c:89)
    by 0x5CBF1F: TestSettings() (validat1.cpp:280)
    by 0x5CB2D1: ValidateAll(bool) (validat1.cpp:66)
    by 0x5B887E: Validate(int, bool, char const*) (test.cpp:819)
    by 0x5B33BB: main (test.cpp:343)
...

The SIGABRT is due to an assert firing because cacheLineSize == 808.

Its unclear what the issue is or how to reproduce it.

_CRT_SECURE_NO_DEPRECATE is used under Windows

test.cpp and bench.cpp include #define _CRT_SECURE_NO_DEPRECATE. From Security Features in the CRT:

There are several ways to eliminate deprecation warnings for the older, less secure functions. The simplest is simply to define _CRT_SECURE_NO_WARNINGS or use the warning pragma. Either will disable deprecation warnings, but of course the security issues that caused the warnings still exist. It is far better to leave deprecation warnings enabled and take advantage of the new CRT security features.

Other ways the Secure CRT Warning can be disabled include pragma warning(disable: 4996). An audit of the proposed 5.6.3 changes shows its used in one place, and that's misc.h around line 150.

pragma warning(disable: 4996) is used because misc.h provides wrappers for memcpy_s and memmove_s. Once we removed the _CRT_SECURE_NO_DEPRECATE define, misc.h generated a C4996 warning. We ensured the code performs the requisite bounds check, and then disabled the warning on the two wrapper functions. An auditor should sign-off on it.

We also disable Enterprise Analysis warning C6386 because Microsoft performs the same in their headers. Confer, the late answer at Disabling Warnings generated via _CRT_SECURE_NO_DEPRECATE.

This is a Certification and Accreditation (C&A) item.

Verify conformance with FIPS 186-4, Change Notice, Item 5

Reference FIPS 186-3 Change Notice (2-28-12). From 5, Processing Step Error in the Secret Number Generation for ECDSA:

In Appendices B.5.1 and B.5.2, processing step 1 (i.e., N = len(q)) is incorrect. This change notice specifies the following change to step 1: “N = len(n),” ; i.e., “q” is changed to “n”

This change may be significant if the cofactor is greater than one; for the NIST-recommended curves, the cofactor is one, so in this case, both values produce the same value for N.

A cofactor of 2 and 4 are common. Crypto++ optionally operates on ANSI X9.62 and WTLS curves, and some of them have a cofactor that is quite large. The curves are optional because its a free community patch.

AssignFromHelperClass is horrible

The uses of Hack_DefaultValueFromConstReferenceType and Hack_GetValueIntoConstReference are undefined behaviour, and quite foul.

If the VC60 workaround is still needed (VC6 in 2015, really?) the sane way to do it would be:

typename decay<R>::type value;
if (!m_source.GetValue(name, value))
    throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name + "'");
(m_pObject->*pm)(value);

with the following added as private members of AssignFromHelperClass:

template <class R> struct decay { typedef R type; };
template <class R> struct decay<const R&> { typedef R type; };

If you really must support VC6 then do it with #if not by using the same horrible code for compilers that aren't totally broken.

Compile failures under X32 (32-bit integers, longs, pointers on x86_64)

László Böszörményi of Debian helped with some cross validation testing. Building the library under a X32/chroot on Debian x86_64 results in a number of compile failures. Classes and source files with issues include CPU, Integer, Rijndael, SHA, Panama, Tiger, Sosemanuk, VMAC, Whirlpool and GCM.

Here's the 3-second tour for X32 from Debian's wiki on X32 Port: X32 is an ABI for amd64/x86_64 CPUs using 32-bit integers, longs and pointers. The idea is to combine the smaller memory and cache footprint from 32-bit data types with the larger register set of x86_64.

We were not detecting X32, and the following was added to config.h:

#if (__ILP32__ >= 1 || _ILP32 >= 1)
    # define CRYPTOPP_BOOL_X32 1
#else
    # define CRYPTOPP_BOOL_X32 0
#endif

In general, X86 code paths are enabled, and X64 code paths are disabled. That's consistent with ILP32, where integers, longs and pointer are 32-bits. However, even in X32 mode, we still have to push/pop 64-bit registers. For example, from gcm.cpp, within a 32-bit assembly block:

@@ -589,8 +606,13 @@
        AS2(    shr     WORD_REG(dx), 4             )
#endif

-       AS_PUSH_IF86(   bx)
-       AS_PUSH_IF86(   bp)
+       #if CRYPTOPP_BOOL_X32
+           AS1(push  rbx)
+           AS1(push  rbp)
+       #else
+           AS_PUSH_IF86(  bx)
+           AS_PUSH_IF86(  bp)
+       #endif 

On the down side, Valgrind has not been ported to X32. Valgrind has helped us twice in the past with ASM issues (use of CPUID on x86_64 and Salsa on x86_64). I think we should cautiously approach any ASM ports, and possibly consider -DCRYPTOPP_DISABLE_ASM even though we have ported routines.

Also see [Valgrind-developers] Support for x32 ABI.

Crash in RandomNumberGenerator::GenerateWord32 due to stack recursion

Testing of RandomNumberGenerator::GenerateWord32 revealed a potential bug in GenerateBlock. GenerateBlock calls GenerateIntoBufferedTransformation. GenerateIntoBufferedTransformation, in turn, calls, GenerateBlock. Ad infinitum.

In the past, a patch to call OS_GenerateRandom was declined; see Patch for RandomNumberGenerator::GenerateIntoBufferedTransformation bug. It turns out that was not a bad decision. But the issue endured and we got a private bug report against 5.6.3rc4 due to it.

I dug up an old email thread with Wei on the same subject (from 2012 or so), and here's what he had to say about it:

Yeah, you're not supposed to use it directly. It's just meant to define the interface that other RNGs are supposed to implement, and includes some helper functions. I should probably make it so that it can't be instantiated.

So I'd like to make it so it can't be instantiated. The best way I know is to remove the implementations for GenerateIntoBufferedTransformation and GenerateBlock, and make them pure virtuals.

Use of auto_ptr causes dirty compile under Cygwin with -std=c++11

cryptlib.cpp: In member function ‘virtual size_t CryptoPP::PK_Signer::SignMessage(CryptoPP::RandomNumberGenerator&, const byte*, size_t, byte*) const’:
cryptlib.cpp:770:41: warning: ‘auto_ptr’ is deprecated (declared at /usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/backward/auto_ptr.h:87) [-Wdeprecated-declarations]
  std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
                                         ^
cryptlib.cpp: In member function ‘virtual size_t     CryptoPP::PK_Signer::SignMessageWithRecovery(CryptoPP::RandomNumberGenerator&, const byte*, size_t, const byte*, size_t, byte*) const’:
cryptlib.cpp:778:41: warning: ‘auto_ptr’ is deprecated (declared at /usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/backward/auto_ptr.h:87) [-Wdeprecated-declarations]
  std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
                                         ^
cryptlib.cpp: In member function ‘virtual bool     CryptoPP::PK_Verifier::Verify(CryptoPP::PK_MessageAccumulator*) const’:
cryptlib.cpp:786:59: warning: ‘auto_ptr’ is deprecated (declared at /usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/backward/auto_ptr.h:87) [-Wdeprecated-declarations]
  std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
                                                           ^
cryptlib.cpp: In member function ‘virtual bool CryptoPP::PK_Verifier::VerifyMessage(const byte*, size_t, const byte*, size_t) const’:
cryptlib.cpp:792:41: warning: ‘auto_ptr’ is deprecated (declared at /usr/lib/gcc/x86_64-pc-cygwin/4.9.3/include/c++/backward/auto_ptr.h:87) [-Wdeprecated-declarations]
std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
                                         ^
...

Compile Failure under Debian Unstable (x64), GCC 4.9, -std=c++11

Here are some test results from Debian Unstable (x64) with GCC 4.9. The messages below are from the log file called cryptest-result.sh, which is created by the test script located at Release Testing.

Though not readily apparent, they are produced by the following configurations:

  • Debug, C++11
  • Release, C++11
  • Valgrind, Debug, C++11
  • Valgrind, Release, C++11
  • Undefined Behavior sanitizer, C++11
  • Address sanitizer, C++11

Omitting -std= and using -std=c++03 avoids the issue.


Here is what a single squawk looks like:

cryptlib.h:864:39: error: ‘__m128i _mm_aesdeclast_si128(__m128i, __m128i)’ conflicts with a previous declaration
  class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BufferedTransformation : public Algorithm, public Waitable
                                   ^
In file included from /usr/lib/gcc/x86_64-linux-gnu/4.9/include/x86intrin.h:43:0,
             from /usr/include/x86_64-linux-gnu/c++/4.9/bits/opt_random.h:33,
             from /usr/include/c++/4.9/random:50,
             from /usr/include/c++/4.9/bits/stl_algo.h:66,
             from /usr/include/c++/4.9/algorithm:62,
             from stdcpp.h:13,
             from cryptlib.h:85,
             from misc.h:11,
             from cpu.cpp:13:
/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:52:1: note: previous declaration ‘__m128i _mm_aesdeclast_si128(__m128i, __m128i)’
 _mm_aesdeclast_si128 (__m128i __X, __m128i __Y)
 ^
In file included from cpu.cpp:12:0:
cpu.h:89:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
 _mm_aesdeclast_si128 (__m128i a, __m128i b)
 ^

5038:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:44:1: error: redefinition of ‘__m128i _mm_aesdec_si128(__m128i, __m128i)’
5055:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:52:1: error: redefinition of ‘__m128i _mm_aesdeclast_si128(__m128i, __m128i)’
5072:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:61:1: error: redefinition of ‘__m128i _mm_aesenc_si128(__m128i, __m128i)’
5089:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:69:1: error: redefinition of ‘__m128i _mm_aesenclast_si128(__m128i, __m128i)’
5106:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:77:1: error: redefinition of ‘__m128i _mm_aesimc_si128(__m128i)’
5123:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:87:1: error: redefinition of ‘__m128i _mm_aeskeygenassist_si128(__m128i, int)’
5140:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:116:1: error: redefinition of ‘__m128i _mm_clmulepi64_si128(__m128i, __m128i, int)’
5150:cryptlib.h:864:39: error: ‘__m128i _mm_aesdeclast_si128(__m128i, __m128i)’ conflicts with a previous declaration
5166:cpu.h:89:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5171:cryptlib.h:864:39: error: ‘__m128i _mm_aesdec_si128(__m128i, __m128i)’ conflicts with a previous declaration
5187:cpu.h:83:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5192:cryptlib.h:864:39: error: ‘__m128i _mm_aesenclast_si128(__m128i, __m128i)’ conflicts with a previous declaration
5208:cpu.h:77:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5213:cryptlib.h:864:39: error: ‘__m128i _mm_aesenc_si128(__m128i, __m128i)’ conflicts with a previous declaration
5229:cpu.h:71:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5234:cryptlib.h:864:39: error: ‘__m128i _mm_aesimc_si128(__m128i)’ conflicts with a previous declaration
5250:cpu.h:64:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5255:cryptlib.h:864:39: error: ‘__m128i _mm_aeskeygenassist_si128(__m128i, int)’ conflicts with a previous declaration
5271:cpu.h:57:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5276:cryptlib.h:864:39: error: ‘__m128i _mm_clmulepi64_si128(__m128i, __m128i, int)’ conflicts with a previous declaration
5292:cpu.h:51:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5320:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:44:1: error: redefinition of ‘__m128i _mm_aesdec_si128(__m128i, __m128i)’
5337:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:52:1: error: redefinition of ‘__m128i _mm_aesdeclast_si128(__m128i, __m128i)’
5354:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:61:1: error: redefinition of ‘__m128i _mm_aesenc_si128(__m128i, __m128i)’
5371:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:69:1: error: redefinition of ‘__m128i _mm_aesenclast_si128(__m128i, __m128i)’
5388:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:77:1: error: redefinition of ‘__m128i _mm_aesimc_si128(__m128i)’
5405:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:87:1: error: redefinition of ‘__m128i _mm_aeskeygenassist_si128(__m128i, int)’
5422:/usr/lib/gcc/x86_64-linux-gnu/4.9/include/wmmintrin.h:116:1: error: redefinition of ‘__m128i _mm_clmulepi64_si128(__m128i, __m128i, int)’
5432:cryptlib.h:864:39: error: ‘__m128i _mm_aesdeclast_si128(__m128i, __m128i)’ conflicts with a previous declaration
5448:cpu.h:89:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5453:cryptlib.h:864:39: error: ‘__m128i _mm_aesdec_si128(__m128i, __m128i)’ conflicts with a previous declaration
5469:cpu.h:83:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5474:cryptlib.h:864:39: error: ‘__m128i _mm_aesenclast_si128(__m128i, __m128i)’ conflicts with a previous declaration
5490:cpu.h:77:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5495:cryptlib.h:864:39: error: ‘__m128i _mm_aesenc_si128(__m128i, __m128i)’ conflicts with a previous declaration
5511:cpu.h:71:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5516:cryptlib.h:864:39: error: ‘__m128i _mm_aesimc_si128(__m128i)’ conflicts with a previous declaration
5532:cpu.h:64:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5537:cryptlib.h:864:39: error: ‘__m128i _mm_aeskeygenassist_si128(__m128i, int)’ conflicts with a previous declaration
5553:cpu.h:57:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling
5558:cryptlib.h:864:39: error: ‘__m128i _mm_clmulepi64_si128(__m128i, __m128i, int)’ conflicts with a previous declaration
5574:cpu.h:51:1: note: -fabi-version=6 (or =0) avoids this error with a change in mangling

Library fails to detect when SSE, SSE2, SSE3 are available under Clang

The library fails to detect when SSE, SSE2, SSE3 are available under Clang when the Integrated Assembler is being used in the GNUmakefile. The issue is:

   GAS219_OR_LATER := $(shell $(CXX) -xc -c /dev/null -Wa,-v -o/dev/null 2>&1 | $(EGREP) -i -c "GNU assembler version (2\.19|2\.[2-9]|[3-9])")

Reduces to/results in:

$ clang++ -xc -c /dev/null -Wa,-v -o/dev/null 2>&1
clang: error: unsupported argument '-v' to option 'Wa,'

The error makes code like this kick in:

ifeq ($(GAS210_OR_LATER),0) # .intel_syntax wasn't supported until GNU assembler 2.10
CXXFLAGS += -DCRYPTOPP_DISABLE_ASM
...

The issue was reported upstream at LLVM Issue 24200: With integrated assembler enabled, fail to fetch version string of assembler.

socketft defines _WINSOCK_DEPRECATED_NO_WARNINGS

To help facilitate the release of Crypto++ 5.6.3, _WINSOCK_DEPRECATED_NO_WARNINGS was defined before including Winsock gear to avoid the warnings and the rewrite. pragmas were used to disable warning C4996 before including the affected header; and then the warning was re-enabled.

See 05076db and 185a2c8

'dynamic' target fails on MinGW x32 and x64

g++ -shared -o libcryptopp.so -DNDEBUG -g2 -O3 -march=native -Wall -Wextra -Wno-type-limits -Wno-unknown-pragmas -pipe 3way.o adler32.o algebra.o algparam.o arc4.o asn.o authenc.o base32.o base64.o basecode.o bfinit.o blowfish.o blumshub.o camellia.o cast.o casts.o cbcmac.o ccm.o channels.o cmac.o cpu.o crc.o cryptlib.o default.o des.o dessp.o dh.o dh2.o dll.o dsa.o eax.o ec2n.o eccrypto.o ecp.o elgamal.o emsa2.o eprecomp.o esign.o files.o filters.o fips140.o fipstest.o gcm.o gf256.o gf2_32.o gf2n.o gfpcrypt.o gost.o gzip.o hex.o hmac.o hrtimer.o ida.o idea.o integer.o iterhash.o luc.o mars.o marss.o md2.o md4.o md5.o misc.o modes.o mqueue.o mqv.o nbtheory.o network.o oaep.o osrng.o panama.o pkcspad.o polynomi.o pssr.o pubkey.o queue.o rabin.o randpool.o rc2.o rc5.o rc6.o rdtables.o rijndael.o ripemd.o rng.o rsa.o rw.o safer.o salsa.o seal.o seed.o serpent.o sha.o sha3.o shacal2.o shark.o sharkbox.o simple.o skipjack.o socketft.o sosemanuk.o square.o squaretb.o strciphr.o tea.o tftables.o tiger.o tigertab.o trdlocal.o ttmac.o twofish.o vmac.o wait.o wake.o whrlpool.o winpipes.o xtr.o xtrcrypt.o zdeflate.o zinflate.o zlib.o
socketft.o: In function `ZN8CryptoPP14SocketReceiver16GetReceiveResultEv':
c:\cryptopp-master/socketft.cpp:372: undefined reference to `WSAGetOverlappedResult@20'
c:\cryptopp-master/socketft.cpp:379: undefined reference to `WSAGetLastError@0'
socketft.o: In function `ZN8CryptoPP12SocketSender13GetSendResultEv':
c:\cryptopp-master/socketft.cpp:469: undefined reference to `WSAGetOverlappedResult@20'
socketft.o: In function `ZN8CryptoPP12SocketSender4SendEPKhj':
c:\cryptopp-master/socketft.cpp:418: undefined reference to `WSASend@28'
c:\cryptopp-master/socketft.cpp:425: undefined reference to `WSAGetLastError@0'
socketft.o: In function `ZN8CryptoPP6Socket8ShutDownEi':
c:\cryptopp-master/socketft.cpp:209: undefined reference to `shutdown@8'
socketft.o: In function `ZN8CryptoPP12SocketSender7SendEofEv':
c:\cryptopp-master/socketft.cpp:437: undefined reference to `WSAEventSelect@12'
socketft.o: In function `ZN8CryptoPP14SocketReceiver7ReceiveEPhj':
c:\cryptopp-master/socketft.cpp:337: undefined reference to `WSARecv@28'
c:\cryptopp-master/socketft.cpp:344: undefined reference to `WSAGetLastError@0'
socketft.o: In function `ZN8CryptoPP6Socket11CloseSocketEv':
c:\cryptopp-master/socketft.cpp:85: undefined reference to `closesocket@4'
socketft.o: In function `ZN8CryptoPP6Socket6CreateEi':
c:\cryptopp-master/socketft.cpp:73: undefined reference to `socket@12'
socketft.o: In function `ZN8CryptoPP6Socket11CloseSocketEv':
c:\cryptopp-master/socketft.cpp:85: undefined reference to `closesocket@4'
socketft.o: In function `ZN8CryptoPP6Socket4BindEjPKc':
c:\cryptopp-master/socketft.cpp:104: undefined reference to `inet_addr@4'
c:\cryptopp-master/socketft.cpp:113: undefined reference to `htons@4'
socketft.o: In function `ZN8CryptoPP6Socket4BindEPK8sockaddri':
c:\cryptopp-master/socketft.cpp:122: undefined reference to `bind@12'
socketft.o: In function `ZN8CryptoPP6Socket12SetLastErrorEi':
c:\cryptopp-master/socketft.cpp:300: undefined reference to `WSASetLastError@4'
socketft.o: In function `ZN8CryptoPP6Socket4BindEjPKc':
c:\cryptopp-master/socketft.cpp:101: undefined reference to `htonl@4'
socketft.o: In function `ZN8CryptoPP6Socket4BindEPK8sockaddri':
c:\cryptopp-master/socketft.cpp:122: undefined reference to `bind@12'
socketft.o: In function `ZN8CryptoPP6Socket6ListenEi':
c:\cryptopp-master/socketft.cpp:128: undefined reference to `listen@8'
socketft.o: In function `ZN8CryptoPP6Socket7ConnectEPKcj':
c:\cryptopp-master/socketft.cpp:138: undefined reference to `inet_addr@4'
c:\cryptopp-master/socketft.cpp:152: undefined reference to `htons@4'
socketft.o: In function `ZN8CryptoPP6Socket7ConnectEPK8sockaddri':
c:\cryptopp-master/socketft.cpp:160: undefined reference to `connect@12'
socketft.o: In function `ZN8CryptoPP6Socket7ConnectEPKcj':
c:\cryptopp-master/socketft.cpp:142: undefined reference to `gethostbyname@4'
socketft.o: In function `ZN8CryptoPP6Socket12GetLastErrorEv':
c:\cryptopp-master/socketft.cpp:291: undefined reference to `WSAGetLastError@0'
socketft.o: In function `ZN8CryptoPP6Socket12SetLastErrorEi':
c:\cryptopp-master/socketft.cpp:300: undefined reference to `WSASetLastError@4'
socketft.o: In function `ZN8CryptoPP6Socket7ConnectEPK8sockaddri':
c:\cryptopp-master/socketft.cpp:160: undefined reference to `connect@12'
socketft.o: In function `ZN8CryptoPP6Socket12GetLastErrorEv':
c:\cryptopp-master/socketft.cpp:291: undefined reference to `WSAGetLastError@0'
socketft.o: In function `ZN8CryptoPP6Socket6AcceptERS0_P8sockaddrPi':
c:\cryptopp-master/socketft.cpp:170: undefined reference to `accept@12'
socketft.o: In function `ZN8CryptoPP6Socket11CloseSocketEv':
c:\cryptopp-master/socketft.cpp:85: undefined reference to `closesocket@4'
socketft.o: In function `ZN8CryptoPP6Socket12GetLastErrorEv':
c:\cryptopp-master/socketft.cpp:291: undefined reference to `WSAGetLastError@0'
socketft.o: In function `ZN8CryptoPP6Socket11GetSockNameEP8sockaddrPi':
c:\cryptopp-master/socketft.cpp:181: undefined reference to `getsockname@12'
socketft.o: In function `ZN8CryptoPP6Socket11GetPeerNameEP8sockaddrPi':
c:\cryptopp-master/socketft.cpp:187: undefined reference to `getpeername@12'
socketft.o: In function `ZN8CryptoPP6Socket4SendEPKhji':
c:\cryptopp-master/socketft.cpp:193: undefined reference to `send@16'
socketft.o: In function `ZN8CryptoPP6Socket7ReceiveEPhji':
c:\cryptopp-master/socketft.cpp:201: undefined reference to `recv@16'
socketft.o: In function `ZN8CryptoPP6Socket8ShutDownEi':
c:\cryptopp-master/socketft.cpp:209: undefined reference to `shutdown@8'
socketft.o: In function `ZN8CryptoPP6Socket5IOCtlElPm':
c:\cryptopp-master/socketft.cpp:217: undefined reference to `ioctlsocket@12'
socketft.o: In function `ZN8CryptoPP6Socket9SendReadyEPK7timeval':
c:\cryptopp-master/socketft.cpp:234: undefined reference to `select@20'
socketft.o: In function `ZN8CryptoPP6Socket12ReceiveReadyEPK7timeval':
c:\cryptopp-master/socketft.cpp:251: undefined reference to `select@20'
socketft.o: In function `ZN8CryptoPP6Socket12SetLastErrorEi':
c:\cryptopp-master/socketft.cpp:300: undefined reference to `WSASetLastError@4'
socketft.o: In function `ZN8CryptoPP6Socket12StartSocketsEv':
c:\cryptopp-master/socketft.cpp:273: undefined reference to `WSAStartup@8'
socketft.o: In function `ZN8CryptoPP6Socket15ShutdownSocketsEv':
c:\cryptopp-master/socketft.cpp:282: undefined reference to `WSACleanup@0'
socketft.o: In function `ZN8CryptoPP6Socket12GetLastErrorEv':
c:\cryptopp-master/socketft.cpp:291: undefined reference to `WSAGetLastError@0'
socketft.o: In function `ZN8CryptoPP6Socket11CloseSocketEv':
c:\cryptopp-master/socketft.cpp:85: undefined reference to `closesocket@4'
c:\cryptopp-master/socketft.cpp:85: undefined reference to `closesocket@4'
socketft.o: In function `ZN8CryptoPP12SocketSender7EofSentEv':
c:\cryptopp-master/socketft.cpp:446: undefined reference to `WSAEnumNetworkEvents@12'
socketft.o: In function `ZN8CryptoPP6Socket16PortNameToNumberEPKcS2_':
c:\cryptopp-master/socketft.cpp:263: undefined reference to `getservbyname@8'
c:\cryptopp-master/socketft.cpp:266: undefined reference to `ntohs@4'
socketft.o: In function `ZN8CryptoPP6Socket12GetLastErrorEv':
c:\cryptopp-master/socketft.cpp:291: undefined reference to `WSAGetLastError@0'
collect2.exe: error: ld returned 1 exit status
make: *** [libcryptopp.so] Error 1

Null pointers passed to memcpy

misc.h:177:26: runtime error: null pointer passed as argument 1, which is declared to never be null
misc.h:177:26: runtime error: null pointer passed as argument 2, which is declared to never be null

I suggest adding a check for count > 0 to memcpy_s and memmov_s if they are supposed to be "secure".

Assert in class NullAllocator, function deallocate

Hi,

there is an assert in an app I try to build when encrypting the user data.
The affected function is here:
https://github.com/ola-ct/Qt-SESAM/blob/master/libSESAM/crypter.cpp#L139

The code runs in an assert here:
https://github.com/weidai11/cryptopp/blob/master/secblock.h#L161

This is the stacktrace:

#0  0x00007ffff5a9b267 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:55
#1  0x00007ffff5a9ceca in __GI_abort () at abort.c:89
#2  0x00007ffff5a9403d in __assert_fail_base (
    fmt=0x7ffff5bf6028 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", 
    assertion=assertion@entry=0x4a3814 "false", 
    file=file@entry=0x4a37e0 "/usr/include/crypto++/secblock.h", 
    line=line@entry=151, 
    function=function@entry=0x4a3ac0 <CryptoPP::NullAllocator<unsigned int>::deallocate(void*, unsigned long)::__PRETTY_FUNCTION__> "void CryptoPP::NullAllocator<T>::deallocate(void*, CryptoPP::NullAllocator<T>::size_type) [with T = unsigned int; CryptoPP::NullAllocator<T>::size_type = long unsigned int]")
    at assert.c:92
#3  0x00007ffff5a940f2 in __GI___assert_fail (assertion=0x4a3814 "false", 
    file=0x4a37e0 "/usr/include/crypto++/secblock.h", line=151, 
    function=0x4a3ac0 <CryptoPP::NullAllocator<unsigned int>::deallocate(void*, unsigned long)::__PRETTY_FUNCTION__> "void CryptoPP::NullAllocator<T>::deallocate(void*, CryptoPP::NullAllocator<T>::size_type) [with T = unsigned int; CryptoPP::NullAllocator<T>::size_type = long unsigned int]") at assert.c:101
#4  0x000000000045bbbf in CryptoPP::NullAllocator<unsigned int>::deallocate (
    this=0x7fffffffca20, p=0x3c, n=316) at /usr/include/crypto++/secblock.h:151
#5  0x000000000045b96d in CryptoPP::FixedSizeAllocatorWithCleanup<unsigned int, 60ul, CryptoPP::NullAllocator<unsigned int>, true>::deallocate (
---Type <return> to continue, or q <return> to quit---
    this=0x7fffffffc930, p=0x3c, n=316) at /usr/include/crypto++/secblock.h:202
#6  0x000000000045b4ab in CryptoPP::SecBlock<unsigned int, CryptoPP::FixedSizeAllocatorWithCleanup<unsigned int, 60ul, CryptoPP::NullAllocator<unsigned int>, true> >::~SecBlock (this=0x7fffffffc930, __in_chrg=<optimized out>)
    at /usr/include/crypto++/secblock.h:261
#7  0x000000000045a44c in CryptoPP::FixedSizeSecBlock<unsigned int, 60u, CryptoPP::FixedSizeAllocatorWithCleanup<unsigned int, 60ul, CryptoPP::NullAllocator<unsigned int>, true> >::~FixedSizeSecBlock (this=0x7fffffffc930, 
    __in_chrg=<optimized out>) at /usr/include/crypto++/secblock.h:422
#8  0x000000000045a466 in CryptoPP::FixedSizeAlignedSecBlock<unsigned int, 60u, true>::~FixedSizeAlignedSecBlock (this=0x7fffffffc930, 
    __in_chrg=<optimized out>) at /usr/include/crypto++/secblock.h:429
#9  0x000000000045a4ac in CryptoPP::Rijndael::Base::~Base (
    this=0x7fffffffc918, __in_chrg=<optimized out>)
    at /usr/include/crypto++/rijndael.h:21
#10 0x000000000045a544 in CryptoPP::Rijndael::Enc::~Enc (this=0x7fffffffc918, 
    __in_chrg=<optimized out>) at /usr/include/crypto++/rijndael.h:40
#11 0x000000000045a5d0 in CryptoPP::ClonableImpl<CryptoPP::BlockCipherFinal<(CryptoPP::CipherDir)0, CryptoPP::Rijndael::Enc>, CryptoPP::Rijndael::Enc>::~ClonableImpl (this=0x7fffffffc918, __in_chrg=<optimized out>)
    at /usr/include/crypto++/simple.h:16
#12 0x000000000045a65c in CryptoPP::BlockCipherFinal<(CryptoPP::CipherDir)0, CryptoPP::Rijndael::Enc>::~BlockCipherFinal (this=0x7fffffffc918, 
---Type <return> to continue, or q <return> to quit---
    __in_chrg=<optimized out>) at /usr/include/crypto++/seckey.h:151
#13 0x000000000045a6da in CryptoPP::ObjectHolder<CryptoPP::BlockCipherFinal<(CryptoPP::CipherDir)0, CryptoPP::Rijndael::Enc> >::~ObjectHolder (
    this=0x7fffffffc918, __in_chrg=<optimized out>)
    at /usr/include/crypto++/misc.h:83
#14 0x000000000045bd76 in CryptoPP::CipherModeFinalTemplate_CipherHolder<CryptoPP::BlockCipherFinal<(CryptoPP::CipherDir)0, CryptoPP::Rijndael::Enc>, CryptoPP::CBC_Encryption>::~CipherModeFinalTemplate_CipherHolder (this=0x7fffffffc8d0, 
    __in_chrg=<optimized out>) at /usr/include/crypto++/modes.h:248
#15 0x0000000000457198 in Crypter::encrypt (key=..., IV=..., plain=..., 
    padding=CryptoPP::BlockPaddingSchemeDef::NO_PADDING) at crypter.cpp:143
#16 0x0000000000456836 in Crypter::encode (key=..., IV=..., salt=..., KGK=..., 
    data=..., compress=true) at crypter.cpp:90

I tried to build the code with the crypto++ lib that is packaged in Ubuntu 15.04:
http://packages.ubuntu.com/vivid/libcrypto++-dev

There is also a version of crypto++ packaged in the application but want to use the system's lib.
The maintainer of the app does not want to support other versions. This is why I am asking for support here.

Clang integrated assembler and "unknown token in expression"

integer.cpp:542:2: error: unknown token in expression
        AS1(    neg             %1)
        ^
./cpu.h:220:17: note: expanded from macro 'AS1'
        #define AS1(x) GNU_AS1(x)
                       ^
./cpu.h:215:24: note: expanded from macro 'GNU_AS1'
        #define GNU_AS1(x) "\n\t" #x ";"
                              ^
<inline asm>:3:6: note: instantiated into assembly here
        neg %rcx;
            ^
integer.cpp:542:2: error: unknown token in expression
        AS1(    neg             %1)
        ^
./cpu.h:220:17: note: expanded from macro 'AS1'
        #define AS1(x) GNU_AS1(x)
                       ^
./cpu.h:215:24: note: expanded from macro 'GNU_AS1'
        #define GNU_AS1(x) "\n\t" #x ";"
                              ^
<inline asm>:3:6: note: instantiated into assembly here
        neg %rcx;
            ^

This looks exactly like the missing operand size discussed at Clang Inline Assembly and Compatibility.

WaitObjectsTracer causes dirty compile under VS2015

Maximilian Zamorsky reports WaitObjectsTracer causes dirty compile under VS2015:

1>  network.cpp
1>...\cryptopp\wait.h(141): error C2220: warning treated as error - no 'object' file generated
1>...\cryptopp\wait.h(141): warning C4589: Constructor of abstract class 'WaitObjectsTracer' ignores initializer for virtual base class 'Tracer'
1>  ...\cryptopp\wait.h(141): note: to simplify migration, consider the temporary use of /Wv:18 flag with the version of the compiler with which you used to build without warnings
1>  ...\cryptopp\wait.h(141): note: virtual base classes are only initialized by the most-derived type

This appears to be a bug in Visual Studio 2015; see VS 2015 generates a copy constructor and then complains about it on Microsoft Connect.

Configuration failure under S/390{x}

László Böszörményi of Debian helped with some cross validation testing. Building the library under a S/390/chroot on Debian x86_64 results in a configuration failure. There were actually two failures - one was reported, the other was silent.


The first reported failure was a failure to detect the big endian platform:

FAILED:  Your machine is big endian.
passed:  CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS is not defined. Will
restrict to aligned data access.
passed:  sizeof(byte) == 1
passed:  sizeof(word16) == 2
passed:  sizeof(word32) == 4
passed:  sizeof(word64) == 8
passed:  sizeof(hword) == 2, sizeof(word) == 4, sizeof(dword) == 8
Some critical setting in config.h is in error.  Please fix it and recompile.
Aborted

The fix was easy enough: add the following to config.h for the platform:

// define this if running on a big-endian CPU
#if !defined(IS_LITTLE_ENDIAN) && (defined(__BIG_ENDIAN__) || (defined(__s390__) || defined(__s390x__) || defined(__zarch__)) || ... || defined(__ARMEB__) || (defined(__MWERKS__) && !defined(__INTEL__)))
#   define IS_BIG_ENDIAN
#endif

We also added the following to produce a hardstop in the future under certain somewhat known conditions:

// Sanity checks. Some processors have more than big-, little- and bi-endian modes. PDP mode, where order results in "4312", should
//   raise red flags immediately. Additionally, mis-classified machines, like (previosuly) S/390, should raise red flags immediately.
#if defined(IS_BIG_ENDIAN) && defined(__GNUC__) && defined(__BYTE_ORDER__) && (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__)
# error "IS_BIG_ENDIAN is set, but __BYTE_ORDER__  does not equal __ORDER_BIG_ENDIAN__"
#endif
#if defined(IS_LITTLE_ENDIAN) && defined(__GNUC__) && defined(__BYTE_ORDER__) && (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__)
# error "IS_LITTLE_ENDIAN is set, but __BYTE_ORDER__  does not equal __ORDER_LITTLE_ENDIAN__"
#endif

The second unreported issue was a failure to detect the availability of int128_t and uint128_t on S/390. It means the "Slow Word" integers would be used, which could negatively impact performance. It was caught through an additional sanity check added to config.h:

// Detect availabliltiy of int128_t and unint128_t in preprocessor, http://gcc.gnu.org/ml/gcc-help/2015-08/msg00185.html.
// Produce a compiler error. It can be commented out, but you may not get the benefit of of faster native integers.
#if (__SIZEOF_INT128__ >= 16) && !defined(CRYPTOPP_WORD128_AVAILABLE)
# error "An int128_t and uint128_t are available, but CRYPTOPP_WORD128_AVAILABLE is not defined"
#endif

Missing Git tags

Add missing git tags for a few of the latest releases:

  • 5.4
  • 5.5.2
  • 5.6.0
  • 5.6.1
  • 5.6.2

Adding 5.6.2 tag:

git checkout 789f81f048c9bc472c7e7596f49b02eadd6fc1fd
git tag -a v5.6.2 -m 'version 5.6.2'

filters.cpp and undefined behavior

filters.cpp generates the following findings under UBsan.

$ make ubsan
$ ./cryptest.exe v | grep error

A smaller (but inclusive) list is generated with ./cryptest.exe tv all | grep error.


Fedora 22, i386 (GCC 5.1):

filters.cpp:519:84: runtime error: null pointer passed as argument 1, which is declared to never be null
filters.cpp:291:28: runtime error: null pointer passed as argument 1, which is declared to never be null
filters.cpp:280:39: runtime error: null pointer passed as argument 1, which is declared to never be null
filters.cpp:280:39: runtime error: null pointer passed as argument 2, which is declared to never be null
filters.cpp:281:50: runtime error: null pointer passed as argument 1, which is declared to never be null
filters.cpp:281:50: runtime error: null pointer passed as argument 2, which is declared to never be null
filters.cpp:677:35: runtime error: null pointer passed as argument 2, which is declared to never be null

Zeroizer may be removed if assembler is not available

This apples to the library in general, and the intersection of assemblers and compilers. It was recently brought to light with Clang testing.

Clang has an integrated assembler that's not quite as mature as it needs to be. There are 5 or 6 LLVM bugs that affect Crypto++ (cf., 18916, 24200, 24226, 24232 and a few others). When the assembler is disabled, the library disables the inline assembly code paths that perform the zeroization and leave it to C++ statements.

C++ statements with volatile are somewhat ambiguous because the meaning of volatile is not well defined in the standard. See, for example, Ian Lance Taylor's blog at http://www.airs.com/blog/archives/154. In fact, the Crypto++ code has comments regarding work arounds due to GCC optimizing out a write of 0 on occasion.

Crash in SHA under iOS 5.1.1

$ . ./setenv-ios.sh
$ make -f GNUmakefile-cross 
clang++ -DNDEBUG -g2 -Os -mios-version-min=5.1 -DCRYPTOPP_NO_UNALIGNED_DATA_ACCESS -DCRYPTOPP_DISABLE_ASM
-arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk
-stdlib=libc++ -c cryptlib.cpp
...

JWs-iPad:~/cryptopp563 root# ./cryptest.exe tv sha
Using seed: 1443896312     

Testing MessageDigest algorithm SHA-1.
...
Testing MessageDigest algorithm SHA-224.
...
Testing MessageDigest algorithm SHA-256.
...
Testing MessageDigest algorithm SHA-384.
...Abort trap: 6

BlumBlumShub validation fails under ARMEL (likely others)

László Böszörményi of Debian helped with some cross validation testing. Building the library under a ARMEL/chroot on Debian x86_64 produces the following results:

BlumBlumShub validation suite running...

passed    49ea2cfdb01064a0bbb92af101dac18a94f7b7ce
FAILED    53171c6887956cea5d3b
cryptest.exe: integer.cpp:2210: void CryptoPP::MultiplyTop(CryptoPP::word*, CryptoPP::word*, const word*, const word*, const word*, size_t):
Assertion `c3 >= 0 && c3 <= 2' failed.
uncaught target signal 6 (Aborted) - core dumped
Aborted

The assert is due lack of -DNDEBUG, and it is expected in this case.

Böszörményi tried both Crypto++ 5.6.1 with patches (which effectively makes it roughly 5.6.2) and Crypto++ 5.6.3. The results were reproduced under 5.6.3 RC1 candidate as well.


The following configurations fail to reproduce the issue. Each configuration is tested after a make clean to ensure artifacts don't cross pollinate.

  • export CXXFLAGS="-DDEBUG -g3 -Og"
  • export CXXFLAGS="-g3 -Og"
  • export CXXFLAGS="-g3 -O1"

The issue can be reproduced with:

  • export CXXFLAGS="-g3 -O2"
  • export CXXFLAGS="-g3 -O3"

The presence of -DDEBUG tells the makefile to enlist GXXLIB's debug and concept checks. In this case, two additional defines are defined: -D_GLIBCXX_DEBUG and -D_GLIBCXX_CONCEPT_CHECKS.

The presence of -O3 tells the makefile to add -DCRYPTOPP_NO_UNALIGNED_DATA_ACCESS, which forbids unaligned data access (which is undefined behavior in C/C++). The __NO__ define ensures CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS is not defined. Aligned data access is effect all the time on this platform, regardless of -DCRYPTOPP_NO_UNALIGNED_DATA_ACCESS. It can be verified by inspecting the head of cryptest.exe v output and the message (similar to) "unaligned data access is not allowed...". The results have been verified with UBsan, Asan and Valgrind.

Use of auto_ptr causes dirty compile under C++11

Opened to tend to all issues related to dirty compiles due to use of auto_ptr and C++011. It includes Issue 17.

Bug 17 cleared the issue under Cygwin by using a lot of define magic to determine when C++ 11 was _really_ available, and then switched to a unique_ptr if C++11 was really available. Its correct, but it might not be the easiest way to get there.

Denis provided an insightful observation in Issue 17, but it was kind of lost upon us as we rushed to use C++ language features to solve the problem. The problem was more cleanly solved...

We found we could simply use member_ptr from smartptr.h. member_ptr (1) provides the basic functionality we need, and (2) provides reset and release. member_ptr allows us to (3) forgo all the additional logic need to determine when unique_ptr was _really_ available, and (4) forgo the using auto_ptr = unique_ptr<T> template declaration.

Need extensible way to handle Clang Integrated Assembler/LLVM Issues 18916 and 24200

Issue 18916: https://llvm.org/bugs/show_bug.cgi?id=18916
Issue 24200: https://llvm.org/bugs/show_bug.cgi?id=24200

LLVM will eventually fix the 18916 issue (".intel_syntax noprefix;" and ".att_syntax prefix;"). If they fix it in a forward compatible way, then we can just leave WORKAROUND_LLVM_BUG_18916 in effect and things will "just work". If its not a forward fix, then we can guard with a define like CRYPTOPP_CLANG_41_OR_EARLIER once we know when its available. So it should not be a problem either way.

The 24200 issue is going to be trickier because we need to know when to switch to fixes for Clang Integrated Assembler in the source code (and not the GNUmakefile). The source code is guarded with CRYPTOPP_USING_CLANG_INTEGRATED_ASSEMBLER, but we won't know when to activate it.

The first problem with 24200 is the only way I am aware to determine when Clang's assembler is being used is through the compiler driver. If we get the clang: error... string, then its the integrated assembler.

$ clang++ -xc -c /dev/null -Wa,-v -o/dev/null 2>&1
clang: error: unsupported argument '-v' to option 'Wa,'

The second issue with 24200 is the Integrated Assembler can be switched off (https://stackoverflow.com/questions/11118887/how-to-switch-off-llvms-integrated-assembler), but we don't know how to test for it. Ideally, there would be a #define available, but it appears there is none. Confer, "Determine Clang Assembler versus System Assembler at compile time?", http://lists.cs.uiuc.edu/pipermail/cfe-users/2015-July/000719.html.

Maybe we will be able to test in the makefile, and then define/undefine CRYPTOPP_USING_CLANG_INTEGRATED_ASSEMBLER using sed. This way, config.h stays in sync with the actual build tools and settings.

Tests fail on MinGW-32

On MinGW-32, the cryptest.exe v with CRYPTOPP_NO_UNALIGNED_ACCESS defined crashes with SIGSEGV:

Using seed: 1438287574


Testing Settings...

passed:  Your machine is little endian.
passed:  CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS is not defined. Will restrict to a
ligned data access.
passed:  sizeof(byte) == 1
passed:  sizeof(word16) == 2
passed:  sizeof(word32) == 4
passed:  sizeof(word64) == 8
passed:  sizeof(hword) == 2, sizeof(word) == 4, sizeof(dword) == 8

Testing rotate...

passed    left rotate
passed    right rotate

Testing conversions...

passed    signed char
passed    signed char overflow
passed    unsigned char
passed    unsigned char overflow
passed    signed short
passed    signed short overflow
passed    unsigned short
passed    unsigned short overflow
passed    signed int
passed    signed int overflow
passed    unsigned int
passed    unsigned int overflow
passed    signed long
passed    signed long overflow
passed    unsigned long
passed    unsigned long overflow
passed    signed long long
passed    unsigned long long
passed    ssize_t
passed    size_t

No operating system provided blocking random number generator, skipping test.

Testing operating system provided nonblocking random number generator...

passed:  100000 generated bytes compressed to 100020 bytes by DEFLATE

CRC-32 validation suite running...

passed   00000000   ""
passed   43beb7e8   "a"
passed   c2412435   "abc"
passed   7f9d1520   "message digest"
passed   bd50274c   "abcdefghijklmnopqrstuvwxyz"
passed   d2e6c21f   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456
789"
passed   724aa97c   "12345678901234567890123456789012345678901234567890123456789
012345678901234567890"
passed   2639f4cb   "123456789"

Adler-32 validation suite running...

passed   00000001   ""
passed   00620062   "a"
passed   024d0127   "abc"
passed   29750586   "message digest"
passed   90860b20   "abcdefghijklmnopqrstuvwxyz"
passed   8adb150c   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456
789"
passed   15d870f9   "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaa" repeated 15625 times

MD2 validation suite running...

passed   8350e5a3e24c153df2275c9f80692773   ""
passed   32ec01ec4a6dac72c0ab96fb34c0b5d1   "a"
passed   da853b0d3f88d99b30283a69e6ded6bb   "abc"
passed   ab4f496bfb2a530b219ff33031fe06b0   "message digest"
passed   4e8ddff3650292ab5a4108c3aa47940b   "abcdefghijklmnopqrstuvwxyz"
passed   da33def2a42df13975352846c30338cd   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi
jklmnopqrstuvwxyz0123456789"
passed   d5976f79d83d3a0dc9806c3c66f3efd8   "12345678901234567890123456789012345
678901234567890123456789012345678901234567890"

MD5 validation suite running...

passed   d41d8cd98f00b204e9800998ecf8427e   ""
passed   0cc175b9c0f1b6a831c399e269772661   "a"
passed   900150983cd24fb0d6963f7d28e17f72   "abc"
passed   f96b697d7cb7938d525a2f31aaf161d0   "message digest"
passed   c3fcd3d76192e4007dfb496cca67e13b   "abcdefghijklmnopqrstuvwxyz"
passed   d174ab98d277d9f5a5611c2c9f419d9f   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghi
jklmnopqrstuvwxyz0123456789"
passed   57edf4a22be3c955ac49da2e2107b67a   "12345678901234567890123456789012345
678901234567890123456789012345678901234567890"

SHA validation suite running...


Testing MessageDigest algorithm SHA-1.

Program received signal SIGSEGV, Segmentation fault.
0x004f8ebc in __chkstk_ms ()
(gdb) backtrace
#0  0x004f8ebc in __chkstk_ms ()
#1  0x00497c57 in CryptoPP::Rijndael::Enc::AdvancedProcessBlocks (
    this=this@entry=0x7b10d0 <s_globalRNG+48>,
    inBlocks=inBlocks@entry=0x2e92990 "1438287574",
    xorBlocks=xorBlocks@entry=0x0,
    outBlocks=outBlocks@entry=0x2e982e0 "\rр-є\rр-є\rр-є\rр-є<<<<<<<<",
    length=length@entry=16, flags=flags@entry=0) at rijndael.cpp:1215
#2  0x004988ab in CryptoPP::Rijndael::Enc::ProcessAndXorBlock (
    this=0x7b10d0 <s_globalRNG+48>, inBlock=0x2e92990 "1438287574",
    xorBlock=0x0, outBlock=0x2e982e0 "\rр-є\rр-є\rр-є\rр-є<<<<<<<<")
    at rijndael.cpp:365
#3  0x004a7f75 in ProcessBlock (
    outBlock=0x2e982e0 "\rр-є\rр-є\rр-є\rр-є<<<<<<<<",
    inBlock=<optimized out>, this=<optimized out>) at cryptlib.h:470
#4  CryptoPP::OFB_ModePolicy::WriteKeystream (this=0x7b10a0 <s_globalRNG>,
    keystreamBuffer=0x2e982e0 "\rр-є\rр-є\rр-є\rр-є<<<<<<<<",
    iterationCount=1) at modes.cpp:84
#5  0x0055d4b5 in CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolde
r<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::GenerateB
lock (this=0x7b10a0 <s_globalRNG>, outString=0x28def0 "", length=4)
    at strciphr.cpp:61
#6  0x0043ce87 in CryptoPP::RandomNumberGenerator::GenerateWord32 (
    this=0x7b10bc <s_globalRNG+28>, min=0, max=63) at cryptlib.cpp:263
#7  0x0042c440 in RandomizedTransfer (source=..., target=..., channel=...,
    finish=true) at datatest.cpp:69
#8  0x0042d704 in _fu94___ZNSs4_Rep20_S_empty_rep_storageE ()
    at datatest.cpp:123
#9  0x00430cac in _fu2426___ZTIi () at datatest.cpp:573
#10 0x00432bfb in _fu871___ZSt4cout () at datatest.cpp:716
#11 0x00432fa5 in RunTestDataFile (
    filename=filename@entry=0x64267f <ValidateBBS()::output1+1457> "TestVectors/
sha.txt", overrideParameters=..., thorough=thorough@entry=true)
    at datatest.cpp:755
#12 0x0042925c in _fu800___ZSt4cout () at validat3.cpp:173
#13 0x00419db5 in ValidateAll (thorough=thorough@entry=false)
    at validat1.cpp:61
#14 0x0040b61d in _fu523___ZSt4cout () at test.cpp:847
#15 0x00605f89 in _fu2814___ZSt3cin () at test.cpp:367

Dump file (if it helps)


cryptest.exe tv all crashes on Testing SymmetricCipher algorithm TEA/ECB. The problem seems to be the same.
Here is the call stack:

Testing FileList algorithm all.txt collection.

Testing SymmetricCipher algorithm TEA/ECB.

Program received signal SIGSEGV, Segmentation fault.
0x004f920c in __chkstk_ms ()
(gdb) backtrace
#0  0x004f920c in __chkstk_ms ()
#1  0x00497fa7 in CryptoPP::Rijndael::Enc::AdvancedProcessBlocks (
    this=this@entry=0x7b10d0 <GlobalRNG()::s_globalRNG+48>,
    inBlocks=inBlocks@entry=0x2ca7dd0 "1438330210",
    xorBlocks=xorBlocks@entry=0x0,
    outBlocks=outBlocks@entry=0x2ca8390 "\rр-є\rр-є\rр-є\rр-є<<<<<<<<",
    length=length@entry=16, flags=flags@entry=0) at rijndael.cpp:1215
#2  0x00498bfb in CryptoPP::Rijndael::Enc::ProcessAndXorBlock (
    this=0x7b10d0 <GlobalRNG()::s_globalRNG+48>,
    inBlock=0x2ca7dd0 "1438330210", xorBlock=0x0,
    outBlock=0x2ca8390 "\rр-є\rр-є\rр-є\rр-є<<<<<<<<") at rijndael.cpp:365
#3  0x004a82c5 in ProcessBlock (
    outBlock=0x2ca8390 "\rр-є\rр-є\rр-є\rр-є<<<<<<<<",
    inBlock=<optimized out>, this=<optimized out>) at cryptlib.h:470
#4  CryptoPP::OFB_ModePolicy::WriteKeystream (
    this=0x7b10a0 <GlobalRNG()::s_globalRNG>,
    keystreamBuffer=0x2ca8390 "\rр-є\rр-є\rр-є\rр-є<<<<<<<<",
    iterationCount=1) at modes.cpp:84
#5  0x0055d805 in CryptoPP::AdditiveCipherTemplate<CryptoPP::AbstractPolicyHolde
r<CryptoPP::AdditiveCipherAbstractPolicy, CryptoPP::OFB_ModePolicy> >::GenerateB
lock (this=0x7b10a0 <GlobalRNG()::s_globalRNG>, outString=0x28dba0 "",
    length=4) at strciphr.cpp:61
#6  0x0043d1d7 in CryptoPP::RandomNumberGenerator::GenerateWord32 (
    this=0x7b10bc <GlobalRNG()::s_globalRNG+28>, min=0, max=63)
    at cryptlib.cpp:263
#7  0x0042c790 in RandomizedTransfer (source=..., target=..., channel=...,
    finish=true) at datatest.cpp:69
#8  0x0042da54 in _fu94___ZNSs4_Rep20_S_empty_rep_storageE ()
    at datatest.cpp:123
#9  0x0042e363 in _fu95___ZNSs4_Rep20_S_empty_rep_storageE ()
    at datatest.cpp:129
#10 0x0042e403 in TestSymmetricCipher (v=..., overrideParameters=...)
    at datatest.cpp:328
#11 0x00432cce in _fu870___ZSt4cout () at datatest.cpp:710
#12 0x004330c4 in _fu871___ZSt4cout () at datatest.cpp:720
#13 0x004332f5 in RunTestDataFile (filename=0x2ca849c "TestVectors/all.txt",
    overrideParameters=..., thorough=thorough@entry=true) at datatest.cpp:755
#14 0x00605473 in _fu2781___ZSt4cerr () at test.cpp:315

Steps to reproduce:

  1. Install MinGW-32 with GCC 4.8.1, as in my case. Seems to be the latest MinGW-32. Don't forget about MSYS.
  2. Run gdb --args ./cryptest.exe v or gdb --args ./cryptest.exe tv all in MSYS console
  3. Finally, execute run in GDB console. You'll see the program output till the crash and the crash information.
  4. Type backtrace to get the stack trace.
  5. After all, type kill and quit to stop debugging.

Or simply run cryptest.exe v to get Windows's crash message.


Environment information:
uname -a:

MINGW32_NT-6.1 ИЛЬЯ-ПК 1.0.18(0.48/3/2) 2012-11-21 22:34 i686 Msys

g++ -v:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.8.1/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32 --build=mingw32 --without-pic --enable-shared --enable-static --with-gnu-ld --enable-lto --enable-libssp --disable-multilib --enable-languages=c,c++,fortran,objc,obj-c++,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32-registry --enable-libstdcxx-debug --enable-version-specific-runtime-libs --with-gmp=/usr/src/pkg/gmp-5.1.2-1-mingw32-src/bld --with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld --with-mpfr= --with-system-zlib --with-gnu-as --enable-decimal-float=yes --enable-libgomp --enable-threads --with-libiconv-prefix=/mingw32 --with-libintl-prefix=/mingw --disable-bootstrap LDFLAGS=-s CFLAGS=-D_USE_32BIT_TIME_T
Thread model: win32
gcc version 4.8.1 (GCC)

To build the library, I simply uncomment the line with CRYPTOPP_NO_UNALLIGNED_ACCESS in config.h and then run make.

A problem with random generator on MinGW

This code causes a segmentation fault:

unsigned int result;
GenerateBlock((byte*)&result, sizeof(unsigned int));

Here is the call stack (image, as I cannot copy text from Code::Blocks call stack window):
Call stack
This problem may be caused by issue 26.

ECIES uses byte count, and not bit count, for label size

This issue was originally investigated and reported by Jesse Wilson and Daniele Perito at Problem with the way gfpcrypt HMAC's the encoding parameters' length in DHAES_MODE. Since that time, David Hook of the Bouncy Castle project investigated further and found another interop issue: Crypto++'s ECIES should use a bit count for the label, and not a byte count.

The issue was confirmed by cross referencing both P1363, revision 13 and subsequent P1363 2000 publications.

This report creates an actionable item for tracking.

MinGW cannot compile the library due to missing symbol MinGW _hypot

make
...
g++ -DNDEBUG -std=c++03 -g3 -O1  -march=native -pipe -c nbtheory.cpp
In file included from nbtheory.cpp:14:0:
c:\mingw\include\math.h: In function 'float hypotf(float, float)':
c:\mingw\include\math.h:635:30: error: '_hypot' was not declared in this scope
     { return (float)(_hypot (x, y)); }
                              ^

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.