aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/constructs/passhash/info.txt3
-rw-r--r--src/constructs/passhash/passhash.cpp42
-rw-r--r--src/constructs/passhash/passhash.h2
3 files changed, 31 insertions, 16 deletions
diff --git a/src/constructs/passhash/info.txt b/src/constructs/passhash/info.txt
index b2f54ef0a..fdc68deac 100644
--- a/src/constructs/passhash/info.txt
+++ b/src/constructs/passhash/info.txt
@@ -1,9 +1,8 @@
define PASSHASH
<requires>
+libstate
pbkdf2
-sha2
-hmac
rng
base64
</requires>
diff --git a/src/constructs/passhash/passhash.cpp b/src/constructs/passhash/passhash.cpp
index dade15ddb..d3571808d 100644
--- a/src/constructs/passhash/passhash.cpp
+++ b/src/constructs/passhash/passhash.cpp
@@ -6,9 +6,9 @@
*/
#include <botan/passhash.h>
+#include <botan/loadstor.h>
+#include <botan/libstate.h>
#include <botan/pbkdf2.h>
-#include <botan/hmac.h>
-#include <botan/sha2_64.h>
#include <botan/base64.h>
#include <botan/pipe.h>
@@ -16,17 +16,21 @@ namespace Botan {
namespace {
-const u32bit SALT_BYTES = 8; // 64 bits of salt
+const std::string MAGIC_PREFIX = "$9$";
+const u32bit SALT_BYTES = 10; // 80 bits of salt
const u32bit PBKDF_OUTPUT_LEN = 15; // 112 bits output
const u32bit WORK_FACTOR_SCALE = 10000;
+const std::string PBKDF_MAC = "HMAC(SHA-1)";
}
std::string password_hash(const std::string& pass,
RandomNumberGenerator& rng,
- byte work_factor)
+ u16bit work_factor)
{
- PKCS5_PBKDF2 kdf(new HMAC(new SHA_512));
+ PKCS5_PBKDF2 kdf(
+ global_state().algorithm_factory().make_mac(PBKDF_MAC)
+ );
SecureVector<byte> salt(SALT_BYTES);
rng.randomize(&salt[0], salt.size());
@@ -40,40 +44,52 @@ std::string password_hash(const std::string& pass,
Pipe pipe(new Base64_Encoder);
pipe.start_msg();
- pipe.write(work_factor);
+ pipe.write(get_byte(0, work_factor));
+ pipe.write(get_byte(1, work_factor));
pipe.write(salt);
pipe.write(pbkdf2_output);
pipe.end_msg();
- return pipe.read_all_as_string();
+ return MAGIC_PREFIX + pipe.read_all_as_string();
}
bool password_hash_ok(const std::string& pass, const std::string& hash)
{
+ if(hash.size() != (36 + MAGIC_PREFIX.size()))
+ return false;
+
+ for(size_t i = 0; i != MAGIC_PREFIX.size(); ++i)
+ if(hash[i] != MAGIC_PREFIX[i])
+ return false;
+
Pipe pipe(new Base64_Decoder);
pipe.start_msg();
- pipe.write(hash);
+ pipe.write(hash.c_str() + MAGIC_PREFIX.size());
pipe.end_msg();
SecureVector<byte> bin = pipe.read_all();
- if(bin.size() != (1 + PBKDF_OUTPUT_LEN + SALT_BYTES))
+ const u32bit WORKFACTOR_BYTES = 2;
+
+ if(bin.size() != (WORKFACTOR_BYTES + PBKDF_OUTPUT_LEN + SALT_BYTES))
return false;
- u32bit kdf_iterations = WORK_FACTOR_SCALE * bin[0];
+ u32bit kdf_iterations = WORK_FACTOR_SCALE * load_be<u16bit>(bin, 0);
if(kdf_iterations == 0)
return false;
- PKCS5_PBKDF2 kdf(new HMAC(new SHA_512));
+ PKCS5_PBKDF2 kdf(
+ global_state().algorithm_factory().make_mac(PBKDF_MAC)
+ );
SecureVector<byte> cmp = kdf.derive_key(
PBKDF_OUTPUT_LEN, pass,
- &bin[1], SALT_BYTES,
+ &bin[WORKFACTOR_BYTES], SALT_BYTES,
kdf_iterations).bits_of();
return same_mem(cmp.begin(),
- bin.begin() + 1 + SALT_BYTES,
+ bin.begin() + WORKFACTOR_BYTES + SALT_BYTES,
PBKDF_OUTPUT_LEN);
}
diff --git a/src/constructs/passhash/passhash.h b/src/constructs/passhash/passhash.h
index e3b0419fe..9676ff85e 100644
--- a/src/constructs/passhash/passhash.h
+++ b/src/constructs/passhash/passhash.h
@@ -20,7 +20,7 @@ namespace Botan {
*/
std::string BOTAN_DLL password_hash(const std::string& password,
RandomNumberGenerator& rng,
- byte work_factor = 10);
+ u16bit work_factor = 10);
/**
* Check a previously created password hash