-/* $OpenBSD: bcrypt.c,v 1.46 2014/11/24 22:47:01 tedu Exp $ */
+/* $OpenBSD: bcrypt.c,v 1.47 2014/12/30 10:27:24 tedu Exp $ */
/*
* Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
return 0;
}
+/*
+ * Measure this system's performance by measuring the time for 8 rounds.
+ * We are aiming for something that takes between 0.25 and 0.5 seconds.
+ */
+int
+bcrypt_autorounds(void)
+{
+ clock_t before, after;
+ int r = 8;
+ char buf[_PASSWORD_LEN];
+ int duration;
+
+ before = clock();
+ bcrypt_newhash("testpassword", r, buf, sizeof(buf));
+ after = clock();
+
+ duration = after - before;
+
+ /* too quick? slow it down. */
+ while (r < 16 && duration <= CLOCKS_PER_SEC / 4) {
+ r += 1;
+ duration *= 2;
+ }
+ /* too slow? speed it up. */
+ while (r > 4 && duration > CLOCKS_PER_SEC / 2) {
+ r -= 1;
+ duration /= 2;
+ }
+
+ return r;
+}
+
/*
* internal utilities
*/
-/* $OpenBSD: cryptutil.c,v 1.6 2014/12/24 22:10:34 tedu Exp $ */
+/* $OpenBSD: cryptutil.c,v 1.7 2014/12/30 10:27:24 tedu Exp $ */
/*
* Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
*
#include <login_cap.h>
#include <errno.h>
+int bcrypt_autorounds(void);
+
int
crypt_checkpass(const char *pass, const char *goodhash)
{
errno = EINVAL;
goto err;
}
- rounds = strtonum(pref + 9, 4, 31, &errstr);
- if (errstr)
- goto err;
+ if (strcmp(pref + 9, "a") == 0) {
+ rounds = bcrypt_autorounds();
+ } else {
+ rounds = strtonum(pref + 9, 4, 31, &errstr);
+ if (errstr)
+ goto err;
+ }
rv = bcrypt_newhash(pass, rounds, hash, hashlen);
err: