1 /* One way encryption based on SHA256 sum.
2 Copyright (C) 2007, 2009 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@redhat.com>, 2007.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
19
20 #include <assert.h>
21 #include <errno.h>
22 #include <stdbool.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/param.h>
26
27 #include "sha256.h"
28 #include "libcrypt.h"
29
30 /* Define our magic string to mark salt for SHA256 "encryption"
31 replacement. */
32 static const char sha256_salt_prefix[] = "$5$";
33
34 /* Prefix for optional rounds specification. */
35 static const char sha256_rounds_prefix[] = "rounds=";
36
37 /* Maximum salt string length. */
38 #define SALT_LEN_MAX 16
39 /* Default number of rounds if not explicitly specified. */
40 #define ROUNDS_DEFAULT 5000
41 /* Minimum number of rounds. */
42 #define ROUNDS_MIN 1000
43 /* Maximum number of rounds. */
44 #define ROUNDS_MAX 999999999
45
46 /* Table with characters for base64 transformation. */
47 static const char b64t[64] =
48 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
49
50 #define B64_FROM_24BIT(b2, b1, b0, steps) \
51 { \
52 int n = (steps); \
53 unsigned int w = ((b2) << 16) | ((b1) << 8) | (b0); \
54 while (n-- > 0 && buflen > 0) \
55 { \
56 *cp++ = b64t[w & 0x3f]; \
57 --buflen; \
58 w >>= 6; \
59 } \
60 }
61
62 char *
__sha256_crypt_r(const char * key,const char * salt,char * buffer,int buflen)63 __sha256_crypt_r (const char *key,
64 const char *salt,
65 char *buffer,
66 int buflen)
67 {
68 unsigned char alt_result[32]
69 __attribute__ ((__aligned__ (__alignof__ (uint32_t))));
70 unsigned char temp_result[32]
71 __attribute__ ((__aligned__ (__alignof__ (uint32_t))));
72 size_t salt_len;
73 size_t key_len;
74 size_t cnt;
75 char *cp;
76 char *copied_key = NULL;
77 char *copied_salt = NULL;
78 char *p_bytes;
79 char *s_bytes;
80 /* Default number of rounds. */
81 size_t rounds = ROUNDS_DEFAULT;
82 bool rounds_custom = false;
83
84 /* Find beginning of salt string. The prefix should normally always
85 be present. Just in case it is not. */
86 if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
87 /* Skip salt prefix. */
88 salt += sizeof (sha256_salt_prefix) - 1;
89
90 if (strncmp (salt, sha256_rounds_prefix, sizeof (sha256_rounds_prefix) - 1)
91 == 0)
92 {
93 const char *num = salt + sizeof (sha256_rounds_prefix) - 1;
94 char *endp;
95 unsigned long int srounds = strtoul (num, &endp, 10);
96 if (*endp == '$')
97 {
98 salt = endp + 1;
99 rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
100 rounds_custom = true;
101 }
102 }
103
104 salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
105 key_len = strlen (key);
106
107 if ((uintptr_t)key % __alignof__ (uint32_t) != 0)
108 {
109 char *tmp = (char *) alloca (key_len + __alignof__ (uint32_t));
110 key = copied_key =
111 memcpy (tmp + __alignof__ (uint32_t)
112 - (uintptr_t)tmp % __alignof__ (uint32_t),
113 key, key_len);
114 assert ((uintptr_t)key % __alignof__ (uint32_t) == 0);
115 }
116
117 if ((uintptr_t)salt % __alignof__ (uint32_t) != 0)
118 {
119 char *tmp = (char *) alloca (salt_len + __alignof__ (uint32_t));
120 salt = copied_salt =
121 memcpy (tmp + __alignof__ (uint32_t)
122 - (uintptr_t)tmp % __alignof__ (uint32_t),
123 salt, salt_len);
124 assert ((uintptr_t)salt % __alignof__ (uint32_t) == 0);
125 }
126
127 struct sha256_ctx ctx;
128 struct sha256_ctx alt_ctx;
129
130 /* Prepare for the real work. */
131 __sha256_init_ctx (&ctx);
132
133 /* Add the key string. */
134 __sha256_process_bytes (key, key_len, &ctx);
135
136 /* The last part is the salt string. This must be at most 16
137 characters and it ends at the first `$' character. */
138 __sha256_process_bytes (salt, salt_len, &ctx);
139
140
141 /* Compute alternate SHA256 sum with input KEY, SALT, and KEY. The
142 final result will be added to the first context. */
143 __sha256_init_ctx (&alt_ctx);
144
145 /* Add key. */
146 __sha256_process_bytes (key, key_len, &alt_ctx);
147
148 /* Add salt. */
149 __sha256_process_bytes (salt, salt_len, &alt_ctx);
150
151 /* Add key again. */
152 __sha256_process_bytes (key, key_len, &alt_ctx);
153
154 /* Now get result of this (32 bytes) and add it to the other
155 context. */
156 __sha256_finish_ctx (&alt_ctx, alt_result);
157
158 /* Add for any character in the key one byte of the alternate sum. */
159 for (cnt = key_len; cnt > 32; cnt -= 32)
160 __sha256_process_bytes (alt_result, 32, &ctx);
161 __sha256_process_bytes (alt_result, cnt, &ctx);
162
163 /* Take the binary representation of the length of the key and for every
164 1 add the alternate sum, for every 0 the key. */
165 for (cnt = key_len; cnt > 0; cnt >>= 1)
166 if ((cnt & 1) != 0)
167 __sha256_process_bytes (alt_result, 32, &ctx);
168 else
169 __sha256_process_bytes (key, key_len, &ctx);
170
171 /* Create intermediate result. */
172 __sha256_finish_ctx (&ctx, alt_result);
173
174 /* Start computation of P byte sequence. */
175 __sha256_init_ctx (&alt_ctx);
176
177 /* For every character in the password add the entire password. */
178 for (cnt = 0; cnt < key_len; ++cnt)
179 __sha256_process_bytes (key, key_len, &alt_ctx);
180
181 /* Finish the digest. */
182 __sha256_finish_ctx (&alt_ctx, temp_result);
183
184 /* Create byte sequence P. */
185 cp = p_bytes = alloca (key_len);
186 for (cnt = key_len; cnt >= 32; cnt -= 32)
187 cp = mempcpy (cp, temp_result, 32);
188 memcpy (cp, temp_result, cnt);
189
190 /* Start computation of S byte sequence. */
191 __sha256_init_ctx (&alt_ctx);
192
193 /* For every character in the password add the entire password. */
194 for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
195 __sha256_process_bytes (salt, salt_len, &alt_ctx);
196
197 /* Finish the digest. */
198 __sha256_finish_ctx (&alt_ctx, temp_result);
199
200 /* Create byte sequence S. */
201 cp = s_bytes = alloca (salt_len);
202 for (cnt = salt_len; cnt >= 32; cnt -= 32)
203 cp = mempcpy (cp, temp_result, 32);
204 memcpy (cp, temp_result, cnt);
205
206 /* Repeatedly run the collected hash value through SHA256 to burn
207 CPU cycles. */
208 for (cnt = 0; cnt < rounds; ++cnt)
209 {
210 /* New context. */
211 __sha256_init_ctx (&ctx);
212
213 /* Add key or last result. */
214 if ((cnt & 1) != 0)
215 __sha256_process_bytes (p_bytes, key_len, &ctx);
216 else
217 __sha256_process_bytes (alt_result, 32, &ctx);
218
219 /* Add salt for numbers not divisible by 3. */
220 if (cnt % 3 != 0)
221 __sha256_process_bytes (s_bytes, salt_len, &ctx);
222
223 /* Add key for numbers not divisible by 7. */
224 if (cnt % 7 != 0)
225 __sha256_process_bytes (p_bytes, key_len, &ctx);
226
227 /* Add key or last result. */
228 if ((cnt & 1) != 0)
229 __sha256_process_bytes (alt_result, 32, &ctx);
230 else
231 __sha256_process_bytes (p_bytes, key_len, &ctx);
232
233 /* Create intermediate result. */
234 __sha256_finish_ctx (&ctx, alt_result);
235 }
236
237 /* Now we can construct the result string. It consists of three
238 parts. */
239 cp = stpncpy (buffer, sha256_salt_prefix, MAX (0, buflen));
240 buflen -= sizeof (sha256_salt_prefix) - 1;
241
242 if (rounds_custom)
243 {
244 int n = snprintf (cp, MAX (0, buflen), "%s%zu$",
245 sha256_rounds_prefix, rounds);
246 cp += n;
247 buflen -= n;
248 }
249
250 cp = stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
251 buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
252
253 if (buflen > 0)
254 {
255 *cp++ = '$';
256 --buflen;
257 }
258
259 B64_FROM_24BIT (alt_result[0], alt_result[10], alt_result[20], 4);
260 B64_FROM_24BIT (alt_result[21], alt_result[1], alt_result[11], 4);
261 B64_FROM_24BIT (alt_result[12], alt_result[22], alt_result[2], 4);
262 B64_FROM_24BIT (alt_result[3], alt_result[13], alt_result[23], 4);
263 B64_FROM_24BIT (alt_result[24], alt_result[4], alt_result[14], 4);
264 B64_FROM_24BIT (alt_result[15], alt_result[25], alt_result[5], 4);
265 B64_FROM_24BIT (alt_result[6], alt_result[16], alt_result[26], 4);
266 B64_FROM_24BIT (alt_result[27], alt_result[7], alt_result[17], 4);
267 B64_FROM_24BIT (alt_result[18], alt_result[28], alt_result[8], 4);
268 B64_FROM_24BIT (alt_result[9], alt_result[19], alt_result[29], 4);
269 B64_FROM_24BIT (0, alt_result[31], alt_result[30], 3);
270 if (buflen <= 0)
271 {
272 __set_errno (ERANGE);
273 buffer = NULL;
274 }
275 else
276 *cp = '\0'; /* Terminate the string. */
277
278 /* Clear the buffer for the intermediate result so that people
279 attaching to processes or reading core dumps cannot get any
280 information. We do it in this way to clear correct_words[]
281 inside the SHA256 implementation as well. */
282 __sha256_init_ctx (&ctx);
283 __sha256_finish_ctx (&ctx, alt_result);
284 memset (&ctx, '\0', sizeof (ctx));
285 memset (&alt_ctx, '\0', sizeof (alt_ctx));
286
287 memset (temp_result, '\0', sizeof (temp_result));
288 memset (p_bytes, '\0', key_len);
289 memset (s_bytes, '\0', salt_len);
290 if (copied_key != NULL)
291 memset (copied_key, '\0', key_len);
292 if (copied_salt != NULL)
293 memset (copied_salt, '\0', salt_len);
294
295 return buffer;
296 }
297
298 static char *buffer;
299
300 /* This entry point is equivalent to the `crypt' function in Unix
301 libcs. */
302 char *
__sha256_crypt(const unsigned char * key,const unsigned char * salt)303 __sha256_crypt (const unsigned char *key, const unsigned char *salt)
304 {
305 /* We don't want to have an arbitrary limit in the size of the
306 password. We can compute an upper bound for the size of the
307 result in advance and so we can prepare the buffer we pass to
308 `sha256_crypt_r'. */
309 static int buflen;
310 int needed = (sizeof (sha256_salt_prefix) - 1
311 + sizeof (sha256_rounds_prefix) + 9 + 1
312 + strlen (salt) + 1 + 43 + 1);
313
314 if (buflen < needed)
315 {
316 char *new_buffer = (char *) realloc (buffer, needed);
317 if (new_buffer == NULL)
318 return NULL;
319
320 buffer = new_buffer;
321 buflen = needed;
322 }
323
324 return __sha256_crypt_r ((const char *) key, (const char *) salt, buffer, buflen);
325 }
326