microblaze: add ulps file
[uclibc-ng.git] / libcrypt / sha256-crypt.c
blob81bbe6ae6f2b962ae7da52a22a2328ffe7a77d78
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.
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.
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.
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/>. */
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>
27 #include "sha256.h"
28 #include "libcrypt.h"
30 /* Define our magic string to mark salt for SHA256 "encryption"
31 replacement. */
32 static const char sha256_salt_prefix[] = "$5$";
34 /* Prefix for optional rounds specification. */
35 static const char sha256_rounds_prefix[] = "rounds=";
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
46 /* Table with characters for base64 transformation. */
47 static const char b64t[64] =
48 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
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 } \
62 char *
63 __sha256_crypt_r (const char *key,
64 const char *salt,
65 char *buffer,
66 int buflen)
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;
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;
90 if (strncmp (salt, sha256_rounds_prefix, sizeof (sha256_rounds_prefix) - 1)
91 == 0)
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 == '$')
98 salt = endp + 1;
99 rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
100 rounds_custom = true;
104 salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
105 key_len = strlen (key);
107 if ((key - (char *) 0) % __alignof__ (uint32_t) != 0)
109 char *tmp = (char *) alloca (key_len + __alignof__ (uint32_t));
110 key = copied_key =
111 memcpy (tmp + __alignof__ (uint32_t)
112 - (tmp - (char *) 0) % __alignof__ (uint32_t),
113 key, key_len);
114 assert ((key - (char *) 0) % __alignof__ (uint32_t) == 0);
117 if ((salt - (char *) 0) % __alignof__ (uint32_t) != 0)
119 char *tmp = (char *) alloca (salt_len + __alignof__ (uint32_t));
120 salt = copied_salt =
121 memcpy (tmp + __alignof__ (uint32_t)
122 - (tmp - (char *) 0) % __alignof__ (uint32_t),
123 salt, salt_len);
124 assert ((salt - (char *) 0) % __alignof__ (uint32_t) == 0);
127 struct sha256_ctx ctx;
128 struct sha256_ctx alt_ctx;
130 /* Prepare for the real work. */
131 __sha256_init_ctx (&ctx);
133 /* Add the key string. */
134 __sha256_process_bytes (key, key_len, &ctx);
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);
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);
145 /* Add key. */
146 __sha256_process_bytes (key, key_len, &alt_ctx);
148 /* Add salt. */
149 __sha256_process_bytes (salt, salt_len, &alt_ctx);
151 /* Add key again. */
152 __sha256_process_bytes (key, key_len, &alt_ctx);
154 /* Now get result of this (32 bytes) and add it to the other
155 context. */
156 __sha256_finish_ctx (&alt_ctx, alt_result);
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);
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);
171 /* Create intermediate result. */
172 __sha256_finish_ctx (&ctx, alt_result);
174 /* Start computation of P byte sequence. */
175 __sha256_init_ctx (&alt_ctx);
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);
181 /* Finish the digest. */
182 __sha256_finish_ctx (&alt_ctx, temp_result);
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);
190 /* Start computation of S byte sequence. */
191 __sha256_init_ctx (&alt_ctx);
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);
197 /* Finish the digest. */
198 __sha256_finish_ctx (&alt_ctx, temp_result);
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);
206 /* Repeatedly run the collected hash value through SHA256 to burn
207 CPU cycles. */
208 for (cnt = 0; cnt < rounds; ++cnt)
210 /* New context. */
211 __sha256_init_ctx (&ctx);
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);
219 /* Add salt for numbers not divisible by 3. */
220 if (cnt % 3 != 0)
221 __sha256_process_bytes (s_bytes, salt_len, &ctx);
223 /* Add key for numbers not divisible by 7. */
224 if (cnt % 7 != 0)
225 __sha256_process_bytes (p_bytes, key_len, &ctx);
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);
233 /* Create intermediate result. */
234 __sha256_finish_ctx (&ctx, alt_result);
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;
242 if (rounds_custom)
244 int n = snprintf (cp, MAX (0, buflen), "%s%zu$",
245 sha256_rounds_prefix, rounds);
246 cp += n;
247 buflen -= n;
250 cp = stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
251 buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
253 if (buflen > 0)
255 *cp++ = '$';
256 --buflen;
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)
272 __set_errno (ERANGE);
273 buffer = NULL;
275 else
276 *cp = '\0'; /* Terminate the string. */
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));
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);
295 return buffer;
298 static char *buffer;
300 /* This entry point is equivalent to the `crypt' function in Unix
301 libcs. */
302 char *
303 __sha256_crypt (const unsigned char *key, const unsigned char *salt)
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);
314 if (buflen < needed)
316 char *new_buffer = (char *) realloc (buffer, needed);
317 if (new_buffer == NULL)
318 return NULL;
320 buffer = new_buffer;
321 buflen = needed;
324 return __sha256_crypt_r ((const char *) key, (const char *) salt, buffer, buflen);