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