summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-10-17 16:32:28 +0000
committerweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-10-17 16:32:28 +0000
commit68bd19cb320b2023aa892c2de15b419edf3f3086 (patch)
treee508ea100a61e22b1f3d56c3aa2b4479e93da51e
parent9242d66857d0199765f58148ea33821438f864e2 (diff)
downloadcryptopp-68bd19cb320b2023aa892c2de15b419edf3f3086.tar.gz
bug fixes and KAT for X9.17 RNG
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@11 57ff6487-cd31-0410-9ec3-f628ee90f5f0
-rw-r--r--Readme.txt8
-rw-r--r--algparam.cpp6
-rw-r--r--algparam.h4
-rw-r--r--cryptlib.h2
-rw-r--r--fipstest.cpp34
-rw-r--r--modes.cpp8
-rw-r--r--osrng.h25
-rw-r--r--rng.cpp37
-rw-r--r--rng.h5
-rw-r--r--validat1.cpp4
10 files changed, 103 insertions, 30 deletions
diff --git a/Readme.txt b/Readme.txt
index 37f5327..8c3c3bb 100644
--- a/Readme.txt
+++ b/Readme.txt
@@ -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
diff --git a/algparam.cpp b/algparam.cpp
index 1ef7de4..1b980b6 100644
--- a/algparam.cpp
+++ b/algparam.cpp
@@ -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)
{
diff --git a/algparam.h b/algparam.h
index 3e09d1f..624fcdc 100644
--- a/algparam.h
+++ b/algparam.h
@@ -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
{
diff --git a/cryptlib.h b/cryptlib.h
index 9be8849..b73669d 100644
--- a/cryptlib.h
+++ b/cryptlib.h
@@ -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
diff --git a/fipstest.cpp b/fipstest.cpp
index 063ab6b..5699390 100644
--- a/fipstest.cpp
+++ b/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
diff --git a/modes.cpp b/modes.cpp
index 1b5f853..a517c71 100644
--- a/modes.cpp
+++ b/modes.cpp
@@ -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;
}
}
diff --git a/osrng.h b/osrng.h
index 3a40560..c5814a5 100644
--- a/osrng.h
+++ b/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();
@@ -107,6 +109,20 @@ private:
};
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)
{
SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH);
@@ -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>
diff --git a/rng.cpp b/rng.cpp
index b16e6bd..0119d30 100644
--- a/rng.cpp
+++ b/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
diff --git a/rng.h b/rng.h
index f4afaeb..5b0998d 100644
--- a/rng.h
+++ b/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
diff --git a/validat1.cpp b/validat1.cpp
index b96a522..9c03951 100644
--- a/validat1.cpp
+++ b/validat1.cpp
@@ -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())