aboutsummaryrefslogtreecommitdiffstats
path: root/src/kdf/pbkdf2
diff options
context:
space:
mode:
Diffstat (limited to 'src/kdf/pbkdf2')
-rw-r--r--src/kdf/pbkdf2/modinfo.txt10
-rw-r--r--src/kdf/pbkdf2/pbkdf2.cpp81
-rw-r--r--src/kdf/pbkdf2/pbkdf2.h30
3 files changed, 121 insertions, 0 deletions
diff --git a/src/kdf/pbkdf2/modinfo.txt b/src/kdf/pbkdf2/modinfo.txt
new file mode 100644
index 000000000..e51a331c6
--- /dev/null
+++ b/src/kdf/pbkdf2/modinfo.txt
@@ -0,0 +1,10 @@
+realname "Pbkdf2"
+
+define PBKDF2
+
+load_on auto
+
+<add>
+pbkdf2.cpp
+pbkdf2.h
+</add>
diff --git a/src/kdf/pbkdf2/pbkdf2.cpp b/src/kdf/pbkdf2/pbkdf2.cpp
new file mode 100644
index 000000000..09d51d2a6
--- /dev/null
+++ b/src/kdf/pbkdf2/pbkdf2.cpp
@@ -0,0 +1,81 @@
+/*************************************************
+* PBKDF2 Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/pbkdf2.h>
+#include <botan/loadstor.h>
+#include <botan/hmac.h>
+#include <botan/lookup.h>
+#include <botan/xor_buf.h>
+
+namespace Botan {
+
+/*************************************************
+* Return a PKCS#5 PBKDF2 derived key *
+*************************************************/
+OctetString PKCS5_PBKDF2::derive(u32bit key_len,
+ const std::string& passphrase,
+ const byte salt[], u32bit salt_size,
+ u32bit iterations) const
+ {
+ if(iterations == 0)
+ throw Invalid_Argument("PKCS#5 PBKDF2: Invalid iteration count");
+
+ if(passphrase.length() == 0)
+ throw Invalid_Argument("PKCS#5 PBKDF2: Empty passphrase is invalid");
+
+ HMAC hmac(hash_name);
+
+ hmac.set_key(reinterpret_cast<const byte*>(passphrase.data()),
+ passphrase.length());
+
+ SecureVector<byte> key(key_len);
+
+ byte* T = key.begin();
+
+ u32bit counter = 1;
+ while(key_len)
+ {
+ u32bit T_size = std::min(hmac.OUTPUT_LENGTH, key_len);
+ SecureVector<byte> U(hmac.OUTPUT_LENGTH);
+
+ hmac.update(salt, salt_size);
+ for(u32bit j = 0; j != 4; ++j)
+ hmac.update(get_byte(j, counter));
+ hmac.final(U);
+ xor_buf(T, U, T_size);
+
+ for(u32bit j = 1; j != iterations; ++j)
+ {
+ hmac.update(U);
+ hmac.final(U);
+ xor_buf(T, U, T_size);
+ }
+
+ key_len -= T_size;
+ T += T_size;
+ ++counter;
+ }
+
+ return key;
+ }
+
+/*************************************************
+* Return the name of this type *
+*************************************************/
+std::string PKCS5_PBKDF2::name() const
+ {
+ return "PBKDF2(" + hash_name + ")";
+ }
+
+/*************************************************
+* PKCS5_PBKDF2 Constructor *
+*************************************************/
+PKCS5_PBKDF2::PKCS5_PBKDF2(const std::string& h_name) : hash_name(h_name)
+ {
+ if(!have_hash(hash_name))
+ throw Algorithm_Not_Found(hash_name);
+ }
+
+}
diff --git a/src/kdf/pbkdf2/pbkdf2.h b/src/kdf/pbkdf2/pbkdf2.h
new file mode 100644
index 000000000..dc6e41b9e
--- /dev/null
+++ b/src/kdf/pbkdf2/pbkdf2.h
@@ -0,0 +1,30 @@
+/*************************************************
+* PBKDF2 Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_PBKDF2_H__
+#define BOTAN_PBKDF2_H__
+
+#include <botan/s2k.h>
+
+namespace Botan {
+
+/*************************************************
+* PKCS #5 PBKDF2 *
+*************************************************/
+class BOTAN_DLL PKCS5_PBKDF2 : public S2K
+ {
+ public:
+ std::string name() const;
+ S2K* clone() const { return new PKCS5_PBKDF2(hash_name); }
+ PKCS5_PBKDF2(const std::string&);
+ private:
+ OctetString derive(u32bit, const std::string&,
+ const byte[], u32bit, u32bit) const;
+ const std::string hash_name;
+ };
+
+}
+
+#endif