diff options
-rw-r--r-- | checks/validate.cpp | 13 | ||||
-rw-r--r-- | doc/log.txt | 1 | ||||
-rw-r--r-- | src/constructs/passhash/passhash9.cpp | 33 | ||||
-rw-r--r-- | src/constructs/passhash/passhash9.h | 16 |
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 |