aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--checks/dolook.cpp6
-rw-r--r--doc/api.tex81
-rw-r--r--doc/examples/decrypt.cpp20
-rw-r--r--doc/examples/encrypt.cpp21
-rw-r--r--doc/examples/encrypt2.cpp15
-rw-r--r--doc/examples/passhash.cpp27
-rw-r--r--doc/examples/row_encryptor.cpp7
-rw-r--r--src/constructs/cryptobox/cryptobox.cpp12
-rw-r--r--src/pbe/pbes1/pbes1.cpp6
-rw-r--r--src/pbe/pbes2/pbes2.cpp6
-rw-r--r--src/s2k/pbkdf1/pbkdf1.cpp8
-rw-r--r--src/s2k/pbkdf1/pbkdf1.h8
-rw-r--r--src/s2k/pbkdf2/pbkdf2.cpp8
-rw-r--r--src/s2k/pbkdf2/pbkdf2.h8
-rw-r--r--src/s2k/pgps2k/pgp_s2k.cpp7
-rw-r--r--src/s2k/pgps2k/pgp_s2k.h8
-rw-r--r--src/s2k/s2k.cpp55
-rw-r--r--src/s2k/s2k.h58
18 files changed, 150 insertions, 211 deletions
diff --git a/checks/dolook.cpp b/checks/dolook.cpp
index 28ac60c1b..aa2d58e1f 100644
--- a/checks/dolook.cpp
+++ b/checks/dolook.cpp
@@ -60,9 +60,9 @@ class S2K_Filter : public Filter
{ passphrase += std::string(reinterpret_cast<const char*>(in), len); }
void end_msg()
{
- s2k->change_salt(salt, salt.size());
- s2k->set_iterations(iterations);
- SymmetricKey x = s2k->derive_key(outlen, passphrase);
+ SymmetricKey x = s2k->derive_key(outlen, passphrase,
+ &salt[0], salt.size(),
+ iterations);
send(x.bits_of());
}
S2K_Filter(S2K* algo, const SymmetricKey& s, u32bit o, u32bit i)
diff --git a/doc/api.tex b/doc/api.tex
index 556e76aa0..20177a9f8 100644
--- a/doc/api.tex
+++ b/doc/api.tex
@@ -2621,53 +2621,46 @@ degree of applicability.
\subsection{S2K Algorithms}
-There are various procedures (usually fairly ad-hoc) for turning a passphrase
-into a (mostly) arbitrary length key for a symmetric cipher. A general
-interface for such algorithms is presented in \filename{s2k.h}. The main
-function is \function{derive\_key}, which takes a passphrase, and the desired
-length of the output key, and returns a key of that length, deterministically
-produced from the passphrase. If an algorithm can't produce a key of that size,
-it will throw an exception (most notably, PKCS \#5's PBKDF1 can only produce
-strings between 1 and $n$ bytes, where $n$ is the output size of the underlying
-hash function).
-
-Most such algorithms allow the use of a ``salt'', which provides some extra
-randomness and helps against dictionary attacks on the passphrase. Simply call
-\function{change\_salt} (there are variations of it for most of the ways you
-might wish to specify a salt, check the header for details) with a block of
-random data. You can also have the class generate a new salt for you with
-\function{new\_random\_salt}; the salt that was generated can be retrieved with
-\function{current\_salt}.
-
-Additionally some algorithms allow you to set some sort of iteration
-count, which will make the algorithm take longer to compute the final
-key (reducing the speed of brute-force attacks of various kinds). This
-can be changed with the \function{set\_iterations} function. Most
-standards recommend an iteration count of at least 1000. Currently
-defined S2K algorithms are ``PBKDF1(digest)'', ``PBKDF2(digest)'', and
-``OpenPGP-S2K(digest)''; you can retrieve any of these using the
-\function{get\_s2k}, found in \filename{lookup.h}. As of this writing,
-``PBKDF2(SHA-256)'' with 10000 iterations and an 8 byte salt is
-recommend for new applications.
+There are various procedures (usually fairly ad-hoc) for turning a
+passphrase into a (mostly) arbitrary length key for a symmetric
+cipher. A general interface for such algorithms is presented in
+\filename{s2k.h}. The main function is \function{derive\_key}, which
+takes a passphrase, a salt, an iteration count, and the desired length
+of the output key, and returns a key of that length, deterministically
+produced from the passphrase and salt. If an algorithm can't produce a
+key of that size, it will throw an exception (most notably, PKCS \#5's
+PBKDF1 can only produce strings between 1 and $n$ bytes, where $n$ is
+the output size of the underlying hash function).
+
+The purpose of the iteration count is to make the algorithm take
+longer to compute the final key (reducing the speed of brute-force
+attacks of various kinds). Most standards recommend an iteration count
+of at least 10000. Currently defined S2K algorithms are
+``PBKDF1(digest)'', ``PBKDF2(digest)'', and ``OpenPGP-S2K(digest)'';
+you can retrieve any of these using the \function{get\_s2k}, found in
+\filename{lookup.h}. As of this writing, ``PBKDF2(SHA-256)'' with
+10000 iterations and a 16 byte salt is recommend for new applications.
\subsubsection{OpenPGP S2K}
-There are some oddities about OpenPGP's S2K algorithms that are documented
-here. For one thing, it uses the iteration count in a strange manner; instead
-of specifying how many times to iterate the hash, it tells how many
-\emph{bytes} should be hashed in total (including the salt). So the exact
-iteration count will depend on the size of the salt (which is fixed at 8 bytes
-by the OpenPGP standard, though the implementation will allow any salt size)
-and the size of the passphrase.
-
-To get what OpenPGP calls ``Simple S2K'', set iterations to 0 (the default for
-OpenPGP S2K), and do not specify a salt. To get ``Salted S2K'', again leave the
-iteration count at 0, but give an 8-byte salt. ``Salted and Iterated S2K''
-requires an 8-byte salt and some iteration count (this should be significantly
-larger than the size of the longest passphrase that might reasonably be used;
-somewhere from 1024 to 65536 would probably be about right). Using both a
-reasonably sized salt and a large iteration count is highly recommended to
-prevent password guessing attempts.
+There are some oddities about OpenPGP's S2K algorithms that are
+documented here. For one thing, it uses the iteration count in a
+strange manner; instead of specifying how many times to iterate the
+hash, it tells how many \emph{bytes} should be hashed in total
+(including the salt). So the exact iteration count will depend on the
+size of the salt (which is fixed at 8 bytes by the OpenPGP standard,
+though the implementation will allow any salt size) and the size of
+the passphrase.
+
+To get what OpenPGP calls ``Simple S2K'', set iterations to 0, and do
+not specify a salt. To get ``Salted S2K'', again leave the iteration
+count at 0, but give an 8-byte salt. ``Salted and Iterated S2K''
+requires an 8-byte salt and some iteration count (this should be
+significantly larger than the size of the longest passphrase that
+might reasonably be used; somewhere from 1024 to 65536 would probably
+be about right). Using both a reasonably sized salt and a large
+iteration count is highly recommended to prevent password guessing
+attempts.
\subsection{Checksums}
diff --git a/doc/examples/decrypt.cpp b/doc/examples/decrypt.cpp
index ebab5d804..de261b5f3 100644
--- a/doc/examples/decrypt.cpp
+++ b/doc/examples/decrypt.cpp
@@ -106,12 +106,22 @@ int main(int argc, char* argv[])
const u32bit iv_len = block_size_of(algo);
std::auto_ptr<S2K> s2k(get_s2k("PBKDF2(SHA-1)"));
- s2k->set_iterations(8192);
- s2k->change_salt(b64_decode(salt_str));
- SymmetricKey bc_key = s2k->derive_key(key_len, "BLK" + passphrase);
- InitializationVector iv = s2k->derive_key(iv_len, "IVL" + passphrase);
- SymmetricKey mac_key = s2k->derive_key(16, "MAC" + passphrase);
+ const u32bit PBKDF2_ITERATIONS = 8192;
+
+ SecureVector<byte> salt = b64_decode(salt_str);
+
+ SymmetricKey bc_key = s2k->derive_key(key_len, "BLK" + passphrase,
+ &salt[0], salt.size(),
+ PBKDF2_ITERATIONS);
+
+ InitializationVector iv = s2k->derive_key(iv_len, "IVL" + passphrase,
+ &salt[0], salt.size(),
+ PBKDF2_ITERATIONS);
+
+ SymmetricKey mac_key = s2k->derive_key(16, "MAC" + passphrase,
+ &salt[0], salt.size(),
+ PBKDF2_ITERATIONS);
Pipe pipe(new Base64_Decoder,
get_cipher(algo + "/CBC", bc_key, iv, DECRYPTION),
diff --git a/doc/examples/encrypt.cpp b/doc/examples/encrypt.cpp
index f903c2f24..4999fa086 100644
--- a/doc/examples/encrypt.cpp
+++ b/doc/examples/encrypt.cpp
@@ -125,17 +125,26 @@ int main(int argc, char* argv[])
AutoSeeded_RNG rng;
std::auto_ptr<S2K> s2k(get_s2k("PBKDF2(SHA-1)"));
- s2k->set_iterations(8192);
- s2k->new_random_salt(rng, 8);
- SymmetricKey bc_key = s2k->derive_key(key_len, "BLK" + passphrase);
- InitializationVector iv = s2k->derive_key(iv_len, "IVL" + passphrase);
- SymmetricKey mac_key = s2k->derive_key(16, "MAC" + passphrase);
+ SecureVector<byte> salt(8);
+ rng.randomize(&salt[0], salt.size());
+
+ const u32bit PBKDF2_ITERATIONS = 8192;
+
+ SymmetricKey bc_key = s2k->derive_key(key_len, "BLK" + passphrase,
+ &salt[0], salt.size(),
+ PBKDF2_ITERATIONS);
+ InitializationVector iv = s2k->derive_key(iv_len, "IVL" + passphrase,
+ &salt[0], salt.size(),
+ PBKDF2_ITERATIONS);
+ SymmetricKey mac_key = s2k->derive_key(16, "MAC" + passphrase,
+ &salt[0], salt.size(),
+ PBKDF2_ITERATIONS);
// Just to be all fancy we even write a (simple) header.
out << "-------- ENCRYPTED FILE --------" << std::endl;
out << algo << std::endl;
- out << b64_encode(s2k->current_salt()) << std::endl;
+ out << b64_encode(salt) << std::endl;
Pipe pipe(new Fork(
new Chain(new MAC_Filter("HMAC(SHA-1)", mac_key),
diff --git a/doc/examples/encrypt2.cpp b/doc/examples/encrypt2.cpp
index dac2f8314..41f4fb478 100644
--- a/doc/examples/encrypt2.cpp
+++ b/doc/examples/encrypt2.cpp
@@ -26,16 +26,21 @@ int main()
PKCS5_PBKDF2 pbkdf2(new HMAC(new SHA_160));
- pbkdf2.set_iterations(4096);
- pbkdf2.new_random_salt(rng, 8);
- SecureVector<byte> the_salt = pbkdf2.current_salt();
+ const u32bit PBKDF2_ITERATIONS = 8192;
- SecureVector<byte> master_key = pbkdf2.derive_key(48, passphrase).bits_of();
+ SecureVector<byte> salt(8);
+ rng.randomize(&salt[0], salt.size());
+
+ SecureVector<byte> master_key = pbkdf2.derive_key(48, passphrase,
+ &salt[0], salt.size(),
+ PBKDF2_ITERATIONS).bits_of();
KDF* kdf = get_kdf("KDF2(SHA-1)");
SymmetricKey key = kdf->derive_key(20, master_key, "cipher key");
+
SymmetricKey mac_key = kdf->derive_key(20, master_key, "hmac key");
+
InitializationVector iv = kdf->derive_key(8, master_key, "cipher iv");
Pipe pipe(new Fork(
@@ -50,7 +55,7 @@ int main()
)
);
- outfile.write((const char*)the_salt.begin(), the_salt.size());
+ outfile.write((const char*)salt.begin(), salt.size());
pipe.start_msg();
infile >> pipe;
diff --git a/doc/examples/passhash.cpp b/doc/examples/passhash.cpp
index 24f7ff674..8c50de072 100644
--- a/doc/examples/passhash.cpp
+++ b/doc/examples/passhash.cpp
@@ -55,18 +55,26 @@ int main(int argc, char* argv[])
return 0;
}
+const u32bit SALT_BYTES = 8; // 64 bits of salt
+const u32bit PBKDF_OUTPUT_LEN = 16; // 128 bits output
+const u32bit KDF_ITERATIONS = 100000;
+
std::string password_hash(const std::string& pass,
RandomNumberGenerator& rng)
{
PKCS5_PBKDF2 kdf(new HMAC(new SHA_160));
- kdf.set_iterations(10000);
- kdf.new_random_salt(rng, 6); // 48 bits
+ SecureVector<byte> salt(SALT_BYTES);
+ rng.randomize(&salt[0], salt.size());
+
+ // Encode the salt plus 96 bits of PBKDF2 output
Pipe pipe(new Base64_Encoder);
pipe.start_msg();
- pipe.write(kdf.current_salt());
- pipe.write(kdf.derive_key(12, pass).bits_of());
+ pipe.write(salt);
+ pipe.write(kdf.derive_key(PBKDF_OUTPUT_LEN, pass,
+ &salt[0], salt.size(),
+ KDF_ITERATIONS).bits_of());
pipe.end_msg();
return pipe.read_all_as_string();
@@ -81,12 +89,15 @@ bool password_hash_ok(const std::string& pass, const std::string& hash)
SecureVector<byte> hash_bin = pipe.read_all();
- PKCS5_PBKDF2 kdf(new HMAC(new SHA_160));
+ if(hash_bin.size() != (PBKDF_OUTPUT_LEN + SALT_BYTES))
+ return false;
- kdf.set_iterations(10000);
- kdf.change_salt(hash_bin, 6);
+ PKCS5_PBKDF2 kdf(new HMAC(new SHA_160));
- SecureVector<byte> cmp = kdf.derive_key(12, pass).bits_of();
+ SecureVector<byte> cmp = kdf.derive_key(
+ PBKDF_OUTPUT_LEN, pass,
+ &hash_bin[0], SALT_BYTES,
+ KDF_ITERATIONS).bits_of();
return same_mem(cmp.begin(), hash_bin.begin() + 6, 12);
}
diff --git a/doc/examples/row_encryptor.cpp b/doc/examples/row_encryptor.cpp
index 17f44ce7b..7c234105d 100644
--- a/doc/examples/row_encryptor.cpp
+++ b/doc/examples/row_encryptor.cpp
@@ -66,10 +66,9 @@ void Row_Encryptor::init(const std::string& passphrase)
{
std::auto_ptr<S2K> s2k(get_s2k("PBKDF2(SHA-160)"));
- s2k->set_iterations(10000);
- s2k->change_salt(&s2k_salt[0], s2k_salt.size());
-
- SecureVector<byte> key = s2k->derive_key(32, passphrase).bits_of();
+ SecureVector<byte> key = s2k->derive_key(32, passphrase,
+ &s2k_salt[0], s2k_salt.size(),
+ 10000).bits_of();
/*
Save pointers to the EAX objects so we can change the IV as needed
diff --git a/src/constructs/cryptobox/cryptobox.cpp b/src/constructs/cryptobox/cryptobox.cpp
index 20435fa59..c862b5c50 100644
--- a/src/constructs/cryptobox/cryptobox.cpp
+++ b/src/constructs/cryptobox/cryptobox.cpp
@@ -48,10 +48,10 @@ std::string encrypt(const byte input[], u32bit input_len,
rng.randomize(pbkdf_salt.begin(), pbkdf_salt.size());
PKCS5_PBKDF2 pbkdf(new HMAC(new SHA_512));
- pbkdf.change_salt(pbkdf_salt.begin(), pbkdf_salt.size());
- pbkdf.set_iterations(PBKDF_ITERATIONS);
- OctetString mk = pbkdf.derive_key(PBKDF_OUTPUT_LEN, passphrase);
+ OctetString mk = pbkdf.derive_key(PBKDF_OUTPUT_LEN, passphrase,
+ &pbkdf_salt[0], pbkdf_salt.size(),
+ PBKDF_ITERATIONS);
SymmetricKey cipher_key(mk.begin(), CIPHER_KEY_LEN);
SymmetricKey mac_key(mk.begin() + CIPHER_KEY_LEN, MAC_KEY_LEN);
@@ -109,10 +109,10 @@ std::string decrypt(const byte input[], u32bit input_len,
SecureVector<byte> pbkdf_salt(ciphertext + VERSION_CODE_LEN, PBKDF_SALT_LEN);
PKCS5_PBKDF2 pbkdf(new HMAC(new SHA_512));
- pbkdf.change_salt(pbkdf_salt.begin(), pbkdf_salt.size());
- pbkdf.set_iterations(PBKDF_ITERATIONS);
- OctetString mk = pbkdf.derive_key(PBKDF_OUTPUT_LEN, passphrase);
+ OctetString mk = pbkdf.derive_key(PBKDF_OUTPUT_LEN, passphrase,
+ &pbkdf_salt[0], pbkdf_salt.size(),
+ PBKDF_ITERATIONS);
SymmetricKey cipher_key(mk.begin(), CIPHER_KEY_LEN);
SymmetricKey mac_key(mk.begin() + CIPHER_KEY_LEN, MAC_KEY_LEN);
diff --git a/src/pbe/pbes1/pbes1.cpp b/src/pbe/pbes1/pbes1.cpp
index 1d851d1a5..36cfaa6b4 100644
--- a/src/pbe/pbes1/pbes1.cpp
+++ b/src/pbe/pbes1/pbes1.cpp
@@ -80,9 +80,9 @@ void PBE_PKCS5v15::set_key(const std::string& passphrase)
{
PKCS5_PBKDF1 pbkdf(hash_function->clone());
- pbkdf.set_iterations(iterations);
- pbkdf.change_salt(salt, salt.size());
- SymmetricKey key_and_iv = pbkdf.derive_key(16, passphrase);
+ SymmetricKey key_and_iv = pbkdf.derive_key(16, passphrase,
+ &salt[0], salt.size(),
+ iterations);
key.set(key_and_iv.begin(), 8);
iv.set(key_and_iv.begin() + 8, 8);
diff --git a/src/pbe/pbes2/pbes2.cpp b/src/pbe/pbes2/pbes2.cpp
index bd24c449b..63772263f 100644
--- a/src/pbe/pbes2/pbes2.cpp
+++ b/src/pbe/pbes2/pbes2.cpp
@@ -87,9 +87,9 @@ void PBE_PKCS5v20::set_key(const std::string& passphrase)
{
PKCS5_PBKDF2 pbkdf(new HMAC(hash_function->clone()));
- pbkdf.set_iterations(iterations);
- pbkdf.change_salt(salt, salt.size());
- key = pbkdf.derive_key(key_length, passphrase).bits_of();
+ key = pbkdf.derive_key(key_length, passphrase,
+ &salt[0], salt.size(),
+ iterations).bits_of();
}
/**
diff --git a/src/s2k/pbkdf1/pbkdf1.cpp b/src/s2k/pbkdf1/pbkdf1.cpp
index fcc5b9a97..8e521e988 100644
--- a/src/s2k/pbkdf1/pbkdf1.cpp
+++ b/src/s2k/pbkdf1/pbkdf1.cpp
@@ -12,10 +12,10 @@ 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
+OctetString PKCS5_PBKDF1::derive_key(u32bit key_len,
+ const std::string& passphrase,
+ const byte salt[], u32bit salt_size,
+ u32bit iterations) const
{
if(iterations == 0)
throw Invalid_Argument("PKCS5_PBKDF1: Invalid iteration count");
diff --git a/src/s2k/pbkdf1/pbkdf1.h b/src/s2k/pbkdf1/pbkdf1.h
index 4e5cafdb0..053a2dbe1 100644
--- a/src/s2k/pbkdf1/pbkdf1.h
+++ b/src/s2k/pbkdf1/pbkdf1.h
@@ -22,6 +22,11 @@ class BOTAN_DLL PKCS5_PBKDF1 : public S2K
std::string name() const;
S2K* clone() const;
+ OctetString derive_key(u32bit output_len,
+ const std::string& passphrase,
+ const byte salt[], u32bit salt_len,
+ u32bit iterations) const;
+
/**
* Create a PKCS #5 instance using the specified hash function.
* @param hash a pointer to a hash function object to use
@@ -33,9 +38,6 @@ class BOTAN_DLL PKCS5_PBKDF1 : public S2K
~PKCS5_PBKDF1() { delete hash; }
private:
- OctetString derive(u32bit, const std::string&,
- const byte[], u32bit, u32bit) const;
-
HashFunction* hash;
};
diff --git a/src/s2k/pbkdf2/pbkdf2.cpp b/src/s2k/pbkdf2/pbkdf2.cpp
index 6f790c06b..e7aebbfe2 100644
--- a/src/s2k/pbkdf2/pbkdf2.cpp
+++ b/src/s2k/pbkdf2/pbkdf2.cpp
@@ -14,10 +14,10 @@ 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
+OctetString PKCS5_PBKDF2::derive_key(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");
diff --git a/src/s2k/pbkdf2/pbkdf2.h b/src/s2k/pbkdf2/pbkdf2.h
index 7510338bb..b6d231916 100644
--- a/src/s2k/pbkdf2/pbkdf2.h
+++ b/src/s2k/pbkdf2/pbkdf2.h
@@ -22,6 +22,11 @@ class BOTAN_DLL PKCS5_PBKDF2 : public S2K
std::string name() const;
S2K* clone() const;
+ OctetString derive_key(u32bit output_len,
+ const std::string& passphrase,
+ const byte salt[], u32bit salt_len,
+ u32bit iterations) const;
+
/**
* Create a PKCS #5 instance using the specified message auth code
* @param mac the MAC to use
@@ -29,9 +34,6 @@ class BOTAN_DLL PKCS5_PBKDF2 : public S2K
PKCS5_PBKDF2(MessageAuthenticationCode* mac);
~PKCS5_PBKDF2();
private:
- OctetString derive(u32bit, const std::string&,
- const byte[], u32bit, u32bit) const;
-
MessageAuthenticationCode* mac;
};
diff --git a/src/s2k/pgps2k/pgp_s2k.cpp b/src/s2k/pgps2k/pgp_s2k.cpp
index 86394d84d..49ff6892c 100644
--- a/src/s2k/pgps2k/pgp_s2k.cpp
+++ b/src/s2k/pgps2k/pgp_s2k.cpp
@@ -14,9 +14,10 @@ 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
+OctetString OpenPGP_S2K::derive_key(u32bit key_len,
+ const std::string& passphrase,
+ const byte salt_buf[], u32bit salt_size,
+ u32bit iterations) const
{
SecureVector<byte> key(key_len), hash_buf;
diff --git a/src/s2k/pgps2k/pgp_s2k.h b/src/s2k/pgps2k/pgp_s2k.h
index 00e95f7fa..7f25623f3 100644
--- a/src/s2k/pgps2k/pgp_s2k.h
+++ b/src/s2k/pgps2k/pgp_s2k.h
@@ -22,12 +22,14 @@ class BOTAN_DLL OpenPGP_S2K : public S2K
std::string name() const;
S2K* clone() const;
+ OctetString derive_key(u32bit output_len,
+ const std::string& passphrase,
+ const byte salt[], u32bit salt_len,
+ u32bit iterations) 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;
};
diff --git a/src/s2k/s2k.cpp b/src/s2k/s2k.cpp
deleted file mode 100644
index 42064529d..000000000
--- a/src/s2k/s2k.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-* 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.resize(length);
- rng.randomize(salt, length);
- }
-
-}
diff --git a/src/s2k/s2k.h b/src/s2k/s2k.h
index 7af92519b..82f5abeef 100644
--- a/src/s2k/s2k.h
+++ b/src/s2k/s2k.h
@@ -39,62 +39,22 @@ class BOTAN_DLL S2K
/**
* 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 output_len the desired length of the key to produce
* @param passphrase the password to derive the key from
+ * @param salt the randomly chosen salt
+ * @param salt_len length of salt in bytes
+ * @param iterations the number of iterations to use (use 10K or more)
*/
- OctetString derive_key(u32bit key_len,
- const std::string& passphrase) const;
+ virtual OctetString derive_key(u32bit output_len,
+ const std::string& passphrase,
+ const byte salt[], u32bit salt_len,
+ u32bit iterations) const = 0;
- /**
- * 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; }
+ S2K() {}
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;
};
}