aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/credits.txt9
-rw-r--r--doc/license.txt2
-rw-r--r--include/sha1prng.h2
-rw-r--r--src/sha1prng.cpp167
4 files changed, 177 insertions, 3 deletions
diff --git a/doc/credits.txt b/doc/credits.txt
index 67a64539c..cdf6a2bba 100644
--- a/doc/credits.txt
+++ b/doc/credits.txt
@@ -17,6 +17,11 @@ D: Binary file I/O support, allocator fixes
N: Hany Greiss
D: Windows porting
+N: Manuel Hartl
+W: http://www.flexsecure.de/
+D: SHA1PRNG
+
N: Yves Jerschow
D: Optimizations for memory load/store and HMAC
@@ -32,13 +37,13 @@ D: Bzip2 compression module
S: Colorado, USA
N: Justin Karneges
-D: The Qt-related modules, X.509 API design
+D: Qt support modules (mutexes and types), X.509 API design
N: Jack Lloyd
W: http://www.randombit.net/
P: 3F69 2E64 6D92 3BBE E7AE 9258 5C0F 96E8 4EC1 6D6B
-D: Original author
+D: Original designer/author, maintainer 2001-current
S: New York NY, USA
N: Joel Low
diff --git a/doc/license.txt b/doc/license.txt
index 827bc839b..43cc7decb 100644
--- a/doc/license.txt
+++ b/doc/license.txt
@@ -5,6 +5,8 @@ Copyright (C) 1999-2008 Jack Lloyd
2005-2006 Matt Johnston
2006 Luca Piccarreta
2007 Yves Jerschow
+ 2007 FlexSecure GmbH
+ 2007 Manuel Hartl
Redistribution and use in source and binary forms, for any use, with or without
modification, is permitted provided that the following conditions are met:
diff --git a/include/sha1prng.h b/include/sha1prng.h
index e762cf069..0ba2a96a9 100644
--- a/include/sha1prng.h
+++ b/include/sha1prng.h
@@ -12,7 +12,7 @@
namespace Botan {
/*************************************************
-* SHA1PRNG (propriery *
+* SHA1PRNG *
*************************************************/
class SHA1PRNG : public RandomNumberGenerator
{
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;
+ }
+
+}