diff options
Diffstat (limited to 'src/s2k')
-rw-r--r-- | src/s2k/pbkdf1/info.txt | 10 | ||||
-rw-r--r-- | src/s2k/pbkdf1/pbkdf1.cpp | 53 | ||||
-rw-r--r-- | src/s2k/pbkdf1/pbkdf1.h | 42 | ||||
-rw-r--r-- | src/s2k/pbkdf2/info.txt | 10 | ||||
-rw-r--r-- | src/s2k/pbkdf2/pbkdf2.cpp | 80 | ||||
-rw-r--r-- | src/s2k/pbkdf2/pbkdf2.h | 38 | ||||
-rw-r--r-- | src/s2k/pgps2k/info.txt | 10 | ||||
-rw-r--r-- | src/s2k/pgps2k/pgp_s2k.cpp | 82 | ||||
-rw-r--r-- | src/s2k/pgps2k/pgp_s2k.h | 30 | ||||
-rw-r--r-- | src/s2k/s2k.cpp | 53 | ||||
-rw-r--r-- | src/s2k/s2k.h | 97 |
11 files changed, 505 insertions, 0 deletions
diff --git a/src/s2k/pbkdf1/info.txt b/src/s2k/pbkdf1/info.txt new file mode 100644 index 000000000..3c1ae802c --- /dev/null +++ b/src/s2k/pbkdf1/info.txt @@ -0,0 +1,10 @@ +realname "Pbkdf1" + +define PBKDF1 + +load_on auto + +<add> +pbkdf1.cpp +pbkdf1.h +</add> diff --git a/src/s2k/pbkdf1/pbkdf1.cpp b/src/s2k/pbkdf1/pbkdf1.cpp new file mode 100644 index 000000000..00d1ea9ab --- /dev/null +++ b/src/s2k/pbkdf1/pbkdf1.cpp @@ -0,0 +1,53 @@ +/************************************************* +* PBKDF1 Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#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/src/s2k/pbkdf1/pbkdf1.h b/src/s2k/pbkdf1/pbkdf1.h new file mode 100644 index 000000000..99d0188db --- /dev/null +++ b/src/s2k/pbkdf1/pbkdf1.h @@ -0,0 +1,42 @@ +/************************************************* +* PBKDF1 Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_PBKDF1_H__ +#define BOTAN_PBKDF1_H__ + +#include <botan/s2k.h> +#include <botan/base.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/src/s2k/pbkdf2/info.txt b/src/s2k/pbkdf2/info.txt new file mode 100644 index 000000000..e51a331c6 --- /dev/null +++ b/src/s2k/pbkdf2/info.txt @@ -0,0 +1,10 @@ +realname "Pbkdf2" + +define PBKDF2 + +load_on auto + +<add> +pbkdf2.cpp +pbkdf2.h +</add> diff --git a/src/s2k/pbkdf2/pbkdf2.cpp b/src/s2k/pbkdf2/pbkdf2.cpp new file mode 100644 index 000000000..baa227526 --- /dev/null +++ b/src/s2k/pbkdf2/pbkdf2.cpp @@ -0,0 +1,80 @@ +/************************************************* +* PBKDF2 Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#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/src/s2k/pbkdf2/pbkdf2.h b/src/s2k/pbkdf2/pbkdf2.h new file mode 100644 index 000000000..1b27c5acb --- /dev/null +++ b/src/s2k/pbkdf2/pbkdf2.h @@ -0,0 +1,38 @@ +/************************************************* +* PBKDF2 Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_PBKDF2_H__ +#define BOTAN_PBKDF2_H__ + +#include <botan/s2k.h> +#include <botan/base.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/src/s2k/pgps2k/info.txt b/src/s2k/pgps2k/info.txt new file mode 100644 index 000000000..a3d5a146f --- /dev/null +++ b/src/s2k/pgps2k/info.txt @@ -0,0 +1,10 @@ +realname "Pgps2k" + +define PGPS2K + +load_on auto + +<add> +pgp_s2k.cpp +pgp_s2k.h +</add> diff --git a/src/s2k/pgps2k/pgp_s2k.cpp b/src/s2k/pgps2k/pgp_s2k.cpp new file mode 100644 index 000000000..66a243e45 --- /dev/null +++ b/src/s2k/pgps2k/pgp_s2k.cpp @@ -0,0 +1,82 @@ +/************************************************* +* OpenPGP S2K Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include <botan/pgp_s2k.h> +#include <botan/lookup.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); + + std::auto_ptr<HashFunction> hash(get_hash(hash_name)); + + 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_name); + } + +/************************************************* +* OpenPGP S2K Constructor * +*************************************************/ +OpenPGP_S2K::OpenPGP_S2K(const std::string& h) : hash_name(h) + { + } + +} diff --git a/src/s2k/pgps2k/pgp_s2k.h b/src/s2k/pgps2k/pgp_s2k.h new file mode 100644 index 000000000..cd263a735 --- /dev/null +++ b/src/s2k/pgps2k/pgp_s2k.h @@ -0,0 +1,30 @@ +/************************************************* +* OpenPGP S2K Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_OPENPGP_S2K_H__ +#define BOTAN_OPENPGP_S2K_H__ + +#include <botan/s2k.h> + +namespace Botan { + +/************************************************* +* OpenPGP S2K * +*************************************************/ +class BOTAN_DLL OpenPGP_S2K : public S2K + { + public: + std::string name() const; + S2K* clone() const; + OpenPGP_S2K(const std::string&); + private: + OctetString derive(u32bit, const std::string&, + const byte[], u32bit, u32bit) const; + const std::string hash_name; + }; + +} + +#endif diff --git a/src/s2k/s2k.cpp b/src/s2k/s2k.cpp new file mode 100644 index 000000000..9c67aef10 --- /dev/null +++ b/src/s2k/s2k.cpp @@ -0,0 +1,53 @@ +/************************************************* +* S2K Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#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/src/s2k/s2k.h b/src/s2k/s2k.h new file mode 100644 index 000000000..3efcff638 --- /dev/null +++ b/src/s2k/s2k.h @@ -0,0 +1,97 @@ +/************************************************* +* S2K Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#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: + virtual OctetString derive(u32bit, const std::string&, + const byte[], u32bit, u32bit) const = 0; + SecureVector<byte> salt; + u32bit iter; + }; + +} + +#endif |