crypt-entry.c 5.3 KB

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