aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-06-07 19:45:25 +0000
committerlloyd <[email protected]>2008-06-07 19:45:25 +0000
commit64fe249a1fdfc2a41a41c6863a07b23960879293 (patch)
tree110854301a1ce39bfae3b1279c24185d03577483 /src
parentf180b1a85275279785e145d11fc3a9077400f11b (diff)
Check in the first import from InSiTo, SHA1PRNG, which implements the
Java SecureRandom PRNG algorithm. (I accidentally checked in the header in the previous revision).
Diffstat (limited to 'src')
-rw-r--r--src/sha1prng.cpp167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/sha1prng.cpp b/src/sha1prng.cpp
new file mode 100644
index 000000000..562b001bd
--- /dev/null
+++ b/src/sha1prng.cpp
@@ -0,0 +1,167 @@
+/*************************************************
+* SHA1PRNG Source File *
+* (C) 2007 FlexSecure GmbH / Manuel Hartl *
+* (C) 2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/sha1prng.h>
+#include <botan/lookup.h>
+#include <botan/bit_ops.h>
+#include <algorithm>
+
+namespace Botan {
+
+/*************************************************
+* Generate a buffer of random bytes *
+*************************************************/
+void SHA1PRNG::randomize(byte result[], u32bit length) throw(PRNG_Unseeded)
+ {
+ if(!is_seeded())
+ throw PRNG_Unseeded(name());
+
+ const u32bit SHA1_BYTES = hash->OUTPUT_LENGTH;
+
+ u32bit resultIndex=0;
+ /**
+ * use ramining bytes from buffer for result
+ */
+ if(buf_pos>0)
+ {
+ u32bit remainderCountIndex=buf_pos;
+ unsigned int j = length >= (unsigned)(SHA1_BYTES - buf_pos) ? SHA1_BYTES - buf_pos : length;
+
+ for(;resultIndex < j;resultIndex++)
+ {
+ result[resultIndex] = buffer[remainderCountIndex];
+ buffer[remainderCountIndex++] = 0;
+ }
+
+ buf_pos += j;
+ }
+
+ /**
+ * fill result with fresh random bytes
+ */
+ while(resultIndex < length)
+ {
+ hash->update(state.begin(),SHA1_BYTES);
+ hash->final(buffer.begin());
+ update_state(buffer.begin());
+ int k=length-1 <= SHA1_BYTES ? length : SHA1_BYTES;
+ for(int j = 0;j < k; j++)
+ {
+ result[resultIndex++] = buffer[j];
+ buffer[j] = 0;
+ }
+ buf_pos+=k;
+ }
+ buf_pos %=SHA1_BYTES;
+ }
+
+/*************************************************
+* Refill the internal state *
+*************************************************/
+void SHA1PRNG::update_state(byte update[])
+ {
+ signed int i = 1;
+ bool flag2 = false;
+
+ for(u32bit k = 0; k < state.size(); k++)
+ {
+ int b1 = state[k]%256;
+ if(b1>128)
+ {
+ b1-=256;
+ }
+
+ int b2 = update[k]%256;
+ if(b2>128)
+ {
+ b2-=256;
+ }
+ int j = b1+b2+i;
+ if(j>256)
+ {
+ j-=256;
+ }
+ flag2 |= state.begin()[k] != (byte)j;
+ state.begin()[k] = (byte)j;
+ i = j >> 8;
+ }
+
+ if(!flag2)
+ {
+ state[0]++;
+ }
+ }
+
+/*************************************************
+* Add entropy to internal state *
+*************************************************/
+void SHA1PRNG::add_randomness(const byte data[], u32bit length)
+ {
+ prng->add_entropy(data, length);
+ MemoryVector<byte> for_rand;
+ for_rand.set(data, length);
+
+ if(prng->is_seeded())
+ {
+ prng->randomize(for_rand, length);
+ hash->clear();
+ hash->update(for_rand,length);
+ hash->final(state.begin());
+ }
+ }
+
+/*************************************************
+* Check if the RNG is seeded *
+*************************************************/
+bool SHA1PRNG::is_seeded() const
+ {
+ return prng->is_seeded();
+ }
+
+/*************************************************
+* Clear memory of sensitive data *
+*************************************************/
+void SHA1PRNG::clear() throw()
+ {
+ hash->clear();
+ prng->clear();
+ }
+
+/*************************************************
+* Return the name of this type *
+*************************************************/
+std::string SHA1PRNG::name() const
+ {
+ return "SHA1PRNG";
+ }
+
+/*************************************************
+* SHA1PRNG Constructor *
+*************************************************/
+SHA1PRNG::SHA1PRNG(RandomNumberGenerator* prng_ptr)
+ {
+ if(!prng_ptr)
+ throw Invalid_Argument("SHA1PRNG constructor: NULL prng");
+
+ hash = get_hash("SHA-1");
+ prng = prng_ptr;
+
+ buf_pos = 0;
+
+ state.grow_to(hash->OUTPUT_LENGTH);
+ buffer.grow_to(hash->OUTPUT_LENGTH);
+ }
+
+/*************************************************
+* SHA1PRNG Destructor *
+*************************************************/
+SHA1PRNG::~SHA1PRNG()
+ {
+ delete hash;
+ delete prng;
+ }
+
+}