1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21: #include <assert.h>
22: #include <errno.h>
23: #include <stdbool.h>
24: #include <stdlib.h>
25: #include <string.h>
26: #include <sys/param.h>
27:
28: #include "sha256.h"
29:
30:
31:
32:
33: static const char sha256_salt_prefix[] = "$5$";
34:
35:
36: static const char sha256_rounds_prefix[] = "rounds=";
37:
38:
39: #define SALT_LEN_MAX 16
40:
41: #define ROUNDS_DEFAULT 5000
42:
43: #define ROUNDS_MIN 1000
44:
45: #define ROUNDS_MAX 999999999
46:
47:
48: static const char b64t[64] =
49: "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
50:
51:
52:
53: extern char *__sha256_crypt_r (const char *key, const char *salt,
54: char *buffer, int buflen);
55: extern char *__sha256_crypt (const char *key, const char *salt);
56:
57:
58: char *
59: __sha256_crypt_r (key, salt, buffer, buflen)
60: const char *key;
61: const char *salt;
62: char *buffer;
63: int buflen;
64: {
65: unsigned char alt_result[32]
66: __attribute__ ((__aligned__ (__alignof__ (uint32_t))));
67: unsigned char temp_result[32]
68: __attribute__ ((__aligned__ (__alignof__ (uint32_t))));
69: struct sha256_ctx ctx;
70: struct sha256_ctx alt_ctx;
71: size_t salt_len;
72: size_t key_len;
73: size_t cnt;
74: char *cp;
75: char *copied_key = NULL;
76: char *copied_salt = NULL;
77: char *p_bytes;
78: char *s_bytes;
79:
80: size_t rounds = ROUNDS_DEFAULT;
81: bool rounds_custom = false;
82:
83:
84:
85: if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
86:
87: salt += sizeof (sha256_salt_prefix) - 1;
88:
89: if (strncmp (salt, sha256_rounds_prefix, sizeof (sha256_rounds_prefix) - 1)
90: == 0)
91: {
92: const char *num = salt + sizeof (sha256_rounds_prefix) - 1;
93: char *endp;
94: unsigned long int srounds = strtoul (num, &endp, 10);
95: if (*endp == '$')
96: {
97: salt = endp + 1;
98: rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
99: rounds_custom = true;
100: }
101: }
102:
103: salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
104: key_len = strlen (key);
105:
106: if ((key - (char *) 0) % __alignof__ (uint32_t) != 0)
107: {
108: char *tmp = (char *) alloca (key_len + __alignof__ (uint32_t));
109: key = copied_key =
110: memcpy (tmp + __alignof__ (uint32_t)
111: - (tmp - (char *) 0) % __alignof__ (uint32_t),
112: key, key_len);
113: assert ((key - (char *) 0) % __alignof__ (uint32_t) == 0);
114: }
115:
116: if ((salt - (char *) 0) % __alignof__ (uint32_t) != 0)
117: {
118: char *tmp = (char *) alloca (salt_len + __alignof__ (uint32_t));
119: salt = copied_salt =
120: memcpy (tmp + __alignof__ (uint32_t)
121: - (tmp - (char *) 0) % __alignof__ (uint32_t),
122: salt, salt_len);
123: assert ((salt - (char *) 0) % __alignof__ (uint32_t) == 0);
124: }
125:
126:
127: __sha256_init_ctx (&ctx);
128:
129:
130: __sha256_process_bytes (key, key_len, &ctx);
131:
132:
133:
134:
135: __sha256_process_bytes (salt, salt_len, &ctx);
136:
137:
138:
139:
140: __sha256_init_ctx (&alt_ctx);
141:
142:
143: __sha256_process_bytes (key, key_len, &alt_ctx);
144:
145:
146: __sha256_process_bytes (salt, salt_len, &alt_ctx);
147:
148:
149: __sha256_process_bytes (key, key_len, &alt_ctx);
150:
151:
152:
153: __sha256_finish_ctx (&alt_ctx, alt_result);
154:
155:
156: for (cnt = key_len; cnt > 32; cnt -= 32)
157: __sha256_process_bytes (alt_result, 32, &ctx);
158: __sha256_process_bytes (alt_result, cnt, &ctx);
159:
160:
161:
162: for (cnt = key_len; cnt > 0; cnt >>= 1)
163: if ((cnt & 1) != 0)
164: __sha256_process_bytes (alt_result, 32, &ctx);
165: else
166: __sha256_process_bytes (key, key_len, &ctx);
167:
168:
169: __sha256_finish_ctx (&ctx, alt_result);
170:
171:
172: __sha256_init_ctx (&alt_ctx);
173:
174:
175: for (cnt = 0; cnt < key_len; ++cnt)
176: __sha256_process_bytes (key, key_len, &alt_ctx);
177:
178:
179: __sha256_finish_ctx (&alt_ctx, temp_result);
180:
181:
182: cp = p_bytes = alloca (key_len);
183: for (cnt = key_len; cnt >= 32; cnt -= 32)
184: cp = mempcpy (cp, temp_result, 32);
185: memcpy (cp, temp_result, cnt);
186:
187:
188: __sha256_init_ctx (&alt_ctx);
189:
190:
191: for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
192: __sha256_process_bytes (salt, salt_len, &alt_ctx);
193:
194:
195: __sha256_finish_ctx (&alt_ctx, temp_result);
196:
197:
198: cp = s_bytes = alloca (salt_len);
199: for (cnt = salt_len; cnt >= 32; cnt -= 32)
200: cp = mempcpy (cp, temp_result, 32);
201: memcpy (cp, temp_result, cnt);
202:
203:
204:
205: for (cnt = 0; cnt < rounds; ++cnt)
206: {
207:
208: __sha256_init_ctx (&ctx);
209:
210:
211: if ((cnt & 1) != 0)
212: __sha256_process_bytes (p_bytes, key_len, &ctx);
213: else
214: __sha256_process_bytes (alt_result, 32, &ctx);
215:
216:
217: if (cnt % 3 != 0)
218: __sha256_process_bytes (s_bytes, salt_len, &ctx);
219:
220:
221: if (cnt % 7 != 0)
222: __sha256_process_bytes (p_bytes, key_len, &ctx);
223:
224:
225: if ((cnt & 1) != 0)
226: __sha256_process_bytes (alt_result, 32, &ctx);
227: else
228: __sha256_process_bytes (p_bytes, key_len, &ctx);
229:
230:
231: __sha256_finish_ctx (&ctx, alt_result);
232: }
233:
234:
235:
236: cp = __stpncpy (buffer, sha256_salt_prefix, MAX (0, buflen));
237: buflen -= sizeof (sha256_salt_prefix) - 1;
238:
239: if (rounds_custom)
240: {
241: int n = snprintf (cp, MAX (0, buflen), "%s%zu$",
242: sha256_rounds_prefix, rounds);
243: cp += n;
244: buflen -= n;
245: }
246:
247: cp = __stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
248: buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
249:
250: if (buflen > 0)
251: {
252: *cp++ = '$';
253: --buflen;
254: }
255:
256: #define b64_from_24bit(B2, B1, B0, N) \
257: do { \
258: unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
259: int n = (N); \
260: while (n-- > 0 && buflen > 0) \
261: { \
262: *cp++ = b64t[w & 0x3f]; \
263: --buflen; \
264: w >>= 6; \
265: } \
266: } while (0)
267:
268: b64_from_24bit (alt_result[0], alt_result[10], alt_result[20], 4);
269: b64_from_24bit (alt_result[21], alt_result[1], alt_result[11], 4);
270: b64_from_24bit (alt_result[12], alt_result[22], alt_result[2], 4);
271: b64_from_24bit (alt_result[3], alt_result[13], alt_result[23], 4);
272: b64_from_24bit (alt_result[24], alt_result[4], alt_result[14], 4);
273: b64_from_24bit (alt_result[15], alt_result[25], alt_result[5], 4);
274: b64_from_24bit (alt_result[6], alt_result[16], alt_result[26], 4);
275: b64_from_24bit (alt_result[27], alt_result[7], alt_result[17], 4);
276: b64_from_24bit (alt_result[18], alt_result[28], alt_result[8], 4);
277: b64_from_24bit (alt_result[9], alt_result[19], alt_result[29], 4);
278: b64_from_24bit (0, alt_result[31], alt_result[30], 3);
279: if (buflen <= 0)
280: {
281: __set_errno (ERANGE);
282: buffer = NULL;
283: }
284: else
285: *cp = '\0';
286:
287:
288:
289:
290:
291: __sha256_init_ctx (&ctx);
292: __sha256_finish_ctx (&ctx, alt_result);
293: memset (temp_result, '\0', sizeof (temp_result));
294: memset (p_bytes, '\0', key_len);
295: memset (s_bytes, '\0', salt_len);
296: memset (&ctx, '\0', sizeof (ctx));
297: memset (&alt_ctx, '\0', sizeof (alt_ctx));
298: if (copied_key != NULL)
299: memset (copied_key, '\0', key_len);
300: if (copied_salt != NULL)
301: memset (copied_salt, '\0', salt_len);
302:
303: return buffer;
304: }
305:
306: #ifndef _LIBC
307: # define libc_freeres_ptr(decl) decl
308: #endif
309: libc_freeres_ptr (static char *buffer);
310:
311:
312:
313: char *
314: __sha256_crypt (const char *key, const char *salt)
315: {
316:
317:
318:
319:
320: static int buflen;
321: int needed = (sizeof (sha256_salt_prefix) - 1
322: + sizeof (sha256_rounds_prefix) + 9 + 1
323: + strlen (salt) + 1 + 43 + 1);
324:
325: if (buflen < needed)
326: {
327: char *new_buffer = (char *) realloc (buffer, needed);
328: if (new_buffer == NULL)
329: return NULL;
330:
331: buffer = new_buffer;
332: buflen = needed;
333: }
334:
335: return __sha256_crypt_r (key, salt, buffer, buflen);
336: }
337:
338: #ifndef _LIBC
339: static void
340: __attribute__ ((__destructor__))
341: free_mem (void)
342: {
343: free (buffer);
344: }
345: #endif