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