[openssh-commits] [openssh] 01/07: upstream commit

git+noreply at mindrot.org git+noreply at mindrot.org
Thu May 21 16:47:10 AEST 2015


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 9173d0fbe44de7ebcad8a15618e13a8b8d78902e
Author: dtucker at openbsd.org <dtucker at openbsd.org>
Date:   Fri May 15 05:44:21 2015 +0000

    upstream commit
    
    Use a salted hash of the lock passphrase instead of plain
     text and do constant-time comparisons of it. Should prevent leaking any
     information about it via timing, pointed out by Ryan Castellucci.  Add a 0.1s
     incrementing delay for each failed unlock attempt up to 10s.  ok markus@
     (earlier version), djm@
    
    Upstream-ID: c599fcc325aa1cc65496b25220b622d22208c85f
---
 ssh-agent.c | 53 ++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 40 insertions(+), 13 deletions(-)

diff --git a/ssh-agent.c b/ssh-agent.c
index c75575f..9e2a37f 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-agent.c,v 1.202 2015/04/24 06:26:49 jmc Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.203 2015/05/15 05:44:21 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
@@ -68,6 +68,7 @@
 #include <time.h>
 #include <string.h>
 #include <unistd.h>
+#include <util.h>
 
 #include "key.h"	/* XXX for typedef */
 #include "buffer.h"	/* XXX for typedef */
@@ -140,8 +141,12 @@ char socket_name[PATH_MAX];
 char socket_dir[PATH_MAX];
 
 /* locking */
+#define LOCK_SIZE	32
+#define LOCK_SALT_SIZE	16
+#define LOCK_ROUNDS	1
 int locked = 0;
-char *lock_passwd = NULL;
+char lock_passwd[LOCK_SIZE];
+char lock_salt[LOCK_SALT_SIZE];
 
 extern char *__progname;
 
@@ -660,23 +665,45 @@ send:
 static void
 process_lock_agent(SocketEntry *e, int lock)
 {
-	int r, success = 0;
-	char *passwd;
+	int r, success = 0, delay;
+	char *passwd, passwdhash[LOCK_SIZE];
+	static u_int fail_count = 0;
+	size_t pwlen;
 
-	if ((r = sshbuf_get_cstring(e->request, &passwd, NULL)) != 0)
+	if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0)
 		fatal("%s: buffer error: %s", __func__, ssh_err(r));
-	if (locked && !lock && strcmp(passwd, lock_passwd) == 0) {
-		locked = 0;
-		explicit_bzero(lock_passwd, strlen(lock_passwd));
-		free(lock_passwd);
-		lock_passwd = NULL;
-		success = 1;
+	if (pwlen == 0) {
+		debug("empty password not supported");
+	} else if (locked && !lock) {
+		if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
+		    passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0)
+			fatal("bcrypt_pbkdf");
+		if (timingsafe_bcmp(passwdhash, lock_passwd, LOCK_SIZE) == 0) {
+			debug("agent unlocked");
+			locked = 0;
+			fail_count = 0;
+			explicit_bzero(lock_passwd, sizeof(lock_passwd));
+			success = 1;
+		} else {
+			/* delay in 0.1s increments up to 10s */
+			if (fail_count < 100)
+				fail_count++;
+			delay = 100000 * fail_count;
+			debug("unlock failed, delaying %0.1lf seconds",
+			    (double)delay/1000000);
+			usleep(delay);
+		}
+		explicit_bzero(passwdhash, sizeof(passwdhash));
 	} else if (!locked && lock) {
+		debug("agent locked");
 		locked = 1;
-		lock_passwd = xstrdup(passwd);
+		arc4random_buf(lock_salt, sizeof(lock_salt));
+		if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt),
+		    lock_passwd, sizeof(lock_passwd), LOCK_ROUNDS) < 0)
+			fatal("bcrypt_pbkdf");
 		success = 1;
 	}
-	explicit_bzero(passwd, strlen(passwd));
+	explicit_bzero(passwd, pwlen);
 	free(passwd);
 	send_status(e, success);
 }

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list