copy bcrypt autotune from encrypt(1) and expose via crypt_newhash
authortedu <tedu@openbsd.org>
Tue, 30 Dec 2014 10:27:24 +0000 (10:27 +0000)
committertedu <tedu@openbsd.org>
Tue, 30 Dec 2014 10:27:24 +0000 (10:27 +0000)
ok deraadt miod

lib/libc/crypt/bcrypt.c
lib/libc/crypt/cryptutil.c

index 94758ca..abcbe13 100644 (file)
@@ -1,4 +1,4 @@
-/*     $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>
@@ -224,6 +224,38 @@ bcrypt_checkpass(const char *pass, const char *goodhash)
        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
  */
index f101240..7e93dad 100644 (file)
@@ -1,4 +1,4 @@
-/* $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>
  *
@@ -21,6 +21,8 @@
 #include <login_cap.h>
 #include <errno.h>
 
+int bcrypt_autorounds(void);
+
 int
 crypt_checkpass(const char *pass, const char *goodhash)
 {
@@ -64,9 +66,13 @@ crypt_newhash(const char *pass, const char *pref, char *hash, size_t hashlen)
                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: