Project

General

Profile

Bug #5413 ยป 0001-Update-bcrypt-to-default-to-making-2b-hash-format.patch

Patrick Domack, 2014-12-07 06:49 PM

View differences:

usr/src/lib/crypt_modules/bsdbf/bcrypt.c
76 76
#define	BCRYPT_MINLOGROUNDS	4	/* we have log2(rounds) in salt */
77 77
#define	BCRYPT_MAXLOGROUNDS	31
78 78

  
79
char   *bcrypt_gensalt(uint8_t);
80

  
81
static void encode_salt(char *, uint8_t *, uint16_t, uint8_t);
82
static void encode_base64(uint8_t *, uint8_t *, uint16_t);
83
static void decode_base64(uint8_t *, uint16_t, uint8_t *);
84

  
85
static char    encrypted[128]; /* _PASSWORD_LEN in <pwd.h> on OpenBSD */
86
static char    gsalt[BCRYPT_MAXSALT * 4 / 3 + 1];
87
static char    error[] = ":";
88

  
89
static uint8_t Base64Code[] =
90
"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
91

  
92
static uint8_t index_64[128] =
93
{
94
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
95
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
96
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
97
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
98
	255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
99
	56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
100
	255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
101
	7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
102
	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
103
	255, 255, 255, 255, 255, 255, 28, 29, 30,
104
	31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
105
	41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
106
	51, 52, 53, 255, 255, 255, 255, 255
107
};
108
#define	CHAR64(c)	((c) > 127 ? 255 : index_64[(c)])
109

  
110
static void
111
decode_base64(uint8_t *buffer, uint16_t len, uint8_t *data)
112
{
113
	uint8_t *bp = buffer;
114
	uint8_t *p = data;
115
	uint8_t c1, c2, c3, c4;
116
	while (bp < buffer + len) {
117
		c1 = CHAR64(*p);
118
		c2 = CHAR64(*(p + 1));
119

  
120
		/* Invalid data */
121
		if (c1 == 255 || c2 == 255)
122
			break;
123

  
124
		*bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
125
		if (bp >= buffer + len)
126
			break;
127

  
128
		c3 = CHAR64(*(p + 2));
129
		if (c3 == 255)
130
			break;
131

  
132
		*bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
133
		if (bp >= buffer + len)
134
			break;
135

  
136
		c4 = CHAR64(*(p + 3));
137
		if (c4 == 255)
138
			break;
139
		*bp++ = ((c3 & 0x03) << 6) | c4;
140

  
141
		p += 4;
142
	}
143
}
79
#define	BCRYPT_SALTSPACE	(7 + (BCRYPT_MAXSALT * 4 + 2) / 3 + 1)
80
#define	BCRYPT_HASHSPACE	61
144 81

  
145
static void
146
encode_salt(char *salt, uint8_t *csalt, uint16_t clen, uint8_t logr)
147
{
148
	salt[0] = '$';
149
	salt[1] = BCRYPT_VERSION;
150
	salt[2] = 'a';
151
	salt[3] = '$';
82
char   *bcrypt_gensalt(uint8_t);
152 83

  
153
	(void) snprintf(salt + 4, 4, "%2.2u$", logr);
84
static int encode_base64(uint8_t *, uint8_t *, uint16_t);
85
static int decode_base64(uint8_t *, uint16_t, uint8_t *);
154 86

  
155
	encode_base64((uint8_t *)salt + 7, csalt, clen);
156
}
157 87
/*
158 88
 * Generates a salt for this version of crypt.
159 89
 * Since versions may change. Keeping this here
......
161 91
 */
162 92

  
163 93
char *
164
bcrypt_gensalt(uint8_t log_rounds)
94
bcrypt_initsalt(int log_rounds, uint8_t *salt, size_t saltbuflen)
165 95
{
166 96
	uint8_t csalt[BCRYPT_MAXSALT];
167 97
	uint16_t i;
......
179 109
	else if (log_rounds > BCRYPT_MAXLOGROUNDS)
180 110
		log_rounds = BCRYPT_MAXLOGROUNDS;
181 111

  
182
	encode_salt(gsalt, csalt, BCRYPT_MAXSALT, log_rounds);
183
	return (gsalt);
112
	(void) snprintf((char *)salt, saltbuflen, "$2b$%2.2u$", log_rounds);
113
	encode_base64(salt + 7, csalt, BCRYPT_MAXSALT);
114
	return (char *)(salt);
184 115
}
185 116
/*
186 117
 * We handle $Vers$log2(NumRounds)$salt+passwd$
187 118
 *  i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou
188 119
 */
189 120

  
190
char   *
191
bcrypt(key, salt)
192
	const char   *key;
193
	const char   *salt;
121
static int
122
bcrypt_hashpass(const char *key, const char *salt, char *encrypted,
123
    size_t encryptedlen)
194 124
{
195 125
	blf_ctx state;
196 126
	uint32_t rounds, i, k;
......
202 132
	uint32_t cdata[BCRYPT_BLOCKS];
203 133
	char arounds[3];
204 134

  
205
	/* Discard "$" identifier */
135
	if (encryptedlen < BCRYPT_HASHSPACE)
136
		return (-1);
137

  
138
	/* Check and discard "$" identifier */
139
	if (salt[0] != '$')
140
		return (-1);
206 141
	salt++;
207 142

  
208
	if (*salt > BCRYPT_VERSION) {
209
		/* How do I handle errors ? Return ':' */
210
		return (error);
143
	if (*salt != BCRYPT_VERSION) {
144
		return (-1);
211 145
	}
212 146

  
213 147
	/* Check for minor versions */
148
	minor = 0;
214 149
	if (salt[1] != '$') {
215
		switch (salt[1]) {
150
		switch ((minor = salt[1])) {
216 151
		    case 'a': /* 'ab' should not yield the same as 'abab' */
152
			key_len = (uint8_t)(strlen(key) + 1);
153
			salt++;
154
			break;
217 155
		    case 'b': /* cap input length at 72 bytes */
218
			minor = salt[1];
156
		    case 'y':
157
			key_len = strlen(key);
158
			if (key_len > 72)
159
				key_len = 72;
160
			key_len++; /* include the NUL */
219 161
			salt++;
220 162
			break;
221 163
		    default:
222
			return (error);
164
			return (-1);
223 165
		}
224 166
	} else
225
		minor = 0;
167
		key_len = (uint8_t)(strlen(key) + 1);
226 168

  
227 169
	/* Discard version + "$" identifier */
228 170
	salt += 2;
229 171

  
230 172
	if (salt[2] != '$')
231 173
		/* Out of sync with passwd entry */
232
		return (error);
174
		return (-1);
233 175

  
234 176
	(void) memcpy(arounds, salt, sizeof (arounds));
235 177
	if (arounds[sizeof (arounds) - 1] != '$')
236
		return (error);
178
		return (-1);
237 179
	if ((logr = atoi(arounds)) < BCRYPT_MINLOGROUNDS ||
238 180
	    logr > BCRYPT_MAXLOGROUNDS)
239
		return (error);
181
		return (-1);
240 182
	/* Computer power doesn't increase linear, 2^x should be fine */
241 183
	rounds = 1U << logr;
242 184

  
......
244 186
	salt += 3;
245 187

  
246 188
	if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
247
		return (error);
189
		return (-1);
248 190

  
249 191
	/* We dont want the base64 salt but the raw data */
250
	decode_base64(csalt, BCRYPT_MAXSALT, (uint8_t *)salt);
192
	if (decode_base64(csalt, BCRYPT_MAXSALT, (uint8_t *)salt))
193
		return (-1);
251 194
	salt_len = BCRYPT_MAXSALT;
252
	if (minor <= 'a')
253
		key_len = (uint8_t)(strlen(key) + (minor >= 'a' ? 1 : 0));
254
	else {
255
		/*
256
		 * strlen() returns a size_t, but the function calls
257
		 * below result in implicit casts to a narrower integer
258
		 * type, so cap key_len at the actual maximum supported
259
		 * length here to avoid integer wraparound
260
		 */
261
		key_len = strlen(key);
262
		if (key_len > 72)
263
			key_len = 72;
264
		key_len++; /* include the NUL */
265
	}
266 195

  
267 196
	/* Setting up S-Boxes and Subkeys */
268 197
	Blowfish_initstate(&state);
......
306 235
	encode_base64((uint8_t *)encrypted + i + 3, csalt, BCRYPT_MAXSALT);
307 236
	encode_base64((uint8_t *)encrypted + strlen(encrypted), ciphertext,
308 237
	    4 * BCRYPT_BLOCKS - 1);
309
	return (encrypted);
238
	memset(&state, 0, sizeof (state));
239
	memset(ciphertext, 0, sizeof (ciphertext));
240
	memset(csalt, 0, sizeof (csalt));
241
	memset(cdata, 0, sizeof (cdata));
242
	return (0);
310 243
}
311 244

  
312
static void
245
static const uint8_t Base64Code[] =
246
"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
247

  
248
static const uint8_t index_64[128] =
249
{
250
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
251
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
252
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
253
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
254
	255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
255
	56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
256
	255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
257
	7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
258
	17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
259
	255, 255, 255, 255, 255, 255, 28, 29, 30,
260
	31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
261
	41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
262
	51, 52, 53, 255, 255, 255, 255, 255
263
};
264
#define	CHAR64(c)	((c) > 127 ? 255 : index_64[(c)])
265

  
266
static int
267
decode_base64(uint8_t *buffer, uint16_t len, uint8_t *data)
268
{
269
	uint8_t *bp = buffer;
270
	uint8_t *p = data;
271
	uint8_t c1, c2, c3, c4;
272
	while (bp < buffer + len) {
273
		c1 = CHAR64(*p);
274
		c2 = CHAR64(*(p + 1));
275

  
276
		/* Invalid data */
277
		if (c1 == 255 || c2 == 255)
278
			return (-1);
279

  
280
		*bp++ = (c1 << 2) | ((c2 & 0x30) >> 4);
281
		if (bp >= buffer + len)
282
			break;
283

  
284
		c3 = CHAR64(*(p + 2));
285
		if (c3 == 255)
286
			return (-1);
287

  
288
		*bp++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2);
289
		if (bp >= buffer + len)
290
			break;
291

  
292
		c4 = CHAR64(*(p + 3));
293
		if (c4 == 255)
294
			return (-1);
295
		*bp++ = ((c3 & 0x03) << 6) | c4;
296

  
297
		p += 4;
298
	}
299
	return (0);
300
}
301

  
302
static int
313 303
encode_base64(uint8_t *buffer, uint8_t *data, uint16_t len)
314 304
{
315 305
	uint8_t *bp = buffer;
......
337 327
		*bp++ = Base64Code[c2 & 0x3f];
338 328
	}
339 329
	*bp = '\0';
330
	return (0);
340 331
}
332

  
333

  
334
/*
335
 * classic interface
336
 */
337
char *
338
bcrypt_gensalt(uint8_t log_rounds)
339
{
340
	static char    gsalt[BCRYPT_SALTSPACE];
341

  
342
	bcrypt_initsalt(log_rounds, (uint8_t *) gsalt, sizeof (gsalt));
343

  
344
	return (gsalt);
345
}
346

  
347
char *
348
bcrypt(const char *pass, const char *salt)
349
{
350
	static char    gencrypted[BCRYPT_HASHSPACE];
351
	static char    gerror[2];
352

  
353
	/* How do I handle errors ? Return ':' */
354
	strlcpy(gerror, ":", sizeof (gerror));
355
	if (bcrypt_hashpass(pass, salt, gencrypted, sizeof (gencrypted)) != 0)
356
		return (gerror);
357

  
358
	return (gencrypted);
359
}
360

  
341 361
#if 0
342 362
void
343 363
main()
344
- 
    (1-1/1)