aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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