Fix BZ#14090 - md5/sha512 with large sizes
[platform/upstream/glibc.git] / crypt / sha512-crypt.c
1 /* One way encryption based on SHA512 sum.
2    Copyright (C) 2007, 2009, 2012 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 "sha512.h"
28
29
30 #ifdef USE_NSS
31 typedef int PRBool;
32 # include <hasht.h>
33 # include <nsslowhash.h>
34
35 # define sha512_init_ctx(ctxp, nss_ctxp) \
36   do                                                                          \
37     {                                                                         \
38       if (((nss_ctxp = NSSLOWHASH_NewContext (nss_ictx, HASH_AlgSHA512))      \
39            == NULL))                                                          \
40         {                                                                     \
41           if (nss_ctx != NULL)                                                \
42             NSSLOWHASH_Destroy (nss_ctx);                                     \
43           if (nss_alt_ctx != NULL)                                            \
44             NSSLOWHASH_Destroy (nss_alt_ctx);                                 \
45           return NULL;                                                        \
46         }                                                                     \
47       NSSLOWHASH_Begin (nss_ctxp);                                            \
48     }                                                                         \
49   while (0)
50
51 # define sha512_process_bytes(buf, len, ctxp, nss_ctxp) \
52   NSSLOWHASH_Update (nss_ctxp, (const unsigned char *) buf, len)
53
54 # define sha512_finish_ctx(ctxp, nss_ctxp, result) \
55   do                                                                          \
56     {                                                                         \
57       unsigned int ret;                                                       \
58       NSSLOWHASH_End (nss_ctxp, result, &ret, sizeof (result));               \
59       assert (ret == sizeof (result));                                        \
60       NSSLOWHASH_Destroy (nss_ctxp);                                          \
61       nss_ctxp = NULL;                                                        \
62     }                                                                         \
63   while (0)
64 #else
65 # define sha512_init_ctx(ctxp, nss_ctxp) \
66   __sha512_init_ctx (ctxp)
67
68 # define sha512_process_bytes(buf, len, ctxp, nss_ctxp) \
69   __sha512_process_bytes(buf, len, ctxp)
70
71 # define sha512_finish_ctx(ctxp, nss_ctxp, result) \
72   __sha512_finish_ctx (ctxp, result)
73 #endif
74
75
76 /* Define our magic string to mark salt for SHA512 "encryption"
77    replacement.  */
78 static const char sha512_salt_prefix[] = "$6$";
79
80 /* Prefix for optional rounds specification.  */
81 static const char sha512_rounds_prefix[] = "rounds=";
82
83 /* Maximum salt string length.  */
84 #define SALT_LEN_MAX 16
85 /* Default number of rounds if not explicitly specified.  */
86 #define ROUNDS_DEFAULT 5000
87 /* Minimum number of rounds.  */
88 #define ROUNDS_MIN 1000
89 /* Maximum number of rounds.  */
90 #define ROUNDS_MAX 999999999
91
92 /* Table with characters for base64 transformation.  */
93 static const char b64t[64] =
94 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
95
96
97 /* Prototypes for local functions.  */
98 extern char *__sha512_crypt_r (const char *key, const char *salt,
99                                char *buffer, int buflen);
100 extern char *__sha512_crypt (const char *key, const char *salt);
101
102
103 char *
104 __sha512_crypt_r (key, salt, buffer, buflen)
105      const char *key;
106      const char *salt;
107      char *buffer;
108      int buflen;
109 {
110   unsigned char alt_result[64]
111     __attribute__ ((__aligned__ (__alignof__ (uint64_t))));
112   unsigned char temp_result[64]
113     __attribute__ ((__aligned__ (__alignof__ (uint64_t))));
114   size_t salt_len;
115   size_t key_len;
116   size_t cnt;
117   char *cp;
118   char *copied_key = NULL;
119   char *copied_salt = NULL;
120   char *p_bytes;
121   char *s_bytes;
122   /* Default number of rounds.  */
123   size_t rounds = ROUNDS_DEFAULT;
124   bool rounds_custom = false;
125   size_t alloca_used = 0;
126   char *free_key = NULL;
127   char *free_pbytes = NULL;
128
129   /* Find beginning of salt string.  The prefix should normally always
130      be present.  Just in case it is not.  */
131   if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
132     /* Skip salt prefix.  */
133     salt += sizeof (sha512_salt_prefix) - 1;
134
135   if (strncmp (salt, sha512_rounds_prefix, sizeof (sha512_rounds_prefix) - 1)
136       == 0)
137     {
138       const char *num = salt + sizeof (sha512_rounds_prefix) - 1;
139       char *endp;
140       unsigned long int srounds = strtoul (num, &endp, 10);
141       if (*endp == '$')
142         {
143           salt = endp + 1;
144           rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
145           rounds_custom = true;
146         }
147     }
148
149   salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
150   key_len = strlen (key);
151
152   if ((key - (char *) 0) % __alignof__ (uint64_t) != 0)
153     {
154       char *tmp;
155
156       if (__libc_use_alloca (alloca_used + key_len + __alignof__ (uint64_t)))
157         tmp = alloca_account (key_len + __alignof__ (uint64_t), alloca_used);
158       else
159         {
160           free_key = tmp = (char *) malloc (key_len + __alignof__ (uint64_t));
161           if (tmp == NULL)
162             return NULL;
163         }
164
165       key = copied_key =
166         memcpy (tmp + __alignof__ (uint64_t)
167                 - (tmp - (char *) 0) % __alignof__ (uint64_t),
168                 key, key_len);
169       assert ((key - (char *) 0) % __alignof__ (uint64_t) == 0);
170     }
171
172   if ((salt - (char *) 0) % __alignof__ (uint64_t) != 0)
173     {
174       char *tmp = (char *) alloca (salt_len + __alignof__ (uint64_t));
175       salt = copied_salt =
176         memcpy (tmp + __alignof__ (uint64_t)
177                 - (tmp - (char *) 0) % __alignof__ (uint64_t),
178                 salt, salt_len);
179       assert ((salt - (char *) 0) % __alignof__ (uint64_t) == 0);
180     }
181
182 #ifdef USE_NSS
183   /* Initialize libfreebl3.  */
184   NSSLOWInitContext *nss_ictx = NSSLOW_Init ();
185   if (nss_ictx == NULL)
186     {
187       free (free_key);
188       return NULL;
189     }
190   NSSLOWHASHContext *nss_ctx = NULL;
191   NSSLOWHASHContext *nss_alt_ctx = NULL;
192 #else
193   struct sha512_ctx ctx;
194   struct sha512_ctx alt_ctx;
195 #endif
196
197   /* Prepare for the real work.  */
198   sha512_init_ctx (&ctx, nss_ctx);
199
200   /* Add the key string.  */
201   sha512_process_bytes (key, key_len, &ctx, nss_ctx);
202
203   /* The last part is the salt string.  This must be at most 16
204      characters and it ends at the first `$' character.  */
205   sha512_process_bytes (salt, salt_len, &ctx, nss_ctx);
206
207
208   /* Compute alternate SHA512 sum with input KEY, SALT, and KEY.  The
209      final result will be added to the first context.  */
210   sha512_init_ctx (&alt_ctx, nss_alt_ctx);
211
212   /* Add key.  */
213   sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
214
215   /* Add salt.  */
216   sha512_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
217
218   /* Add key again.  */
219   sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
220
221   /* Now get result of this (64 bytes) and add it to the other
222      context.  */
223   sha512_finish_ctx (&alt_ctx, nss_alt_ctx, alt_result);
224
225   /* Add for any character in the key one byte of the alternate sum.  */
226   for (cnt = key_len; cnt > 64; cnt -= 64)
227     sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
228   sha512_process_bytes (alt_result, cnt, &ctx, nss_ctx);
229
230   /* Take the binary representation of the length of the key and for every
231      1 add the alternate sum, for every 0 the key.  */
232   for (cnt = key_len; cnt > 0; cnt >>= 1)
233     if ((cnt & 1) != 0)
234       sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
235     else
236       sha512_process_bytes (key, key_len, &ctx, nss_ctx);
237
238   /* Create intermediate result.  */
239   sha512_finish_ctx (&ctx, nss_ctx, alt_result);
240
241   /* Start computation of P byte sequence.  */
242   sha512_init_ctx (&alt_ctx, nss_alt_ctx);
243
244   /* For every character in the password add the entire password.  */
245   for (cnt = 0; cnt < key_len; ++cnt)
246     sha512_process_bytes (key, key_len, &alt_ctx, nss_alt_ctx);
247
248   /* Finish the digest.  */
249   sha512_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
250
251   /* Create byte sequence P.  */
252   if (__libc_use_alloca (alloca_used + key_len))
253     cp = p_bytes = (char *) alloca (key_len);
254   else
255     {
256       free_pbytes = cp = p_bytes = (char *)malloc (key_len);
257       if (free_pbytes == NULL)
258         {
259           free (free_key);
260           return NULL;
261         }
262     }
263
264   for (cnt = key_len; cnt >= 64; cnt -= 64)
265     cp = mempcpy (cp, temp_result, 64);
266   memcpy (cp, temp_result, cnt);
267
268   /* Start computation of S byte sequence.  */
269   sha512_init_ctx (&alt_ctx, nss_alt_ctx);
270
271   /* For every character in the password add the entire password.  */
272   for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
273     sha512_process_bytes (salt, salt_len, &alt_ctx, nss_alt_ctx);
274
275   /* Finish the digest.  */
276   sha512_finish_ctx (&alt_ctx, nss_alt_ctx, temp_result);
277
278   /* Create byte sequence S.  */
279   cp = s_bytes = alloca (salt_len);
280   for (cnt = salt_len; cnt >= 64; cnt -= 64)
281     cp = mempcpy (cp, temp_result, 64);
282   memcpy (cp, temp_result, cnt);
283
284   /* Repeatedly run the collected hash value through SHA512 to burn
285      CPU cycles.  */
286   for (cnt = 0; cnt < rounds; ++cnt)
287     {
288       /* New context.  */
289       sha512_init_ctx (&ctx, nss_ctx);
290
291       /* Add key or last result.  */
292       if ((cnt & 1) != 0)
293         sha512_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
294       else
295         sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
296
297       /* Add salt for numbers not divisible by 3.  */
298       if (cnt % 3 != 0)
299         sha512_process_bytes (s_bytes, salt_len, &ctx, nss_ctx);
300
301       /* Add key for numbers not divisible by 7.  */
302       if (cnt % 7 != 0)
303         sha512_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
304
305       /* Add key or last result.  */
306       if ((cnt & 1) != 0)
307         sha512_process_bytes (alt_result, 64, &ctx, nss_ctx);
308       else
309         sha512_process_bytes (p_bytes, key_len, &ctx, nss_ctx);
310
311       /* Create intermediate result.  */
312       sha512_finish_ctx (&ctx, nss_ctx, alt_result);
313     }
314
315 #ifdef USE_NSS
316   /* Free libfreebl3 resources. */
317   NSSLOW_Shutdown (nss_ictx);
318 #endif
319
320   /* Now we can construct the result string.  It consists of three
321      parts.  */
322   cp = __stpncpy (buffer, sha512_salt_prefix, MAX (0, buflen));
323   buflen -= sizeof (sha512_salt_prefix) - 1;
324
325   if (rounds_custom)
326     {
327       int n = snprintf (cp, MAX (0, buflen), "%s%zu$",
328                         sha512_rounds_prefix, rounds);
329       cp += n;
330       buflen -= n;
331     }
332
333   cp = __stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
334   buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
335
336   if (buflen > 0)
337     {
338       *cp++ = '$';
339       --buflen;
340     }
341
342   void b64_from_24bit (unsigned int b2, unsigned int b1, unsigned int b0,
343                        int n)
344   {
345     unsigned int w = (b2 << 16) | (b1 << 8) | b0;
346     while (n-- > 0 && buflen > 0)
347       {
348         *cp++ = b64t[w & 0x3f];
349         --buflen;
350         w >>= 6;
351       }
352   }
353
354   b64_from_24bit (alt_result[0], alt_result[21], alt_result[42], 4);
355   b64_from_24bit (alt_result[22], alt_result[43], alt_result[1], 4);
356   b64_from_24bit (alt_result[44], alt_result[2], alt_result[23], 4);
357   b64_from_24bit (alt_result[3], alt_result[24], alt_result[45], 4);
358   b64_from_24bit (alt_result[25], alt_result[46], alt_result[4], 4);
359   b64_from_24bit (alt_result[47], alt_result[5], alt_result[26], 4);
360   b64_from_24bit (alt_result[6], alt_result[27], alt_result[48], 4);
361   b64_from_24bit (alt_result[28], alt_result[49], alt_result[7], 4);
362   b64_from_24bit (alt_result[50], alt_result[8], alt_result[29], 4);
363   b64_from_24bit (alt_result[9], alt_result[30], alt_result[51], 4);
364   b64_from_24bit (alt_result[31], alt_result[52], alt_result[10], 4);
365   b64_from_24bit (alt_result[53], alt_result[11], alt_result[32], 4);
366   b64_from_24bit (alt_result[12], alt_result[33], alt_result[54], 4);
367   b64_from_24bit (alt_result[34], alt_result[55], alt_result[13], 4);
368   b64_from_24bit (alt_result[56], alt_result[14], alt_result[35], 4);
369   b64_from_24bit (alt_result[15], alt_result[36], alt_result[57], 4);
370   b64_from_24bit (alt_result[37], alt_result[58], alt_result[16], 4);
371   b64_from_24bit (alt_result[59], alt_result[17], alt_result[38], 4);
372   b64_from_24bit (alt_result[18], alt_result[39], alt_result[60], 4);
373   b64_from_24bit (alt_result[40], alt_result[61], alt_result[19], 4);
374   b64_from_24bit (alt_result[62], alt_result[20], alt_result[41], 4);
375   b64_from_24bit (0, 0, alt_result[63], 2);
376
377   if (buflen <= 0)
378     {
379       __set_errno (ERANGE);
380       buffer = NULL;
381     }
382   else
383     *cp = '\0';         /* Terminate the string.  */
384
385   /* Clear the buffer for the intermediate result so that people
386      attaching to processes or reading core dumps cannot get any
387      information.  We do it in this way to clear correct_words[]
388      inside the SHA512 implementation as well.  */
389 #ifndef USE_NSS
390   __sha512_init_ctx (&ctx);
391   __sha512_finish_ctx (&ctx, alt_result);
392   memset (&ctx, '\0', sizeof (ctx));
393   memset (&alt_ctx, '\0', sizeof (alt_ctx));
394 #endif
395   memset (temp_result, '\0', sizeof (temp_result));
396   memset (p_bytes, '\0', key_len);
397   memset (s_bytes, '\0', salt_len);
398   if (copied_key != NULL)
399     memset (copied_key, '\0', key_len);
400   if (copied_salt != NULL)
401     memset (copied_salt, '\0', salt_len);
402
403   free (free_key);
404   free (free_pbytes);
405   return buffer;
406 }
407
408 #ifndef _LIBC
409 # define libc_freeres_ptr(decl) decl
410 #endif
411 libc_freeres_ptr (static char *buffer);
412
413 /* This entry point is equivalent to the `crypt' function in Unix
414    libcs.  */
415 char *
416 __sha512_crypt (const char *key, const char *salt)
417 {
418   /* We don't want to have an arbitrary limit in the size of the
419      password.  We can compute an upper bound for the size of the
420      result in advance and so we can prepare the buffer we pass to
421      `sha512_crypt_r'.  */
422   static int buflen;
423   int needed = (sizeof (sha512_salt_prefix) - 1
424                 + sizeof (sha512_rounds_prefix) + 9 + 1
425                 + strlen (salt) + 1 + 86 + 1);
426
427   if (buflen < needed)
428     {
429       char *new_buffer = (char *) realloc (buffer, needed);
430       if (new_buffer == NULL)
431         return NULL;
432
433       buffer = new_buffer;
434       buflen = needed;
435     }
436
437   return __sha512_crypt_r (key, salt, buffer, buflen);
438 }
439
440 #ifndef _LIBC
441 static void
442 __attribute__ ((__destructor__))
443 free_mem (void)
444 {
445   free (buffer);
446 }
447 #endif