aboutsummaryrefslogtreecommitdiff
path: root/crypt
diff options
context:
space:
mode:
Diffstat (limited to 'crypt')
-rw-r--r--crypt/Banner1
-rw-r--r--crypt/COPYING.LIB482
-rw-r--r--crypt/ChangeLog.old24
-rw-r--r--crypt/Makefile36
-rw-r--r--crypt/README49
-rw-r--r--crypt/README.ufc-crypt135
-rw-r--r--crypt/cert.c112
-rw-r--r--crypt/cert.input171
-rw-r--r--crypt/crypt.texi412
-rw-r--r--crypt/examples/genpass.c32
-rw-r--r--crypt/examples/mygetpass.c25
-rw-r--r--crypt/examples/testpass.c26
-rw-r--r--crypt/genpass.c.texi32
-rw-r--r--crypt/mygetpass.c.texi25
-rw-r--r--crypt/speeds.c153
-rw-r--r--crypt/sysdeps/mach/hurd/Implies2
-rw-r--r--crypt/sysdeps/unix/Makefile4
-rw-r--r--crypt/sysdeps/unix/crypt-entry.c149
-rw-r--r--crypt/sysdeps/unix/crypt-private.h60
-rw-r--r--crypt/sysdeps/unix/crypt.c120
-rw-r--r--crypt/sysdeps/unix/crypt.h71
-rw-r--r--crypt/sysdeps/unix/crypt_util.c914
-rw-r--r--crypt/sysdeps/unix/des_impl.c615
-rw-r--r--crypt/sysdeps/unix/patchlevel.h25
-rw-r--r--crypt/sysdeps/unix/ufc-crypt.h29
-rw-r--r--crypt/testpass.c.texi26
-rw-r--r--crypt/ufc.c55
27 files changed, 3785 insertions, 0 deletions
diff --git a/crypt/Banner b/crypt/Banner
new file mode 100644
index 0000000000..9cb25bdf0c
--- /dev/null
+++ b/crypt/Banner
@@ -0,0 +1 @@
+crypt add-on version 2.1 by Michael Glad and others
diff --git a/crypt/COPYING.LIB b/crypt/COPYING.LIB
new file mode 100644
index 0000000000..161a3d1d47
--- /dev/null
+++ b/crypt/COPYING.LIB
@@ -0,0 +1,482 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/crypt/ChangeLog.old b/crypt/ChangeLog.old
new file mode 100644
index 0000000000..8fba95e7f8
--- /dev/null
+++ b/crypt/ChangeLog.old
@@ -0,0 +1,24 @@
+1998-12-25 Geoff Keating <geoffk@ozemail.com.au>
+
+ * sysdeps/unix/ufc-crypt.h: Use <stdint.h>.
+
+ * configure: Delete the code dealing with building the add-on
+ outside glibc, as this doesn't work.
+
+1998-12-10 Geoff Keating <geoffk@ozemail.com.au>
+
+ * sysdeps/unix/crypt-entry.c: Don't include "patchlevel.h".
+
+ * sysdeps/unix/crypt.h: Move __crypt_r, __setkey_r, __encrypt_r to...
+ * sysdeps/unix/crypt-private.h: ...here.
+
+ * sysdeps/unix/crypt.h: Add __restrict to the structure parameters.
+ * sysdeps/unix/crypt-private.h: Likewise. Also add const to
+ first parameter of _ufc_mk_keytab_r.
+ * sysdeps/unix/crypt.c: Update prototypes.
+ * sysdeps/unix/crypt-entry.c: Likewise.
+ * sysdeps/unix/crypt_util.c: Likewise.
+
+ * sysdeps/unix/crypt-entry.c (crypt): Use __crypt_r not crypt_r.
+
+ChangeLog starts here, with version 2.0.96.
diff --git a/crypt/Makefile b/crypt/Makefile
new file mode 100644
index 0000000000..1be33be001
--- /dev/null
+++ b/crypt/Makefile
@@ -0,0 +1,36 @@
+# Copyright (C) 1996 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+
+# The GNU C Library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+
+# The GNU C Library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public
+# License along with the GNU C Library; see the file COPYING.LIB. If not,
+# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+#
+# Sub-makefile for DES crypt portion of the library.
+#
+subdir := crypt
+
+tests = cert
+
+include ../Makeconfig
+
+rpath-dirs += md5-crypt
+
+include ../Rules
+
+ifeq ($(build-shared),yes)
+$(objpfx)cert: $(common-objpfx)md5-crypt/libcrypt.so$(libcrypt.so-version)
+else
+$(objpfx)cert: $(common-objpfx)md5-crypt/libcrypt.a
+endif
diff --git a/crypt/README b/crypt/README
new file mode 100644
index 0000000000..09ee9d128b
--- /dev/null
+++ b/crypt/README
@@ -0,0 +1,49 @@
+This is the distribution tar file for the cryptography add-on to the
+GNU C library. For the version number, see the file "Banner".
+
+The add-on is not included in the main distribution of the GNU C
+library because some governments, most notably those of France,
+Russia, and the US, have very restrictive rules governing the
+distribution and use of encryption software. Please read the node
+"Legal Problems" in the manual for more details.
+
+In particular, the US does not allow export of this software without a
+licence, including via the Internet. So please do not download it
+from the main FSF FTP site at ftp.gnu.org if you are outside
+the US. This software was completely developed outside the US.
+
+To install the add-on, unpack the tar file in the top level of the GNU
+C library distribution. Then build GNU C library like this:
+
+configure --enable-add-ons
+make
+make install
+
+It is not presently possible to add the add-on to the GNU C library
+without recompiling the GNU C library.
+
+The additional functionality provided by the add-on consists of:
+
+* DES-based crypt(). This is only for backwards compatibility;
+ for new installations the MD5-based crypt(), provided with the main
+ GNU C library distribution, should be used instead.
+
+* The AUTH_DES RPC authentication method. In a given situation, this
+ may be more or less secure than the AUTH_UNIX authentication method
+ which is provided with the main GNU C library distribution.
+
+* User-visible DES encryption routines. Note that DES by itself is
+ not now considered a very secure encryption method.
+
+The add-on also includes a manual, the file "crypt.texi". The manual
+will be integrated with the GNU C library manual when the GNU C
+library is installed.
+
+Report bugs in this library (or its manual) in the same way as for the
+GNU C library; that is, using the `glibcbug' shell script to send
+e-mail to <bugs@gnu.org>. Simply run this shell script and fill in
+the information. Nevertheless you can still send bug reports to
+<bug-glibc@gnu.org> as normal electronic mails.
+
+The add-on is free software. See the file COPYING.LIB for copying
+conditions.
diff --git a/crypt/README.ufc-crypt b/crypt/README.ufc-crypt
new file mode 100644
index 0000000000..74d81dd865
--- /dev/null
+++ b/crypt/README.ufc-crypt
@@ -0,0 +1,135 @@
+The following is the README for UFC-crypt, with those portions deleted
+that are known to be incorrect for the implementation used with the
+GNU C library.
+
+
+ UFC-crypt: ultra fast 'crypt' implementation
+ ============================================
+
+ @(#)README 2.27 11 Sep 1996
+
+Design goals/non goals:
+----------------------
+
+- Crypt implementation plugin compatible with crypt(3)/fcrypt.
+
+- High performance when used for password cracking.
+
+- Portable to most 32/64 bit machines.
+
+- Startup time/mixed salt performance not critical.
+
+Features of the implementation:
+------------------------------
+
+- On most machines, UFC-crypt runs 30-60 times faster than crypt(3) when
+ invoked repeated times with the same salt and varying passwords.
+
+- With mostly constant salts, performance is about two to three times
+ that of the default fcrypt implementation shipped with Alec
+ Muffets 'Crack' password cracker. For instructions on how to
+ plug UFC-crypt into 'Crack', see below.
+
+- With alternating salts, performance is only about twice
+ that of crypt(3).
+
+- Requires 165 kb for tables.
+
+Author & licensing etc
+----------------------
+
+UFC-crypt is created by Michael Glad, email: glad@daimi.aau.dk, and has
+been donated to the Free Software Foundation, Inc. It is covered by the
+GNU library license version 2, see the file 'COPYING.LIB'.
+
+NOTES FOR USERS OUTSIDE THE US:
+------------------------------
+
+The US government limits the export of DES based software/hardware.
+This software is written in Aarhus, Denmark. It can therefore be retrieved
+from ftp sites outside the US without breaking US law. Please do not
+ftp it from american sites.
+
+Benchmark table:
+---------------
+
+The table shows how many operations per second UFC-crypt can
+do on various machines.
+
+|--------------|-------------------------------------------|
+|Machine | SUN* SUN* HP* DecStation HP |
+| | 3/50 ELC 9000/425e 3100 9000/720 |
+|--------------|-------------------------------------------|
+| Crypt(3)/sec | 4.6 30 15 25 57 |
+| Ufc/sec | 220 990 780 1015 3500 |
+|--------------|-------------------------------------------|
+| Speedup | 48 30 52 40 60 |
+|--------------|-------------------------------------------|
+
+*) Compiled using special assembly language support module.
+
+It seems as if performance is limited by CPU bus and data cache capacity.
+This also makes the benchmarks debatable compared to a real test with
+UFC-crypt wired into Crack. However, the table gives an outline of
+what can be expected.
+
+Optimizations:
+-------------
+
+Here are the optimizations used relative to an ordinary implementation
+such as the one said to be used in crypt(3).
+
+Major optimizations
+*******************
+
+- Keep data packed as bits in integer variables -- allows for
+ fast permutations & parallel xor's in CPU hardware.
+
+- Let adjacent final & initial permutations collapse.
+
+- Keep working data in 'E expanded' format all the time.
+
+- Implement DES 'f' function mostly by table lookup
+
+- Calculate the above function on 12 bit basis rather than 6
+ as would be the most natural.
+
+- Implement setup routines so that performance is limited by the DES
+ inner loops only.
+
+- Instead of doing salting in the DES inner loops, modify the above tables
+ each time a new salt is seen. According to the BSD crypt code this is
+ ugly :-)
+
+Minor (dirty) optimizations
+***************************
+
+- combine iterations of DES inner loop so that DES only loops
+ 8 times. This saves a lot of variable swapping.
+
+- Implement key access by a walking pointer rather than coding
+ as array indexing.
+
+- As described, the table based f function uses a 3 dimensional array:
+
+ sb ['number of 12 bit segment']['12 bit index']['48 bit half index']
+
+ Code the routine with 4 (one dimensional) vectors.
+
+- Design the internal data format & uglify the DES loops so that
+ the compiler does not need to do bit shifts when indexing vectors.
+
+Revision history
+****************
+
+UFC patchlevel 0: base version; released to alt.sources on Sep 24 1991
+UFC patchlevel 1: patch released to alt.sources on Sep 27 1991.
+ No longer rebuilds sb tables when seeing a new salt.
+UFC-crypt pl0: Essentially UFC pl 1. Released to comp.sources.misc
+ on Oct 22 1991.
+UFC-crypt pl1: Released to comp.sources.misc in march 1992
+ * setkey/encrypt routines added
+ * added validation/benchmarking programs
+ * reworked keyschedule setup code
+ * memory demands reduced
+ * 64 bit support added
diff --git a/crypt/cert.c b/crypt/cert.c
new file mode 100644
index 0000000000..49896be1d9
--- /dev/null
+++ b/crypt/cert.c
@@ -0,0 +1,112 @@
+
+/*
+ * This crypt(3) validation program shipped with UFC-crypt
+ * is derived from one distributed with Phil Karns PD DES package.
+ *
+ * @(#)cert.c 1.8 11 Aug 1996
+ */
+
+#include <stdio.h>
+#include "crypt.h"
+
+int totfails = 0;
+
+#if __STDC__ - 0
+int main (int argc, char *argv[]);
+void get8 (char *cp);
+void put8 (char *cp);
+void good_bye (void) __attribute__ ((noreturn));
+#else
+void get8(), put8();
+#endif
+
+void good_bye ()
+{
+ if(totfails == 0) {
+ printf("Passed DES validation suite\n");
+ exit(0);
+ } else {
+ printf("%d failures during DES validation suite!!!\n", totfails);
+ exit(1);
+ }
+}
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char key[64],plain[64],cipher[64],answer[64];
+ int i;
+ int test;
+ int fail;
+
+ for(test=0;!feof(stdin);test++){
+
+ get8(key);
+ printf(" K: "); put8(key);
+ setkey(key);
+
+ get8(plain);
+ printf(" P: "); put8(plain);
+
+ get8(answer);
+ printf(" C: "); put8(answer);
+
+ for(i=0;i<64;i++)
+ cipher[i] = plain[i];
+ encrypt(cipher, 0);
+
+ for(i=0;i<64;i++)
+ if(cipher[i] != answer[i])
+ break;
+ fail = 0;
+ if(i != 64){
+ printf(" Encrypt FAIL");
+ fail++; totfails++;
+ }
+
+ encrypt(cipher, 1);
+
+ for(i=0;i<64;i++)
+ if(cipher[i] != plain[i])
+ break;
+ if(i != 64){
+ printf(" Decrypt FAIL");
+ fail++; totfails++;
+ }
+
+ if(fail == 0)
+ printf(" OK");
+ printf("\n");
+ }
+ good_bye();
+}
+void
+get8(cp)
+char *cp;
+{
+ int i,j,t;
+
+ for(i=0;i<8;i++){
+ scanf("%2x",&t);
+ if(feof(stdin))
+ good_bye();
+ for(j=0; j<8 ; j++) {
+ *cp++ = (t & (0x01 << (7-j))) != 0;
+ }
+ }
+}
+void
+put8(cp)
+char *cp;
+{
+ int i,j,t;
+
+ for(i=0;i<8;i++){
+ t = 0;
+ for(j = 0; j<8; j++)
+ t = (t<<1) | *cp++;
+ printf("%02x", t);
+ }
+}
diff --git a/crypt/cert.input b/crypt/cert.input
new file mode 100644
index 0000000000..d843fa8a8d
--- /dev/null
+++ b/crypt/cert.input
@@ -0,0 +1,171 @@
+0101010101010101 95f8a5e5dd31d900 8000000000000000
+0101010101010101 dd7f121ca5015619 4000000000000000
+0101010101010101 2e8653104f3834ea 2000000000000000
+0101010101010101 4bd388ff6cd81d4f 1000000000000000
+0101010101010101 20b9e767b2fb1456 0800000000000000
+0101010101010101 55579380d77138ef 0400000000000000
+0101010101010101 6cc5defaaf04512f 0200000000000000
+0101010101010101 0d9f279ba5d87260 0100000000000000
+0101010101010101 d9031b0271bd5a0a 0080000000000000
+0101010101010101 424250b37c3dd951 0040000000000000
+0101010101010101 b8061b7ecd9a21e5 0020000000000000
+0101010101010101 f15d0f286b65bd28 0010000000000000
+0101010101010101 add0cc8d6e5deba1 0008000000000000
+0101010101010101 e6d5f82752ad63d1 0004000000000000
+0101010101010101 ecbfe3bd3f591a5e 0002000000000000
+0101010101010101 f356834379d165cd 0001000000000000
+0101010101010101 2b9f982f20037fa9 0000800000000000
+0101010101010101 889de068a16f0be6 0000400000000000
+0101010101010101 e19e275d846a1298 0000200000000000
+0101010101010101 329a8ed523d71aec 0000100000000000
+0101010101010101 e7fce22557d23c97 0000080000000000
+0101010101010101 12a9f5817ff2d65d 0000040000000000
+0101010101010101 a484c3ad38dc9c19 0000020000000000
+0101010101010101 fbe00a8a1ef8ad72 0000010000000000
+0101010101010101 750d079407521363 0000008000000000
+0101010101010101 64feed9c724c2faf 0000004000000000
+0101010101010101 f02b263b328e2b60 0000002000000000
+0101010101010101 9d64555a9a10b852 0000001000000000
+0101010101010101 d106ff0bed5255d7 0000000800000000
+0101010101010101 e1652c6b138c64a5 0000000400000000
+0101010101010101 e428581186ec8f46 0000000200000000
+0101010101010101 aeb5f5ede22d1a36 0000000100000000
+0101010101010101 e943d7568aec0c5c 0000000080000000
+0101010101010101 df98c8276f54b04b 0000000040000000
+0101010101010101 b160e4680f6c696f 0000000020000000
+0101010101010101 fa0752b07d9c4ab8 0000000010000000
+0101010101010101 ca3a2b036dbc8502 0000000008000000
+0101010101010101 5e0905517bb59bcf 0000000004000000
+0101010101010101 814eeb3b91d90726 0000000002000000
+0101010101010101 4d49db1532919c9f 0000000001000000
+0101010101010101 25eb5fc3f8cf0621 0000000000800000
+0101010101010101 ab6a20c0620d1c6f 0000000000400000
+0101010101010101 79e90dbc98f92cca 0000000000200000
+0101010101010101 866ecedd8072bb0e 0000000000100000
+0101010101010101 8b54536f2f3e64a8 0000000000080000
+0101010101010101 ea51d3975595b86b 0000000000040000
+0101010101010101 caffc6ac4542de31 0000000000020000
+0101010101010101 8dd45a2ddf90796c 0000000000010000
+0101010101010101 1029d55e880ec2d0 0000000000008000
+0101010101010101 5d86cb23639dbea9 0000000000004000
+0101010101010101 1d1ca853ae7c0c5f 0000000000002000
+0101010101010101 ce332329248f3228 0000000000001000
+0101010101010101 8405d1abe24fb942 0000000000000800
+0101010101010101 e643d78090ca4207 0000000000000400
+0101010101010101 48221b9937748a23 0000000000000200
+0101010101010101 dd7c0bbd61fafd54 0000000000000100
+0101010101010101 2fbc291a570db5c4 0000000000000080
+0101010101010101 e07c30d7e4e26e12 0000000000000040
+0101010101010101 0953e2258e8e90a1 0000000000000020
+0101010101010101 5b711bc4ceebf2ee 0000000000000010
+0101010101010101 cc083f1e6d9e85f6 0000000000000008
+0101010101010101 d2fd8867d50d2dfe 0000000000000004
+0101010101010101 06e7ea22ce92708f 0000000000000002
+0101010101010101 166b40b44aba4bd6 0000000000000001
+8001010101010101 0000000000000000 95a8d72813daa94d
+4001010101010101 0000000000000000 0eec1487dd8c26d5
+2001010101010101 0000000000000000 7ad16ffb79c45926
+1001010101010101 0000000000000000 d3746294ca6a6cf3
+0801010101010101 0000000000000000 809f5f873c1fd761
+0401010101010101 0000000000000000 c02faffec989d1fc
+0201010101010101 0000000000000000 4615aa1d33e72f10
+0180010101010101 0000000000000000 2055123350c00858
+0140010101010101 0000000000000000 df3b99d6577397c8
+0120010101010101 0000000000000000 31fe17369b5288c9
+0110010101010101 0000000000000000 dfdd3cc64dae1642
+0108010101010101 0000000000000000 178c83ce2b399d94
+0104010101010101 0000000000000000 50f636324a9b7f80
+0102010101010101 0000000000000000 a8468ee3bc18f06d
+0101800101010101 0000000000000000 a2dc9e92fd3cde92
+0101400101010101 0000000000000000 cac09f797d031287
+0101200101010101 0000000000000000 90ba680b22aeb525
+0101100101010101 0000000000000000 ce7a24f350e280b6
+0101080101010101 0000000000000000 882bff0aa01a0b87
+0101040101010101 0000000000000000 25610288924511c2
+0101020101010101 0000000000000000 c71516c29c75d170
+0101018001010101 0000000000000000 5199c29a52c9f059
+0101014001010101 0000000000000000 c22f0a294a71f29f
+0101012001010101 0000000000000000 ee371483714c02ea
+0101011001010101 0000000000000000 a81fbd448f9e522f
+0101010801010101 0000000000000000 4f644c92e192dfed
+0101010401010101 0000000000000000 1afa9a66a6df92ae
+0101010201010101 0000000000000000 b3c1cc715cb879d8
+0101010180010101 0000000000000000 19d032e64ab0bd8b
+0101010140010101 0000000000000000 3cfaa7a7dc8720dc
+0101010120010101 0000000000000000 b7265f7f447ac6f3
+0101010110010101 0000000000000000 9db73b3c0d163f54
+0101010108010101 0000000000000000 8181b65babf4a975
+0101010104010101 0000000000000000 93c9b64042eaa240
+0101010102010101 0000000000000000 5570530829705592
+0101010101800101 0000000000000000 8638809e878787a0
+0101010101400101 0000000000000000 41b9a79af79ac208
+0101010101200101 0000000000000000 7a9be42f2009a892
+0101010101100101 0000000000000000 29038d56ba6d2745
+0101010101080101 0000000000000000 5495c6abf1e5df51
+0101010101040101 0000000000000000 ae13dbd561488933
+0101010101020101 0000000000000000 024d1ffa8904e389
+0101010101018001 0000000000000000 d1399712f99bf02e
+0101010101014001 0000000000000000 14c1d7c1cffec79e
+0101010101012001 0000000000000000 1de5279dae3bed6f
+0101010101011001 0000000000000000 e941a33f85501303
+0101010101010801 0000000000000000 da99dbbc9a03f379
+0101010101010401 0000000000000000 b7fc92f91d8e92e9
+0101010101010201 0000000000000000 ae8e5caa3ca04e85
+0101010101010180 0000000000000000 9cc62df43b6eed74
+0101010101010140 0000000000000000 d863dbb5c59a91a0
+0101010101010120 0000000000000000 a1ab2190545b91d7
+0101010101010110 0000000000000000 0875041e64c570f7
+0101010101010108 0000000000000000 5a594528bebef1cc
+0101010101010104 0000000000000000 fcdb3291de21f0c0
+0101010101010102 0000000000000000 869efd7f9f265a09
+1046913489980131 0000000000000000 88d55e54f54c97b4
+1007103489988020 0000000000000000 0c0cc00c83ea48fd
+10071034c8980120 0000000000000000 83bc8ef3a6570183
+1046103489988020 0000000000000000 df725dcad94ea2e9
+1086911519190101 0000000000000000 e652b53b550be8b0
+1086911519580101 0000000000000000 af527120c485cbb0
+5107b01519580101 0000000000000000 0f04ce393db926d5
+1007b01519190101 0000000000000000 c9f00ffc74079067
+3107915498080101 0000000000000000 7cfd82a593252b4e
+3107919498080101 0000000000000000 cb49a2f9e91363e3
+10079115b9080140 0000000000000000 00b588be70d23f56
+3107911598080140 0000000000000000 406a9a6ab43399ae
+1007d01589980101 0000000000000000 6cb773611dca9ada
+9107911589980101 0000000000000000 67fd21c17dbb5d70
+9107d01589190101 0000000000000000 9592cb4110430787
+1007d01598980120 0000000000000000 a6b7ff68a318ddd3
+1007940498190101 0000000000000000 4d102196c914ca16
+0107910491190401 0000000000000000 2dfa9f4573594965
+0107910491190101 0000000000000000 b46604816c0e0774
+0107940491190401 0000000000000000 6e7e6221a4f34e87
+19079210981a0101 0000000000000000 aa85e74643233199
+1007911998190801 0000000000000000 2e5a19db4d1962d6
+10079119981a0801 0000000000000000 23a866a809d30894
+1007921098190101 0000000000000000 d812d961f017d320
+100791159819010b 0000000000000000 055605816e58608f
+1004801598190101 0000000000000000 abd88e8b1b7716f1
+1004801598190102 0000000000000000 537ac95be69da1e1
+1004801598190108 0000000000000000 aed0f6ae3c25cdd8
+1002911598100104 0000000000000000 b3e35a5ee53e7b8d
+1002911598190104 0000000000000000 61c79c71921a2ef8
+1002911598100201 0000000000000000 e2f5728f0995013c
+1002911698100101 0000000000000000 1aeac39a61f0a464
+7ca110454a1a6e57 01a1d6d039776742 690f5b0d9a26939b
+0131d9619dc1376e 5cd54ca83def57da 7a389d10354bd271
+07a1133e4a0b2686 0248d43806f67172 868ebb51cab4599a
+3849674c2602319e 51454b582ddf440a 7178876e01f19b2a
+04b915ba43feb5b6 42fd443059577fa2 af37fb421f8c4095
+0113b970fd34f2ce 059b5e0851cf143a 86a560f10ec6d85b
+0170f175468fb5e6 0756d8e0774761d2 0cd3da020021dc09
+43297fad38e373fe 762514b829bf486a ea676b2cb7db2b7a
+07a7137045da2a16 3bdd119049372802 dfd64a815caf1a0f
+04689104c2fd3b2f 26955f6835af609a 5c513c9c4886c088
+37d06bb516cb7546 164d5e404f275232 0a2aeeae3ff4ab77
+1f08260d1ac2465e 6b056e18759f5cca ef1bf03e5dfa575a
+584023641aba6176 004bd6ef09176062 88bf0db6d70dee56
+025816164629b007 480d39006ee762f2 a1f9915541020b56
+49793ebc79b3258f 437540c8698f3cfa 6fbf1cafcffd0556
+4fb05e1515ab73a7 072d43a077075292 2f22e49bab7ca1ac
+49e95d6d4ca229bf 02fe55778117f12a 5a6b612cc26cce4a
+018310dc409b26d6 1d9d5c5018f728c2 5f4c038ed12b2e41
+1c587f1c13924fef 305532286d6f295a 63fac0d034d9f793
diff --git a/crypt/crypt.texi b/crypt/crypt.texi
new file mode 100644
index 0000000000..1a4177a024
--- /dev/null
+++ b/crypt/crypt.texi
@@ -0,0 +1,412 @@
+@node Cryptographic Functions
+@c @node Cryptographic Functions, , Top, Top
+@chapter DES Encryption and Password Handling
+@c %MENU% DES encryption and password handling
+
+On many systems, it is unnecessary to have any kind of user
+authentication; for instance, a workstation which is not connected to a
+network probably does not need any user authentication, because to use
+the machine an intruder must have physical access.
+
+Sometimes, however, it is necessary to be sure that a user is authorised
+to use some service a machine provides---for instance, to log in as a
+particular user id (@pxref{Users and Groups}). One traditional way of
+doing this is for each user to choose a secret @dfn{password}; then, the
+system can ask someone claiming to be a user what the user's password
+is, and if the person gives the correct password then the system can
+grant the appropriate privileges.
+
+If all the passwords are just stored in a file somewhere, then this file
+has to be very carefully protected. To avoid this, passwords are run
+through a @dfn{one-way function}, a function which makes it difficult to
+work out what its input was by looking at its output, before storing in
+the file.
+
+The GNU C library already provides a one-way function based on MD5. The
+@code{crypt} add-on provides additional compatibility with the standard
+UNIX one-way function based on the Data Encryption Standard.
+
+It also provides support for Secure RPC, and some library functions that
+can be used to perform normal DES encryption.
+
+The add-on is not included in the main distribution of the GNU C library
+because some governments, most notably those of France, Russia,
+and the US, have very restrictive rules governing the distribution and
+use of encryption software. The first section below tries to describe some
+of those rules.
+
+@menu
+* Legal Problems:: This software can get you locked up, or worse.
+* getpass:: Prompting the user for a password.
+* crypt:: A one-way function for UNIX passwords.
+* DES Encryption:: Routines for DES encryption.
+@end menu
+
+@node Legal Problems
+@section Legal Problems
+
+Because of the continuously changing state of the law, it's not possible
+to provide a definitive survey of the laws affecting cryptography.
+Instead, this section warns you of some of the known trouble spots; this
+may help you when you try to find out what the laws of your country are.
+
+Some countries require that you have a licence to use, posess, or import
+cryptography. These countries are believed to include Byelorussia,
+Burma, France, India, Indonesia, Israel, Kazakhstan, Pakistan, Russia,
+and Saudi Arabia.
+
+Some countries restrict the transmission of encrypted messages by radio;
+some telecommunications carriers restrict the transmission of encrypted
+messages over their network.
+
+Many countries have some form of export control for encryption software.
+The Wassenaar Arrangement is a multilateral agreement between 33
+countries (Argentina, Australia, Austria, Belgium, Bulgaria, Canada, the
+Czech Republic, Denmark, Finland, France, Germany, Greece, Hungary,
+Ireland, Italy, Japan, Luxembourg, the Netherlands, New Zealand, Norway,
+Poland, Portugal, the Republic of Korea, Romania, the Russian
+Federation, the Slovak Republic, Spain, Sweden, Switzerland, Turkey,
+Ukraine, the United Kingdom and the United States) which restricts some
+kinds of encryption exports. Different countries apply the arrangement
+in different ways; some do not allow the exception for certain kinds of
+``public domain'' software (which would include this library), some
+only restrict the export of software in tangible form, and others impose
+significant additional restrictions.
+
+The United States has additional rules. This software would generally
+be exportable under 15 CFR 740.13(e), which permits exports of
+``encryption source code'' which is ``publicly available'' and which is
+``not subject to an express agreement for the payment of a licensing fee or
+royalty for commercial production or sale of any product developed with
+the source code'' to most countries.
+
+The rules in this area are continuously changing. If you know of any
+information in this manual that is out-of-date, please report it using
+the @code{glibcbug} script. @xref{Reporting Bugs}.
+
+@node getpass
+@section Reading Passwords
+
+When reading in a password, it is desirable to avoid displaying it on
+the screen, to help keep it secret. The following function handles this
+in a convenient way.
+
+@comment unistd.h
+@comment BSD
+@deftypefun {char *} getpass (const char * @var{prompt})
+
+@code{getpass} outputs @var{prompt}, then reads a string in from the
+terminal without echoing it. It tries to connect to the real terminal,
+@file{/dev/tty}, if possible, to encourage users not to put plaintext
+passwords in files; otherwise, it uses @code{stdin} and @code{stderr}.
+@code{getpass} also disables the INTR, QUIT, and SUSP characters on the
+terminal using the @code{ISIG} terminal attribute (@pxref{Local Modes}).
+The terminal is flushed before and after @code{getpass}, so that
+characters of a mistyped password are not accidentally visible.
+
+In other C libraries, @code{getpass} may only return the first
+@code{PASS_MAX} bytes of a password. The GNU C library has no limit, so
+@code{PASS_MAX} is undefined.
+
+The prototype for this function is in @file{unistd.h}. @code{PASS_MAX}
+would be defined in @file{limits.h}.
+@end deftypefun
+
+This precise set of operations may not suit all possible situations. In
+this case, it is recommended that users write their own @code{getpass}
+substitute. For instance, a very simple substitute is as follows:
+
+@smallexample
+@include ../crypt/mygetpass.c.texi
+@end smallexample
+
+The substitute takes the same parameters as @code{getline}
+(@pxref{Line Input}); the user must print any prompt desired.
+
+@node crypt
+@section Encrypting Passwords
+
+@comment crypt.h
+@comment BSD, SVID
+@deftypefun {char *} crypt (const char * @var{key}, const char * @var{salt})
+
+The @code{crypt} function takes a password, @var{key}, as a string, and
+a @var{salt} character array which is described below, and returns a
+printable ASCII string which starts with another salt. It is believed
+that, given the output of the function, the best way to find a @var{key}
+that will produce that output is to guess values of @var{key} until the
+original value of @var{key} is found.
+
+The @var{salt} parameter does two things. Firstly, it selects which
+algorithm is used, the MD5-based one or the DES-based one. Secondly, it
+makes life harder for someone trying to guess passwords against a file
+containing many passwords; without a @var{salt}, an intruder can make a
+guess, run @code{crypt} on it once, and compare the result with all the
+passwords. With a @var{salt}, the intruder must run @code{crypt} once
+for each different salt.
+
+For the MD5-based algorithm, the @var{salt} should consist of the string
+@code{$1$}, followed by up to 8 characters, terminated by either
+another @code{$} or the end of the string. The result of @code{crypt}
+will be the @var{salt}, followed by a @code{$} if the salt didn't end
+with one, followed by 22 characters from the alphabet
+@code{./0-9A-Za-z}, up to 34 characters total. Every character in the
+@var{key} is significant.
+
+For the DES-based algorithm, the @var{salt} should consist of two
+characters from the alphabet @code{./0-9A-Za-z}, and the result of
+@code{crypt} will be those two characters followed by 11 more from the
+same alphabet, 13 in total. Only the first 8 characters in the
+@var{key} are significant. If the @code{crypt} add-on is not installed,
+trying to use the DES-based algorithm will return an empty string and
+set @code{errno} to @code{EOPNOTSUPP}.
+
+The MD5-based algorithm is available in the GNU C library even if the
+@code{crypt} add-on is not installed. It also has no limit on the
+useful length of the password used, and is slightly more secure. It is
+therefore preferred over the DES-based algorithm.
+
+When the user enters their password for the first time, the @var{salt}
+should be set to a new string which is reasonably random. To verify a
+password against the result of a previous call to @code{crypt}, pass
+the result of the previous call as the @var{salt}.
+@end deftypefun
+
+The following short program is an example of how to use @code{crypt} the
+first time a password is entered. Note that the @var{salt} generation
+is just barely acceptable; in particular, it is not unique between
+machines, and in many applications it would not be acceptable to let an
+attacker know what time the user's password was last set.
+
+@smallexample
+@include ../crypt/genpass.c.texi
+@end smallexample
+
+The next program shows how to verify a password. It prompts the user
+for a password and prints ``Access granted.'' if the user types
+@code{GNU libc manual}.
+
+@smallexample
+@include ../crypt/testpass.c.texi
+@end smallexample
+
+@comment crypt.h
+@comment GNU
+@deftypefun {char *} crypt_r (const char * @var{key}, const char * @var{salt}, {struct crypt_data *} @var{data})
+
+The @code{crypt_r} function does the same thing as @code{crypt}, but
+takes an extra parameter which includes space for its result (among
+other things), so it can be reentrant. @code{data@w{->}initialized} must be
+cleared to zero before the first time @code{crypt_r} is called.
+
+The @code{crypt_r} function is a GNU extension.
+@end deftypefun
+
+The @code{crypt} and @code{crypt_r} functions are prototyped in the
+header @file{crypt.h}.
+
+@node DES Encryption
+@section DES Encryption
+
+The Data Encryption Standard is described in the US Government Federal
+Information Processing Standards (FIPS) 46-3 published by the National
+Institute of Standards and Technology. The DES has been very thoroughly
+analysed since it was developed in the late 1970s, and no new
+significant flaws have been found.
+
+However, the DES uses only a 56-bit key (plus 8 parity bits), and a
+machine has been built in 1998 which can search through all possible
+keys in about 6 days, which cost about US$200000; faster searches would
+be possible with more money. This makes simple DES unsecure for most
+purposes, and NIST no longer permits new US government systems
+to use simple DES.
+
+For serious encryption functionality, it is recommended that one of the
+many free encryption libraries be used instead of these routines.
+
+The DES is a reversible operation which takes a 64-bit block and a
+64-bit key, and produces another 64-bit block. Usually the bits are
+numbered so that the most-significant bit, the first bit, of each block
+is numbered 1.
+
+Under that numbering, every 8th bit of the key (the 8th, 16th, and so
+on) is not used by the encryption algorithm itself. But the key must
+have odd parity; that is, out of bits 1 through 8, and 9 through 16, and
+so on, there must be an odd number of `1' bits, and this completely
+specifies the unused bits.
+
+@comment crypt.h
+@comment BSD, SVID
+@deftypefun void setkey (const char * @var{key})
+
+The @code{setkey} function sets an internal data structure to be an
+expanded form of @var{key}. @var{key} is specified as an array of 64
+bits each stored in a @code{char}, the first bit is @code{key[0]} and
+the 64th bit is @code{key[63]}. The @var{key} should have the correct
+parity.
+@end deftypefun
+
+@comment crypt.h
+@comment BSD, SVID
+@deftypefun void encrypt (char * @var{block}, int @var{edflag})
+
+The @code{encrypt} function encrypts @var{block} if
+@var{edflag} is 0, otherwise it decrypts @var{block}, using a key
+previously set by @code{setkey}. The result is
+placed in @var{block}.
+
+Like @code{setkey}, @var{block} is specified as an array of 64 bits each
+stored in a @code{char}, but there are no parity bits in @var{block}.
+@end deftypefun
+
+@comment crypt.h
+@comment GNU
+@deftypefun void setkey_r (const char * @var{key}, {struct crypt_data *} @var{data})
+@comment crypt.h
+@comment GNU
+@deftypefunx void encrypt_r (char * @var{block}, int @var{edflag}, {struct crypt_data *} @var{data})
+
+These are reentrant versions of @code{setkey} and @code{encrypt}. The
+only difference is the extra parameter, which stores the expanded
+version of @var{key}. Before calling @code{setkey_r} the first time,
+@code{data->initialised} must be cleared to zero.
+@end deftypefun
+
+The @code{setkey_r} and @code{encrypt_r} functions are GNU extensions.
+@code{setkey}, @code{encrypt}, @code{setkey_r}, and @code{encrypt_r} are
+defined in @file{crypt.h}.
+
+If the @code{crypt} add-on is not used to build the library, programs
+that use these four functions will crash when the functions are called.
+If this is a problem, the @code{ecb_crypt} function described below is
+recommended instead.
+
+@comment rpc/des_crypt.h
+@comment SUNRPC
+@deftypefun int ecb_crypt (char * @var{key}, char * @var{blocks}, unsigned @var{len}, unsigned @var{mode})
+
+The function @code{ecb_crypt} encrypts or decrypts one or more blocks
+using DES. Each block is encrypted independently.
+
+The @var{blocks} and the @var{key} are stored packed in 8-bit bytes, so
+that the first bit of the key is the most-significant bit of
+@code{key[0]} and the 63rd bit of the key is stored as the
+least-significant bit of @code{key[7]}. The @var{key} should have the
+correct parity.
+
+@var{len} is the number of bytes in @var{blocks}. It should be a
+multiple of 8 (so that there is a whole number of blocks to encrypt).
+@var{len} is limited to a maximum of @code{DES_MAXDATA} bytes.
+
+The result of the encryption replaces the input in @var{blocks}.
+
+The @var{mode} parameter is the bitwise OR of two of the following:
+
+@table @code
+@comment rpc/des_crypt.h
+@comment SUNRPC
+@item DES_ENCRYPT
+@findex DES_ENCRYPT
+This constant, used in the @var{mode} parameter, specifies that
+@var{blocks} is to be encrypted.
+
+@comment rpc/des_crypt.h
+@comment SUNRPC
+@item DES_DECRYPT
+@findex DES_DECRYPT
+This constant, used in the @var{mode} parameter, specifies that
+@var{blocks} is to be decrypted.
+
+@comment rpc/des_crypt.h
+@comment SUNRPC
+@item DES_HW
+@findex DES_HW
+This constant, used in the @var{mode} parameter, asks to use a hardware
+device. If no hardware device is available, encryption happens anyway,
+but in software.
+
+@comment rpc/des_crypt.h
+@comment SUNRPC
+@item DES_SW
+@findex DES_SW
+This constant, used in the @var{mode} parameter, specifies that no
+hardware device is to be used.
+@end table
+
+The result of the function will be one of these values:
+
+@table @code
+@comment rpc/des_crypt.h
+@comment SUNRPC
+@item DESERR_NONE
+@findex DESERR_NONE
+The encryption succeeded.
+
+@comment rpc/des_crypt.h
+@comment SUNRPC
+@item DESERR_NOHWDEVICE
+@findex DESERR_NOHWDEVICE
+The encryption succeeded, but there was no hardware device available.
+
+@comment rpc/des_crypt.h
+@comment SUNRPC
+@item DESERR_HWERROR
+@findex DESERR_HWERROR
+The encryption failed because of a hardware problem. In the GNU
+library, this error code is also returned if the @code{crypt} add-on was
+not used to build the library.
+
+@comment rpc/des_crypt.h
+@comment SUNRPC
+@item DESERR_BADPARAM
+@findex DESERR_BADPARAM
+The encryption failed because of a bad parameter, for instance @var{len}
+is not a multiple of 8 or @var{len} is larger than @code{DES_MAXDATA}.
+@end table
+@end deftypefun
+
+@comment rpc/des_crypt.h
+@comment SUNRPC
+@deftypefun int DES_FAILED (int @var{err})
+This macro returns 1 if @var{err} is a `success' result code from
+@code{ecb_crypt} or @code{cbc_crypt}, and 0 otherwise.
+@end deftypefun
+
+@comment rpc/des_crypt.h
+@comment SUNRPC
+@deftypefun int cbc_crypt (char * @var{key}, char * @var{blocks}, unsigned @var{len}, unsigned @var{mode}, char * @var{ivec})
+
+The function @code{cbc_crypt} encrypts or decrypts one or more blocks
+using DES in Cipher Block Chaining mode.
+
+For encryption in CBC mode, each block is exclusive-ored with @var{ivec}
+before being encrypted, then @var{ivec} is replaced with the result of
+the encryption, then the next block is processed. Decryption is the
+reverse of this process.
+
+This has the advantage that blocks which are the same before being
+encrypted are very unlikely to be the same after being encrypted, making
+it much harder to detect patterns in the data.
+
+Usually, @var{ivec} is set to 8 random bytes before encryption starts.
+Then the 8 random bytes are transmitted along with the encrypted data
+(without themselves being encrypted), and passed back in as @var{ivec}
+for decryption. Another possibility is to set @var{ivec} to 8 zeroes
+initially, and have the first the block encrypted consist of 8 random
+bytes.
+
+Otherwise, all the parameters are similar to those for @code{ecb_crypt}.
+@end deftypefun
+
+@comment rpc/des_crypt.h
+@comment SUNRPC
+@deftypefun void des_setparity (char * @var{key})
+
+The function @code{des_setparity} changes the 64-bit @var{key}, stored
+packed in 8-bit bytes, to have odd parity by altering the low bits of
+each byte.
+@end deftypefun
+
+The @code{ecb_crypt}, @code{cbc_crypt}, and @code{des_setparity}
+functions and their accompanying macros are all defined in the header
+@file{rpc/des_crypt.h}.
diff --git a/crypt/examples/genpass.c b/crypt/examples/genpass.c
new file mode 100644
index 0000000000..a7626dbed5
--- /dev/null
+++ b/crypt/examples/genpass.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <crypt.h>
+
+int
+main(void)
+{
+ unsigned long seed[2];
+ char salt[] = "$1$........";
+ const char *const seedchars =
+ "./0123456789ABCDEFGHIJKLMNOPQRST"
+ "UVWXYZabcdefghijklmnopqrstuvwxyz";
+ char *password;
+ int i;
+
+ /* Generate a (not very) random seed.
+ You should do it better than this... */
+ seed[0] = time(NULL);
+ seed[1] = getpid() ^ (seed[0] >> 14 & 0x30000);
+
+ /* Turn it into printable characters from `seedchars'. */
+ for (i = 0; i < 8; i++)
+ salt[3+i] = seedchars[(seed[i/5] >> (i%5)*6) & 0x3f];
+
+ /* Read in the user's password and encrypt it. */
+ password = crypt(getpass("Password:"), salt);
+
+ /* Print the results. */
+ puts(password);
+ return 0;
+}
diff --git a/crypt/examples/mygetpass.c b/crypt/examples/mygetpass.c
new file mode 100644
index 0000000000..6fe06f4637
--- /dev/null
+++ b/crypt/examples/mygetpass.c
@@ -0,0 +1,25 @@
+#include <termios.h>
+#include <stdio.h>
+
+ssize_t
+my_getpass (char **lineptr, size_t *n, FILE *stream)
+{
+ struct termios old, new;
+ int nread;
+
+ /* Turn echoing off and fail if we can't. */
+ if (tcgetattr (fileno (stream), &old) != 0)
+ return -1;
+ new = old;
+ new.c_lflag &= ~ECHO;
+ if (tcsetattr (fileno (stream), TCSAFLUSH, &new) != 0)
+ return -1;
+
+ /* Read the password. */
+ nread = getline (lineptr, n, stream);
+
+ /* Restore terminal. */
+ (void) tcsetattr (fileno (stream), TCSAFLUSH, &old);
+
+ return nread;
+}
diff --git a/crypt/examples/testpass.c b/crypt/examples/testpass.c
new file mode 100644
index 0000000000..5bd616d2a0
--- /dev/null
+++ b/crypt/examples/testpass.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <crypt.h>
+
+int
+main(void)
+{
+ /* Hashed form of "GNU libc manual". */
+ const char *const pass = "$1$/iSaq7rB$EoUw5jJPPvAPECNaaWzMK/";
+
+ char *result;
+ int ok;
+
+/*@group*/
+ /* Read in the user's password and encrypt it,
+ passing the expected password in as the salt. */
+ result = crypt(getpass("Password:"), pass);
+/*@end group*/
+
+ /* Test the result. */
+ ok = strcmp (result, pass) == 0;
+
+ puts(ok ? "Access granted." : "Access denied.");
+ return ok ? 0 : 1;
+}
diff --git a/crypt/genpass.c.texi b/crypt/genpass.c.texi
new file mode 100644
index 0000000000..aaee62986e
--- /dev/null
+++ b/crypt/genpass.c.texi
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <crypt.h>
+
+int
+main(void)
+@{
+ unsigned long seed[2];
+ char salt[] = "$1$........";
+ const char *const seedchars =
+ "./0123456789ABCDEFGHIJKLMNOPQRST"
+ "UVWXYZabcdefghijklmnopqrstuvwxyz";
+ char *password;
+ int i;
+
+ /* @r{Generate a (not very) random seed.
+ You should do it better than this...} */
+ seed[0] = time(NULL);
+ seed[1] = getpid() ^ (seed[0] >> 14 & 0x30000);
+
+ /* @r{Turn it into printable characters from `seedchars'.} */
+ for (i = 0; i < 8; i++)
+ salt[3+i] = seedchars[(seed[i/5] >> (i%5)*6) & 0x3f];
+
+ /* @r{Read in the user's password and encrypt it.} */
+ password = crypt(getpass("Password:"), salt);
+
+ /* @r{Print the results.} */
+ puts(password);
+ return 0;
+@}
diff --git a/crypt/mygetpass.c.texi b/crypt/mygetpass.c.texi
new file mode 100644
index 0000000000..717d21447f
--- /dev/null
+++ b/crypt/mygetpass.c.texi
@@ -0,0 +1,25 @@
+#include <termios.h>
+#include <stdio.h>
+
+ssize_t
+my_getpass (char **lineptr, size_t *n, FILE *stream)
+@{
+ struct termios old, new;
+ int nread;
+
+ /* @r{Turn echoing off and fail if we can't.} */
+ if (tcgetattr (fileno (stream), &old) != 0)
+ return -1;
+ new = old;
+ new.c_lflag &= ~ECHO;
+ if (tcsetattr (fileno (stream), TCSAFLUSH, &new) != 0)
+ return -1;
+
+ /* @r{Read the password.} */
+ nread = getline (lineptr, n, stream);
+
+ /* @r{Restore terminal.} */
+ (void) tcsetattr (fileno (stream), TCSAFLUSH, &old);
+
+ return nread;
+@}
diff --git a/crypt/speeds.c b/crypt/speeds.c
new file mode 100644
index 0000000000..7362391892
--- /dev/null
+++ b/crypt/speeds.c
@@ -0,0 +1,153 @@
+/*
+ * This fcrypt/crypt speed testing program
+ * is derived from one floating around in
+ * the net. It's distributed along with
+ * UFC-crypt but is not covered by any
+ * licence.
+ *
+ * @(#)speeds.c 1.11 20 Aug 1996
+ */
+
+#include <signal.h>
+#include <stdio.h>
+
+#ifndef SIGVTALRM
+/*
+ * patch from chip@chinacat.unicom.com (Chip Rosenthal):
+ * you may enable it if your system does not include
+ * a setitimer() function. You'll have to ensure the
+ * existence a environment variable: HZ giving how many
+ * ticks goes per second.
+ * If not existing in your default environment 50, 60
+ * or even 100 may be the right value. Perhaps you should
+ * then use 'time ./ufc 10000' instead of guessing.
+ */
+#define NO_ITIMER
+#endif
+
+#ifdef NO_ITIMER
+#include <sys/types.h>
+#include <sys/times.h>
+#else
+#include <sys/time.h>
+#endif
+
+static int cnt;
+#ifdef NO_ITIMER
+char *hz;
+struct tms tstart, tfinish;
+#endif
+#define ITIME 10 /* Number of seconds to run test. */
+
+char *crypt(), *fcrypt();
+
+void
+Stop ()
+{
+ double elapsed;
+#ifdef NO_ITIMER
+ (void) times(&tfinish);
+ elapsed = ((tfinish.tms_utime + tfinish.tms_stime) -
+ (tstart.tms_utime + tstart.tms_stime)) / atoi(hz);
+ printf("elapsed time = %d sec, CPU time = %f sec\n", ITIME, elapsed);
+#else
+ elapsed = ITIME;
+#endif
+ printf ("Did %f %s()s per second.\n", ((float) cnt) / elapsed,
+#if defined(FCRYPT)
+ "fcrypt"
+#else
+ "crypt"
+#endif
+ );
+ exit (0);
+}
+
+/*
+ * Silly rewrite of 'bzero'. I do so
+ * because some machines don't have
+ * bzero and some don't have memset.
+ */
+
+static void clearmem(start, cnt)
+ char *start;
+ int cnt;
+ { while(cnt--)
+ *start++ = '\0';
+ }
+
+main ()
+{
+ char *s;
+#ifdef NO_ITIMER
+ extern char *getenv();
+#else
+ struct itimerval itv;
+#endif
+
+#ifdef NO_ITIMER
+ if ((hz = getenv("HZ")) == NULL) {
+ fprintf(stderr, "HZ environment parameter undefined\n");
+ exit(1);
+ }
+#endif
+
+#ifdef FCRYPT
+ printf("\n");
+ printf("Warning: this version of the speed program may run slower when\n");
+ printf("benchmarking UFC-crypt than previous versions. This is because it\n");
+ printf("stresses the CPU hardware cache in order to get benchmark figures\n");
+ printf("that corresponds closer to the performance that can be expected in\n");
+ printf("a password cracker.\n\n");
+#endif
+
+ printf ("Running %s for %d seconds of virtual time ...\n",
+#ifdef FCRYPT
+ "UFC-crypt",
+#else
+ "crypt(libc)",
+#endif
+ ITIME);
+
+#ifdef FCRYPT
+ init_des ();
+#endif
+
+#ifdef NO_ITIMER
+ signal(SIGALRM, Stop);
+ switch (fork()) {
+ case -1:
+ perror("fork failed");
+ exit(1);
+ case 0:
+ sleep(10);
+ kill(getppid(), SIGALRM);
+ exit(0);
+ default:
+ (void) times(&tstart);
+ }
+#else
+ clearmem ((char*)&itv, (int)sizeof (itv));
+ signal (SIGVTALRM, Stop);
+ itv.it_value.tv_sec = ITIME;
+ itv.it_value.tv_usec = 0;
+ setitimer (ITIMER_VIRTUAL, &itv, NULL);
+#endif
+
+
+ s = "fredred";
+ for (cnt = 0;; cnt++)
+ {
+#ifdef FCRYPT
+ s = fcrypt (s, "eek");
+#else
+ s = crypt (s, "eek");
+#endif
+ }
+}
+
+
+
+
+
+
diff --git a/crypt/sysdeps/mach/hurd/Implies b/crypt/sysdeps/mach/hurd/Implies
new file mode 100644
index 0000000000..03a772586f
--- /dev/null
+++ b/crypt/sysdeps/mach/hurd/Implies
@@ -0,0 +1,2 @@
+# The Hurd uses Unix like DES crypto function.
+unix
diff --git a/crypt/sysdeps/unix/Makefile b/crypt/sysdeps/unix/Makefile
new file mode 100644
index 0000000000..65810482d0
--- /dev/null
+++ b/crypt/sysdeps/unix/Makefile
@@ -0,0 +1,4 @@
+ifeq ($(subdir),md5-crypt)
+libcrypt-routines += crypt crypt_util
+dont_distribute += crypt.c crypt_util.c
+endif
diff --git a/crypt/sysdeps/unix/crypt-entry.c b/crypt/sysdeps/unix/crypt-entry.c
new file mode 100644
index 0000000000..9d99c53a2b
--- /dev/null
+++ b/crypt/sysdeps/unix/crypt-entry.c
@@ -0,0 +1,149 @@
+/*
+ * UFC-crypt: ultra fast crypt(3) implementation
+ *
+ * Copyright (C) 1991, 1992, 1993, 1996, 1997 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * crypt entry points
+ *
+ * @(#)crypt-entry.c 1.2 12/20/96
+ *
+ */
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+#include <string.h>
+
+#ifndef STATIC
+#define STATIC static
+#endif
+
+#ifndef DOS
+#include "ufc-crypt.h"
+#else
+/*
+ * Thanks to greg%wind@plains.NoDak.edu (Greg W. Wettstein)
+ * for DOS patches
+ */
+#include "ufc.h"
+#endif
+#include "crypt.h"
+#include "crypt-private.h"
+
+/* Prototypes for local functions. */
+#if __STDC__ - 0
+#ifndef __GNU_LIBRARY__
+void _ufc_clearmem (char *start, int cnt);
+#else
+#define _ufc_clearmem(start, cnt) memset(start, 0, cnt)
+#endif
+extern char *__md5_crypt_r (const char *key, const char *salt, char *buffer,
+ int buflen);
+extern char *__md5_crypt (const char *key, const char *salt);
+#endif
+
+/* Define our magic string to mark salt for MD5 encryption
+ replacement. This is meant to be the same as for other MD5 based
+ encryption implementations. */
+static const char md5_salt_prefix[] = "$1$";
+
+/* For use by the old, non-reentrant routines (crypt/encrypt/setkey) */
+extern struct crypt_data _ufc_foobar;
+
+/*
+ * UNIX crypt function
+ */
+
+char *
+__crypt_r (key, salt, data)
+ const char *key;
+ const char *salt;
+ struct crypt_data * __restrict data;
+{
+ ufc_long res[4];
+ char ktab[9];
+ ufc_long xx = 25; /* to cope with GCC long long compiler bugs */
+
+#ifdef _LIBC
+ /* Try to find out whether we have to use MD5 encryption replacement. */
+ if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
+ return __md5_crypt_r (key, salt, (char *) data,
+ sizeof (struct crypt_data));
+#endif
+
+ /*
+ * Hack DES tables according to salt
+ */
+ _ufc_setup_salt_r (salt, data);
+
+ /*
+ * Setup key schedule
+ */
+ _ufc_clearmem (ktab, (int) sizeof (ktab));
+ (void) strncpy (ktab, key, 8);
+ _ufc_mk_keytab_r (ktab, data);
+
+ /*
+ * Go for the 25 DES encryptions
+ */
+ _ufc_clearmem ((char*) res, (int) sizeof (res));
+ _ufc_doit_r (xx, data, &res[0]);
+
+ /*
+ * Do final permutations
+ */
+ _ufc_dofinalperm_r (res, data);
+
+ /*
+ * And convert back to 6 bit ASCII
+ */
+ _ufc_output_conversion_r (res[0], res[1], salt, data);
+ return data->crypt_3_buf;
+}
+weak_alias (__crypt_r, crypt_r)
+
+char *
+crypt (key, salt)
+ const char *key;
+ const char *salt;
+{
+#ifdef _LIBC
+ /* Try to find out whether we have to use MD5 encryption replacement. */
+ if (strncmp (md5_salt_prefix, salt, sizeof (md5_salt_prefix) - 1) == 0)
+ return __md5_crypt (key, salt);
+#endif
+
+ return __crypt_r (key, salt, &_ufc_foobar);
+}
+
+
+/*
+ * To make fcrypt users happy.
+ * They don't need to call init_des.
+ */
+#ifdef _LIBC
+weak_alias (crypt, fcrypt)
+#else
+char *
+__fcrypt (key, salt)
+ const char *key;
+ const char *salt;
+{
+ return crypt (key, salt);
+}
+#endif
diff --git a/crypt/sysdeps/unix/crypt-private.h b/crypt/sysdeps/unix/crypt-private.h
new file mode 100644
index 0000000000..130cccd373
--- /dev/null
+++ b/crypt/sysdeps/unix/crypt-private.h
@@ -0,0 +1,60 @@
+/*
+ * UFC-crypt: ultra fast crypt(3) implementation
+ *
+ * Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * @(#)crypt-private.h 1.4 12/20/96
+ */
+
+/* Prototypes for local functions in libcrypt.a. */
+
+#ifndef CRYPT_PRIVATE_H
+#define CRYPT_PRIVATE_H 1
+
+#include <features.h>
+
+/* crypt.c */
+extern void _ufc_doit_r (ufc_long itr, struct crypt_data * __restrict __data,
+ ufc_long *res);
+
+
+/* crypt_util.c */
+extern void __init_des_r (struct crypt_data * __restrict __data);
+extern void __init_des (void);
+
+extern void _ufc_setup_salt_r (__const char *s,
+ struct crypt_data * __restrict __data);
+extern void _ufc_mk_keytab_r (__const char *key,
+ struct crypt_data * __restrict __data);
+extern void _ufc_dofinalperm_r (ufc_long *res,
+ struct crypt_data * __restrict __data);
+extern void _ufc_output_conversion_r (ufc_long v1, ufc_long v2,
+ __const char *salt,
+ struct crypt_data * __restrict __data);
+
+extern void __setkey_r (__const char *__key,
+ struct crypt_data * __restrict __data);
+extern void __encrypt_r (char * __restrict __block, int __edflag,
+ struct crypt_data * __restrict __data);
+
+/* crypt-entry.c */
+extern char *__crypt_r (__const char *__key, __const char *__salt,
+ struct crypt_data * __restrict __data);
+extern char *fcrypt (__const char *key, __const char *salt);
+
+#endif /* crypt-private.h */
diff --git a/crypt/sysdeps/unix/crypt.c b/crypt/sysdeps/unix/crypt.c
new file mode 100644
index 0000000000..8e2a576a70
--- /dev/null
+++ b/crypt/sysdeps/unix/crypt.c
@@ -0,0 +1,120 @@
+/*
+ * UFC-crypt: ultra fast crypt(3) implementation
+ *
+ * Copyright (C) 1991, 1992, 1993, 1996 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * @(#)crypt.c 2.25 12/20/96
+ *
+ * Semiportable C version
+ *
+ */
+
+#include "ufc-crypt.h"
+#include "crypt.h"
+#include "crypt-private.h"
+
+#ifdef _UFC_32_
+
+/*
+ * 32 bit version
+ */
+
+#define SBA(sb, v) (*(long32*)((char*)(sb)+(v)))
+
+void
+_ufc_doit_r(itr, __data, res)
+ ufc_long itr, *res;
+ struct crypt_data * __restrict __data;
+{
+ int i;
+ long32 s, *k;
+ long32 *sb01 = (long32*)__data->sb0;
+ long32 *sb23 = (long32*)__data->sb2;
+ long32 l1, l2, r1, r2;
+
+ l1 = (long32)res[0]; l2 = (long32)res[1];
+ r1 = (long32)res[2]; r2 = (long32)res[3];
+
+ while(itr--) {
+ k = (long32*)__data->keysched;
+ for(i=8; i--; ) {
+ s = *k++ ^ r1;
+ l1 ^= SBA(sb01, s & 0xffff); l2 ^= SBA(sb01, (s & 0xffff)+4);
+ l1 ^= SBA(sb01, s >>= 16 ); l2 ^= SBA(sb01, (s )+4);
+ s = *k++ ^ r2;
+ l1 ^= SBA(sb23, s & 0xffff); l2 ^= SBA(sb23, (s & 0xffff)+4);
+ l1 ^= SBA(sb23, s >>= 16 ); l2 ^= SBA(sb23, (s )+4);
+
+ s = *k++ ^ l1;
+ r1 ^= SBA(sb01, s & 0xffff); r2 ^= SBA(sb01, (s & 0xffff)+4);
+ r1 ^= SBA(sb01, s >>= 16 ); r2 ^= SBA(sb01, (s )+4);
+ s = *k++ ^ l2;
+ r1 ^= SBA(sb23, s & 0xffff); r2 ^= SBA(sb23, (s & 0xffff)+4);
+ r1 ^= SBA(sb23, s >>= 16 ); r2 ^= SBA(sb23, (s )+4);
+ }
+ s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s;
+ }
+ res[0] = l1; res[1] = l2; res[2] = r1; res[3] = r2;
+}
+
+#endif
+
+#ifdef _UFC_64_
+
+/*
+ * 64 bit version
+ */
+
+#define SBA(sb, v) (*(long64*)((char*)(sb)+(v)))
+
+void
+_ufc_doit_r(itr, __data, res)
+ ufc_long itr, *res;
+ struct crypt_data * __restrict __data;
+{
+ int i;
+ long64 l, r, s, *k;
+ register long64 *sb01 = (long64*)__data->sb0;
+ register long64 *sb23 = (long64*)__data->sb2;
+
+ l = (((long64)res[0]) << 32) | ((long64)res[1]);
+ r = (((long64)res[2]) << 32) | ((long64)res[3]);
+
+ while(itr--) {
+ k = (long64*)__data->keysched;
+ for(i=8; i--; ) {
+ s = *k++ ^ r;
+ l ^= SBA(sb23, (s ) & 0xffff);
+ l ^= SBA(sb23, (s >>= 16) & 0xffff);
+ l ^= SBA(sb01, (s >>= 16) & 0xffff);
+ l ^= SBA(sb01, (s >>= 16) );
+
+ s = *k++ ^ l;
+ r ^= SBA(sb23, (s ) & 0xffff);
+ r ^= SBA(sb23, (s >>= 16) & 0xffff);
+ r ^= SBA(sb01, (s >>= 16) & 0xffff);
+ r ^= SBA(sb01, (s >>= 16) );
+ }
+ s=l; l=r; r=s;
+ }
+
+ res[0] = l >> 32; res[1] = l & 0xffffffff;
+ res[2] = r >> 32; res[3] = r & 0xffffffff;
+}
+
+#endif
diff --git a/crypt/sysdeps/unix/crypt.h b/crypt/sysdeps/unix/crypt.h
new file mode 100644
index 0000000000..13191e6f33
--- /dev/null
+++ b/crypt/sysdeps/unix/crypt.h
@@ -0,0 +1,71 @@
+/*
+ * UFC-crypt: ultra fast crypt(3) implementation
+ *
+ * Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the GNU C Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * @(#)crypt.h 1.5 12/20/96
+ *
+ */
+
+#ifndef _CRYPT_H
+#define _CRYPT_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Encrypt at most 8 characters from KEY using salt to perturb DES. */
+extern char *crypt __P ((__const char *__key, __const char *__salt));
+
+/* Setup DES tables according KEY. */
+extern void setkey __P ((__const char *__key));
+
+/* Encrypt data in BLOCK in place if EDFLAG is zero; otherwise decrypt
+ block in place. */
+extern void encrypt __P ((char *__block, int __edflag));
+
+#ifdef __USE_GNU
+/* Reentrant versions of the functions above. The additional argument
+ points to a structure where the results are placed in. */
+struct crypt_data
+ {
+ char keysched[16 * 8];
+ char sb0[32768];
+ char sb1[32768];
+ char sb2[32768];
+ char sb3[32768];
+ /* end-of-aligment-critical-data */
+ char crypt_3_buf[14];
+ char current_salt[2];
+ long int current_saltbits;
+ int direction, initialized;
+ };
+
+extern char *crypt_r __P ((__const char *__key, __const char *__salt,
+ struct crypt_data * __restrict __data));
+
+extern void setkey_r __P ((__const char *__key,
+ struct crypt_data * __restrict __data));
+
+extern void encrypt_r __P ((char *__block, int __edflag,
+ struct crypt_data * __restrict __data));
+#endif
+
+__END_DECLS
+
+#endif /* crypt.h */
diff --git a/crypt/sysdeps/unix/crypt_util.c b/crypt/sysdeps/unix/crypt_util.c
new file mode 100644
index 0000000000..671571c51d
--- /dev/null
+++ b/crypt/sysdeps/unix/crypt_util.c
@@ -0,0 +1,914 @@
+/*
+ * UFC-crypt: ultra fast crypt(3) implementation
+ *
+ * Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * @(#)crypt_util.c 2.56 12/20/96
+ *
+ * Support routines
+ *
+ */
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+#include <string.h>
+
+#ifndef STATIC
+#define STATIC static
+#endif
+
+#ifndef DOS
+#include "patchlevel.h"
+#include "ufc-crypt.h"
+#else
+/*
+ * Thanks to greg%wind@plains.NoDak.edu (Greg W. Wettstein)
+ * for DOS patches
+ */
+#include "pl.h"
+#include "ufc.h"
+#endif
+#include "crypt.h"
+#include "crypt-private.h"
+
+/* Prototypes for local functions. */
+#if __STDC__ - 0
+#ifndef __GNU_LIBRARY__
+void _ufc_clearmem (char *start, int cnt);
+void _ufc_copymem (char *from, char *to, int cnt);
+#endif
+#ifdef _UFC_32_
+STATIC void shuffle_sb (long32 *k, ufc_long saltbits);
+#else
+STATIC void shuffle_sb (long64 *k, ufc_long saltbits);
+#endif
+#endif
+
+
+static const char patchlevel_str[] = PATCHLEVEL;
+
+/*
+ * Permutation done once on the 56 bit
+ * key derived from the original 8 byte ASCII key.
+ */
+static const int pc1[56] = {
+ 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
+ 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
+ 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
+ 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
+};
+
+/*
+ * How much to rotate each 28 bit half of the pc1 permutated
+ * 56 bit key before using pc2 to give the i' key
+ */
+static const int rots[16] = {
+ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+/*
+ * Permutation giving the key
+ * of the i' DES round
+ */
+static const int pc2[48] = {
+ 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
+ 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
+ 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
+ 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
+};
+
+/*
+ * The E expansion table which selects
+ * bits from the 32 bit intermediate result.
+ */
+static const int esel[48] = {
+ 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
+ 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
+ 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
+ 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1
+};
+
+/*
+ * Permutation done on the
+ * result of sbox lookups
+ */
+static const int perm32[32] = {
+ 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
+ 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
+};
+
+/*
+ * The sboxes
+ */
+static const int sbox[8][4][16]= {
+ { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
+ { 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
+ { 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
+ { 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 }
+ },
+
+ { { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
+ { 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
+ { 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
+ { 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 }
+ },
+
+ { { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
+ { 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
+ { 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
+ { 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 }
+ },
+
+ { { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
+ { 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
+ { 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
+ { 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 }
+ },
+
+ { { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
+ { 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
+ { 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
+ { 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 }
+ },
+
+ { { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
+ { 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
+ { 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
+ { 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 }
+ },
+
+ { { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
+ { 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
+ { 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
+ { 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 }
+ },
+
+ { { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
+ { 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
+ { 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
+ { 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 }
+ }
+};
+
+/*
+ * This is the initial
+ * permutation matrix
+ */
+static const int initial_perm[64] = {
+ 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
+ 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
+ 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
+ 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
+};
+
+/*
+ * This is the final
+ * permutation matrix
+ */
+static const int final_perm[64] = {
+ 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
+ 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
+ 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
+ 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25
+};
+
+#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')
+#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
+
+static const ufc_long BITMASK[24] = {
+ 0x40000000, 0x20000000, 0x10000000, 0x08000000, 0x04000000, 0x02000000,
+ 0x01000000, 0x00800000, 0x00400000, 0x00200000, 0x00100000, 0x00080000,
+ 0x00004000, 0x00002000, 0x00001000, 0x00000800, 0x00000400, 0x00000200,
+ 0x00000100, 0x00000080, 0x00000040, 0x00000020, 0x00000010, 0x00000008
+};
+
+static const unsigned char bytemask[8] = {
+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
+};
+
+static const ufc_long longmask[32] = {
+ 0x80000000, 0x40000000, 0x20000000, 0x10000000,
+ 0x08000000, 0x04000000, 0x02000000, 0x01000000,
+ 0x00800000, 0x00400000, 0x00200000, 0x00100000,
+ 0x00080000, 0x00040000, 0x00020000, 0x00010000,
+ 0x00008000, 0x00004000, 0x00002000, 0x00001000,
+ 0x00000800, 0x00000400, 0x00000200, 0x00000100,
+ 0x00000080, 0x00000040, 0x00000020, 0x00000010,
+ 0x00000008, 0x00000004, 0x00000002, 0x00000001
+};
+
+/*
+ * do_pc1: permform pc1 permutation in the key schedule generation.
+ *
+ * The first index is the byte number in the 8 byte ASCII key
+ * - second - - the two 28 bits halfs of the result
+ * - third - selects the 7 bits actually used of each byte
+ *
+ * The result is kept with 28 bit per 32 bit with the 4 most significant
+ * bits zero.
+ */
+static ufc_long do_pc1[8][2][128];
+
+/*
+ * do_pc2: permform pc2 permutation in the key schedule generation.
+ *
+ * The first index is the septet number in the two 28 bit intermediate values
+ * - second - - - septet values
+ *
+ * Knowledge of the structure of the pc2 permutation is used.
+ *
+ * The result is kept with 28 bit per 32 bit with the 4 most significant
+ * bits zero.
+ */
+static ufc_long do_pc2[8][128];
+
+/*
+ * eperm32tab: do 32 bit permutation and E selection
+ *
+ * The first index is the byte number in the 32 bit value to be permuted
+ * - second - is the value of this byte
+ * - third - selects the two 32 bit values
+ *
+ * The table is used and generated internally in init_des to speed it up
+ */
+static ufc_long eperm32tab[4][256][2];
+
+/*
+ * efp: undo an extra e selection and do final
+ * permutation giving the DES result.
+ *
+ * Invoked 6 bit a time on two 48 bit values
+ * giving two 32 bit longs.
+ */
+static ufc_long efp[16][64][2];
+
+/*
+ * For use by the old, non-reentrant routines
+ * (crypt/encrypt/setkey)
+ */
+struct crypt_data _ufc_foobar;
+
+#ifdef __GNU_LIBRARY__
+#include <bits/libc-lock.h>
+
+__libc_lock_define_initialized (static, _ufc_tables_lock)
+#endif
+
+#ifdef DEBUG
+
+void
+_ufc_prbits(a, n)
+ ufc_long *a;
+ int n;
+{
+ ufc_long i, j, t, tmp;
+ n /= 8;
+ for(i = 0; i < n; i++) {
+ tmp=0;
+ for(j = 0; j < 8; j++) {
+ t=8*i+j;
+ tmp|=(a[t/24] & BITMASK[t % 24])?bytemask[j]:0;
+ }
+ (void)printf("%02x ",tmp);
+ }
+ printf(" ");
+}
+
+static void
+_ufc_set_bits(v, b)
+ ufc_long v;
+ ufc_long *b;
+{
+ ufc_long i;
+ *b = 0;
+ for(i = 0; i < 24; i++) {
+ if(v & longmask[8 + i])
+ *b |= BITMASK[i];
+ }
+}
+
+#endif
+
+#ifndef __GNU_LIBRARY__
+/*
+ * Silly rewrites of 'bzero'/'memset'. I do so
+ * because some machines don't have
+ * bzero and some don't have memset.
+ */
+
+void
+_ufc_clearmem(start, cnt)
+ char *start;
+ int cnt;
+{
+ while(cnt--)
+ *start++ = '\0';
+}
+
+void
+_ufc_copymem(from, to, cnt)
+ char *from, *to;
+ int cnt;
+{
+ while(cnt--)
+ *to++ = *from++;
+}
+#else
+#define _ufc_clearmem(start, cnt) memset(start, 0, cnt)
+#define _ufc_copymem(from, to, cnt) memcpy(to, from, cnt)
+#endif
+
+/* lookup a 6 bit value in sbox */
+
+#define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf];
+
+/*
+ * Initialize unit - may be invoked directly
+ * by fcrypt users.
+ */
+
+void
+__init_des_r(__data)
+ struct crypt_data * __restrict __data;
+{
+ int comes_from_bit;
+ int bit, sg;
+ ufc_long j;
+ ufc_long mask1, mask2;
+ int e_inverse[64];
+ static volatile int small_tables_initialized = 0;
+
+#ifdef _UFC_32_
+ long32 *sb[4];
+ sb[0] = (long32*)__data->sb0; sb[1] = (long32*)__data->sb1;
+ sb[2] = (long32*)__data->sb2; sb[3] = (long32*)__data->sb3;
+#endif
+#ifdef _UFC_64_
+ long64 *sb[4];
+ sb[0] = (long64*)__data->sb0; sb[1] = (long64*)__data->sb1;
+ sb[2] = (long64*)__data->sb2; sb[3] = (long64*)__data->sb3;
+#endif
+
+ if(small_tables_initialized == 0) {
+#ifdef __GNU_LIBRARY__
+ __libc_lock_lock (_ufc_tables_lock);
+ if(small_tables_initialized)
+ goto small_tables_done;
+#endif
+
+ /*
+ * Create the do_pc1 table used
+ * to affect pc1 permutation
+ * when generating keys
+ */
+ _ufc_clearmem((char*)do_pc1, (int)sizeof(do_pc1));
+ for(bit = 0; bit < 56; bit++) {
+ comes_from_bit = pc1[bit] - 1;
+ mask1 = bytemask[comes_from_bit % 8 + 1];
+ mask2 = longmask[bit % 28 + 4];
+ for(j = 0; j < 128; j++) {
+ if(j & mask1)
+ do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2;
+ }
+ }
+
+ /*
+ * Create the do_pc2 table used
+ * to affect pc2 permutation when
+ * generating keys
+ */
+ _ufc_clearmem((char*)do_pc2, (int)sizeof(do_pc2));
+ for(bit = 0; bit < 48; bit++) {
+ comes_from_bit = pc2[bit] - 1;
+ mask1 = bytemask[comes_from_bit % 7 + 1];
+ mask2 = BITMASK[bit % 24];
+ for(j = 0; j < 128; j++) {
+ if(j & mask1)
+ do_pc2[comes_from_bit / 7][j] |= mask2;
+ }
+ }
+
+ /*
+ * Now generate the table used to do combined
+ * 32 bit permutation and e expansion
+ *
+ * We use it because we have to permute 16384 32 bit
+ * longs into 48 bit in order to initialize sb.
+ *
+ * Looping 48 rounds per permutation becomes
+ * just too slow...
+ *
+ */
+
+ _ufc_clearmem((char*)eperm32tab, (int)sizeof(eperm32tab));
+ for(bit = 0; bit < 48; bit++) {
+ ufc_long mask1,comes_from;
+ comes_from = perm32[esel[bit]-1]-1;
+ mask1 = bytemask[comes_from % 8];
+ for(j = 256; j--;) {
+ if(j & mask1)
+ eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK[bit % 24];
+ }
+ }
+
+ /*
+ * Create an inverse matrix for esel telling
+ * where to plug out bits if undoing it
+ */
+ for(bit=48; bit--;) {
+ e_inverse[esel[bit] - 1 ] = bit;
+ e_inverse[esel[bit] - 1 + 32] = bit + 48;
+ }
+
+ /*
+ * create efp: the matrix used to
+ * undo the E expansion and effect final permutation
+ */
+ _ufc_clearmem((char*)efp, (int)sizeof efp);
+ for(bit = 0; bit < 64; bit++) {
+ int o_bit, o_long;
+ ufc_long word_value, mask1, mask2;
+ int comes_from_f_bit, comes_from_e_bit;
+ int comes_from_word, bit_within_word;
+
+ /* See where bit i belongs in the two 32 bit long's */
+ o_long = bit / 32; /* 0..1 */
+ o_bit = bit % 32; /* 0..31 */
+
+ /*
+ * And find a bit in the e permutated value setting this bit.
+ *
+ * Note: the e selection may have selected the same bit several
+ * times. By the initialization of e_inverse, we only look
+ * for one specific instance.
+ */
+ comes_from_f_bit = final_perm[bit] - 1; /* 0..63 */
+ comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */
+ comes_from_word = comes_from_e_bit / 6; /* 0..15 */
+ bit_within_word = comes_from_e_bit % 6; /* 0..5 */
+
+ mask1 = longmask[bit_within_word + 26];
+ mask2 = longmask[o_bit];
+
+ for(word_value = 64; word_value--;) {
+ if(word_value & mask1)
+ efp[comes_from_word][word_value][o_long] |= mask2;
+ }
+ }
+ small_tables_initialized = 1;
+#ifdef __GNU_LIBRARY__
+small_tables_done:
+ __libc_lock_unlock(_ufc_tables_lock);
+#endif
+ }
+
+ /*
+ * Create the sb tables:
+ *
+ * For each 12 bit segment of an 48 bit intermediate
+ * result, the sb table precomputes the two 4 bit
+ * values of the sbox lookups done with the two 6
+ * bit halves, shifts them to their proper place,
+ * sends them through perm32 and finally E expands
+ * them so that they are ready for the next
+ * DES round.
+ *
+ */
+
+ _ufc_clearmem((char*)__data->sb0, (int)sizeof(__data->sb0));
+ _ufc_clearmem((char*)__data->sb1, (int)sizeof(__data->sb1));
+ _ufc_clearmem((char*)__data->sb2, (int)sizeof(__data->sb2));
+ _ufc_clearmem((char*)__data->sb3, (int)sizeof(__data->sb3));
+
+ for(sg = 0; sg < 4; sg++) {
+ int j1, j2;
+ int s1, s2;
+
+ for(j1 = 0; j1 < 64; j1++) {
+ s1 = s_lookup(2 * sg, j1);
+ for(j2 = 0; j2 < 64; j2++) {
+ ufc_long to_permute, inx;
+
+ s2 = s_lookup(2 * sg + 1, j2);
+ to_permute = (((ufc_long)s1 << 4) |
+ (ufc_long)s2) << (24 - 8 * (ufc_long)sg);
+
+#ifdef _UFC_32_
+ inx = ((j1 << 6) | j2) << 1;
+ sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0];
+ sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1];
+ sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0];
+ sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1];
+ sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0];
+ sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1];
+ sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0];
+ sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1];
+#endif
+#ifdef _UFC_64_
+ inx = ((j1 << 6) | j2);
+ sb[sg][inx] =
+ ((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) |
+ (long64)eperm32tab[0][(to_permute >> 24) & 0xff][1];
+ sb[sg][inx] |=
+ ((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) |
+ (long64)eperm32tab[1][(to_permute >> 16) & 0xff][1];
+ sb[sg][inx] |=
+ ((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) |
+ (long64)eperm32tab[2][(to_permute >> 8) & 0xff][1];
+ sb[sg][inx] |=
+ ((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) |
+ (long64)eperm32tab[3][(to_permute) & 0xff][1];
+#endif
+ }
+ }
+ }
+
+ __data->initialized++;
+}
+
+void
+__init_des()
+{
+ __init_des_r(&_ufc_foobar);
+}
+
+/*
+ * Process the elements of the sb table permuting the
+ * bits swapped in the expansion by the current salt.
+ */
+
+#ifdef _UFC_32_
+STATIC void
+shuffle_sb(k, saltbits)
+ long32 *k;
+ ufc_long saltbits;
+{
+ ufc_long j;
+ long32 x;
+ for(j=4096; j--;) {
+ x = (k[0] ^ k[1]) & (long32)saltbits;
+ *k++ ^= x;
+ *k++ ^= x;
+ }
+}
+#endif
+
+#ifdef _UFC_64_
+STATIC void
+shuffle_sb(k, saltbits)
+ long64 *k;
+ ufc_long saltbits;
+{
+ ufc_long j;
+ long64 x;
+ for(j=4096; j--;) {
+ x = ((*k >> 32) ^ *k) & (long64)saltbits;
+ *k++ ^= (x << 32) | x;
+ }
+}
+#endif
+
+/*
+ * Setup the unit for a new salt
+ * Hopefully we'll not see a new salt in each crypt call.
+ */
+
+void
+_ufc_setup_salt_r(s, __data)
+ __const char *s;
+ struct crypt_data * __restrict __data;
+{
+ ufc_long i, j, saltbits;
+
+ if(__data->initialized == 0)
+ __init_des_r(__data);
+
+ if(s[0] == __data->current_salt[0] && s[1] == __data->current_salt[1])
+ return;
+ __data->current_salt[0] = s[0]; __data->current_salt[1] = s[1];
+
+ /*
+ * This is the only crypt change to DES:
+ * entries are swapped in the expansion table
+ * according to the bits set in the salt.
+ */
+ saltbits = 0;
+ for(i = 0; i < 2; i++) {
+ long c=ascii_to_bin(s[i]);
+ for(j = 0; j < 6; j++) {
+ if((c >> j) & 0x1)
+ saltbits |= BITMASK[6 * i + j];
+ }
+ }
+
+ /*
+ * Permute the sb table values
+ * to reflect the changed e
+ * selection table
+ */
+#ifdef _UFC_32_
+#define LONGG long32*
+#endif
+#ifdef _UFC_64_
+#define LONGG long64*
+#endif
+
+ shuffle_sb((LONGG)__data->sb0, __data->current_saltbits ^ saltbits);
+ shuffle_sb((LONGG)__data->sb1, __data->current_saltbits ^ saltbits);
+ shuffle_sb((LONGG)__data->sb2, __data->current_saltbits ^ saltbits);
+ shuffle_sb((LONGG)__data->sb3, __data->current_saltbits ^ saltbits);
+
+ __data->current_saltbits = saltbits;
+}
+
+void
+_ufc_mk_keytab_r(key, __data)
+ const char *key;
+ struct crypt_data * __restrict __data;
+{
+ ufc_long v1, v2, *k1;
+ int i;
+#ifdef _UFC_32_
+ long32 v, *k2;
+ k2 = (long32*)__data->keysched;
+#endif
+#ifdef _UFC_64_
+ long64 v, *k2;
+ k2 = (long64*)__data->keysched;
+#endif
+
+ v1 = v2 = 0; k1 = &do_pc1[0][0][0];
+ for(i = 8; i--;) {
+ v1 |= k1[*key & 0x7f]; k1 += 128;
+ v2 |= k1[*key++ & 0x7f]; k1 += 128;
+ }
+
+ for(i = 0; i < 16; i++) {
+ k1 = &do_pc2[0][0];
+
+ v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i]));
+ v = k1[(v1 >> 21) & 0x7f]; k1 += 128;
+ v |= k1[(v1 >> 14) & 0x7f]; k1 += 128;
+ v |= k1[(v1 >> 7) & 0x7f]; k1 += 128;
+ v |= k1[(v1 ) & 0x7f]; k1 += 128;
+
+#ifdef _UFC_32_
+ *k2++ = (v | 0x00008000);
+ v = 0;
+#endif
+#ifdef _UFC_64_
+ v = (v << 32);
+#endif
+
+ v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i]));
+ v |= k1[(v2 >> 21) & 0x7f]; k1 += 128;
+ v |= k1[(v2 >> 14) & 0x7f]; k1 += 128;
+ v |= k1[(v2 >> 7) & 0x7f]; k1 += 128;
+ v |= k1[(v2 ) & 0x7f];
+
+#ifdef _UFC_32_
+ *k2++ = (v | 0x00008000);
+#endif
+#ifdef _UFC_64_
+ *k2++ = v | 0x0000800000008000l;
+#endif
+ }
+
+ __data->direction = 0;
+}
+
+/*
+ * Undo an extra E selection and do final permutations
+ */
+
+void
+_ufc_dofinalperm_r(res, __data)
+ ufc_long *res;
+ struct crypt_data * __restrict __data;
+{
+ ufc_long v1, v2, x;
+ ufc_long l1,l2,r1,r2;
+
+ l1 = res[0]; l2 = res[1];
+ r1 = res[2]; r2 = res[3];
+
+ x = (l1 ^ l2) & __data->current_saltbits; l1 ^= x; l2 ^= x;
+ x = (r1 ^ r2) & __data->current_saltbits; r1 ^= x; r2 ^= x;
+
+ v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3;
+
+ v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1];
+ v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1];
+ v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1];
+ v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1];
+
+ v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1];
+ v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1];
+ v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1];
+ v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1];
+
+ v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1];
+ v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1];
+ v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1];
+ v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1];
+
+ v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1];
+ v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1];
+ v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1];
+ v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1];
+
+ res[0] = v1; res[1] = v2;
+}
+
+/*
+ * crypt only: convert from 64 bit to 11 bit ASCII
+ * prefixing with the salt
+ */
+
+void
+_ufc_output_conversion_r(v1, v2, salt, __data)
+ ufc_long v1, v2;
+ __const char *salt;
+ struct crypt_data * __restrict __data;
+{
+ int i, s, shf;
+
+ __data->crypt_3_buf[0] = salt[0];
+ __data->crypt_3_buf[1] = salt[1] ? salt[1] : salt[0];
+
+ for(i = 0; i < 5; i++) {
+ shf = (26 - 6 * i); /* to cope with MSC compiler bug */
+ __data->crypt_3_buf[i + 2] = bin_to_ascii((v1 >> shf) & 0x3f);
+ }
+
+ s = (v2 & 0xf) << 2;
+ v2 = (v2 >> 2) | ((v1 & 0x3) << 30);
+
+ for(i = 5; i < 10; i++) {
+ shf = (56 - 6 * i);
+ __data->crypt_3_buf[i + 2] = bin_to_ascii((v2 >> shf) & 0x3f);
+ }
+
+ __data->crypt_3_buf[12] = bin_to_ascii(s);
+ __data->crypt_3_buf[13] = 0;
+}
+
+
+/*
+ * UNIX encrypt function. Takes a bitvector
+ * represented by one byte per bit and
+ * encrypt/decrypt according to edflag
+ */
+
+void
+__encrypt_r(__block, __edflag, __data)
+ char *__block;
+ int __edflag;
+ struct crypt_data * __restrict __data;
+{
+ ufc_long l1, l2, r1, r2, res[4];
+ int i;
+#ifdef _UFC_32_
+ long32 *kt;
+ kt = (long32*)__data->keysched;
+#endif
+#ifdef _UFC_64_
+ long64 *kt;
+ kt = (long64*)__data->keysched;
+#endif
+
+ /*
+ * Undo any salt changes to E expansion
+ */
+ _ufc_setup_salt_r("..", __data);
+
+ /*
+ * Reverse key table if
+ * changing operation (encrypt/decrypt)
+ */
+ if((__edflag == 0) != (__data->direction == 0)) {
+ for(i = 0; i < 8; i++) {
+#ifdef _UFC_32_
+ long32 x;
+ x = kt[2 * (15-i)];
+ kt[2 * (15-i)] = kt[2 * i];
+ kt[2 * i] = x;
+
+ x = kt[2 * (15-i) + 1];
+ kt[2 * (15-i) + 1] = kt[2 * i + 1];
+ kt[2 * i + 1] = x;
+#endif
+#ifdef _UFC_64_
+ long64 x;
+ x = kt[15-i];
+ kt[15-i] = kt[i];
+ kt[i] = x;
+#endif
+ }
+ __data->direction = __edflag;
+ }
+
+ /*
+ * Do initial permutation + E expansion
+ */
+ i = 0;
+ for(l1 = 0; i < 24; i++) {
+ if(__block[initial_perm[esel[i]-1]-1])
+ l1 |= BITMASK[i];
+ }
+ for(l2 = 0; i < 48; i++) {
+ if(__block[initial_perm[esel[i]-1]-1])
+ l2 |= BITMASK[i-24];
+ }
+
+ i = 0;
+ for(r1 = 0; i < 24; i++) {
+ if(__block[initial_perm[esel[i]-1+32]-1])
+ r1 |= BITMASK[i];
+ }
+ for(r2 = 0; i < 48; i++) {
+ if(__block[initial_perm[esel[i]-1+32]-1])
+ r2 |= BITMASK[i-24];
+ }
+
+ /*
+ * Do DES inner loops + final conversion
+ */
+ res[0] = l1; res[1] = l2;
+ res[2] = r1; res[3] = r2;
+ _ufc_doit_r((ufc_long)1, __data, &res[0]);
+
+ /*
+ * Do final permutations
+ */
+ _ufc_dofinalperm_r(res, __data);
+
+ /*
+ * And convert to bit array
+ */
+ l1 = res[0]; r1 = res[1];
+ for(i = 0; i < 32; i++) {
+ *__block++ = (l1 & longmask[i]) != 0;
+ }
+ for(i = 0; i < 32; i++) {
+ *__block++ = (r1 & longmask[i]) != 0;
+ }
+}
+weak_alias (__encrypt_r, encrypt_r)
+
+void
+encrypt(__block, __edflag)
+ char *__block;
+ int __edflag;
+{
+ __encrypt_r(__block, __edflag, &_ufc_foobar);
+}
+
+
+/*
+ * UNIX setkey function. Take a 64 bit DES
+ * key and setup the machinery.
+ */
+
+void
+__setkey_r(__key, __data)
+ __const char *__key;
+ struct crypt_data * __restrict __data;
+{
+ int i,j;
+ unsigned char c;
+ unsigned char ktab[8];
+
+ _ufc_setup_salt_r("..", __data); /* be sure we're initialized */
+
+ for(i = 0; i < 8; i++) {
+ for(j = 0, c = 0; j < 8; j++)
+ c = c << 1 | *__key++;
+ ktab[i] = c >> 1;
+ }
+ _ufc_mk_keytab_r(ktab, __data);
+}
+weak_alias (__setkey_r, setkey_r)
+
+void
+setkey(__key)
+ __const char *__key;
+{
+ __setkey_r(__key, &_ufc_foobar);
+}
diff --git a/crypt/sysdeps/unix/des_impl.c b/crypt/sysdeps/unix/des_impl.c
new file mode 100644
index 0000000000..f4fee720a1
--- /dev/null
+++ b/crypt/sysdeps/unix/des_impl.c
@@ -0,0 +1,615 @@
+/* Copyright (C) 1992 Eric Young - see COPYING for more details */
+/* Collected from libdes and modified for SECURE RPC by Martin Kuck 1994 */
+#include <string.h>
+#include "des.h"
+
+
+static const unsigned long des_SPtrans[8][64] =
+{
+ { /* nibble 0 */
+ 0x00820200, 0x00020000, 0x80800000, 0x80820200,
+ 0x00800000, 0x80020200, 0x80020000, 0x80800000,
+ 0x80020200, 0x00820200, 0x00820000, 0x80000200,
+ 0x80800200, 0x00800000, 0x00000000, 0x80020000,
+ 0x00020000, 0x80000000, 0x00800200, 0x00020200,
+ 0x80820200, 0x00820000, 0x80000200, 0x00800200,
+ 0x80000000, 0x00000200, 0x00020200, 0x80820000,
+ 0x00000200, 0x80800200, 0x80820000, 0x00000000,
+ 0x00000000, 0x80820200, 0x00800200, 0x80020000,
+ 0x00820200, 0x00020000, 0x80000200, 0x00800200,
+ 0x80820000, 0x00000200, 0x00020200, 0x80800000,
+ 0x80020200, 0x80000000, 0x80800000, 0x00820000,
+ 0x80820200, 0x00020200, 0x00820000, 0x80800200,
+ 0x00800000, 0x80000200, 0x80020000, 0x00000000,
+ 0x00020000, 0x00800000, 0x80800200, 0x00820200,
+ 0x80000000, 0x80820000, 0x00000200, 0x80020200},
+
+ { /* nibble 1 */
+ 0x10042004, 0x00000000, 0x00042000, 0x10040000,
+ 0x10000004, 0x00002004, 0x10002000, 0x00042000,
+ 0x00002000, 0x10040004, 0x00000004, 0x10002000,
+ 0x00040004, 0x10042000, 0x10040000, 0x00000004,
+ 0x00040000, 0x10002004, 0x10040004, 0x00002000,
+ 0x00042004, 0x10000000, 0x00000000, 0x00040004,
+ 0x10002004, 0x00042004, 0x10042000, 0x10000004,
+ 0x10000000, 0x00040000, 0x00002004, 0x10042004,
+ 0x00040004, 0x10042000, 0x10002000, 0x00042004,
+ 0x10042004, 0x00040004, 0x10000004, 0x00000000,
+ 0x10000000, 0x00002004, 0x00040000, 0x10040004,
+ 0x00002000, 0x10000000, 0x00042004, 0x10002004,
+ 0x10042000, 0x00002000, 0x00000000, 0x10000004,
+ 0x00000004, 0x10042004, 0x00042000, 0x10040000,
+ 0x10040004, 0x00040000, 0x00002004, 0x10002000,
+ 0x10002004, 0x00000004, 0x10040000, 0x00042000},
+
+ { /* nibble 2 */
+ 0x41000000, 0x01010040, 0x00000040, 0x41000040,
+ 0x40010000, 0x01000000, 0x41000040, 0x00010040,
+ 0x01000040, 0x00010000, 0x01010000, 0x40000000,
+ 0x41010040, 0x40000040, 0x40000000, 0x41010000,
+ 0x00000000, 0x40010000, 0x01010040, 0x00000040,
+ 0x40000040, 0x41010040, 0x00010000, 0x41000000,
+ 0x41010000, 0x01000040, 0x40010040, 0x01010000,
+ 0x00010040, 0x00000000, 0x01000000, 0x40010040,
+ 0x01010040, 0x00000040, 0x40000000, 0x00010000,
+ 0x40000040, 0x40010000, 0x01010000, 0x41000040,
+ 0x00000000, 0x01010040, 0x00010040, 0x41010000,
+ 0x40010000, 0x01000000, 0x41010040, 0x40000000,
+ 0x40010040, 0x41000000, 0x01000000, 0x41010040,
+ 0x00010000, 0x01000040, 0x41000040, 0x00010040,
+ 0x01000040, 0x00000000, 0x41010000, 0x40000040,
+ 0x41000000, 0x40010040, 0x00000040, 0x01010000},
+
+ { /* nibble 3 */
+ 0x00100402, 0x04000400, 0x00000002, 0x04100402,
+ 0x00000000, 0x04100000, 0x04000402, 0x00100002,
+ 0x04100400, 0x04000002, 0x04000000, 0x00000402,
+ 0x04000002, 0x00100402, 0x00100000, 0x04000000,
+ 0x04100002, 0x00100400, 0x00000400, 0x00000002,
+ 0x00100400, 0x04000402, 0x04100000, 0x00000400,
+ 0x00000402, 0x00000000, 0x00100002, 0x04100400,
+ 0x04000400, 0x04100002, 0x04100402, 0x00100000,
+ 0x04100002, 0x00000402, 0x00100000, 0x04000002,
+ 0x00100400, 0x04000400, 0x00000002, 0x04100000,
+ 0x04000402, 0x00000000, 0x00000400, 0x00100002,
+ 0x00000000, 0x04100002, 0x04100400, 0x00000400,
+ 0x04000000, 0x04100402, 0x00100402, 0x00100000,
+ 0x04100402, 0x00000002, 0x04000400, 0x00100402,
+ 0x00100002, 0x00100400, 0x04100000, 0x04000402,
+ 0x00000402, 0x04000000, 0x04000002, 0x04100400},
+
+ { /* nibble 4 */
+ 0x02000000, 0x00004000, 0x00000100, 0x02004108,
+ 0x02004008, 0x02000100, 0x00004108, 0x02004000,
+ 0x00004000, 0x00000008, 0x02000008, 0x00004100,
+ 0x02000108, 0x02004008, 0x02004100, 0x00000000,
+ 0x00004100, 0x02000000, 0x00004008, 0x00000108,
+ 0x02000100, 0x00004108, 0x00000000, 0x02000008,
+ 0x00000008, 0x02000108, 0x02004108, 0x00004008,
+ 0x02004000, 0x00000100, 0x00000108, 0x02004100,
+ 0x02004100, 0x02000108, 0x00004008, 0x02004000,
+ 0x00004000, 0x00000008, 0x02000008, 0x02000100,
+ 0x02000000, 0x00004100, 0x02004108, 0x00000000,
+ 0x00004108, 0x02000000, 0x00000100, 0x00004008,
+ 0x02000108, 0x00000100, 0x00000000, 0x02004108,
+ 0x02004008, 0x02004100, 0x00000108, 0x00004000,
+ 0x00004100, 0x02004008, 0x02000100, 0x00000108,
+ 0x00000008, 0x00004108, 0x02004000, 0x02000008},
+
+ { /* nibble 5 */
+ 0x20000010, 0x00080010, 0x00000000, 0x20080800,
+ 0x00080010, 0x00000800, 0x20000810, 0x00080000,
+ 0x00000810, 0x20080810, 0x00080800, 0x20000000,
+ 0x20000800, 0x20000010, 0x20080000, 0x00080810,
+ 0x00080000, 0x20000810, 0x20080010, 0x00000000,
+ 0x00000800, 0x00000010, 0x20080800, 0x20080010,
+ 0x20080810, 0x20080000, 0x20000000, 0x00000810,
+ 0x00000010, 0x00080800, 0x00080810, 0x20000800,
+ 0x00000810, 0x20000000, 0x20000800, 0x00080810,
+ 0x20080800, 0x00080010, 0x00000000, 0x20000800,
+ 0x20000000, 0x00000800, 0x20080010, 0x00080000,
+ 0x00080010, 0x20080810, 0x00080800, 0x00000010,
+ 0x20080810, 0x00080800, 0x00080000, 0x20000810,
+ 0x20000010, 0x20080000, 0x00080810, 0x00000000,
+ 0x00000800, 0x20000010, 0x20000810, 0x20080800,
+ 0x20080000, 0x00000810, 0x00000010, 0x20080010},
+
+ { /* nibble 6 */
+ 0x00001000, 0x00000080, 0x00400080, 0x00400001,
+ 0x00401081, 0x00001001, 0x00001080, 0x00000000,
+ 0x00400000, 0x00400081, 0x00000081, 0x00401000,
+ 0x00000001, 0x00401080, 0x00401000, 0x00000081,
+ 0x00400081, 0x00001000, 0x00001001, 0x00401081,
+ 0x00000000, 0x00400080, 0x00400001, 0x00001080,
+ 0x00401001, 0x00001081, 0x00401080, 0x00000001,
+ 0x00001081, 0x00401001, 0x00000080, 0x00400000,
+ 0x00001081, 0x00401000, 0x00401001, 0x00000081,
+ 0x00001000, 0x00000080, 0x00400000, 0x00401001,
+ 0x00400081, 0x00001081, 0x00001080, 0x00000000,
+ 0x00000080, 0x00400001, 0x00000001, 0x00400080,
+ 0x00000000, 0x00400081, 0x00400080, 0x00001080,
+ 0x00000081, 0x00001000, 0x00401081, 0x00400000,
+ 0x00401080, 0x00000001, 0x00001001, 0x00401081,
+ 0x00400001, 0x00401080, 0x00401000, 0x00001001},
+
+ { /* nibble 7 */
+ 0x08200020, 0x08208000, 0x00008020, 0x00000000,
+ 0x08008000, 0x00200020, 0x08200000, 0x08208020,
+ 0x00000020, 0x08000000, 0x00208000, 0x00008020,
+ 0x00208020, 0x08008020, 0x08000020, 0x08200000,
+ 0x00008000, 0x00208020, 0x00200020, 0x08008000,
+ 0x08208020, 0x08000020, 0x00000000, 0x00208000,
+ 0x08000000, 0x00200000, 0x08008020, 0x08200020,
+ 0x00200000, 0x00008000, 0x08208000, 0x00000020,
+ 0x00200000, 0x00008000, 0x08000020, 0x08208020,
+ 0x00008020, 0x08000000, 0x00000000, 0x00208000,
+ 0x08200020, 0x08008020, 0x08008000, 0x00200020,
+ 0x08208000, 0x00000020, 0x00200020, 0x08008000,
+ 0x08208020, 0x00200000, 0x08200000, 0x08000020,
+ 0x00208000, 0x00008020, 0x08008020, 0x08200000,
+ 0x00000020, 0x08208000, 0x00208020, 0x00000000,
+ 0x08000000, 0x08200020, 0x00008000, 0x00208020}};
+
+static const unsigned long des_skb[8][64] =
+{
+ { /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+ 0x00000000, 0x00000010, 0x20000000, 0x20000010,
+ 0x00010000, 0x00010010, 0x20010000, 0x20010010,
+ 0x00000800, 0x00000810, 0x20000800, 0x20000810,
+ 0x00010800, 0x00010810, 0x20010800, 0x20010810,
+ 0x00000020, 0x00000030, 0x20000020, 0x20000030,
+ 0x00010020, 0x00010030, 0x20010020, 0x20010030,
+ 0x00000820, 0x00000830, 0x20000820, 0x20000830,
+ 0x00010820, 0x00010830, 0x20010820, 0x20010830,
+ 0x00080000, 0x00080010, 0x20080000, 0x20080010,
+ 0x00090000, 0x00090010, 0x20090000, 0x20090010,
+ 0x00080800, 0x00080810, 0x20080800, 0x20080810,
+ 0x00090800, 0x00090810, 0x20090800, 0x20090810,
+ 0x00080020, 0x00080030, 0x20080020, 0x20080030,
+ 0x00090020, 0x00090030, 0x20090020, 0x20090030,
+ 0x00080820, 0x00080830, 0x20080820, 0x20080830,
+ 0x00090820, 0x00090830, 0x20090820, 0x20090830},
+ { /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+ 0x00000000, 0x02000000, 0x00002000, 0x02002000,
+ 0x00200000, 0x02200000, 0x00202000, 0x02202000,
+ 0x00000004, 0x02000004, 0x00002004, 0x02002004,
+ 0x00200004, 0x02200004, 0x00202004, 0x02202004,
+ 0x00000400, 0x02000400, 0x00002400, 0x02002400,
+ 0x00200400, 0x02200400, 0x00202400, 0x02202400,
+ 0x00000404, 0x02000404, 0x00002404, 0x02002404,
+ 0x00200404, 0x02200404, 0x00202404, 0x02202404,
+ 0x10000000, 0x12000000, 0x10002000, 0x12002000,
+ 0x10200000, 0x12200000, 0x10202000, 0x12202000,
+ 0x10000004, 0x12000004, 0x10002004, 0x12002004,
+ 0x10200004, 0x12200004, 0x10202004, 0x12202004,
+ 0x10000400, 0x12000400, 0x10002400, 0x12002400,
+ 0x10200400, 0x12200400, 0x10202400, 0x12202400,
+ 0x10000404, 0x12000404, 0x10002404, 0x12002404,
+ 0x10200404, 0x12200404, 0x10202404, 0x12202404},
+ { /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+ 0x00000000, 0x00000001, 0x00040000, 0x00040001,
+ 0x01000000, 0x01000001, 0x01040000, 0x01040001,
+ 0x00000002, 0x00000003, 0x00040002, 0x00040003,
+ 0x01000002, 0x01000003, 0x01040002, 0x01040003,
+ 0x00000200, 0x00000201, 0x00040200, 0x00040201,
+ 0x01000200, 0x01000201, 0x01040200, 0x01040201,
+ 0x00000202, 0x00000203, 0x00040202, 0x00040203,
+ 0x01000202, 0x01000203, 0x01040202, 0x01040203,
+ 0x08000000, 0x08000001, 0x08040000, 0x08040001,
+ 0x09000000, 0x09000001, 0x09040000, 0x09040001,
+ 0x08000002, 0x08000003, 0x08040002, 0x08040003,
+ 0x09000002, 0x09000003, 0x09040002, 0x09040003,
+ 0x08000200, 0x08000201, 0x08040200, 0x08040201,
+ 0x09000200, 0x09000201, 0x09040200, 0x09040201,
+ 0x08000202, 0x08000203, 0x08040202, 0x08040203,
+ 0x09000202, 0x09000203, 0x09040202, 0x09040203},
+ { /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+ 0x00000000, 0x00100000, 0x00000100, 0x00100100,
+ 0x00000008, 0x00100008, 0x00000108, 0x00100108,
+ 0x00001000, 0x00101000, 0x00001100, 0x00101100,
+ 0x00001008, 0x00101008, 0x00001108, 0x00101108,
+ 0x04000000, 0x04100000, 0x04000100, 0x04100100,
+ 0x04000008, 0x04100008, 0x04000108, 0x04100108,
+ 0x04001000, 0x04101000, 0x04001100, 0x04101100,
+ 0x04001008, 0x04101008, 0x04001108, 0x04101108,
+ 0x00020000, 0x00120000, 0x00020100, 0x00120100,
+ 0x00020008, 0x00120008, 0x00020108, 0x00120108,
+ 0x00021000, 0x00121000, 0x00021100, 0x00121100,
+ 0x00021008, 0x00121008, 0x00021108, 0x00121108,
+ 0x04020000, 0x04120000, 0x04020100, 0x04120100,
+ 0x04020008, 0x04120008, 0x04020108, 0x04120108,
+ 0x04021000, 0x04121000, 0x04021100, 0x04121100,
+ 0x04021008, 0x04121008, 0x04021108, 0x04121108},
+ { /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+ 0x00000000, 0x10000000, 0x00010000, 0x10010000,
+ 0x00000004, 0x10000004, 0x00010004, 0x10010004,
+ 0x20000000, 0x30000000, 0x20010000, 0x30010000,
+ 0x20000004, 0x30000004, 0x20010004, 0x30010004,
+ 0x00100000, 0x10100000, 0x00110000, 0x10110000,
+ 0x00100004, 0x10100004, 0x00110004, 0x10110004,
+ 0x20100000, 0x30100000, 0x20110000, 0x30110000,
+ 0x20100004, 0x30100004, 0x20110004, 0x30110004,
+ 0x00001000, 0x10001000, 0x00011000, 0x10011000,
+ 0x00001004, 0x10001004, 0x00011004, 0x10011004,
+ 0x20001000, 0x30001000, 0x20011000, 0x30011000,
+ 0x20001004, 0x30001004, 0x20011004, 0x30011004,
+ 0x00101000, 0x10101000, 0x00111000, 0x10111000,
+ 0x00101004, 0x10101004, 0x00111004, 0x10111004,
+ 0x20101000, 0x30101000, 0x20111000, 0x30111000,
+ 0x20101004, 0x30101004, 0x20111004, 0x30111004},
+ { /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+ 0x00000000, 0x08000000, 0x00000008, 0x08000008,
+ 0x00000400, 0x08000400, 0x00000408, 0x08000408,
+ 0x00020000, 0x08020000, 0x00020008, 0x08020008,
+ 0x00020400, 0x08020400, 0x00020408, 0x08020408,
+ 0x00000001, 0x08000001, 0x00000009, 0x08000009,
+ 0x00000401, 0x08000401, 0x00000409, 0x08000409,
+ 0x00020001, 0x08020001, 0x00020009, 0x08020009,
+ 0x00020401, 0x08020401, 0x00020409, 0x08020409,
+ 0x02000000, 0x0A000000, 0x02000008, 0x0A000008,
+ 0x02000400, 0x0A000400, 0x02000408, 0x0A000408,
+ 0x02020000, 0x0A020000, 0x02020008, 0x0A020008,
+ 0x02020400, 0x0A020400, 0x02020408, 0x0A020408,
+ 0x02000001, 0x0A000001, 0x02000009, 0x0A000009,
+ 0x02000401, 0x0A000401, 0x02000409, 0x0A000409,
+ 0x02020001, 0x0A020001, 0x02020009, 0x0A020009,
+ 0x02020401, 0x0A020401, 0x02020409, 0x0A020409},
+ { /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+ 0x00000000, 0x00000100, 0x00080000, 0x00080100,
+ 0x01000000, 0x01000100, 0x01080000, 0x01080100,
+ 0x00000010, 0x00000110, 0x00080010, 0x00080110,
+ 0x01000010, 0x01000110, 0x01080010, 0x01080110,
+ 0x00200000, 0x00200100, 0x00280000, 0x00280100,
+ 0x01200000, 0x01200100, 0x01280000, 0x01280100,
+ 0x00200010, 0x00200110, 0x00280010, 0x00280110,
+ 0x01200010, 0x01200110, 0x01280010, 0x01280110,
+ 0x00000200, 0x00000300, 0x00080200, 0x00080300,
+ 0x01000200, 0x01000300, 0x01080200, 0x01080300,
+ 0x00000210, 0x00000310, 0x00080210, 0x00080310,
+ 0x01000210, 0x01000310, 0x01080210, 0x01080310,
+ 0x00200200, 0x00200300, 0x00280200, 0x00280300,
+ 0x01200200, 0x01200300, 0x01280200, 0x01280300,
+ 0x00200210, 0x00200310, 0x00280210, 0x00280310,
+ 0x01200210, 0x01200310, 0x01280210, 0x01280310},
+ { /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+ 0x00000000, 0x04000000, 0x00040000, 0x04040000,
+ 0x00000002, 0x04000002, 0x00040002, 0x04040002,
+ 0x00002000, 0x04002000, 0x00042000, 0x04042000,
+ 0x00002002, 0x04002002, 0x00042002, 0x04042002,
+ 0x00000020, 0x04000020, 0x00040020, 0x04040020,
+ 0x00000022, 0x04000022, 0x00040022, 0x04040022,
+ 0x00002020, 0x04002020, 0x00042020, 0x04042020,
+ 0x00002022, 0x04002022, 0x00042022, 0x04042022,
+ 0x00000800, 0x04000800, 0x00040800, 0x04040800,
+ 0x00000802, 0x04000802, 0x00040802, 0x04040802,
+ 0x00002800, 0x04002800, 0x00042800, 0x04042800,
+ 0x00002802, 0x04002802, 0x00042802, 0x04042802,
+ 0x00000820, 0x04000820, 0x00040820, 0x04040820,
+ 0x00000822, 0x04000822, 0x00040822, 0x04040822,
+ 0x00002820, 0x04002820, 0x00042820, 0x04042820,
+ 0x00002822, 0x04002822, 0x00042822, 0x04042822},
+};
+
+#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
+ l|=((unsigned long)(*((c)++)))<< 8, \
+ l|=((unsigned long)(*((c)++)))<<16, \
+ l|=((unsigned long)(*((c)++)))<<24)
+
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff))
+
+/*
+ * IP and FP
+ * The problem is more of a geometric problem that random bit fiddling.
+ * 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
+ * 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
+ * 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
+ * 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
+ *
+ * 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
+ * 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
+ * 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
+ * 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
+ *
+ * The output has been subject to swaps of the form
+ * 0 1 -> 3 1 but the odd and even bits have been put into
+ * 2 3 2 0
+ * different words. The main trick is to remember that
+ * t=((l>>size)^r)&(mask);
+ * r^=t;
+ * l^=(t<<size);
+ * can be used to swap and move bits between words.
+ *
+ * So l = 0 1 2 3 r = 16 17 18 19
+ * 4 5 6 7 20 21 22 23
+ * 8 9 10 11 24 25 26 27
+ * 12 13 14 15 28 29 30 31
+ * becomes (for size == 2 and mask == 0x3333)
+ * t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
+ * 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
+ * 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
+ * 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
+ *
+ * Thanks for hints from Richard Outerbridge - he told me IP&FP
+ * could be done in 15 xor, 10 shifts and 5 ands.
+ * When I finally started to think of the problem in 2D
+ * I first got ~42 operations without xors. When I remembered
+ * how to use xors :-) I got it to its final state.
+ */
+
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ (b)^=(t),\
+ (a)^=((t)<<(n)))
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+ (a)=(a)^(t)^(t>>(16-(n))))
+
+
+/* The changes to this macro may help or hinder, depending on the
+ * compiler and the achitecture. gcc2 always seems to do well :-).
+ * Inspired by Dana How <how@isl.stanford.edu>
+ * DO NOT use the alternative version on machines with 8 byte longs.
+ */
+#ifdef ALT_ECB
+#define D_ENCRYPT(L,R,S) \
+ u=((R^s[S ])<<2); \
+ t= R^s[S+1]; \
+ t=((t>>2)+(t<<30)); \
+ L^= \
+ *(const unsigned long *)(des_SP+0x0100+((t )&0xfc))+ \
+ *(const unsigned long *)(des_SP+0x0300+((t>> 8)&0xfc))+ \
+ *(const unsigned long *)(des_SP+0x0500+((t>>16)&0xfc))+ \
+ *(const unsigned long *)(des_SP+0x0700+((t>>24)&0xfc))+ \
+ *(const unsigned long *)(des_SP+ ((u )&0xfc))+ \
+ *(const unsigned long *)(des_SP+0x0200+((u>> 8)&0xfc))+ \
+ *(const unsigned long *)(des_SP+0x0400+((u>>16)&0xfc))+ \
+ *(const unsigned long *)(des_SP+0x0600+((u>>24)&0xfc));
+#else /* original version */
+#define D_ENCRYPT(L,R,S) \
+ u=(R^s[S ]); \
+ t=R^s[S+1]; \
+ t=((t>>4)+(t<<28)); \
+ L^= des_SPtrans[1][(t )&0x3f]| \
+ des_SPtrans[3][(t>> 8)&0x3f]| \
+ des_SPtrans[5][(t>>16)&0x3f]| \
+ des_SPtrans[7][(t>>24)&0x3f]| \
+ des_SPtrans[0][(u )&0x3f]| \
+ des_SPtrans[2][(u>> 8)&0x3f]| \
+ des_SPtrans[4][(u>>16)&0x3f]| \
+ des_SPtrans[6][(u>>24)&0x3f];
+#endif
+
+#define ITERATIONS 16
+
+static const char shifts2[16] =
+{0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0};
+
+static void des_set_key (char *, unsigned long *) internal_function;
+static void des_encrypt (unsigned long *, unsigned long *, int)
+ internal_function;
+int _des_crypt (char *, unsigned, struct desparams *);
+
+static void
+internal_function
+des_set_key (char *key, unsigned long *schedule)
+{
+ register unsigned long c, d, t, s;
+ register unsigned char *in;
+ register unsigned long *k;
+ register int i;
+
+ k = (unsigned long *) schedule;
+ in = (unsigned char *) key;
+
+ c2l (in, c);
+ c2l (in, d);
+
+ /* I now do it in 47 simple operations :-)
+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+ * for the inspiration. :-) */
+ PERM_OP (d, c, t, 4, 0x0f0f0f0f);
+ HPERM_OP (c, t, -2, 0xcccc0000);
+ HPERM_OP (d, t, -2, 0xcccc0000);
+ PERM_OP (d, c, t, 1, 0x55555555);
+ PERM_OP (c, d, t, 8, 0x00ff00ff);
+ PERM_OP (d, c, t, 1, 0x55555555);
+ d = (((d & 0x000000ff) << 16) | (d & 0x0000ff00) |
+ ((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4));
+ c &= 0x0fffffff;
+
+ for (i = 0; i < ITERATIONS; i++)
+ {
+ if (shifts2[i])
+ {
+ c = ((c >> 2) | (c << 26));
+ d = ((d >> 2) | (d << 26));
+ }
+ else
+ {
+ c = ((c >> 1) | (c << 27));
+ d = ((d >> 1) | (d << 27));
+ }
+ c &= 0x0fffffff;
+ d &= 0x0fffffff;
+ /* could be a few less shifts but I am to lazy at this
+ * point in time to investigate */
+ s = des_skb[0][(c) & 0x3f] |
+ des_skb[1][((c >> 6) & 0x03) | ((c >> 7) & 0x3c)] |
+ des_skb[2][((c >> 13) & 0x0f) | ((c >> 14) & 0x30)] |
+ des_skb[3][((c >> 20) & 0x01) | ((c >> 21) & 0x06) | ((c >> 22) & 0x38)];
+ t = des_skb[4][(d) & 0x3f] |
+ des_skb[5][((d >> 7) & 0x03) | ((d >> 8) & 0x3c)] |
+ des_skb[6][(d >> 15) & 0x3f] |
+ des_skb[7][((d >> 21) & 0x0f) | ((d >> 22) & 0x30)];
+
+ /* table contained 0213 4657 */
+ *(k++) = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff;
+ s = ((s >> 16) | (t & 0xffff0000));
+
+ s = (s << 4) | (s >> 28);
+ *(k++) = s & 0xffffffff;
+ }
+}
+
+
+static void
+internal_function
+des_encrypt (unsigned long *buf, unsigned long *schedule, int encrypt)
+{
+ register unsigned long l, r, t, u;
+#ifdef ALT_ECB
+ register const unsigned char *des_SP = (const unsigned char *) des_SPtrans;
+#endif
+ register int i;
+ register unsigned long *s;
+
+ l = buf[0];
+ r = buf[1];
+
+ /* do IP */
+ PERM_OP (r, l, t, 4, 0x0f0f0f0f);
+ PERM_OP (l, r, t, 16, 0x0000ffff);
+ PERM_OP (r, l, t, 2, 0x33333333);
+ PERM_OP (l, r, t, 8, 0x00ff00ff);
+ PERM_OP (r, l, t, 1, 0x55555555);
+ /* r and l are reversed - remember that :-) - fix
+ * it in the next step */
+
+ /* Things have been modified so that the initial rotate is
+ * done outside the loop. This required the
+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
+ * One perl script later and things have a 5% speed up on a sparc2.
+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+ * for pointing this out. */
+ t = (r << 1) | (r >> 31);
+ r = (l << 1) | (l >> 31);
+ l = t;
+
+ /* clear the top bits on machines with 8byte longs */
+ l &= 0xffffffff;
+ r &= 0xffffffff;
+
+ s = (unsigned long *) schedule;
+ /* I don't know if it is worth the effort of loop unrolling the
+ * inner loop */
+ if (encrypt)
+ {
+ for (i = 0; i < 32; i += 4)
+ {
+ D_ENCRYPT (l, r, i + 0); /* 1 */
+ D_ENCRYPT (r, l, i + 2); /* 2 */
+ }
+ }
+ else
+ {
+ for (i = 30; i > 0; i -= 4)
+ {
+ D_ENCRYPT (l, r, i - 0); /* 16 */
+ D_ENCRYPT (r, l, i - 2); /* 15 */
+ }
+ }
+ l = (l >> 1) | (l << 31);
+ r = (r >> 1) | (r << 31);
+ /* clear the top bits on machines with 8byte longs */
+ l &= 0xffffffff;
+ r &= 0xffffffff;
+
+ /* swap l and r
+ * we will not do the swap so just remember they are
+ * reversed for the rest of the subroutine
+ * luckily FP fixes this problem :-) */
+
+ PERM_OP (r, l, t, 1, 0x55555555);
+ PERM_OP (l, r, t, 8, 0x00ff00ff);
+ PERM_OP (r, l, t, 2, 0x33333333);
+ PERM_OP (l, r, t, 16, 0x0000ffff);
+ PERM_OP (r, l, t, 4, 0x0f0f0f0f);
+
+ buf[0] = l;
+ buf[1] = r;
+
+ l = r = t = u = 0;
+}
+
+
+int
+_des_crypt (char *buf, unsigned len, struct desparams *desp)
+{
+ unsigned long schedule[32];
+ register unsigned long tin0, tin1;
+ register unsigned long tout0, tout1, xor0, xor1;
+ register unsigned char *in, *out;
+ unsigned long tbuf[2];
+ unsigned char *iv, *oiv;
+ int cbc_mode;
+
+ cbc_mode = (desp->des_mode == CBC) ? 1 : 0;
+
+ in = (unsigned char *) buf;
+ out = (unsigned char *) buf;
+ oiv = iv = (unsigned char *) desp->des_ivec;
+
+ des_set_key (desp->des_key, schedule);
+
+ tin0 = tin1 = 0; /* For GCC */
+ if (desp->des_dir == ENCRYPT)
+ {
+ c2l (iv, tout0);
+ c2l (iv, tout1);
+ for (; len > 0; len -= 8)
+ {
+ c2l (in, tin0);
+ c2l (in, tin1);
+ if (cbc_mode)
+ {
+ tin0 ^= tout0;
+ tin1 ^= tout1;
+ }
+ tbuf[0] = tin0;
+ tbuf[1] = tin1;
+ des_encrypt (tbuf, schedule, 1);
+ tout0 = tbuf[0];
+ tout1 = tbuf[1];
+ l2c (tout0, out);
+ l2c (tout1, out);
+ }
+ l2c (tout0, oiv);
+ l2c (tout1, oiv);
+ }
+ else
+ {
+ c2l (iv, xor0);
+ c2l (iv, xor1);
+ for (; len > 0; len -= 8)
+ {
+ c2l (in, tin0);
+ c2l (in, tin1);
+ tbuf[0] = tin0;
+ tbuf[1] = tin1;
+ des_encrypt (tbuf, schedule, 0);
+ if (cbc_mode)
+ {
+ tout0 = tbuf[0] ^ xor0;
+ tout1 = tbuf[1] ^ xor1;
+ xor0 = tin0;
+ xor1 = tin1;
+ }
+ else
+ {
+ tout0 = tbuf[0];
+ tout1 = tbuf[1];
+ }
+ l2c (tout0, out);
+ l2c (tout1, out);
+ }
+ l2c (tin0, oiv);
+ l2c (tin1, oiv);
+ }
+ tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0;
+ tbuf[0] = tbuf[1] = 0;
+ __bzero (schedule, sizeof (schedule));
+
+ return (1);
+}
diff --git a/crypt/sysdeps/unix/patchlevel.h b/crypt/sysdeps/unix/patchlevel.h
new file mode 100644
index 0000000000..450c091f60
--- /dev/null
+++ b/crypt/sysdeps/unix/patchlevel.h
@@ -0,0 +1,25 @@
+/*
+ * UFC-crypt: ultra fast crypt(3) implementation
+ *
+ * Copyright (C) 1991, 1992, 1993, 1996 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * @(#)patchlevel.h 1.13 9/10/96
+ *
+ */
+
+#define PATCHLEVEL "UFC-crypt, patchlevel 1e, @(#)patchlevel.h 1.13 9/10/96"
diff --git a/crypt/sysdeps/unix/ufc-crypt.h b/crypt/sysdeps/unix/ufc-crypt.h
new file mode 100644
index 0000000000..879211afec
--- /dev/null
+++ b/crypt/sysdeps/unix/ufc-crypt.h
@@ -0,0 +1,29 @@
+/* Types for UFC-crypt.
+ Copyright (C) 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdint.h>
+
+typedef uint_fast32_t ufc_long;
+typedef uint64_t long64;
+typedef uint32_t long32;
+#if UINT_FAST32_MAX == UINT_FAST64_MAX
+# define _UFC_64_
+#else
+# define _UFC_32_
+#endif
diff --git a/crypt/testpass.c.texi b/crypt/testpass.c.texi
new file mode 100644
index 0000000000..517c8e5a57
--- /dev/null
+++ b/crypt/testpass.c.texi
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <crypt.h>
+
+int
+main(void)
+@{
+ /* @r{Hashed form of "GNU libc manual".} */
+ const char *const pass = "$1$/iSaq7rB$EoUw5jJPPvAPECNaaWzMK/";
+
+ char *result;
+ int ok;
+
+@group
+ /* @r{Read in the user's password and encrypt it,
+ passing the expected password in as the salt.} */
+ result = crypt(getpass("Password:"), pass);
+@end group
+
+ /* @r{Test the result.} */
+ ok = strcmp (result, pass) == 0;
+
+ puts(ok ? "Access granted." : "Access denied.");
+ return ok ? 0 : 1;
+@}
diff --git a/crypt/ufc.c b/crypt/ufc.c
new file mode 100644
index 0000000000..858bdee0bc
--- /dev/null
+++ b/crypt/ufc.c
@@ -0,0 +1,55 @@
+/*
+ * UFC-crypt: ultra fast crypt(3) implementation
+ *
+ * Copyright (C) 1991, 1992, 1993, 1996 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * @(#)ufc.c 2.7 9/10/96
+ *
+ * Stub main program for debugging
+ * and benchmarking.
+ *
+ */
+
+#include <stdio.h>
+
+char *crypt();
+
+main(argc, argv)
+ int argc;
+ char **argv;
+ { char *s;
+ unsigned long i,iterations;
+
+ if(argc != 2) {
+ fprintf(stderr, "usage: ufc iterations\n");
+ exit(1);
+ }
+ argv++;
+ iterations = atoi(*argv);
+ printf("ufc: running %d iterations\n", iterations);
+
+ for(i=0; i<iterations; i++)
+ s=crypt("foob","ar");
+ if(strcmp(s, "arlEKn0OzVJn.") == 0)
+ printf("OK\n");
+ else {
+ printf("wrong result: %s!!\n", s);
+ exit(1);
+ }
+ exit(0);
+ }
+