1*f9151ba9Snia /* $NetBSD: bcrypt.c,v 1.22 2021/10/16 10:53:33 nia Exp $ */
2c89c003eSitojun /* $OpenBSD: bcrypt.c,v 1.16 2002/02/19 19:39:36 millert Exp $ */
3c89c003eSitojun
4c89c003eSitojun /*
5c89c003eSitojun * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
6c89c003eSitojun * All rights reserved.
7c89c003eSitojun *
8c89c003eSitojun * Redistribution and use in source and binary forms, with or without
9c89c003eSitojun * modification, are permitted provided that the following conditions
10c89c003eSitojun * are met:
11c89c003eSitojun * 1. Redistributions of source code must retain the above copyright
12c89c003eSitojun * notice, this list of conditions and the following disclaimer.
13c89c003eSitojun * 2. Redistributions in binary form must reproduce the above copyright
14c89c003eSitojun * notice, this list of conditions and the following disclaimer in the
15c89c003eSitojun * documentation and/or other materials provided with the distribution.
16c89c003eSitojun * 3. All advertising materials mentioning features or use of this software
17c89c003eSitojun * must display the following acknowledgement:
18c89c003eSitojun * This product includes software developed by Niels Provos.
19c89c003eSitojun * 4. The name of the author may not be used to endorse or promote products
20c89c003eSitojun * derived from this software without specific prior written permission.
21c89c003eSitojun *
22c89c003eSitojun * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23c89c003eSitojun * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24c89c003eSitojun * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25c89c003eSitojun * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26c89c003eSitojun * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27c89c003eSitojun * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28c89c003eSitojun * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29c89c003eSitojun * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30c89c003eSitojun * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31c89c003eSitojun * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32c89c003eSitojun */
33c89c003eSitojun
34c89c003eSitojun /* This password hashing algorithm was designed by David Mazieres
35c89c003eSitojun * <dm@lcs.mit.edu> and works as follows:
36c89c003eSitojun *
37c89c003eSitojun * 1. state := InitState ()
38c89c003eSitojun * 2. state := ExpandKey (state, salt, password) 3.
39c89c003eSitojun * REPEAT rounds:
40c89c003eSitojun * state := ExpandKey (state, 0, salt)
41c89c003eSitojun * state := ExpandKey(state, 0, password)
42c89c003eSitojun * 4. ctext := "OrpheanBeholderScryDoubt"
43c89c003eSitojun * 5. REPEAT 64:
44c89c003eSitojun * ctext := Encrypt_ECB (state, ctext);
45c89c003eSitojun * 6. RETURN Concatenate (salt, ctext);
46c89c003eSitojun *
47c89c003eSitojun */
48b91cb5beSjdolecek #include <sys/cdefs.h>
49*f9151ba9Snia __RCSID("$NetBSD: bcrypt.c,v 1.22 2021/10/16 10:53:33 nia Exp $");
50b91cb5beSjdolecek
51c89c003eSitojun #include <stdio.h>
52c89c003eSitojun #include <stdlib.h>
53c89c003eSitojun #include <sys/types.h>
54c89c003eSitojun #include <string.h>
55c89c003eSitojun #include <pwd.h>
562c53ed14Schristos #include <errno.h>
57d205f30aSchristos #include <limits.h>
58c89c003eSitojun
592c53ed14Schristos #include "crypt.h"
6090099f5fSthorpej #include "blowfish.c"
61c89c003eSitojun
62c89c003eSitojun /* This implementation is adaptable to current computing power.
63c89c003eSitojun * You can have up to 2^31 rounds which should be enough for some
64c89c003eSitojun * time to come.
65c89c003eSitojun */
66c89c003eSitojun
67c89c003eSitojun #define BCRYPT_VERSION '2'
68c89c003eSitojun #define BCRYPT_MAXSALT 16 /* Precomputation is just so nice */
696fa22775Schristos #define BCRYPT_MAXSALTLEN (7 + (BCRYPT_MAXSALT * 4 + 2) / 3 + 1)
70c89c003eSitojun #define BCRYPT_BLOCKS 6 /* Ciphertext blocks */
71c89c003eSitojun #define BCRYPT_MINROUNDS 16 /* we have log2(rounds) in salt */
72c89c003eSitojun
73c89c003eSitojun static void encode_salt(char *, u_int8_t *, u_int16_t, u_int8_t);
746fa22775Schristos static void encode_base64(u_int8_t *, u_int8_t *, u_int16_t);
75d205f30aSchristos static void decode_base64(u_int8_t *, u_int16_t, const u_int8_t *);
76c89c003eSitojun
77*f9151ba9Snia crypt_private char *__bcrypt(const char *, const char *); /* XXX */
78c89c003eSitojun
79c89c003eSitojun static char encrypted[_PASSWORD_LEN];
80c89c003eSitojun
8165b9988bSdrochner static const u_int8_t Base64Code[] =
82c89c003eSitojun "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
83c89c003eSitojun
847724b89cSchristos char *bcrypt_gensalt(u_int8_t);
857724b89cSchristos
8665b9988bSdrochner static const u_int8_t index_64[128] =
87c89c003eSitojun {
88c89c003eSitojun 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
89c89c003eSitojun 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
90c89c003eSitojun 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
91c89c003eSitojun 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
92c89c003eSitojun 255, 255, 255, 255, 255, 255, 0, 1, 54, 55,
93c89c003eSitojun 56, 57, 58, 59, 60, 61, 62, 63, 255, 255,
94c89c003eSitojun 255, 255, 255, 255, 255, 2, 3, 4, 5, 6,
95c89c003eSitojun 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
96c89c003eSitojun 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
97c89c003eSitojun 255, 255, 255, 255, 255, 255, 28, 29, 30,
98c89c003eSitojun 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
99c89c003eSitojun 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
100c89c003eSitojun 51, 52, 53, 255, 255, 255, 255, 255
101c89c003eSitojun };
102c89c003eSitojun #define CHAR64(c) ( (c) > 127 ? 255 : index_64[(c)])
103c89c003eSitojun
104c89c003eSitojun static void
decode_base64(u_int8_t * buffer,u_int16_t len,const u_int8_t * data)105d205f30aSchristos decode_base64(u_int8_t *buffer, u_int16_t len, const u_int8_t *data)
106c89c003eSitojun {
107c89c003eSitojun u_int8_t *bp = buffer;
108d205f30aSchristos const u_int8_t *p = data;
109c89c003eSitojun u_int8_t c1, c2, c3, c4;
110c89c003eSitojun while (bp < buffer + len) {
111c89c003eSitojun c1 = CHAR64(*p);
112c89c003eSitojun c2 = CHAR64(*(p + 1));
113c89c003eSitojun
114c89c003eSitojun /* Invalid data */
115c89c003eSitojun if (c1 == 255 || c2 == 255)
116c89c003eSitojun break;
117c89c003eSitojun
118d205f30aSchristos *bp++ = ((u_int32_t)c1 << 2) | (((u_int32_t)c2 & 0x30) >> 4);
119c89c003eSitojun if (bp >= buffer + len)
120c89c003eSitojun break;
121c89c003eSitojun
122c89c003eSitojun c3 = CHAR64(*(p + 2));
123c89c003eSitojun if (c3 == 255)
124c89c003eSitojun break;
125c89c003eSitojun
126d205f30aSchristos *bp++ = (((u_int32_t)c2 & 0x0f) << 4) | (((uint32_t)c3 & 0x3c) >> 2);
127c89c003eSitojun if (bp >= buffer + len)
128c89c003eSitojun break;
129c89c003eSitojun
130c89c003eSitojun c4 = CHAR64(*(p + 3));
131c89c003eSitojun if (c4 == 255)
132c89c003eSitojun break;
133c89c003eSitojun *bp++ = ((c3 & 0x03) << 6) | c4;
134c89c003eSitojun
135c89c003eSitojun p += 4;
136c89c003eSitojun }
137c89c003eSitojun }
138c89c003eSitojun
139c89c003eSitojun static void
encode_salt(char * salt,u_int8_t * csalt,u_int16_t clen,u_int8_t logr)140c89c003eSitojun encode_salt(char *salt, u_int8_t *csalt, u_int16_t clen, u_int8_t logr)
141c89c003eSitojun {
142c89c003eSitojun salt[0] = '$';
143c89c003eSitojun salt[1] = BCRYPT_VERSION;
144c89c003eSitojun salt[2] = 'a';
145c89c003eSitojun salt[3] = '$';
146c89c003eSitojun
147c89c003eSitojun snprintf(salt + 4, 4, "%2.2u$", logr);
148c89c003eSitojun
1496fa22775Schristos encode_base64((u_int8_t *) salt + 7, csalt, clen);
150c89c003eSitojun }
151c89c003eSitojun
152*f9151ba9Snia crypt_private int
__gensalt_blowfish(char * salt,size_t saltlen,const char * option)1533131ddccSchristos __gensalt_blowfish(char *salt, size_t saltlen, const char *option)
154c89c003eSitojun {
1552c53ed14Schristos size_t i;
156c89c003eSitojun u_int32_t seed = 0;
1572c53ed14Schristos u_int8_t csalt[BCRYPT_MAXSALT];
158d205f30aSchristos unsigned long nrounds;
159d205f30aSchristos char *ep;
1602c53ed14Schristos
1612c53ed14Schristos if (saltlen < BCRYPT_MAXSALTLEN) {
1622c53ed14Schristos errno = ENOSPC;
1632c53ed14Schristos return -1;
1642c53ed14Schristos }
165999ac788Smlelstv if (option == NULL) {
166999ac788Smlelstv errno = EINVAL;
167999ac788Smlelstv return -1;
168999ac788Smlelstv }
169d205f30aSchristos nrounds = strtoul(option, &ep, 0);
170d205f30aSchristos if (option == ep || *ep) {
171d205f30aSchristos errno = EINVAL;
172d205f30aSchristos return -1;
173d205f30aSchristos }
174d205f30aSchristos if (errno == ERANGE && nrounds == ULONG_MAX)
175d205f30aSchristos return -1;
1762c53ed14Schristos
1772c53ed14Schristos if (nrounds < 4)
1782c53ed14Schristos nrounds = 4;
179ccdea5dfSdrochner else if (nrounds > 31)
180ccdea5dfSdrochner nrounds = 31;
181c89c003eSitojun
182c89c003eSitojun for (i = 0; i < BCRYPT_MAXSALT; i++) {
183c89c003eSitojun if (i % 4 == 0)
184c89c003eSitojun seed = arc4random();
185c89c003eSitojun csalt[i] = seed & 0xff;
186c89c003eSitojun seed = seed >> 8;
187c89c003eSitojun }
188d205f30aSchristos encode_salt(salt, csalt, BCRYPT_MAXSALT, (u_int8_t)nrounds);
1892c53ed14Schristos return 0;
1902c53ed14Schristos }
191c89c003eSitojun
1922c53ed14Schristos /* Generates a salt for this version of crypt.
1932c53ed14Schristos Since versions may change. Keeping this here
1942c53ed14Schristos seems sensible.
1952c53ed14Schristos XXX: compat.
1962c53ed14Schristos */
1972c53ed14Schristos char *
bcrypt_gensalt(u_int8_t log_rounds)1982c53ed14Schristos bcrypt_gensalt(u_int8_t log_rounds)
1992c53ed14Schristos {
2002c53ed14Schristos static char gsalt[BCRYPT_MAXSALTLEN];
2013131ddccSchristos char num[10];
2023131ddccSchristos
2033131ddccSchristos (void)snprintf(num, sizeof(num), "%d", log_rounds);
2043131ddccSchristos if (__gensalt_blowfish(gsalt, sizeof(gsalt), num) == -1)
2052c53ed14Schristos return NULL;
206c89c003eSitojun return gsalt;
207c89c003eSitojun }
208c89c003eSitojun
209c89c003eSitojun /* We handle $Vers$log2(NumRounds)$salt+passwd$
210c89c003eSitojun i.e. $2$04$iwouldntknowwhattosayetKdJ6iFtacBqJdKe6aW7ou */
211c89c003eSitojun
212*f9151ba9Snia crypt_private char *
__bcrypt(const char * key,const char * salt)213f9113d00Smatt __bcrypt(const char *key, const char *salt)
214c89c003eSitojun {
215c89c003eSitojun blf_ctx state;
216c89c003eSitojun u_int32_t rounds, i, k;
217c89c003eSitojun u_int16_t j;
218c89c003eSitojun u_int8_t key_len, salt_len, logr, minor;
219c89c003eSitojun u_int8_t ciphertext[4 * BCRYPT_BLOCKS] = "OrpheanBeholderScryDoubt";
220c89c003eSitojun u_int8_t csalt[BCRYPT_MAXSALT];
221c89c003eSitojun u_int32_t cdata[BCRYPT_BLOCKS];
222ccdea5dfSdrochner int n;
2230d2c1e1bSchristos size_t len;
224c89c003eSitojun
225c89c003eSitojun /* Discard "$" identifier */
226c89c003eSitojun salt++;
227c89c003eSitojun
2280d2c1e1bSchristos if (*salt > BCRYPT_VERSION)
2290d2c1e1bSchristos return NULL;
230c89c003eSitojun
231c89c003eSitojun /* Check for minor versions */
232c89c003eSitojun if (salt[1] != '$') {
233c89c003eSitojun switch (salt[1]) {
234c89c003eSitojun case 'a':
235c89c003eSitojun /* 'ab' should not yield the same as 'abab' */
236c89c003eSitojun minor = salt[1];
237c89c003eSitojun salt++;
238c89c003eSitojun break;
239c89c003eSitojun default:
2400d2c1e1bSchristos return NULL;
241c89c003eSitojun }
242c89c003eSitojun } else
243c89c003eSitojun minor = 0;
244c89c003eSitojun
245c89c003eSitojun /* Discard version + "$" identifier */
246c89c003eSitojun salt += 2;
247c89c003eSitojun
248c89c003eSitojun if (salt[2] != '$')
249c89c003eSitojun /* Out of sync with passwd entry */
2500d2c1e1bSchristos return NULL;
251c89c003eSitojun
252c89c003eSitojun /* Computer power doesn't increase linear, 2^x should be fine */
253ccdea5dfSdrochner n = atoi(salt);
254ccdea5dfSdrochner if (n > 31 || n < 0)
2550d2c1e1bSchristos return NULL;
256ccdea5dfSdrochner logr = (u_int8_t)n;
257ccdea5dfSdrochner if ((rounds = (u_int32_t) 1 << logr) < BCRYPT_MINROUNDS)
2580d2c1e1bSchristos return NULL;
259c89c003eSitojun
260c89c003eSitojun /* Discard num rounds + "$" identifier */
261c89c003eSitojun salt += 3;
262c89c003eSitojun
263c89c003eSitojun if (strlen(salt) * 3 / 4 < BCRYPT_MAXSALT)
2640d2c1e1bSchristos return NULL;
265c89c003eSitojun
266c89c003eSitojun /* We dont want the base64 salt but the raw data */
267d205f30aSchristos decode_base64(csalt, BCRYPT_MAXSALT, (const u_int8_t *)salt);
268c89c003eSitojun salt_len = BCRYPT_MAXSALT;
2690d2c1e1bSchristos len = strlen(key);
2703b47f52cSchristos if (len > 72)
2713b47f52cSchristos key_len = 72;
2723b47f52cSchristos else
2733b47f52cSchristos key_len = (uint8_t)len;
2743b47f52cSchristos key_len += minor >= 'a' ? 1 : 0;
275c89c003eSitojun
276c89c003eSitojun /* Setting up S-Boxes and Subkeys */
277c89c003eSitojun Blowfish_initstate(&state);
278c89c003eSitojun Blowfish_expandstate(&state, csalt, salt_len,
279d205f30aSchristos (const u_int8_t *) key, key_len);
280c89c003eSitojun for (k = 0; k < rounds; k++) {
281d205f30aSchristos Blowfish_expand0state(&state, (const u_int8_t *) key, key_len);
282c89c003eSitojun Blowfish_expand0state(&state, csalt, salt_len);
283c89c003eSitojun }
284c89c003eSitojun
285c89c003eSitojun /* This can be precomputed later */
286c89c003eSitojun j = 0;
287c89c003eSitojun for (i = 0; i < BCRYPT_BLOCKS; i++)
288c89c003eSitojun cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_BLOCKS, &j);
289c89c003eSitojun
290c89c003eSitojun /* Now do the encryption */
291c89c003eSitojun for (k = 0; k < 64; k++)
292c89c003eSitojun blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
293c89c003eSitojun
294c89c003eSitojun for (i = 0; i < BCRYPT_BLOCKS; i++) {
295c89c003eSitojun ciphertext[4 * i + 3] = cdata[i] & 0xff;
296c89c003eSitojun cdata[i] = cdata[i] >> 8;
297c89c003eSitojun ciphertext[4 * i + 2] = cdata[i] & 0xff;
298c89c003eSitojun cdata[i] = cdata[i] >> 8;
299c89c003eSitojun ciphertext[4 * i + 1] = cdata[i] & 0xff;
300c89c003eSitojun cdata[i] = cdata[i] >> 8;
301c89c003eSitojun ciphertext[4 * i + 0] = cdata[i] & 0xff;
302c89c003eSitojun }
303c89c003eSitojun
304c89c003eSitojun
305c89c003eSitojun i = 0;
306c89c003eSitojun encrypted[i++] = '$';
307c89c003eSitojun encrypted[i++] = BCRYPT_VERSION;
308c89c003eSitojun if (minor)
309c89c003eSitojun encrypted[i++] = minor;
310c89c003eSitojun encrypted[i++] = '$';
311c89c003eSitojun
312c89c003eSitojun snprintf(encrypted + i, 4, "%2.2u$", logr);
313c89c003eSitojun
314c89c003eSitojun encode_base64((u_int8_t *) encrypted + i + 3, csalt, BCRYPT_MAXSALT);
315c89c003eSitojun encode_base64((u_int8_t *) encrypted + strlen(encrypted), ciphertext,
316c89c003eSitojun 4 * BCRYPT_BLOCKS - 1);
3171239c2bbSriastradh explicit_memset(&state, 0, sizeof(state));
318c89c003eSitojun return encrypted;
319c89c003eSitojun }
320c89c003eSitojun
3216fa22775Schristos static void
encode_base64(u_int8_t * buffer,u_int8_t * data,u_int16_t len)322c89c003eSitojun encode_base64(u_int8_t *buffer, u_int8_t *data, u_int16_t len)
323c89c003eSitojun {
324c89c003eSitojun u_int8_t *bp = buffer;
325c89c003eSitojun u_int8_t *p = data;
326c89c003eSitojun u_int8_t c1, c2;
327c89c003eSitojun while (p < data + len) {
328c89c003eSitojun c1 = *p++;
329d205f30aSchristos *bp++ = Base64Code[((u_int32_t)c1 >> 2)];
330c89c003eSitojun c1 = (c1 & 0x03) << 4;
331c89c003eSitojun if (p >= data + len) {
332c89c003eSitojun *bp++ = Base64Code[c1];
333c89c003eSitojun break;
334c89c003eSitojun }
335c89c003eSitojun c2 = *p++;
336d205f30aSchristos c1 |= ((u_int32_t)c2 >> 4) & 0x0f;
337c89c003eSitojun *bp++ = Base64Code[c1];
338c89c003eSitojun c1 = (c2 & 0x0f) << 2;
339c89c003eSitojun if (p >= data + len) {
340c89c003eSitojun *bp++ = Base64Code[c1];
341c89c003eSitojun break;
342c89c003eSitojun }
343c89c003eSitojun c2 = *p++;
344d205f30aSchristos c1 |= ((u_int32_t)c2 >> 6) & 0x03;
345c89c003eSitojun *bp++ = Base64Code[c1];
346c89c003eSitojun *bp++ = Base64Code[c2 & 0x3f];
347c89c003eSitojun }
348c89c003eSitojun *bp = '\0';
349c89c003eSitojun }
350c89c003eSitojun #if 0
351c89c003eSitojun void
352c89c003eSitojun main()
353c89c003eSitojun {
354c89c003eSitojun char blubber[73];
355c89c003eSitojun char salt[100];
356c89c003eSitojun char *p;
357c89c003eSitojun salt[0] = '$';
358c89c003eSitojun salt[1] = BCRYPT_VERSION;
359c89c003eSitojun salt[2] = '$';
360c89c003eSitojun
361c89c003eSitojun snprintf(salt + 3, 4, "%2.2u$", 5);
362c89c003eSitojun
363c89c003eSitojun printf("24 bytes of salt: ");
364c89c003eSitojun fgets(salt + 6, 94, stdin);
365c89c003eSitojun salt[99] = 0;
366c89c003eSitojun printf("72 bytes of password: ");
367c89c003eSitojun fpurge(stdin);
368c89c003eSitojun fgets(blubber, 73, stdin);
369c89c003eSitojun blubber[72] = 0;
370c89c003eSitojun
371c89c003eSitojun p = crypt(blubber, salt);
372c89c003eSitojun printf("Passwd entry: %s\n\n", p);
373c89c003eSitojun
374c89c003eSitojun p = bcrypt_gensalt(5);
375c89c003eSitojun printf("Generated salt: %s\n", p);
376c89c003eSitojun p = crypt(blubber, p);
377c89c003eSitojun printf("Passwd entry: %s\n", p);
378c89c003eSitojun }
379c89c003eSitojun #endif
380