| xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * UFC-crypt: ultra fast crypt(3) implementation | 
 | 3 |  * | 
 | 4 |  * Copyright (C) 1991-2016 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 | #include <errno.h> | 
 | 31 | #include <fips-private.h> | 
 | 32 |  | 
 | 33 | #ifndef STATIC | 
 | 34 | #define STATIC static | 
 | 35 | #endif | 
 | 36 |  | 
 | 37 | #include "crypt-private.h" | 
 | 38 |  | 
 | 39 | /* Prototypes for local functions.  */ | 
 | 40 | #ifndef __GNU_LIBRARY__ | 
 | 41 | void _ufc_clearmem (char *start, int cnt); | 
 | 42 | #else | 
 | 43 | #define _ufc_clearmem(start, cnt)   memset(start, 0, cnt) | 
 | 44 | #endif | 
 | 45 | extern char *__md5_crypt_r (const char *key, const char *salt, char *buffer, | 
 | 46 | 			    int buflen); | 
 | 47 | extern char *__md5_crypt (const char *key, const char *salt); | 
 | 48 | extern char *__sha256_crypt_r (const char *key, const char *salt, | 
 | 49 | 			       char *buffer, int buflen); | 
 | 50 | extern char *__sha256_crypt (const char *key, const char *salt); | 
 | 51 | extern char *__sha512_crypt_r (const char *key, const char *salt, | 
 | 52 | 			       char *buffer, int buflen); | 
 | 53 | extern char *__sha512_crypt (const char *key, const char *salt); | 
 | 54 |  | 
 | 55 | /* Define our magic string to mark salt for MD5 encryption | 
 | 56 |    replacement.  This is meant to be the same as for other MD5 based | 
 | 57 |    encryption implementations.  */ | 
 | 58 | static const char md5_salt_prefix[] = "$1$"; | 
 | 59 |  | 
 | 60 | /* Magic string for SHA256 encryption.  */ | 
 | 61 | static const char sha256_salt_prefix[] = "$5$"; | 
 | 62 |  | 
 | 63 | /* Magic string for SHA512 encryption.  */ | 
 | 64 | static const char sha512_salt_prefix[] = "$6$"; | 
 | 65 |  | 
 | 66 | /* For use by the old, non-reentrant routines (crypt/encrypt/setkey)  */ | 
 | 67 | extern struct crypt_data _ufc_foobar; | 
 | 68 |  | 
 | 69 | /* | 
 | 70 |  * UNIX crypt function | 
 | 71 |  */ | 
 | 72 |  | 
 | 73 | char * | 
 | 74 | __crypt_r (const char *key, const char *salt, | 
 | 75 | 	   struct crypt_data * __restrict data) | 
 | 76 | { | 
 | 77 |   ufc_long res[4]; | 
 | 78 |   char ktab[9]; | 
 | 79 |   ufc_long xx = 25; /* to cope with GCC long long compiler bugs */ | 
 | 80 |  | 
 | 81 | #ifdef _LIBC | 
 | 82 |   /* Try to find out whether we have to use MD5 encryption replacement.  */ | 
 | 83 |   if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0) | 
 | 84 |     { | 
 | 85 |       /* FIPS rules out MD5 password encryption.  */ | 
 | 86 |       if (fips_enabled_p ()) | 
 | 87 | 	{ | 
 | 88 | 	  __set_errno (EPERM); | 
 | 89 | 	  return NULL; | 
 | 90 | 	} | 
 | 91 |       return __md5_crypt_r (key, salt, (char *) data, | 
 | 92 | 			    sizeof (struct crypt_data)); | 
 | 93 |     } | 
 | 94 |  | 
 | 95 |   /* Try to find out whether we have to use SHA256 encryption replacement.  */ | 
 | 96 |   if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0) | 
 | 97 |     return __sha256_crypt_r (key, salt, (char *) data, | 
 | 98 | 			     sizeof (struct crypt_data)); | 
 | 99 |  | 
 | 100 |   /* Try to find out whether we have to use SHA512 encryption replacement.  */ | 
 | 101 |   if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0) | 
 | 102 |     return __sha512_crypt_r (key, salt, (char *) data, | 
 | 103 | 			     sizeof (struct crypt_data)); | 
 | 104 | #endif | 
 | 105 |  | 
 | 106 |   /* | 
 | 107 |    * Hack DES tables according to salt | 
 | 108 |    */ | 
 | 109 |   if (!_ufc_setup_salt_r (salt, data)) | 
 | 110 |     { | 
 | 111 |       __set_errno (EINVAL); | 
 | 112 |       return NULL; | 
 | 113 |     } | 
 | 114 |  | 
 | 115 |   /* FIPS rules out DES password encryption.  */ | 
 | 116 |   if (fips_enabled_p ()) | 
 | 117 |     { | 
 | 118 |       __set_errno (EPERM); | 
 | 119 |       return NULL; | 
 | 120 |     } | 
 | 121 |  | 
 | 122 |   /* | 
 | 123 |    * Setup key schedule | 
 | 124 |    */ | 
 | 125 |   _ufc_clearmem (ktab, (int) sizeof (ktab)); | 
 | 126 |   (void) strncpy (ktab, key, 8); | 
 | 127 |   _ufc_mk_keytab_r (ktab, data); | 
 | 128 |  | 
 | 129 |   /* | 
 | 130 |    * Go for the 25 DES encryptions | 
 | 131 |    */ | 
 | 132 |   _ufc_clearmem ((char*) res, (int) sizeof (res)); | 
 | 133 |   _ufc_doit_r (xx,  data, &res[0]); | 
 | 134 |  | 
 | 135 |   /* | 
 | 136 |    * Do final permutations | 
 | 137 |    */ | 
 | 138 |   _ufc_dofinalperm_r (res, data); | 
 | 139 |  | 
 | 140 |   /* | 
 | 141 |    * And convert back to 6 bit ASCII | 
 | 142 |    */ | 
 | 143 |   _ufc_output_conversion_r (res[0], res[1], salt, data); | 
 | 144 |   return data->crypt_3_buf; | 
 | 145 | } | 
 | 146 | weak_alias (__crypt_r, crypt_r) | 
 | 147 |  | 
 | 148 | char * | 
 | 149 | crypt (const char *key, const char *salt) | 
 | 150 | { | 
 | 151 | #ifdef _LIBC | 
 | 152 |   /* Try to find out whether we have to use MD5 encryption replacement.  */ | 
 | 153 |   if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0 | 
 | 154 |       /* Let __crypt_r deal with the error code if FIPS is enabled.  */ | 
 | 155 |       && !fips_enabled_p ()) | 
 | 156 |     return __md5_crypt (key, salt); | 
 | 157 |  | 
 | 158 |   /* Try to find out whether we have to use SHA256 encryption replacement.  */ | 
 | 159 |   if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0) | 
 | 160 |     return __sha256_crypt (key, salt); | 
 | 161 |  | 
 | 162 |   /* Try to find out whether we have to use SHA512 encryption replacement.  */ | 
 | 163 |   if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0) | 
 | 164 |     return __sha512_crypt (key, salt); | 
 | 165 | #endif | 
 | 166 |  | 
 | 167 |   return __crypt_r (key, salt, &_ufc_foobar); | 
 | 168 | } | 
 | 169 |  | 
 | 170 |  | 
 | 171 | /* | 
 | 172 |  * To make fcrypt users happy. | 
 | 173 |  * They don't need to call init_des. | 
 | 174 |  */ | 
 | 175 | #ifdef _LIBC | 
 | 176 | weak_alias (crypt, fcrypt) | 
 | 177 | #else | 
 | 178 | char * | 
 | 179 | __fcrypt (const char *key, const char *salt) | 
 | 180 | { | 
 | 181 |   return crypt (key, salt); | 
 | 182 | } | 
 | 183 | #endif |