Make global seed deteminsitic from the command line

pull/871/head
Jeffrey Walton 2019-08-04 02:20:15 -04:00
parent 86e4199923
commit d4bcc4c707
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
1 changed files with 42 additions and 24 deletions

View File

@ -34,6 +34,7 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <locale> #include <locale>
#include <cstdlib>
#include <ctime> #include <ctime>
#ifdef CRYPTOPP_WIN32_AVAILABLE #ifdef CRYPTOPP_WIN32_AVAILABLE
@ -89,7 +90,8 @@ int (*AdhocTest)(int argc, char *argv[]) = NULLPTR;
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
NAMESPACE_BEGIN(Test) NAMESPACE_BEGIN(Test)
const int MAX_PHRASE_LENGTH=250; const int MAX_PHRASE_LENGTH = 250;
const int GLOBAL_SEED_LENGTH = 16;
std::string g_argvPathHint=""; std::string g_argvPathHint="";
void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed); void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed);
@ -125,7 +127,8 @@ void HexDecode(const char *infile, const char *outfile);
void FIPS140_GenerateRandomFiles(); void FIPS140_GenerateRandomFiles();
bool Validate(int, bool, const char *); bool Validate(int, bool);
bool GetGlobalSeed(int argc, char* argv[], std::string& seed);
void SetArgvPathHint(const char* argv0, std::string& pathHint); void SetArgvPathHint(const char* argv0, std::string& pathHint);
ANONYMOUS_NAMESPACE_BEGIN ANONYMOUS_NAMESPACE_BEGIN
@ -173,16 +176,17 @@ int scoped_main(int argc, char *argv[])
{ {
RegisterFactories(All); RegisterFactories(All);
// Some editors have problems with the '\0' character when redirecting output. // Set a seed for reproducible results. It can be set on the command line or
s_globalSeed = IntToString(time(NULLPTR)); // in the environment. The command line takes precedent. For example:
s_globalSeed.resize(16, ' '); // ./cryptest.exe v seed=abcdefg
GetGlobalSeed(argc, argv, s_globalSeed);
#if (CRYPTOPP_USE_AES_GENERATOR) #if (CRYPTOPP_USE_AES_GENERATOR)
// Fetch the SymmetricCipher interface, not the RandomNumberGenerator // Fetch the SymmetricCipher interface, not the RandomNumberGenerator
// interface, to key the underlying cipher. If CRYPTOPP_USE_AES_GENERATOR is 1 // 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. // then AES/OFB based is used. Otherwise the OS random number generator is used.
SymmetricCipher& cipher = dynamic_cast<SymmetricCipher&>(GlobalRNG()); SymmetricCipher& cipher = dynamic_cast<SymmetricCipher&>(GlobalRNG());
cipher.SetKeyWithIV((byte *)s_globalSeed.data(), 16, (byte *)s_globalSeed.data()); cipher.SetKeyWithIV((byte *)s_globalSeed.data(), s_globalSeed.size(), (byte *)s_globalSeed.data());
#endif #endif
std::string command, executableName, macFilename; std::string command, executableName, macFilename;
@ -393,7 +397,7 @@ int scoped_main(int argc, char *argv[])
else if (command == "ir") else if (command == "ir")
InformationRecoverFile(argc-3, argv[2], argv+3); InformationRecoverFile(argc-3, argv[2], argv+3);
else if (command == "v" || command == "vv") else if (command == "v" || command == "vv")
return !Validate(argc>2 ? StringToValue<int, true>(argv[2]) : 0, argv[1][1] == 'v', argc>3 ? argv[3] : NULLPTR); return !Validate(argc>2 ? StringToValue<int, true>(argv[2]) : 0, argv[1][1] == 'v');
else if (command.substr(0,1) == "b") // "b", "b1", "b2", ... else if (command.substr(0,1) == "b") // "b", "b1", "b2", ...
BenchmarkWithCommand(argc, argv); BenchmarkWithCommand(argc, argv);
else if (command == "z") else if (command == "z")
@ -446,6 +450,36 @@ int scoped_main(int argc, char *argv[])
} }
} // main() } // main()
bool GetGlobalSeed(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.
if (s_globalSeed.size() < GLOBAL_SEED_LENGTH)
s_globalSeed.resize(GLOBAL_SEED_LENGTH, ' ');
return ret;
}
void SetArgvPathHint(const char* argv0, std::string& pathHint) void SetArgvPathHint(const char* argv0, std::string& pathHint)
{ {
# if (PATH_MAX > 0) // Posix # if (PATH_MAX > 0) // Posix
@ -886,26 +920,10 @@ void HexDecode(const char *in, const char *out)
FileSource(in, true, new HexDecoder(new FileSink(out))); FileSource(in, true, new HexDecoder(new FileSink(out)));
} }
bool Validate(int alg, bool thorough, const char *seedInput) bool Validate(int alg, bool thorough)
{ {
bool result; bool result;
// Some editors have problems with the '\0' character when redirecting output.
// seedInput is argv[3] when issuing 'cryptest.exe v all <seed>'
if (seedInput != NULLPTR)
{
// s_globalSeed = seedInput;
s_globalSeed.resize(16, ' ');
}
#if (CRYPTOPP_USE_AES_GENERATOR)
// Fetch the OFB_Mode<AES> interface, not the RandomNumberGenerator
// 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.
SymmetricCipher& cipher = dynamic_cast<SymmetricCipher&>(GlobalRNG());
cipher.SetKeyWithIV((byte *)s_globalSeed.data(), 16, (byte *)s_globalSeed.data());
#endif
g_testBegin = ::time(NULLPTR); g_testBegin = ::time(NULLPTR);
PrintSeedAndThreads(); PrintSeedAndThreads();