Back to index

glibc  2.9
crypt-entry.c
Go to the documentation of this file.
00001 /*
00002  * UFC-crypt: ultra fast crypt(3) implementation
00003  *
00004  * Copyright (C) 1991,1992,1993,1996,1997,2007 Free Software Foundation, Inc.
00005  *
00006  * The GNU C Library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * The GNU C Library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with the GNU C Library; if not, write to the Free
00018  * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019  * 02111-1307 USA.
00020  *
00021  * crypt entry points
00022  *
00023  * @(#)crypt-entry.c 1.2 12/20/96
00024  *
00025  */
00026 
00027 #ifdef DEBUG
00028 #include <stdio.h>
00029 #endif
00030 #include <string.h>
00031 
00032 #ifndef STATIC
00033 #define STATIC static
00034 #endif
00035 
00036 #ifndef DOS
00037 #include "ufc-crypt.h"
00038 #else
00039 /*
00040  * Thanks to greg%wind@plains.NoDak.edu (Greg W. Wettstein)
00041  * for DOS patches
00042  */
00043 #include "ufc.h"
00044 #endif
00045 #include "crypt.h"
00046 #include "crypt-private.h"
00047 
00048 /* Prototypes for local functions.  */
00049 #if __STDC__ - 0
00050 #ifndef __GNU_LIBRARY__
00051 void _ufc_clearmem (char *start, int cnt);
00052 #else
00053 #define _ufc_clearmem(start, cnt)   memset(start, 0, cnt)
00054 #endif
00055 extern char *__md5_crypt_r (const char *key, const char *salt, char *buffer,
00056                          int buflen);
00057 extern char *__md5_crypt (const char *key, const char *salt);
00058 extern char *__sha256_crypt_r (const char *key, const char *salt,
00059                             char *buffer, int buflen);
00060 extern char *__sha256_crypt (const char *key, const char *salt);
00061 extern char *__sha512_crypt_r (const char *key, const char *salt,
00062                             char *buffer, int buflen);
00063 extern char *__sha512_crypt (const char *key, const char *salt);
00064 #endif
00065 
00066 /* Define our magic string to mark salt for MD5 encryption
00067    replacement.  This is meant to be the same as for other MD5 based
00068    encryption implementations.  */
00069 static const char md5_salt_prefix[] = "$1$";
00070 
00071 /* Magic string for SHA256 encryption.  */
00072 static const char sha256_salt_prefix[] = "$5$";
00073 
00074 /* Magic string for SHA512 encryption.  */
00075 static const char sha512_salt_prefix[] = "$6$";
00076 
00077 /* For use by the old, non-reentrant routines (crypt/encrypt/setkey)  */
00078 extern struct crypt_data _ufc_foobar;
00079 
00080 /*
00081  * UNIX crypt function
00082  */
00083 
00084 char *
00085 __crypt_r (key, salt, data)
00086      const char *key;
00087      const char *salt;
00088      struct crypt_data * __restrict data;
00089 {
00090   ufc_long res[4];
00091   char ktab[9];
00092   ufc_long xx = 25; /* to cope with GCC long long compiler bugs */
00093 
00094 #ifdef _LIBC
00095   /* Try to find out whether we have to use MD5 encryption replacement.  */
00096   if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
00097     return __md5_crypt_r (key, salt, (char *) data,
00098                        sizeof (struct crypt_data));
00099 
00100   /* Try to find out whether we have to use SHA256 encryption replacement.  */
00101   if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
00102     return __sha256_crypt_r (key, salt, (char *) data,
00103                           sizeof (struct crypt_data));
00104 
00105   /* Try to find out whether we have to use SHA512 encryption replacement.  */
00106   if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
00107     return __sha512_crypt_r (key, salt, (char *) data,
00108                           sizeof (struct crypt_data));
00109 #endif
00110 
00111   /*
00112    * Hack DES tables according to salt
00113    */
00114   _ufc_setup_salt_r (salt, data);
00115 
00116   /*
00117    * Setup key schedule
00118    */
00119   _ufc_clearmem (ktab, (int) sizeof (ktab));
00120   (void) strncpy (ktab, key, 8);
00121   _ufc_mk_keytab_r (ktab, data);
00122 
00123   /*
00124    * Go for the 25 DES encryptions
00125    */
00126   _ufc_clearmem ((char*) res, (int) sizeof (res));
00127   _ufc_doit_r (xx,  data, &res[0]);
00128 
00129   /*
00130    * Do final permutations
00131    */
00132   _ufc_dofinalperm_r (res, data);
00133 
00134   /*
00135    * And convert back to 6 bit ASCII
00136    */
00137   _ufc_output_conversion_r (res[0], res[1], salt, data);
00138   return data->crypt_3_buf;
00139 }
00140 weak_alias (__crypt_r, crypt_r)
00141 
00142 char *
00143 crypt (key, salt)
00144      const char *key;
00145      const char *salt;
00146 {
00147 #ifdef _LIBC
00148   /* Try to find out whether we have to use MD5 encryption replacement.  */
00149   if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
00150     return __md5_crypt (key, salt);
00151 
00152   /* Try to find out whether we have to use SHA256 encryption replacement.  */
00153   if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
00154     return __sha256_crypt (key, salt);
00155 
00156   /* Try to find out whether we have to use SHA512 encryption replacement.  */
00157   if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0)
00158     return __sha512_crypt (key, salt);
00159 #endif
00160 
00161   return __crypt_r (key, salt, &_ufc_foobar);
00162 }
00163 
00164 
00165 /*
00166  * To make fcrypt users happy.
00167  * They don't need to call init_des.
00168  */
00169 #ifdef _LIBC
00170 weak_alias (crypt, fcrypt)
00171 #else
00172 char *
00173 __fcrypt (key, salt)
00174      const char *key;
00175      const char *salt;
00176 {
00177   return crypt (key, salt);
00178 }
00179 #endif