diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/libc/crypt/bcrypt.c | 74 |
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); |