aboutsummaryrefslogtreecommitdiffstats
path: root/src/block/blowfish/blowfish.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2011-03-08 22:18:37 +0000
committerlloyd <[email protected]>2011-03-08 22:18:37 +0000
commite8ae96510f3d87e3b142df81b51c3b15e30e77f9 (patch)
tree4f61ddba33a8e06b85ba2edc1b74d1a02e7c4739 /src/block/blowfish/blowfish.cpp
parent5f4aafe005d1031b955718fbb94d6beec3e6ea48 (diff)
parent41da07c02a36add833965be5ddc60ef1cf089beb (diff)
propagate from branch 'net.randombit.botan' (head dd068808e5bf87c982765a8bcc314996053a5bdd)
to branch 'net.randombit.botan.c++0x' (head 34696d52a8148d64f7021b3e193fc56f051b9dd2)
Diffstat (limited to 'src/block/blowfish/blowfish.cpp')
-rw-r--r--src/block/blowfish/blowfish.cpp57
1 files changed, 53 insertions, 4 deletions
diff --git a/src/block/blowfish/blowfish.cpp b/src/block/blowfish/blowfish.cpp
index ea227e93e..b6319eec0 100644
--- a/src/block/blowfish/blowfish.cpp
+++ b/src/block/blowfish/blowfish.cpp
@@ -1,6 +1,6 @@
/*
* Blowfish
-* (C) 1999-2009 Jack Lloyd
+* (C) 1999-2011 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -87,20 +87,66 @@ void Blowfish::key_schedule(const byte key[], size_t length)
{
clear();
+ const byte null_salt[16] = { 0 };
+
+ key_expansion(key, length, null_salt);
+ }
+
+void Blowfish::key_expansion(const byte key[],
+ size_t length,
+ const byte salt[16])
+ {
for(size_t i = 0, j = 0; i != 18; ++i, j += 4)
P[i] ^= make_u32bit(key[(j ) % length], key[(j+1) % length],
key[(j+2) % length], key[(j+3) % length]);
u32bit L = 0, R = 0;
- generate_sbox(P, L, R);
- generate_sbox(S, L, R);
+ generate_sbox(P, L, R, salt, 0);
+ generate_sbox(S, L, R, salt, 2);
+ }
+
+/*
+* Modified key schedule used for bcrypt password hashing
+*/
+void Blowfish::eks_key_schedule(const byte key[], size_t length,
+ const byte salt[16], size_t workfactor)
+ {
+ if(length == 0 || length >= 56)
+ throw Invalid_Key_Length("EKSBlowfish", length);
+
+ if(workfactor == 0)
+ throw std::invalid_argument("Bcrypt work factor must be at least 1");
+
+ /*
+ * On a 2.8 GHz Core-i7, workfactor == 18 takes about 25 seconds to
+ * hash a password. This seems like a reasonable upper bound for the
+ * time being.
+ */
+ if(workfactor > 18)
+ throw std::invalid_argument("Requested Bcrypt work factor too large");
+
+ clear();
+
+ const byte null_salt[16] = { 0 };
+
+ key_expansion(key, length, salt);
+
+ const size_t rounds = 1 << workfactor;
+
+ for(size_t r = 0; r != rounds; ++r)
+ {
+ key_expansion(key, length, null_salt);
+ key_expansion(salt, 16, null_salt);
+ }
}
/*
* Generate one of the Sboxes
*/
void Blowfish::generate_sbox(MemoryRegion<u32bit>& box,
- u32bit& L, u32bit& R) const
+ u32bit& L, u32bit& R,
+ const byte salt[16],
+ size_t salt_off) const
{
const u32bit* S1 = &S[0];
const u32bit* S2 = &S[256];
@@ -109,6 +155,9 @@ void Blowfish::generate_sbox(MemoryRegion<u32bit>& box,
for(size_t i = 0; i != box.size(); i += 2)
{
+ L ^= load_be<u32bit>(salt, (i + salt_off) % 4);
+ R ^= load_be<u32bit>(salt, (i + salt_off + 1) % 4);
+
for(size_t j = 0; j != 16; j += 2)
{
L ^= P[j];