2017-01-27 12:05:45 +00:00
// test.cpp - originally written and placed in the public domain by Wei Dai
2017-02-21 07:03:29 +00:00
// CryptoPP::Test namespace added by JW in February 2017
2017-07-23 20:20:52 +00:00
// scoped_main added to CryptoPP::Test namespace by JW in July 2017
// Also see http://github.com/weidai11/cryptopp/issues/447
2015-11-05 06:59:46 +00:00
# define CRYPTOPP_DEFAULT_NO_DLL
# define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
# include "dll.h"
# include "cryptlib.h"
2018-07-10 21:08:13 +00:00
# include "aes.h"
2015-11-05 06:59:46 +00:00
# include "filters.h"
# include "md5.h"
# include "ripemd.h"
# include "rng.h"
# include "gzip.h"
# include "default.h"
# include "randpool.h"
# include "ida.h"
# include "base64.h"
# include "factory.h"
# include "whrlpool.h"
# include "tiger.h"
# include "smartptr.h"
2017-08-16 16:21:07 +00:00
# include "pkcspad.h"
2017-03-08 21:59:24 +00:00
# include "stdcpp.h"
2018-07-10 21:08:13 +00:00
# include "osrng.h"
2016-09-17 16:23:02 +00:00
# include "ossig.h"
2016-09-16 15:27:15 +00:00
# include "trap.h"
2015-11-05 06:59:46 +00:00
# include "validate.h"
# include "bench.h"
# include <iostream>
2015-11-18 20:32:28 +00:00
# include <sstream>
# include <locale>
2019-08-05 07:51:58 +00:00
# include <cstdlib>
2017-03-08 21:59:24 +00:00
# include <ctime>
2015-11-05 06:59:46 +00:00
# ifdef CRYPTOPP_WIN32_AVAILABLE
2016-04-28 05:05:47 +00:00
# define WIN32_LEAN_AND_MEAN
2015-11-05 06:59:46 +00:00
# include <windows.h>
# endif
2019-01-03 04:43:44 +00:00
# if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_BSD_AVAILABLE)
# include <sys/types.h>
# include <sys/stat.h>
# include <unistd.h>
# define UNIX_PATH_FAMILY 1
# endif
# if defined(CRYPTOPP_OSX_AVAILABLE)
# include <sys/types.h>
# include <sys/stat.h>
# include <unistd.h>
# include <mach-o/dyld.h>
# define UNIX_PATH_FAMILY 1
# endif
2023-06-25 22:28:11 +00:00
# if (CRYPTOPP_MSC_VERSION >= 1000)
2015-11-05 06:59:46 +00:00
# include <crtdbg.h> // for the debug heap
# endif
# if defined(__MWERKS__) && defined(macintosh)
# include <console.h>
# endif
# ifdef _OPENMP
# include <omp.h>
# endif
# ifdef __BORLANDC__
# pragma comment(lib, "cryptlib_bds.lib")
# endif
// Aggressive stack checking with VS2005 SP1 and above.
2017-05-11 16:05:57 +00:00
# if (_MSC_FULL_VER >= 140050727)
2015-11-05 06:59:46 +00:00
# pragma strict_gs_check (on)
# endif
2018-07-10 21:08:13 +00:00
// If CRYPTOPP_USE_AES_GENERATOR is 1 then AES/OFB based is used.
// Otherwise the OS random number generator is used.
# define CRYPTOPP_USE_AES_GENERATOR 1
2017-07-23 20:20:52 +00:00
// Global namespace, provided by other source files
void FIPS140_SampleApplication ( ) ;
void RegisterFactories ( CryptoPP : : Test : : TestClass suites ) ;
int ( * AdhocTest ) ( int argc , char * argv [ ] ) = NULLPTR ;
NAMESPACE_BEGIN ( CryptoPP )
NAMESPACE_BEGIN ( Test )
2015-11-05 06:59:46 +00:00
2019-08-05 07:51:58 +00:00
const int MAX_PHRASE_LENGTH = 250 ;
const int GLOBAL_SEED_LENGTH = 16 ;
2019-01-02 08:30:49 +00:00
std : : string g_argvPathHint = " " ;
2015-11-05 06:59:46 +00:00
void GenerateRSAKey ( unsigned int keyLength , const char * privFilename , const char * pubFilename , const char * seed ) ;
2017-02-21 07:03:29 +00:00
std : : string RSAEncryptString ( const char * pubFilename , const char * seed , const char * message ) ;
std : : string RSADecryptString ( const char * privFilename , const char * ciphertext ) ;
2015-11-05 06:59:46 +00:00
void RSASignFile ( const char * privFilename , const char * messageFilename , const char * signatureFilename ) ;
bool RSAVerifyFile ( const char * pubFilename , const char * messageFilename , const char * signatureFilename ) ;
void DigestFile ( const char * file ) ;
void HmacFile ( const char * hexKey , const char * file ) ;
void AES_CTR_Encrypt ( const char * hexKey , const char * hexIV , const char * infile , const char * outfile ) ;
2017-02-21 07:03:29 +00:00
std : : string EncryptString ( const char * plaintext , const char * passPhrase ) ;
std : : string DecryptString ( const char * ciphertext , const char * passPhrase ) ;
2015-11-05 06:59:46 +00:00
void EncryptFile ( const char * in , const char * out , const char * passPhrase ) ;
void DecryptFile ( const char * in , const char * out , const char * passPhrase ) ;
void SecretShareFile ( int threshold , int nShares , const char * filename , const char * seed ) ;
void SecretRecoverFile ( int threshold , const char * outFilename , char * const * inFilenames ) ;
void InformationDisperseFile ( int threshold , int nShares , const char * filename ) ;
void InformationRecoverFile ( int threshold , const char * outFilename , char * const * inFilenames ) ;
void GzipFile ( const char * in , const char * out , int deflate_level ) ;
void GunzipFile ( const char * in , const char * out ) ;
void Base64Encode ( const char * infile , const char * outfile ) ;
void Base64Decode ( const char * infile , const char * outfile ) ;
void HexEncode ( const char * infile , const char * outfile ) ;
void HexDecode ( const char * infile , const char * outfile ) ;
void FIPS140_GenerateRandomFiles ( ) ;
2019-08-05 07:51:58 +00:00
bool Validate ( int , bool ) ;
bool SetGlobalSeed ( int argc , char * argv [ ] , std : : string & seed ) ;
2019-01-03 01:22:55 +00:00
void SetArgvPathHint ( const char * argv0 , std : : string & pathHint ) ;
2018-07-10 13:21:52 +00:00
2017-02-21 07:03:29 +00:00
ANONYMOUS_NAMESPACE_BEGIN
2018-07-10 13:21:52 +00:00
# if (CRYPTOPP_USE_AES_GENERATOR)
2017-02-21 07:03:29 +00:00
OFB_Mode < AES > : : Encryption s_globalRNG ;
2018-07-10 13:21:52 +00:00
# else
2018-07-10 21:08:13 +00:00
NonblockingRng s_globalRNG ;
2018-07-10 13:21:52 +00:00
# endif
2017-02-21 07:03:29 +00:00
NAMESPACE_END
2015-11-05 06:59:46 +00:00
RandomNumberGenerator & GlobalRNG ( )
{
return dynamic_cast < RandomNumberGenerator & > ( s_globalRNG ) ;
}
2018-07-10 21:08:13 +00:00
// Global seed used for the self tests
std : : string s_globalSeed ;
void PrintSeedAndThreads ( ) ;
2016-09-16 15:27:15 +00:00
// See misc.h and trap.h for comments and usage
2016-10-18 02:00:31 +00:00
# if defined(CRYPTOPP_DEBUG) && defined(UNIX_SIGNALS_AVAILABLE)
2016-09-16 15:27:15 +00:00
static const SignalHandler < SIGTRAP , false > s_dummyHandler ;
2016-10-10 22:03:31 +00:00
// static const DebugTrapHandler s_dummyHandler;
2016-09-16 15:27:15 +00:00
# endif
2017-07-23 20:20:52 +00:00
int scoped_main ( int argc , char * argv [ ] )
2015-11-05 06:59:46 +00:00
{
# ifdef _CRTDBG_LEAK_CHECK_DF
// Turn on leak-checking
int tempflag = _CrtSetDbgFlag ( _CRTDBG_REPORT_FLAG ) ;
tempflag | = _CRTDBG_LEAK_CHECK_DF ;
_CrtSetDbgFlag ( tempflag ) ;
# endif
2018-09-12 17:06:28 +00:00
# ifdef _SUNPRO_CC
// No need for thread safety for the test program
cout . set_safe_flag ( stream_MT : : unsafe_object ) ;
cin . set_safe_flag ( stream_MT : : unsafe_object ) ;
# endif
2015-11-05 06:59:46 +00:00
try
2016-04-28 05:05:47 +00:00
{
2017-07-23 20:20:52 +00:00
RegisterFactories ( All ) ;
2015-11-05 06:59:46 +00:00
2019-08-05 07:51:58 +00:00
// A hint to help locate TestData/ and TestVectors/ after install.
SetArgvPathHint ( argv [ 0 ] , g_argvPathHint ) ;
2019-08-07 01:01:22 +00:00
// Set a seed for reproducible results. If the seed is too short then
// it is padded with spaces. If the seed is missing then time() is used.
2019-08-05 07:51:58 +00:00
// For example:
// ./cryptest.exe v seed=abcdefg
SetGlobalSeed ( argc , argv , s_globalSeed ) ;
2015-11-05 06:59:46 +00:00
2018-07-10 13:21:52 +00:00
# if (CRYPTOPP_USE_AES_GENERATOR)
2018-07-11 10:59:44 +00:00
// Fetch the SymmetricCipher interface, not the RandomNumberGenerator
2018-07-10 21:08:13 +00:00
// interface, to key the underlying cipher. If CRYPTOPP_USE_AES_GENERATOR is 1
// then AES/OFB based is used. Otherwise the OS random number generator is used.
2018-07-11 10:59:44 +00:00
SymmetricCipher & cipher = dynamic_cast < SymmetricCipher & > ( GlobalRNG ( ) ) ;
2019-08-05 07:51:58 +00:00
cipher . SetKeyWithIV ( ( byte * ) s_globalSeed . data ( ) , s_globalSeed . size ( ) , ( byte * ) s_globalSeed . data ( ) ) ;
2018-07-10 13:21:52 +00:00
# endif
2015-11-05 06:59:46 +00:00
std : : string command , executableName , macFilename ;
if ( argc < 2 )
2022-08-24 05:07:25 +00:00
command = " X-help " ;
2015-11-05 06:59:46 +00:00
else
command = argv [ 1 ] ;
if ( command = = " g " )
{
char thisSeed [ 1024 ] , privFilename [ 128 ] , pubFilename [ 128 ] ;
unsigned int keyLength ;
2017-02-21 07:03:29 +00:00
std : : cout < < " Key length in bits: " ;
std : : cin > > keyLength ;
2015-11-05 06:59:46 +00:00
2017-02-21 07:03:29 +00:00
std : : cout < < " \n Save private key to file: " ;
std : : cin > > privFilename ;
2015-11-05 06:59:46 +00:00
2017-02-21 07:03:29 +00:00
std : : cout < < " \n Save public key to file: " ;
std : : cin > > pubFilename ;
2015-11-05 06:59:46 +00:00
2017-02-21 07:03:29 +00:00
std : : cout < < " \n Random Seed: " ;
std : : ws ( std : : cin ) ;
std : : cin . getline ( thisSeed , 1024 ) ;
2015-11-05 06:59:46 +00:00
GenerateRSAKey ( keyLength , privFilename , pubFilename , thisSeed ) ;
}
else if ( command = = " rs " )
RSASignFile ( argv [ 2 ] , argv [ 3 ] , argv [ 4 ] ) ;
else if ( command = = " rv " )
{
bool verified = RSAVerifyFile ( argv [ 2 ] , argv [ 3 ] , argv [ 4 ] ) ;
2017-02-21 07:03:29 +00:00
std : : cout < < ( verified ? " valid signature " : " invalid signature " ) < < std : : endl ;
2015-11-05 06:59:46 +00:00
}
else if ( command = = " r " )
{
char privFilename [ 128 ] , pubFilename [ 128 ] ;
char thisSeed [ 1024 ] , message [ 1024 ] ;
2017-02-21 07:03:29 +00:00
std : : cout < < " Private key file: " ;
std : : cin > > privFilename ;
2015-11-05 06:59:46 +00:00
2017-02-21 07:03:29 +00:00
std : : cout < < " \n Public key file: " ;
std : : cin > > pubFilename ;
2015-11-05 06:59:46 +00:00
2017-02-21 07:03:29 +00:00
std : : cout < < " \n Random Seed: " ;
std : : ws ( std : : cin ) ;
std : : cin . getline ( thisSeed , 1024 ) ;
2015-11-05 06:59:46 +00:00
2017-02-21 07:03:29 +00:00
std : : cout < < " \n Message: " ;
std : : cin . getline ( message , 1024 ) ;
2015-11-05 06:59:46 +00:00
2017-02-21 07:03:29 +00:00
std : : string ciphertext = RSAEncryptString ( pubFilename , thisSeed , message ) ;
std : : cout < < " \n Ciphertext: " < < ciphertext < < std : : endl ;
2015-11-05 06:59:46 +00:00
2017-02-21 07:03:29 +00:00
std : : string decrypted = RSADecryptString ( privFilename , ciphertext . c_str ( ) ) ;
std : : cout < < " \n Decrypted: " < < decrypted < < std : : endl ;
2015-11-05 06:59:46 +00:00
}
else if ( command = = " mt " )
{
MaurerRandomnessTest mt ;
FileStore fs ( argv [ 2 ] ) ;
fs . TransferAllTo ( mt ) ;
2017-02-21 07:03:29 +00:00
std : : cout < < " Maurer Test Value: " < < mt . GetTestValue ( ) < < std : : endl ;
2015-11-05 06:59:46 +00:00
}
else if ( command = = " mac_dll " )
{
std : : string fname ( argv [ 2 ] ? argv [ 2 ] : " " ) ;
// sanity check on file size
2017-02-21 07:03:29 +00:00
std : : fstream dllFile ( fname . c_str ( ) , std : : ios : : in | std : : ios : : out | std : : ios : : binary ) ;
2015-11-05 06:59:46 +00:00
if ( ! dllFile . good ( ) )
{
2017-02-21 07:03:29 +00:00
std : : cerr < < " Failed to open file \" " < < fname < < " \" \n " ;
2015-11-05 06:59:46 +00:00
return 1 ;
}
std : : ifstream : : pos_type fileEnd = dllFile . seekg ( 0 , std : : ios_base : : end ) . tellg ( ) ;
if ( fileEnd > 20 * 1000 * 1000 )
{
2017-02-21 07:03:29 +00:00
std : : cerr < < " Input file " < < fname < < " is too large " ;
std : : cerr < < " (size is " < < fileEnd < < " ). \n " ;
2015-11-05 06:59:46 +00:00
return 1 ;
}
// read file into memory
unsigned int fileSize = ( unsigned int ) fileEnd ;
SecByteBlock buf ( fileSize ) ;
dllFile . seekg ( 0 , std : : ios_base : : beg ) ;
dllFile . read ( ( char * ) buf . begin ( ) , fileSize ) ;
// find positions of relevant sections in the file, based on version 8 of documentation from http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
2016-01-25 16:39:47 +00:00
word32 coffPos = * ( word16 * ) ( void * ) ( buf + 0x3c ) ;
2015-11-05 06:59:46 +00:00
word32 optionalHeaderPos = coffPos + 24 ;
2016-01-25 16:39:47 +00:00
word16 optionalHeaderMagic = * ( word16 * ) ( void * ) ( buf + optionalHeaderPos ) ;
2015-11-05 06:59:46 +00:00
if ( optionalHeaderMagic ! = 0x10b & & optionalHeaderMagic ! = 0x20b )
{
2017-02-21 07:03:29 +00:00
std : : cerr < < " Target file is not a PE32 or PE32+ image. \n " ;
2015-11-05 06:59:46 +00:00
return 3 ;
}
word32 checksumPos = optionalHeaderPos + 64 ;
word32 certificateTableDirectoryPos = optionalHeaderPos + ( optionalHeaderMagic = = 0x10b ? 128 : 144 ) ;
2016-01-25 16:39:47 +00:00
word32 certificateTablePos = * ( word32 * ) ( void * ) ( buf + certificateTableDirectoryPos ) ;
word32 certificateTableSize = * ( word32 * ) ( void * ) ( buf + certificateTableDirectoryPos + 4 ) ;
2015-11-05 06:59:46 +00:00
if ( certificateTableSize ! = 0 )
2017-02-21 07:03:29 +00:00
std : : cerr < < " Warning: certificate table (IMAGE_DIRECTORY_ENTRY_SECURITY) of target image is not empty. \n " ;
2015-11-05 06:59:46 +00:00
// find where to place computed MAC
byte mac [ ] = CRYPTOPP_DUMMY_DLL_MAC ;
byte * found = std : : search ( buf . begin ( ) , buf . end ( ) , mac + 0 , mac + sizeof ( mac ) ) ;
if ( found = = buf . end ( ) )
{
2017-02-21 07:03:29 +00:00
std : : cerr < < " MAC placeholder not found. The MAC may already be placed. \n " ;
2015-11-05 06:59:46 +00:00
return 2 ;
}
word32 macPos = ( unsigned int ) ( found - buf . begin ( ) ) ;
// compute MAC
member_ptr < MessageAuthenticationCode > pMac ( NewIntegrityCheckingMAC ( ) ) ;
2016-09-16 15:27:15 +00:00
CRYPTOPP_ASSERT ( pMac - > DigestSize ( ) = = sizeof ( mac ) ) ;
2015-11-05 06:59:46 +00:00
MeterFilter f ( new HashFilter ( * pMac , new ArraySink ( mac , sizeof ( mac ) ) ) ) ;
f . AddRangeToSkip ( 0 , checksumPos , 4 ) ;
f . AddRangeToSkip ( 0 , certificateTableDirectoryPos , 8 ) ;
f . AddRangeToSkip ( 0 , macPos , sizeof ( mac ) ) ;
f . AddRangeToSkip ( 0 , certificateTablePos , certificateTableSize ) ;
f . PutMessageEnd ( buf . begin ( ) , buf . size ( ) ) ;
2016-10-02 20:20:25 +00:00
// Encode MAC
2017-02-21 07:03:29 +00:00
std : : string hexMac ;
2016-10-02 20:20:25 +00:00
HexEncoder encoder ;
encoder . Put ( mac , sizeof ( mac ) ) , encoder . MessageEnd ( ) ;
2016-10-02 22:40:28 +00:00
hexMac . resize ( static_cast < size_t > ( encoder . MaxRetrievable ( ) ) ) ;
encoder . Get ( reinterpret_cast < byte * > ( & hexMac [ 0 ] ) , hexMac . size ( ) ) ;
2016-10-02 20:20:25 +00:00
// Report MAC and location
2016-10-02 22:40:28 +00:00
std : : cout < < " Placing MAC " < < hexMac < < " in " < < fname < < " at file offset " < < macPos ;
2016-10-02 20:20:25 +00:00
std : : cout < < " (0x " < < std : : hex < < macPos < < std : : dec < < " ). \n " ;
2015-11-05 06:59:46 +00:00
// place MAC
dllFile . seekg ( macPos , std : : ios_base : : beg ) ;
dllFile . write ( ( char * ) mac , sizeof ( mac ) ) ;
}
else if ( command = = " m " )
DigestFile ( argv [ 2 ] ) ;
else if ( command = = " tv " )
{
2015-12-26 04:50:28 +00:00
// TestDataFile() adds CRYPTOPP_DATA_DIR as required
2015-11-05 06:59:46 +00:00
std : : string fname = ( argv [ 2 ] ? argv [ 2 ] : " all " ) ;
if ( fname . find ( " .txt " ) = = std : : string : : npos )
2018-12-07 19:25:10 +00:00
fname + = " .txt " ;
if ( fname . find ( " TestVectors " ) = = std : : string : : npos )
fname = " TestVectors/ " + fname ;
2016-07-24 23:28:01 +00:00
2018-07-10 21:08:13 +00:00
PrintSeedAndThreads ( ) ;
2017-07-23 20:20:52 +00:00
return ! RunTestDataFile ( fname . c_str ( ) ) ;
2015-11-05 06:59:46 +00:00
}
else if ( command = = " t " )
{
// VC60 workaround: use char array instead of std::string to workaround MSVC's getline bug
char passPhrase [ MAX_PHRASE_LENGTH ] , plaintext [ 1024 ] ;
2017-02-21 07:03:29 +00:00
std : : cout < < " Passphrase: " ;
std : : cin . getline ( passPhrase , MAX_PHRASE_LENGTH ) ;
2015-11-05 06:59:46 +00:00
2017-02-21 07:03:29 +00:00
std : : cout < < " \n Plaintext: " ;
2018-12-07 19:25:10 +00:00
std : : cin . getline ( plaintext , sizeof ( plaintext ) ) ;
2015-11-05 06:59:46 +00:00
2017-02-21 07:03:29 +00:00
std : : string ciphertext = EncryptString ( plaintext , passPhrase ) ;
std : : cout < < " \n Ciphertext: " < < ciphertext < < std : : endl ;
2015-11-05 06:59:46 +00:00
2017-02-21 07:03:29 +00:00
std : : string decrypted = DecryptString ( ciphertext . c_str ( ) , passPhrase ) ;
std : : cout < < " \n Decrypted: " < < decrypted < < std : : endl ;
2015-11-05 06:59:46 +00:00
return 0 ;
}
else if ( command = = " e64 " )
Base64Encode ( argv [ 2 ] , argv [ 3 ] ) ;
else if ( command = = " d64 " )
Base64Decode ( argv [ 2 ] , argv [ 3 ] ) ;
else if ( command = = " e16 " )
HexEncode ( argv [ 2 ] , argv [ 3 ] ) ;
else if ( command = = " d16 " )
HexDecode ( argv [ 2 ] , argv [ 3 ] ) ;
else if ( command = = " e " | | command = = " d " )
{
char passPhrase [ MAX_PHRASE_LENGTH ] ;
2017-02-21 07:03:29 +00:00
std : : cout < < " Passphrase: " ;
std : : cin . getline ( passPhrase , MAX_PHRASE_LENGTH ) ;
2015-11-05 06:59:46 +00:00
if ( command = = " e " )
EncryptFile ( argv [ 2 ] , argv [ 3 ] , passPhrase ) ;
else
DecryptFile ( argv [ 2 ] , argv [ 3 ] , passPhrase ) ;
}
else if ( command = = " ss " )
{
char thisSeed [ 1024 ] ;
2017-02-21 07:03:29 +00:00
std : : cout < < " \n Random Seed: " ;
std : : ws ( std : : cin ) ;
2018-12-07 19:25:10 +00:00
std : : cin . getline ( thisSeed , sizeof ( thisSeed ) ) ;
2017-07-23 20:20:52 +00:00
SecretShareFile ( StringToValue < int , true > ( argv [ 2 ] ) , StringToValue < int , true > ( argv [ 3 ] ) , argv [ 4 ] , thisSeed ) ;
2015-11-05 06:59:46 +00:00
}
else if ( command = = " sr " )
SecretRecoverFile ( argc - 3 , argv [ 2 ] , argv + 3 ) ;
else if ( command = = " id " )
2017-07-23 20:20:52 +00:00
InformationDisperseFile ( StringToValue < int , true > ( argv [ 2 ] ) , StringToValue < int , true > ( argv [ 3 ] ) , argv [ 4 ] ) ;
2015-11-05 06:59:46 +00:00
else if ( command = = " ir " )
InformationRecoverFile ( argc - 3 , argv [ 2 ] , argv + 3 ) ;
else if ( command = = " v " | | command = = " vv " )
2022-08-24 05:37:30 +00:00
{
int testNumber = argc > 2 ? StringToValue < int , true > ( argv [ 2 ] ) : 0 ;
return Validate ( testNumber , command = = " vv " /*thorough*/ ) ? 0 : 1 ;
}
2017-05-20 03:29:59 +00:00
else if ( command . substr ( 0 , 1 ) = = " b " ) // "b", "b1", "b2", ...
2017-07-23 20:20:52 +00:00
BenchmarkWithCommand ( argc , argv ) ;
2015-11-05 06:59:46 +00:00
else if ( command = = " z " )
GzipFile ( argv [ 3 ] , argv [ 4 ] , argv [ 2 ] [ 0 ] - ' 0 ' ) ;
else if ( command = = " u " )
GunzipFile ( argv [ 2 ] , argv [ 3 ] ) ;
else if ( command = = " fips " )
FIPS140_SampleApplication ( ) ;
else if ( command = = " fips-rand " )
FIPS140_GenerateRandomFiles ( ) ;
else if ( command = = " a " )
{
if ( AdhocTest )
return ( * AdhocTest ) ( argc , argv ) ;
else
{
2017-02-21 07:03:29 +00:00
std : : cerr < < " AdhocTest not defined. \n " ;
2015-11-05 06:59:46 +00:00
return 1 ;
}
}
else if ( command = = " hmac " )
HmacFile ( argv [ 2 ] , argv [ 3 ] ) ;
else if ( command = = " ae " )
AES_CTR_Encrypt ( argv [ 2 ] , argv [ 3 ] , argv [ 4 ] , argv [ 5 ] ) ;
2022-08-24 05:07:25 +00:00
else if ( command = = " h " | | command = = " X-help " )
2015-11-05 06:59:46 +00:00
{
2018-12-07 17:25:52 +00:00
FileSource usage ( DataDir ( " TestData/usage.dat " ) . c_str ( ) , true , new FileSink ( std : : cout ) ) ;
2022-08-24 05:07:25 +00:00
return command = = " h " ? 0 : 1 ;
2015-11-05 06:59:46 +00:00
}
else if ( command = = " V " )
{
2017-02-21 07:03:29 +00:00
std : : cout < < CRYPTOPP_VERSION / 100 < < ' . ' < < ( CRYPTOPP_VERSION % 100 ) / 10 < < ' . ' < < CRYPTOPP_VERSION % 10 < < std : : endl ;
2015-11-05 06:59:46 +00:00
}
else
{
2017-02-21 07:03:29 +00:00
std : : cerr < < " Unrecognized command. Run \" cryptest h \" to obtain usage information. \n " ;
2015-11-05 06:59:46 +00:00
return 1 ;
}
return 0 ;
}
2017-07-23 20:20:52 +00:00
catch ( const Exception & e )
2015-11-05 06:59:46 +00:00
{
2017-07-23 20:20:52 +00:00
std : : cout < < " \n Exception caught: " < < e . what ( ) < < std : : endl ;
2015-11-05 06:59:46 +00:00
return - 1 ;
}
catch ( const std : : exception & e )
{
2017-02-21 07:03:29 +00:00
std : : cout < < " \n std::exception caught: " < < e . what ( ) < < std : : endl ;
2015-11-05 06:59:46 +00:00
return - 2 ;
}
2017-05-04 23:11:24 +00:00
} // main()
2015-11-05 06:59:46 +00:00
2019-08-05 07:51:58 +00:00
bool SetGlobalSeed ( int argc , char * argv [ ] , std : : string & seed )
{
bool ret = false ;
for ( int i = 0 ; i < argc ; + + i )
{
std : : string arg ( argv [ i ] ) ;
std : : string : : size_type pos = arg . find ( " seed= " ) ;
if ( pos ! = std : : string : : npos )
{
// length of "seed=" is 5
seed = arg . substr ( pos + 5 ) ;
ret = true ; goto finish ;
}
}
// Use a random seed if none is provided
if ( s_globalSeed . empty ( ) )
s_globalSeed = IntToString ( time ( NULLPTR ) ) ;
finish :
// Some editors have problems with '\0' fill characters when redirecting output.
s_globalSeed . resize ( GLOBAL_SEED_LENGTH , ' ' ) ;
return ret ;
}
2019-01-03 01:22:55 +00:00
void SetArgvPathHint ( const char * argv0 , std : : string & pathHint )
{
2019-01-08 22:03:45 +00:00
# if (PATH_MAX > 0) // Posix
size_t path_max = ( size_t ) PATH_MAX ;
# elif (MAX_PATH > 0) // Microsoft
size_t path_max = ( size_t ) MAX_PATH ;
# else
size_t path_max = 260 ;
# endif
2019-01-03 04:43:44 +00:00
// OS X and Solaris provide a larger path using pathconf than MAX_PATH.
// Also see https://stackoverflow.com/a/33249023/608639 for FreeBSD.
2019-01-08 22:03:45 +00:00
# if defined(_PC_PATH_MAX)
2019-01-03 04:43:44 +00:00
long ret = pathconf ( argv0 , _PC_PATH_MAX ) ;
2019-01-08 22:03:45 +00:00
const size_t old_path_max = path_max ;
2019-01-03 04:43:44 +00:00
if ( SafeConvert ( ret , path_max ) = = false )
2019-01-08 22:03:45 +00:00
path_max = old_path_max ;
2019-01-03 04:43:44 +00:00
# endif
const size_t argLen = std : : strlen ( argv0 ) ;
if ( argLen > = path_max )
return ; // Can't use realpath safely
pathHint = std : : string ( argv0 , argLen ) ;
2019-01-03 01:22:55 +00:00
# if defined(AT_EXECFN)
if ( getauxval ( AT_EXECFN ) )
pathHint = getauxval ( AT_EXECFN ) ;
2023-06-25 22:28:11 +00:00
# elif defined(CRYPTOPP_MSC_VERSION) && (CRYPTOPP_MSC_VERSION > 1310)
2019-01-03 01:22:55 +00:00
char * pgmptr = NULLPTR ;
errno_t err = _get_pgmptr ( & pgmptr ) ;
if ( err = = 0 & & pgmptr ! = NULLPTR )
pathHint = pgmptr ;
2020-01-27 07:27:51 +00:00
# elif defined(__MINGW32__) || defined(__MINGW64__)
std : : string t ( path_max , ( char ) 0 ) ;
if ( _fullpath ( & t [ 0 ] , pathHint . c_str ( ) , path_max ) )
{
t . resize ( strlen ( t . c_str ( ) ) ) ;
std : : swap ( pathHint , t ) ;
}
2019-01-03 04:43:44 +00:00
# elif defined(CRYPTOPP_OSX_AVAILABLE)
std : : string t ( path_max , ( char ) 0 ) ;
unsigned int len = ( unsigned int ) t . size ( ) ;
if ( _NSGetExecutablePath ( & t [ 0 ] , & len ) = = 0 )
{
t . resize ( len ) ;
std : : swap ( pathHint , t ) ;
}
2019-01-03 01:22:55 +00:00
# elif defined(sun) || defined(__sun)
2019-01-03 04:43:44 +00:00
if ( getexecname ( ) )
pathHint = getexecname ( ) ;
# endif
2020-01-27 07:27:51 +00:00
# if defined(__MINGW32__) || defined(__MINGW64__)
// This path exists to stay out of the Posix paths that follow
; ;
# elif (_POSIX_C_SOURCE >= 200809L) || (_XOPEN_SOURCE >= 700)
2019-01-03 04:43:44 +00:00
char * resolved = realpath ( pathHint . c_str ( ) , NULLPTR ) ;
if ( resolved ! = NULLPTR )
{
pathHint = resolved ;
std : : free ( resolved ) ;
}
2019-01-09 06:04:59 +00:00
# elif defined(UNIX_PATH_FAMILY)
2019-01-03 04:43:44 +00:00
std : : string resolved ( path_max , ( char ) 0 ) ;
char * r = realpath ( pathHint . c_str ( ) , & resolved [ 0 ] ) ;
if ( r ! = NULLPTR )
{
resolved . resize ( std : : strlen ( & resolved [ 0 ] ) ) ;
std : : swap ( pathHint , resolved ) ;
}
2019-01-09 06:04:59 +00:00
# endif
2019-01-03 04:43:44 +00:00
2019-01-09 06:04:59 +00:00
# if defined(UNIX_PATH_FAMILY)
2019-01-03 04:43:44 +00:00
// Is it possible for realpath to fail?
struct stat buf ; int x ;
x = lstat ( pathHint . c_str ( ) , & buf ) ;
2019-01-08 22:31:53 +00:00
if ( x ! = 0 | | S_ISLNK ( buf . st_mode ) )
2019-01-03 04:43:44 +00:00
pathHint . clear ( ) ;
2019-01-03 01:22:55 +00:00
# endif
2019-01-03 04:43:44 +00:00
// Trim the executable name, leave the path with a slash.
2019-01-03 01:22:55 +00:00
std : : string : : size_type pos = pathHint . find_last_of ( " \\ / " ) ;
if ( pos ! = std : : string : : npos )
pathHint . erase ( pos + 1 ) ;
}
2015-11-05 06:59:46 +00:00
void FIPS140_GenerateRandomFiles ( )
{
# ifdef OS_RNG_AVAILABLE
DefaultAutoSeededRNG rng ;
RandomNumberStore store ( rng , ULONG_MAX ) ;
for ( unsigned int i = 0 ; i < 100000 ; i + + )
store . TransferTo ( FileSink ( ( IntToString ( i ) + " .rnd " ) . c_str ( ) ) . Ref ( ) , 20000 ) ;
# else
2017-02-21 07:03:29 +00:00
std : : cout < < " OS provided RNG not available. \n " ;
2015-11-05 06:59:46 +00:00
exit ( - 1 ) ;
# endif
}
2018-07-10 21:08:13 +00:00
void PrintSeedAndThreads ( )
2015-11-18 20:32:28 +00:00
{
2018-07-10 21:08:13 +00:00
std : : cout < < " Using seed: " < < s_globalSeed < < std : : endl ;
2015-11-18 20:32:28 +00:00
# ifdef _OPENMP
int tc = 0 ;
# pragma omp parallel
{
tc = omp_get_num_threads ( ) ;
}
2019-01-22 08:42:53 +00:00
std : : cout < < " OpenMP version " < < ( int ) _OPENMP < < " , " ;
2019-01-22 08:44:34 +00:00
std : : cout < < tc < < ( tc = = 1 ? " thread " : " threads " ) < < std : : endl ;
2015-11-18 20:32:28 +00:00
# endif
}
2015-11-05 06:59:46 +00:00
SecByteBlock HexDecodeString ( const char * hex )
{
StringSource ss ( hex , true , new HexDecoder ) ;
SecByteBlock result ( ( size_t ) ss . MaxRetrievable ( ) ) ;
ss . Get ( result , result . size ( ) ) ;
return result ;
}
void GenerateRSAKey ( unsigned int keyLength , const char * privFilename , const char * pubFilename , const char * seed )
{
2018-01-21 13:45:02 +00:00
// DEREncode() changed to Save() at Issue 569.
2015-11-05 06:59:46 +00:00
RandomPool randPool ;
randPool . IncorporateEntropy ( ( byte * ) seed , strlen ( seed ) ) ;
RSAES_OAEP_SHA_Decryptor priv ( randPool , keyLength ) ;
HexEncoder privFile ( new FileSink ( privFilename ) ) ;
2018-01-21 13:45:02 +00:00
priv . AccessMaterial ( ) . Save ( privFile ) ;
2015-11-05 06:59:46 +00:00
privFile . MessageEnd ( ) ;
RSAES_OAEP_SHA_Encryptor pub ( priv ) ;
HexEncoder pubFile ( new FileSink ( pubFilename ) ) ;
2018-01-21 13:45:02 +00:00
pub . AccessMaterial ( ) . Save ( pubFile ) ;
2015-11-05 06:59:46 +00:00
pubFile . MessageEnd ( ) ;
}
2017-02-21 07:03:29 +00:00
std : : string RSAEncryptString ( const char * pubFilename , const char * seed , const char * message )
2015-11-05 06:59:46 +00:00
{
FileSource pubFile ( pubFilename , true , new HexDecoder ) ;
RSAES_OAEP_SHA_Encryptor pub ( pubFile ) ;
RandomPool randPool ;
randPool . IncorporateEntropy ( ( byte * ) seed , strlen ( seed ) ) ;
2017-02-21 07:03:29 +00:00
std : : string result ;
2015-11-05 06:59:46 +00:00
StringSource ( message , true , new PK_EncryptorFilter ( randPool , pub , new HexEncoder ( new StringSink ( result ) ) ) ) ;
return result ;
}
2017-02-21 07:03:29 +00:00
std : : string RSADecryptString ( const char * privFilename , const char * ciphertext )
2015-11-05 06:59:46 +00:00
{
FileSource privFile ( privFilename , true , new HexDecoder ) ;
RSAES_OAEP_SHA_Decryptor priv ( privFile ) ;
2017-02-21 07:03:29 +00:00
std : : string result ;
2017-07-23 20:20:52 +00:00
StringSource ( ciphertext , true , new HexDecoder ( new PK_DecryptorFilter ( GlobalRNG ( ) , priv , new StringSink ( result ) ) ) ) ;
2015-11-05 06:59:46 +00:00
return result ;
}
void RSASignFile ( const char * privFilename , const char * messageFilename , const char * signatureFilename )
{
FileSource privFile ( privFilename , true , new HexDecoder ) ;
2017-04-24 09:05:14 +00:00
RSASS < PKCS1v15 , SHA1 > : : Signer priv ( privFile ) ;
2017-07-23 20:20:52 +00:00
FileSource f ( messageFilename , true , new SignerFilter ( GlobalRNG ( ) , priv , new HexEncoder ( new FileSink ( signatureFilename ) ) ) ) ;
2015-11-05 06:59:46 +00:00
}
bool RSAVerifyFile ( const char * pubFilename , const char * messageFilename , const char * signatureFilename )
{
FileSource pubFile ( pubFilename , true , new HexDecoder ) ;
2017-04-24 09:05:14 +00:00
RSASS < PKCS1v15 , SHA1 > : : Verifier pub ( pubFile ) ;
2015-11-05 06:59:46 +00:00
FileSource signatureFile ( signatureFilename , true , new HexDecoder ) ;
if ( signatureFile . MaxRetrievable ( ) ! = pub . SignatureLength ( ) )
return false ;
SecByteBlock signature ( pub . SignatureLength ( ) ) ;
signatureFile . Get ( signature , signature . size ( ) ) ;
2017-02-07 23:51:44 +00:00
SignatureVerificationFilter * verifierFilter = new SignatureVerificationFilter ( pub ) ;
2015-11-05 06:59:46 +00:00
verifierFilter - > Put ( signature , pub . SignatureLength ( ) ) ;
FileSource f ( messageFilename , true , verifierFilter ) ;
return verifierFilter - > GetLastResult ( ) ;
}
void DigestFile ( const char * filename )
{
SHA1 sha ;
RIPEMD160 ripemd ;
SHA256 sha256 ;
Tiger tiger ;
SHA512 sha512 ;
Whirlpool whirlpool ;
2017-02-21 07:03:29 +00:00
2015-11-05 06:59:46 +00:00
vector_member_ptrs < HashFilter > filters ( 6 ) ;
filters [ 0 ] . reset ( new HashFilter ( sha ) ) ;
filters [ 1 ] . reset ( new HashFilter ( ripemd ) ) ;
filters [ 2 ] . reset ( new HashFilter ( tiger ) ) ;
filters [ 3 ] . reset ( new HashFilter ( sha256 ) ) ;
filters [ 4 ] . reset ( new HashFilter ( sha512 ) ) ;
filters [ 5 ] . reset ( new HashFilter ( whirlpool ) ) ;
member_ptr < ChannelSwitch > channelSwitch ( new ChannelSwitch ) ;
size_t i ;
for ( i = 0 ; i < filters . size ( ) ; i + + )
channelSwitch - > AddDefaultRoute ( * filters [ i ] ) ;
FileSource ( filename , true , channelSwitch . release ( ) ) ;
2017-02-21 07:03:29 +00:00
HexEncoder encoder ( new FileSink ( std : : cout ) , false ) ;
2015-11-05 06:59:46 +00:00
for ( i = 0 ; i < filters . size ( ) ; i + + )
{
2017-02-21 07:03:29 +00:00
std : : cout < < filters [ i ] - > AlgorithmName ( ) < < " : " ;
2015-11-05 06:59:46 +00:00
filters [ i ] - > TransferTo ( encoder ) ;
2017-02-21 07:03:29 +00:00
std : : cout < < " \n " ;
2015-11-05 06:59:46 +00:00
}
}
void HmacFile ( const char * hexKey , const char * file )
{
member_ptr < MessageAuthenticationCode > mac ;
if ( strcmp ( hexKey , " selftest " ) = = 0 )
{
2017-02-21 07:03:29 +00:00
std : : cerr < < " Computing HMAC/SHA1 value for self test. \n " ;
2015-11-05 06:59:46 +00:00
mac . reset ( NewIntegrityCheckingMAC ( ) ) ;
}
else
{
std : : string decodedKey ;
StringSource ( hexKey , true , new HexDecoder ( new StringSink ( decodedKey ) ) ) ;
mac . reset ( new HMAC < SHA1 > ( ( const byte * ) decodedKey . data ( ) , decodedKey . size ( ) ) ) ;
}
2017-02-21 07:03:29 +00:00
FileSource ( file , true , new HashFilter ( * mac , new HexEncoder ( new FileSink ( std : : cout ) ) ) ) ;
2015-11-05 06:59:46 +00:00
}
void AES_CTR_Encrypt ( const char * hexKey , const char * hexIV , const char * infile , const char * outfile )
{
SecByteBlock key = HexDecodeString ( hexKey ) ;
SecByteBlock iv = HexDecodeString ( hexIV ) ;
CTR_Mode < AES > : : Encryption aes ( key , key . size ( ) , iv ) ;
FileSource ( infile , true , new StreamTransformationFilter ( aes , new FileSink ( outfile ) ) ) ;
}
2017-02-21 07:03:29 +00:00
std : : string EncryptString ( const char * instr , const char * passPhrase )
2015-11-05 06:59:46 +00:00
{
2017-02-21 07:03:29 +00:00
std : : string outstr ;
2015-11-05 06:59:46 +00:00
DefaultEncryptorWithMAC encryptor ( passPhrase , new HexEncoder ( new StringSink ( outstr ) ) ) ;
encryptor . Put ( ( byte * ) instr , strlen ( instr ) ) ;
encryptor . MessageEnd ( ) ;
return outstr ;
}
2017-02-21 07:03:29 +00:00
std : : string DecryptString ( const char * instr , const char * passPhrase )
2015-11-05 06:59:46 +00:00
{
2017-02-21 07:03:29 +00:00
std : : string outstr ;
2015-11-05 06:59:46 +00:00
HexDecoder decryptor ( new DefaultDecryptorWithMAC ( passPhrase , new StringSink ( outstr ) ) ) ;
decryptor . Put ( ( byte * ) instr , strlen ( instr ) ) ;
decryptor . MessageEnd ( ) ;
return outstr ;
}
void EncryptFile ( const char * in , const char * out , const char * passPhrase )
{
FileSource f ( in , true , new DefaultEncryptorWithMAC ( passPhrase , new FileSink ( out ) ) ) ;
}
void DecryptFile ( const char * in , const char * out , const char * passPhrase )
{
FileSource f ( in , true , new DefaultDecryptorWithMAC ( passPhrase , new FileSink ( out ) ) ) ;
}
void SecretShareFile ( int threshold , int nShares , const char * filename , const char * seed )
{
2016-09-16 15:27:15 +00:00
CRYPTOPP_ASSERT ( nShares > = 1 & & nShares < = 1000 ) ;
2015-11-18 20:32:28 +00:00
if ( nShares < 1 | | nShares > 1000 )
throw InvalidArgument ( " SecretShareFile: " + IntToString ( nShares ) + " is not in range [1, 1000] " ) ;
2015-11-05 06:59:46 +00:00
RandomPool rng ;
rng . IncorporateEntropy ( ( byte * ) seed , strlen ( seed ) ) ;
2017-03-01 11:10:06 +00:00
ChannelSwitch * channelSwitch = NULLPTR ;
2015-11-05 06:59:46 +00:00
FileSource source ( filename , false , new SecretSharing ( rng , threshold , nShares , channelSwitch = new ChannelSwitch ) ) ;
2017-04-14 03:13:07 +00:00
// Be careful of the type of Sink used. An ArraySink will stop writing data once the array
// is full. Also see http://groups.google.com/forum/#!topic/cryptopp-users/XEKKLCEFH3Y.
2015-11-05 06:59:46 +00:00
vector_member_ptrs < FileSink > fileSinks ( nShares ) ;
2017-02-21 07:03:29 +00:00
std : : string channel ;
2015-11-05 06:59:46 +00:00
for ( int i = 0 ; i < nShares ; i + + )
{
char extension [ 5 ] = " .000 " ;
extension [ 1 ] = ' 0 ' + byte ( i / 100 ) ;
extension [ 2 ] = ' 0 ' + byte ( ( i / 10 ) % 10 ) ;
extension [ 3 ] = ' 0 ' + byte ( i % 10 ) ;
2017-02-21 07:03:29 +00:00
fileSinks [ i ] . reset ( new FileSink ( ( std : : string ( filename ) + extension ) . c_str ( ) ) ) ;
2015-11-05 06:59:46 +00:00
channel = WordToString < word32 > ( i ) ;
2015-11-18 20:32:28 +00:00
fileSinks [ i ] - > Put ( ( const byte * ) channel . data ( ) , 4 ) ;
2015-11-05 06:59:46 +00:00
channelSwitch - > AddRoute ( channel , * fileSinks [ i ] , DEFAULT_CHANNEL ) ;
}
source . PumpAll ( ) ;
}
void SecretRecoverFile ( int threshold , const char * outFilename , char * const * inFilenames )
{
2016-09-16 15:27:15 +00:00
CRYPTOPP_ASSERT ( threshold > = 1 & & threshold < = 1000 ) ;
2015-11-18 20:32:28 +00:00
if ( threshold < 1 | | threshold > 1000 )
throw InvalidArgument ( " SecretRecoverFile: " + IntToString ( threshold ) + " is not in range [1, 1000] " ) ;
2015-11-05 06:59:46 +00:00
SecretRecovery recovery ( threshold , new FileSink ( outFilename ) ) ;
vector_member_ptrs < FileSource > fileSources ( threshold ) ;
SecByteBlock channel ( 4 ) ;
int i ;
for ( i = 0 ; i < threshold ; i + + )
{
fileSources [ i ] . reset ( new FileSource ( inFilenames [ i ] , false ) ) ;
fileSources [ i ] - > Pump ( 4 ) ;
fileSources [ i ] - > Get ( channel , 4 ) ;
2017-02-21 07:03:29 +00:00
fileSources [ i ] - > Attach ( new ChannelSwitch ( recovery , std : : string ( ( char * ) channel . begin ( ) , 4 ) ) ) ;
2015-11-05 06:59:46 +00:00
}
while ( fileSources [ 0 ] - > Pump ( 256 ) )
for ( i = 1 ; i < threshold ; i + + )
fileSources [ i ] - > Pump ( 256 ) ;
for ( i = 0 ; i < threshold ; i + + )
fileSources [ i ] - > PumpAll ( ) ;
}
void InformationDisperseFile ( int threshold , int nShares , const char * filename )
{
2016-09-16 15:27:15 +00:00
CRYPTOPP_ASSERT ( threshold > = 1 & & threshold < = 1000 ) ;
2015-11-18 20:32:28 +00:00
if ( threshold < 1 | | threshold > 1000 )
throw InvalidArgument ( " InformationDisperseFile: " + IntToString ( nShares ) + " is not in range [1, 1000] " ) ;
2015-11-05 06:59:46 +00:00
2017-03-01 11:10:06 +00:00
ChannelSwitch * channelSwitch = NULLPTR ;
2015-11-05 06:59:46 +00:00
FileSource source ( filename , false , new InformationDispersal ( threshold , nShares , channelSwitch = new ChannelSwitch ) ) ;
2017-04-14 03:13:07 +00:00
// Be careful of the type of Sink used. An ArraySink will stop writing data once the array
// is full. Also see http://groups.google.com/forum/#!topic/cryptopp-users/XEKKLCEFH3Y.
2015-11-05 06:59:46 +00:00
vector_member_ptrs < FileSink > fileSinks ( nShares ) ;
2017-02-21 07:03:29 +00:00
std : : string channel ;
2015-11-05 06:59:46 +00:00
for ( int i = 0 ; i < nShares ; i + + )
{
char extension [ 5 ] = " .000 " ;
extension [ 1 ] = ' 0 ' + byte ( i / 100 ) ;
extension [ 2 ] = ' 0 ' + byte ( ( i / 10 ) % 10 ) ;
extension [ 3 ] = ' 0 ' + byte ( i % 10 ) ;
2017-02-21 07:03:29 +00:00
fileSinks [ i ] . reset ( new FileSink ( ( std : : string ( filename ) + extension ) . c_str ( ) ) ) ;
2015-11-05 06:59:46 +00:00
channel = WordToString < word32 > ( i ) ;
2015-11-18 20:32:28 +00:00
fileSinks [ i ] - > Put ( ( const byte * ) channel . data ( ) , 4 ) ;
2015-11-05 06:59:46 +00:00
channelSwitch - > AddRoute ( channel , * fileSinks [ i ] , DEFAULT_CHANNEL ) ;
}
source . PumpAll ( ) ;
}
void InformationRecoverFile ( int threshold , const char * outFilename , char * const * inFilenames )
{
2016-09-16 15:27:15 +00:00
CRYPTOPP_ASSERT ( threshold < = 1000 ) ;
2015-11-18 20:32:28 +00:00
if ( threshold < 1 | | threshold > 1000 )
throw InvalidArgument ( " InformationRecoverFile: " + IntToString ( threshold ) + " is not in range [1, 1000] " ) ;
2015-11-05 06:59:46 +00:00
InformationRecovery recovery ( threshold , new FileSink ( outFilename ) ) ;
vector_member_ptrs < FileSource > fileSources ( threshold ) ;
SecByteBlock channel ( 4 ) ;
int i ;
for ( i = 0 ; i < threshold ; i + + )
{
fileSources [ i ] . reset ( new FileSource ( inFilenames [ i ] , false ) ) ;
fileSources [ i ] - > Pump ( 4 ) ;
fileSources [ i ] - > Get ( channel , 4 ) ;
2017-02-21 07:03:29 +00:00
fileSources [ i ] - > Attach ( new ChannelSwitch ( recovery , std : : string ( ( char * ) channel . begin ( ) , 4 ) ) ) ;
2015-11-05 06:59:46 +00:00
}
while ( fileSources [ 0 ] - > Pump ( 256 ) )
for ( i = 1 ; i < threshold ; i + + )
fileSources [ i ] - > Pump ( 256 ) ;
for ( i = 0 ; i < threshold ; i + + )
fileSources [ i ] - > PumpAll ( ) ;
}
void GzipFile ( const char * in , const char * out , int deflate_level )
{
// FileSource(in, true, new Gzip(new FileSink(out), deflate_level));
// use a filter graph to compare decompressed data with original
//
// Source ----> Gzip ------> Sink
// \ |
// \ Gunzip
// \ |
// \ v
2016-07-24 23:28:01 +00:00
// > ComparisonFilter
2015-11-05 06:59:46 +00:00
EqualityComparisonFilter comparison ;
Gunzip gunzip ( new ChannelSwitch ( comparison , " 0 " ) ) ;
gunzip . SetAutoSignalPropagation ( 0 ) ;
FileSink sink ( out ) ;
ChannelSwitch * cs ;
Gzip gzip ( cs = new ChannelSwitch ( sink ) , deflate_level ) ;
cs - > AddDefaultRoute ( gunzip ) ;
cs = new ChannelSwitch ( gzip ) ;
cs - > AddDefaultRoute ( comparison , " 1 " ) ;
FileSource source ( in , true , cs ) ;
comparison . ChannelMessageSeriesEnd ( " 0 " ) ;
comparison . ChannelMessageSeriesEnd ( " 1 " ) ;
}
void GunzipFile ( const char * in , const char * out )
{
FileSource ( in , true , new Gunzip ( new FileSink ( out ) ) ) ;
}
void Base64Encode ( const char * in , const char * out )
{
FileSource ( in , true , new Base64Encoder ( new FileSink ( out ) ) ) ;
}
void Base64Decode ( const char * in , const char * out )
{
FileSource ( in , true , new Base64Decoder ( new FileSink ( out ) ) ) ;
}
void HexEncode ( const char * in , const char * out )
{
FileSource ( in , true , new HexEncoder ( new FileSink ( out ) ) ) ;
}
void HexDecode ( const char * in , const char * out )
{
FileSource ( in , true , new HexDecoder ( new FileSink ( out ) ) ) ;
}
2019-08-05 07:51:58 +00:00
bool Validate ( int alg , bool thorough )
2015-11-05 06:59:46 +00:00
{
bool result ;
2017-09-20 22:43:51 +00:00
g_testBegin = : : time ( NULLPTR ) ;
2018-07-10 21:08:13 +00:00
PrintSeedAndThreads ( ) ;
2015-11-05 06:59:46 +00:00
2019-02-13 16:31:18 +00:00
// TODO: we need to group these tests like benchmarks...
2015-11-05 06:59:46 +00:00
switch ( alg )
{
2017-07-23 20:20:52 +00:00
case 0 : result = ValidateAll ( thorough ) ; break ;
case 1 : result = TestSettings ( ) ; break ;
case 2 : result = TestOS_RNG ( ) ; break ;
// case 3: result = TestSecRandom(); break;
case 4 : result = ValidateMD5 ( ) ; break ;
case 5 : result = ValidateSHA ( ) ; break ;
case 6 : result = ValidateDES ( ) ; break ;
case 7 : result = ValidateIDEA ( ) ; break ;
case 8 : result = ValidateARC4 ( ) ; break ;
case 9 : result = ValidateRC5 ( ) ; break ;
case 10 : result = ValidateBlowfish ( ) ; break ;
// case 11: result = ValidateDiamond2(); break;
case 12 : result = ValidateThreeWay ( ) ; break ;
case 13 : result = ValidateBBS ( ) ; break ;
case 14 : result = ValidateDH ( ) ; break ;
2018-12-11 21:17:56 +00:00
case 15 : result = ValidateX25519 ( ) ; break ;
case 16 : result = ValidateRSA ( ) ; break ;
case 17 : result = ValidateElGamal ( ) ; break ;
case 18 : result = ValidateDSA ( thorough ) ; break ;
2017-07-23 20:20:52 +00:00
// case 18: result = ValidateHAVAL(); break;
case 19 : result = ValidateSAFER ( ) ; break ;
case 20 : result = ValidateLUC ( ) ; break ;
case 21 : result = ValidateRabin ( ) ; break ;
// case 22: result = ValidateBlumGoldwasser(); break;
case 23 : result = ValidateECP ( ) ; break ;
case 24 : result = ValidateEC2N ( ) ; break ;
// case 25: result = ValidateMD5MAC(); break;
case 26 : result = ValidateGOST ( ) ; break ;
case 27 : result = ValidateTiger ( ) ; break ;
case 28 : result = ValidateRIPEMD ( ) ; break ;
case 29 : result = ValidateHMAC ( ) ; break ;
// case 30: result = ValidateXMACC(); break;
case 31 : result = ValidateSHARK ( ) ; break ;
case 32 : result = ValidateLUC_DH ( ) ; break ;
case 33 : result = ValidateLUC_DL ( ) ; break ;
case 34 : result = ValidateSEAL ( ) ; break ;
case 35 : result = ValidateCAST ( ) ; break ;
case 36 : result = ValidateSquare ( ) ; break ;
case 37 : result = ValidateRC2 ( ) ; break ;
case 38 : result = ValidateRC6 ( ) ; break ;
case 39 : result = ValidateMARS ( ) ; break ;
case 40 : result = ValidateRW ( ) ; break ;
case 41 : result = ValidateMD2 ( ) ; break ;
case 42 : result = ValidateNR ( ) ; break ;
case 43 : result = ValidateMQV ( ) ; break ;
case 44 : result = ValidateRijndael ( ) ; break ;
case 45 : result = ValidateTwofish ( ) ; break ;
case 46 : result = ValidateSerpent ( ) ; break ;
case 47 : result = ValidateCipherModes ( ) ; break ;
case 48 : result = ValidateCRC32 ( ) ; break ;
case 49 : result = ValidateCRC32C ( ) ; break ;
case 50 : result = ValidateECDSA ( ) ; break ;
2017-11-25 08:27:07 +00:00
case 51 : result = ValidateECGDSA ( thorough ) ; break ;
2017-07-23 20:20:52 +00:00
case 52 : result = ValidateXTR_DH ( ) ; break ;
case 53 : result = ValidateSKIPJACK ( ) ; break ;
case 54 : result = ValidateSHA2 ( ) ; break ;
case 55 : result = ValidatePanama ( ) ; break ;
case 56 : result = ValidateAdler32 ( ) ; break ;
case 57 : result = ValidateMD4 ( ) ; break ;
case 58 : result = ValidatePBKDF ( ) ; break ;
2018-04-01 00:09:38 +00:00
case 59 : result = ValidateHKDF ( ) ; break ;
case 60 : result = ValidateScrypt ( ) ; break ;
case 61 : result = ValidateESIGN ( ) ; break ;
case 62 : result = ValidateDLIES ( ) ; break ;
case 63 : result = ValidateBaseCode ( ) ; break ;
case 64 : result = ValidateSHACAL2 ( ) ; break ;
case 65 : result = ValidateARIA ( ) ; break ;
case 66 : result = ValidateCamellia ( ) ; break ;
case 67 : result = ValidateWhirlpool ( ) ; break ;
2021-04-16 07:23:15 +00:00
case 68 : result = ValidateLSH ( ) ; break ;
case 69 : result = ValidateTTMAC ( ) ; break ;
2018-11-09 03:08:59 +00:00
case 70 : result = ValidateSalsa ( ) ; break ;
case 71 : result = ValidateChaCha ( ) ; break ;
2019-01-24 14:36:05 +00:00
case 72 : result = ValidateChaChaTLS ( ) ; break ;
case 73 : result = ValidateSosemanuk ( ) ; break ;
case 74 : result = ValidateRabbit ( ) ; break ;
case 75 : result = ValidateHC128 ( ) ; break ;
case 76 : result = ValidateHC256 ( ) ; break ;
2018-11-09 03:08:59 +00:00
case 80 : result = ValidateVMAC ( ) ; break ;
case 81 : result = ValidateCCM ( ) ; break ;
case 82 : result = ValidateGCM ( ) ; break ;
2019-10-12 11:14:38 +00:00
case 83 : result = ValidateXTS ( ) ; break ;
case 84 : result = ValidateCMAC ( ) ; break ;
case 85 : result = ValidateSM3 ( ) ; break ;
case 86 : result = ValidateBLAKE2s ( ) ; break ;
case 87 : result = ValidateBLAKE2b ( ) ; break ;
case 88 : result = ValidatePoly1305 ( ) ; break ;
case 89 : result = ValidateSipHash ( ) ; break ;
case 90 : result = ValidateHashDRBG ( ) ; break ;
case 91 : result = ValidateHmacDRBG ( ) ; break ;
case 92 : result = ValidateNaCl ( ) ; break ;
2018-11-09 03:08:59 +00:00
case 100 : result = ValidateCHAM ( ) ; break ;
case 101 : result = ValidateSIMECK ( ) ; break ;
case 102 : result = ValidateSIMON ( ) ; break ;
case 103 : result = ValidateSPECK ( ) ; break ;
2016-12-24 09:56:34 +00:00
2019-02-13 16:31:18 +00:00
case 110 : result = ValidateSHA3 ( ) ; break ;
case 111 : result = ValidateSHAKE ( ) ; break ;
case 112 : result = ValidateSHAKE_XOF ( ) ; break ;
2019-08-05 07:51:58 +00:00
case 120 : result = ValidateMQV ( ) ; break ;
case 121 : result = ValidateHMQV ( ) ; break ;
case 122 : result = ValidateFHMQV ( ) ; break ;
2017-05-06 04:24:35 +00:00
# if defined(CRYPTOPP_EXTENDED_VALIDATION)
2016-12-24 09:56:34 +00:00
// http://github.com/weidai11/cryptopp/issues/92
2017-07-23 20:20:52 +00:00
case 9999 : result = TestSecBlock ( ) ; break ;
2016-12-24 09:56:34 +00:00
// http://github.com/weidai11/cryptopp/issues/64
2017-07-23 20:20:52 +00:00
case 9998 : result = TestPolynomialMod2 ( ) ; break ;
2016-12-24 09:56:34 +00:00
// http://github.com/weidai11/cryptopp/issues/336
2017-07-23 20:20:52 +00:00
case 9997 : result = TestIntegerBitops ( ) ; break ;
2018-03-25 04:43:21 +00:00
// http://github.com/weidai11/cryptopp/issues/602
case 9996 : result = TestIntegerOps ( ) ; break ;
2017-01-11 03:09:38 +00:00
// http://github.com/weidai11/cryptopp/issues/360
2018-03-25 04:43:21 +00:00
case 9995 : result = TestRounding ( ) ; break ;
2016-12-24 09:56:34 +00:00
// http://github.com/weidai11/cryptopp/issues/242
2018-03-25 04:43:21 +00:00
case 9994 : result = TestHuffmanCodes ( ) ; break ;
2016-12-24 09:56:34 +00:00
// http://github.com/weidai11/cryptopp/issues/346
2018-03-25 04:43:21 +00:00
case 9993 : result = TestASN1Parse ( ) ; break ;
2021-03-21 08:06:38 +00:00
case 9992 : result = TestASN1Functions ( ) ; break ;
2018-12-25 15:08:49 +00:00
// http://github.com/weidai11/cryptopp/issues/242
2021-03-21 08:06:38 +00:00
case 9991 : result = TestX25519 ( ) ; break ;
2018-12-25 15:08:49 +00:00
// http://github.com/weidai11/cryptopp/issues/346
2021-03-21 08:06:38 +00:00
case 9990 : result = TestEd25519 ( ) ; break ;
2018-08-07 02:19:59 +00:00
# if defined(CRYPTOPP_ALTIVEC_AVAILABLE)
2021-03-21 08:06:38 +00:00
case 9989 : result = TestAltivecOps ( ) ; break ;
2018-08-07 02:19:59 +00:00
# endif
2016-12-24 09:56:34 +00:00
# endif
2015-11-05 06:59:46 +00:00
default : return false ;
}
2017-09-20 22:43:51 +00:00
g_testEnd = : : time ( NULLPTR ) ;
2015-11-05 06:59:46 +00:00
2018-07-11 10:59:44 +00:00
std : : cout < < " \n Seed used was " < < s_globalSeed ;
std : : cout < < " \n Test started at " < < TimeToString ( g_testBegin ) ;
std : : cout < < " \n Test ended at " < < TimeToString ( g_testEnd ) < < std : : endl ;
2015-11-05 06:59:46 +00:00
return result ;
}
2017-07-23 20:20:52 +00:00
NAMESPACE_END // Test
NAMESPACE_END // CryptoPP
// Microsoft puts a byte in global namespace. Combined with
// a 'using namespace CryptoPP', it causes compile failures.
// Also see http://github.com/weidai11/cryptopp/issues/442
// and http://github.com/weidai11/cryptopp/issues/447.
int CRYPTOPP_API main ( int argc , char * argv [ ] )
{
return CryptoPP : : Test : : scoped_main ( argc , argv ) ;
}