diff options
Diffstat (limited to 'botan/src/s2k')
-rw-r--r-- | botan/src/s2k/info.txt | 13 | ||||
-rw-r--r-- | botan/src/s2k/pbkdf1/info.txt | 14 | ||||
-rw-r--r-- | botan/src/s2k/pbkdf1/pbkdf1.cpp | 55 | ||||
-rw-r--r-- | botan/src/s2k/pbkdf1/pbkdf1.h | 44 | ||||
-rw-r--r-- | botan/src/s2k/pbkdf2/info.txt | 14 | ||||
-rw-r--r-- | botan/src/s2k/pbkdf2/pbkdf2.cpp | 82 | ||||
-rw-r--r-- | botan/src/s2k/pbkdf2/pbkdf2.h | 40 | ||||
-rw-r--r-- | botan/src/s2k/pgps2k/info.txt | 14 | ||||
-rw-r--r-- | botan/src/s2k/pgps2k/pgp_s2k.cpp | 74 | ||||
-rw-r--r-- | botan/src/s2k/pgps2k/pgp_s2k.h | 36 | ||||
-rw-r--r-- | botan/src/s2k/s2k.cpp | 55 | ||||
-rw-r--r-- | botan/src/s2k/s2k.h | 102 |
12 files changed, 543 insertions, 0 deletions
diff --git a/botan/src/s2k/info.txt b/botan/src/s2k/info.txt new file mode 100644 index 0000000..e603fd9 --- /dev/null +++ b/botan/src/s2k/info.txt @@ -0,0 +1,13 @@ +realname "String to Key Functions" + +load_on auto + +<add> +s2k.cpp +s2k.h +</add> + +<requires> +rng +sym_algo +</requires> diff --git a/botan/src/s2k/pbkdf1/info.txt b/botan/src/s2k/pbkdf1/info.txt new file mode 100644 index 0000000..4c5b275 --- /dev/null +++ b/botan/src/s2k/pbkdf1/info.txt @@ -0,0 +1,14 @@ +realname "Pbkdf1" + +define PBKDF1 + +load_on auto + +<add> +pbkdf1.cpp +pbkdf1.h +</add> + +<requires> +hash +</requires> diff --git a/botan/src/s2k/pbkdf1/pbkdf1.cpp b/botan/src/s2k/pbkdf1/pbkdf1.cpp new file mode 100644 index 0000000..04e3aa4 --- /dev/null +++ b/botan/src/s2k/pbkdf1/pbkdf1.cpp @@ -0,0 +1,55 @@ +/* +* PBKDF1 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/pbkdf1.h> + +namespace Botan { + +/* +* Return a PKCS#5 PBKDF1 derived key +*/ +OctetString PKCS5_PBKDF1::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 PBKDF1: Invalid iteration count"); + + if(key_len > hash->OUTPUT_LENGTH) + throw Exception("PKCS#5 PBKDF1: Requested output length too long"); + + hash->update(passphrase); + hash->update(salt, salt_size); + SecureVector<byte> key = hash->final(); + + for(u32bit j = 1; j != iterations; ++j) + { + hash->update(key); + hash->final(key); + } + + return OctetString(key, std::min(key_len, key.size())); + } + +/* +* Clone this type +*/ +S2K* PKCS5_PBKDF1::clone() const + { + return new PKCS5_PBKDF1(hash->clone()); + } + +/* +* Return the name of this type +*/ +std::string PKCS5_PBKDF1::name() const + { + return "PBKDF1(" + hash->name() + ")"; + } + +} diff --git a/botan/src/s2k/pbkdf1/pbkdf1.h b/botan/src/s2k/pbkdf1/pbkdf1.h new file mode 100644 index 0000000..4e5cafd --- /dev/null +++ b/botan/src/s2k/pbkdf1/pbkdf1.h @@ -0,0 +1,44 @@ +/* +* PBKDF1 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PBKDF1_H__ +#define BOTAN_PBKDF1_H__ + +#include <botan/s2k.h> +#include <botan/hash.h> + +namespace Botan { + +/** +* This class implements the PKCS #5 PBKDF1 functionality. +*/ +class BOTAN_DLL PKCS5_PBKDF1 : public S2K + { + public: + std::string name() const; + S2K* clone() const; + + /** + * Create a PKCS #5 instance using the specified hash function. + * @param hash a pointer to a hash function object to use + */ + PKCS5_PBKDF1(HashFunction* hash_in) : hash(hash_in) {} + + PKCS5_PBKDF1(const PKCS5_PBKDF1& other) : + S2K(), hash(other.hash->clone()) {} + + ~PKCS5_PBKDF1() { delete hash; } + private: + OctetString derive(u32bit, const std::string&, + const byte[], u32bit, u32bit) const; + + HashFunction* hash; + }; + +} + +#endif diff --git a/botan/src/s2k/pbkdf2/info.txt b/botan/src/s2k/pbkdf2/info.txt new file mode 100644 index 0000000..921aeb1 --- /dev/null +++ b/botan/src/s2k/pbkdf2/info.txt @@ -0,0 +1,14 @@ +realname "Pbkdf2" + +define PBKDF2 + +load_on auto + +<add> +pbkdf2.cpp +pbkdf2.h +</add> + +<requires> +mac +</requires> diff --git a/botan/src/s2k/pbkdf2/pbkdf2.cpp b/botan/src/s2k/pbkdf2/pbkdf2.cpp new file mode 100644 index 0000000..1de27c9 --- /dev/null +++ b/botan/src/s2k/pbkdf2/pbkdf2.cpp @@ -0,0 +1,82 @@ +/* +* PBKDF2 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/pbkdf2.h> +#include <botan/loadstor.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"); + + mac->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(mac->OUTPUT_LENGTH, key_len); + SecureVector<byte> U(mac->OUTPUT_LENGTH); + + mac->update(salt, salt_size); + for(u32bit j = 0; j != 4; ++j) + mac->update(get_byte(j, counter)); + mac->final(U); + xor_buf(T, U, T_size); + + for(u32bit j = 1; j != iterations; ++j) + { + mac->update(U); + mac->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(" + mac->name() + ")"; + } + +S2K* PKCS5_PBKDF2::clone() const + { + return new PKCS5_PBKDF2(mac->clone()); + } + +/* +* PKCS5_PBKDF2 Constructor +*/ +PKCS5_PBKDF2::PKCS5_PBKDF2(MessageAuthenticationCode* m) : mac(m) {} + +PKCS5_PBKDF2::~PKCS5_PBKDF2() { delete mac; } + +} diff --git a/botan/src/s2k/pbkdf2/pbkdf2.h b/botan/src/s2k/pbkdf2/pbkdf2.h new file mode 100644 index 0000000..7510338 --- /dev/null +++ b/botan/src/s2k/pbkdf2/pbkdf2.h @@ -0,0 +1,40 @@ +/* +* PBKDF2 +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_PBKDF2_H__ +#define BOTAN_PBKDF2_H__ + +#include <botan/s2k.h> +#include <botan/mac.h> + +namespace Botan { + +/** +* This class implements the PKCS #5 PBKDF2 functionality. +*/ +class BOTAN_DLL PKCS5_PBKDF2 : public S2K + { + public: + std::string name() const; + S2K* clone() const; + + /** + * Create a PKCS #5 instance using the specified message auth code + * @param mac the MAC to use + */ + PKCS5_PBKDF2(MessageAuthenticationCode* mac); + ~PKCS5_PBKDF2(); + private: + OctetString derive(u32bit, const std::string&, + const byte[], u32bit, u32bit) const; + + MessageAuthenticationCode* mac; + }; + +} + +#endif diff --git a/botan/src/s2k/pgps2k/info.txt b/botan/src/s2k/pgps2k/info.txt new file mode 100644 index 0000000..14b75a0 --- /dev/null +++ b/botan/src/s2k/pgps2k/info.txt @@ -0,0 +1,14 @@ +realname "Pgps2k" + +define PGPS2K + +load_on auto + +<add> +pgp_s2k.cpp +pgp_s2k.h +</add> + +<requires> +hash +</requires> diff --git a/botan/src/s2k/pgps2k/pgp_s2k.cpp b/botan/src/s2k/pgps2k/pgp_s2k.cpp new file mode 100644 index 0000000..86394d8 --- /dev/null +++ b/botan/src/s2k/pgps2k/pgp_s2k.cpp @@ -0,0 +1,74 @@ +/* +* OpenPGP S2K +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/pgp_s2k.h> +#include <algorithm> +#include <memory> + +namespace Botan { + +/* +* Derive a key using the OpenPGP S2K algorithm +*/ +OctetString OpenPGP_S2K::derive(u32bit key_len, const std::string& passphrase, + const byte salt_buf[], u32bit salt_size, + u32bit iterations) const + { + SecureVector<byte> key(key_len), hash_buf; + + u32bit pass = 0, generated = 0, + total_size = passphrase.size() + salt_size; + u32bit to_hash = std::max(iterations, total_size); + + hash->clear(); + while(key_len > generated) + { + for(u32bit j = 0; j != pass; ++j) + hash->update(0); + + u32bit left = to_hash; + while(left >= total_size) + { + hash->update(salt_buf, salt_size); + hash->update(passphrase); + left -= total_size; + } + if(left <= salt_size) + hash->update(salt_buf, left); + else + { + hash->update(salt_buf, salt_size); + left -= salt_size; + hash->update(reinterpret_cast<const byte*>(passphrase.data()), left); + } + + hash_buf = hash->final(); + key.copy(generated, hash_buf, hash->OUTPUT_LENGTH); + generated += hash->OUTPUT_LENGTH; + ++pass; + } + + return key; + } + +/* +* Return the name of this type +*/ +std::string OpenPGP_S2K::name() const + { + return "OpenPGP-S2K(" + hash->name() + ")"; + } + +/* +* Return a clone of this object +*/ +S2K* OpenPGP_S2K::clone() const + { + return new OpenPGP_S2K(hash->clone()); + } + +} diff --git a/botan/src/s2k/pgps2k/pgp_s2k.h b/botan/src/s2k/pgps2k/pgp_s2k.h new file mode 100644 index 0000000..00e95f7 --- /dev/null +++ b/botan/src/s2k/pgps2k/pgp_s2k.h @@ -0,0 +1,36 @@ +/* +* OpenPGP S2K +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_OPENPGP_S2K_H__ +#define BOTAN_OPENPGP_S2K_H__ + +#include <botan/s2k.h> +#include <botan/hash.h> + +namespace Botan { + +/* +* OpenPGP S2K +*/ +class BOTAN_DLL OpenPGP_S2K : public S2K + { + public: + std::string name() const; + S2K* clone() const; + + OpenPGP_S2K(HashFunction* hash_in) : hash(hash_in) {} + ~OpenPGP_S2K() { delete hash; } + private: + OctetString derive(u32bit, const std::string&, + const byte[], u32bit, u32bit) const; + + HashFunction* hash; + }; + +} + +#endif diff --git a/botan/src/s2k/s2k.cpp b/botan/src/s2k/s2k.cpp new file mode 100644 index 0000000..b8a8ef7 --- /dev/null +++ b/botan/src/s2k/s2k.cpp @@ -0,0 +1,55 @@ +/* +* S2K +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/s2k.h> + +namespace Botan { + +/* +* Derive a key from a passphrase +*/ +OctetString S2K::derive_key(u32bit key_len, + const std::string& passphrase) const + { + return derive(key_len, passphrase, salt, salt.size(), iterations()); + } + +/* +* Set the number of iterations +*/ +void S2K::set_iterations(u32bit i) + { + iter = i; + } + +/* +* Change the salt +*/ +void S2K::change_salt(const byte new_salt[], u32bit length) + { + salt.set(new_salt, length); + } + +/* +* Change the salt +*/ +void S2K::change_salt(const MemoryRegion<byte>& new_salt) + { + change_salt(new_salt.begin(), new_salt.size()); + } + +/* +* Create a new random salt +*/ +void S2K::new_random_salt(RandomNumberGenerator& rng, + u32bit length) + { + salt.create(length); + rng.randomize(salt, length); + } + +} diff --git a/botan/src/s2k/s2k.h b/botan/src/s2k/s2k.h new file mode 100644 index 0000000..7af9251 --- /dev/null +++ b/botan/src/s2k/s2k.h @@ -0,0 +1,102 @@ +/* +* S2K +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_S2K_H__ +#define BOTAN_S2K_H__ + +#include <botan/symkey.h> +#include <botan/rng.h> + +namespace Botan { + +/* +* S2K Interface +*/ +class BOTAN_DLL S2K + { + public: + /** + * Create a copy of this object. + * @return an auto_ptr to a copy of this object + */ + virtual S2K* clone() const = 0; + + /** + * Get the algorithm name. + * @return the name of this S2K algorithm + */ + virtual std::string name() const = 0; + + /** + * Clear this objects internal values. + */ + virtual void clear() {} + + /** + * Derive a key from a passphrase with this S2K object. It will use + * the salt value and number of iterations configured in this object. + * @param key_len the desired length of the key to produce + * @param passphrase the password to derive the key from + */ + OctetString derive_key(u32bit key_len, + const std::string& passphrase) const; + + /** + * Set the number of iterations for the one-way function during + * key generation. + * @param n the desired number of iterations + */ + void set_iterations(u32bit n); + + /** + * Set a new salt value. + * @param new_salt a byte array defining the new salt value + * @param len the length of the above byte array + */ + void change_salt(const byte new_salt[], u32bit len); + + /** + * Set a new salt value. + * @param new_salt the new salt value + */ + void change_salt(const MemoryRegion<byte>& new_salt); + + /** + * Create a new random salt value using the rng + * @param rng the random number generator to use + * @param len the desired length of the new salt value + */ + void new_random_salt(RandomNumberGenerator& rng, u32bit len); + + /** + * Get the number of iterations for the key derivation currently + * configured in this S2K object. + * @return the current number of iterations + */ + u32bit iterations() const { return iter; } + + /** + * Get the currently configured salt value of this S2K object. + * @return the current salt value + */ + SecureVector<byte> current_salt() const { return salt; } + + S2K() { iter = 0; } + virtual ~S2K() {} + private: + S2K(const S2K&) {} + S2K& operator=(const S2K&) { return (*this); } + + virtual OctetString derive(u32bit, const std::string&, + const byte[], u32bit, u32bit) const = 0; + SecureVector<byte> salt; + u32bit iter; + }; + +} + +#endif |