mirror of
https://github.com/shadps4-emu/ext-cryptopp.git
synced 2024-11-23 09:59:42 +00:00
bug fixes and KAT for X9.17 RNG
This commit is contained in:
parent
0e0049180d
commit
deea52fd3b
@ -1,5 +1,5 @@
|
||||
Crypto++: a C++ Class Library of Cryptographic Primitives
|
||||
Version 5.0 9/11/2002
|
||||
Version 5.1 (in development)
|
||||
|
||||
This library includes:
|
||||
|
||||
@ -241,3 +241,9 @@ History
|
||||
- is being evaluated for FIPS 140-2 compliance
|
||||
- fixed a bug in HMAC::TruncatedFinal()
|
||||
- fixed SKIPJACK byte ordering following NIST clarification dated 5/9/02
|
||||
|
||||
5.01 (special FIPS 140-2 release, in development)
|
||||
- added known answer test for X9.17 RNG in FIPS 140 power-up self test
|
||||
|
||||
5.1 (in development)
|
||||
- fixed a bug in CBC and ECB modes with processing non-aligned data
|
||||
|
@ -6,7 +6,11 @@
|
||||
|
||||
NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
const std::type_info &g_typeidInteger = typeid(Integer);
|
||||
const std::type_info & IntegerTypeId()
|
||||
{
|
||||
static const std::type_info &s_typeidInteger = typeid(Integer);
|
||||
return s_typeidInteger;
|
||||
}
|
||||
|
||||
void AssignIntToInteger(void *pInteger, const void *pInt)
|
||||
{
|
||||
|
@ -241,7 +241,7 @@ AssignFromHelperClass<T, T> AssignFromHelper(T *pObject, const NameValuePairs &s
|
||||
|
||||
void AssignIntToInteger(void *pInteger, const void *pInt);
|
||||
|
||||
extern const std::type_info &g_typeidInteger;
|
||||
const std::type_info & IntegerTypeId();
|
||||
|
||||
template <class BASE, class T>
|
||||
class AlgorithmParameters : public NameValuePairs
|
||||
@ -283,7 +283,7 @@ public:
|
||||
else if (strcmp(name, m_name) == 0)
|
||||
{
|
||||
// special case for retrieving an Integer parameter when an int was passed in
|
||||
if (valueType == g_typeidInteger && typeid(T) == typeid(int))
|
||||
if (valueType == IntegerTypeId() && typeid(T) == typeid(int))
|
||||
AssignIntToInteger(pValue, &m_value);
|
||||
else
|
||||
{
|
||||
|
@ -4,7 +4,7 @@
|
||||
classes that provide a uniform interface to this library.
|
||||
*/
|
||||
|
||||
/*! \mainpage <a href="http://www.cryptopp.com">Crypto++</a><sup><small>TM</small></sup> Library 5.0 Reference Manual
|
||||
/*! \mainpage <a href="http://www.cryptopp.com">Crypto++</a><sup><small>TM</small></sup> Library 5.1 Reference Manual
|
||||
<dl>
|
||||
<dt>Abstract Base Classes<dd>
|
||||
cryptlib.h
|
||||
|
34
fipstest.cpp
34
fipstest.cpp
@ -23,6 +23,34 @@ NAMESPACE_BEGIN(CryptoPP)
|
||||
|
||||
extern PowerUpSelfTestStatus g_powerUpSelfTestStatus;
|
||||
|
||||
void KnownAnswerTest(RandomNumberGenerator &rng, const char *output)
|
||||
{
|
||||
EqualityComparisonFilter comparison;
|
||||
|
||||
RandomNumberStore(rng, strlen(output)/2).TransferAllTo(comparison, "0");
|
||||
StringSource(output, true, new HexDecoder(new ChannelSwitch(comparison, "1")));
|
||||
|
||||
comparison.ChannelMessageSeriesEnd("0");
|
||||
comparison.ChannelMessageSeriesEnd("1");
|
||||
}
|
||||
|
||||
template <class CIPHER>
|
||||
void X917RNG_KnownAnswerTest(
|
||||
const char *key,
|
||||
const char *seed,
|
||||
const char *output,
|
||||
unsigned int deterministicTimeVector,
|
||||
CIPHER *dummy = NULL)
|
||||
{
|
||||
std::string decodedKey, decodedSeed;
|
||||
StringSource(key, true, new HexDecoder(new StringSink(decodedKey)));
|
||||
StringSource(seed, true, new HexDecoder(new StringSink(decodedSeed)));
|
||||
|
||||
AutoSeededX917RNG<CIPHER> rng;
|
||||
rng.Reseed((const byte *)decodedKey.data(), decodedKey.size(), (const byte *)decodedSeed.data(), deterministicTimeVector);
|
||||
KnownAnswerTest(rng, output);
|
||||
}
|
||||
|
||||
void KnownAnswerTest(StreamTransformation &encryption, StreamTransformation &decryption, const char *plaintext, const char *ciphertext)
|
||||
{
|
||||
EqualityComparisonFilter comparison;
|
||||
@ -208,6 +236,12 @@ void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleSha
|
||||
|
||||
// algorithm tests
|
||||
|
||||
X917RNG_KnownAnswerTest<DES_EDE3>(
|
||||
"48851090B4992453E83CDA86416534E53EA2FCE1A0B3A40C", // key
|
||||
"7D00BD0A79F6B0F5", // seed
|
||||
"22B590B08B53363AEB89AD65F81A5B6FB83F326CE06BF35751E6C41B43B729C4", // output
|
||||
1489728269); // time vector
|
||||
|
||||
SymmetricEncryptionKnownAnswerTest<DES>(
|
||||
"0123456789abcdef", // key
|
||||
"1234567890abcdef", // IV
|
||||
|
@ -144,11 +144,11 @@ void BlockOrientedCipherModeBase::ProcessData(byte *outString, const byte *inStr
|
||||
unsigned int s = BlockSize();
|
||||
assert(length % s == 0);
|
||||
unsigned int alignment = m_cipher->BlockAlignment();
|
||||
bool requireAlignedInput = RequireAlignedInput();
|
||||
bool inputAlignmentOk = !RequireAlignedInput() || IsAlignedOn(inString, alignment);
|
||||
|
||||
if (IsAlignedOn(outString, alignment))
|
||||
{
|
||||
if (!requireAlignedInput || IsAlignedOn(inString, alignment))
|
||||
if (inputAlignmentOk)
|
||||
ProcessBlocks(outString, inString, length / s);
|
||||
else
|
||||
{
|
||||
@ -160,7 +160,7 @@ void BlockOrientedCipherModeBase::ProcessData(byte *outString, const byte *inStr
|
||||
{
|
||||
while (length)
|
||||
{
|
||||
if (!requireAlignedInput || IsAlignedOn(inString, alignment))
|
||||
if (inputAlignmentOk)
|
||||
ProcessBlocks(m_buffer, inString, 1);
|
||||
else
|
||||
{
|
||||
@ -168,6 +168,8 @@ void BlockOrientedCipherModeBase::ProcessData(byte *outString, const byte *inStr
|
||||
ProcessBlocks(m_buffer, m_buffer, 1);
|
||||
}
|
||||
memcpy(outString, m_buffer, s);
|
||||
inString += s;
|
||||
outString += s;
|
||||
length -= s;
|
||||
}
|
||||
}
|
||||
|
25
osrng.h
25
osrng.h
@ -96,6 +96,8 @@ public:
|
||||
explicit AutoSeededX917RNG(bool blocking = false)
|
||||
{Reseed(blocking);}
|
||||
void Reseed(bool blocking = false);
|
||||
// exposed for testing
|
||||
void Reseed(const byte *key, unsigned int keylength, const byte *seed, unsigned long timeVector);
|
||||
|
||||
byte GenerateByte();
|
||||
|
||||
@ -106,6 +108,20 @@ private:
|
||||
unsigned int m_counter;
|
||||
};
|
||||
|
||||
template <class BLOCK_CIPHER>
|
||||
void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(const byte *key, unsigned int keylength, const byte *seed, unsigned long timeVector)
|
||||
{
|
||||
m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector));
|
||||
|
||||
if (FIPS_140_2_ComplianceEnabled())
|
||||
{
|
||||
m_lastBlock.resize(16);
|
||||
m_rng->GenerateBlock(m_lastBlock, m_lastBlock.size());
|
||||
m_counter = 0;
|
||||
m_isDifferent = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <class BLOCK_CIPHER>
|
||||
void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking)
|
||||
{
|
||||
@ -117,15 +133,8 @@ void AutoSeededX917RNG<BLOCK_CIPHER>::Reseed(bool blocking)
|
||||
key = seed + BLOCK_CIPHER::BLOCKSIZE;
|
||||
} // check that seed and key don't have same value
|
||||
while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0);
|
||||
m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH), seed));
|
||||
|
||||
if (FIPS_140_2_ComplianceEnabled())
|
||||
{
|
||||
m_lastBlock.resize(16);
|
||||
m_rng->GenerateBlock(m_lastBlock, m_lastBlock.size());
|
||||
m_counter = 0;
|
||||
m_isDifferent = false;
|
||||
}
|
||||
Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, 0);
|
||||
}
|
||||
|
||||
template <class BLOCK_CIPHER>
|
||||
|
37
rng.cpp
37
rng.cpp
@ -51,20 +51,29 @@ byte LC_RNG::GenerateByte()
|
||||
|
||||
// ********************************************************
|
||||
|
||||
X917RNG::X917RNG(BlockTransformation *c, const byte *seed)
|
||||
X917RNG::X917RNG(BlockTransformation *c, const byte *seed, unsigned long deterministicTimeVector)
|
||||
: cipher(c),
|
||||
S(cipher->BlockSize()),
|
||||
dtbuf(S),
|
||||
randseed(seed, S),
|
||||
randbuf(S),
|
||||
randbuf_counter(0)
|
||||
randbuf_counter(0),
|
||||
m_deterministicTimeVector(deterministicTimeVector)
|
||||
{
|
||||
time_t tstamp1 = time(0);
|
||||
xorbuf(dtbuf, (byte *)&tstamp1, STDMIN((int)sizeof(tstamp1), S));
|
||||
cipher->ProcessBlock(dtbuf);
|
||||
clock_t tstamp2 = clock();
|
||||
xorbuf(dtbuf, (byte *)&tstamp2, STDMIN((int)sizeof(tstamp2), S));
|
||||
cipher->ProcessBlock(dtbuf);
|
||||
if (m_deterministicTimeVector)
|
||||
{
|
||||
memset(dtbuf, 0, S);
|
||||
memcpy(dtbuf, (byte *)&m_deterministicTimeVector, STDMIN((int)sizeof(m_deterministicTimeVector), S));
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t tstamp1 = time(0);
|
||||
xorbuf(dtbuf, (byte *)&tstamp1, STDMIN((int)sizeof(tstamp1), S));
|
||||
cipher->ProcessBlock(dtbuf);
|
||||
clock_t tstamp2 = clock();
|
||||
xorbuf(dtbuf, (byte *)&tstamp2, STDMIN((int)sizeof(tstamp2), S));
|
||||
cipher->ProcessBlock(dtbuf);
|
||||
}
|
||||
}
|
||||
|
||||
byte X917RNG::GenerateByte()
|
||||
@ -72,8 +81,16 @@ byte X917RNG::GenerateByte()
|
||||
if (randbuf_counter==0)
|
||||
{
|
||||
// calculate new enciphered timestamp
|
||||
clock_t tstamp = clock();
|
||||
xorbuf(dtbuf, (byte *)&tstamp, STDMIN((int)sizeof(tstamp), S));
|
||||
if (m_deterministicTimeVector)
|
||||
{
|
||||
xorbuf(dtbuf, (byte *)&m_deterministicTimeVector, STDMIN((int)sizeof(m_deterministicTimeVector), S));
|
||||
while (++m_deterministicTimeVector == 0) {} // skip 0
|
||||
}
|
||||
else
|
||||
{
|
||||
clock_t tstamp = clock();
|
||||
xorbuf(dtbuf, (byte *)&tstamp, STDMIN((int)sizeof(tstamp), S));
|
||||
}
|
||||
cipher->ProcessBlock(dtbuf);
|
||||
|
||||
// combine enciphered timestamp with seed
|
||||
|
5
rng.h
5
rng.h
@ -32,8 +32,8 @@ private:
|
||||
class X917RNG : public RandomNumberGenerator
|
||||
{
|
||||
public:
|
||||
// cipher will be deleted by destructor
|
||||
X917RNG(BlockTransformation *cipher, const byte *seed);
|
||||
// cipher will be deleted by destructor, deterministicTimeVector = 0 means obtain time vector from system
|
||||
X917RNG(BlockTransformation *cipher, const byte *seed, unsigned long deterministicTimeVector = 0);
|
||||
|
||||
byte GenerateByte();
|
||||
|
||||
@ -43,6 +43,7 @@ private:
|
||||
SecByteBlock dtbuf; // buffer for enciphered timestamp
|
||||
SecByteBlock randseed, randbuf;
|
||||
int randbuf_counter; // # of unused bytes left in randbuf
|
||||
unsigned long m_deterministicTimeVector;
|
||||
};
|
||||
|
||||
/** This class implements Maurer's Universal Statistical Test for Random Bit Generators
|
||||
|
@ -226,7 +226,7 @@ bool TestOS_RNG()
|
||||
member_ptr<RandomNumberGenerator> rng;
|
||||
#ifdef BLOCKING_RNG_AVAILABLE
|
||||
try {rng.reset(new BlockingRng);}
|
||||
catch (OS_RNG_Err &e) {}
|
||||
catch (OS_RNG_Err &) {}
|
||||
#endif
|
||||
|
||||
if (rng.get())
|
||||
@ -304,7 +304,7 @@ bool TestOS_RNG()
|
||||
rng.reset(NULL);
|
||||
#ifdef NONBLOCKING_RNG_AVAILABLE
|
||||
try {rng.reset(new NonblockingRng);}
|
||||
catch (OS_RNG_Err &e) {}
|
||||
catch (OS_RNG_Err &) {}
|
||||
#endif
|
||||
|
||||
if (rng.get())
|
||||
|
Loading…
Reference in New Issue
Block a user