summaryrefslogtreecommitdiff
path: root/lib/libc/crypt
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2014-02-17 08:58:51 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2014-02-17 08:58:51 +0000
commit9c8c3760f65b2eea155136432a4ad68e7ef58388 (patch)
tree44fdd16bb97c2808df71fbf7e446164b9db5fa9e /lib/libc/crypt
parentb2bfcbef522c26445610375ce13c90a17365507c (diff)
sticking strlen into a char leads to wraparound at 256. fix this and
introduce a new 'b' hash minor. still generate 'a' minors for now. reported by solar designer. diff by some combination of solar and jca. ok deraadt
Diffstat (limited to 'lib/libc/crypt')
-rw-r--r--lib/libc/crypt/bcrypt.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/lib/libc/crypt/bcrypt.c b/lib/libc/crypt/bcrypt.c
index f27e77eb5fd..1d7352e3f82 100644
--- a/lib/libc/crypt/bcrypt.c
+++ b/lib/libc/crypt/bcrypt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bcrypt.c,v 1.26 2013/12/19 14:31:07 deraadt Exp $ */
+/* $OpenBSD: bcrypt.c,v 1.27 2014/02/17 08:58:50 tedu Exp $ */
/*
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
@@ -168,7 +168,8 @@ bcrypt(const char *key, const char *salt)
blf_ctx state;
u_int32_t rounds, i, k;
u_int16_t j;
- u_int8_t key_len, salt_len, logr, minor;
+ size_t key_len;
+ u_int8_t salt_len, logr, minor;
u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
u_int8_t csalt[BCRYPT_MAXSALT];
u_int32_t cdata[BCRYPT_BLOCKS];
@@ -185,8 +186,8 @@ bcrypt(const char *key, const char *salt)
/* Check for minor versions */
if (salt[1] != '$') {
switch (salt[1]) {
- case 'a':
- /* 'ab' should not yield the same as 'abab' */
+ case 'a': /* 'ab' should not yield the same as 'abab' */
+ case 'b': /* cap input length at 72 bytes */
minor = salt[1];
salt++;
break;
@@ -220,7 +221,19 @@ bcrypt(const char *key, const char *salt)
/* We dont want the base64 salt but the raw data */
decode_base64(csalt, BCRYPT_MAXSALT, (u_int8_t *) salt);
salt_len = BCRYPT_MAXSALT;
- key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
+ if (minor <= 'a')
+ key_len = (u_int8_t)(strlen(key) + (minor >= 'a' ? 1 : 0));
+ else {
+ /* strlen() returns a size_t, but the function calls
+ * below result in implicit casts to a narrower integer
+ * type, so cap key_len at the actual maximum supported
+ * length here to avoid integer wraparound */
+ key_len = strlen(key);
+ if (key_len > 72)
+ key_len = 72;
+ if (minor >= 'a')
+ key_len++; /* include the NUL */
+ }
/* Setting up S-Boxes and Subkeys */
Blowfish_initstate(&state);