Fix BZ#14090 - md5/sha512 with large sizes
[platform/upstream/glibc.git] / crypt / crypt-entry.c
1 /*
2  * UFC-crypt: ultra fast crypt(3) implementation
3  *
4  * Copyright (C) 1991-1993,1996-1997,2007,2012 Free Software Foundation, Inc.
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  * crypt entry points
21  *
22  * @(#)crypt-entry.c    1.2 12/20/96
23  *
24  */
25
26 #ifdef DEBUG
27 #include <stdio.h>
28 #endif
29 #include <string.h>
30
31 #ifndef STATIC
32 #define STATIC static
33 #endif
34
35 #ifndef DOS
36 #include "ufc-crypt.h"
37 #else
38 /*
39  * Thanks to greg%wind@plains.NoDak.edu (Greg W. Wettstein)
40  * for DOS patches
41  */
42 #include "ufc.h"
43 #endif
44 #include "crypt.h"
45 #include "crypt-private.h"
46
47 /* Prototypes for local functions.  */
48 #ifndef __GNU_LIBRARY__
49 void _ufc_clearmem (char *start, int cnt);
50 #else
51 #define _ufc_clearmem(start, cnt)   memset(start, 0, cnt)
52 #endif
53 extern char *__md5_crypt_r (const char *key, const char *salt, char *buffer,
54                             int buflen);
55 extern char *__md5_crypt (const char *key, const char *salt);
56 extern char *__sha256_crypt_r (const char *key, const char *salt,
57                                char *buffer, int buflen);
58 extern char *__sha256_crypt (const char *key, const char *salt);
59 extern char *__sha512_crypt_r (const char *key, const char *salt,
60                                char *buffer, int buflen);
61 extern char *__sha512_crypt (const char *key, const char *salt);
62
63 /* Define our magic string to mark salt for MD5 encryption
64    replacement.  This is meant to be the same as for other MD5 based
65    encryption implementations.  */
66 static const char md5_salt_prefix[] = "$1$";
67
68 /* Magic string for SHA256 encryption.  */
69 static const char sha256_salt_prefix[] = "$5$";
70
71 /* Magic string for SHA512 encryption.  */
72 static const char sha512_salt_prefix[] = "$6$";
73
74 /* For use by the old, non-reentrant routines (crypt/encrypt/setkey)  */
75 extern struct crypt_data _ufc_foobar;
76
77 /*
78  * UNIX crypt function
79  */
80
81 char *
82 __crypt_r (key, salt, data)
83      const char *key;
84      const char *salt;
85      struct crypt_data * __restrict data;
86 {
87   ufc_long res[4];
88   char ktab[9];
89   ufc_long xx = 25; /* to cope with GCC long long compiler bugs */
90
91 #ifdef _LIBC
92   /* Try to find out whether we have to use MD5 encryption replacement.  */
93   if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
94     return __md5_crypt_r (key, salt, (char *) data,
95                           sizeof (struct crypt_data));
96
97   /* Try to find out whether we have to use SHA256 encryption replacement.  */
98   if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
99     return __sha256_crypt_r (key, salt, (char *) data,
100                              sizeof (struct crypt_data));
101
102   /* Try to find out whether we have to use SHA512 encryption replacement.  */
103   if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
104     return __sha512_crypt_r (key, salt, (char *) data,
105                              sizeof (struct crypt_data));
106 #endif
107
108   /*
109    * Hack DES tables according to salt
110    */
111   _ufc_setup_salt_r (salt, data);
112
113   /*
114    * Setup key schedule
115    */
116   _ufc_clearmem (ktab, (int) sizeof (ktab));
117   (void) strncpy (ktab, key, 8);
118   _ufc_mk_keytab_r (ktab, data);
119
120   /*
121    * Go for the 25 DES encryptions
122    */
123   _ufc_clearmem ((char*) res, (int) sizeof (res));
124   _ufc_doit_r (xx,  data, &res[0]);
125
126   /*
127    * Do final permutations
128    */
129   _ufc_dofinalperm_r (res, data);
130
131   /*
132    * And convert back to 6 bit ASCII
133    */
134   _ufc_output_conversion_r (res[0], res[1], salt, data);
135   return data->crypt_3_buf;
136 }
137 weak_alias (__crypt_r, crypt_r)
138
139 char *
140 crypt (key, salt)
141      const char *key;
142      const char *salt;
143 {
144 #ifdef _LIBC
145   /* Try to find out whether we have to use MD5 encryption replacement.  */
146   if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
147     return __md5_crypt (key, salt);
148
149   /* Try to find out whether we have to use SHA256 encryption replacement.  */
150   if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
151     return __sha256_crypt (key, salt);
152
153   /* Try to find out whether we have to use SHA512 encryption replacement.  */
154   if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
155     return __sha512_crypt (key, salt);
156 #endif
157
158   return __crypt_r (key, salt, &_ufc_foobar);
159 }
160
161
162 /*
163  * To make fcrypt users happy.
164  * They don't need to call init_des.
165  */
166 #ifdef _LIBC
167 weak_alias (crypt, fcrypt)
168 #else
169 char *
170 __fcrypt (key, salt)
171      const char *key;
172      const char *salt;
173 {
174   return crypt (key, salt);
175 }
176 #endif