summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authortedu <>2014-05-03 16:33:35 +0000
committertedu <>2014-05-03 16:33:35 +0000
commit15fbf8f546dc0fe5cb255e4cdcd53ea50d1bd327 (patch)
tree48c68bbb8492a36d893348aa75a8210d13ab5c5b /src/lib
parent58df0c2f798c15843068e587fe18d9a9b0cf386a (diff)
downloadopenbsd-15fbf8f546dc0fe5cb255e4cdcd53ea50d1bd327.tar.gz
openbsd-15fbf8f546dc0fe5cb255e4cdcd53ea50d1bd327.tar.bz2
openbsd-15fbf8f546dc0fe5cb255e4cdcd53ea50d1bd327.zip
1. Drop support for no minor. This variant doesn't exist anymore.
2. Pull up the actual minor processing code into the switch that parses it. 3. atoi is actually simpler than strtonum in this case, but check the input beforehand so we don't get unexpected results. 4. Slightly more consistent style between various parse and check and increment operations on salt. ok deraadt
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libc/crypt/bcrypt.c74
1 files changed, 30 insertions, 44 deletions
diff --git a/src/lib/libc/crypt/bcrypt.c b/src/lib/libc/crypt/bcrypt.c
index 7fcb2a5187..8c6d50c0a6 100644
--- a/src/lib/libc/crypt/bcrypt.c
+++ b/src/lib/libc/crypt/bcrypt.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bcrypt.c,v 1.39 2014/04/19 15:19:20 tedu Exp $ */ 1/* $OpenBSD: bcrypt.c,v 1.40 2014/05/03 16:33:35 tedu Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> 4 * Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
@@ -94,45 +94,44 @@ bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
94 u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt"; 94 u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
95 u_int8_t csalt[BCRYPT_MAXSALT]; 95 u_int8_t csalt[BCRYPT_MAXSALT];
96 u_int32_t cdata[BCRYPT_BLOCKS]; 96 u_int32_t cdata[BCRYPT_BLOCKS];
97 char arounds[3];
98 97
99 /* Discard "$" identifier */ 98 /* Check and discard "$" identifier */
100 if (*salt != '$') 99 if (salt[0] != '$')
101 return -1; 100 return -1;
102 salt++; 101 salt += 1;
103 102
104 if (*salt != BCRYPT_VERSION) 103 if (salt[0] != BCRYPT_VERSION)
105 return -1; 104 return -1;
106 105
107 /* Check for minor versions */ 106 /* Check for minor versions */
108 if (salt[1] != '$') { 107 switch ((minor = salt[1])) {
109 switch (salt[1]) { 108 case 'a':
110 case 'a': /* 'ab' should not yield the same as 'abab' */ 109 key_len = (u_int8_t)(strlen(key) + 1);
111 case 'b': /* cap input length at 72 bytes */ 110 break;
112 minor = salt[1]; 111 case 'b':
113 salt++; 112 /* strlen() returns a size_t, but the function calls
114 if (salt[1] != '$') 113 * below result in implicit casts to a narrower integer
115 return -1; 114 * type, so cap key_len at the actual maximum supported
116 break; 115 * length here to avoid integer wraparound */
117 default: 116 key_len = strlen(key);
118 return -1; 117 if (key_len > 72)
119 } 118 key_len = 72;
120 } else 119 key_len++; /* include the NUL */
121 minor = 0; 120 break;
122 121 default:
123 /* Discard version + "$" identifier */ 122 return -1;
124 salt += 2; 123 }
125
126 if (salt[2] != '$') 124 if (salt[2] != '$')
127 /* Out of sync with passwd entry */
128 return -1; 125 return -1;
126 /* Discard version + "$" identifier */
127 salt += 3;
129 128
130 memcpy(arounds, salt, sizeof(arounds)); 129 /* Check and parse num rounds */
131 if (arounds[sizeof(arounds) - 1] != '$') 130 if (!isdigit((unsigned char)salt[0]) ||
131 !isdigit((unsigned char)salt[1]) || salt[2] != '$')
132 return -1; 132 return -1;
133 arounds[sizeof(arounds) - 1] = 0; 133 logr = atoi(salt);
134 logr = strtonum(arounds, BCRYPT_MINLOGROUNDS, 31, NULL); 134 if (logr < BCRYPT_MINLOGROUNDS || logr > 31)
135 if (logr == 0)
136 return -1; 135 return -1;
137 /* Computer power doesn't increase linearly, 2^x should be fine */ 136 /* Computer power doesn't increase linearly, 2^x should be fine */
138 rounds = 1U << logr; 137 rounds = 1U << logr;
@@ -147,18 +146,6 @@ bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
147 if (decode_base64(csalt, BCRYPT_MAXSALT, salt)) 146 if (decode_base64(csalt, BCRYPT_MAXSALT, salt))
148 return -1; 147 return -1;
149 salt_len = BCRYPT_MAXSALT; 148 salt_len = BCRYPT_MAXSALT;
150 if (minor <= 'a')
151 key_len = (u_int8_t)(strlen(key) + (minor >= 'a' ? 1 : 0));
152 else {
153 /* strlen() returns a size_t, but the function calls
154 * below result in implicit casts to a narrower integer
155 * type, so cap key_len at the actual maximum supported
156 * length here to avoid integer wraparound */
157 key_len = strlen(key);
158 if (key_len > 72)
159 key_len = 72;
160 key_len++; /* include the NUL */
161 }
162 149
163 /* Setting up S-Boxes and Subkeys */ 150 /* Setting up S-Boxes and Subkeys */
164 Blowfish_initstate(&state); 151 Blowfish_initstate(&state);
@@ -192,8 +179,7 @@ bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
192 i = 0; 179 i = 0;
193 encrypted[i++] = '$'; 180 encrypted[i++] = '$';
194 encrypted[i++] = BCRYPT_VERSION; 181 encrypted[i++] = BCRYPT_VERSION;
195 if (minor) 182 encrypted[i++] = minor;
196 encrypted[i++] = minor;
197 encrypted[i++] = '$'; 183 encrypted[i++] = '$';
198 184
199 snprintf(encrypted + i, 4, "%2.2u$", logr); 185 snprintf(encrypted + i, 4, "%2.2u$", logr);