summaryrefslogtreecommitdiff
path: root/src/lib/libc/crypt
diff options
context:
space:
mode:
authortedu <>2015-01-07 15:46:23 +0000
committertedu <>2015-01-07 15:46:23 +0000
commit5c9b3b611b1c619f5126563f11242854906c7a01 (patch)
treea8d9116352c580e672f335db5105948cd1131e79 /src/lib/libc/crypt
parentff0c9188b62e1decc7b1dffce46d25332dbf8b26 (diff)
downloadopenbsd-5c9b3b611b1c619f5126563f11242854906c7a01.tar.gz
openbsd-5c9b3b611b1c619f5126563f11242854906c7a01.tar.bz2
openbsd-5c9b3b611b1c619f5126563f11242854906c7a01.zip
set errno = EINVAL for invalid salts and hashes in most functions.
remember to set EACCES in bcrypt_checkpass for hash differences. the higher level crypt_checkpass function will reset errno to EACCES in all cases, which is probably the right behavior, but this change gives code working with the lower level functions the correct errno if they care.
Diffstat (limited to 'src/lib/libc/crypt')
-rw-r--r--src/lib/libc/crypt/bcrypt.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/src/lib/libc/crypt/bcrypt.c b/src/lib/libc/crypt/bcrypt.c
index 1114eae44e..dc174f2a4d 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.48 2015/01/05 13:10:10 tedu Exp $ */ 1/* $OpenBSD: bcrypt.c,v 1.49 2015/01/07 15:46:23 tedu Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2014 Ted Unangst <tedu@openbsd.org> 4 * Copyright (c) 2014 Ted Unangst <tedu@openbsd.org>
@@ -65,8 +65,10 @@ bcrypt_initsalt(int log_rounds, uint8_t *salt, size_t saltbuflen)
65{ 65{
66 uint8_t csalt[BCRYPT_MAXSALT]; 66 uint8_t csalt[BCRYPT_MAXSALT];
67 67
68 if (saltbuflen < BCRYPT_SALTSPACE) 68 if (saltbuflen < BCRYPT_SALTSPACE) {
69 errno = EINVAL;
69 return -1; 70 return -1;
71 }
70 72
71 arc4random_buf(csalt, sizeof(csalt)); 73 arc4random_buf(csalt, sizeof(csalt));
72 74
@@ -98,15 +100,15 @@ bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
98 u_int32_t cdata[BCRYPT_BLOCKS]; 100 u_int32_t cdata[BCRYPT_BLOCKS];
99 101
100 if (encryptedlen < BCRYPT_HASHSPACE) 102 if (encryptedlen < BCRYPT_HASHSPACE)
101 return -1; 103 goto inval;
102 104
103 /* Check and discard "$" identifier */ 105 /* Check and discard "$" identifier */
104 if (salt[0] != '$') 106 if (salt[0] != '$')
105 return -1; 107 goto inval;
106 salt += 1; 108 salt += 1;
107 109
108 if (salt[0] != BCRYPT_VERSION) 110 if (salt[0] != BCRYPT_VERSION)
109 return -1; 111 goto inval;
110 112
111 /* Check for minor versions */ 113 /* Check for minor versions */
112 switch ((minor = salt[1])) { 114 switch ((minor = salt[1])) {
@@ -124,20 +126,20 @@ bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
124 key_len++; /* include the NUL */ 126 key_len++; /* include the NUL */
125 break; 127 break;
126 default: 128 default:
127 return -1; 129 goto inval;
128 } 130 }
129 if (salt[2] != '$') 131 if (salt[2] != '$')
130 return -1; 132 goto inval;
131 /* Discard version + "$" identifier */ 133 /* Discard version + "$" identifier */
132 salt += 3; 134 salt += 3;
133 135
134 /* Check and parse num rounds */ 136 /* Check and parse num rounds */
135 if (!isdigit((unsigned char)salt[0]) || 137 if (!isdigit((unsigned char)salt[0]) ||
136 !isdigit((unsigned char)salt[1]) || salt[2] != '$') 138 !isdigit((unsigned char)salt[1]) || salt[2] != '$')
137 return -1; 139 goto inval;
138 logr = atoi(salt); 140 logr = atoi(salt);
139 if (logr < BCRYPT_MINLOGROUNDS || logr > 31) 141 if (logr < BCRYPT_MINLOGROUNDS || logr > 31)
140 return -1; 142 goto inval;
141 /* Computer power doesn't increase linearly, 2^x should be fine */ 143 /* Computer power doesn't increase linearly, 2^x should be fine */
142 rounds = 1U << logr; 144 rounds = 1U << logr;
143 145
@@ -145,11 +147,11 @@ bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
145 salt += 3; 147 salt += 3;
146 148
147 if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT) 149 if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
148 return -1; 150 goto inval;
149 151
150 /* We dont want the base64 salt but the raw data */ 152 /* We dont want the base64 salt but the raw data */
151 if (decode_base64(csalt, BCRYPT_MAXSALT, salt)) 153 if (decode_base64(csalt, BCRYPT_MAXSALT, salt))
152 return -1; 154 goto inval;
153 salt_len = BCRYPT_MAXSALT; 155 salt_len = BCRYPT_MAXSALT;
154 156
155 /* Setting up S-Boxes and Subkeys */ 157 /* Setting up S-Boxes and Subkeys */
@@ -189,6 +191,10 @@ bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
189 explicit_bzero(csalt, sizeof(csalt)); 191 explicit_bzero(csalt, sizeof(csalt));
190 explicit_bzero(cdata, sizeof(cdata)); 192 explicit_bzero(cdata, sizeof(cdata));
191 return 0; 193 return 0;
194
195inval:
196 errno = EINVAL;
197 return -1;
192} 198}
193 199
194/* 200/*
@@ -217,8 +223,10 @@ bcrypt_checkpass(const char *pass, const char *goodhash)
217 if (bcrypt_hashpass(pass, goodhash, hash, sizeof(hash)) != 0) 223 if (bcrypt_hashpass(pass, goodhash, hash, sizeof(hash)) != 0)
218 return -1; 224 return -1;
219 if (strlen(hash) != strlen(goodhash) || 225 if (strlen(hash) != strlen(goodhash) ||
220 timingsafe_bcmp(hash, goodhash, strlen(goodhash)) != 0) 226 timingsafe_bcmp(hash, goodhash, strlen(goodhash)) != 0) {
227 errno = EACCES;
221 return -1; 228 return -1;
229 }
222 230
223 explicit_bzero(hash, sizeof(hash)); 231 explicit_bzero(hash, sizeof(hash));
224 return 0; 232 return 0;