1 /* Copyright (C) 2013 Alexander Peslyak
2 * Copyright (C) 2018 Björn Esser <besser82@fedoraproject.org>
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted.
6 *
7 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
8 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
10 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
11 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
12 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
13 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
14 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
15 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
16 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
17 * SUCH DAMAGE.
18 */
19
20 #include "crypt-port.h"
21 #include "crypt-hashes.h"
22
23 #include <errno.h>
24
25 #if INCLUDE_scrypt
26
27 static int
28 check_salt_char (char ch)
29 {
30 if (ch > 'z')
31 return 0;
32 if (ch >= 'a')
33 return 1;
34 if (ch > 'Z')
35 return 0;
36 if (ch >= 'A')
37 return 1;
38 if (ch > '9')
39 return 0;
40 if (ch >= '.' || ch == '$')
41 return 1;
42 return 0;
43 }
44
45 static int
46 verify_salt (const char *setting, size_t set_size)
47 {
48 for (size_t i = 3 + 1 + 5 * 2; i < set_size; i++)
49 {
50 if (!check_salt_char (setting[i]))
51 {
52 /* Salt is terminated properly.
53 Following characters don't matter. */
54 if (setting[i - 1] == '$')
55 break;
56
57 /* Salt has an invalid character. */
58 return 0;
59 }
60 }
61 return 1;
62 }
63
64 static uint8_t *
65 encode64_uint32 (uint8_t * dst, ssize_t dstlen,
66 uint32_t src, uint32_t srcbits)
67 {
68 uint32_t bit;
69
70 for (bit = 0; bit < srcbits; bit += 6)
71 {
72 if (dstlen < 1)
73 {
74 errno = ERANGE;
75 return NULL;
76 }
77 *dst++ = ascii64[src & 0x3f];
78 dstlen--;
79 src >>= 6;
80 }
81
82 *dst = '\0';
83 return dst;
84 }
85
86 static uint8_t *
87 encode64 (uint8_t * dst, ssize_t dstlen,
88 const uint8_t * src, size_t srclen)
89 {
90 size_t i;
91
92 for (i = 0; i < srclen; )
93 {
94 uint8_t * dnext;
95 uint32_t value = 0, bits = 0;
96 do
97 {
98 value |= (uint32_t) src[i++] << bits;
99 bits += 8;
100 }
101 while (bits < 24 && i < srclen);
102 dnext = encode64_uint32 (dst, dstlen, value, bits);
103 if (!dnext)
104 {
105 errno = ERANGE;
106 return NULL;
107 }
108 dstlen -= (dnext - dst);
109 dst = dnext;
110 }
111
112 *dst = '\0';
113 return dst;
114 }
115
116 static uint32_t
117 N2log2 (uint64_t N)
118 {
119 uint32_t N_log2;
120
121 if (N < 2)
122 return 0;
123
124 N_log2 = 2;
125 while (N >> N_log2 != 0)
126 N_log2++;
127 N_log2--;
128
129 if (N >> N_log2 != 1)
130 return 0;
131
132 return N_log2;
133 }
134
135 /*
136 * Wrapper for crypt_yescrypt_rn to compute the hash.
137 */
138 void
139 crypt_scrypt_rn (const char *phrase, size_t phr_size,
140 const char *setting, size_t set_size,
141 uint8_t *output, size_t o_size,
142 void *scratch, size_t s_size)
143 {
144 if (o_size < set_size + 1 + 43 + 1 ||
145 CRYPT_OUTPUT_SIZE < set_size + 1 + 43 + 1)
146 {
147 errno = ERANGE;
148 return;
149 }
150
151 /* Setting is invalid. */
152 if (strncmp (setting, "$7$", 3) || !verify_salt (setting, set_size))
153 {
154 errno = EINVAL;
155 return;
156 }
157
158 crypt_yescrypt_rn (phrase, phr_size, setting, set_size,
159 output, o_size, scratch, s_size);
160 return;
161 }
162
163 void
164 gensalt_scrypt_rn (unsigned long count,
165 const uint8_t *rbytes, size_t nrbytes,
166 uint8_t *output, size_t o_size)
167 {
168 /* Up to 512 bits (64 bytes) of entropy for computing the salt portion
169 of the MCF-setting are supported. */
170 nrbytes = (nrbytes > 64 ? 64 : nrbytes);
171
172 if (o_size < 3 + 1 + 5 * 2 + BASE64_LEN (nrbytes) + 1 ||
173 CRYPT_GENSALT_OUTPUT_SIZE < 3 + 1 + 5 * 2 + BASE64_LEN (nrbytes) + 1)
174 {
175 errno = ERANGE;
176 return;
177 }
178
179 if ((count > 0 && count < 6) || count > 11 || nrbytes < 16)
180 {
181 errno = EINVAL;
182 return;
183 }
184
185 /* Temporary buffer for operation. The buffer is guaranteed to be
186 large enough to hold the maximum size of the generated salt. */
187 uint8_t outbuf[CRYPT_GENSALT_OUTPUT_SIZE];
188 uint8_t *out_p = outbuf + 4;
189 ssize_t out_s = CRYPT_GENSALT_OUTPUT_SIZE - (out_p - outbuf);
190
191 /* Valid cost parameters are from 6 to 11. The default is 7.
192 Any cost parameter below 6 is not to be considered strong
193 enough anymore, because using less than 32 MiBytes of RAM
194 when computing a hash is even weaker than bcrypt ($2y$).
195 These are used to set scrypt's 'N' and 'r' parameters as
196 follows:
197 N (block count) is specified in units of r (block size,
198 adjustable in steps of 128 bytes).
199
200 128 bytes * r = size of each memory block
201
202 128 bytes * r * N = total amount of memory used for hashing
203 in N blocks of r * 128 bytes.
204
205 The author of yescrypt recommends in the documentation to use
206 r=8 (a block size of 1 KiB) for total sizes of 2 MiB and less,
207 and r=32 (a block size of 4KiB) above that.
208 This has to do with the typical per-core last-level cache sizes
209 of current CPUs. */
210 if (count == 0)
211 count = 7;
212
213 uint32_t p = 1;
214 uint32_t r = 32;
215 uint64_t N = 1ULL << (count + 7); // 6 -> 8192, 7 -> 16384, ... 11 -> 262144
216
217 if (out_s > (ssize_t) BASE64_LEN (30))
218 {
219 outbuf[0] = '$';
220 outbuf[1] = '7';
221 outbuf[2] = '$';
222 outbuf[3] = ascii64[N2log2 (N)];
223
224 out_p = encode64_uint32 (out_p, out_s, r, 30);
225 out_s -= (out_p - outbuf);
226 }
227
228 if (out_p && out_s > (ssize_t) BASE64_LEN (30))
229 {
230 out_p = encode64_uint32 (out_p, out_s, p, 30);
231 out_s -= (out_p - outbuf);
232 }
233
234 if (out_p && out_s > (ssize_t) BASE64_LEN (nrbytes))
235 {
236 out_p = encode64 (out_p, out_s, rbytes, nrbytes);
237 }
238
239 if (out_p)
240 {
241 strcpy_or_abort (output, o_size, outbuf);
242 }
243
244 return;
245 }
246
247 #endif /* INCLUDE_scrypt */