summary refs log tree commit diff
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);
+  }
+