aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-08-22 01:11:05 +0000
committerlloyd <[email protected]>2010-08-22 01:11:05 +0000
commitdad1a47b186ac7501f1213336d77f8cc878e99e9 (patch)
treef660f730aa59f713b432d60814c0af3ec710d32c
parente7d9701a86658efbc316ccfeaf48cec8c094fc35 (diff)
For passhash9, add another interface that allows the caller to specify
which PRF they want to use. The old interface just calls this new version with alg_id set to 0 which is HMAC(SHA-1), which was previously the only supported PRF. Assign new codepoints for HMAC(SHA-256) and CMAC(Blowfish) to allow their use with passhash9. Have the generate+check tests run a test for each supported PRF.
-rw-r--r--checks/validate.cpp13
-rw-r--r--doc/log.txt1
-rw-r--r--src/constructs/passhash/passhash9.cpp33
-rw-r--r--src/constructs/passhash/passhash9.h16
4 files changed, 45 insertions, 18 deletions
diff --git a/checks/validate.cpp b/checks/validate.cpp
index 68035f293..6e7a2e553 100644
--- a/checks/validate.cpp
+++ b/checks/validate.cpp
@@ -71,12 +71,17 @@ bool test_passhash(RandomNumberGenerator& rng)
std::cout << "." << std::flush;
- std::string gen_hash = generate_passhash9(input, rng, 5);
+ for(byte alg_id = 0; alg_id <= 2; ++alg_id)
+ {
+ std::string gen_hash = generate_passhash9(input, alg_id, rng, 1);
- if(!check_passhash9(input, gen_hash))
- return false;
+ if(!check_passhash9(input, gen_hash))
+ return false;
+
+ std::cout << "." << std::flush;
+ }
- std::cout << "." << std::endl;;
+ std::cout << std::endl;
#endif
diff --git a/doc/log.txt b/doc/log.txt
index f0982039d..755efc3f3 100644
--- a/doc/log.txt
+++ b/doc/log.txt
@@ -3,6 +3,7 @@
- Switch default PKCS #8 encryption algorithm from AES-128 to AES-256
- Use smaller tables in the first round of AES
- Allow using PBKDF2 with empty passphrases
+ - Support use of HMAC(SHA-256) and CMAC(Blowfish) in passhash9
* 1.9.10, 2010-08-12
- Add a constant time AES implementation using SSSE3
diff --git a/src/constructs/passhash/passhash9.cpp b/src/constructs/passhash/passhash9.cpp
index 920aafc4c..6618f36fa 100644
--- a/src/constructs/passhash/passhash9.cpp
+++ b/src/constructs/passhash/passhash9.cpp
@@ -23,6 +23,8 @@ const u32bit ALGID_BYTES = 1;
const u32bit SALT_BYTES = 12; // 96 bits of salt
const u32bit PASSHASH9_PBKDF_OUTPUT_LEN = 24; // 192 bits output
+const byte PASSHASH9_DEFAULT_ALGO = 0; // HMAC(SHA-1)
+
const u32bit WORK_FACTOR_SCALE = 10000;
MessageAuthenticationCode* get_pbkdf_prf(byte alg_id)
@@ -33,34 +35,37 @@ MessageAuthenticationCode* get_pbkdf_prf(byte alg_id)
{
if(alg_id == 0)
return af.make_mac("HMAC(SHA-1)");
+ else if(alg_id == 1)
+ return af.make_mac("HMAC(SHA-256)");
+ else if(alg_id == 2)
+ return af.make_mac("CMAC(Blowfish)");
}
catch(Algorithm_Not_Found) {}
return 0;
}
-std::pair<byte, MessageAuthenticationCode*> choose_pbkdf_prf()
- {
- for(byte alg_id = 0; alg_id != 255; ++alg_id)
- {
- MessageAuthenticationCode* prf = get_pbkdf_prf(alg_id);
- if(prf)
- return std::make_pair(alg_id, prf);
- }
+}
- throw Internal_Error("Passhash9: No PRF available");
+std::string generate_passhash9(const std::string& pass,
+ RandomNumberGenerator& rng,
+ u16bit work_factor)
+ {
+ return generate_passhash9(pass, PASSHASH9_DEFAULT_ALGO, rng, work_factor);
}
-}
-
std::string generate_passhash9(const std::string& pass,
+ byte alg_id,
RandomNumberGenerator& rng,
u16bit work_factor)
{
- std::pair<byte, MessageAuthenticationCode*> prf = choose_pbkdf_prf();
- byte alg_id = prf.first;
+ MessageAuthenticationCode* prf = get_pbkdf_prf(alg_id);
+
+ if(!prf)
+ throw Invalid_Argument("Passhash9: Algorithm id " + to_string(alg_id) +
+ " is not defined");
- PKCS5_PBKDF2 kdf(prf.second); // takes ownership of pointer
+ PKCS5_PBKDF2 kdf(prf); // takes ownership of pointer
SecureVector<byte> salt(SALT_BYTES);
rng.randomize(&salt[0], salt.size());
diff --git a/src/constructs/passhash/passhash9.h b/src/constructs/passhash/passhash9.h
index 8900d55d3..92cc391dc 100644
--- a/src/constructs/passhash/passhash9.h
+++ b/src/constructs/passhash/passhash9.h
@@ -23,6 +23,22 @@ std::string BOTAN_DLL generate_passhash9(const std::string& password,
u16bit work_factor = 10);
/**
+* Create a password hash using PBKDF2
+* @param password the password
+* @param alg_id specifies which PRF to use with PBKDF2
+* 0 is HMAC(SHA-1)
+* 1 is HMAC(SHA-256)
+* 2 is CMAC(Blowfish)
+* all other values are currently undefined
+* @param rng a random number generator
+* @param work_factor how much work to do to slow down guessing attacks
+*/
+std::string BOTAN_DLL generate_passhash9(const std::string& password,
+ byte alg_id,
+ RandomNumberGenerator& rng,
+ u16bit work_factor = 10);
+
+/**
* Check a previously created password hash
* @param password the password to check against
* @param hash the stored hash to check against