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